# Schedules Pivot Guardrails ## Purpose - Replace "recurring entries" with first-class "schedules". - Keep entry creation separate from schedule templates. - Preserve compatibility during migration. ## Terminology - Use `Schedule` and `Schedules` in new UI and API surfaces. - Legacy `/api/recurring-entries` remains compatibility-only and is deprecated. ## Data Model Rules - `entries` are real posted records. - `schedules` are templates that can materialize future entries. - `entries.source_schedule_id` links posted entries created by schedule execution. - Legacy recurring flags on `entries` are normalized to non-recurring in migration. ## Compatibility Window - Canonical routes: - `GET/POST /api/schedules` - `PATCH/DELETE /api/schedules/[id]` - Compatibility routes (deprecated): - `GET/POST /api/recurring-entries` - `PATCH/DELETE /api/recurring-entries/[id]` ## Frequency Contract - Allowed frequencies: - `DAILY` - `WEEKLY` - `MONTHLY` - `YEARLY` - Legacy `BIWEEKLY` and `QUARTERLY` values are mapped during migration: - `BIWEEKLY` -> `WEEKLY` with interval doubled - `QUARTERLY` -> `MONTHLY` with interval tripled ## Scheduler Service - Runs as separate workspace app: `apps/scheduler`. - Uses UTC schedule evaluation. - Uses `FOR UPDATE SKIP LOCKED` and unique index on `(source_schedule_id, occurred_at)` for idempotency. - Must not log secrets or sensitive payloads. ## User Settings - User-level page size stored in `user_settings.data.entryPanelPageSize`. - Default is `10`. - Applied to Entries and Schedules tab "Show more" increments.