Horizontal services consumption — quick reference
Tier: Public
Status: v1.0 (contributor cheat sheet)
Audience: module authors, vertical builders, third-party integrators.
One-page summary of RFC-0001 §8 (Decision F). Consume platform services; never reimplement them.
Full RFC table and enforcement layers: RFC-0001 §8.2. Deep dives:
- Tenancy + ACL →
TENANCY-AND-ACL.md - Prisma vs API →
DATA-ACCESS-BOUNDARIES.md - Auth (login/sessions) →
AUTH-STRATEGY.md
Obligation table (abbreviated)
| Concern | Platform owns | You must | You must not |
|---|---|---|---|
| Identity / sessions | User, Session, /auth/* | Use session/bearer auth via platform routes | Parallel session model |
| Tenancy | Workspace, WorkspaceMember, requireActiveWorkspace | Scope all ops to session activeWorkspaceId | Parallel tenancy concept |
| ACL / roles | AclService, WorkspaceRole | Call platform ACL in services; declare roles via SDK conventions | Custom permission tables |
| Billing | WorkspaceBilling, Stripe/RevenueCat integration | Declare addonCodes / tierLimits via SDK | Import Stripe/RevenueCat in module code |
| AI | Orchestrator, tool registry, BYOK vault | registerAiTools, register prompts/knowledge via SDK | Call LLM providers directly from module code |
| Observability | Pino logger, error handler, audit conventions | Use platform logger and event shapes | Ad-hoc logging stacks |
| i18n | @umbraculum/i18n, @umbraculum/i18n-react | Module-prefixed message namespaces | Forked translation system |
| UI | @umbraculum/ui, @umbraculum/navigation | Build on design tokens + route IDs | Parallel component library |
| Secrets | Platform key vault (AI BYOK today) | Register secret kinds via SDK | Secrets in module env/files |
| Integrations | Devices, attachments, readings framework | Register device kinds via integrations SDK | Parallel device-ingestion path |
| HTTP | Fastify plugins, registerModule() | Register routes through module registration | Custom CORS/auth around platform |
| Database | Prisma + Postgres schemas | Use platform client; module models in module schema | Parallel ORM; client-side Postgres |
| Rendering | @umbraculum/rendering, BullMQ jobs | registerDocumentTemplate, submit render jobs | Bundle PDF/XLSX engines in module |
| Notifications | Outbound-delivery service (RFC-0008) | Register intents/templates via SDK | SMTP/provider SDK in module |
Pre-flight (60 seconds)
Before writing code, answer no to every question below. If any answer is yes, stop — you are proposing a platform change or misclassifying the work.
- Does my module define its own login or session store?
- Does my module use a workspace id from the request body without session membership checks?
- Does my module ship its own role/permission tables?
- Does my module call Stripe, Anthropic, or SMTP directly?
- Does
apps/weborapps/nativeimport Prisma orDATABASE_URL? - Does my published npm package expose Prisma types?
In-repo module slice checklist
For code under services/api/src/modules/<code>/:
- Routes registered via
registerModule()— not a standalone Fastify app. requireActiveWorkspace()at the route boundary.assertMembership(today) /AclService.requireRole(target) in services.- Prisma queries include
workspaceId. - DTOs in
packages/<code>-contracts/with Zod parsers (RFC-0003). - L2 cross-workspace isolation test for new routes (
TESTING.md).
Third-party module checklist
For packages outside this monorepo:
- Pin
@umbraculum/module-sdkand@umbraculum/<code>-contractsfrom npm (when published). - Integrate via HTTP + documented routes (
API-OPENAPI.md). - No database credentials in the integrator deployment for Umbraculum data.
- Respect the same tenancy/ACL semantics the API enforces (you inherit them by calling the API).
Cross-references
README.md— four contributor pathscanonical-module.md— mini-RFC + consumption checklist (Tier 1)third-party-module.md— external repo pathhorizontal-package.md— when you are adding cross-cutting infrastructure