From 24d54f8beda5dba4959914e7b8649d92f8aaaa84 Mon Sep 17 00:00:00 2001 From: gabogg Date: Fri, 12 Jun 2026 13:36:19 +0000 Subject: [PATCH] docs: add Phase 5 Implementation and Settlement Design Document --- docs/PHASE_5_IMPLEMENTATION.md | 123 +++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 docs/PHASE_5_IMPLEMENTATION.md diff --git a/docs/PHASE_5_IMPLEMENTATION.md b/docs/PHASE_5_IMPLEMENTATION.md new file mode 100644 index 0000000..f6fc67d --- /dev/null +++ b/docs/PHASE_5_IMPLEMENTATION.md @@ -0,0 +1,123 @@ +# Phase 5 Implementation & Settlement Design Document + +**Variable Remuneration, Compensation, and Commissions System - Hoteles Estelar** + +--- + +This document outlines the detailed architectural decisions, logical workflows, API specifications, UI mockups, and E2E verification plans for **Phase 5: Settlement Engine & Approvals**. + +## 1. Architectural Strategy & Logic Flows + +### 1.1. Core Settlement Calculation Engine (US-COM-006) +The system calculates commissions automatically based on defined rules. For a target period (`YYYY-MM`), the calculation steps are: +1. **Fetch Active Plans**: Resolve the active version of each `CompensationPlan` for target collaborators. +2. **Fetch Goals**: Resolve the goal amount for target users from the `Goal` table for the matching period. +3. **Fetch Sales Results**: Retrieve and sum the total `amount` and `salesCount` of `SalesResult` records generated by each collaborator in the period. +4. **Determine Achievement**: + $$\text{Achievement \%} = \frac{\text{Sum of Sales Amount}}{\text{Goal Amount}}$$ +5. **Apply Rules**: + - Compare the Achievement % against boundaries in the plan's `CalculationRule` list. + - For `TIER` rules: Payout is calculated as: + $$\text{Commission} = \text{Sum of Sales Amount} \times \text{Rule Rate}$$ + - For `BONUS` rules: Payout is the fixed `payoutAmount` configured. +6. **Enforce Cap Limit**: If the sum of calculated payouts exceeds the plan's `maxCap`, the payout is capped at `maxCap`. + +### 1.2. Retroactive Adjustments & PMS Clawbacks +Hotel booking modifications, refunds, or cancellations frequently occur after past commissions have been paid. The engine processes retroactive adjustments as follows: + +```mermaid +graph TD + A[Start Calculation for Month M] --> B[Retrieve Month M-1 and M-2 Sales Results] + B --> C[Fetch Original Settlements for Month M-1 and M-2] + C --> D{Any sales discrepancy found?} + D -->|No| E[Continue with normal month M calculation] + D -->|Yes| F[Recalculate past commission with live sales data] + F --> G[Calculate Delta: Corrected Payout - Previously Paid Payout] + G --> H[Create Pending Adjustment Settlement record in DB linked to Original ID] + H --> I[Add Delta to Month M Total Payout: Total = Commission + Bonus + Sum(Deltas)] +``` + +- If $\Delta \text{Payout} < 0$, it is treated as a **Clawback** (reduction). +- If $\Delta \text{Payout} > 0$, it is treated as an **Adjustment Credit** (addition). +- A self-referencing relationship is stored in the `Settlement` table via `originalSettlementId` to preserve the historical audit trail. + +### 1.3. Webhook Branching & Environment Isolation +To prevent test calculation suites from polluting production records, the n8n workflows implement a strict routing architecture: +1. **Conditional Branching**: The n8n webhook endpoint evaluates the request URI path. +2. **Test/Staging calls**: Webhooks routed via `/webhook-test/calculate-settlements` route to `http://app-dev:3001` (running development stack, connected to `TEST_DATABASE_URL`) and validate signatures using `N8N_WEBHOOK_SECRET_DEV`. +3. **Production calls**: Webhooks routed via `/webhook/calculate-settlements` route to `http://app-prod:3000` and validate signatures using `N8N_WEBHOOK_SECRET`. + +### 1.4. SOC 2 Log Redaction +All Next.js API routes run console outputs through a filtering proxy that redacts base salaries, passwords, and custom compensation parameters before writing to standard streams: +- Intercepts logs on settlement mutations. +- Replaces values for keys: `password`, `passwordHash`, `baseSalary`, `bankAccount`, and `salary` with `[REDACTED]`. + +--- + +## 2. API Specifications + +### 2.1. `POST /api/settlements/calculate` (Process Settlements) +- **Role Restriction**: `admin` | `analyst` +- **Request Body**: + ```json + { + "period": "2026-06", + "simulateOnly": false + } + ``` +- **Response**: + - `201 Created` (Direct commit mode): + ```json + { + "success": true, + "code": "SETTLEMENTS_CALCULATED", + "metadata": { + "count": 14, + "totalCommission": 85000.00, + "totalAdjustment": -3500.00 + } + } + ``` + +### 2.2. `POST /api/settlements/[id]/approve` (Approve Payout) +- **Role Restriction**: `commercial_leader` +- **Logic**: Enforces RLS. A leader can only approve settlements belonging to collaborators of hotels in their region. Sets status to `APPROVED`, logs `approvedBy`, and triggers a callback notification. +- **Response**: `200 OK`. + +### 2.3. `POST /api/settlements/[id]/reject` (Reject Payout) +- **Role Restriction**: `commercial_leader` +- **Request Body**: + ```json + { + "reason": "Venta reportada del colaborador no coincide con el cierre del hotel" + } + ``` +- **Logic**: Sets status to `REJECTED`, stores the mandatory reason in the database, and sets the state to allow correction and recalculation. +- **Response**: `200 OK`. + +--- + +## 3. UI Design Specifications + +### 3.1. Simulation Dashboard (`/sales/simulation`) +Provides analysts with a dry-run environment: +1. **Period Selector**: Dropdown to select the target payout month. +2. **Comparison Matrix**: Grid displaying: + - Collaborator | Plan Version | Goal | Confirmed Sales | Achievement % | Proposed Commission | Retroactive Adjustments | Total Payout (Simulated) +3. **Dry-Run Mode Toggle**: Execute calculations without writing data or triggering final callbacks. + +### 3.2. Approvals Panel (`/settlements/approvals`) +Allows leaders to sign off on payouts: +1. **Segregated List**: Displays pending settlements, restricted to the leader's region. +2. **Reason Modal**: Appears when selecting "Rechazar", requiring a text entry. +3. **Status Badges**: Shows simulated vs finalized payout progress. + +--- + +## 4. Headless Puppeteer Verification Plan + +We will create a verification script `prisma/test-phase5-ui.js` that tests: +1. **Engine Accuracy**: Seed sales/goals, run calculation, verify output against expected mathematical tiers. +2. **Clawback Delta Logic**: Update a past month's sale amount, run the calculation again, and verify that the current month's proposed settlement contains a negative adjustment equal to the commission delta. +3. **Leader Isolation**: Confirm `lider_ctg` is blocked from approving a settlement for a collaborator in Antioquia (`EST-MDE`). +4. **Rejection Constraint**: Ensure a rejection request fails (400) if the reason is omitted.