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
capabilityModeandcapabilityOverrides
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 persistenceprojects/contracts.ts: shared project status and visibility contractssearch/persistence.tsandsearch/portal.ts: same-mutation portal search projection and optional Meilisearch mirroringbilling/organizationPlans/repair.ts: organization plan repair-state classificationtenancy/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 policybilling/overview: billing-summary contracts and aggregationbilling/catalog/contracts.ts: catalog read contractsbilling/commercialProvenance.ts: shared commercial provenanceprojects/commercialContext.ts: organization project validation for commercial writestime/contracts.tsandtime/summary.ts: time response contracts and reusable time/project rollupsbilling/{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:
clientAccountsclientContacts- 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
documentstable -
storage-backed upload URL generation
-
uploaded-file registration during the pre-drive migration phase Touches:
-
projects -
clientAccounts
Not yet surfaced here:
-
projectUpdates -
project detail or publish workflows
-
This is not the final drive backend. The target model moves to
driveItems,fileAssets,richDocuments, andfileRequestsas defined in client-drive-spec.md and ../development/client-drive-implementation-plan.md.
Owns the live org time list/create surface.
Owns:
- listing recent time entries inside visible client scope
- logging draft time entries
Touches:
timeEntriesprojectsclientAccounts
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:
clientBillingProfilesinvoiceRecordssubscriptionRecordsclientAccounts
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_storageprojectsclientAccounts
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/accountportal/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:
clientContactsprojectUpdates
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.
clientAccountsclientContactsclientAccessAssignmentsorgRolePoliciesorgPermissionOverridesprojectsprojectUpdatestimeEntriesclientBillingProfilesinvoiceRecordssubscriptionRecordsdocuments
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 sharingapps/app/src/app/[locale]/portal/**consume client-safe summaries for projects, billing, and documentsapps/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