SRS — Events & Planner
Module owner: Domain 2 — Event. The Event is the core entity of Yam3at: every quotation, booking, payment, message, review and file belongs to exactly one Event. This module covers event creation, the event dashboard (aggregation hub), archive/rebook, and the planner suite that grows in Scale and Vision phases.
Related: Quotations · Booking · Payments · Messaging & Notifications
Purpose
Give customers a single container per occasion (wedding, graduation, corporate event…) from which they discover vendors, request quotes, book, pay, communicate and later review — replacing scattered WhatsApp threads and spreadsheets with one organized workspace.
Actors
| Actor |
Role in this module |
| Customer |
Creates and owns events; manages planner data |
| Vendor |
No direct access; sees only the event context attached to RFQs/bookings sent to them |
| Admin |
Read access for support/dispute handling; cannot edit customer events |
| System |
Auto-archives past events, computes budget aggregates, sends milestone reminders |
User stories
- As a customer, I want to create an event with its type, date, city and rough budget, so that everything I do next (quotes, bookings, chats) is organized under it.
- As a customer, I want an event dashboard showing my open quotations, confirmed bookings, unread messages and paid/outstanding amounts, so that I always know where I stand.
- As a customer, I want to duplicate a past event ("rebook"), so that my recurring diwaniya or annual corporate gathering takes one tap to set up again.
- As a customer, I want a budget tracker per category (Scale), so that I know before accepting a quote whether it blows my budget.
- As a customer, I want a checklist template for my event type (Scale), so that I don't forget the cake tasting three weeks out.
- As a customer, I want a seating planner and QR invitations (Vision), so that guest logistics live in the same place as everything else.
Functional requirements
Event CRUD — MVP
| ID |
Requirement |
Phase |
| SRS-EVT-001 |
Customer can create an Event with: event_type (from admin-managed list: wedding, engagement, birthday, graduation, corporate, conference, exhibition, diwaniya, baby shower, other), name, event_date (nullable — "date not decided yet" allowed), city (Kuwait governorates at launch: Al Asimah, Hawalli, Farwaniya, Mubarak Al-Kabeer, Ahmadi, Jahra), venue_status (enum: venue_booked, venue_needed, home/private), expected_guests (integer), budget_total (KWD, 3 decimals, optional), notes (free text). |
MVP |
| SRS-EVT-002 |
Customer can edit any event field while the event is active. Changing event_date prompts a confirmation listing affected bookings and notifies each booked vendor (see SRS-MSG catalog). Date changes never silently reschedule bookings — vendors must re-confirm. |
MVP |
| SRS-EVT-003 |
Customer can view a list of their events split into Upcoming, Past, and Archived, sorted by event_date (nulls last). |
MVP |
| SRS-EVT-004 |
Customer can archive an event. Archiving is blocked while the event has bookings in pending or confirmed status or quotations in pending/quoted/negotiating; the block message lists the blockers with links. Archiving cancels any remaining draft RFQs. |
MVP |
| SRS-EVT-005 |
Customer can delete an event only if it has zero quotations, bookings and payments (soft delete, retained 30 days). Otherwise only archive is offered. |
MVP |
| SRS-EVT-006 |
System auto-moves events to Past at event_date + 1 day (Asia/Kuwait timezone) and triggers the booking-completion flow (see SRS-BKG-011). |
MVP |
Event dashboard — MVP
| ID |
Requirement |
Phase |
| SRS-EVT-010 |
Event dashboard aggregates, per event: quotation counts by status, bookings by status, unread message count across the event's conversations, payments summary (total paid, deposits outstanding), and days-until-event countdown. |
MVP |
| SRS-EVT-011 |
Dashboard exposes primary actions contextually: "Request quotes" (always), "Compare quotes" (≥2 quoted RFQ responses), "Pay deposit" (booking awaiting deposit), "Leave a review" (completed booking without review). |
MVP |
| SRS-EVT-012 |
Dashboard shows a vendor roster: every vendor with an accepted quote or booking on this event, with category, booking status and a message shortcut. |
MVP |
| SRS-EVT-013 |
All dashboard aggregates are denormalized counters updated by domain events (quotation status change, message received, payment captured) — no on-request table scans. |
MVP |
Rebook (duplicate) — MVP
| ID |
Requirement |
Phase |
| SRS-EVT-020 |
Customer can duplicate any past/archived event. Copied: type, name (suffixed " — نسخة" / " — copy"), city, venue status, guest count, budget, notes, and (Scale) checklist structure with all items reset to incomplete. Never copied: quotations, bookings, payments, messages, dates. |
MVP |
| SRS-EVT-021 |
The rebook flow offers "invite the same vendors": for each vendor booked on the source event who is still active and approved, pre-fill a new RFQ targeting them (customer confirms per vendor before anything is sent). |
MVP |
Planner suite — Scale
| ID |
Requirement |
Phase |
| SRS-EVT-030 |
Budget tracker: customer allocates budget_total across categories (venue, catering, photography…). Accepted quotes and bookings auto-post as committed amounts against their category; manual expense entries allowed. Dashboard shows allocated vs committed vs paid, with over-budget warning at ≥100% of a category allocation. |
Scale |
| SRS-EVT-031 |
Checklist: admin-managed checklist templates per event type with relative due dates (e.g. "book venue — 90 days before"). Instantiated on event creation (or on demand); items have title AR/EN, due date, done flag, optional linked category. Reminders via notification engine at due date −3 days and on due date. |
Scale |
| SRS-EVT-032 |
Guest list: guests with name, phone (optional), group/family, invited count (adults/children), status (invited, confirmed, declined, no_reply). Aggregate confirmed count feeds expected_guests suggestion. CSV import/export. |
Scale |
| SRS-EVT-033 |
Timeline / milestones: ordered milestones (title, datetime, linked booking optional). Event-day run sheet view. Vendor-linked milestones visible to that vendor. |
Scale |
| SRS-EVT-034 |
Document storage: per-event file area (contracts, mood boards, permits). Max 25 files/event, 20 MB/file, types: jpg, png, pdf, docx, xlsx. Stored on S3-compatible storage, private, signed URLs. |
Scale |
Vision
| ID |
Requirement |
Phase |
| SRS-EVT-040 |
Seating planner: drag-and-drop tables/seats bound to guest list entries. |
Vision |
| SRS-EVT-041 |
QR invitations: per-guest unique QR, digital invitation card AR/EN, check-in scan app for the event host. |
Vision |
| SRS-EVT-042 |
RSVP micro-site per event: guests confirm/decline via link, syncing guest list statuses without an app install. |
Vision |
Business rules
- An event belongs to exactly one customer account; there is no event sharing/co-planning in MVP (multi-planner collaboration is Vision).
- Deleting or archiving an event never deletes financial records — payments and invoices are immutable (see Payments).
budget_total is advisory only in MVP; it never blocks quote acceptance (soft warning only).
- Active-event limit: 20 active events per customer (abuse guard, admin-configurable).
- Event
city drives default vendor search filtering but never hard-blocks cross-city RFQs.
- All timestamps stored UTC, displayed Asia/Kuwait (UTC+3) at launch; timezone is a per-country platform setting for expansion.
Validation rules
| Field |
Rule |
name |
required, 2–100 chars, Arabic/English/digits, no URLs |
event_type |
required, must exist in event_types reference table and be active |
event_date |
optional; if set: today ≤ date ≤ today + 3 years |
city |
required, from cities reference table (country-scoped) |
venue_status |
required, one of the three enum values |
expected_guests |
optional, integer 1–100,000 |
budget_total |
optional, decimal(12,3), 0.000 < value ≤ 9,999,999.999 KWD |
notes |
optional, ≤ 2,000 chars |
Permissions matrix
| Action |
Customer (owner) |
Other customer |
Vendor |
Admin (support) |
Admin (super) |
| Create event |
✔ |
— |
✘ |
✘ |
✘ |
| View event full detail |
✔ |
✘ |
RFQ/booking context subset only |
✔ (read) |
✔ (read) |
| Edit / archive / rebook |
✔ |
✘ |
✘ |
✘ |
✘ |
| Delete (eligible) event |
✔ |
✘ |
✘ |
✘ |
✔ (GDPR-style removal request) |
| Manage checklist/guests/budget (Scale) |
✔ |
✘ |
✘ |
✘ |
✘ |
Vendor-visible subset per RFQ/booking: event type, date, city, guest count, and the RFQ description — never budget total, notes, other vendors, or guest list.
Status / state machine
stateDiagram-v2
[*] --> Active : customer creates event
Active --> Past : event_date + 1 day (system)
Active --> Archived : customer archives (no open RFQs/bookings)
Past --> Archived : customer archives
Archived --> Active : customer unarchives (date in future or null)
Active --> Deleted : customer deletes (no linked records, soft delete 30d)
Past --> [*]
Archived --> [*]
Edge cases
- Date passes with a booking still
pending: event moves to Past; pending bookings auto-cancel per SRS-BKG-016; customer and vendor are notified.
- No event date set: event never auto-moves to Past; a nudge notification fires 30 days after creation if still dateless with activity.
- Guest count changed after quotes received: existing quotes are untouched; customer is prompted to inform quoting vendors (one-tap message per conversation).
- Duplicate of an event whose vendors were suspended: suspended vendors are skipped in the rebook vendor list with an explanatory badge.
- Two devices editing simultaneously: last-write-wins with
updated_at optimistic check; stale write returns 409 and the client refetches.
Empty / loading / error states
| Surface |
Empty |
Loading |
Error |
| Events list |
Illustration + "أنشئ يمعتك الأولى" / "Create your first event" CTA |
Skeleton cards ×3 |
Retry banner, cached list if available |
| Event dashboard |
Per-widget empty hints ("No quotes yet — browse vendors") |
Per-widget skeletons; shell renders immediately |
Widget-level error with per-widget retry (one failing aggregate must not blank the page) |
| Rebook flow |
— |
Progress state on duplicate action |
On failure nothing is created (transaction), toast with retry |
Acceptance criteria
Data entities touched
events, event_types (reference), cities (reference), event_counters (denormalized aggregates), event_files (Scale), event_budget_lines (Scale), event_checklist_items + checklist_templates (Scale), event_guests (Scale), event_milestones (Scale). Foreign keys from quotation_requests, bookings, conversations, payments, reviews all reference events.id.
POST /api/v1/events
GET /api/v1/events?status=active|past|archived
GET /api/v1/events/{id}
PATCH /api/v1/events/{id}
DELETE /api/v1/events/{id}
POST /api/v1/events/{id}/archive
POST /api/v1/events/{id}/unarchive
POST /api/v1/events/{id}/duplicate
GET /api/v1/events/{id}/dashboard
GET /api/v1/events/{id}/vendors
# Scale
GET|POST|PATCH|DELETE /api/v1/events/{id}/budget-lines
GET|POST|PATCH|DELETE /api/v1/events/{id}/checklist-items
GET|POST|PATCH|DELETE /api/v1/events/{id}/guests
GET|POST|PATCH|DELETE /api/v1/events/{id}/milestones
GET|POST|DELETE /api/v1/events/{id}/files