This document describes the system architecture for the Celerity POC Tracker, including the data model, entity relationships, and technology stack.
The application uses a multi-tenant architecture where each organization operates with isolated data. The system is built on Convex for the backend, which provides real-time data synchronization and TypeScript-first APIs.
The data model follows a hierarchical structure with organizations as the root tenant.
organizationsRoot tenant container. Each organization has isolated data and its own set of team members and clients.
| Field | Type | Description |
|---|---|---|
| name | string | Display name |
| slug | string | URL-safe identifier |
| createdAt | number | Unix timestamp |
teamMembersJunction table linking users to organizations with role assignments.
| Field | Type | Description |
|---|---|---|
| userId | Id<users> | Reference to user |
| organizationId | Id<organizations> | Reference to org |
| role | admin | account_manager | viewer | Org-level permission |
clientsCustomer accounts (brands) within an organization.
| Field | Type | Description |
|---|---|---|
| organizationId | Id<organizations> | Parent organization |
| name | string | Client/brand name |
| isActive | boolean | Active status |
channelsAdvertising platforms (lookup table shared across organizations).
| Field | Type | Description |
|---|---|---|
| name | string | Platform name |
| slug | string | URL-safe identifier |
| iconUrl | string? | Optional icon URL |
clientChannelsJunction table enabling clients to use specific channels.
| Field | Type | Description |
|---|---|---|
| clientId | Id<clients> | Reference to client |
| channelId | Id<channels> | Reference to channel |
| isActive | boolean | Active status |
campaignGroupsContainer for campaigns within a client-channel combination.
| Field | Type | Description |
|---|---|---|
| clientChannelId | Id<clientChannels> | Parent client-channel |
| name | string | Group name |
| weeklyBudget | number? | Budget allocation |
campaignsIndividual advertising campaigns with performance targets.
| Field | Type | Description |
|---|---|---|
| campaignGroupId | Id<campaignGroups> | Parent group |
| name | string | Campaign name |
| targetRoas | number? | Target ROAS |
weeklyMetricsWeekly performance data for each campaign.
| Field | Type | Description |
|---|---|---|
| campaignId | Id<campaigns> | Parent campaign |
| weekStart | string | ISO date (Monday) |
| adSpend | number | Spend in dollars |
| sales | number | Sales in dollars |
| roas | number | Return on ad spend |
The schema uses junction tables for many-to-many relationships.
organizations
│
├── teamMembers ──────► users
│
└── clients
│
└── clientChannels ──────► channels (lookup)
│
└── campaignGroups
│
└── campaigns
│
└── weeklyMetricsReal-time backend platform providing database, serverless functions, and authentication. Generates TypeScript types from schema definitions.
React framework with App Router architecture. Uses server and client components with Turbopack for development.
Utility-first CSS framework with custom design tokens. Supports dark/light themes via CSS variables.
Accessible component primitives built on Radix UI. Components are copied into the codebase rather than imported as a dependency.
Used throughout the stack. Convex automatically generates types from schema, providing end-to-end type safety.
Hosting platform for the Next.js frontend. Convex backend is hosted separately on Convex Cloud.