206 lines
6.6 KiB
Markdown
206 lines
6.6 KiB
Markdown
# Architecture and System Design
|
|
|
|
**Sistema de Remuneración Variable, Compensación y Comisiones - Hoteles Estelar**
|
|
|
|
---
|
|
|
|
## 1. Technical Stack Selection
|
|
|
|
To keep resource footprint low on the self-hosted VPS while providing a premium, modern user experience, we recommend a unified **Next.js Full-Stack App Router** architecture.
|
|
|
|
* **Frontend**: Next.js App Router (React + TypeScript).
|
|
* **Styling**: Vanilla CSS with a structured design system (CSS variables, dark/light theme tokens, premium layout aesthetics, smooth CSS micro-animations).
|
|
* **Backend**: Next.js API Routes (Node.js runtime).
|
|
* **ORM**: Prisma ORM (provides type-safe database queries and automated schema migrations).
|
|
* **Database**: PostgreSQL (hosted on the existing `postgres` Docker stack).
|
|
* **Excel Processing**: `xlsx` (SheetJS) for high-performance parser logic.
|
|
* **Authentication**: NextAuth.js or custom lightweight JWT session cookies.
|
|
* **Hosting**: Docker container integrated into the Dockge stack manager, reverse proxied by Caddy with split DNS resolving over WireGuard VPN for security-sensitive areas.
|
|
|
|
---
|
|
|
|
## 2. System Architecture
|
|
|
|
```mermaid
|
|
graph TD
|
|
User([Colaborador / Líder / Admin]) -->|HTTPS| Caddy[Caddy Reverse Proxy]
|
|
Caddy -->|Internal Network| NextJS[Next.js Full-Stack App]
|
|
|
|
subgraph NextJS Container
|
|
UI[React Frontend / Vanilla CSS] <--> API[API Routes / Controllers]
|
|
Engine[Settlement Engine] <--> API
|
|
Parser[Excel Parser] <--> API
|
|
end
|
|
|
|
API -->|Prisma Client| DB[(PostgreSQL)]
|
|
Jobs[Integration CRON Jobs] -->|Fetch Sales| API
|
|
External[External PMS / ERP / CRM] -->|API Push / Pull| Jobs
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Database Schema Design (Entity-Relationship Diagram)
|
|
|
|
```mermaid
|
|
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. Key Business Logic: Settlement & Calculation Engine
|
|
|
|
The engine computes commissions based on the formula:
|
|
|
|
$$\text{Achievement \%} = \left( \frac{\text{Sales Amount}}{\text{Goal Amount}} \right) \times 100$$
|
|
|
|
### Calculation Flow:
|
|
1. **Fetch inputs**: Get sales results, goals, and matching active compensation plan for the collaborator for the period `YYYY-MM`.
|
|
2. **Determine Achievement Level**: Check against the plan's `CALCULATION_RULES` (tiers).
|
|
3. **Calculate Commission**:
|
|
- *Fixed Rate*: $\text{Sales} \times \text{percentage\_rate}$.
|
|
- *Tiers/Scales*: Apply rate corresponding to the achievement level tier.
|
|
4. **Apply Caps**: If calculated commission exceeds the plan's `max_cap`, set it to `max_cap`.
|
|
5. **Add Special Bonuses**: If the collaborator achieves certain thresholds (e.g., >100% meta), add the specific tier's fixed `payout_amount` as a bonus.
|
|
6. **Generate Output**: Store as a `SETTLEMENT` entry in `SIMULATED` status.
|
|
|
|
---
|
|
|
|
## 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`. |
|