feat(api): ROT/RUT, articles, and project lifecycle on the v1 API (#904)

* feat(api): ROT/RUT + articles + dimensions on the v1 invoice surface (#895)

- v1 invoice POST now routes through buildInvoiceWriteData, the same
  builder as the dashboard: ROT/RUT deduction lines (server-side compute,
  personnummer encryption), article_id + revenue_account linkage,
  accruals, and line_type no longer get silently dropped on the wire.
- v1 invoice PATCH accepts default_dimensions so integrations can tag a
  draft with a project/cost centre after creation.
- New PATCH/DELETE /dimensions/:id/values/:valueId: rename, archive,
  set end_date on project codes; delete unreferenced values (409 with an
  archive hint when the BFL retention trigger blocks).
- New GET /articles: read-only artikelregister list (incl. housework_type)
  so callers can resolve article_id before composing invoice lines.
- Invoice GET/POST projections now expose deduction fields and full item
  columns; dry-run previews never echo the encrypted personnummer.

Closes #895

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* refactor(api): address review on #904

- Extract shared v1 invoice projections to lib/api/v1/invoice-columns.ts
  so create/detail/patch responses can't drift; PATCH now returns
  deduction_total + deduction_personnummer_last4 like GET/POST.
- Narrow the v1 create customer fetch back to the three fields the
  builder reads instead of select('*').

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-07-06 15:21:53 +02:00
committed by GitHub
co-authored by Claude Opus 4.7
parent 31b244acf5
commit cdac1808c9
12 changed files with 1311 additions and 148 deletions
+9
View File
@@ -186,6 +186,15 @@ export const V1_ENDPOINT_SCOPES: Record<string, ApiKeyScope> = {
// is bookkeeping:write (it mints codes that journal lines reference).
'GET /api/v1/companies/:companyId/dimensions': 'reports:read',
'POST /api/v1/companies/:companyId/dimensions/:id/values': 'bookkeeping:write',
// Value lifecycle (#895): rename/archive/end-date via PATCH; DELETE only
// succeeds for unreferenced values (BFL retention trigger guards the rest).
'PATCH /api/v1/companies/:companyId/dimensions/:id/values/:valueId': 'bookkeeping:write',
'DELETE /api/v1/companies/:companyId/dimensions/:id/values/:valueId': 'bookkeeping:write',
// Articles (artikelregister, #895): read-only list so invoice items can
// link article_id / copy housework_type + revenue_account. Rides
// invoices:read (the register exists to serve invoicing).
'GET /api/v1/companies/:companyId/articles': 'invoices:read',
// Webhooks (Phase 6 PR-1)
'GET /api/v1/companies/:companyId/webhooks': 'webhooks:manage',