Skip to main content

Agency Manager Backend Module Map

Purpose

This is the current backend ownership map for the shipped agency client-work slice.

Use it to answer:

  • which Convex modules already exist
  • which tables they currently own or read
  • which parts of the client-work model are surfaced versus still schema-only

Grounding Constraint

The current repo does not expose this slice through standalone registered clients, projects, time, billing, or documents API namespaces. Phase 8 has started colocating reusable implementation under top-level business owners, beginning with billing/catalog, billing/customers, billing/invoices, billing/quotes, billing/subscriptions, billing/transactions, billing/stripeConnect, billing/customerImports, billing/reconciliation, billing/financialOperations, and billing/webhooks, while the registered audience paths remain under org/clientBilling*.

Most client-work implementation is still grouped under packages/backend/convex/org/*.

Document that reality first. Do not describe extracted namespaces as if they already exist.

Current Ownership Map

organizations

Owns:

  • organization records
  • org memberships in orgUsers
  • membership resolution helpers
  • org selection and preference helpers

This is the current registered compatibility namespace for the future tenancy boundary. Its lifecycle, domain, and file-share workflows consume neutral access, audit, client-scope, billing-plan, and tenancy helpers; they no longer import private org implementation.

Primary files:

  • organizations/*
  • organizations/memberships.ts

viewer

Owns:

  • current viewer/session resolution used across surfaces
  • cross-surface identity helpers

This is still infrastructure, not client-work business state.

access/org

Owns the reusable organization-realm authorization implementation.

Owns:

  • org role resolution
  • org capability resolution for existing admin, billing, portal, and settings actions
  • org role policy loading from orgRolePolicies
  • per-membership capabilityMode and capabilityOverrides

Important limit:

The current capability system does not yet model the full planned client-work permission grammar. It is real for org admin and billing controls, but the new client-work routes still rely partly on coarse role checks.

The existing org/access/* files are organization-surface adapters while the namespace normalization remains in progress.

clients/scope.ts

Owns the current client-visibility rule for the org client-work slice.

Owns:

  • global client visibility for owners
  • scoped client visibility for non-owners through clientAccessAssignments
  • shared helpers used by the org client-work modules to filter visible client accounts

This file is the current source of truth for org client scope.

clients/readContext.ts

Loads organization datasets through the resolved client scope and exposes the shared visible-client context used by overview, analytics, project, billing, contract, time, and Drive read models.

clients/relationships/*

Owns client-facing staff relationships, portal-response handling, relationship contact normalization, and the relationship configuration read model. org/clientRelationship.ts is the registered staff facade.

clients/focus/*

Owns persistent per-user client focus state and its client-summary contract. clients/focus.ts is the registered client-focus family.

org/overview.ts and org/overview/*

Own the registered organization overview and attention API plus its scope-filtered operations read model.

org/analytics.ts and org/analytics/*

Own the registered analytics/configuration API, range-scoped aggregate read model, analytics configuration persistence, and project-billing classification.

org/preferences.ts and org/preferences/*

Own organization-user quick actions, pinned work, attention dismissals, visibility filtering, normalization, and no-op persistence guards.

Cross-surface support owners

  • audit/organization.ts: organization audit persistence
  • projects/contracts.ts: shared project status and visibility contracts
  • search/persistence.ts and search/portal.ts: same-mutation portal search projection and optional Meilisearch mirroring
  • billing/organizationPlans/repair.ts: organization plan repair-state classification
  • tenancy/billingIdentity.ts: unique organization billing-email policy

Portal and tenancy consumers use these owners directly and do not import private org modules.

providers/stripe

Owns all Stripe SDK access and provider-specific translation.

Owns:

  • runtime credentials, livemode enforcement, API version pinning, and clients
  • Stripe Connect OAuth, account inspection, and switch-blocker reads
  • catalog, customer, invoice, quote, subscription, and platform-billing request/response translation
  • webhook body limits, signature verification, and provider event construction
  • Stripe transport snapshots, validation, pagination, tax normalization, and idempotency contracts

Customer adapters are split into accounts, billing portal, payment-method safety, transactions, and import scanning. Subscription adapters are split into lifecycle, previews, schedules, collection, and normalization. Business authorization, Convex persistence, durable-write state, and registered functions remain with their billing, audience, and system owners.

billing/catalog

Owns the reusable connected-account product and price catalog implementation.

Owns:

  • generation-pinned catalog reads and persistence
  • connected-account catalog synchronization and durable Stripe writes
  • price-archive usage guardrails
  • catalog webhook projection and stale-event handling

The current registered adapters remain org/clientBilling.ts, org/clientBillingNodeActions.ts, and org/clientBillingWebhooks.ts. They retain audience authorization and runtime boundaries while calling the catalog implementation directly.

billing/customers

Owns the reusable connected-account billing-customer implementation.

Owns:

  • billing-profile persistence and client billing-activity updates
  • generation-pinned customer and Stripe connection context construction
  • billing-profile and customer manager contracts
  • orchestration of provider-owned customer provisioning, updates, recreation, tax-ID synchronization, snapshots, and billing-portal sessions
  • setup intents, default payment methods, guarded payment-method removal, and customer balance adjustments
  • customer webhook projection, tombstoning, and stale-event handling

The current registered adapters remain org/clientBilling.ts, org/clientBillingNodeActions.ts, and org/clientBillingWebhooks.ts. They resolve organization authorization, client visibility, and runtime boundaries and inject those capabilities into the customer implementation.

billing/invoices

Owns the reusable connected-account invoice implementation.

Owns:

  • generation-pinned invoice detail, manager context, payment snapshots, and contracts
  • draft creation, finalization, sending, reminders, partial collection, write-off, credit notes, refunds, voiding, and draft deletion
  • exact-once tracked-time reservation, attachment, release, and status follow-up
  • durable invoice snapshot synchronization and activity logging
  • invoice and payment webhook projection, deletion tombstones, search synchronization, and billing-state updates

The current registered adapters remain org/clientBilling.ts, org/clientBillingNodeActions.ts, and org/clientBillingWebhooks.ts. They retain organization authorization, client visibility, and runtime boundaries and inject those capabilities into the invoice implementation.

billing/quotes

Owns the reusable connected-account quote implementation.

Owns:

  • generation-pinned quote detail, manager context, and contracts
  • quote line items, draft creation and updates, finalization, acceptance, hosted/PDF URLs, revision, and cancellation
  • expiring, one-time PDF download tokens
  • durable quote snapshot synchronization
  • stale-aware quote webhook projection, search synchronization, billing activity, and connection-generation tagging

The current registered adapters remain org/clientBilling.ts, org/clientBillingNodeActions.ts, and org/clientBillingWebhooks.ts. They retain organization authorization, client visibility, and runtime boundaries and inject those capabilities into the quote implementation.

billing/subscriptions

Owns the reusable connected-account subscription implementation.

Owns:

  • generation-pinned subscription detail, manager context, and contracts
  • subscription creation, pricing changes, discounts, and trial management
  • schedules, collection pauses, service pauses/resumes, cancellation, and reactivation
  • durable subscription snapshot synchronization through the existing registered mutation boundary
  • stale-aware subscription webhook projection, search synchronization, and billing-profile aggregate-state recomputation

The current registered adapters remain org/clientBilling.ts, org/clientBillingNodeActions.ts, and org/clientBillingWebhooks.ts. They retain organization authorization, client visibility, finance step-up, registered paths, and runtime boundaries while injecting those capabilities into the subscription implementation.

billing/transactions

Owns the reusable connected-account transaction read model.

Owns:

  • connected-account payment and customer-balance provider reads
  • normalized, deduplicated, newest-first transaction projection
  • invoice, quote, subscription, and cached invoice-payment correlation
  • transaction response contracts
  • idempotent finance-event webhook persistence

The registered Node and webhook adapters remain org/clientBillingNodeActions.ts and org/clientBillingWebhooks.ts. They keep viewer authorization, registered paths, action query/mutation hops, org audit ownership, receipt persistence, and repair replay boundaries while injecting those capabilities into the transaction implementation.

billing/stripeConnect

Owns reusable connected-account lifecycle, generation, OAuth, switching, revocation, account-claim, readiness, and connection-projection policy. Registered org actions and callback/HTTP surfaces remain runtime and audience adapters.

billing/customerImports

Owns bounded Stripe customer discovery, deterministic review and matching, generation-pinned apply leases, idempotent client/profile linking, durable metadata writes, and resumable billing-history synchronization.

billing/reconciliation

Owns oldest-first connected-account health refresh, oldest-reconciled-first profile rotation, generation-pinned customer-history projection, monotonic page checkpoints, definitive missing-customer tombstones, retry/continuation policy, and exact completion.

The registered cron target and internal functions remain under org/clientBilling* until Phase 8.2. The adapters preserve every action transaction hop and inject runtime notification policy.

billing/financialOperations

Owns the reusable connected-account write safety protocol.

Owns:

  • exact actor, tenant, request, Stripe account, and generation reservations
  • provider-attempt leases and deterministic per-stage idempotency keys
  • durable intermediate/final provider checkpoints and retry classification
  • idempotent local projection, completion audit policy, and terminal recovery redaction
  • destructive-operation confirmation contracts
  • safe current-generation unresolved-operation visibility

Organization session, capability, email, and finance-step-up revalidation live under access/org. Portal tenant, client-grant, and support-session revalidation live under access/portal. Stable registered paths remain in org/clientBilling.ts until Phase 8.2.

billing/webhooks

Owns the connected-account webhook infrastructure.

Owns:

  • signed-request transport policy and the single atomic mutation hop
  • source-aware event deduplication and durable receipt persistence
  • exhaustive event classification and resource-projection dispatch
  • atomic projection, connection-receipt, webhook-receipt, and repair creation
  • bounded repair scanning, retry/backoff, generation-pinned replay, and explicit administrator retry or data-loss acknowledgement
  • privacy-first raw-payload retention and terminal repair marking
  • shared payload decoding and deterministic snapshot ordering

The registered HTTP, mutation, query, action, and cron compatibility paths remain under org/clientBilling* until Phase 8.2. Organization authorization, search indexing, audit persistence, and notification policy are injected at those adapters without splitting the existing mutation transactions.

Cross-cutting commercial read support

The former org/clientBilling access, contract, context, reference, shared, and validator buckets have been removed.

Current owners:

  • access/org/billing.ts: organization billing visibility and management policy
  • billing/overview: billing-summary contracts and aggregation
  • billing/catalog/contracts.ts: catalog read contracts
  • billing/commercialProvenance.ts: shared commercial provenance
  • projects/commercialContext.ts: organization project validation for commercial writes
  • time/contracts.ts and time/summary.ts: time response contracts and reusable time/project rollups
  • billing/{customers,invoices,quotes,subscriptions,stripeConnect}: resource-specific validators, contexts, and compact record references

The stable org/clientBilling.ts surface owns only organization scope, authorization, and registration for the manager-context reads. It calls the resource builders directly, preserving their single-query transaction.

org/clients.ts and clients/accounts/*

org/clients.ts owns the registered staff client API. Reusable client-account implementation lives under clients/accounts.

Owns:

  • listing visible client accounts
  • creating and editing client accounts
  • client detail, delivery, billing, portal-access, and operating-trend projections
  • client and contact lifecycle
  • client time insights
  • portal availability settings

Touches:

  • clientAccounts
  • clientContacts
  • client-owned project, billing, portal, file, note, and time records used by the consolidated client read model

org/documents.ts

Owns the current transitional org drive surface.

Owns:

  • drive-finder listing inside visible client scope on top of the legacy documents table

  • storage-backed upload URL generation

  • uploaded-file registration during the pre-drive migration phase Touches:

  • projects

  • clientAccounts

Not yet surfaced here:

Owns the live org time list/create surface.

Owns:

  • listing recent time entries inside visible client scope
  • logging draft time entries

Touches:

  • timeEntries
  • projects
  • clientAccounts

Not yet surfaced here:

  • approval or locking workflows
  • team-vs-own split behavior

org/clientBilling.ts

Owns the current org client billing workspace.

Owns:

  • billing-profile listing and upsert
  • invoice-record listing
  • subscription-record listing
  • billing access checks layered on the existing org capability model

Touches:

  • clientBillingProfiles
  • invoiceRecords
  • subscriptionRecords
  • clientAccounts

Important limit:

This is a read-heavy operational billing surface today. It is not yet a full Stripe-native invoice or subscription write surface.

org/documents.ts

Owns the live org documents workspace.

Owns:

  • document listing inside visible client scope
  • storage-backed upload URL generation
  • document registration after upload

Touches:

  • documents
  • _storage
  • projects
  • clientAccounts

Important limit:

Request flows, richer metadata edits, and review workflows are not yet surfaced.

portal/*

Current portal ownership is narrower than the older product docs implied.

Live portal areas include:

  • portal/account
  • portal/activity
  • portal support and account settings flows

The portal is not yet reading the new client-work tables through dedicated projects, files, or billing pages.

dev/seed/clientWork.ts

Owns the demo dataset for the org client-work slice.

This file is important product documentation by implementation because it shows the current seeded shape for:

  • client accounts
  • contacts
  • projects
  • project updates
  • time entries
  • billing records
  • documents
  • client-access assignments

Schema-Only Or Seed-Only Parts Of The Slice

These parts of the model exist, but are not yet first-class app surfaces:

  • clientContacts
  • projectUpdates

Those should be treated as the next surface work, not as missing schema.

Current Boundary Rule

For the shipped slice, keep using the current org/* family ownership until the detail workflows force a clearer extraction.

Do not create new top-level namespaces only because the product docs once recommended them. The current implementation is coherent enough to finish the first detail layer in place.

  • clientAccounts
  • clientContacts
  • clientAccessAssignments
  • orgRolePolicies
  • orgPermissionOverrides
  • projects
  • projectUpdates
  • timeEntries
  • clientBillingProfiles
  • invoiceRecords
  • subscriptionRecords
  • documents

Existing organization, membership, auth, and notification tables remain where they already belong.

Route Ownership Map

UI ownership should follow this backend map:

  • apps/app/src/app/[locale]/org/** create and manage client accounts, projects, time, billing visibility, and document sharing
  • apps/app/src/app/[locale]/portal/** consume client-safe summaries for projects, billing, and documents
  • apps/app/src/app/[locale]/platform/** later operate agencies, plans, support tooling, and cross-tenant concerns

Validation Scenarios

This module map should support these scenarios cleanly:

  • agency creates a client account without touching billing or project modules
  • agency connects Stripe without touching app SaaS billing state
  • agency adds a project and later exposes updates to the portal
  • staff logs time against a project without mutating the client account record itself
  • Stripe invoice state can sync into billing views without changing project or document records
  • Stripe subscription state can sync into billing views without changing project or document records
  • a shared document can be attached to a client account or project with explicit portal visibility
  • the portal dashboard can load a safe account summary through portal-facing projections without bypassing access boundaries