7411a0171b
* feat(mileage): körjournal with milersättning booking, MCP tools and CSV export New mileage_trips table (RLS, booked-delete trigger per BFL retention), lib/mileage service reusing the payroll schablon rates, /api/mileage routes (trips CRUD, period booking to 7331, salary-run push, körjournal CSV), Körjournal dashboard page + nav, and three staged MCP tools (search-only catalog). Trips book as one verifikat per period via the engine; salary path inserts mileage_taxfree line items. mileage_trips classified in the full-archive export. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * refactor(mileage): use shared roundOre helper per tightened ratchet baseline Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(mileage): pending_operations op-type migration + Swedish review findings - New migration pair adds log_mileage_trip/book_mileage_period to the pending_operations operation_type CHECK (pg-real audit). - bookMileagePeriod refuses a period spanning several employees and names the employee in the verifikationstext when scoped (BFL motpart). - vehicle_registration required for förmånsbil trips (schema, service, MCP staging, UI surfaces the field). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(mileage): claim-first booking, CSV injection guard and driver column - bookMileagePeriod claims trips (draft to booked CAS) before creating the verifikat, so a concurrent second booking loses the race instead of double-booking; claim reverts if verifikat creation fails. - Körjournal CSV neutralizes formula-injection triggers (OWASP) and adds a Förare column naming the employee per trip. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(mileage): resolve CodeRabbit + Swedish review round: race, drift and hardening - Copying a round trip no longer re-doubles the stored distance. - pushMileageToSalaryRun claims trips before inserting line items (retry can no longer double-pay); CLAIM_LOST replaces misleading NO_TRIPS on lost races. - Booked trips are DB-immutable via a BEFORE UPDATE trigger (new migration 20260807113215): only claim/link/revert transitions and notes edits pass. - Cross-year periods rejected (schablon rates are per calendar year); payroll config year read from the date string, not TZ-dependent getFullYear(). - MCP staged bookings freeze the previewed trip set (trip_ids in params) and the commit fails on drift; validation errors return 400, not 500. - PATCH enforces the förmånsbil regnr rule on the effective row; export validates dates before they reach the Content-Disposition header; employee_id is verified company-scoped on trip creation; stale orphaned claims released. - UI: fetch flags reset in finally; ICU plural for draft summary; distance stored at the column's 1-decimal precision. - Tests: [id] route suite, pushMileageToSalaryRun suite, claim-race, drift, cross-year and update-trigger pg cases. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(mileage): revert-to-draft must clear salary_run_id at the trigger level New migration 20260807114924 replaces the booked-immutability function: a booked -> draft revert now rejects rows keeping salary_run_id, closing the DB-level double-pay path CodeRabbit flagged. pg test pins both directions; the CLAIM_LOST unit test now asserts the revert. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(mileage): company-scope employee_id on PATCH (Superagent P2) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(mileage): valid v4 uuid in cross-company employee PATCH test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
78 lines
2.2 KiB
SQL
78 lines
2.2 KiB
SQL
-- Add log_mileage_trip and book_mileage_period to the pending_operations
|
|
-- operation type CHECK (korjournal MCP tools, PR #1448).
|
|
--
|
|
-- NOTE on the value list: this constraint is re-created wholesale, so the list
|
|
-- below is every value from 20260727110000 PLUS the two new mileage values.
|
|
|
|
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',
|
|
'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',
|
|
'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'
|
|
)) NOT VALID;
|
|
|
|
NOTIFY pgrst, 'reload schema';
|