# WorkSpace ERP (WS) Demo — Technical Architecture

**Status:** Build-ready handoff · **Version:** 3.1.0 · **Audience:** Frontend & Backend developers

This document defines the **target production architecture** for WorkSpace ERP (WS), an ISP-focused multi-tenant SaaS ERP. The interactive HTML prototype in `v3/` validates UX, navigation, and domain behaviour; production delivery uses the stack below.

---

## 1. Architecture principles

| # | Principle | Implementation |
|---|-----------|----------------|
| a | **Backend: Java Spring Boot** | Modular monolith; REST API; OpenAPI 3.1 contract |
| b | **Frontend: React + Node.js** | React SPA; Node.js build toolchain (Vite); BFF optional |
| c | **Multi-tenant shared database** | Default: single schema, `tenantId` on all tenant data |
| d | **Optional dedicated database** | Enterprise tenants: routed `DataSource` per `databaseRef` |
| e | **Multi-company isolation** | `companyId` scopes legal entities within a tenant |
| f | **Tenant global unique entity model** | UUID primary keys; globally unique across platform |
| g | **Modular monolithic architecture** | Domain modules in one deployable unit; clear package boundaries |
| h | **Cloud agnostic** | Containers, external config, S3-compatible storage, portable K8s |

---

## 2. System context

```
┌─────────────────────────────────────────────────────────────────┐
│  React SPA (Node.js build)                                      │
│  packages/ws-app — shell, modules, design tokens                │
└────────────────────────────┬────────────────────────────────────┘
                             │ HTTPS / REST (OpenAPI)
                             │ Headers: Authorization, X-WS-Tenant-Id, X-WS-Company-Id
┌────────────────────────────▼────────────────────────────────────┐
│  Spring Boot Modular Monolith                                   │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐           │
│  │ platform │ │ structure│ │ finance  │ │ crm      │  …       │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘           │
│  Shared: security, tenancy routing, audit, events                 │
└────────────────────────────┬────────────────────────────────────┘
                             │
         ┌───────────────────┴───────────────────┐
         │                                       │
┌────────▼────────┐                   ┌──────────▼──────────┐
│ Shared DB       │                   │ Dedicated DB(s)      │
│ (default)       │                   │ (tenant.databaseRef) │
│ tenantId filter │                   │ per enterprise tenant│
└─────────────────┘                   └─────────────────────┘
```

---

## 3. Multi-tenancy & data isolation

### 3.1 Shared database (default)

- All tenants in one PostgreSQL (or compatible) schema.
- Every tenant-scoped row includes `tenant_id UUID NOT NULL`.
- Spring: `TenantContext` + `@TenantId` on entities or Hibernate filter.
- Optional PostgreSQL RLS for defence in depth.

### 3.2 Dedicated database (optional)

- Tenant record: `databaseMode: DEDICATED`, `databaseRef: "jdbc:…"` or secret key.
- `TenantConnectionRouter` selects `DataSource` before transaction.
- Same entity model and API; no client changes.
- Used for regulated / enterprise ISP customers.

### 3.3 Multi-company isolation

- One tenant may operate multiple legal entities (companies).
- Company-scoped entities carry `company_id UUID NOT NULL`.
- Session context: tenant + active company (switcher in shell header).
- Unique constraints: `(tenant_id, company_id, code)` for business keys.

### 3.4 Tenant global unique entity model

- Primary keys: **UUID v7** (time-sortable) or ULID.
- IDs are globally unique across the platform (not composite per tenant).
- `tenantId` / `companyId` are scope columns, not part of the PK.
- Standard audit columns: `created_at`, `created_by`, `updated_at`, `updated_by`, `version`.

See [ENTITY-MODEL.md](./ENTITY-MODEL.md) for the full entity catalogue.

---

## 4. Modular monolith (Spring Boot)

Recommended Maven/Gradle structure:

```
ws-backend/
  ws-platform/      # tenants, applications, modules, signups
  ws-tenancy/       # TenantContext, connection routing, filters
  ws-structure/     # company profile, org hierarchy
  ws-finance/       # GL, COA, journals, currencies
  ws-crm/           # contacts, cases
  ws-access/        # categories, groups, RBAC
  ws-approval/      # workflows, requests
  ws-operations/    # products, payments, self-service
  ws-app/           # @SpringBootApplication, actuator, config
```

**Rules:**

- Modules communicate via **domain events** or **internal service interfaces**, not direct cross-module DB access.
- Each module owns its tables and REST controllers under `/api/v1/{domain}/…`.
- Shared kernel: security, tenancy, audit, exception handling, OpenAPI.

---

## 5. Frontend (React + Node.js)

```
ws-frontend/
  packages/ws-app/
    src/
      shell/           # layout, nav, session, tenant/company switcher
      modules/
        dashboard/
        structure/
        finance/
        contacts/
        crm/
        access/
        approval/
        platform/
        operations/
      api/             # generated from OpenAPI (or hand-written client)
      design-tokens/   # from v3/css/kit-theme.css
```

**Prototype mapping:** Each file in `v3/js/modules/*.js` → one React feature module. Navigation node IDs (`to_gl_journals`, `ta_divisions`, etc.) become route keys.

---

## 6. API contract

- **Spec:** [openapi/ws-api-v3.yaml](./openapi/ws-api-v3.yaml)
- **Base path:** `/api/v1`
- **Auth:** Bearer JWT (OIDC / Spring Security)
- **Context headers:**
  - `X-WS-Tenant-Id` — required for tenant APIs
  - `X-WS-Company-Id` — required for company-scoped APIs
  - `X-Request-Id` — correlation / tracing

Prototype client: `v3/js/platform/api-client.js` (`apiMode: local` | `http`).

---

## 7. Cloud agnostic deployment

| Concern | Approach |
|---------|----------|
| Runtime | Container image (Jib / Dockerfile) |
| Config | Env vars + ConfigMaps / Parameter Store |
| Secrets | Vault, AWS Secrets Manager, K8s secrets |
| Database | PostgreSQL (managed or self-hosted) |
| Object storage | S3-compatible API |
| Ingress | Any load balancer / ingress controller |
| Observability | OpenTelemetry, Prometheus, structured logs |

No vendor-specific SDKs in application code; use interfaces and adapters.

---

## 8. Prototype vs production

| Layer | Prototype (`v3/`) | Production |
|-------|-------------------|------------|
| UI | Vanilla JS modules | React components |
| Data | `localStorage` via `WSDataStore` | Spring JPA + PostgreSQL |
| API | `WSApiClient` local mode | `WSApiClient` http mode |
| Auth | Dummy users / session | OIDC + JWT |
| Tenancy | `WSTenancy` JS filters | `TenantContext` + DB routing |

The prototype is the **authoritative UX and navigation reference**. Domain logic and screen flows should be ported module-by-module.

---

## 9. Related documents

| Document | Purpose |
|----------|---------|
| [HANDOFF.md](./HANDOFF.md) | Step-by-step developer onboarding |
| [ENTITY-MODEL.md](./ENTITY-MODEL.md) | Tables, scope, relationships |
| [MODULE-MAP.md](./MODULE-MAP.md) | Prototype → Spring/React mapping |
| [openapi/ws-api-v3.yaml](./openapi/ws-api-v3.yaml) | REST contract |

**Machine-readable manifest:** `v3/js/core/architecture.js`
