Complete NextSteps roadmap: planning engine UI, calendar cluster, flexible wishes
Works through every numbered item in NextSteps260913.md section 3, plus the three known verification issues in section 4.1. Surface what the backend already computed: - 3.1 render surplus_advice in PlanResults, mirroring the shortfall remedies - 3.2 surface VacationBalance.is_assumed so assumed statutory years are visible - 3.3 age-4 expiry given the proposed plan, via a new Age4Projection reusing the existing _age4_projections arithmetic (Dashboard stat verified, not rebuilt) Calendar cluster (one pass over the holiday data): - new GET /api/calendar/days exposing roda dagar, klamdagar and day overrides, paginated four years at a time - 3.4 shade roda dagar/klamdagar, with R/K badges so colour is not the only signal - 3.6 click-to-override behind an explicit mode toggle, leaving drag multi-select intact - 3.7 click month/year to advance - 3.8 per-year red-days list in Settings, statutory days plus overrides i18n: - 3.5 five backend-generated Swedish surfaces converted to message_key + data, following the tips_service pattern; old string fields replaced, not kept Flexible wishes (3.9): - PLANNING_ENGINE_SPEC section 10: window_mode, candidate search, cost function, deterministic tie-break, two-pass ordering, test matrix rows 15-24 - backend: entity, migration 006, _FULL_SCHEMA sync, repository, allocator - frontend: season-preset toggle in WishEditor, unplaced outcome rendering Fixes (4.1): - pin typecheck to the local tsc rather than npx resolving a newer TypeScript - ignore generated coverage/ and dist/ in the ESLint flat config - fix the flaky usePlanApply test properly, with waitFor rather than a retry Tests: backend 361 -> 404, frontend 540 -> 704. Coverage 89.47% -> 96.52% lines. Not yet verified in a browser. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RXMhc9nT6sNz1SL4j8dznL
This commit is contained in:
@@ -13,13 +13,16 @@ from __future__ import annotations
|
||||
import aiosqlite
|
||||
|
||||
# Full schema used by test fixtures directly (avoids a full Alembic run in tests).
|
||||
# This MUST stay in sync with migrations/versions/001_initial_schema.py.
|
||||
# This MUST stay in sync with the migration chain (migrations/versions/*.py),
|
||||
# i.e. it always reflects the state after the latest migration, not just 001.
|
||||
_FULL_SCHEMA = """
|
||||
CREATE TABLE IF NOT EXISTS workspace (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
planning_goal TEXT NOT NULL DEFAULT 'balanced'
|
||||
CHECK (planning_goal IN ('max_time','max_money','balanced')),
|
||||
planning_mode TEXT NOT NULL DEFAULT 'solo'
|
||||
CHECK (planning_mode IN ('solo','couple')),
|
||||
created_at TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
@@ -31,6 +34,8 @@ CREATE TABLE IF NOT EXISTS personal_data (
|
||||
CHECK (salary_type IN ('monthly','hourly')),
|
||||
employment_status TEXT NOT NULL DEFAULT 'employed'
|
||||
CHECK (employment_status IN ('employed','jobseeking','none')),
|
||||
min_vacation_days_per_year INTEGER NOT NULL DEFAULT 20
|
||||
CHECK (min_vacation_days_per_year >= 0 AND min_vacation_days_per_year <= 60),
|
||||
personnummer_enc TEXT,
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
deleted_at TIMESTAMP,
|
||||
@@ -65,20 +70,43 @@ CREATE TABLE IF NOT EXISTS child (
|
||||
name TEXT NOT NULL,
|
||||
birth_date DATE NOT NULL,
|
||||
preschool_start_date DATE,
|
||||
preschool_planning_days_per_year INTEGER NOT NULL DEFAULT 6
|
||||
CHECK (preschool_planning_days_per_year >= 0 AND preschool_planning_days_per_year <= 30),
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
FOREIGN KEY (workspace_id) REFERENCES workspace(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS break_period (
|
||||
CREATE TABLE IF NOT EXISTS leave_wish (
|
||||
id TEXT PRIMARY KEY,
|
||||
workspace_id TEXT NOT NULL,
|
||||
child_id TEXT,
|
||||
name TEXT NOT NULL,
|
||||
start_date DATE NOT NULL,
|
||||
end_date DATE NOT NULL,
|
||||
window_start_month INTEGER NOT NULL DEFAULT 1
|
||||
CHECK (window_start_month >= 1 AND window_start_month <= 12),
|
||||
window_start_day INTEGER NOT NULL DEFAULT 1
|
||||
CHECK (window_start_day >= 1 AND window_start_day <= 31),
|
||||
window_end_month INTEGER NOT NULL DEFAULT 1
|
||||
CHECK (window_end_month >= 1 AND window_end_month <= 12),
|
||||
window_end_day INTEGER NOT NULL DEFAULT 1
|
||||
CHECK (window_end_day >= 1 AND window_end_day <= 31),
|
||||
target_weeks INTEGER NOT NULL,
|
||||
recurrence TEXT NOT NULL DEFAULT 'once'
|
||||
CHECK (recurrence IN ('yearly','once')),
|
||||
first_year INTEGER NOT NULL DEFAULT 2026,
|
||||
last_year INTEGER,
|
||||
priority INTEGER NOT NULL DEFAULT 1 CHECK (priority >= 1),
|
||||
parent_mode TEXT NOT NULL DEFAULT 'either'
|
||||
CHECK (parent_mode IN ('either','both','specific')),
|
||||
parent_personal_data_uuid TEXT,
|
||||
goal_override TEXT
|
||||
CHECK (goal_override IS NULL OR goal_override IN ('max_time','max_money','balanced')),
|
||||
window_mode TEXT NOT NULL DEFAULT 'fixed'
|
||||
CHECK (window_mode IN ('fixed','flexible')),
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP NOT NULL,
|
||||
FOREIGN KEY (workspace_id) REFERENCES workspace(id) ON DELETE CASCADE
|
||||
FOREIGN KEY (workspace_id) REFERENCES workspace(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (child_id) REFERENCES child(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (parent_personal_data_uuid) REFERENCES personal_data(uuid) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS parental_leave_fetch (
|
||||
@@ -132,6 +160,18 @@ CREATE TABLE IF NOT EXISTS planned_leave_day (
|
||||
FOREIGN KEY (child_id) REFERENCES child(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (parent_personal_data_uuid) REFERENCES personal_data(uuid) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS day_override (
|
||||
id TEXT PRIMARY KEY,
|
||||
workspace_id TEXT NOT NULL,
|
||||
date DATE NOT NULL,
|
||||
is_working_day INTEGER NOT NULL,
|
||||
note TEXT,
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP NOT NULL,
|
||||
UNIQUE(workspace_id, date),
|
||||
FOREIGN KEY (workspace_id) REFERENCES workspace(id) ON DELETE CASCADE
|
||||
);
|
||||
"""
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user