Bluewoo HRMS
AI Development GuideFoundations

Architecture Principles

Anti-patterns to avoid and patterns to embrace when building HRMS

Architecture Principles

This document defines the architectural rules for the HRMS project. These are lessons learned from previous projects and represent locked decisions.

Anti-Patterns to AVOID

These are mistakes from the Bluewoo project that must not be repeated:

NEVER DO:
├── GraphQL Federation (too complex for our scale)
├── Multiple microservices with separate databases
├── Event sourcing without customers
├── Abstract factory patterns for 2 implementations
├── Custom ORMs or query builders
├── Premature optimization ("Enterprise Cosplay")
└── Rigid single-manager hierarchies (doesn't fit startups)

Why These Are Forbidden

GraphQL Federation

  • Adds massive complexity for marginal benefit
  • Requires additional tooling and expertise
  • REST is sufficient for our scale

Microservices

  • Single database is simpler and faster
  • No network overhead between services
  • Easier to debug and deploy
  • Monolith scales to 100+ tenants easily

Event Sourcing

  • No customers means no feedback on what events matter
  • Adds complexity without proven value
  • Can be added later if needed

Abstract Factories

  • If there are only 2 implementations, use if/else
  • Abstractions without 3+ implementations are premature
  • Copy-paste is better than wrong abstraction

Custom ORMs

  • Prisma is proven and well-documented
  • Custom solutions create maintenance burden
  • AI assistants know Prisma patterns

Premature Optimization

  • Build for 100 tenants first, not 10,000
  • Optimize when there's actual performance data
  • "Enterprise Cosplay" wastes development time

Rigid Hierarchies

  • Real companies have matrix organizations
  • Employees can have multiple managers
  • Teams and departments overlap

Patterns to EMBRACE

These are the approved patterns for HRMS:

ALWAYS DO:
├── Single PostgreSQL with Prisma
├── Row-Level Security for multi-tenancy
├── Simple REST APIs with OpenAPI
├── Monorepo with clear module boundaries
├── Feature flags for gradual rollout
├── AI-embedded in core, not bolted on
└── Flexible org structures (multi-everything)

Implementation Details

Single PostgreSQL with Prisma

// All data in one database
// Use Prisma 5.x (not 6.x)
// All IDs are UUIDs
const prisma = new PrismaClient()

Row-Level Security

-- Tenant isolation at database level
ALTER TABLE employees ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON employees
  USING (tenant_id = current_tenant_id());

REST APIs

// Simple, predictable endpoints
GET    /api/employees
GET    /api/employees/:id
POST   /api/employees
PATCH  /api/employees/:id
DELETE /api/employees/:id

Module Boundaries

apps/api/src/modules/
├── employees/      # Employee management
├── org/            # Org structure
├── timeoff/        # Time-off tracking
├── documents/      # Document management
├── goals/          # OKR/Goals
└── feed/           # Team communication

Flexible Org Structures

// Multi-everything approach
interface EmployeeOrgRelations {
  primaryManagerId?: string        // 0..1
  dottedLineManagerIds: string[]   // 0..N
  additionalManagerIds: string[]   // 0..N
  teamIds: string[]                // 0..N
  departmentIds: string[]          // 0..N
  roleIds: string[]                // 0..N
}

Decision Filter

For every technical decision, ask:

"Will this help our first 10 customers TODAY?"

If the answer is no, don't do it. This filter prevents:

  • Premature abstraction
  • Over-engineering
  • Feature creep
  • Technology churn

Locked Decisions

These decisions are final and cannot be changed without an ADR:

DecisionStatus
PostgreSQL onlyLOCKED
Prisma ORMLOCKED
REST APIsLOCKED
Monolith architectureLOCKED
Multi-tenant with RLSLOCKED
NestJS backendLOCKED
Next.js frontendLOCKED

Architecture Diagram

┌─────────────────────────────────────────────────┐
│                   Frontend                       │
│              Next.js 15 (App Router)            │
│         Shadcn/ui + Tailwind + React Query      │
└─────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────┐
│                   Backend                        │
│                  NestJS 10                       │
│        REST APIs + Auth.js + Prisma 5           │
└─────────────────────────────────────────────────┘

           ┌────────────┴────────────┐
           ▼                         ▼
┌──────────────────┐     ┌──────────────────┐
│   PostgreSQL 17   │     │   AI Service     │
│   (HRMS Data)     │     │   (Express)      │
│   with RLS        │     │   + MongoDB      │
└──────────────────┘     └──────────────────┘