ERP Unlocked Monorepo Guide
🏗️ Structure Overview
Section titled “🏗️ Structure Overview”This repository has been refactored into a monorepo structure with clear separation of concerns:
/├── apps/ # Applications│ ├── webapp/ # Main Astro customer application (port 4321)│ ├── marketing/ # Static marketing website (port 3001)│ ├── internal/ # Internal admin portal (port 4322)│ ├── crm/ # CRM Astro application│ ├── pdf-api/ # FastAPI PDF processing service (port 8000)│ └── pdf-worker/ # Celery worker service├── packages/ # Shared packages│ ├── ui/ # Shared UI components (Astro + React)│ ├── db/ # Database schema & migrations (Drizzle ORM)│ ├── auth/ # Authentication utilities (Clerk)│ ├── utils/ # TypeScript utilities│ ├── ai/ # AI/ML utilities│ ├── crm/ # CRM-specific utilities│ ├── trigger/ # Background job orchestration (Trigger.dev)│ ├── observability/ # OpenTelemetry tracing, logging & metrics│ ├── pdf-shared/ # Python shared library│ └── mockoon/ # Mockoon TUI – run/export/import mock APIs├── docs/ # Project documentation├── debt/ # Technical debt planning└── scripts/ # Project-level scripts🔐 Authentication & Organizations
Section titled “🔐 Authentication & Organizations”Clerk Integration
Section titled “Clerk Integration”The monorepo uses Clerk for authentication and organization management:
- Package:
@repo/auth- Centralized authentication utilities - Features: User authentication, organization management, role-based access control
- Organization Context: Multi-tenant support with organization isolation
- Middleware: Automatic organization context resolution for protected routes
Organization Management
Section titled “Organization Management”Organizations provide multi-tenant isolation across all applications:
- Database Schema:
@repo/db/schema/organizations.ts- Organization and member tables - API Routes:
/api/organizations/*- Organization CRUD operations - Member Management: Role-based access control (admin, member)
- Context Resolution: Automatic organization context in middleware
💳 Billing & Subscriptions
Section titled “💳 Billing & Subscriptions”Stripe Integration
Section titled “Stripe Integration”Billing functionality is integrated throughout the system:
- Database Schema:
@repo/db/schema/billing.ts- Organization billing records@repo/db/schema/subscriptions.ts- Subscription management@repo/db/schema/usage-events.ts- Usage tracking for billing@repo/db/schema/invoices.ts- Invoice records
- API Routes:
/api/billing/*- Checkout, portal, and billing management/api/subscriptions/*- Subscription status and management/api/webhooks/stripe- Stripe webhook handling
- Features: Usage-based billing, subscription management, payment processing
Billing Architecture
Section titled “Billing Architecture”- Organization Scoped: All billing is tied to specific organizations
- Usage Tracking: Automatic usage tracking for order processing
- Webhook Processing: Real-time Stripe event handling
- Multi-tenant: Complete isolation between organizations
📊 Observability & Logging
Section titled “📊 Observability & Logging”Two-Layer Logger Architecture
Section titled “Two-Layer Logger Architecture”The monorepo implements a layered logging and observability system to balance functionality and bundle size:
- Base Logger (
@repo/utils/logger): Pure Pino logger with no OpenTelemetry dependencies. Use in shared packages and apps that don’t require distributed tracing. - Enhanced Logger (
@repo/observability): OTEL-integrated logger with tracing, metrics, and instrumentation. Use in main applications for comprehensive observability.
Logger by Application
Section titled “Logger by Application”- webapp: Uses
@repo/observability(full tracing, metrics, and context propagation) - crm: Uses
@repo/utils/logger(base logger only - avoids OTEL bundling issues in Astro v5) - marketing: Uses
@repo/utils/logger(base logger only - static site with minimal logging) - internal: Uses
@repo/utils/logger(base logger only - internal administrative portal) - pdf-api: Uses
@repo/utils/logger(base logger with Python-specific configuration) - pdf-worker: Uses
@repo/utils/logger(base logger with Celery integration)
OTEL Initialization & Configuration
Section titled “OTEL Initialization & Configuration”The OTEL NodeSDK is initialized in apps/webapp to avoid bundling issues in shared packages:
- Initialization:
apps/webapp/otel-init.cjs- Runs before app startup - Configuration:
packages/observability/src/otel-config.ts- Configures SDK, exporters, and instrumentations - Environment Variables: See root
.envconfiguration above (OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_ENDPOINT, etc.)
Logger Usage Examples
Section titled “Logger Usage Examples”// In webapp (with tracing)import { logger } from '@repo/observability';logger.info('Message with trace context', { userId: '123' });
// In shared packages or other apps (no OTEL)import { logger } from '@repo/utils';logger.info('Basic message', { context: 'value' });For detailed setup and configuration, see docs/observability-architecture.md.
🚀 Quick Start
Section titled “🚀 Quick Start”Installation
Section titled “Installation”# Install all dependenciespnpm install
# Build all applicationspnpm -r buildDevelopment
Section titled “Development”# Start webapp development serverpnpm --filter webapp dev
# Start internal admin development serverpnpm --filter internal dev
# Build specific apppnpm --filter webapp build
# Run linting across all packagespnpm -r lint🔧 Environment Variables
Section titled “🔧 Environment Variables”Layered Configuration
Section titled “Layered Configuration”Each service uses a layered environment approach:
- Root
.env- Shared infrastructure (database, Redis, observability) - App-specific
.env- Service-specific configuration
Required Environment Variables
Section titled “Required Environment Variables”Root Environment (.env)
Section titled “Root Environment (.env)”# DatabaseDATABASE_URL=postgresql://...DB_POOL_MAX=20
# RedisREDIS_URL=redis://localhost:6379/0
# ObservabilityTRIGGER_API_KEY=...LOG_LEVEL=infoOTEL_SERVICE_NAME=erp-unlockedOTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318OTEL_EXPORTER_OTLP_HEADERS=...
# StorageR2_ACCESS_KEY_ID=...R2_SECRET_ACCESS_KEY=...Webapp Environment (apps/webapp/.env)
Section titled “Webapp Environment (apps/webapp/.env)”# Clerk AuthenticationPUBLIC_CLERK_PUBLISHABLE_KEY=...CLERK_SECRET_KEY=...
# Stripe Billing (Usage-Based)STRIPE_SECRET_KEY=...STRIPE_PUBLISHABLE_KEY=...STRIPE_WEBHOOK_SECRET=...STRIPE_BASE_PRICE_ID=... # Base subscription priceSTRIPE_USAGE_PRICE_ID=... # Metered usage price
# Feature Flags (Flagsmith)FLAGSMITH_ENVIRONMENT_KEY=...FLAGSMITH_API_URL=...
# Application URLsPUBLIC_WEBAPP_URL=http://localhost:4321PDF API Environment (apps/pdf-api/.env)
Section titled “PDF API Environment (apps/pdf-api/.env)”# PDF ProcessingPDF_PROCESSOR_TOKEN=...GEMINI_API_KEY=...
# StorageR2_BUCKET_NAME=...R2_ENDPOINT=...Setup Environment Files
Section titled “Setup Environment Files”# Copy example filescp .env.example .envcp apps/webapp/.env.example apps/webapp/.envcp apps/pdf-api/.env.example apps/pdf-api/.envcp apps/pdf-worker/.env.example apps/pdf-worker/.envDocker Compose Integration
Section titled “Docker Compose Integration”services: web: env_file: - .env # Shared variables - apps/webapp/.env # App-specific variables📦 Package Management
Section titled “📦 Package Management”Workspace Commands
Section titled “Workspace Commands”# Install dependency in specific apppnpm --filter webapp add react-query
# Install dev dependency in rootpnpm add -D -w prettier
# Run script in all packagespnpm -r test
# Run script in specific packagepnpm --filter pdf-api startPackage References
Section titled “Package References”# Add shared package to apppnpm --filter webapp add @repo/ui@workspace:*pnpm --filter webapp add @repo/db@workspace:*pnpm --filter webapp add @repo/auth@workspace:*🗄️ Database & Data Management
Section titled “🗄️ Database & Data Management”Database Schema
Section titled “Database Schema”The database is organized around organizations for multi-tenant support:
- Core Tables:
organizations,organization_members,users - Business Logic:
orders,pdf_documents,erp_products,erp_customers - Billing:
organization_billing,subscriptions,usage_events,invoices - Connections:
erp_connectionsfor ERP system integrations
Organization Isolation
Section titled “Organization Isolation”All data is automatically scoped to organizations:
- Middleware: Automatic organization context injection
- Queries: All database queries include organization filtering
- API Routes: Organization context validation on all protected endpoints
🔄 Background Jobs & Triggers
Section titled “🔄 Background Jobs & Triggers”Trigger.dev Integration
Section titled “Trigger.dev Integration”Background job processing using Trigger.dev:
- Package:
@repo/trigger- Job orchestration and scheduling - Features: Delayed jobs, recurring tasks, webhook processing
- Use Cases: PDF processing, ERP synchronization, billing operations
Celery Workers
Section titled “Celery Workers”Python-based background processing:
- Service:
apps/pdf-worker- PDF processing and AI extraction - Features: Async task processing, Redis-based queuing
- Integration: Seamless integration with FastAPI services
🧪 Testing & Quality
Section titled “🧪 Testing & Quality”Testing Strategy
Section titled “Testing Strategy”- Unit Tests: Individual package testing with Vitest (TS) and pytest (Python)
- Integration Tests: End-to-end testing for critical workflows
- Database Tests: Schema validation and migration testing
Code Quality
Section titled “Code Quality”- Linting: ESLint + Prettier for TypeScript/JavaScript
- Python: Ruff for linting and formatting
- Type Safety: Comprehensive TypeScript types across all packages
🚀 Deployment & CI/CD
Section titled “🚀 Deployment & CI/CD”Build Process
Section titled “Build Process”# Build all applicationspnpm build
# Build specific apppnpm --filter webapp build
# Build Python packagescd apps/pdf-api && uv run buildcd apps/pdf-worker && uv run buildDocker Integration
Section titled “Docker Integration”- Multi-stage builds for optimized production images
- Layer caching for faster builds
- Environment-specific configurations
Deployment Targets
Section titled “Deployment Targets”- Web Applications: Vercel, Netlify, or similar static hosting
- API Services: Railway, Render, or container platforms
- Background Workers: Container platforms with Redis support
📚 Development Workflows
Section titled “📚 Development Workflows”Adding New Features
Section titled “Adding New Features”- Create/Update Schemas: Add database tables in
@repo/db - Implement Business Logic: Add functions in appropriate packages
- Create API Routes: Add endpoints in relevant applications
- Update Types: Ensure TypeScript types are comprehensive
- Add Tests: Include unit and integration tests
Package Development
Section titled “Package Development”- Create Package Structure: Follow existing package patterns
- Define Exports: Update
package.jsonexports - Add Dependencies: Use workspace references where possible
- Update Documentation: Include usage examples and API docs
Database Changes
Section titled “Database Changes”- Schema Updates: Modify schema files in
@repo/db - Generate Migrations: Use Drizzle migration tools
- Test Migrations: Verify in development environment
- Deploy Safely: Use proper migration strategies
🔍 Troubleshooting
Section titled “🔍 Troubleshooting”Common Issues
Section titled “Common Issues”- Package Resolution: Ensure workspace dependencies are properly configured
- Environment Variables: Check both root and app-specific
.envfiles - Database Connections: Verify organization context is properly set
- Build Failures: Check for missing dependencies or type errors
Debug Commands
Section titled “Debug Commands”# Check workspace statuspnpm list --depth=0
# Verify package buildspnpm -r build
# Run tests with coveragepnpm -r test --coverage
# Check database migrationspnpm --filter @repo/db db:generate📖 Additional Resources
Section titled “📖 Additional Resources”- Architecture Overview: See
docs/architecture.mdfor system design details - API Documentation: Check individual app README files for API specifics
- Deployment Guide: See
docs/deployment-guide.mdfor production setup - Authentication Guide: See
docs/authentication-architecture.mdfor auth details - Observability Guide: See
docs/observability-architecture.mdfor tracing, logging & metrics setup