e8aa0670ca
* feat(salary): agent path to set this month's per-run salary
Agents could not do variable owner pay: the only per-run edit tool,
gnubok_update_payslip_line, edits the display-only Grundlon line that
every recalculation rebuilds from salary_run_employees.monthly_salary,
so the fixed employee salary silently won (user-reported).
- lib/salary/run-employees.ts: setRunEmployeeSalary() shared service
(draft gate, roundOre, 0 = nollkorning, display-line refresh); the
cookie route PATCH now delegates to it (behavior unchanged)
- MCP: gnubok_set_run_salary staged tool (search catalog: tools/list
budget at zero headroom), op type set_run_salary (medium risk),
commitSetRunSalary executor, payroll:write scope, payroll_month
loadout + payroll-monthly skill step; update_payslip_line description
now warns that recalc rebuilds base salary lines
- v1 REST: PATCH /salary-runs/{id}/employees/{employeeId} accepting
monthly_salary (draft only, dry-run, idempotency key)
- Migration pair (NOT VALID + VALIDATE) adds set_run_salary to the
pending_operations op-type CHECK; base list verified against prod live
- Tests: service, staged tool, executor, cookie route, v1 route; spec
snapshot updated
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MP37pE3zk667nP6S766iJG
* fix(salary): harden set_run_salary per skeptic + CI findings
- Clear calculation_breakdown when the per-run salary changes so the
existing book preflights force a recalculation: a run can no longer
be booked with gross/tax derived from the old salary (skeptic R1)
- Enforce SALARY_OVERRIDE_MAX (10 MSEK) in the shared service and the
v1 body schema: closes the unbounded/1e307-overflow path that wrote
Infinity -> NULL -> 500 (skeptic R2)
- Promote gnubok_set_run_salary to the default catalog: a search-only
WRITE is uncallable on Claude.ai (update_customer lesson) while three
surfaces pointed agents at it; payload ceiling bumped 63.8K -> 64.4K
with a ledger entry, read-demotion left as its own change (skeptic R3)
- Granskning label type_set_run_salary in vocabulary.ts + sv/en (R4)
- Display-line refresh is fire-and-forget again (write already
committed; matches pre-refactor route behavior) and DB error details
carry the SQLSTATE code for Swedish error mapping
- v1 risk metadata aligned to 'medium'; NOT_DRAFT message now covers
salary edits, not just roster changes
- npm run apiskill:generate committed (CI apiskill:check failure)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MP37pE3zk667nP6S766iJG
* chore(migrations): rename set_run_salary pair past main's newest versions
origin/main gained 20260828120000 and 20260828154800 after this branch
staged 20260828110000/1; out-of-order versions are skipped at merge, so
the pair moves to 20260828160000/1 (byte-identical SQL, reference in the
VALIDATE header updated).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MP37pE3zk667nP6S766iJG
* chore: retrigger Supabase preview after migration-version repair
The preview branch tracked 20260828110000/1 before the rename to
20260828160000/1; the orphan rows are deleted from the preview branch's
schema_migrations (preview only, prod never saw those versions) and this
empty commit re-runs the tasks.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MP37pE3zk667nP6S766iJG
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
100 lines
3.3 KiB
SQL
100 lines
3.3 KiB
SQL
-- Add 'set_run_salary' to the pending_operations operation_type CHECK
|
|
-- constraint.
|
|
--
|
|
-- gnubok_set_run_salary (MCP) stages "set THIS run's base salary for one
|
|
-- employee" (salary_run_employees.monthly_salary, draft runs only; the
|
|
-- employee master's fixed salary is untouched). The user approves it in
|
|
-- Granskning and commitSetRunSalary in lib/pending-operations/commit.ts
|
|
-- writes the per-run value via lib/salary/run-employees.ts. This closes the
|
|
-- variable-owner-pay gap: agents previously could only edit the display-only
|
|
-- 'Grundlön' payslip line, which every recalculation rebuilds from this
|
|
-- column. Risk 'medium': draft-only, no booking impact until the run is
|
|
-- calculated and booked (both separately staged).
|
|
--
|
|
-- NOTE on the value list: this constraint is re-created wholesale (the
|
|
-- established pattern here), so the list below is every value of the
|
|
-- constraint as left by 20260825100000 PLUS the new value. Dropping any
|
|
-- existing value here would silently revoke it.
|
|
--
|
|
-- NOT VALID + separate VALIDATE migration (paired file, same pattern as
|
|
-- 20260825100000 / 20260825100001).
|
|
--
|
|
-- pg-test: tests/pg/pending-operations-op-type-audit.pg.test.ts asserts every
|
|
-- op type staged in server.ts or tiered in risk-tiers.ts is accepted here.
|
|
ALTER TABLE public.pending_operations
|
|
DROP CONSTRAINT IF EXISTS pending_operations_operation_type_check;
|
|
|
|
ALTER TABLE public.pending_operations
|
|
ADD CONSTRAINT pending_operations_operation_type_check
|
|
CHECK (operation_type IN (
|
|
'categorize_transaction',
|
|
'create_customer',
|
|
'create_invoice',
|
|
'mark_invoice_paid',
|
|
'send_invoice',
|
|
'mark_invoice_sent',
|
|
'match_transaction_invoice',
|
|
'close_period',
|
|
'lock_period',
|
|
'unlock_period',
|
|
'set_opening_balances',
|
|
'run_year_end',
|
|
'post_kontantmetod_cutoff',
|
|
'run_currency_revaluation',
|
|
'import_sie',
|
|
'explain_voucher_gap',
|
|
'uncategorize_transaction',
|
|
'approve_supplier_invoice',
|
|
'credit_supplier_invoice',
|
|
'credit_invoice',
|
|
'convert_invoice',
|
|
'create_transaction',
|
|
'attach_document_to_transaction',
|
|
'create_voucher',
|
|
'correct_entry',
|
|
'reverse_entry',
|
|
'create_supplier',
|
|
'create_supplier_invoice_from_inbox',
|
|
'post_annual_depreciation',
|
|
'link_invoice_voucher',
|
|
'undo_sie_import',
|
|
'match_batch_allocate',
|
|
'bulk_book_transactions',
|
|
'create_salary_run',
|
|
'generate_agi',
|
|
'link_transaction_journal_entry',
|
|
'link_supplier_invoice_voucher',
|
|
'submit_vat_declaration',
|
|
'submit_agi',
|
|
'create_article',
|
|
'update_article',
|
|
'bulk_book_inbox_items',
|
|
'create_dimension_value',
|
|
'retag_line_dimensions',
|
|
'link_document_to_voucher',
|
|
'update_payslip_line',
|
|
'set_run_salary',
|
|
'register_absence',
|
|
'create_employee',
|
|
'update_employee',
|
|
'set_employee_opening_balances',
|
|
'vacation_year_close',
|
|
'create_account',
|
|
'update_account',
|
|
'set_voucher_note',
|
|
'book_salary_run',
|
|
'delete_absence',
|
|
'update_company_settings',
|
|
'update_customer',
|
|
'update_invoice',
|
|
'create_recurring_schedule',
|
|
'update_recurring_schedule',
|
|
'log_mileage_trip',
|
|
'book_mileage_period',
|
|
'link_documents_to_vouchers',
|
|
'reconciliation_match',
|
|
'reconciliation_unmatch',
|
|
'reconciliation_signoff',
|
|
'reconciliation_residual'
|
|
)) NOT VALID;
|