145 lines
4.1 KiB
Markdown
145 lines
4.1 KiB
Markdown
# 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.
|