Skip to content

feat: implement issues #626–#629 — multi-currency FX, tax engine, payment reconciliation, cohort analytics - #665

Merged
Smartdevs17 merged 1 commit into
Smartdevs17:mainfrom
devsimze:feat/issues-626-627-628-629-fx-tax-reconciliation-cohorts
Jul 29, 2026
Merged

feat: implement issues #626–#629 — multi-currency FX, tax engine, payment reconciliation, cohort analytics#665
Smartdevs17 merged 1 commit into
Smartdevs17:mainfrom
devsimze:feat/issues-626-627-628-629-fx-tax-reconciliation-cohorts

Conversation

@devsimze

@devsimze devsimze commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements four platform-services issues:

#628 — Automated payment reconciliation

  • Matching engine: exact match (reference/txHash, or amount+date within a tight window), fuzzy match (amount tolerance + date window, confidence score), never crosses currencies, never double-claims a record, leaves split/partial payments as exceptions.
  • Exception handling workflow (open → investigating → resolved/written_off, with assignee + resolution note).
  • Reconciliation reporting, analytics (match rate, exception aging/trend), and CSV export.
  • REST API + a daily scheduled task (daily-payment-reconciliation, 0 5 * * *).
  • Named payment-reconciliation throughout (routes/services/mount path) — this repo already has an unrelated on-chain balance reconciliation feature (Backend: Add Payment Reconciliation Report Generator with CSV/PDF Export #465) at routes/reconciliation.ts / /api/v1/reconciliation / services/reconciliation/, so a distinct name avoided clobbering it.
  • Docs: backend/docs/PAYMENT_RECONCILIATION.md.

#627 — Jurisdiction-aware tax engine

  • Per-jurisdiction tax rule CRUD (rate, effective window, type: VAT/GST/sales tax/withholding).
  • Automated calculate() with exemption lookup and an audit-log entry per calculation.
  • Compliance checks (missing rules, expired exemptions, overlapping rule windows) and exemption lifecycle management.
  • Layered onto the existing tax-reports.ts/routes/tax.ts (Issue Add tax report generation for merchant compliance #351) rather than duplicating it — new endpoints appended, existing ones untouched.
  • Docs: backend/docs/TAX_ENGINE.md.

#626 — Multi-currency invoices with FX conversion

  • FxService: TTL-based rate cache (each fetch is a new FxRate row, so history comes for free), pluggable rate source (documented placeholder — swap in a real forex API), conversion, and threshold-based rate alerts.
  • Multi-currency invoice generation (locks the FX rate at generation time) and reconversion at payment time, plus multi-currency reporting — added to the existing invoice service/routes.
  • Docs: backend/docs/FX_CONVERSION.md.

#629 — Subscription cohort retention analytics

  • In-memory, event-sourced cohort service (matches this repo's existing lightweight analytics.ts pattern rather than adding new schema, since there's no persisted subscription-lifecycle table to build on).
  • Retention curves, revenue cohort analysis, churn cohort analysis (with cumulative churn), cohort comparison, and CSV export.
  • Docs: backend/docs/COHORT_ANALYTICS.md.

Schema

New Prisma models: ReconciliationBatch/Record/Match/Exception, TaxJurisdictionRule/TaxExemption/TaxCalculationAuditLog, FxRate/FxRateAlert, plus presentmentCurrency/presentmentAmount/fxRate/fxRateLockedAt on Invoice. Migration: backend/prisma/migrations/20260629130000_reconciliation_tax_fx/.

Known pre-existing issue, not introduced or fixed by this PR: schema.prisma on main currently defines enum SubscriptionStatus twice (once for the Stripe-style Subscription model, once under "New Enums"), which breaks prisma generate/prisma validate for the whole schema. I verified this PR's additions are valid in isolation (temporarily renamed the second enum locally, confirmed prisma validate passes, then reverted). Left it untouched since I don't know which of the two definitions is authoritative — flagging for maintainers.

Test plan

  • npx vitest run src/services/__tests__/payment-reconciliation.test.ts src/services/__tests__/tax-engine.test.ts src/services/__tests__/fx-service.test.ts src/services/__tests__/cohort-analytics.test.ts src/services/__tests__/tax-reports.test.ts — 92/92 passing
  • tsc --noEmit — zero new errors attributable to any file touched in this PR (verified by diffing against the pre-existing baseline error set)
  • All new services run against an in-memory fallback when DATABASE_URL is unset, matching the pattern used by services/archival/ and services/vaults/

Closes #626
Closes #627
Closes #628
Closes #629

…cy FX, tax engine, payment reconciliation, cohort analytics

Adds four platform-services features:

- Smartdevs17#628 Automated payment reconciliation: exact/fuzzy matching engine,
  exception workflow, reconciliation reporting/analytics, REST API, and a
  daily scheduled task. Named `payment-reconciliation` throughout (routes,
  services, mount path) to avoid colliding with the existing unrelated
  on-chain balance-reconciliation feature (Smartdevs17#465) already at
  routes/reconciliation.ts and /api/v1/reconciliation.
- Smartdevs17#627 Jurisdiction-aware tax engine: per-jurisdiction rule CRUD, automated
  calculation with exemption handling, compliance checks, and an audit
  trail — layered onto the existing tax-reports service/routes.
- Smartdevs17#626 Multi-currency invoices: FX rate cache with TTL (and free history via
  cache rows), pluggable rate source, threshold alerts, and multi-currency
  invoice generation/reconversion/reporting on the existing invoice service.
- Smartdevs17#629 Subscription cohort analytics: in-memory retention/revenue/churn
  cohort analysis, comparison, and CSV export, matching this codebase's
  existing lightweight analytics-service pattern.

New Prisma models: ReconciliationBatch/Record/Match/Exception,
TaxJurisdictionRule/TaxExemption/TaxCalculationAuditLog, FxRate/FxRateAlert,
plus presentment-currency fields on Invoice.

Known pre-existing issue (not introduced here, not fixed): schema.prisma on
main currently defines `enum SubscriptionStatus` twice, which breaks
`prisma generate`/`validate` for the whole schema. Verified our additions
are valid in isolation; left the duplicate untouched since resolving it
requires knowing which of the two call sites is authoritative.

Closes Smartdevs17#626, Smartdevs17#627, Smartdevs17#628, Smartdevs17#629

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

@Abidoyesimze is attempting to deploy a commit to the smartdevs17's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jul 29, 2026

Copy link
Copy Markdown

@devsimze Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Smartdevs17
Smartdevs17 merged commit 6974473 into Smartdevs17:main Jul 29, 2026
9 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants