# `workspaces` — Wedding Workspace (Tenant Root)

**Module:** Workspace  
**Type:** Tenant Root  
**Soft Delete:** No (lifecycle via `workspace_status`)

---

## Purpose

The central entity of the INVEETAIRE multi-tenant architecture. Each workspace represents one wedding. All tenant-scoped data is anchored to a `workspace_id` from this table.

---

## Columns

| Column | Type | Nullable | Default | Description |
|--------|------|----------|---------|-------------|
| `id` | `BIGINT UNSIGNED AUTO_INCREMENT` | No | — | Internal surrogate key |
| `slug` | `VARCHAR(60)` | No | — | URL-safe public identifier. Immutable after creation |
| `groom_name` | `VARCHAR(100)` | No | — | Groom display name |
| `bride_name` | `VARCHAR(100)` | No | — | Bride display name |
| `wedding_date` | `DATE` | No | — | Primary event date. Governs phase transitions |
| `event_type_id` | `TINYINT UNSIGNED` | No | — | → `event_types.id`. Immutable after creation |
| `commercial_plan_id` | `TINYINT UNSIGNED` | No | — | → `commercial_plans.id` |
| `custom_guest_limit` | `SMALLINT UNSIGNED` | Yes | NULL | Configurable guest limit for Custom plan |
| `workspace_status` | `VARCHAR(20)` | No | `provisioned` | `provisioned \| setup \| active \| live \| post_event \| archived \| purged` |
| `created_by` | `BIGINT UNSIGNED` | Yes | — | → `users.id` (Super Admin who provisioned) |
| `created_at` | `DATETIME` | No | `CURRENT_TIMESTAMP` | Creation timestamp |
| `updated_at` | `DATETIME` | Yes | NULL | Last modification |
| `activated_at` | `DATETIME` | Yes | NULL | First invitation sent timestamp |
| `wedding_day_at` | `DATETIME` | Yes | NULL | Timestamp workspace entered Live phase |
| `archived_at` | `DATETIME` | Yes | NULL | Timestamp workspace was archived |
| `purged_at` | `DATETIME` | Yes | NULL | Timestamp workspace was purged |

---

## Primary Key

`id` — `BIGINT UNSIGNED`

---

## Indexes

| Name | Columns | Type |
|------|---------|------|
| `PRIMARY` | `id` | Primary |
| `uq_workspaces_slug` | `slug` | Unique |
| `idx_workspaces_status` | `workspace_status` | Index |
| `idx_workspaces_wedding_date` | `wedding_date` | Index |

---

## Foreign Keys

| Column | References | On Delete | On Update |
|--------|-----------|-----------|-----------|
| `event_type_id` | `event_types.id` | RESTRICT | CASCADE |
| `commercial_plan_id` | `commercial_plans.id` | RESTRICT | CASCADE |
| `created_by` | `users.id` | SET NULL | CASCADE |

---

## Referenced By (cascading children)

| Table | Column |
|-------|--------|
| `users` | `workspace_id` |
| `retention_policies` | `workspace_id` |
| `invitations` | `workspace_id` |
| `wedding_events` | `workspace_id` |
| `guests` | `workspace_id` |
| `checkins` | `workspace_id` |
| `message_templates` | `workspace_id` |
| `media_files` | `workspace_id` |
| `budget_settings` | `workspace_id` |
| `timeline_phases` | `workspace_id` |
| `vendor_categories` | `workspace_id` |
| `notifications` | `workspace_id` |
| *(+ 20 more cascade children)* | `workspace_id` |

---

## Workspace Status Lifecycle

```
provisioned → setup → active → live → post_event → archived → purged
```

| Status | Meaning |
|--------|---------|
| `provisioned` | Workspace created by Super Admin, couple not yet setup |
| `setup` | Couple is configuring invitation and guest list |
| `active` | Invitation published, RSVPs being collected |
| `live` | Wedding day — check-in operations active |
| `post_event` | Event over, data in retention period |
| `archived` | Data archived, read-only |
| `purged` | Data deleted per retention policy |

---

## Business Rules

- `slug` is immutable after creation (used in invitation URLs)
- `wedding_date` determines automated phase transitions
- Deleting a workspace cascades to ALL tenant data
- `custom_guest_limit` overrides the plan limit for special arrangements

---

## Notes

- The `created_by` FK is deferred (resolved after `users` table creation due to circular dependency)
- Public invitation URLs use `slug`, not `id`
