# INVEETAIRE — AI Context Guide

> **Version:** v1.0.0  
> **Audience:** AI Assistants (Claude, ChatGPT, Gemini) and new developers  
> **Purpose:** Understand the INVEETAIRE business domain without reverse-engineering the codebase

---

## What is INVEETAIRE?

INVEETAIRE is a **wedding management SaaS platform** built in PHP. It enables wedding couples to:

1. Create and publish a **digital wedding invitation** with RSVP
2. Manage their **guest list** (names, groups, contact numbers)
3. Track **WhatsApp invitation delivery** to each guest
4. Run **day-of check-in operations** via QR scan
5. Manage **wedding budget**, **vendors**, and a **planning timeline**

The platform is multi-tenant: every couple gets their own isolated **Workspace**.

---

## The Three User Roles

| Role | Who | Access |
|------|-----|--------|
| **Super Admin** | Platform operators / developers | Full platform control: create workspaces, manage couples & crew, system config |
| **Couple** | The wedding couple | Full access to their own workspace — guests, invitation, budget, vendors, timeline |
| **Event Crew** | Wedding-day staff assigned by couple | Operational access only — check-in scanner, guest lookup, WhatsApp queue |

These roles are seeded in the `roles` table and cannot be deleted (`is_system = 1`).

---

## What is a Workspace?

A **Workspace** is the top-level container for one wedding. Think of it as a "project" or "account" owned by a couple.

- Every workspace has a `slug` (URL-safe identifier), couple names, wedding date, and event type
- A workspace progresses through lifecycle statuses: `provisioned → setup → active → live → post_event → archived → purged`
- All tenant data (guests, invitations, checkins, budget, vendors) belongs to exactly one workspace
- Workspaces are isolated — a user in workspace A can never access data in workspace B

**Who creates a workspace?** The Super Admin creates a workspace and assigns a Couple account to it.

---

## How Does a Couple Own a Workspace?

A `users` record with `role_id = 2` (couple) is linked to a workspace via `workspace_id`. The couple logs in and accesses only their workspace data.

A workspace can have exactly **one couple account** and **multiple crew accounts**.

---

## What is a Wedding Event?

Within a workspace, a **Wedding Event** (`wedding_events` table) represents one ceremony — e.g., *Akad Nikah*, *Holy Matrimony*, *Reception*. Most Indonesian weddings have 2–3 distinct ceremonies.

A workspace can have multiple wedding events. Each guest can be invited to specific events (via `guest_events`).

---

## How Are Guests Related to Weddings?

1. A **Guest** (`guests` table) belongs to a workspace
2. Each guest is assigned to one or more **Wedding Events** via `guest_events` (junction table)
3. Each guest has a unique `guest_code` (random token) — used in their personal invitation URL
4. Guests go through a lifecycle tracked by status fields:
   - `invitation_status`: `not_sent → sent → opened`
   - `rsvp_status`: `pending → attending → declined`
   - `checkin_status`: `not_arrived → checked_in → no_show`

---

## What is an Invitation?

Each workspace has **exactly one invitation** record. The invitation is the couple's digital wedding card.

- The couple selects a **Theme** (visual template) and customizes sections (hero, story, gallery, venue, RSVP, wishes, gift info)
- When the couple is ready, the invitation is **published** — each guest gets a unique URL: `/i/{workspace_slug}/{guest_code}`
- Guests can RSVP through the invitation (if RSVP is enabled)
- Guests can submit wishes to the couple's wish wall

The `invitation_sections` table stores per-section visibility and config (JSON) for the selected theme.

---

## What is Attendance?

On the wedding day, **Crew** members use a **QR scanner** to check in guests.

- Each guest's invitation has a QR code containing their `guest_code`
- Scanning creates a `checkins` record, recording: who scanned, which event, how many actual attendees, and whether they brought gift envelopes (angpao)
- The `label_print_jobs` table tracks requests to print label stickers (angpao labels, souvenir labels, VIP labels) at check-in
- A checkin can be flagged as a **correction** (re-check-in to fix a mistake)

---

## What is the Guest Timeline?

`guest_timelines` is an **append-only audit log** for each guest. Every significant event (invitation sent, opened, RSVP submitted, checked in, etc.) creates a new row. This allows the couple to see the full history of interactions with each guest.

---

## What Modules Exist?

### Operational Modules (used on/before the wedding day)

| Module | Purpose |
|--------|---------|
| **Guest Management** | Add, edit, import, filter guests |
| **Invitation Builder** | Design and publish the digital invitation |
| **WhatsApp Sending** | Compose and distribute invitation messages |
| **Check-in Scanner** | QR-based attendance at the event |
| **RSVP Tracking** | Monitor guest responses |

### Planning Modules (used weeks/months before)

| Module | Purpose |
|--------|---------|
| **Budget Planner** | Set total budget, categories, expenses, payments |
| **Vendor Manager** | Track vendors, quotations, and communications |
| **Timeline Planner** | Tasks organized into phases/milestones |

### Administrative Modules (Super Admin only)

| Module | Purpose |
|--------|---------|
| **Workspace Management** | Create and monitor workspaces |
| **Crew Management** | Create crew accounts and assign to workspaces |
| **System Configuration** | Platform-level feature flags |
| **Audit Logs** | Immutable event log for all platform actions |

---

## How Do Crew Interact with the System?

- **Crew accounts** are created by the Super Admin and assigned to a specific workspace
- Crew log in with a **username** (not email) and a password
- Inside the workspace, Crew see a limited sidebar — only: Check-in Scanner, Guest List, WhatsApp Queue
- Crew **cannot** access: invitation builder, budget, vendors, timeline, workspace settings
- Crew check-in actions are recorded in `checkins` with the crew member's `user_id` as `operator_id`

---

## Multi-Tenancy and Data Isolation

Every tenant table has a `workspace_id` column. The application's `WorkspaceMiddleware` enforces that the authenticated user can only access data matching their own `workspace_id`.

**Denormalized workspace_id**: Some child tables (e.g., `checkins`, `rsvps`, `guest_timelines`) also store `workspace_id` directly. This is intentional — it avoids JOINs in hot query paths and enables fast workspace-level isolation enforcement.

---

## Commercial Plans

Workspaces are assigned a **Commercial Plan** (`commercial_plans` table) which sets limits:
- `max_crew_accounts` — max crew members per workspace
- `max_guests` — max guests per workspace
- `max_gallery_images` — max gallery images per invitation
- `default_retention_days` — days active post-wedding before archiving
- `default_archive_days` — days archived before purging

---

## Key Technical Concepts

| Concept | Explanation |
|---------|-------------|
| `guest_code` | Opaque random token — unique per guest within workspace — used in URLs instead of internal `id` |
| `workspace_slug` | URL-safe workspace identifier — immutable after creation |
| `session_token` | Cryptographically random token stored in cookie — maps to `sessions` table row |
| `role_snapshot` | The role at login time, stored in `sessions` — avoids querying `roles` on every request |
| Soft delete | `is_deleted = 1` + `deleted_at` timestamp — record is hidden but preserved for audit |
| `audit_logs` | Uses soft (non-enforced) foreign keys so logs survive actor/entity deletion |

---

## What Does NOT Exist Yet (Future Sprints)

| Feature | Sprint |
|---------|--------|
| Supabase database mirror | DX002 |
| Schema synchronization | DX002 |
| System health monitoring | DX003 |
| Log browser | DX003 |
| Queue management UI | DX003 |
| WhatsApp API integration (automatic delivery) | Future |
| Email notification system | Future |
| Payment gateway integration | Future |
