semillero-special-hotel/docs/ARCHITECTURE.md

6.6 KiB

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

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)

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.