7.6 KiB
7.6 KiB
Architecture and System Design
Variable Remuneration, Compensation, and Commissions System - Hoteles Estelar
1. Technical Stack
- Frontend: Next.js App Router (React + TypeScript).
- Styling: Vanilla CSS utilizing CSS Modules (
*.module.css) for component-level style isolation, paired with a global variables system (globals.css) defining the design tokens. - Backend: Next.js API Routes (Node.js runtime).
- ORM: Prisma ORM (providing type-safe database queries and automated schema migrations).
- Database: PostgreSQL (decoupled, configured via environment variables to run on any host/network).
- Workflow Engine: n8n (external service triggered via API Webhooks). Runs the actual calculation steps, anomaly checks, AI-assisted audits, and notifications. This allows live monitoring of tasks and flexible AI model switching (e.g., swapping OpenAI/Anthropic/Ollama models within n8n nodes without rebuilding the Next.js codebase).
- Auditing: Ready-to-use, community-proven
@explita/prisma-audit-logPrisma Client Extension. It automatically intercepts database mutations (create, update, delete), tracks changes (old vs new state), handles sensitive field masking (e.g. passwords), and records logs into theAuditLogtable. This approach is database-agnostic, requires no native OS dependencies, and runs purely inside the runtime.
2. Decoupled Network & Environment Independence
The project is structured to run in any isolated Docker environment. All parameters are fed via environment variables:
DATABASE_URL: Connection string for PostgreSQL (e.g.postgresql://user:pass@host:port/dbname).N8N_WEBHOOK_URL: The entry point for the n8n workflow engine.N8N_API_KEY: Token to authorize callbacks from n8n to the Next.js API.NEXTAUTH_SECRET: Secret for securing JWT cookies.
Component Interaction:
graph TD
User([User Client]) -->|HTTPS| WebApp[Next.js App Router]
subgraph Isolated Network
WebApp -->|Prisma Client| DB[(PostgreSQL)]
WebApp -->|HTTP POST Webhook| n8n[n8n Workflow Engine]
n8n -->|HTTP POST Callback| WebApp
n8n -->|Interact| LLM[AI Model / Provider]
end
3. Database Schema Design (Entity-Relationship Diagram)
erDiagram
REGIONS ||--o{ HOTELS : contains
HOTELS ||--o{ USERS : houses
USERS ||--o{ GOALS : achieves
USERS ||--o{ SALES_RESULTS : generates
USERS ||--o{ SETTLEMENTS : receives
COMPENSATION_PLANS ||--o{ CALCULATION_RULES : dictates
COMPENSATION_PLANS ||--o{ SETTLEMENTS : calculates
USERS ||--o{ AUDIT_LOGS : executes
USERS ||--o{ NOTIFICATIONS : receives
REGIONS {
int id PK
string name
string code
}
HOTELS {
int id PK
string name
string code
int region_id FK
string status
}
USERS {
int id PK
string username
string email
string password_hash
string role "ADMIN | DIRECTOR | GERENTE | LIDER | ANALISTA | CONSULTA | COLABORADOR"
int hotel_id FK
string area
string status "ACTIVE | INACTIVE"
datetime created_at
}
COMPENSATION_PLANS {
int id PK
string name
string code UK
datetime validity_start
datetime validity_end
string type "PERCENTAGE | SCALE | CONDITIONAL | FIXED"
string formula "JSON or string representation"
decimal meta_amount
decimal percentage_rate
decimal max_cap
string status "DRAFT | ACTIVE | INACTIVE"
int version
int created_by FK
datetime created_at
}
CALCULATION_RULES {
int id PK
int plan_id FK
string type "TIER | BONUS"
decimal min_achievement "percentage"
decimal max_achievement "percentage"
decimal rate "multiplier or percentage"
decimal payout_amount "fixed payment"
}
GOALS {
int id PK
string target_type "INDIVIDUAL | TEAM | HOTEL"
int target_id "user_id, team_id, or hotel_id"
string period "YYYY-MM"
decimal amount
datetime created_at
}
SALES_RESULTS {
int id PK
string source "EXCEL | API"
int hotel_id FK
int user_id FK "colaborador"
string period "YYYY-MM"
decimal amount
int sales_count
string status "PENDING | PROCESSED"
int uploaded_by FK
datetime created_at
}
SETTLEMENTS {
int id PK
string period "YYYY-MM"
int plan_id FK
int user_id FK
decimal sales_amount
decimal goal_amount
decimal achievement_percentage
decimal calculated_commission
decimal calculated_bonus
decimal total_payout
string status "SIMULATED | PENDING | APPROVED | REJECTED"
int approved_by FK
datetime approved_at
string rejection_reason
datetime created_at
}
AUDIT_LOGS {
int id PK
int user_id FK
string action "CREATE | UPDATE | DELETE | APPROVE | REJECT | LOGIN"
string target_table
int target_id
json previous_value
json new_value
string ip_address
datetime created_at
}
NOTIFICATIONS {
int id PK
int user_id FK
string title
string message
string status "UNREAD | READ"
string type "EMAIL | PUSH"
datetime sent_at
}
4. Workflows & n8n Integration Model
By offloading calculations and integrations to n8n, we achieve a highly visual, modular, and editable workflow architecture.
4.1. Sales Data Import Workflow
- Trigger: Next.js calls
POST /api/n8n/import-saleswhich forwards the parsed Excel payload to n8n's webhook URL. - n8n Processing:
- Iterates through sales records.
- Queries Next.js APIs to validate collaborator codes and hotel IDs.
- Cleanses data and identifies duplicates.
- Uses an LLM node (with configurable models: GPT-4, Claude 3.5, Gemini, etc.) to perform semantic anomaly checks (e.g., flag sales values that deviate more than 2.5 standard deviations from the collaborator's monthly average).
- Response: n8n POSTs the sanitized/flagged list back to
POST /api/sales/batch-savein Next.js to update the database.
4.2. Settlement Calculation Workflow
- Trigger: Next.js calls n8n to execute the calculation for period
YYYY-MM. - n8n Processing:
- Pulls active plans, individual goals, and actual sales from the Next.js API.
- Evaluates the mathematical formulas.
- Evaluates rule scales and applies caps.
- Generates notifications (via email or push notifications) using n8n integrations.
- Response: Updates database records via the Next.js API and completes the task.
5. Security & Access Control Model (RBAC)
We define role-based access restrictions as follows:
| Role | Access Level | Restrictions |
|---|---|---|
| Administrador | Full system write & read. | None. |
| Director Comercial | Reads all dashboards & reports. Can configure metadata. | Cannot calculate or approve. |
| Gerente Hotel | Reads data, sales, and settlements for their specific Hotel. | Restricted to hotel_id. |
| Líder Comercial | Triggers simulations, views dashboards. Approves/Rejects settlements. | Restricted to their region/team. |
| Analista Financiero | Reviews calculations. Exports consolidated PDF/Excel reports. | Cannot approve. |
| Consulta | Read-only. | No mutations allowed. |
| Colaborador | Consults own history & dashboard. | Restricted to user_id. |