Group events
A dedicated channel for customers to propose private events (birthdays, communions, company dinners, bachelor/ette parties, afterworks) without cluttering the regular reservation flow.
Event types
- Birthday (with extra fields: name and age of the birthday guest)
- Communion
- Afterwork
- Company dinner
- Bachelor/ette party
- Other
Customer flow
On the public page, if you have group_events_enabled on, the option "Is this an event? Send us a proposal" appears.
Form with:
- Event type.
- Preferred date + alternate (optional).
- Preferred time (optional, default 13:00).
- Group size (1-200).
- Per-person budget (optional, in cents).
- Customer details: name, phone, email (recommended).
- Requirements (free text, up to 2000 characters): diets, allergies, decoration, music, etc.
- Type-specific fields: birthday guest's name, address if it's at home...
The customer submits and gets a visual confirmation with a reference code.
Validations
- Rate limiting: max 3 proposals/IP in 15 minutes.
- Idempotency: the same proposal sent twice doesn't duplicate.
- Group size between 1 and 200.
Statuses
Pending → Accepted → Reservation created
v v
Expired Declined
- Pending: just submitted, awaiting response.
- Accepted: the restaurant owner accepted and a linked provisional reservation was created.
- Declined: the restaurant owner declined (with optional message).
- Expired: 14 days without response.
14-day automatic expiration
Each proposal is born with expires_at = now() + 14 days. A daily cron at 03:15 UTC marks pending overdue ones as expired.
This guarantees that:
- The customer isn't waiting indefinitely.
- The restaurant owner has a clear deadline.
- The pending inbox stays clean.
Manage from the dashboard
/app/eventos lists proposals with a status filter (default: pending).
Each card shows:
- Customer name and phone
- Event type (badge)
- Status (colored badge)
- Preferred date + alternate
- Size and budget
Click a proposal → side panel with full detail and two actions:
- Accept and create reservation: requires a message (min. 2 characters) that the customer receives by email. Creates a linked provisional reservation in pending state.
- Decline: also requires a message. The proposal stays as
declined.
Once answered, it can't be repeated.
Automatic email to the restaurant owner
When a proposal comes in, RestaPro sends an email to the team (to the configured alert_emails) with a summary and a direct link to the dashboard.
Accept = reservation created
On accept, the system:
- Creates a reservation with
source = group_event, statuspending, preferred date and time. - Links the reservation to the
proposal_id. - If the customer left an email, sends them confirmation with reference code and the restaurant owner's message.
Afterward you can refine the reservation in /app/reservas: assign a specific table, adjust the time, add internal notes.
Pinche manages it too
- "List pending proposals" → conversational summary.
- "Accept Ana's proposal with this message: confirmed, we'll call you Monday" → executes with prior confirmation.
- "Decline Carlos's proposal. Tell him: we have a private event that day." → declines and notifies the customer.
Best practices
- Reply within 48 h: acceptance rate drops fast if you delay.
- Personalize the message: your customer sees literally what you write.
- Attach a proposed menu in the message if you have a fixed group menu (link to the menu PDF).
- If you decline, propose an alternative: "not that date, what about Saturday?".
- For large groups (15+): pre-call the customer before accepting to confirm operational details.