Rework balances around per-parent days left and deduce the partner from FK
Manual entry now takes one parent's sjukpenningnivå, lägstanivå and dubbeldagar left (plus optional reserved days) and derives the rest in build_snapshot, shared with the scraper. The scraper also reads the family panel and exposes a partner deduction; with two parents it is saved as a 'deduced' snapshot (migration 002). Parent count is the single source of entitlement: one member gets 480 days and 96 savable at age 4, two get 240 and 48 each. Workspaces are capped at two parents. Also lands the in-flight squash of migrations 002–011 into the initial schema and the removal of planning_mode. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -3,10 +3,12 @@
|
||||
A planner for Swedish parental leave (föräldraledighet) — solo or with a
|
||||
partner — that folds in vacation days and optimizes leave over time so that
|
||||
as few days as possible are lost at the child's 4th birthday, after which
|
||||
only 96 days may be saved (48 per parent, in couple mode).
|
||||
only 96 days may be saved (48 per parent, non-poolable, as soon as the child
|
||||
has two or more parents).
|
||||
|
||||
Full-stack monorepo: TypeScript/React/Vite frontend, Python/FastAPI backend,
|
||||
SQLite by default (Postgres as an optional extra).
|
||||
SQLite by default. Postgres is a partial stub, not a usable swap yet — see
|
||||
`backend/README.md`.
|
||||
|
||||
## Quick start
|
||||
|
||||
@@ -52,9 +54,11 @@ Three tabs:
|
||||
per-parent bars against each parent's savable cap, a year-by-year
|
||||
timeline, and shortfall/surplus detail below the fold.
|
||||
- **Kalender** — where leave is authored. Drag a range to create a period,
|
||||
click a band to edit it, click a day to change how it's funded or mark it
|
||||
worked/off. A season-preset rail helps place common periods (summer,
|
||||
Christmas, Easter).
|
||||
click a band to edit it, click a day to change which resource funds it
|
||||
(sjukpenning/lägstanivå/vacation). A season-preset rail helps place common
|
||||
periods (summer, Christmas, Easter). Day overrides (marking a specific date
|
||||
as a working day or a free day, overriding the calendar) live in
|
||||
Inställningar, not on the calendar itself.
|
||||
- **Inställningar**.
|
||||
|
||||
**The calendar is the plan.** There's no separate propose-then-apply step:
|
||||
@@ -63,8 +67,9 @@ an undo. A `LeaveWish` is a recurring intent (e.g. "summer", "Christmas");
|
||||
the allocator decides which resource — parental days, vacation, unpaid —
|
||||
funds each day, without retyping days a user has pinned by hand.
|
||||
|
||||
First run walks a wizard: add the child, choose solo or couple planning
|
||||
(optionally add a partner), then set balances — fetch from
|
||||
First run walks a wizard: add the child, optionally add a partner (planning
|
||||
solo vs. together is derived from whether a partner has been added — there
|
||||
is no separate solo/couple choice), then set balances — fetch from
|
||||
Försäkringskassan via BankID, enter manually, or skip (figures are then
|
||||
marked as estimates).
|
||||
|
||||
@@ -75,7 +80,7 @@ backend/app/
|
||||
entities/ persistence-layer row shapes
|
||||
models/ Pydantic v2 API schemas
|
||||
repositories/ abstract repository interfaces
|
||||
repositories_impl/ sqlite/ (default) and postgres/ (optional) impls
|
||||
repositories_impl/ sqlite/ (default, complete) and postgres/ (partial — one entity only)
|
||||
services/ business logic — planning, tips, analytics, auth
|
||||
scrapers/ Försäkringskassan scraper (Playwright)
|
||||
routers/ thin FastAPI route handlers
|
||||
@@ -113,11 +118,10 @@ npm run lint # ESLint, zero warnings allowed
|
||||
npm run coverage # Vitest, thresholds: lines 96% / functions 91% / branches 92% / statements 96%
|
||||
```
|
||||
|
||||
Current numbers: backend 587 tests passing at ~87% coverage (gate: 80%);
|
||||
frontend 949 tests across 62 files passing at ~99% lines/statements, ~93%
|
||||
functions, ~95% branches (gates: 96/91/92/96 — see
|
||||
`frontend/vitest.config.ts`). Gates are a regression ratchet, not a target —
|
||||
they sit a couple of points below the measured baseline.
|
||||
Both suites pass comfortably above their gates (backend ~84% vs. an 80%
|
||||
floor; frontend above 96/91/92/96 — see `frontend/vitest.config.ts`). Gates
|
||||
are a regression ratchet, not a target; run the commands above for current
|
||||
numbers rather than trusting a hardcoded count here, which drifts fast.
|
||||
|
||||
CI (`.github/workflows/ci.yml`) runs all of the above, plus a Playwright E2E
|
||||
suite that reports but does not yet block merges.
|
||||
|
||||
Reference in New Issue
Block a user