Create your own
Lesson illustration

End-to-End Architecture: Next.js, FastAPI, Claude, Supabase, Integrations, and AWS

You now have the two architectural constraints that matter most: a clear growth-workflow blueprint and a tenant-access policy. This lesson turns them into a deployable system shape: where each responsibility lives, which components may communicate, and where tenant security, AI governance, and operational reliability are enforced.

The goal is not to choose every AWS setting today. It is to create a reference architecture that remains valid as you build lead research, qualification, outreach approvals, CRM synchronization, analytics, and recommendations.

By the end, you will have a diagram and a concise architecture document for a production-oriented, multi-tenant command center.


Start with the architectural decision record

Your system is a hybrid SaaS architecture:

  • AWS runs your application compute, async workers, secrets, logs, queues, container images, and tenant-scoped files.
  • Supabase provides authentication and the shared PostgreSQL system of record for product data.
  • Anthropic Claude is an external model provider, accessed only by trusted backend services.
  • GoHighLevel and Airtable are external systems integrated through backend connector code.
  • Next.js is the client-facing command center.
  • FastAPI is the product’s policy-enforcement and orchestration boundary.

This division matters because it avoids two common failures:

  1. Putting sensitive logic in the frontend, such as Claude calls, connector tokens, or direct CRM mutation.
  2. Treating an external system as if it were your canonical product database.

For your SaaS, Supabase is the canonical source of truth for your workflow and governance records. GoHighLevel remains authoritative for live CRM delivery and opportunity state; Airtable is an intake source. FastAPI is responsible for translating between these systems while enforcing the organization boundary from the previous lesson.

Here is the proposed v1 deployment decision:

ConcernChosen componentArchitectural rule
Client dashboardNext.js on AWS Amplify HostingNo provider keys, service keys, or connector credentials reach the browser.
AuthenticationSupabase AuthUsers authenticate globally; FastAPI validates each request and resolves active organization membership.
Product APIFastAPI on Amazon ECS FargateAll protected product operations pass through FastAPI.
Long-running automationPython worker on ECS FargateWorkers consume only durable jobs and re-validate tenant context before acting.
Durable job queueAmazon SQS with dead-letter queueQueue messages identify work; they should not carry unnecessary customer data.
Product dataSupabase PostgresTenant-owned tables use organization_id, RLS, and tenant-consistent relationships.
AI featuresClaude API from FastAPI or workersClaude is never called directly from the browser and never receives authority to act on its own.
Integration credentialsAWS Secrets ManagerCredentials are decrypted only by narrowly permitted backend task roles.
Files and export artifactsAmazon S3The API issues scoped access; object paths and policies remain tenant-aware.
ObservabilityAmazon CloudWatchAPI, worker, queue, and connector failures are observable by tenant and run.

This makes the central boundary easy to remember:

Next.js presents the workspace; FastAPI enforces product policy; workers perform durable work; Supabase preserves the tenant-scoped record of what happened.


Study the AWS execution model

Guidance for Building a Containerized and Scalable Web ...

Read AWS’s reference guidance to anchor the ECS, load-balancing, autoscaling, and operational parts of your design. It is a general three-tier example, so focus on the operational roles of the services rather than copying its identity or data-store choices.

In Overview, read the overview and inspect the accompanying architecture diagram. Then, in Well-Architected Pillars, find the Reliability discussion. Read the ALB and Fargate discussion. Relate the load-balanced service to FastAPI and the independently scaled background service to your automation worker.

A useful distinction is that API scaling and worker scaling solve different problems.

  • The FastAPI service scales with interactive demand: dashboard reads, approval actions, contact edits, and short AI drafting requests.
  • The worker service scales with queued work: imports, enrichment, CRM synchronization, multi-step automation, and retries.
  • The SQS queue absorbs bursts. A large Airtable import should not slow an operator trying to review an outreach draft.
  • A dead-letter queue preserves jobs that repeatedly fail, rather than retrying them forever without visibility.
This AWS diagram depicts an SQS queue feeding several ECS Fargate worker tasks, with CloudWatch alarms informing autoscaling and completed work sent to downstream systems. In your command center, the downstream systems are Supabase, Claude, GoHighLevel, Airtable, and S3; this pattern applies to the worker service, not to browser requests.

Your API and worker should run as separate ECS services even if they initially share much of the same Python package. They have different inbound access, scaling signals, timeout profiles, and permissions:

ServiceReceivesMay initiateMust not do
FastAPI APIAuthenticated browser requests and verified webhooksShort database work, Claude requests, job submissionBlock on a long import or expose credentials
Automation workerSQS messages onlyConnector calls, long-running research, retries, status updatesAccept public internet traffic
Webhook handlerSigned external provider webhook requestsVerification, idempotent event persistence, downstream job submissionTreat a provider payload as already authorized tenant data

For v1, deploy FastAPI and worker tasks in private subnets. An internet-facing Application Load Balancer terminates HTTPS and routes only public API and webhook requests to FastAPI. The worker has no public listener.

Because Claude, Supabase, GoHighLevel, and Airtable are managed external services, private tasks need controlled outbound network access. The important principle at this stage is not the exact networking product selection; it is that outbound access is deliberate, logged where practical, and paired with least-privilege credentials.


The end-to-end reference architecture

The following is the architecture to place in your product documentation. It deliberately separates the public UI, trusted application runtime, managed data, and external providers.

Read the diagram from the trust boundaries inward:

  1. The browser is untrusted. It can request actions and supply an active organization identifier, but it cannot establish its own authority.
  2. Next.js renders the command center and manages client experience. It does not become the location for privileged integrations.
  3. FastAPI is the public product boundary. It validates tokens, resolves the organization, checks role and workflow state, and decides whether work is immediate or asynchronous.
  4. The worker is trusted infrastructure, but still not omnipotent. It must re-load the automation run and verify its organization, connector connection, state, and allowed action.
  5. Supabase stores the durable, tenant-scoped evidence of work: contacts, campaigns, approvals, events, automation runs, outputs, and audit entries.
  6. Claude and integration providers are outside your trust boundary. Inputs are minimized, validated, and tied to one authorized organization.

Keep Claude behind the service boundary

For product automation, Claude is a dependency of your backend, not a frontend feature.

This diagram shows business logic and user interface code above an Agent SDK layer, which manages tool routing, streaming, state, and error handling before requests reach the Claude API. In this command-center architecture, FastAPI and the worker service occupy the trusted orchestration layer: they define allowed tools and handle model outputs before any CRM, database, or file action occurs.

The diagram’s main lesson is ownership: your application owns business rules and tool definitions. An AI integration SDK can reduce plumbing, but it cannot decide whether an operator may access Client A’s CRM record or activate Client B’s campaign.

Your v1 rule should therefore be:

  • Next.js may show a Claude-generated result.
  • FastAPI or a worker sends the Claude request.
  • FastAPI constructs the request using validated tenant configuration, source evidence, and user intent.
  • FastAPI validates the response before storing or displaying it.
  • A model-proposed tool action returns to backend code for authorization.
  • Connector code, not Claude, performs a GoHighLevel or Airtable action.

How To Build an API with Python (LLM Integration, FastAPI, Ollama & More)

Watch “How To Build an API with Python (LLM Integration, FastAPI, Ollama & More)” by Tech With Tim for the core reason to place an API between a frontend and a language model: central control of secrets, access, and usage.

Watch the opening rationale. Focus on the architectural principle rather than the tutorial’s particular local-model tooling: an application API is where you protect model credentials and apply user-level access or usage controls.

Use two execution modes for AI features:

ModeSuitable examplesWhere it runs
InteractiveDraft outreach copy, summarize review evidence, answer a dashboard questionFastAPI, with a strict timeout and optional streamed response
DurableResearch a lead list, enrich many companies, generate a campaign asset batch, retry a failed external API requestWorker, initiated from SQS and recorded as an automation run

A short interactive request can return a validated draft to a reviewer. A lead-enrichment batch should create a durable run first and return promptly with a status the command center can monitor.


Make the four key flows explicit

An architecture diagram is valuable only if the important flows have clear contracts. These are the four that your product needs from day one.

1. Authenticated dashboard request

  1. The user signs in through Supabase Auth and receives a session access token.
  2. Next.js renders the workspace and its typed API client includes that token when calling FastAPI.
  3. FastAPI validates the token, resolves the requested active organization through an active membership, and checks the required permission.
  4. FastAPI queries only records belonging to that organization and returns a role-appropriate response.
  5. Supabase RLS remains a second enforcement layer for browser-accessible data and accidental query mistakes.

The browser should not use a Supabase service key, AWS credential, GoHighLevel credential, Airtable token, or Anthropic API key.

2. Claude-assisted product action

Consider an operator who asks for an outreach draft.

  1. The browser sends the prospect ID, campaign context, and requested action to FastAPI.
  2. FastAPI validates the user, role, active organization, prospect ownership, campaign state, and consent-related workflow conditions.
  3. FastAPI retrieves approved tenant context and evidence from Supabase.
  4. FastAPI sends only the necessary information to Claude using a typed request.
  5. FastAPI validates the returned structure, stores the draft as a tenant-owned version, and records model usage metadata.
  6. The UI displays the draft for review; it does not automatically publish it.

Later lessons will make the prompt contract, response schema, tool allowlist, cost metering, and prompt-injection defenses explicit. The architecture already reserves the correct enforcement point for all of them.

3. Durable automation run

Consider importing 5,000 leads from Airtable or synchronizing campaign results from GoHighLevel.

  1. FastAPI authorizes the request and inserts an automation_run in Supabase with the active organization_id, initiator, action type, and idempotency key.
  2. FastAPI sends a minimal SQS message containing the run ID and enough routing metadata to locate it safely.
  3. The worker receives the message and re-loads the automation run from Supabase.
  4. The worker verifies state, tenant ownership, connector scope, and idempotency before any external call.
  5. The worker records step status and connector attempts in Supabase.
  6. If retries are exhausted, SQS places the message in the dead-letter queue and CloudWatch raises an operational signal.

The queue should not become a hidden database. Store the durable state in Supabase; use SQS to reliably schedule processing.

4. Incoming integration webhook

GoHighLevel may send contact, opportunity, or delivery events to your platform.

  1. GoHighLevel sends a webhook to a dedicated FastAPI webhook route behind the Application Load Balancer.
  2. FastAPI verifies the provider signature and identifies the linked tenant integration connection.
  3. FastAPI persists a provider event ID for idempotency before processing the business payload.
  4. FastAPI records a normalized tenant-scoped event in Supabase.
  5. If follow-up work is required, FastAPI submits a worker job rather than blocking the webhook acknowledgment.

Never identify a tenant from a provider payload field alone. The integration connection configuration, signature verification result, and stored external-account linkage must all agree on the organization.


Frontend environment and deployment boundaries

You have chosen AWS Amplify Hosting for the production Next.js client, not a self-hosted Next.js container. That is a good v1 choice because it keeps frontend hosting operationally separate from your Python services.

Still, the Next.js environment-variable rules are essential: whether the app is hosted by Amplify or a container platform, a value exposed to browser JavaScript is public by design.

Guides: Self-Hosting

Read the “Environment Variables” section in the official Next.js documentation. Although this architecture uses Amplify Hosting rather than a self-hosted Next.js service, the public-versus-server environment boundary and promotion principle apply directly.

In Environment Variables, read the environment-variable guidance. Pay particular attention to the NEXT_PUBLIC_ convention: treat every such value as visible to a user of your SaaS.

For the command center, the only frontend configuration values likely to be public are values such as:

  • The API base URL, for example https://api.yourdomain.com
  • The Supabase project URL
  • The Supabase anonymous browser key
  • A non-secret deployment or release identifier

These are never public:

  • ANTHROPIC_API_KEY
  • Supabase service_role key
  • GoHighLevel access tokens
  • Airtable personal access tokens
  • Webhook signing secrets
  • Encryption keys
  • AWS access credentials
  • Database passwords

Put private runtime values in AWS Secrets Manager, and grant each ECS task role access only to the secrets it requires. For example, a worker that performs Airtable intake should not automatically be able to read a GoHighLevel credential for every client.

Do not add Redis merely because Next.js documentation discusses shared caches for multi-instance self-hosting. Amplify avoids that specific self-hosted-cache decision. Add a shared cache only when you identify a real performance need and can define tenant-safe cache keys and invalidation behavior.


Turn the diagram into a build artifact

Create this document now:

docs/product/reference-architecture.md

Use this outline:

# Reference Architecture

## Purpose
- Multi-tenant B2B growth command center
- AWS execution environment with Supabase as the product data system of record
- Explicit non-goals for v1

## System diagram
- Insert the Mermaid diagram from this lesson
- Record diagram version and last-reviewed date

## Component responsibilities
- Next.js on Amplify
- FastAPI API service
- Python worker service
- Supabase Auth and Postgres
- SQS and dead-letter queue
- Secrets Manager, S3, ECR, CloudWatch
- Claude, GoHighLevel, and Airtable

## Trust boundaries
- Browser
- Public API and webhook routes
- Private ECS services
- Managed data services
- External AI and integration providers

## Request and event flows
- Authenticated dashboard request
- Claude-assisted request
- Durable automation run
- Incoming webhook

## Tenant-safety invariants
- FastAPI derives active organization from validated membership
- Every worker job re-validates organization context
- External connection belongs to the same organization as the record
- Browser never receives privileged credentials
- Claude has no independent authority to mutate product or CRM records

## Deployment and operations
- Amplify for Next.js
- ALB plus ECS Fargate for FastAPI
- ECS Fargate worker scaled from SQS metrics
- ECR for backend images
- CloudWatch logs, metrics, alarms, and run correlation
- Secrets Manager for runtime credentials

## Open decisions
- Exact AWS networking layout
- Object retention and export-deletion policy
- Tenant rate limits and usage budgets
- Streaming UX requirements

Before accepting the architecture, use this checklist:

  • The browser has no direct route to Claude, GoHighLevel, Airtable, Secrets Manager, or privileged Supabase access.
  • Every external CRM or AI action passes through FastAPI or the worker.
  • Every tenant-owned action can be tied to an active organization and, when relevant, an automation run.
  • FastAPI and workers are separate ECS services with distinct scaling and permissions.
  • Webhooks are verified and idempotent before they affect the product state.
  • Supabase remains the source of truth for product workflow, approvals, events, and run history.
  • The architecture includes a durable failure path through SQS, dead-letter handling, and CloudWatch visibility.

Key takeaways

Your command center is a multi-tenant system with a deliberately narrow control plane:

  • Next.js on Amplify provides the client workspace.
  • Supabase Auth identifies users; FastAPI validates tokens, memberships, roles, and workflow state.
  • Supabase Postgres holds canonical product and governance data under tenant-scoped controls.
  • FastAPI on ECS Fargate handles interactive, authenticated API work and verified webhooks.
  • Workers on ECS Fargate execute durable automation from SQS, with run state stored in Supabase and failures routed to a dead-letter queue.
  • Claude, GoHighLevel, and Airtable are external dependencies, reached only through trusted backend paths.
  • Secrets Manager, S3, ECR, and CloudWatch provide the operational backbone for a deployable AWS system.

Next, you will scaffold the repository that embodies these boundaries: a FastAPI backend and a Next.js frontend, organized so this reference architecture can become working code rather than remain a diagram.

Can't find a good explanation? Sign up and we'll make it for you

Sign up