Skip to main content
FairLedger

Platform reference · v1.0

FairLedger API & Platform Documentation

How the FairLedger platform is composed, how to feed it data, and how to consume its evidence outputs. Written for engineering, compliance, and audit readers.

1. Platform overview

FairLedger is a multi-tenant SaaS platform that auto-evidences the two quantitative Consumer Duty outcomes — Price & Value and Products & Services — for UK payment and e-money firms. It ingests transactional and pricing data, computes reproducible metric snapshots, and assembles a board-ready evidence pack.

The stack is TanStack Start (React 19, Vite 7) on Cloudflare Workers with Supabase (Postgres + Auth + Storage) as the managed backend. All app-internal server logic is exposed through TanStack createServerFn RPC; public HTTP endpoints live under /api/public/*.

2. Authentication & roles

Authentication uses Supabase Auth (email + password, Google OAuth). Sessions are managed client-side and forwarded to server functions via a bearer-token middleware.

  • Platform roles (public.user_roles): admin, user.
  • Tenant roles (public.tenant_members): owner, admin, member, viewer.
  • Role checks use security-definer helpers has_role(), is_tenant_member(), is_tenant_admin().

3. Public HTTP endpoints

MethodPathPurpose
GET/sitemap.xmlMarketing sitemap for search engines
GET/robots.txtCrawler directives
POST/lovable/email/auth/webhookAuth email dispatcher (managed)
GET/lovable/email/transactional/previewTemplate preview (LOVABLE_API_KEY gated)

All public endpoints are rate-limited via the check_and_increment_rate_limit() function.

4. Server functions (typed RPC)

Client code calls these via useServerFn. Every mutating function enforces auth via requireSupabaseAuth middleware and validates input with Zod.

FunctionPurposeAuth
tenant.createCreate a new workspaceSigned-in user
tenant.listList workspaces the caller belongs toSigned-in user
tenant.addMemberInvite a user to a workspaceTenant admin/owner
ingest.uploadBatchValidate + store a CSV batchTenant member
ingest.analyseBatchCompute metric snapshot from batchTenant member
ingest.deleteBatchRemove batch + linked snapshotsTenant admin/owner
telemetry.trackStore analytics event (consent-gated)Public
launch.sendLaunchAnnouncementDispatch launch emailToken-gated

5. Ingestion schemas

Two CSV shapes are accepted today. Both are validated row-by-row with Zod; failing rows are preserved on the batch record for inspection.

5.1 Orders

ColumnTypeNotes
order_idstringUnique per row
skustringProduct identifier
quantityinteger > 0
unit_pricedecimal > 0In GBP
unit_costdecimal ≥ 0Optional; enables margin
customer_segmentstringOptional
occurred_atISO-8601 date/time

5.2 Price list

ColumnTypeNotes
skustringProduct identifier
list_pricedecimal > 0Published price in GBP
effective_fromISO-8601 date

6. Evidence & board pack

Every successful analysis writes an immutable snapshot to public.metric_snapshots. The Evidence view surfaces:

  • Headline metrics: revenue, margin, SKU count, price dispersion.
  • Fair-Price Gap table: outliers vs. published price list.
  • Top-10 SKU breakdown and monthly revenue series.
  • One-click PDF board pack (React PDF) with methodology appendix.

7. Email & webhooks

Email is sent via Lovable Emails from notify.fairledger.co.uk. The auth webhook route delegates to createAuthEmailHandler; app emails call sendTemplateEmail() from src/lib/email-templates/send-email.ts. Terminal delivery events (bounce, complaint, unsubscribe, resubscribe) can be handled at /lovable/email/events.

8. Security controls

  • Row-Level Security on every tenant-scoped table.
  • Rate limiting on all public write endpoints.
  • Cookie consent (GDPR/PECR) with granular categories.
  • Client-side error capture into client_errors.
  • Audit trail for tenant events in audit_events.
  • Storage bucket tenant-uploads is private; folder-isolated per tenant.

9. Backups & disaster recovery

Point-in-time recovery is enabled on the managed Postgres instance. Storage objects are replicated by the platform. RTO target: 4 hours. RPO target: 15 minutes. Full runbook: docs/DR_RUNBOOK.md.

10. Versioning

This document tracks the deployed platform. Breaking schema changes are gated behind a migration; server-function signatures are versioned via filename (e.g. ingest.functions.ts). Consumers should pin the documented behaviour to the release notes for their integration date.

© 2026 FairLedger Ltd — Platform reference v1.0.