Forge64 logo
All app types

SaaS dashboard architecture

SaaS dashboard architecture: the decisions that matter

The architecture of a SaaS dashboard comes down to 3 choices: organisation-scoped tenancy enforced by RLS plus one helper, append-only partitioned audit log written in the same transaction and transactional outbox for signed outbound webhooks. Each is explained below with the alternatives that were rejected and what you accept by choosing it.

Last checked

Organisation-scoped tenancy enforced by RLS plus one helper

Situation: A SaaS leaks catastrophically if a single query forgets its tenant filter; hand-written WHERE clauses do not scale across a growing team or generated code.

Choice: Every org-owned table carries org_id with a Postgres RLS policy keyed to a per-request setting, and all data access goes through withOrg() which verifies membership first.

  • Rejected: Application-level WHERE org_id filters only: one missed clause is a breach.
  • Rejected: Database per organisation: strongest isolation but migrations and connection counts explode at thousands of orgs.
  • Consequence: Cross-tenant bugs fail closed at the database.
  • Consequence: Every request pays one SET LOCAL; connection pooling must be transaction-scoped.
  • Consequence: Large tenants are isolated by index design, not by hardware, until a dedicated tenant is warranted.

Append-only partitioned audit log written in the same transaction

Situation: Enterprise buyers and incident response need a trustworthy record; best-effort async logging loses the events that matter.

Choice: Write audit rows inside the business transaction with INSERT-only privileges, partitioned monthly with retention by plan.

  • Rejected: Application log lines only: not queryable by customers and easily lost.
  • Rejected: Separate audit service: more infrastructure than phase 1 needs.
  • Consequence: Small write overhead per sensitive action.
  • Consequence: Retention and export are plan features.
  • Consequence: Tamper resistance is by privilege, with hash chaining available later.

Transactional outbox for signed outbound webhooks

Situation: Customers build on webhooks and expect at-least-once delivery without being attacked through them.

Choice: Insert delivery rows in the domain transaction, deliver from a SKIP LOCKED worker with HMAC signatures, backoff, SSRF guards and automatic endpoint disabling.

  • Rejected: Fire-and-forget POST in the request: lost on failure and blocks latency.
  • Rejected: Third-party webhook relay: adds cost and a data processor.
  • Consequence: At-least-once delivery, consumers dedupe by event id.
  • Consequence: Queue depth and failure ratio become first-class alerts.

How the data is indexed

Indexes are chosen from the questions the app asks most often. Each line below names a table and the question its main index answers.

  • organizations: unique (slug) — tenant URL and subdomain lookup.
  • memberships: unique (org_id, user_id) — a user has one membership per org.
  • invitations: unique (token_hash) — accept link resolves in one lookup.
  • usage_events: unique (org_id, idempotency_key) — retries never double-count.
  • usage_rollups: unique (org_id, meter, period_start) — one row per meter per billing period, upsert target.
  • api_keys: unique (prefix) — request auth finds the key by its public prefix.
  • audit_log: (org_id, created_at DESC) — audit page, keyset paginated.
  • webhook_endpoints: (org_id, status) — endpoints for an org, fan-out lookup.

What Forge64 provides underneath

Forge64 matches your description to one of 12 reference architectures, writes the plan and data model into the project, generates the app, and runs a quality gate over the code before you see it. Each app gets its own Postgres database and sign-in with no per-user fee. Hosting on Forge Cloud and Forge Payments are rolling out.

This is a reference design for the category, not a promise that every item is generated today. Built-ins such as email, background jobs, file uploads and search are coming soon, so anything here that needs them is something you add yourself for now.

FAQ

What is the most important architecture decision for a SaaS dashboard?
Organisation-scoped tenancy enforced by RLS plus one helper. Every org-owned table carries org_id with a Postgres RLS policy keyed to a per-request setting, and all data access goes through withOrg() which verifies membership first.
Do I have to make these decisions myself?
No. Forge AI plans them from your description and writes the decisions into the project as architecture records you can read and change.
What do the alternatives cost me?
For example, for "Append-only partitioned audit log written in the same transaction": Application log lines only: not queryable by customers and easily lost. Separate audit service: more infrastructure than phase 1 needs.

Build your app with Forge64

One prompt to a running app with auth, database, hosting and payments. Start free, no credit card required.

Start building for free