# ERP Platform Base - Design Specification **Date:** 2026-04-10 **Status:** Draft (Review Round 2) **Author:** Claude + User --- ## Context Build a commercial SaaS ERP product from scratch using a "platform base + industry plugins" architecture. The base provides core infrastructure (auth, workflow, messaging, configuration), enabling rapid deployment of industry-specific modules (inventory, manufacturing, finance, HR, etc.) on top. The system targets progressive scaling: start with small businesses, expand to mid and large enterprises. Multi-tenant SaaS deployment is the default, with private deployment as an option. --- ## Architecture ### Overall: Modular Monolith (Progressive) Start as a single Rust backend service with well-defined module boundaries. Modules communicate through an internal event bus and shared traits. When a module needs independent scaling, it can be extracted into a standalone service without changing interfaces. ### System Layers ``` Web Frontend (Vite + React 18 + Ant Design 5) ├── Shell / Layout / Navigation └── Module UI (dynamically loaded per tenant config) │ API Layer (REST + WebSocket) │ Rust Backend Service (Axum + Tokio) ├── Auth Module (identity, roles, permissions, tenants) ├── Workflow Engine (BPMN processes, tasks, approvals) ├── Message Center (notifications, templates, channels) └── Config Module (menus, dictionaries, settings, numbering) │ Core Shared Layer (tenant context, audit, events, caching) │ PostgreSQL (primary) + Redis (cache + session + pub/sub) ``` > **Note:** Tauri 桌面端为可选方案,未来行业模块(如工厂仓库)需要硬件集成时启用。主力前端为 Web SPA。 ### Design Principles 1. **Module isolation**: Each business module is an independent Rust crate, interfaces defined via traits 2. **Multi-tenant built-in**: All data tables include `tenant_id`, middleware auto-injects tenant context 3. **Event-driven**: Modules communicate via event bus, no direct coupling 4. **Plugin extensibility**: Industry modules register through standard interfaces, support dynamic enable/disable ### Error Handling Strategy ```rust // erp-core defines the unified error hierarchy // Uses thiserror for typed errors across crate boundaries #[derive(Debug, thiserror::Error)] pub enum AppError { #[error("Not found: {0}")] NotFound(String), #[error("Validation error: {0}")] Validation(String), #[error("Unauthorized")] Unauthorized, #[error("Forbidden: {0}")] Forbidden(String), #[error("Conflict: {0}")] Conflict(String), #[error("Internal error: {0}")] Internal(String), } // Axum IntoResponse impl maps to HTTP status codes // Validation errors include field-level detail for UI rendering ``` **Decision**: `thiserror` for crate boundaries (typed, catchable), `anyhow` never crosses crate boundaries (internal use only for prototyping). Each module defines its own error variants that wrap `AppError`. ### Event Bus Specification ``` EventBus (tokio::sync::broadcast based, in-process) Event { id: UUID v7 event_type: String (e.g., "user.created", "workflow.task.completed") tenant_id: UUID payload: serde_json::Value timestamp: DateTime correlation_id: UUID (for tracing) } Delivery Guarantees: - At-least-once delivery within the process - Events persisted to `domain_events` table before dispatch (outbox pattern) - Failed handlers log to dead-letter storage, trigger alert - No cross-process delivery in Phase 1 (single binary) ``` ### Plugin / Module Registration Interface ```rust // erp-core defines the plugin trait pub trait ErpModule: Send + Sync { fn name(&self) -> &str; fn version(&self) -> &str; fn dependencies(&self) -> Vec<&str>; // required modules fn register_routes(&self, router: Router) -> Router; fn register_event_handlers(&self, bus: &EventBus); fn on_tenant_created(&self, tenant_id: Uuid) -> Result<()>; fn on_tenant_deleted(&self, tenant_id: Uuid) -> Result<()>; } // erp-server assembles modules at startup fn build_app(modules: Vec>) -> Router { ... } ``` Industry modules implement `ErpModule` and are discovered via configuration, not compile-time. ### API Versioning & Contract Governance - Code-first with utoipa: derive OpenAPI from Rust types - Auto-generated Swagger UI at `/docs` in development - `/api/v1/` prefix for all endpoints; v2 only when breaking changes needed - Client sends `X-API-Version: 1` header; server rejects unsupported versions - Tauri client version and server version must be compatible (checked on connect) ### Concurrency & Transaction Strategy - **Optimistic locking**: All mutable entities carry `version` column; updates fail on mismatch - **Idempotency**: Write endpoints accept optional `Idempotency-Key` header - **Cross-module transactions**: Avoided by design; event bus + saga pattern for consistency - **Numbering sequences**: PostgreSQL sequences with `advisory_lock` per tenant per rule ### Audit Logging ``` AuditLog { id: UUID v7 tenant_id: UUID user_id: UUID action: String (e.g., "user.update", "role.create") resource_type: String resource_id: UUID changes: JSONB { before: {}, after: {} } ip_address: String user_agent: String timestamp: DateTime } Retention: 90 days hot, archive to cold storage after Query API: GET /api/v1/audit-logs?resource_type=user&from=... ``` ### Frontend-Backend Communication | Aspect | Decision | |--------|----------| | Auth flow | Login via REST → JWT stored in httpOnly cookie (web) → sent as Bearer header | | REST calls | Standard fetch/axios from browser to backend | | WebSocket | Connect on page load, auth via first message with JWT, auto-reconnect with exponential backoff | | File upload/download | Standard HTTP multipart + blob download | | CORS | Whitelist per tenant, deny by default | ### Security Measures - CORS: Whitelist per tenant, deny by default - Rate limiting: Per-IP + per-user via Redis token bucket - Secret management: Environment variables + vault (HashiCorp Vault for production) - Data encryption: TLS in transit, AES-256 at rest for PII fields (optional per tenant config) - Input validation: Schema-based (JSON Schema for complex inputs, types for simple) - SQL injection: Prevented by SeaORM parameterized queries --- ## Tech Stack ### Backend (Rust) | Component | Choice | Rationale | |-----------|--------|-----------| | Web framework | Axum 0.8 | Tokio-team maintained, best ecosystem | | Async runtime | Tokio | Rust async standard | | ORM | SeaORM | Async, type-safe, migration support | | DB migration | SeaORM Migration | Versioned schema management | | Cache | redis-rs | Official Redis client | | JWT | jsonwebtoken | Lightweight, reliable | | Serialization | serde + serde_json | Rust standard | | Logging | tracing + tracing-subscriber | Structured logging | | Config | config-rs | Multi-format support | | API docs | utoipa (OpenAPI 3) | Auto-generate Swagger | | Testing | Built-in + tokio-test | Unit + integration | ### Web Frontend | Layer | Technology | |-------|-----------| | Build tool | Vite 6 | | UI framework | React 18 + TypeScript | | Component library | Ant Design 5 | | State management | Zustand | | Routing | React Router 7 | | Styling | TailwindCSS + CSS Variables | ### Infrastructure | Component | Technology | |-----------|-----------| | Primary database | PostgreSQL 16+ | | Cache / Session / PubSub | Redis 7+ | | Containerization | Docker + Docker Compose (dev) | --- ## Crate Structure ``` erp/ ├── crates/ │ ├── erp-core/ # Shared: error handling, types, traits, events │ ├── erp-auth/ # Identity & permissions module │ ├── erp-workflow/ # Workflow engine module │ ├── erp-message/ # Message center module │ ├── erp-config/ # System configuration module │ ├── erp-server/ # Axum server entry, assembles all modules │ └── erp-common/ # Shared utilities, macros ├── apps/ │ └── web/ # Vite + React SPA (primary frontend) ├── desktop/ # (Optional) Tauri desktop, enabled per industry need ├── packages/ │ └── ui-components/ # React shared component library ├── migrations/ # Database migrations ├── docs/ # Documentation └── docker/ # Docker configurations ``` --- ## Module 1: Identity & Permissions (Auth) ### Data Model ``` Tenant ├── Organization │ └── Department │ └── Position ├── User │ ├── UserCredential (password / OAuth / SSO) │ ├── UserProfile │ └── UserToken (session) ├── Role │ └── Permission └── Policy (ABAC rules) ``` ### Permission Model: RBAC + ABAC Hybrid - **RBAC**: User -> Role -> Permission, for standard scenarios - **ABAC**: Attribute-based rules (e.g., "department manager can only approve own department's requests") - **Data-level**: Row filtering (e.g., "only see own department's data") ### Authentication Methods | Method | Description | |--------|------------| | Username/Password | Basic auth, Argon2 hash | | OAuth 2.0 | Third-party login (WeChat, DingTalk, WeCom) | | SSO (SAML/OIDC) | Enterprise SSO, required for private deployment | | TOTP | Two-factor authentication | ### Key APIs ``` POST /api/v1/auth/login POST /api/v1/auth/logout POST /api/v1/auth/refresh POST /api/v1/auth/revoke # Revoke a specific token GET /api/v1/users POST /api/v1/users PUT /api/v1/users/:id DELETE /api/v1/users/:id (soft delete) GET /api/v1/roles POST /api/v1/roles PUT /api/v1/roles/:id DELETE /api/v1/roles/:id POST /api/v1/roles/:id/permissions GET /api/v1/permissions # List all available permissions GET /api/v1/tenants/:id/users GET /api/v1/organizations POST /api/v1/organizations PUT /api/v1/organizations/:id DELETE /api/v1/organizations/:id GET /api/v1/organizations/:id/departments POST /api/v1/organizations/:id/departments GET /api/v1/positions POST /api/v1/positions GET /api/v1/policies POST /api/v1/policies PUT /api/v1/policies/:id DELETE /api/v1/policies/:id ``` ### Multi-tenant Isolation - **Default**: Shared database + `tenant_id` column isolation (cost-optimal) - **Switchable**: Independent schema per tenant (for private deployment) - Middleware auto-injects `tenant_id`, application code is tenant-agnostic ### Multi-tenant Migration Strategy - Schema migrations run once globally, affect all tenants' rows - New tenant provisioning: seed data script (default roles, admin user, org structure, menus) - Migrations are versioned and idempotent; failed migrations halt startup - Per-tenant data migrations (e.g., adding default config) trigger on `on_tenant_created` hook --- ## Module 2: Workflow Engine ### Design Goals - BPMN 2.0 **subset** compatible visual process designer - Low latency, high throughput (Rust advantage) - Support conditional branches, parallel gateways, sub-processes - Embeddable into any business module ### BPMN Subset Scope (Phase 4) **Included in Phase 4:** - Start/End events - User Tasks (with assignee, candidate groups) - Service Tasks (HTTP call, script execution) - Exclusive Gateways (conditional branching) - Parallel Gateways (fork/join) - Sequence Flows with conditions - Process variables (basic types: string, number, boolean, date) **Deferred to later phases:** - Inclusive Gateways - Sub-Processes (call activity) - Timer events (intermediate, boundary) - Signal/Message events - Error boundary events - Multi-instance (loop) activities - Data objects and stores ### Core Concepts ``` ProcessDefinition ├── Node Types │ ├── StartNode │ ├── EndNode │ ├── UserTask (human task) │ ├── ServiceTask (system task) │ ├── Gateway (exclusive / parallel / inclusive) │ └── SubProcess ├── Flow (connections) │ └── Condition (expressions) └── ProcessInstance ├── Token (tracks execution position) ├── Task (pending tasks) └── Variable (process variables) ``` ### Key Features | Feature | Description | |---------|------------| | Visual designer | React flowchart editor, drag-and-drop | | Condition expressions | EL expressions: `amount > 10000 && dept == "finance"` | | Countersign / Or-sign | Multi-person approval: all approve / any approve | | Delegate / Transfer | Tasks can be delegated to others | | Reminder / Timeout | Auto-remind, auto-handle on timeout | | Version management | Process definitions versioned, running instances use old version | ### Key APIs ``` POST /api/v1/workflow/definitions GET /api/v1/workflow/definitions/:id PUT /api/v1/workflow/definitions/:id POST /api/v1/workflow/instances GET /api/v1/workflow/instances/:id GET /api/v1/workflow/tasks (my pending) POST /api/v1/workflow/tasks/:id/approve POST /api/v1/workflow/tasks/:id/reject POST /api/v1/workflow/tasks/:id/delegate GET /api/v1/workflow/instances/:id/diagram (highlighted) ``` ### Integration Points - **Auth**: Task assignment based on roles/org structure - **Message**: Pending task notifications, reminders, approval results - **Config**: Process categories, numbering rules --- ## Module 3: Message Center ### Message Channels | Channel | Use Case | |---------|----------| | In-app notifications | Foundation for all messages | | WebSocket | Real-time push, instant desktop alerts | | Email | Important approvals, scheduled reports | | SMS | Verification codes, urgent alerts | | WeCom / DingTalk | Enterprise messaging integration | ### Data Model ``` MessageTemplate ├── Channel type ├── Template content (variable interpolation: {{user_name}}) └── Multi-language versions Message ├── Sender (system / user) ├── Recipient (user / role / department / all) ├── Priority (normal / important / urgent) ├── Read status └── Business reference (deep link to specific page) MessageSubscription ├── User notification preferences ├── Do-not-disturb periods └── Channel preferences (e.g., approvals via in-app + WeCom, reports via email) ``` ### Key Features - **Message aggregation**: Group similar messages (e.g., "You have 5 pending approvals") - **Read/unread**: Read receipts, unread count query - **Message recall**: Sender can recall unread messages - **Scheduled sending**: Set delivery time - **Message archive**: Auto-archive history, searchable ### Key APIs ``` GET /api/v1/messages (list with pagination) GET /api/v1/messages/unread-count PUT /api/v1/messages/:id/read PUT /api/v1/messages/read-all DELETE /api/v1/messages/:id POST /api/v1/messages/send GET /api/v1/message-templates POST /api/v1/message-templates PUT /api/v1/message-subscriptions (update preferences) WS /ws/v1/messages (real-time push) ``` --- ## Module 4: System Configuration ### Configuration Hierarchy ``` Platform (global) └── Tenant └── Organization └── User ``` Lower-level overrides higher-level. Priority: User > Organization > Tenant > Platform. ### Capabilities | Capability | Description | |-----------|------------| | Dynamic menus | Tenants customize menu structure, display by role | | Data dictionaries | System-level and tenant-level enum management | | Numbering rules | Document number generation with concurrency-safe sequences | | Multi-language | i18n resource management, runtime switching | | System parameters | Key-value general configuration | | Theme customization | Tenant-level UI theme (colors, logo) | ### Key APIs ``` GET /api/v1/config/menus # Tenant from middleware PUT /api/v1/config/menus GET /api/v1/config/dictionaries POST /api/v1/config/dictionaries PUT /api/v1/config/dictionaries/:id GET /api/v1/config/settings/:key PUT /api/v1/config/settings/:key GET /api/v1/config/numbering-rules POST /api/v1/config/numbering-rules PUT /api/v1/config/numbering-rules/:id GET /api/v1/config/languages PUT /api/v1/config/languages/:code GET /api/v1/config/themes # Tenant theme PUT /api/v1/config/themes ``` --- ## Database Design Principles - All tables include: `tenant_id`, `created_at`, `updated_at`, `created_by`, `updated_by` - Soft delete via `deleted_at` (no hard deletes) - UUID v7 as primary keys (time-sortable + unique) - JSONB columns for flexible extension data - Indexes on `tenant_id` + business keys for multi-tenant queries --- ## Web UI Design ### Layout Classic SaaS admin panel layout (responsive, mobile-friendly): ``` +----------------------------------------------+ | LOGO Search... 🔔 5 👤 Admin ▾ | ← Top nav bar +--------+-------------------------------------+ | Home | | | Users | Main Content Area | | Roles | (Dynamic per menu selection) | | Flows | Multi-tab support | | Messages| | | Settings| | |--------| | | Inv. | | | Mfg. | | | Finance| | |--------| | | More > | | +--------+-------------------------------------+ ``` ### Key UI Features - **Collapsible sidebar**: Multi-level menus, grouped (base modules / industry modules) - **Multi-tab content**: Switch between open pages like browser tabs - **Global search**: Search menus, users, documents - **Notification panel**: Click bell icon to expand message list - **Dark/Light theme**: Toggle support, follow system preference - **Responsive**: Mobile/tablet adaptive layout - **Browser notifications**: Web Notification API for real-time alerts --- ## Development Roadmap ### Phase 1 - Foundation (2-3 weeks) - Rust workspace scaffolding + Vite + React setup - erp-core: error types, shared types, trait definitions, event bus - ErpModule trait + module registration system - Database migration framework (SeaORM) with tenant provisioning - Docker dev environment (PostgreSQL + Redis) - CI/CD pipeline setup ### Phase 2 - Identity & Permissions (2-3 weeks) - User, Role, Organization, Department, Position CRUD - RBAC + ABAC permission model - JWT auth (access + refresh tokens, token revocation) - httpOnly cookie for web JWT storage - Multi-tenant middleware - Login page UI + user management pages ### Phase 3 - System Configuration (1-2 weeks) - Data dictionaries - Dynamic menus - System parameters (hierarchical override) - Numbering rules (concurrency-safe PostgreSQL sequences) - i18n framework - Settings pages UI ### Phase 4 - Workflow Engine (4-6 weeks) - Process definition storage and versioning - BPMN subset parser (start/end, user/service tasks, exclusive/parallel gateways) - Execution engine with token tracking - Task assignment, countersign, delegation - Condition expression evaluator - React visual flowchart designer - Process diagram viewer (highlighted current node) - Reminder and timeout handling ### Phase 5 - Message Center (2 weeks) - Message templates with variable interpolation - In-app notification CRUD - WebSocket real-time push (auth, reconnect) - Notification panel UI - Message aggregation and read tracking ### Phase 6 - Integration & Polish (2-3 weeks) - Cross-module integration testing - Audit logging verification - Web app deployment and optimization - Performance optimization - Documentation --- ## Verification Plan 1. **Unit tests**: Each module has comprehensive unit tests (80%+ coverage target) 2. **Integration tests**: API endpoint tests against real PostgreSQL/Redis 3. **E2E tests**: Desktop client test automation via Tauri WebDriver 4. **Multi-tenant tests**: Verify data isolation between tenants 5. **Workflow tests**: Full process lifecycle (define -> start -> approve -> complete) 6. **Performance benchmarks**: API response time < 100ms (p99), WebSocket push < 50ms 7. **Security audit**: OWASP top 10 check before release