Files
accounted/supabase/migrations/20260702220000_employees_default_dimensions.sql
T
Jakob WennbergandClaude Fable 5 163fbd8222 feat(dimensions): PR8 salary — employees.default_dimensions, per-employee cost lines, aggregation re-key (#869)
Employees carry a default dimensions bag and the salary booking puts each
employee's cost on their kostnadsställe/projekt
(dev_docs/dimensions_implementation_plan.md PR8):

- employees.default_dimensions (migration 20260702220000; jsonb DEFAULT
  '{}' + object CHECK)
- salary-entries: the one-line-per-account aggregation is re-keyed to
  account+bag — P&L cost lines (löner incl. line items + base remainder,
  arbetsgivaravgifter, semesteravsättning + dess avgifter, pension, SLP)
  split per employee bag while every balance-sheet/settlement leg (2710,
  1930, 2731, 29xx, 2740, 2514) stays aggregated; liability credits equal
  the sum of the rounded debit buckets so entries balance by construction;
  dimension-less runs book byte-identically to before. Replaces the dead
  SalaryRunEmployee.cost_center/project pair (never wired)
- both book routes (dashboard + v1) read the bag via the employees join —
  read-at-book, so the run review shows exactly what will book
- employee form (new + edit) gets a gated Kostnadsställe/Projekt card;
  run review shows per-employee dims chips; run GET + v1 employee
  routes/schemas + MCP list_employees carry the field
- pre-merge audit: all salary reports (salary-journal, AGI,
  avgifter-basis, vacation-liability) read salary_run_employees — not
  journal lines — and every ledger consumer sums per account, so the
  line split breaks nothing; SIE export + dimension P&L pick the split
  up as intended

8 new engine propagation tests + book-route dims flow test.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 22:21:46 +02:00

28 lines
1.4 KiB
SQL

-- Dimensions PR8 (salary): employees carry a default dimension bag so the
-- salary booking can put each employee's cost on their kostnadsställe/projekt.
--
-- employees.default_dimensions {sie_dim_no: code}, e.g. {"1":"KS01"}
--
-- Read at book time by both salary book routes (dashboard + v1) and merged
-- onto the P&L cost lines of the salary/avgifter/semester/pension entries;
-- balance-sheet legs (2710, 1930, 2731, 29xx, 2740, 2514) stay aggregated.
-- Same shape + CHECK as journal_entry_lines.dimensions (20260702084500) and
-- the PR7 producer columns (20260702200000). NOT NULL DEFAULT '{}' is
-- metadata-only on PG11+ (no rewrite). No index: read via the employee row
-- when booking, never containment-queried.
--
-- pg-test: covered-by — plain column add with a type CHECK, no
-- trigger/RPC/RLS/DEFERRABLE change. Propagation logic is TS-side
-- (lib/salary/salary-entries.ts unit tests).
ALTER TABLE public.employees
ADD COLUMN default_dimensions jsonb NOT NULL DEFAULT '{}'::jsonb;
ALTER TABLE public.employees
ADD CONSTRAINT employees_default_dimensions_is_object
CHECK (jsonb_typeof(default_dimensions) = 'object');
COMMENT ON COLUMN public.employees.default_dimensions IS
'Dimension bag {sie_dim_no: code} applied to the employee''s P&L cost lines when a salary run is booked. See lib/salary/salary-entries.ts.';
NOTIFY pgrst, 'reload schema';