Commit Graph
3 Commits
Author SHA1 Message Date
MattssonandClaude Fable 5 4a9fa5e6c5 feat(inbox): staged upload ack, HEIC/HEIF validation, WhatsApp silence fixes (#1605)
* fix(whatsapp): app-side unmute, close silent intake paths, health visibility

- add POST /link/unmute and a Reactivate control on the Pausad state
- company resolution: transient query errors release the row for sweep
  retry; genuine zero-options sends M19 instead of parking silently
- media from unlinked senders bypasses the hourly greeting throttle
  (10 min burst window, daily cap kept)
- GET /link returns 7-day failed-delivery and parked-inbound counts;
  sweep summary logs outboundFailed24h

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(documents): real HEIC/HEIF magic-byte validation, bilingual upload errors

- detect ISO-BMFF ftyp brands (heic/heix/heim/heis/hevc/hevx/hevm/hevs,
  mif1/msf1) instead of exempting image/heic from validation; declared
  heic/heif accepts either family member (iOS labels vary)
- new INBOX_UPLOAD_* structured error codes replace raw English strings
  on the inbox upload and attach-document routes
- registry doc corrected to the real 10 MB cap

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(inbox): staged upload with instant ack and deferred AI extraction

- web uploads insert the inbox item as status processing and respond
  immediately; Bedrock extraction and supplier match run via after()
  with a CAS flip to received (email and WhatsApp channels keep the
  synchronous path)
- widen invoice_inbox_items.status CHECK to include processing
  (migration 20260813180000, pg-real test included)
- crash-recovery sweep cron (*/2) flips stale processing rows;
  bulk-book skips extraction_in_progress items
- workspace: processing chip, in-flight rows disable actions, realtime
  flip, retry-extraction button for empty extractions
- picker accept list drops HEIC/HEIF so iOS transcodes library photos
  to JPEG; server allowlists unchanged (supersedes 2026-08-01 HEIC
  decision, see DECISIONS.md)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(migrations): bump inbox processing-status migration past main's latest

Main merged 20260813210000 while this PR was in flight; an inserted
version older than the latest applied aborts the prod db push at merge.
Renamed 20260813180000 to 20260813213000 and updated references.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(decisions): log preview-tracker orphan repair after migration rename

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 23:57:53 +02:00
Alim Polatandalimpolat 6821568523 feat(registry): add Bank Statement Sheet MCP server (#1472)
* feat(registry): add Bank Statement Sheet MCP server

An MCP server that converts PDF bank statements into transaction data
which arrives with a pass/fail reconciliation verdict. Each file is
checked against its own printed figures — balance continuity where the
bank prints a running balance, footing against the statement's control
totals where it does not. Below the threshold the rows are withheld and
an agent has to ask for them explicitly.

Covers the path the bank import does not: CAMT.053 and CSV are
supported, the PDF itself has no way in.

Verified against the sandbox 2026-08-07: 14 of 14 transactions imported
under Bankfil, Inkomster 35 500 kr and Utgifter −23 540,86 kr to the öre,
zero warnings and zero skipped rows on the semicolon + comma-decimal CSV.

Writes nothing to accounted and requests no scopes. First-time
contributor, so the author profile is added in the same PR.

npm run validate:registry: 21 entries, 3 authors, 0 failures.

Signed-off-by: alimpolat <alimpolat@users.noreply.github.com>

* fix(registry): correct two claims and drop prose em dashes

Addresses the CodeRabbit review on #1472.

The verdict did not survive where the entry said it did. It claimed the
per-row marker "overlever" decomposition into vouchers, which reads as
the verdict persisting into accounted. It does not: the flag exists only
in the MCP response, and nothing imported carries it. Now says so, and
says the reader must have seen the verdict before importing rather than
expect to find it in the books afterwards.

"Den kor inte lokalt" was wrong about the wrong thing. The MCP server
does run locally over stdio; it is the conversion that is remote. The
sentence now separates the local stdio process from the EU API, keeping
the server-side engine, thin MIT client and EU data location intact.

Em and en dashes removed from both files per the repo's coding
guidelines. Five occurrences, not the three flagged.

Not taken: pinning the install command to @0.1.0. Pinning would leave
every installed copy on the first release with no path to fixes; the
version field records what was verified, and the body already dates it.

npm run validate:registry: 21 entries, 3 authors, 0 failures.

Signed-off-by: alimpolat <alimpolat@users.noreply.github.com>

---------

Signed-off-by: alimpolat <alimpolat@users.noreply.github.com>
Co-authored-by: alimpolat <alimpolat@users.noreply.github.com>
2026-08-10 15:23:52 +02:00
3d1ed15b6d feat(registry): move community registry source of truth into the public repo (#1458)
* feat(registry): move community registry source of truth into the public repo

The site's registry page says "Lägg till en egen" and links here, but the
MDX entries lived in the private website repo, so an external contributor
had no path to open the PR we were inviting (found by the first person who
tried). This makes the invitation real:

- registry/entries/ + registry/authors/ hold the 20 existing entries and
  2 author profiles, migrated verbatim from the website repo, which now
  syncs FROM this directory instead of owning the content
- registry/README.md documents the frontmatter convention and the flow
- scripts/validate-registry.ts (npm run validate:registry, wired into
  core-build) checks structure and rejects JSX/import/export in bodies:
  the site renders entries through MDX, which would execute those inside
  the website build
- CONTRIBUTING.md points at the registry for listing community work

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>

* fix(registry): close MDX-safety gaps and correct six compliance claims from PR review

Review bot findings on #1458, both verified and addressed:

- The body safety gate only rejected capitalized JSX tags, but MDX also
  evaluates lowercase HTML tags (<div>, <img onerror=...>) and bare {...}
  expressions. The validator now rejects any raw tag and any brace outside
  fenced code and backtick inline code; literal tags in prose go in
  backticks. Verified: a crafted entry with all three bypasses fails, all
  existing content still passes.
- Six factual errors in migrated entries, each checked against the skill
  sources in .claude/skills/ before editing (these were live on the site
  already): traktamente 2026 is 300 kr not 260; employer contributions for
  66+ at year start (67+ from 2026) are 10.21% not "65+: 16.36%", and the
  under-18 0% claim is replaced with the documented 18-22 youth reduction;
  electronics reverse-charge threshold is 100 000 kr excl VAT per invoice
  not 250 000; half prisbasbelopp 2026 is 29 600 not 24 750; kostnadsställe
  is SIE dimension 1 not 7; SRU period suffixes encode the fiscal-year end
  range (P1 jan-apr, P2 maj-aug, P4 sep-dec) not fixed months.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>

---------

Signed-off-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 10:54:09 +02:00