82 lines
3.8 KiB
Markdown
82 lines
3.8 KiB
Markdown
# Phase 3 Implementation & Security Design Document
|
|
|
|
**Variable Remuneration, Compensation, and Commissions System - Hoteles Estelar**
|
|
|
|
---
|
|
|
|
This document outlines the design decisions, schema details, API routing, and security/RLS validations implemented for **Phase 3: Compensation Configuration**.
|
|
|
|
## 1. Architectural Strategy & Logic Flows
|
|
|
|
### 1.1. Plan Creation & Mandatory Field Validation
|
|
The system allows Administrators to define compensation structures. The database structure ensures strict alignment with commercial dimensions:
|
|
- Plans are tied to hotels, regions, roles, or campaigns.
|
|
- Mandatory fields are verified at both the frontend schema layer (UI form validation) and the backend API layer.
|
|
|
|
### 1.2. Plan Versioning Logic (Audit Integrity)
|
|
To maintain historical reproducibility:
|
|
- Direct updates to a plan in `DRAFT` status are performed in-place (same record).
|
|
- Updates to a plan in `ACTIVE` status trigger the versioning engine:
|
|
1. The existing active plan is updated to `status = 'INACTIVE'` and `validity_end = NOW()`.
|
|
2. A duplicate plan is inserted with `version = original_version + 1`, `status = 'ACTIVE'`, `validity_start = NOW()`, and `validity_end = NULL`.
|
|
3. All calculation rules associated with the original plan are copied to the new version.
|
|
4. Historical settlements (`SETTLEMENTS` table) remain linked to the original `plan_id` (representing the old version), preserving historical calculations.
|
|
|
|
```mermaid
|
|
graph TD
|
|
A[Request to Edit Plan] --> B{Is Status ACTIVE?}
|
|
B -->|No - DRAFT/INACTIVE| C[Update Plan In-Place]
|
|
B -->|Yes - ACTIVE| D[Mark Current Plan as INACTIVE with validity_end = NOW]
|
|
D --> E[Clone Plan Details]
|
|
E --> F[Increment Version +1]
|
|
F --> G[Insert New Plan as ACTIVE with validity_start = NOW]
|
|
G --> H[Clone and Associate Calculation Rules]
|
|
```
|
|
|
|
### 1.3. Calculation Rules Configuration
|
|
Rules define how commissions are computed based on achievement percentiles:
|
|
- **TIER**: Payout is a percentage rate applied to sales once a tier threshold is met (e.g., 90% to 100% achievement yields 1.5% commission rate).
|
|
- **BONUS**: A fixed cash payout once a threshold is met.
|
|
- Boundaries are validated to prevent overlap (`min_achievement` must be `< max_achievement` and contiguous).
|
|
|
|
### 1.4. Goal Assignment
|
|
Goals are assigned per period (`YYYY-MM`) at different scopes (`INDIVIDUAL` | `TEAM` | `HOTEL`) to define target quotas. Calculations evaluate actual sales against these quotas.
|
|
|
|
---
|
|
|
|
## 2. API Specifications
|
|
|
|
### 2.1. `POST /api/plans` (Create Plan)
|
|
- **Role Restriction**: `admin` or `director`
|
|
- **Request Body**:
|
|
```json
|
|
{
|
|
"name": "Plan Ventas CTG Q2",
|
|
"code": "PLAN-CTG-Q2",
|
|
"validityStart": "2026-06-01T00:00:00Z",
|
|
"type": "PERCENTAGE", // PERCENTAGE | SCALE | CONDITIONAL | FIXED
|
|
"status": "DRAFT"
|
|
}
|
|
```
|
|
|
|
### 2.2. `PUT /api/plans/[id]` (Update/Version Plan)
|
|
- **Role Restriction**: `admin` or `director`
|
|
- **Logic**: Evaluates status to execute in-place updates or clone/version logic.
|
|
|
|
### 2.3. `POST /api/plans/[id]/rules` (Configure Rules)
|
|
- **Role Restriction**: `admin` or `director`
|
|
- **Request Body**: Array of calculation rules to bulk upsert.
|
|
|
|
### 2.4. `POST /api/goals` (Assign Goals)
|
|
- **Role Restriction**: `admin` or `director`
|
|
|
|
---
|
|
|
|
## 3. Puppeteer Validation Plan
|
|
We verify usability using headless browser automation tests:
|
|
1. **Form Validation**: Try to submit a plan with empty name or code, confirming that HTML5/React validation prevents submission.
|
|
2. **Creation**: Fill fields, click submit, verify redirect to rules setup.
|
|
3. **Rules Config**: Add tiers, save rules, confirm database records.
|
|
4. **Versioning Check**: Modify an active plan and verify that:
|
|
- Old plan record has status `INACTIVE` and `validity_end` is populated.
|
|
- New plan record is created with version `2` and status `ACTIVE`.
|