# Data Schema Requirements

## Purpose
Define concrete schema requirements for events, recurrence exceptions, CalDAV metadata, and user-access lifecycle state.

## Scope
This document covers:

- Required tables/entities and key fields
- Indexing and uniqueness rules
- Migration/versioning expectations
- Data integrity constraints

## Schema Baseline
- All plugin tables must use WordPress prefix (`$wpdb->prefix`).
- Schema creation/migration uses WordPress mechanisms (`dbDelta`, controlled migrations).
- Charset/collation should follow WordPress defaults.

## Required Logical Entities

### Events
Required fields:
- `id` (PK)
- `uid` (stable iCalendar UID)
- `visibility` (`public`, `private`; default `public`)
- `title`
- `description`
- `location`
- `category`
- `all_day_event`
- `start_datetime`
- `end_datetime`
- `repeat_type`
- `repeat_interval`
- `repeat_range_mode`
- `repeat_count` (nullable)
- `repeat_until` (nullable)
- `timezone` (default `Europe/London`)
- `created_at`
- `updated_at`

Constraints:
- `title`, `start_datetime` required
- `end_datetime >= start_datetime`
- recurrence fields internally consistent
- `visibility` must be one of the supported enum values

Privacy semantics:
- `private` events are stored with full details.
- Public-facing renderers (public ICS/public calendar/sidebar) must apply redaction rules at read time, not by destructively altering stored event data.

### Recurrence Exceptions
Required fields:
- `id` (PK)
- `event_id` (FK -> events.id)
- `occurrence_key` (canonical occurrence datetime key)
- `exception_type` (`deleted_occurrence`, `override_occurrence`)
- `override_payload` (nullable structured data for modified occurrence)
- `created_at`
- `updated_at`

Constraints:
- unique (`event_id`, `occurrence_key`)
- deleted-occurrence exception must suppress that one occurrence without splitting series

### CalDAV Objects
Required fields:
- `id` (PK)
- `event_id` (FK -> events.id)
- `calendar_id`
- `resource_path`
- `etag`
- `sync_version` or equivalent change sequence
- `last_modified_by_user_id` (FK -> caldav_users.id, nullable)
- `created_at`
- `updated_at`

Constraints:
- unique (`calendar_id`, `resource_path`)
- unique `etag` progression by object version

### CalDAV Users
Required fields:
- `id` (PK)
- `email` (unique)
- `password_hash`
- `email_verified_at` (nullable)
- `account_status` (`pending_approval`, `active`)
- `access_level` (implementation detail; approved users are write-enabled)
- `request_state` (implementation detail; tracks approval pipeline when present)
- `created_at`
- `updated_at`

### User Tokens
Required fields:
- `id` (PK)
- `user_id` (FK -> caldav_users.id)
- `token_type` (`verify_email`, `reset_password`)
- `token_hash`
- `expires_at`
- `used_at` (nullable)
- `created_at`

Constraints:
- tokens are single-use
- expired/used tokens are invalid

### Audit Log
Required fields:
- `id` (PK)
- `actor_type` (`wp_user`, `caldav_user`, `system`)
- `actor_id`
- `action`
- `target_type`
- `target_id`
- `result` (`success`, `failure`)
- `context_json`
- `created_at`

## Indexing Requirements
- Events index on `start_datetime`, `end_datetime`
- Events unique index on `uid` where logical uniqueness is required
- Exceptions index on `event_id`
- CalDAV objects index on `calendar_id`, `resource_path`, `etag`
- Users unique index on `email`
- Tokens index on `user_id`, `token_type`, `expires_at`
- Audit log index on `created_at`, `actor_id`, `action`

## Migration and Versioning
- Schema version must be stored in plugin options.
- Upgrades must be incremental, idempotent, and logged.
- Downgrade strategy must be documented; if unsupported, explicit warning required.

## Data Retention
- Behavior on uninstall follows lifecycle requirements.
- If removal is selected, plugin-owned tables and options are removed safely.
- If retention is selected, schema/data remains for future reactivation.

## Verification Requirements
Acceptance should verify:

- Fresh install creates expected schema.
- Upgrade applies required structural changes without data loss.
- Constraints enforce recurrence exception uniqueness and no split-series artifacts.
