# 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.