EmofyEmofy Developers
Architecture

Architecture Overview

The big-picture map of the Emofy Platform — apps, the backend pipeline, data, auth, and the ecosystem.

A high-level map of the platform for engineers. For the exhaustive System Architecture Definition (SAD), see docs/001_SYSTEM_ARCHITECTURE_DEFINITION.md in the repo. The pages in this section drill into each layer:

The shape of the system

                       ┌──────────────────────────────────────┐
                       │            account (Next.js)          │
   sign in  ──────────▶│   Better Auth — issues RS256 JWT      │
                       └──────────────────┬───────────────────┘
                                          │ JWT (+ JWKS for verification)
        ┌───────────────┬─────────────────┼──────────────────┐
        ▼               ▼                 ▼                  ▼
   consumer (web)   admin (web)      native (Expo)      EMAs (iframes)
        │               │                 │                  │
        └───────────────┴────────┬────────┴──────────────────┘
                                  │ REST  (Bearer JWT + X-Org-Id)

                      ┌───────────────────────┐      ┌──────────────┐
                      │    backend (NestJS)    │◀────▶│ Convex       │ real-time
                      │  the only DB writer    │      │ (messaging)  │
                      └───────────┬───────────┘      └──────────────┘
            ┌─────────────┬───────┼────────┬─────────────┐
            ▼             ▼       ▼        ▼             ▼
        Postgres       Redis   BullMQ  Meilisearch   R2 / S3
       (auth+core)    (cache) (queues)  (search)    (files/EMA bundles)

Everything funnels through one backend. The frontends never touch the database; they authenticate via the account app and call the backend over REST.

Apps

The platform is a Turborepo monorepo (pnpm workspaces). apps/ holds deployables, packages/ holds shared code — see the Repository tour for the full list.

AppStackRole
backendNestJS REST APIThe single API surface; deployed to Railway.
accountNext.js + Better AuthSign-in, account, and credential management.
adminNext.jsSuper-admin console.
consumerNext.jsParent / org web experience (/w/{orgId}/*).
nativeExpo / React NativeMobile app (demo-stage).
docsNext.js / FumadocsThis developer portal.
landing, marketingNext.jsPublic sites.

Backend pipeline

The backend is the only service that talks to the database. Every request flows through a global pipeline — authentication → org context → authorization → validation → handler → response envelope — built from an ordered chain of guards and interceptors. The exact order and what each stage does is on the Backend and Request lifecycle pages.

The backend publishes three OpenAPI documents from one shared DocumentBuilder (apps/backend/src/config/openapi-documents.ts):

  • Internal — the full surface used by the web/mobile dashboards ({ success, data } envelope).
  • Developer — the public partner API ({ data, meta } / { error } V1 envelope). A deterministic snapshot is committed and powers the Developer API Reference.
  • EMA — the surface available to Embedded Mini Apps.

See API conventions for how the three surfaces differ.

Auth & multi-tenancy

Authentication is Better Auth (RS256 JWT bearer tokens), issued by the account app and verified by the backend against a JWKS endpoint. The organization plugin models multi-tenancy: a user can hold roles in multiple organizations, and every request carries org context. Tenant isolation is enforced in the data layer by OrgScopedRepository — raw db.select() on tenant tables is forbidden.

Read the trust model in depth: Authentication, Authorization (RBAC), and Multi-tenancy.

Data & infrastructure

  • Database: Postgres via Drizzle ORM — two databases, emofyplatform_auth and emofyplatform_core (ADR-001).
  • Real-time: Convex powers live messaging and presence.
  • Cache & queues: Redis, with BullMQ for durable background jobs.
  • Search: Meilisearch (full-text across feed, messages, tasks).
  • Files: Cloudflare R2 (immutable EMA bundles) + S3 (org uploads).
  • Hosting: Frontends on Vercel; backend on Railway (GHCR image, CI deploy.yml), environments development / staging / main.
  • Infra as code: OpenTofu owns Vercel + Railway wiring; secrets sync from Infisical (ADR-016/017).

Ecosystem: EMAs and webhooks

Third-party and domain-specific features are built as EMAs (Embedded Mini Apps) that request scoped permissions (see EMA Scopes), and as webhook consumers that receive signed events (see Webhooks). The concept and lifecycle are covered in The EMA ecosystem.

On this page