Skip to content

Reservation hook#21

Merged
yohann69 merged 5 commits into
mainfrom
reservation-hook
Oct 15, 2025
Merged

Reservation hook#21
yohann69 merged 5 commits into
mainfrom
reservation-hook

Conversation

@yohann69
Copy link
Copy Markdown
Member

@yohann69 yohann69 commented Oct 15, 2025

Summary by CodeRabbit

  • New Features
    • Sends Discord notifications when reservations are created, ended, or deleted, including item details, user info, and optional profile thumbnails.
  • Improvements
    • Search now separately returns matching categories and items with improved matching across names, descriptions, and locations.
  • Refactor
    • App initialization/routes updated to wire an optional reservation notification service into reservation flows.

@yohann69 yohann69 self-assigned this Oct 15, 2025
@yohann69 yohann69 added the enhancement New feature or request label Oct 15, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Oct 15, 2025

Caution

Review failed

The pull request is closed.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds Discord notification support for reservation create/cancel/delete flows, wires a DiscordService through main/routes/handler, adds ReservationRepository.GetItemName and refactors SearchItemsAndCategories, and extends DiscordService with SendReservationCreated/SendReservationCancelled and embed thumbnail support.

Changes

Cohort / File(s) Summary
Reservation repository updates
handlers/reservation/repository/reservation_repository.go
Added GetItemName(itemID int) (string, error) to fetch item names with proper error handling. Refactored SearchItemsAndCategories to perform separate LIKE searches for categories and items (lowercased matching), return two slices (categories, items), and properly propagate errors and close rows.
Reservation handler Discord integration
handlers/reservation/reservation_handler.go
Added DiscordService *services.DiscordService field and updated constructor to accept it. On reservation create, end, and delete flows, conditionally fetch item name and user info, format dates, and call SendReservationCreated / SendReservationCancelled when DiscordService is provided; preserves prior behavior when nil and uses fallbacks for missing item/user data.
Routing and wiring changes
routes/reservation.go, main.go
SetupReservationRoutes signature updated to accept a *services.DiscordService and pass it into the reservation handler. main.go initializes a reservation-specific Discord webhook from DISCORD_RESERVATION_ALERT_WEBHOOK and injects it into route setup.
Discord service enhancements
services/discord.go
Added SendReservationCreated(...) and SendReservationCancelled(...). Extended embed model to support Thumbnail/Image fields and include user profile thumbnails when available; constructs embeds with item, start/end dates, slot vs open type, and user details.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant API as Fiber App/Routes
  participant H as ReservationHandler
  participant Repo as ReservationRepository
  participant DB as SQL DB
  participant D as DiscordService

  Note over API,H: Reservation Creation Flow
  User->>API: POST /reservations
  API->>H: CreateReservation(req)
  H->>DB: INSERT reservation
  DB-->>H: reservation (id,itemID,user,dates)
  alt DiscordService provided
    H->>Repo: GetItemName(itemID)
    Repo->>DB: SELECT name FROM items WHERE id=?
    DB-->>Repo: name / no-row / error
    Repo-->>H: itemName or error
    H->>D: SendReservationCreated(itemName, start, end, isSlot, user)
    D-->>H: ack/error
  else No DiscordService
    Note over H: Skip notification
  end
  H-->>API: 201 Created
  API-->>User: Response
Loading
sequenceDiagram
  autonumber
  actor User
  participant API as Fiber App/Routes
  participant H as ReservationHandler
  participant Repo as ReservationRepository
  participant DB as SQL DB
  participant D as DiscordService

  Note over API,H: Reservation Cancel/Delete Flow
  User->>API: DELETE /reservations/:id or PATCH end
  API->>H: End/DeleteReservation(id)
  H->>DB: UPDATE/DELETE reservation
  DB-->>H: result (itemID, userToken/userID, dates)
  alt DiscordService provided
    H->>Repo: GetItemName(itemID)
    Repo->>DB: SELECT name FROM items WHERE id=?
    DB-->>Repo: name / error
    Repo-->>H: itemName or error
    H->>DB: SELECT user details if needed
    DB-->>H: user info or defaults
    H->>D: SendReservationCancelled(itemName, start, end, isSlot, user)
    D-->>H: ack/error
  else No DiscordService
    Note over H: Skip notification
  end
  H-->>API: 200 OK
  API-->>User: Response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Reservation hook #21 — Appears to mirror these same code-level changes (added ReservationRepository.GetItemName, wiring DiscordService through routes/handler/main, and added SendReservationCreated/SendReservationCancelled).

Poem

I thump and tap the keys with glee,
Names fetched and dates set true,
Green for hello, red adieu,
Tiny thumbnails peek and flee,
Hop—alerts delivered, nibble, whee. 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The title “Reservation hook” is too generic and does not clearly convey the primary change, which is the integration of Discord notification hooks for reservation lifecycle events. It lacks specificity around the new Discord service additions and the reservation create/cancel notifications. Consider renaming the pull request to explicitly describe the main change, for example “Add Discord notification hooks for reservation events,” so that the title clearly reflects the new Discord integration in the reservation workflows.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3de030b and 4fb5e19.

📒 Files selected for processing (1)
  • handlers/reservation/reservation_handler.go (4 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@yohann69 yohann69 requested a review from Copilot October 15, 2025 17:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds Discord webhook notifications for reservation lifecycle events (creation, ending, deletion). A dedicated reservation webhook URL can be configured via DISCORD_RESERVATION_ALERT_WEBHOOK environment variable, falling back to the default Discord webhook if not set. Notifications include item details, reservation type (slot-based or open-ended), dates, and user information with optional profile pictures.

Key Changes:

  • Added Discord notification methods for reservation created and cancelled events
  • Integrated Discord service into reservation routes and handlers
  • Added repository method to fetch item names for notifications

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
services/discord.go Added new embed types (thumbnail, image) and notification methods for reservation events
routes/reservation.go Updated route setup to accept and pass Discord service to reservation handler
main.go Initialized separate Discord service for reservation notifications with dedicated webhook URL
handlers/reservation/reservation_handler.go Integrated Discord notifications into reservation lifecycle (create, end, delete) with nil checks
handlers/reservation/repository/reservation_repository.go Added GetItemName method to retrieve item names for notification purposes

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment thread handlers/reservation/reservation_handler.go Outdated
Comment thread handlers/reservation/reservation_handler.go Outdated
yohann69 and others added 2 commits October 15, 2025 19:30
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (6)
main.go (1)

85-86: Avoid noisy warnings when no webhook: construct service only if URL is set

Currently a DiscordService is always created; if envs are empty, sends will fail and log warnings. Build the service only when an effective URL exists, pass nil otherwise.

Apply this diff:

-	// Discord reservation-specific webhook (falls back to default if unset)
-	reservationDiscordService := services.NewDiscordService(os.Getenv("DISCORD_RESERVATION_ALERT_WEBHOOK"))
+	// Discord reservation-specific webhook (falls back to default if unset)
+	reservationWebhookURL := os.Getenv("DISCORD_RESERVATION_ALERT_WEBHOOK")
+	if reservationWebhookURL == "" {
+		reservationWebhookURL = os.Getenv("DISCORD_WEBHOOK_URL")
+	}
+	var reservationDiscordService *services.DiscordService
+	if reservationWebhookURL != "" {
+		reservationDiscordService = services.NewDiscordService(reservationWebhookURL)
+	}

Also applies to: 173-173

services/discord.go (2)

125-155: Deduplicate common embed construction

Both methods repeat slot type selection and field assembly. Extract a small helper to build reservation embeds and pass title/color.

Also applies to: 157-187


134-139: Confirm policy: sending full user emails to Discord

Embeds include the user Email field. If Discord is considered a third party, this may be a privacy/compliance concern. Consider masking emails (e.g., jo****@Domain) or removing them if not strictly needed.

If masking is desired, add a helper and use it in both methods:

// Add near `safe`:
func maskEmail(email string) string {
	if email == "" {
		return ""
	}
	at := strings.LastIndex(email, "@")
	if at <= 1 {
		return "***"
	}
	local, domain := email[:at], email[at+1:]
	if len(local) > 2 {
		local = local[:2] + strings.Repeat("*", len(local)-2)
	} else {
		local = strings.Repeat("*", len(local))
	}
	return local + "@" + domain
}

Then replace the Email field values with: safe(maskEmail(user.Email), "N/A").

Note: you'll need to import "strings".

Also applies to: 166-171

handlers/reservation/reservation_handler.go (3)

447-463: Guard against empty webhook to avoid pointless send attempts

Add a URL check to skip sending when the service exists but webhook URL is empty.

-		if h.DiscordService != nil && res.User != nil {
+		if h.DiscordService != nil && h.DiscordService.WebhookURL != "" && res.User != nil {

481-494: Cancellation embed lacks start date—confirm intent

You send an empty startDate; embed will show N/A. If useful, consider fetching and including the original reservation start time.


709-739: Move user lookup to repository to keep handler thin

Direct SQL in the handler breaks the layering established by ReservationRepository. Add a repository method (e.g., GetUserByEmail) and reuse here.

Example repository method:

// In handlers/reservation/repository/reservation_repository.go
func (r *ReservationRepository) GetUserByEmail(email string) (models.ReservationUser, error) {
	var u models.ReservationUser
	row := r.DB.QueryRow("SELECT first_name, last_name, COALESCE(profile_picture,'') FROM newf WHERE email = $1", email)
	u.Email = email
	if err := row.Scan(&u.FirstName, &u.LastName, &u.ProfilePicture); err != nil {
		return u, err
	}
	return u, nil
}

Then replace the inline query with a call to GetUserByEmail.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b5ab71f and 3de030b.

📒 Files selected for processing (5)
  • handlers/reservation/repository/reservation_repository.go (1 hunks)
  • handlers/reservation/reservation_handler.go (4 hunks)
  • main.go (2 hunks)
  • routes/reservation.go (1 hunks)
  • services/discord.go (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
routes/reservation.go (2)
services/discord.go (1)
  • DiscordService (15-18)
handlers/reservation/reservation_handler.go (1)
  • NewReservationHandler (21-26)
services/discord.go (1)
models/reservation.go (1)
  • ReservationUser (6-11)
handlers/reservation/reservation_handler.go (4)
handlers/reservation/repository/reservation_repository.go (2)
  • ReservationRepository (14-16)
  • NewReservationRepository (18-22)
services/discord.go (1)
  • DiscordService (15-18)
utils/logManager.go (2)
  • LogMessage (62-64)
  • LevelWarn (17-17)
models/reservation.go (1)
  • ReservationUser (6-11)
handlers/reservation/repository/reservation_repository.go (1)
utils/logManager.go (3)
  • LogMessage (62-64)
  • LevelWarn (17-17)
  • LevelError (16-16)
main.go (2)
services/discord.go (1)
  • NewDiscordService (20-28)
routes/reservation.go (1)
  • SetupReservationRoutes (12-35)
🔇 Additional comments (3)
routes/reservation.go (1)

9-10: Wiring looks good

Signature/import updates correctly inject DiscordService into the handler. Matches main.go.

Also applies to: 12-15

handlers/reservation/repository/reservation_repository.go (1)

741-754: GetItemName implementation is correct

Query, error handling, and logging are appropriate.

handlers/reservation/reservation_handler.go (1)

21-26: Constructor wiring is correct

Handler now cleanly receives DiscordService via DI.

@yohann69 yohann69 merged commit 6698487 into main Oct 15, 2025
1 check failed
@yohann69 yohann69 deleted the reservation-hook branch October 15, 2025 17:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants