Core Packages for Multi-App Platforms
Goal: Build a small, dependency-light core that multiple apps can consume for identity, database access, RBAC, content/MDX, uploads, billing, events, and email—so each app stays lean while the platform stays consistent.
Principles
- Keep the surface area small — helpers, not frameworks.
- No inward imports — core never depends on app code.
- Make database changes additive only.
- Share a single user identity across all apps.
- Ensure deterministic builds and versioning.
- Maintain clear boundaries between infrastructure primitives (core) and domain logic (apps).
Why Core?
- Consistency: One way to do auth, uploads, pricing, and events.
- Speed: New apps ship faster by reusing plumbing.
- Safety: A single place to harden security checks.
- Observability: Cross-app events flow into the same schema.
High-Level Architecture
- Core holds environment, auth, database access, RBAC, MDX/content utilities, uploads, billing, email, and events.
- Apps import these primitives and build their own domain models and business rules on top.
- Shared database connects everything, with tables like
users
,profiles
, andevents
available to all apps.
Recommended Structure
A lightweight package with sections for:
- Configuration & Environment
- Database Access & Transactions
- Authentication & Roles
- Content Handling (MDX, shared components)
- Uploads & Storage
- Billing & Payment Verification
- Communications (Email, Templates)
- Telemetry & Events
- UI Atoms (optional, minimal shared pieces)
Shared Database Strategy
- One logical database for the whole platform.
- Shared tables for universal concepts (users, profiles, events).
- App-specific domain tables kept outside of core.
- Always include a tenant identifier for future multi-tenant needs.
- Follow strict additive-only migration rules.
Sessions & Single Sign-On
- Apps share the same authentication provider and user table.
- Where possible, use shared cookies for seamless SSO.
- Sessions return the same shape everywhere to avoid fragmentation.
Uploads & Storage
- Core provides utilities for creating and managing upload flows.
- Apps handle role enforcement and store metadata alongside their own domain records.
- Policies should prevent orphaned or unused files.
Billing & Payments
- Products and prices are created once and referenced in app domain tables.
- Core verifies payment webhooks; apps interpret the outcome in their own context (e.g., granting course access).
- Always ensure idempotency in webhook handling.
Events & Observability
- Centralized events table logs activity across apps.
- Events include categories like authentication, content, and billing.
- This creates a foundation for dashboards, analytics, and retention tracking.
Versioning & Publishing
- Core is versioned with semver and changelogged.
- Schema changes must be documented and rolled out carefully.
- Each release comes with upgrade notes for dependent apps.
Security Guardrails
- No secrets or sensitive values should leak into exports.
- All presign and webhook handlers must validate requests.
- RBAC defaults to deny; explicit allow lists control access.
Playbooks
Adding a New App
- Install the core package.
- Wire in environment, database, and session.
- Add domain-specific tables and logic.
- Use uploads, billing, and events as needed.
Adding a New Primitive
- Prove the need in one app first.
- Extract the minimal contract into core.
- Document, test, and release it as a minor version.
Database Evolution
- Add columns or tables in an additive way.
- Release and deploy core first, then apps.
- Schedule cleanup migrations only after safe rollout.