c0ecf2fa3bebd46bdfd0169efd73b89653d1dfed
15
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f266c386f3 |
chore: repo-wide bloat sweep, remove dead code and fold duplicate helpers (#2150)
* chore: repo-wide bloat sweep, remove dead code and fold duplicate helpers Remove 33 dead files, ~270 unreferenced exports/types, 13 dead i18n namespaces and 4 unused dependencies; fold byte-identical helper copies into one canonical home each (lib/utils chunk/sleep/utcDateStamp, lib/dates/iso, lib/invariants/uuid, lib/xml/escape, lib/reports/sru/format, lib/pdf/number-text, lib/browser/panel-request, lib/api/v1/body + v1ValidationError rolled out to ~55 v1 routes, booking-template schemas). No behaviour change: v1 bodies and status codes, MCP tool schemas, DB writes and money math are untouched. Naive ore rounding was deliberately not swapped for roundOre; see DECISIONS.md 2026-09-02 for the full list of things left alone on purpose. tsc, lint, 19588 unit tests and check:guards green; antipattern baseline ratcheted (naive-ore-round 622 -> 620, hand-rolled-invariant 115 -> 113). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(transactions): import RawTransaction from @/types after the ingest re-export removal CI's type ratchet (check:types, full tsconfig) caught the one test file that still imported the type through lib/transactions/ingest. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
9ce1ebc65f |
feat(reports): bokslutsbilagor, the pärm per räkenskapsår (Reko bilagor, PR 4) (#1874)
* feat(reports): bokslutsbilagor, the pärm per räkenskapsår (Reko bilagor, PR 4) One bilaga per balance account as of the balansdag: IB, movement and UB from the trial balance, what it was reconciled against, the difference, the sign-off with who, when and note, and every attached file with its SHA-256; the closing checklist as the first page. JSON and PDF through /api/reports/bokslutsbilagor, in the reports library and on the Avstämning page, and written into every period folder of the full archive. Built from the attested rows, never by recomputing live status. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RvFveUpbdPBXdm7f5FEYoz * fix(reports): load the pärm renderer on demand in the full archive so PDF stubs elsewhere keep working Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RvFveUpbdPBXdm7f5FEYoz * fix(reconciliation): neutral rail dot for a manual account that is merely not attested yet An unsigned manual account without a system specification has nothing to compare against, so an amber dot read as a problem on every balance account of a freshly migrated company. Neutral until it is signed or a specification differs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RvFveUpbdPBXdm7f5FEYoz --------- Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
9ebb2e518f |
feat(reconciliation): absorb the last bank-view tools and retire /reports/bank-reconciliation (#1871)
The old Bankavstämning report page was the only place a user could still tag a bank row as ingående balans or move it to another bank account, so the new /reconciliation page kept linking out to it and the reconciliation lived in two places. Both row tools now live on the account overview (hover-revealed, same endpoints), the ?autorun=1 deep link from the transactions inbox runs the matcher on the new page, and the report slug redirects: old links, ⌘K, the bokslut readiness wizard and the ignore toast all land on /reconciliation. BankReconciliationView and its FocusedReport branches (own range preset, help popover, autoRun plumbing) are removed; the source-grepping parity test for its quick-book path goes with it. Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
99a872987e |
feat(reports): behandlingshistorik as PDF + systemdokumentation pointer and version (#1790)
PR 2 of the behandlingshistorik plan (stacked on #1787). - lib/reports/behandlingshistorik-pdf-template.tsx: landscape A4 react-pdf document. Fixed header (räkenskapsår, urval, legal reference, company) and footer (page x of y, generated in Europe/Stockholm), repeated table header, wrap={false} rows, no `break` props. Two sections in the order the reader needs them: "Ändringar i bokföringssystemet" (p. 9.16 second paragraph) then "Bokföringsposter i registreringsordning" (first paragraph). Meta row: generated, programversion, antal händelser, källor. Details as one wrapped paragraph per row (real-data render 371 events: 1.5 s, 23 pages). Glyphs the bundled Helvetica lacks (arrow, true minus) are mapped to ASCII. - GET /api/reports/behandlingshistorik?format=pdf with a 4 000-event guard (413 REPORT_PDF_TOO_LARGE, CSV/XLSX remain complete); PDF first in the export menu; catalog exports pdf+xlsx. - lib/reports/app-version.ts shared by the route and the archive: revision/systemdokumentation.json now carries system.version and a behandlingshistorik block (where and how it is produced, p. 9.15); the shipped systemdokumentation template §9.3 points at Rapporter > Behandlingshistorik (PDF/CSV/Excel) as well as the backup ZIP. - Settings values that are objects render as "key: value" pairs in every format; report carries category_filter so the document states its urval. - Tests: 4 PDF template tests (valid PDF, empty report, filtered range, 220-row pagination), route pdf 200 + 413, route "unknown format" moved off pdf. Prod read-only render verified visually (header, sections, paging). Claude-Session: https://claude.ai/code/session_01Kw2CFCEt8MxzbJiXMAgMVi Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
4be51aae67 |
feat(reports): behandlingshistorik report (BFL 5 kap. 11 §, BFNAR 2013:2 p. 9.16) (#1787)
* feat(reports): behandlingshistorik report (BFL 5 kap. 11 §, BFNAR 2013:2 p. 9.16) Adds the per-räkenskapsår processing history as a first-class report in Rapporter (Export & arkiv), with CSV/XLSX export. Until now the behandlingshistorik only existed as raw audit_log JSON inside the Säkerhetsbackup ZIP; revisorer ask for a readable per-year document. - lib/reports/behandlingshistorik.ts: read model over journal_entries (committed_at = registreringsdatum, the complete source of bokföringsposter), the trigger-written audit_log (storno, deletions, diffs, kontoplan, settings, period lock/unlock/close, API keys, dimensions, accruals), the rättelse log, company_migration_resets, sie_imports and bank_file_imports. Field-level diffs with Swedish labels; company_settings restricted to processing-relevant keys (p. 9.16 second paragraph); kontoplan seeding and bulk underlag deletions collapse into one summary row; actor labels for users, API keys, MCP, agent, cron and system; fiscal-year mode unions audit rows touching the year's entries regardless of timestamp (bokslut/storno land after period_end), date-range mode narrows by registration time. - GET /api/reports/behandlingshistorik?period_id&from_date&to_date&category&format (json|csv|xlsx), withRouteContext + Zod, e-mail labels via service-role profiles lookup scoped to the ids in the result, app version stamped. - Report catalog row + focused view (category filter, export menu), sv/en. - Tests: 30 read-model tests, 10 route tests; smoke-tested read-only on prod. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Kw2CFCEt8MxzbJiXMAgMVi * fix(reports): keep behandlingshistorik queries statically resolvable for the schema guard tests/schema/no-phantom-columns.test.ts counts `.or()` calls with non-literal arguments as unresolvable and holds a ceiling (379); the report added two. The audit_log table/action filter is now a string literal in the call (pinned to AUDITED_TABLES / GLOBAL_ACTIONS by a unit test), and the migration-reset lookup is two plain `.eq()` queries instead of an interpolated `.or()`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Kw2CFCEt8MxzbJiXMAgMVi --------- Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
5a8dd21931 |
feat(reconciliation): page-owned window, automatic matching, and a way out for unbookable rows (#1742)
Second half of the reconciliation redesign, on top of the bridge in #1737. **Toolbar.** The view hosted its own "Datum från / Datum till" inputs behind a Filtrera button: a second period control competing with the header's räkenskapsår picker (convention 8), and the source of a "typed but not applied" state that needed its own attention line to explain. The window is now owned by the page, narrowed through the shared ReportDateRange like every other report, and applied on change. The view holds no date state at all, which also removes the ref-synchronisation dance and the off-by-one it existed to prevent (a year switch fetching the previous year's window because the refs updated a commit late). Reconciliation opens on the FULL year, not the family default of YTD, and keeps its own preset memory: a reconciliation runs over a whole räkenskapsår, and inheriting a "Denna månad" last used on Resultatrapport would show an alarming difference for a window nobody chose here. ReportDateRange gained defaultPreset and storageKeyPrefix for that; every existing caller keeps its behaviour. **Automatic matching.** "Förhandsgranska" told the user nothing about what it did, and the ochre line above it existed only to point at it: people matched a whole migration row by row next to a button they never found. The matcher now runs by itself, once per window+account, whenever there is unmatched work. It is a dry run, so nothing is written and Tillämpa still requires an explicit click. The button stays as a re-run and is renamed to what it does. ?autorun=1 keeps a distinct meaning (run even on a clean window) so the transactions-inbox deep link still produces a result rather than silence. **A way out for rows that cannot be paired.** An unmatched bank row that no voucher on the account could settle is not reconciliation work, it is an unbooked affärshändelse, and the match picker held nothing for it. Those rows now offer "Bokför" into /transactions?highlight=<id>, with a bulk link in the section header. The rule (direction-compatible and equal to the öre) is extracted to lib/reconciliation/voucher-candidate.ts so it is testable and so the component never imports the server-only reconciliation module. Deliberately strict: a false negative offers booking on a row that could also have been paired, which is a legitimate outcome, while a false positive sends the user into an empty picker. 11 new tests for the candidate rule, covering direction, öre equality, float noise, PostgREST numeric strings and the foreign-account case where the candidate RPC projects no FX amount and no match may be claimed. Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
fa394e3759 |
fix(skattekonto): look-alike beslut rows, the list-to-voucher round trip, makulerad rendering, huvudbok discoverability (#1297)
Four fixes from the exit mail Anders Orback (Center Node AB) sent hours after churning. His five points were mostly one job: reconciling skattekontot against banken before årsredovisningen. Skattekonto look-alike rows. Skatteverket splits a retroactive omprövningsbeslut across every month it re-charges and sends one transaction per month, sharing date, text and amount; only ranteberakningsdatum separates them, and we stored it but rendered it nowhere. A real company posted 15 such vouchers (67 785 kr across Feb 2025-Apr 2026) unable to tell them from duplicates of the automatic hämtning. Surface the field when it carries information: its month differs from the Datum column, or another row in the same band is otherwise indistinguishable. The list-to-voucher round trip. The verifikat list collapsed to a skeleton on every refetch and sprang back, moving rows under the pointer; only the first load shows a skeleton now. Filter state is React-only, so leaving the list loses it: add a hover-revealed open-in-new-tab affordance on the voucher list and the skattekonto page, where the link had been behind a hand-rolled opacity-0 that coarse pointers never trigger. Makulerad rendering. A stornoed verifikat now reads as struck out, per data cell rather than on the row, because text-decoration propagates and a child cannot opt out. Vouchers-per-account discoverability. /reports/huvudbok?account=1930 already existed; the palette matcher requires every token and the entry never contained the word "verifikat". Add ReportDescriptor.searchTerms plus a report-library search box. Also fixes a false "Saknar underlag" compliance chip that flashed before attachment counts resolved, and a keyboard-access regression where HOVER_REVEAL_CLASS carried focus-visible only, hiding controls inside a non-focusable wrapper from keyboard users. No migration. No write paths, storno paths or posted entries touched. Follow-ups filed: #1300 #1301 #1302 #1303 #1304 #1305 #1306 #1307 #1308. Open decision: #1305 (Omförd vs Makulerad). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
14f7478abb |
feat(reports): reskontra per valfritt datum + PDF-export (#1039)
Kundreskontra and leverantörsreskontra were effectively always "as of today": the UI never passed a date, the xlsx export ignored the chosen fiscal year, and no PDF existed. - Both ledger generators reconstruct the ledger as it stood on a backdated as-of date: invoices dated on or before it (including ones fully paid since) with outstanding recomputed from the payment-row history; paid_at dates row-less full payments; undateable legacy amounts degrade to the live values. Today/future dates keep the live computation byte-identical. - New shared reskontra PDF template (aging per counterparty + invoice detail for kundreskontra) with PDF routes for both ledgers. - Both report views get a "Per datum" date control; the export menu offers PDF + Excel and passes the chosen date through. Note: the PDF template deliberately avoids react-pdf's `break` prop: it deadlocks layout when the section spills across pages (reproduced at 40+ rows, documented in the template). Fixes #1020 Fixes #1021 Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
7d7f604e00 |
Add/stripe invoice link (#998)
* feat(supplier-invoices): show registered invoices under "Att betala" with inline approve Registered supplier invoices are already booked as debt (2440) but were hidden from the "Att betala" tab until approved, which confused users. The tab now shows registered invoices too, marked "Ej godkand" with a compact inline approve button. Approval remains the gate for payment, not visibility; status model and approve API untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(reports): add date range filter to huvudbok (kontoanalys) Mounts the existing ReportDateRange control on /reports/huvudbok so the ledger can be narrowed to any date range within the fiscal year, matching Fortnox kontoanalys. Lines before the range roll into each account's opening balance so running balances stay correct at the range start; lines after the range are dropped. Applies to the XLSX export too. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(invoices): add optional payment link on invoices (paste-link MVP) The user pastes a payment link created in their PSP dashboard (e.g. a Stripe Payment Link) onto an invoice. The recipient gets a "Betala online" button in the invoice email and a QR code + clickable link in the PDF payment box. No PSP integration server-side: this is the demand probe; a future Stripe Connect integration would auto-fill the same column. - invoices.payment_link_url (migration 20260709090000), https-only + 2048-char cap enforced in CreateInvoiceSchema; empty string normalises to undefined and build-invoice-write always writes a concrete value so clearing the field on a draft edit NULLs the column - editor field (real invoices only) with one-link-per-invoice hint; strings in sv+en (messages landed via e0e11066) - email button (customer.language, hidden for credit notes/proforma/ delivery notes, URL escaped for the href attribute) + URL in the plain-text part - PDF QR + link row following the Swish QR pattern; wired into send, download and preview routes - derived documents (credit note, proforma convert, recurring) do NOT copy the link: it encodes one amount for one specific invoice - MCP gnubok_create_invoice accepts payment_link_url (validated at staging and re-checked in the commit executor); v1 API exposes the column; tools/list token ceiling bumped 45K -> 45.5K (ledger entry in payload-size.bench.test.ts, headroom was <10 tokens) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(invoices): show oresavrundning on editor/form totals, supplier list and invoice email The rounding logic (getDisplayTotal) was correct but only applied on the PDF, invoice list/detail and review dialog. The invoice editor summary, the supplier invoice form totals and the supplier invoice list showed the raw ore total right next to the toggle, and the invoice email said "Att betala" with the unrounded invoice.total while the attached PDF showed the rounded amount (and the email also ignored the ROT/RUT deduction). Extract the PDF's Att betala block into getAmountToPay (lib/invoices/rounding.ts) and point PDF + email at it so they cannot drift; behavior-identical refactor for the PDF. Booked amounts stay ore-exact; display-only as designed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(reports): adapt huvudbok date-range tests to the two-step entry-lines fetch The date-range tests (0969168f) mocked the old single-query shape with the parent entry embedded on each line; main's refactor (fetchEntryLines) queries journal_entries first and reattaches. Queue entry rows like the other tests so the merge of the two features is actually exercised. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(invoices): fetch full invoice projection in v1 send so ROT/RUT deduction and payment link reach the PDF and email The v1 send route's hand-rolled column list omitted deduction_total, deduction_personnummer_last4, payment_link_url and the item-level ROT/RUT fields, so invoices sent via the public API overstated 'Att betala' and dropped the deduction box. Reuse the shared INVOICE_FULL_COLUMNS/INVOICE_ITEM_FULL_COLUMNS so the send row can never drift from the GET shape again. Also harden the supplier-invoice inline approve: a thrown fetch left the button stuck spinning; failures now refetch the true server state. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
ec27228a8e |
style: remove em/en dashes repo-wide, add CLAUDE.md rule against them (#890)
Em dashes (—) and en dashes (–) had spread across comments, docs, tests, and a few UI strings, reading as AI-generated boilerplate rather than house style. Replaced each with punctuation matching its context: colon for explanatory clauses, comma for asides, plain hyphen for numeric/legal ranges (e.g. "21-23§"), "to"/"till" for date ranges, parentheses for paired-dash asides. messages/en.json and messages/sv.json were fixed by hand together to keep sv/en in sync. Left untouched where the dash is the functional subject rather than decorative punctuation: date-range-parser.ts's separator regex, charset-repair.ts's CP1252 byte-mapping table (and its test), the SIE encoding mojibake docs, generic-csv.ts's minus-sign normalizer, the agent system-prompt files that already instruct against em dashes, and a golden iXBRL test fixture compared byte-for-byte. Also fixes two bugs surfaced along the way: an off-by-one in ApiKeysPanel's scope-label split (a leftover from an earlier partial pass), and a charset-repair test that had lost the literal en-dash it exists to verify. Regenerated the agent atom seed migration (skills:generate) since 27 SKILL.md files changed. Added a CLAUDE.md rule against em/en dashes, with an explicit carve-out for the functional-dash cases above. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
9f7c842a33 |
feat(skatt): setup gates + auto-loading momsdeklaration across Skatt & bokslut tabs (#885)
* feat(skatt): setup gates + auto-loading momsdeklaration across Skatt & bokslut tabs Every tab in the Skatt & bokslut nav group now tells an unconfigured user what is missing and where to fix it, instead of dead-ending or rendering zeros: - Momsdeklaration: gates on vat_registered with a settings CTA; auto-fetches the configured period on load and on every period change (no more "Hämta" button); one period control (räkenskapsår picked inline for helårsmoms, shell selector + back link dropped via new ReportDescriptor.standalone); raw <select>s replaced with the Select primitive; banner when moms_period is missing; BankID connect returns to the page instead of the report library. - Deadlines: callout (sv+en) when no system-generated tax deadlines exist — they are derived from tax settings, so point at /settings/tax rather than presenting an empty manual todo list. - Årsbokslut: "no räkenskapsår yet" (CTA to bookkeeping settings) is now distinguished from "nothing to close yet". - Skattekonto: non-auth fetch failures render an error card with retry instead of the misleading "inget saldo hämtat ännu" empty state. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(skatt): address bot review — res.ok guard, blocking moms_period gate, panel hidden while räkenskapsår unresolved - Auto-fetch treats non-2xx or unparsable responses as errors (with retry) instead of rendering undefined data. - momsPeriodMissing now blocks the declaration (EmptyState + settings CTA) rather than fetching a guessed quarterly period behind a banner — a declaration submittable for the wrong period type is a hazard, not a convenience. - SkatteverketPanel is not rendered while yearly mode awaits a fiscal period, so its actions can never target an unconfirmed period. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
01dbef4015 |
feat(dimensions): PR4 reports — dimension-filtered P&L + Resultat per projekt/kostnadsställe (#862)
* feat(dimensions): PR4 reports — dimension-filtered P&L everywhere + Resultat per projekt/kostnadsställe The Project P&L milestone of the dimensions plan (dev_docs §7 PR4). One choke point lights up everything: generateTrialBalance gains options.dimensions (SIE dim → code map) pushed down as jsonb containment (dimensions @>, served by idx_jel_dimensions_gin) on both line queries, with company-wide opening balances dropped when filtered (they cannot be dimension-scoped; P&L-safe by whitelist). Resultatrapport, resultaträkning, huvudbok, monthly-breakdown and the TB drill-down inherit the filter; the KPI route filters only its P&L-side inputs (income statement, months, expense composition) — never cash/VAT. New report lib/reports/dimension-pnl.ts — "Resultat per projekt/ kostnadsställe" (Fortnox Resultatrapport projekt): value-as-column matrix over one dimension with an explicit "(Utan dimension)" bucket computed as the residual against the same trial-balance pass resultatrapport uses, so every row and the Totalt column reconcile with the unfiltered resultatrapport by construction. Registered in REPORT_CATALOG (visible only when dimensions_enabled), slug-routed view + xlsx export. UI: DimensionFilter (dimension + value picker, persistent "Filtrerad — ej fullständig rapport" chip) mounts in FocusedReport for catalog entries flagged dimensions: true; huvudbok rows show line dim codes. Statutory exclusion pinned by TEST, not convention: lib/reports/__tests__/dimension-statutory-guard.test.ts fails if the filter parser leaks into balance sheet, balansrapport, kassaflöde, VAT, SIE or full-archive routes/generators, or if the catalog whitelist widens. MCP: new gnubok_get_dimension_pnl (reports:read); dimensions filter arg on get_trial_balance/get_income_statement/get_general_ledger with resolve-don't-select (names → registry codes, resolution echoes); query_journal totals fixed to aggregate the FULL match set (was silently slice-scoped while claiming otherwise) with an honest totals_scope field, plus group_by / group_by_dimension aggregation. Also: voucher-detail dim-6 badge now uses the registry name instead of the non-standard "PR" abbreviation (#859 review follow-up). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(dimensions): address #862 review — export disclosure, prior-column suppression, period-label honesty, route hardening - Filtered XLSX/PDF exports now carry the partial-view disclosure past the file boundary (BFNAR 2013:2): filename suffix (-dim6-p001), a "Filtrerad … — ej fullständig rapport" row on every sheet, and a header note/title line in the PDFs. - Resultatrapport drops the prior-year column when a dimension filter is active — project codes are time-limited under K2/K3, so "this code last year" may be a different project (same rule as narrowed date ranges). - dimension-pnl no longer accepts fromDate: the matrix is cumulative from period_start by design (closing-balance semantics), and the period label now states exactly that instead of echoing a lower bound that was never applied. Routes/MCP tool updated to toDate-only. - dimension-pnl routes 404 on an unknown/foreign period id and cap dim_no to 4 digits (matching the MCP tool's PostgREST-path guard, which the generator now also enforces itself). - Statutory-guard test's generateTrialBalance call-site scan is paren-aware instead of a 300-char window; added fully-untagged and injection-guard test cases. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
d63d2aecf0 |
feat: UI slop cleanup, invoice icon/header polish + year-end in Rapporter, journal-list DataList refactor (#847)
UI cleanup: removed AI-slop (redundant suppliers subtitle, decorative Sparkles glyph), decluttered the article-detail header (single status badge + muted type · #number), standardized the invoice icon Receipt→ReceiptText (no $ in a SEK app), and matched ReportExportMenu trigger size to the primary CTA on list pages. Bookkeeping: surfaced year-end closing in Rapporter (catalog descriptor) and dropped the redundant header button; refactored JournalEntryList to DataList primitives + chunked /api/documents/counts in 50-ID batches (large pages previously 400'd); added optional fraction-digit overrides to formatCurrency. The fiscal-year lock indicator is preserved as a labeled Låst/Stängt badge in FiscalYearSelector. All PR-bot findings triaged as false positives (unused import, formatCurrency öre, lock indicator) or intentional design (year-end placement, empty-state messaging). CI green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
739f18fd1c |
fix(reconciliation): drive bank avstämning period from the report header (#771) (#774)
The bank reconciliation view hosted its OWN FiscalYearSelector inside the action bar — but that bar renders below the loading-skeleton early-return, so the selector never mounted, its onReady/onChange never fired, the periodReady gate never flipped, and the page hung on a permanent skeleton (#771). Make the report period-scoped like the ledgers: lib/reports/catalog.ts marks bank-reconciliation `params: 'fiscal'`, so the report page's räkenskapsår selector owns the period. FocusedReport passes periodId + periodBounds down, and BankReconciliationView takes them as props instead of self-selecting. The window seeds from periodBounds and a periodId-keyed effect re-seeds (and writes dateFromRef/dateToRef synchronously) on a year switch, preserving the #751 period-scoped IB-floor behaviour without the deadlock. Manual date edits still apply on demand via "Filtrera". Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
ff01640f60 |
feat(reports,settings): report library + focused report routes, settings modal (#629)
* feat(reports,settings): report library + focused report routes, settings modal Reports - Replace the monolithic /reports tab-switcher with a calm, grouped report library landing (ReportLibrary + RecentReportsShelf) driven by a new lib/reports/catalog.ts. - Each report opens a focused /reports/[slug] route (FocusedReport) with a shared fiscal-year selector, optional date-range, and URL-based account drill-down into the general ledger. - Extract every report view into components/reports/views, add a reusable ReportExportMenu, and remove the old ReportsNav. Settings - Add an intercepting @settingsModal parallel route so in-app navigation to /settings opens as a modal over the current page; hard loads still resolve to the full page. - Share one SettingsShell (rail + content) between page and modal, extract each section into components/settings/sections/*Content, add a settings hotkey and command-palette entry, and remove the old SettingsSidebar. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(reports,settings): remove dead salary-journal entry, fix border token Addresses PR review feedback (#629): - Remove the unreachable `salary-journal` report from the catalog. It had needsEmployees + no route + no FocusedView handler and `hasEmployees` was never plumbed through, so it never appeared in the library and a direct /reports/salary-journal URL rendered a blank frame. The report was never on the old page and has no view component; the API + generator stay in place for a proper follow-up. Drops its two now-unused i18n keys. - Replace opacity-suffixed `border-border/8` section dividers with full-opacity `border-border` across the extracted settings section components, per the design system (no opacity-suffixed border tokens on surfaces). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: re-trigger checks (pg-real hit a Docker Hub registry timeout) --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |