Service Boundaries
Current Services
| Service | Location | Purpose | Database | Tech Stack |
|---|---|---|---|---|
| web | apps/web | Main platform application | Supabase (PostgreSQL) | Next.js 16, React, tRPC |
| rewise | apps/rewise | AI-powered chatbot | Supabase (shared) | Next.js 16, AI SDK |
| nova | apps/nova | Prompt engineering platform | Supabase (shared) | Next.js 16, AI SDK |
| calendar | apps/calendar | Calendar & scheduling | Supabase (shared) | Next.js 16, React |
| finance | apps/finance | Finance management | Supabase (shared) | Next.js 16, React |
| tudo | apps/tudo | Task management (hierarchical) | Supabase (shared) | Next.js 16, React |
| tumeet | apps/tumeet | Meeting management | Supabase (shared) | Next.js 16, React |
| shortener | apps/shortener | URL shortener service | Supabase (shared) | Next.js 16 |
| db | apps/db | Database migrations & schema | Supabase | SQL, TypeScript |
| discord | apps/discord | Discord bot utilities | None (stateless) | Python |
Shared Packages
All services share common infrastructure via workspace packages:Monorepo Architecture
Benefits
- Shared Code: Common utilities, UI components, types shared across services
- Atomic Changes: Change types in one commit, update all services
- Simplified Tooling: Single build system (Turborepo + Bun)
- Easy Refactoring: Move code between services, extract packages
- Consistent Standards: Shared linting, testing, deployment configs
Structure
Workspace Dependencies
Services declare dependencies on shared packages:Communication Patterns
1. Event-Driven (Primary)
When to use: Asynchronous workflows, background processing, cross-service coordination Implementation: Trigger.dev- Loose coupling between services
- Resilient to failures
- Asynchronous processing
- Event log for replay/debugging
2. Shared Database (Current)
When to use: Strong consistency requirements, complex queries across entities Implementation: Supabase PostgreSQL with RLS- Strong consistency
- ACID transactions
- Complex joins possible
- Shared schema (requires coordination)
- ✅ Simple implementation
- ✅ Strong consistency
- ❌ Tight coupling at data layer
- ❌ Schema changes affect multiple services
3. tRPC (Internal API)
When to use: Type-safe communication within web application boundaries Implementation: tRPC routers- End-to-end type safety
- Auto-completion in IDE
- Minimal boilerplate
- Client-side caching with React Query
4. REST API (External)
When to use: Public APIs, webhook endpoints, third-party integrations Implementation: Next.js API routes- Standard HTTP
- OpenAPI documentation possible
- Versioned endpoints (
/api/v1/...) - Rate limiting, authentication
Service Communication Matrix
| From Service | To Service | Pattern | Protocol | Use Case |
|---|---|---|---|---|
| web | rewise | Event-Driven | Trigger.dev | Setup AI for new workspace |
| web | finance | Shared DB | PostgreSQL | Access financial data |
| rewise | web | Event-Driven | Trigger.dev | AI chat completion notification |
| External | web | REST API | HTTP/JSON | Public API access |
| web (client) | web (server) | tRPC | HTTP/JSON | Internal app communication |
| discord | web | Webhook | HTTP/JSON | Discord bot commands |
Deployment Strategies
Current: Vercel Monorepo Deployment
Each app deploys independently to Vercel:Independent Scaling
Each service scales based on its traffic:Service Boundary Decisions
When to Create a New Service
✅ Extract to new service when:- Feature is logically independent (e.g., URL shortener)
- Different scaling requirements (high-traffic vs low-traffic)
- Different technology needs (Python for ML vs TypeScript for web)
- Team ownership boundary (separate team owns feature)
- Independent deployment cycle needed
- Shares most code with existing service
- Tight coupling to core domain
- Low complexity (< 1000 LOC)
- No special scaling or technology needs
Example: Why finance is a separate app
Data Ownership
Current: Shared Database Pattern
Pros:- Simple joins across entities
- Strong consistency
- ACID transactions
- Single source of truth
- Tight coupling at data layer
- Schema changes affect multiple services
- Harder to scale independently
Future: Service-Specific Databases
When to consider:- Service needs specialized database (e.g., PostGIS for geolocation)
- Independent scaling requirements for specific data
- Strong service boundaries needed
Package Extraction Strategy
When to Extract to Package
From the Package Extraction Decision Matrix: Extract when ≥3 HIGH signals:| Signal | Extract Now (HIGH) |
|---|---|
| Reuse Breadth | Actively duplicated in ≥2 apps |
| Complexity | >150 LOC multi-module |
| Domain Ownership | Pure cross-domain utility |
| Testing Needs | Comprehensive tests stable |
Testing Strategies
Unit Tests
Test individual services in isolation:Integration Tests
Test service interactions:End-to-End Tests
Test full user workflows across services (future):Monitoring & Observability
Service Health
Distributed Tracing
Migration Paths
Current State → Future State
Current: Monorepo with shared database Future options:-
Service-Specific Databases (when needed)
- Extract finance data to dedicated DB
- Communicate via events
- Maintain consistency with sagas
-
API Gateway Layer (if REST APIs grow)
- Single entry point for external clients
- Route to appropriate services
- Handle auth, rate limiting centrally
-
GraphQL Federation (if complex queries needed)
- Each service exposes GraphQL schema
- Gateway federates schemas
- Clients query unified graph
Related Documentation
- Architectural Decisions - Why microservices
- Event-Driven Architecture - Inter-service communication
- Monorepo Architecture - Turborepo setup
- Database Schema - Shared schema details