@accounter/server
Version:
Accounter GraphQL server
775 lines (673 loc) • 501 kB
Markdown
# @accounter/server
## 0.2.0-alpha-20260809152350-63e2e85ea7c71902af436002af7633533fe720ac
### Minor Changes
- [#4139](https://github.com/Urigo/accounter-fullstack/pull/4139)
[`73fa00a`](https://github.com/Urigo/accounter-fullstack/commit/73fa00a411451695ca0d1e2f5b56762d5f685e4b)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Batch add/remove tags across selected
charges from the charges table.
Server: new
`batchUpdateChargesTags(chargeIds: [UUID!]!, addTagIds: [UUID!], removeTagIds: [UUID!])` mutation.
It adds and/or removes the given tags on every listed charge while leaving each charge's other
tags untouched (additive/subtractive — unlike `batchUpdateCharges(fields.tags)`, which replaces a
charge's whole tag set). Inserts are idempotent and processing is bounded-concurrency. Consistent
with the existing convention, a tag-only change does **not** degrade accountant approval.
Client: the charges table's selection-column bulk-actions menu gains a "Change tags" action
opening a dialog with Add/Remove modes and a tag multi-select, applied to all selected charges in
one request.
- [#4121](https://github.com/Urigo/accounter-fullstack/pull/4121)
[`b28d745`](https://github.com/Urigo/accounter-fullstack/commit/b28d745456f135d952437ca5ad7056f6188aae33)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Support batch ledger-record regeneration
from the charges table.
The `regenerateLedgerRecords` mutation now accepts a list of charge ids (`chargeIds: [UUID!]!`)
and returns a `GeneratedLedgerRecords` result per charge, in order. Each charge is regenerated
independently, so a single failure surfaces as a per-charge `CommonError` instead of aborting the
whole batch.
On the client, the charges table's selection-column header now exposes a bulk-actions menu with a
"Regenerate ledger" option that regenerates the ledger for all selected charges (with the same
confirmation modal as the per-charge button). The existing per-charge regenerate button calls the
same mutation with a single-element array.
- [#3851](https://github.com/Urigo/accounter-fullstack/pull/3851)
[`a91e4a0`](https://github.com/Urigo/accounter-fullstack/commit/a91e4a0726fed53dda22dfb57b6919411bbeaba3)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Add the Charge Matching Review Screen: a
guided side-by-side UI for pairing document-based and transaction-based charges and merging them
one by one.
- Server: new `chargesAwaitingMatchQueue` GraphQL query that returns a paginated queue of
unmatched base charges with on-the-fly match suggestions, filterable by business, date range and
mode (`DOC_BASE`/`TRANSACTION_BASE`) and sortable `BY_DATE` or `BY_SCORE` (score evaluation
capped at the 100 most recent unmatched charges).
- Client: new `/charges/matching` screen with a filter/sort header, collapsible queue sidebar with
per-item pending/matched/skipped status, side-by-side base-vs-suggestion comparison cards,
alternative-suggestion switching, and accept (merge) / skip actions.
- [#3761](https://github.com/Urigo/accounter-fullstack/pull/3761)
[`837d95c`](https://github.com/Urigo/accounter-fullstack/commit/837d95c0985ade04cf31cc7f956d409a1a7463e5)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Deprecate the legacy gmail-listener email
path now that the v2 multi-tenant `@accounter/email-ingestion-gateway` pipeline (Cloudflare →
Gateway → Server) covers it.
- The server GraphQL fields `businessEmailConfig` (query) and `insertEmailDocuments` (mutation)
are marked `@deprecated` (non-breaking — the legacy listener keeps working for rollback) and
scheduled for removal after cutover. Their resolvers carry matching `@deprecated` JSDoc.
- `@accounter/gmail-listener` is marked deprecated (README banner + package description) and
superseded by the gateway. It is kept only for rollback during the cutover.
- Docs updated to acknowledge the migration (root `CLAUDE.md`, `packages/server/CLAUDE.md`).
The `gmail_listener` auth role and the package itself are intentionally retained for rollback;
hard removal (and `npm deprecate` of the published package) is a follow-up once the cutover is
complete.
- [#4110](https://github.com/Urigo/accounter-fullstack/pull/4110)
[`156c8b1`](https://github.com/Urigo/accounter-fullstack/commit/156c8b11844b4fada6f649a55ec00cc0ef68f92e)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Enrich the `documentsByFilters` query and
expose per-document validation info.
Added a `validation: DocumentValidationInfo` field to the `FinancialDocument` interface (and its
concrete implementers). Its resolver runs all three document validations — basic required-fields,
VAT and allocation — and combines them into a single informative response with per-check results
(`basicValidation`, `vatValidation`, `allocationValidation`), an aggregated `issues` list and an
overall `isValid` flag.
Added new optional filters to `documentsByFilters`:
- `type`: include only documents of the given document types.
- `missingCounterparty`: include only documents missing a creditor or debtor.
- `missingInfo`: include only documents that fail basic information validation.
- `freeText`: free text search across serial number, total amount (raw and normalized),
description, remarks and creditor/debtor (counterparty) business names.
- [#3941](https://github.com/Urigo/accounter-fullstack/pull/3941)
[`b828023`](https://github.com/Urigo/accounter-fullstack/commit/b82802376c5f1f4acc5de274b58348d87fcbe553)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Add a `myMemberships` query that returns
the authenticated caller's own business memberships (`MyBusinessMembership`: composite `id`,
`businessId`, `roleId`, `businessName`), gated by
`@requiresAnyRole(["business_owner", "accountant"])`.
The memberships are resolved per request from `accounter_schema.business_users` (the same
DB-resolved auth context used everywhere else), so callers get an accurate, up-to-date scope
without relying on token claims. This backs the MCP server's server-side membership resolution: an
authenticated caller receives their businesses, and a caller with none receives an empty list
rather than an error.
- [#4111](https://github.com/Urigo/accounter-fullstack/pull/4111)
[`cd1c480`](https://github.com/Urigo/accounter-fullstack/commit/cd1c480b782f9091e163badd7e872b997dc74a97)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Add a `transactionsByFilters` query to the
transactions module. It fetches transactions filtered by transaction ids, charge ids, owners
(scoped to the authorized read scope), counterparty ids, date ranges (event date, debit date, or
any date), missing counterparty, missing info (fails transaction validation), and free text
(source description / reference, amount, counter account, origin key, and counterparty name).
### Patch Changes
- [#3763](https://github.com/Urigo/accounter-fullstack/pull/3763)
[`606c8d7`](https://github.com/Urigo/accounter-fullstack/commit/606c8d7ba94f272659341b4baadd03593d363d5e)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency [`auth0@5.13.0` ↗︎](https://www.npmjs.com/package/auth0/v/5.13.0) (from
`5.12.0`, in `dependencies`)
- [#3768](https://github.com/Urigo/accounter-fullstack/pull/3768)
[`7a7dc71`](https://github.com/Urigo/accounter-fullstack/commit/7a7dc71ba2dc9a660f150340f2352704d571f367)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@3.0.86` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/3.0.86) (from
`3.0.85`, in `dependencies`)
- Updated dependency [`ai@6.0.209` ↗︎](https://www.npmjs.com/package/ai/v/6.0.209) (from `6.0.208`,
in `dependencies`)
- Updated dependency [`playwright@1.61.1` ↗︎](https://www.npmjs.com/package/playwright/v/1.61.1)
(from `1.61.0`, in `dependencies`)
- [#3776](https://github.com/Urigo/accounter-fullstack/pull/3776)
[`b3761d9`](https://github.com/Urigo/accounter-fullstack/commit/b3761d9fa853bd7bb26b41796fdff96af5f45863)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@3.0.87` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/3.0.87) (from
`3.0.86`, in `dependencies`)
- Updated dependency [`ai@6.0.210` ↗︎](https://www.npmjs.com/package/ai/v/6.0.210) (from `6.0.209`,
in `dependencies`)
- [#3778](https://github.com/Urigo/accounter-fullstack/pull/3778)
[`02dc27e`](https://github.com/Urigo/accounter-fullstack/commit/02dc27e172538c66f4f9af228ea2d419d0e81141)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.1` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.1) (from
`3.0.86`, in `dependencies`)
- Updated dependency [`ai@7.0.2` ↗︎](https://www.npmjs.com/package/ai/v/7.0.2) (from `6.0.209`, in
`dependencies`)
- [#3789](https://github.com/Urigo/accounter-fullstack/pull/3789)
[`e26256c`](https://github.com/Urigo/accounter-fullstack/commit/e26256c2e4cd3ba51042446a4617b996d49a9e0c)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.4` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.4) (from
`4.0.1`, in `dependencies`)
- Updated dependency
[`@graphql-tools/utils@11.1.1` ↗︎](https://www.npmjs.com/package/@graphql-tools/utils/v/11.1.1)
(from `11.1.0`, in `dependencies`)
- Updated dependency [`ai@7.0.9` ↗︎](https://www.npmjs.com/package/ai/v/7.0.9) (from `7.0.2`, in
`dependencies`)
- [#3790](https://github.com/Urigo/accounter-fullstack/pull/3790)
[`1f016b8`](https://github.com/Urigo/accounter-fullstack/commit/1f016b8739573311dc0d56ee4fe1a3570ba65428)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.1` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.1) (from
`3.0.87`, in `dependencies`)
- Updated dependency [`ai@7.0.2` ↗︎](https://www.npmjs.com/package/ai/v/7.0.2) (from `6.0.210`, in
`dependencies`)
- [#3825](https://github.com/Urigo/accounter-fullstack/pull/3825)
[`cc16f94`](https://github.com/Urigo/accounter-fullstack/commit/cc16f9472b79c3991d1b8fd186a1a75d2b9e26e1)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@opentelemetry/exporter-trace-otlp-http@0.220.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-http/v/0.220.0)
(from `0.219.0`, in `dependencies`)
- Updated dependency
[`@opentelemetry/resources@2.9.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/resources/v/2.9.0)
(from `2.8.0`, in `dependencies`)
- Updated dependency
[`@opentelemetry/sdk-node@0.220.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/sdk-node/v/0.220.0)
(from `0.219.0`, in `dependencies`)
- [#3832](https://github.com/Urigo/accounter-fullstack/pull/3832)
[`bf8ed3b`](https://github.com/Urigo/accounter-fullstack/commit/bf8ed3b88f5e2abdb045361b7d33ead0a10c352f)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@opentelemetry/auto-instrumentations-node@0.78.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node/v/0.78.0)
(from `0.77.0`, in `dependencies`)
- [#3834](https://github.com/Urigo/accounter-fullstack/pull/3834)
[`77222b7`](https://github.com/Urigo/accounter-fullstack/commit/77222b7052ffb094db5df5c9065ed93e9dc21bf2)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.7` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.7) (from
`4.0.4`, in `dependencies`)
- Updated dependency [`ai@7.0.14` ↗︎](https://www.npmjs.com/package/ai/v/7.0.14) (from `7.0.9`, in
`dependencies`)
- [#3836](https://github.com/Urigo/accounter-fullstack/pull/3836)
[`059b638`](https://github.com/Urigo/accounter-fullstack/commit/059b638702116701a5a0062a7ac3a58a28eeb004)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.7` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.7) (from
`4.0.4`, in `dependencies`)
- Updated dependency
[`@opentelemetry/auto-instrumentations-node@0.78.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node/v/0.78.0)
(from `0.77.0`, in `dependencies`)
- Updated dependency [`ai@7.0.14` ↗︎](https://www.npmjs.com/package/ai/v/7.0.14) (from `7.0.9`, in
`dependencies`)
- [#3837](https://github.com/Urigo/accounter-fullstack/pull/3837)
[`465eefe`](https://github.com/Urigo/accounter-fullstack/commit/465eefe4062076ecdf9f0a447637ddc797039572)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - dependencies updates:
- Updated dependency
[`@opentelemetry/exporter-trace-otlp-http@0.220.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-http/v/0.220.0)
(from `0.219.0`, in `dependencies`)
- Updated dependency
[`@opentelemetry/resources@2.9.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/resources/v/2.9.0)
(from `2.8.0`, in `dependencies`)
- Updated dependency
[`@opentelemetry/sdk-node@0.220.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/sdk-node/v/0.220.0)
(from `0.219.0`, in `dependencies`)
- [#3846](https://github.com/Urigo/accounter-fullstack/pull/3846)
[`d382eb2`](https://github.com/Urigo/accounter-fullstack/commit/d382eb20cf27b76ef80d235080bead1ba66b1e77)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.8` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.8) (from
`4.0.7`, in `dependencies`)
- Updated dependency
[`@graphql-hive/yoga@0.48.2` ↗︎](https://www.npmjs.com/package/@graphql-hive/yoga/v/0.48.2) (from
`0.48.1`, in `dependencies`)
- Updated dependency [`ai@7.0.16` ↗︎](https://www.npmjs.com/package/ai/v/7.0.16) (from `7.0.14`, in
`dependencies`)
- Updated dependency [`iconv-lite@0.7.3` ↗︎](https://www.npmjs.com/package/iconv-lite/v/0.7.3)
(from `0.7.2`, in `dependencies`)
- [#3853](https://github.com/Urigo/accounter-fullstack/pull/3853)
[`a17149a`](https://github.com/Urigo/accounter-fullstack/commit/a17149a90ce064eae93bb88143732174e5875c4c)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@graphql-tools/utils@11.2.0` ↗︎](https://www.npmjs.com/package/@graphql-tools/utils/v/11.2.0)
(from `11.1.1`, in `dependencies`)
- [#3866](https://github.com/Urigo/accounter-fullstack/pull/3866)
[`dd31186`](https://github.com/Urigo/accounter-fullstack/commit/dd311865528c83422d9c5805ebe75005260b765c)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@opentelemetry/semantic-conventions@1.42.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/semantic-conventions/v/1.42.0)
(from `1.41.1`, in `dependencies`)
- [#3872](https://github.com/Urigo/accounter-fullstack/pull/3872)
[`a809750`](https://github.com/Urigo/accounter-fullstack/commit/a809750d9028f7a3305d4e5fccc1be247341fac3)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.9` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.9) (from
`4.0.8`, in `dependencies`)
- Updated dependency [`ai@7.0.17` ↗︎](https://www.npmjs.com/package/ai/v/7.0.17) (from `7.0.16`, in
`dependencies`)
- [#3873](https://github.com/Urigo/accounter-fullstack/pull/3873)
[`246b1e4`](https://github.com/Urigo/accounter-fullstack/commit/246b1e4d41a6424c4b9f251ff0b8cf36c774ab30)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.10` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.10) (from
`4.0.8`, in `dependencies`)
- Updated dependency
[`@opentelemetry/semantic-conventions@1.43.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/semantic-conventions/v/1.43.0)
(from `1.42.0`, in `dependencies`)
- Updated dependency [`ai@7.0.18` ↗︎](https://www.npmjs.com/package/ai/v/7.0.18) (from `7.0.16`, in
`dependencies`)
- Updated dependency [`auth0@5.14.0` ↗︎](https://www.npmjs.com/package/auth0/v/5.14.0) (from
`5.13.0`, in `dependencies`)
- [#3885](https://github.com/Urigo/accounter-fullstack/pull/3885)
[`41b8dc2`](https://github.com/Urigo/accounter-fullstack/commit/41b8dc269929e2e7132ea1d043a6eb227de916ba)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.10` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.10) (from
`4.0.9`, in `dependencies`)
- Updated dependency [`ai@7.0.18` ↗︎](https://www.npmjs.com/package/ai/v/7.0.18) (from `7.0.17`, in
`dependencies`)
- [#3906](https://github.com/Urigo/accounter-fullstack/pull/3906)
[`8f87877`](https://github.com/Urigo/accounter-fullstack/commit/8f87877fc2aec3a37d1b61836d2454803626ef58)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@opentelemetry/semantic-conventions@1.43.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/semantic-conventions/v/1.43.0)
(from `1.42.0`, in `dependencies`)
- [#3909](https://github.com/Urigo/accounter-fullstack/pull/3909)
[`8458c4a`](https://github.com/Urigo/accounter-fullstack/commit/8458c4aa5b7b6a3733360553fc056882a77e6e7b)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency [`auth0@5.14.0` ↗︎](https://www.npmjs.com/package/auth0/v/5.14.0) (from
`5.13.0`, in `dependencies`)
- [#3913](https://github.com/Urigo/accounter-fullstack/pull/3913)
[`6d29a1e`](https://github.com/Urigo/accounter-fullstack/commit/6d29a1ecfc84e1519165e7775aaa90ed3cb4071f)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.12` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.12) (from
`4.0.10`, in `dependencies`)
- Updated dependency [`ai@7.0.22` ↗︎](https://www.npmjs.com/package/ai/v/7.0.22) (from `7.0.18`, in
`dependencies`)
- [#3928](https://github.com/Urigo/accounter-fullstack/pull/3928)
[`ee7df50`](https://github.com/Urigo/accounter-fullstack/commit/ee7df5089190a89094aa36013ab9d1d02828c096)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.14` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.14) (from
`4.0.12`, in `dependencies`)
- Updated dependency [`ai@7.0.26` ↗︎](https://www.npmjs.com/package/ai/v/7.0.26) (from `7.0.22`, in
`dependencies`)
- [#3936](https://github.com/Urigo/accounter-fullstack/pull/3936)
[`5b2ffbb`](https://github.com/Urigo/accounter-fullstack/commit/5b2ffbbec76719fb0b6cd17dbe535755a830287d)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.15` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.15) (from
`4.0.14`, in `dependencies`)
- Updated dependency [`ai@7.0.28` ↗︎](https://www.npmjs.com/package/ai/v/7.0.28) (from `7.0.26`, in
`dependencies`)
- [#3943](https://github.com/Urigo/accounter-fullstack/pull/3943)
[`e61ed55`](https://github.com/Urigo/accounter-fullstack/commit/e61ed5561353766e72c180a0da5cd6c8b0a25d99)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency [`auth0@6.0.0` ↗︎](https://www.npmjs.com/package/auth0/v/6.0.0) (from
`5.14.0`, in `dependencies`)
- [#3955](https://github.com/Urigo/accounter-fullstack/pull/3955)
[`bdcc700`](https://github.com/Urigo/accounter-fullstack/commit/bdcc7001ddaa78524310952919ebf30d331447eb)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency [`ai@7.0.29` ↗︎](https://www.npmjs.com/package/ai/v/7.0.29) (from `7.0.28`, in
`dependencies`)
- [#3961](https://github.com/Urigo/accounter-fullstack/pull/3961)
[`a77d758`](https://github.com/Urigo/accounter-fullstack/commit/a77d758d5e9e98491b5759a7cc421b28af54d61f)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.16` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.16) (from
`4.0.15`, in `dependencies`)
- Updated dependency
[`@graphql-tools/utils@11.2.2` ↗︎](https://www.npmjs.com/package/@graphql-tools/utils/v/11.2.2)
(from `11.2.0`, in `dependencies`)
- Updated dependency [`ai@7.0.31` ↗︎](https://www.npmjs.com/package/ai/v/7.0.31) (from `7.0.29`, in
`dependencies`)
- [#3964](https://github.com/Urigo/accounter-fullstack/pull/3964)
[`49cd281`](https://github.com/Urigo/accounter-fullstack/commit/49cd281e9aa63832cd1eda409472d6074ad83ba4)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - dependencies updates:
- Updated dependency [`ai@7.0.29` ↗︎](https://www.npmjs.com/package/ai/v/7.0.29) (from `7.0.28`, in
`dependencies`)
- Updated dependency [`auth0@6.0.0` ↗︎](https://www.npmjs.com/package/auth0/v/6.0.0) (from
`5.14.0`, in `dependencies`)
- [#3965](https://github.com/Urigo/accounter-fullstack/pull/3965)
[`24cb271`](https://github.com/Urigo/accounter-fullstack/commit/24cb271b6c7a62d1e97e6e591fdf0c9bf4863e95)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.16` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.16) (from
`4.0.15`, in `dependencies`)
- Updated dependency
[`@graphql-tools/utils@11.2.2` ↗︎](https://www.npmjs.com/package/@graphql-tools/utils/v/11.2.2)
(from `11.2.0`, in `dependencies`)
- Updated dependency [`ai@7.0.31` ↗︎](https://www.npmjs.com/package/ai/v/7.0.31) (from `7.0.29`, in
`dependencies`)
- [#4007](https://github.com/Urigo/accounter-fullstack/pull/4007)
[`a549838`](https://github.com/Urigo/accounter-fullstack/commit/a549838ec8d2b909dadb73115171949065b6e842)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.17` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.17) (from
`4.0.16`, in `dependencies`)
- Updated dependency [`ai@7.0.33` ↗︎](https://www.npmjs.com/package/ai/v/7.0.33) (from `7.0.31`, in
`dependencies`)
- [#4018](https://github.com/Urigo/accounter-fullstack/pull/4018)
[`078e11a`](https://github.com/Urigo/accounter-fullstack/commit/078e11aa265af271c7d9b75de3464f1027144105)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@opentelemetry/resources@2.10.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/resources/v/2.10.0)
(from `2.9.0`, in `dependencies`)
- [#4029](https://github.com/Urigo/accounter-fullstack/pull/4029)
[`9337ae5`](https://github.com/Urigo/accounter-fullstack/commit/9337ae5bc529ccb6b761e0083f1264fe8f9d077c)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency [`auth0@6.1.0` ↗︎](https://www.npmjs.com/package/auth0/v/6.1.0) (from `6.0.0`,
in `dependencies`)
- [#4035](https://github.com/Urigo/accounter-fullstack/pull/4035)
[`dc246b3`](https://github.com/Urigo/accounter-fullstack/commit/dc246b37cb08aa58f02ccea01795b167fe101659)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@opentelemetry/auto-instrumentations-node@0.79.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node/v/0.79.0)
(from `0.78.0`, in `dependencies`)
- [#4037](https://github.com/Urigo/accounter-fullstack/pull/4037)
[`e3f2337`](https://github.com/Urigo/accounter-fullstack/commit/e3f233710a581a48dee6e45e956170dc3c2799c3)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency [`playwright@1.62.0` ↗︎](https://www.npmjs.com/package/playwright/v/1.62.0)
(from `1.61.1`, in `dependencies`)
- [#4042](https://github.com/Urigo/accounter-fullstack/pull/4042)
[`a71f169`](https://github.com/Urigo/accounter-fullstack/commit/a71f16930752deda421e7a8cd280e2ba1c42a79f)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.23` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.23) (from
`4.0.17`, in `dependencies`)
- Updated dependency [`ai@7.0.41` ↗︎](https://www.npmjs.com/package/ai/v/7.0.41) (from `7.0.33`, in
`dependencies`)
- Updated dependency [`jose@6.2.4` ↗︎](https://www.npmjs.com/package/jose/v/6.2.4) (from `6.2.3`,
in `dependencies`)
- [#4043](https://github.com/Urigo/accounter-fullstack/pull/4043)
[`244f33b`](https://github.com/Urigo/accounter-fullstack/commit/244f33bbfc2d334ef03ea5d8b94d937da1e1badd)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - dependencies updates:
- Updated dependency
[`@opentelemetry/auto-instrumentations-node@0.79.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node/v/0.79.0)
(from `0.78.0`, in `dependencies`)
- Updated dependency [`auth0@6.1.0` ↗︎](https://www.npmjs.com/package/auth0/v/6.1.0) (from `6.0.0`,
in `dependencies`)
- [#4047](https://github.com/Urigo/accounter-fullstack/pull/4047)
[`4226dd7`](https://github.com/Urigo/accounter-fullstack/commit/4226dd7d9691a539643d7b39991caf849ed26e40)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@opentelemetry/exporter-trace-otlp-http@0.221.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/exporter-trace-otlp-http/v/0.221.0)
(from `0.220.0`, in `dependencies`)
- Updated dependency
[`@opentelemetry/sdk-node@0.221.0` ↗︎](https://www.npmjs.com/package/@opentelemetry/sdk-node/v/0.221.0)
(from `0.220.0`, in `dependencies`)
- [#4057](https://github.com/Urigo/accounter-fullstack/pull/4057)
[`9d7b4ff`](https://github.com/Urigo/accounter-fullstack/commit/9d7b4ff93bcbd19146aca8a6957625632ad1a53d)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@graphql-hive/yoga@0.49.0` ↗︎](https://www.npmjs.com/package/@graphql-hive/yoga/v/0.49.0) (from
`0.48.2`, in `dependencies`)
- [#4066](https://github.com/Urigo/accounter-fullstack/pull/4066)
[`3910f54`](https://github.com/Urigo/accounter-fullstack/commit/3910f548f6da8ec4130878766853ec326df37b94)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.27` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.27) (from
`4.0.23`, in `dependencies`)
- Updated dependency [`ai@7.0.48` ↗︎](https://www.npmjs.com/package/ai/v/7.0.48) (from `7.0.41`, in
`dependencies`)
- Updated dependency [`jose@6.2.7` ↗︎](https://www.npmjs.com/package/jose/v/6.2.7) (from `6.2.4`,
in `dependencies`)
- Updated dependency [`playwright@1.62.1` ↗︎](https://www.npmjs.com/package/playwright/v/1.62.1)
(from `1.62.0`, in `dependencies`)
- [#4075](https://github.com/Urigo/accounter-fullstack/pull/4075)
[`93cafae`](https://github.com/Urigo/accounter-fullstack/commit/93cafaec6c761736c6a38e460807776ba785a879)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@graphql-hive/yoga@0.49.0` ↗︎](https://www.npmjs.com/package/@graphql-hive/yoga/v/0.49.0) (from
`0.48.2`, in `dependencies`)
- [#4081](https://github.com/Urigo/accounter-fullstack/pull/4081)
[`f899b37`](https://github.com/Urigo/accounter-fullstack/commit/f899b37a1561ef168398d122f214d9802178707d)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.27` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.27) (from
`4.0.23`, in `dependencies`)
- Updated dependency [`ai@7.0.48` ↗︎](https://www.npmjs.com/package/ai/v/7.0.48) (from `7.0.41`, in
`dependencies`)
- Updated dependency [`jose@6.2.7` ↗︎](https://www.npmjs.com/package/jose/v/6.2.7) (from `6.2.4`,
in `dependencies`)
- Updated dependency [`playwright@1.62.1` ↗︎](https://www.npmjs.com/package/playwright/v/1.62.1)
(from `1.62.0`, in `dependencies`)
- [#4101](https://github.com/Urigo/accounter-fullstack/pull/4101)
[`0e724c3`](https://github.com/Urigo/accounter-fullstack/commit/0e724c318b801b9ec616732cc1391da8915946c6)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency [`jose@6.2.8` ↗︎](https://www.npmjs.com/package/jose/v/6.2.8) (from `6.2.7`,
in `dependencies`)
- [#4113](https://github.com/Urigo/accounter-fullstack/pull/4113)
[`2d738fe`](https://github.com/Urigo/accounter-fullstack/commit/2d738fe60312d39215227cff0e545d6c5ca45007)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency [`googleapis@174.0.0` ↗︎](https://www.npmjs.com/package/googleapis/v/174.0.0)
(from `173.0.0`, in `dependencies`)
- [#4118](https://github.com/Urigo/accounter-fullstack/pull/4118)
[`6215b22`](https://github.com/Urigo/accounter-fullstack/commit/6215b223e860e2aa6d9c0a5c56f4f44037f6eaab)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency [`basic-auth@3.0.0` ↗︎](https://www.npmjs.com/package/basic-auth/v/3.0.0)
(from `2.0.1`, in `dependencies`)
- [#4120](https://github.com/Urigo/accounter-fullstack/pull/4120)
[`73316d3`](https://github.com/Urigo/accounter-fullstack/commit/73316d3a7704b22a493d5357097a283baf3567ea)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.34` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.34) (from
`4.0.27`, in `dependencies`)
- Updated dependency
[`@graphql-hive/yoga@0.49.1` ↗︎](https://www.npmjs.com/package/@graphql-hive/yoga/v/0.49.1) (from
`0.49.0`, in `dependencies`)
- Updated dependency [`ai@7.0.56` ↗︎](https://www.npmjs.com/package/ai/v/7.0.56) (from `7.0.48`, in
`dependencies`)
- Updated dependency [`auth0@6.2.0` ↗︎](https://www.npmjs.com/package/auth0/v/6.2.0) (from `6.1.0`,
in `dependencies`)
- Updated dependency [`googleapis@174.0.1` ↗︎](https://www.npmjs.com/package/googleapis/v/174.0.1)
(from `174.0.0`, in `dependencies`)
- [#4121](https://github.com/Urigo/accounter-fullstack/pull/4121)
[`b28d745`](https://github.com/Urigo/accounter-fullstack/commit/b28d745456f135d952437ca5ad7056f6188aae33)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - dependencies updates:
- Updated dependency [`jose@6.2.8` ↗︎](https://www.npmjs.com/package/jose/v/6.2.8) (from `6.2.7`,
in `dependencies`)
- [#4128](https://github.com/Urigo/accounter-fullstack/pull/4128)
[`d9d3145`](https://github.com/Urigo/accounter-fullstack/commit/d9d3145793b2ea883fbeda26b659bbeb69f3cb5a)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@google-cloud/pubsub@6.0.0` ↗︎](https://www.npmjs.com/package/@google-cloud/pubsub/v/6.0.0)
(from `5.3.1`, in `dependencies`)
- [#4131](https://github.com/Urigo/accounter-fullstack/pull/4131)
[`4cdb553`](https://github.com/Urigo/accounter-fullstack/commit/4cdb553058e07928815b9fedfd1ff7fb86e6e702)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.30` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.30) (from
`4.0.27`, in `dependencies`)
- Updated dependency
[`@graphql-hive/yoga@0.49.1` ↗︎](https://www.npmjs.com/package/@graphql-hive/yoga/v/0.49.1) (from
`0.49.0`, in `dependencies`)
- Updated dependency [`ai@7.0.52` ↗︎](https://www.npmjs.com/package/ai/v/7.0.52) (from `7.0.48`, in
`dependencies`)
- [#4141](https://github.com/Urigo/accounter-fullstack/pull/4141)
[`16b88ca`](https://github.com/Urigo/accounter-fullstack/commit/16b88ca48ee1006f9d969bf7168455bfbe641eb5)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency [`auth0@6.2.0` ↗︎](https://www.npmjs.com/package/auth0/v/6.2.0) (from `6.1.0`,
in `dependencies`)
- [#4145](https://github.com/Urigo/accounter-fullstack/pull/4145)
[`e8120c7`](https://github.com/Urigo/accounter-fullstack/commit/e8120c7d3a92dd0dd1a22926b6e3f5d66e70e4c7)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency [`auth0@6.2.0` ↗︎](https://www.npmjs.com/package/auth0/v/6.2.0) (from `6.1.0`,
in `dependencies`)
- [#4146](https://github.com/Urigo/accounter-fullstack/pull/4146)
[`4b3cddc`](https://github.com/Urigo/accounter-fullstack/commit/4b3cddc633e8bcd1e4bf352623b8d59ecf0971e5)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.34` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.34) (from
`4.0.30`, in `dependencies`)
- Updated dependency [`ai@7.0.56` ↗︎](https://www.npmjs.com/package/ai/v/7.0.56) (from `7.0.52`, in
`dependencies`)
- Updated dependency [`googleapis@174.0.1` ↗︎](https://www.npmjs.com/package/googleapis/v/174.0.1)
(from `174.0.0`, in `dependencies`)
- [#4149](https://github.com/Urigo/accounter-fullstack/pull/4149)
[`40e131e`](https://github.com/Urigo/accounter-fullstack/commit/40e131ea47520879f220c4c7bec2f0b58a52d729)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency
[`@ai-sdk/anthropic@4.0.36` ↗︎](https://www.npmjs.com/package/@ai-sdk/anthropic/v/4.0.36) (from
`4.0.34`, in `dependencies`)
- Updated dependency [`ai@7.0.58` ↗︎](https://www.npmjs.com/package/ai/v/7.0.58) (from `7.0.56`, in
`dependencies`)
- [#4151](https://github.com/Urigo/accounter-fullstack/pull/4151)
[`eb09479`](https://github.com/Urigo/accounter-fullstack/commit/eb09479067ea9d968f43b210e52252e11cd384c6)
Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
- Updated dependency [`pg@8.23.0` ↗︎](https://www.npmjs.com/package/pg/v/8.23.0) (from `8.22.0`, in
`dependencies`)
- [#4049](https://github.com/Urigo/accounter-fullstack/pull/4049)
[`9c3a01b`](https://github.com/Urigo/accounter-fullstack/commit/9c3a01bf8d6124baa92778888c4c45cb9e665f1a)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Notify when a charge's main document and
main transaction settle in different currencies. The ledger `validate` resolver now surfaces an
error (shown by the client's `ChargeErrors` component) when a charge's main financial document
currency differs from its main transaction currency while the `invoice_payment_currency_diff` flag
is off, prompting the user to turn on the "Invoice-Payment currency difference" switch. The check
is display-only — it does not alter ledger record generation or storage, only fires when each side
resolves to a single differing currency, and falls back to no extra errors if the underlying meta
lookups fail.
- [#3979](https://github.com/Urigo/accounter-fullstack/pull/3979)
[`e3c844b`](https://github.com/Urigo/accounter-fullstack/commit/e3c844b49da2a7bec4094c7ed8f5052fe71504dc)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Exclude charge types that never require
document matching from the awaiting-match queue. Only COMMON, BUSINESS_TRIP and untyped charges
(which resolve to one of those) are expected to hold both documents and transactions;
BANK_DEPOSIT, CREDITCARD_BANK, DIVIDEND, FOREIGN_SECURITIES, INTERNAL, VAT, PAYROLL, CONVERSION
and FINANCIAL charges are now skipped.
- [#3983](https://github.com/Urigo/accounter-fullstack/pull/3983)
[`8ce1562`](https://github.com/Urigo/accounter-fullstack/commit/8ce1562f19af6cf35ec36a9a9c1be85d8e62f9f0)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Score charge-match candidates in parallel.
`findMatches` previously scored candidates in a sequential `await` loop, which serialized the
per-candidate client and issued-document-status DataLoader lookups inside `scoreMatch` into an
N+1. Scoring now runs with `Promise.all` so those loads batch. Ordering is unaffected (results are
sorted afterwards), so match output is unchanged.
- [#3982](https://github.com/Urigo/accounter-fullstack/pull/3982)
[`b97de0e`](https://github.com/Urigo/accounter-fullstack/commit/b97de0e153fcfa35ef598c9a99a908a934afc0ec)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Speed up the `chargesAwaitingMatchQueue`
query by building the match candidate pool once per request instead of once per queued charge.
`ChargesMatcherProvider` now exposes a batch `findMatchesForCharges`, which loads and classifies
the shared candidate pool a single time and scores every source charge against it in memory (the
per-source ±12-month window is still applied in-memory, so results are unchanged). This removes
the previous per-charge re-query and re-hydration of the candidate pool — the dominant cost,
especially for `BY_SCORE` which evaluated up to 100 charges.
Candidate charges are also filtered by `chargeRequiresMatch` before hydration, so charge types
that never require a document match (e.g. `BANK_DEPOSIT`, `CREDITCARD_BANK`, `VAT`) are no longer
loaded or offered as suggestions — mirroring the same filter already applied to the queue's source
charges.
- [#3816](https://github.com/Urigo/accounter-fullstack/pull/3816)
[`6963a16`](https://github.com/Urigo/accounter-fullstack/commit/6963a166897f794d86fad9bed173a31879e3e0db)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Enrich the charges `freeText` filter
(`allCharges` query) so it matches more than just text descriptions. In addition to the existing
`user_description` / transaction / document description matches, the `search_matches` CTE in
`ChargesProvider.getChargesByFilters` now also matches:
- **Amounts** — transaction `amount` and document `total_amount` / `vat_amount`. Both the raw and
`ABS()` values are compared so signed and unsigned inputs match. Thousands separators are
stripped from the search term (via a resolver-computed `freeTextNumeric` param) so both
`1,234.56` and `1234.56` match the plain value stored in the DB.
- **Counterparty business names** — by joining `financial_entities` on the business ids referenced
by the charge's transactions (`business_id`) and documents (`creditor_id`, `debtor_id`). The
document match is split into separate creditor/debtor `UNION` branches so the planner can use
the foreign-key indexes.
- [#3794](https://github.com/Urigo/accounter-fullstack/pull/3794)
[`ffcbb95`](https://github.com/Urigo/accounter-fullstack/commit/ffcbb9576241d6c31f4db2461b1ec12ca85b8b94)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Contract-generated document descriptions
now reflect the billing cycle: monthly contracts keep the billed-month label (`… - May 2026`),
while annual contracts use the contract's start & end dates
(`… January 15th, 2025 → January 14th, 2026`). Also parse `issueMonth` as local midnight to avoid
an off-by-one-month shift in timezones west of UTC.
- [#3850](https://github.com/Urigo/accounter-fullstack/pull/3850)
[`8d765c8`](https://github.com/Urigo/accounter-fullstack/commit/8d765c883a4457b2f22de5be0f95d0bd457d24f7)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - **Conversion charges with multiple
transactions per side**: conversion ledger generation no longer requires exactly two main
transactions. A single conversion can now be split across two or more transactions on the base or
quote side (for example two ILS credits against one USD debit).
- Main transactions are grouped by sign; each side is validated to be single-currency and the two
sides to differ in currency, with failures recorded as ledger errors instead of aborting
generation.
- Each side is aggregated into one representative entry (`aggregateConversionSideEntries`) that
feeds the existing fee and exchange-revaluation calculations, so the classic two-transaction
case is unchanged.
- [#3863](https://github.com/Urigo/accounter-fullstack/pull/3863)
[`35b1125`](https://github.com/Urigo/accounter-fullstack/commit/35b112532514b1447d615826943d192ed8a0d19f)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Add a "Pull Deel Documents" button to the
user nav menu, next to "Add Balance Charge", that triggers the `fetchDeelDocuments` mutation on
demand.
Also improves the underlying Deel invoice fetch/matching logic:
- Distinguishes newly-seen invoices from previously-fetched invoices that are still unmatched, so
a later run can pick up a payment match for an invoice it already recorded (via a new
`updateDeelInvoiceRecords` update path) instead of only ever inserting.
- Reuses an already-matched charge for a given receipt when creating charges from payment
breakdowns, avoiding duplicate charges for invoices that share a receipt.
- Extends the Deel invoice schema/table with `billing_type` and `document_type`, and refines
several payment-receipt and payment-breakdown Zod schemas to match the Deel API more closely.
- [#3873](https://github.com/Urigo/accounter-fullstack/pull/3873)
[`246b1e4`](https://github.com/Urigo/accounter-fullstack/commit/246b1e4d41a6424c4b9f251ff0b8cf36c774ab30)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - - **New helper function
`isSelfIssuedSenderEvidence()`** in `email-ingestion-issuer.helper.ts`: Detects when an email's
only determinable issuer is a known provider (Morning, Sumit) or the tenant's own forwarding
address, indicating no external counterparty. Reuses existing `selectIssuerEmail()` logic to
ensure consistency with issuer resolution.
- **Self-issued binding in control resolver** (`email-ingestion-control.resolver.ts`): When
`isSelfIssuedSenderEvidence()` returns true, the grant's `businessId` is set to the tenant's own
ID instead of the recognized business. This signals to the ingest step that the issuer is the
tenant itself. Also returns `null` for `businessEmailConfig` to spare the gateway needless
document work (link-fetch, body→PDF conversion).
- **Early short-circuit in ingest provider** (`email-ingestion-ingest.provider.ts`): After grant
validation, checks if `grant.businessId === tenantId`. If true, returns `DUPLICATE` outcome with
new `SELF_ISSUED` reason code, skipping all document processing (Cloudinary upload, OCR, dedup
queries, insert queries). Runs before `prepareDocuments()` to avoid unnecessary work.
- **New `IngestReasonCode.SELF_ISSUED`** constant in both `contracts.ts` files (server and
gateway): Distinguishes self-issued skips from content re-deliveries in duplicate outcomes.
- **Comprehensive test coverage**: Added test suites for the new helper function and ingest
behavior, verifying that self-issued emails are detected correctly, grants are consumed, and no
document work or database writes occur.
- [#3938](https://github.com/Urigo/accounter-fullstack/pull/3938)
[`2a0c041`](https://github.com/Urigo/accounter-fullstack/commit/2a0c041b0dc6104039304598f932e7990e84c2c0)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Automatically degrade a charge's accountant
approval (`APPROVED` → `PENDING`) whenever its underlying data changes, so an already-approved
charge is re-flagged for accountant review.
A shared `degradeChargesAccountantApproval` helper (built on
`AccountantApprovalProvider.degradeChargeAccountantApproval`) is now invoked from every
charge-mutating operation:
- **Documents** — upload / batch-upload / Google-Drive batch-upload / insert / update (former and
new charge) / delete / charge-spread.
- **Transactions** — `updateTransaction` and `updateTransactions`, degrading both the former and
the new charge.
- **Misc expenses** — insert / bulk-insert / update (former and new charge) / delete.
- **Charges** — `updateCharge`, `batchUpdateCharges` and `mergeCharges`. Tag-only changes and
explicit accountant-approval changes are intentionally excluded.
- **Ledger** — `regenerateLedgerRecords`.
- **Cron** — `mergeChargesByTransactionReference`.
The helper de-duplicates ids and ignores empty / `EMPTY_UUID` values (degrading a non-approved
charge is a no-op), and returns the freshly-degraded charges so mutations respond with the
up-to-date `PENDING` status rather than a stale one.
- [#3948](https://github.com/Urigo/accounter-fullstack/pull/3948)
[`f933c8c`](https://github.com/Urigo/accounter-fullstack/commit/f933c8cdc8a9dc5378ebb24d332af11079835c1b)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Pre-fill financial fields when switching an
"other"/"unprocessed" document to a financial type in the edit-document modal.
A document can be inserted carrying full financial data (date, amount, VAT, serial number,
debtor/creditor, etc.) while still categorized as `OTHER`/`UNPROCESSED`. Previously, editing such
a document and switching its type to a financial one (e.g. invoice) showed all extended attribute
fields empty — the stored values only appeared after saving and reopening the modal, once the
document re-resolved as a `FinancialDocument`.
The financial fields were only exposed on the `FinancialDocument` GraphQL types, so the edit query
could never fetch the already-stored values for `Unprocessed`/`OtherDocument`. These fields
(`vat`, `serialNumber`, `date`, `amount`, `vatReportDateOverride`, `noVatAmount`,
`allocationNumber`, `exchangeRateOverride`, `debtor`, `creditor`) are now exposed on the
`Unprocessed` and `OtherDocument` types and fetched by the client, and the edit form reads its
financial defaults from the document regardless of its current type — so switching to a financial
type immediately pre-fills the stored values.
- [#3836](https://github.com/Urigo/accounter-fullstack/pull/3836)
[`059b638`](https://github.com/Urigo/accounter-fullstack/commit/059b638702116701a5a0062a7ac3a58a28eeb004)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - - Add `exemptDealer`, `optionalVAT`,
`isReceiptEnough`, `isDocumentsOptional` and `isActive` to `BatchUpdateBusinessInput` in
`financial-entities/typeDefs/businesses.graphql.ts`.
- No resolver change is needed: these fields are already handled by the shared
`updateSingleBusiness` helper (`helpers/update-business.helper.ts`), and
`BatchUpdateBusinessInput` remains a strict structural subset of `UpdateBusinessInput`, so it is
still passed straight through. `isActive` flows to the core financial-entity update via
`hasFinancialEntitiesCoreProperties`; the rest map to the business row update. Tags and
description were already supported through the existing `suggestions` input.
- [#4127](https://github.com/Urigo/accounter-fullstack/pull/4127)
[`5bdeb5c`](https://github.com/Urigo/accounter-fullstack/commit/5bdeb5c61ef2ffc46d93e786cbd1afff0113c68d)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Fix email-ingestion falsely marking
forwarded supplier invoices as self-issued (SELF_ISSUED DUPLICATE) and silently dropping them.
When a supplier (e.g. Aiven) emails a tenant's Accounts-Payable Google Group, the mailing list
rewrites the quoted `From:` to the group's own forwarding address
(`'Aiven Billing' via Account Payables <ap@…>`). The real issuer's address survived only as a body
contact/footer `mailto:` link, which the issuer-candidate extractor did not harvest — so the only
recognized address was the forwarder, hard-coded as a self-issuing provider. The email was bound
to the tenant's own business and skipped at ingest as a `DUPLICATE` (`SELF_ISSUED`), inserting
nothing.
- **Gateway `mime-extractor.ts`**: harvest any body `mailto:` link (not only header-anchored
`From:`/`Reply-To:`/`Sender:` addresses) as lower-priority issuer candidates, so a real issuer
reachable only through a contact/footer link is still recovered for server-side recognition.
- **Server `email-ingestion-control.resolver.ts`**: a positive _external_ business recognition now
wins over the single-address self-issued heuristic. When recognition identifies a real
counterparty (any business other than the tenant), the documents are attributed to it and the
self-issued check is skipped, so a supplier invoice routed through the tenant's own forwarding
group is no longer misclassified.
- **Server `email-ingestion-ingest.provider.ts`**: the self-issued / tenant-matched path now
**QUARANTINEs** (recorded, visible, reprocessable) instead of silently returning `DUPLICATE`
with nothing written, so a misclassification is never silent data loss. The `SELF_ISSUED` reason
code now pairs with the `QUARANTINED` outcome.
- [#4124](https://github.com/Urigo/accounter-fullstack/pull/4124)
[`3f3c0bd`](https://github.com/Urigo/accounter-fullstack/commit/3f3c0bd2b29e6e7beaf370a41eb54cd87e5f10c0)
Thanks [@gilgardosh](https://github.com/gilgardosh)! - Fix v2 email ingestion stranding emails on
a failed document upload. The server consumed the single-use grant in its own committed
transaction before the fallible, non-transactional document preparation (Cloudinary upload, OCR),
so any failure there left the grant burned with **nothing** persiste