semillero-special-hotel/docs/PHASE_4_IMPLEMENTATION.md

9 KiB

Phase 4 Implementation & Integration Design Document

Variable Remuneration, Compensation, and Commissions System - Hoteles Estelar


This document outlines the detailed design decisions, schema mappings, API endpoints, UI layouts, and security/idempotency validations planned for Phase 4: Data Import & Integrations.

1. Architectural Strategy & Logic Flows

1.1. Excel Parser & Data Validation Flow

To prevent manual data-entry errors, the system allows authorized users (Administrators, Analysts, and Commercial Leaders) to upload Excel/CSV sheets with sales results.

Excel Spreadsheet Format Specifications

Two pre-populated spreadsheets are available under the public directory:

  1. Template spreadsheet: import_sales_template.xlsx — Clean column layout with a single dummy row reference. This template is made directly downloadable through the program's UI.
  2. Test spreadsheet: import_sales_test.xlsx — Contains mixed valid and invalid rows to verify frontend/backend validation error rendering.

The spreadsheet contains the following mandatory headers:

  • Colaborador: String representing the unique collaborator username (e.g. colaborador_mde).
  • Periodo: String matching the target period in YYYY-MM format (e.g. 2026-06).
  • Hotel: String representing the unique hotel code (e.g. EST-MDE).
  • Monto: Decimal/Numeric positive value of total sales.
  • Cantidad: Integer positive value of total sales count.
  • Id_Transaccion: String representing the external transaction tracking ID (e.g. TX-EST-MDE-001).

The server-side parsing will:

  1. Parse the uploaded .xlsx or .csv file buffer using the xlsx library.
  2. Resolve row-level records and perform Atomic Validation on all rows before write transactions.
  3. If any row contains errors, abort the entire operation and return a structured JSON report identifying the exact rows, columns, values, error codes, and translation metadata.

1.2. Multilingual "Code + Metadata" Response Pattern

To support dynamic localized UI translations, the API does not return pre-translated text strings. Instead, it enforces the Code + Metadata pattern:

  • Success Responses: Return a strict static success code alongside numeric/string variables in a metadata payload.
  • Error Responses: Return strict error codes (USER_NOT_FOUND, INVALID_PERIOD_FORMAT, etc.) with their respective parameters. The client-side application translates these keys locally using translation tables.

1.3. Two-Tier Idempotency Control (API & DB Layer)

To guarantee that duplicate uploads do not lead to duplicate commission calculations:

  1. API Header Check: The POST /api/sales/import endpoint requires a client-generated Idempotency-Key header.
  2. Key Check:
    • The backend checks if any existing sales results contain an idempotency key matching the pattern ${idempotency_key}-*.
    • True: The import is recognized as a duplicate. The server returns the cached success details of the previous import, preventing re-execution.
    • False: Processing continues.
  3. Row-level uniqueness: Each inserted row is saved with a unique database constraint idempotencyKey = ${idempotency_key}-${row_index}, guaranteeing database-level data integrity under concurrent scenarios.
graph TD
    A[Upload request with Idempotency-Key] --> B{Key already processed?}
    B -->|Yes| C[Return cached/existing import summary]
    B -->|No| D[Parse Excel/CSV Buffer]
    D --> E{Any validation error?}
    E -->|Yes| F[Abort and return detailed error list]
    E -->|No| G{N8N_WEBHOOK_URL set?}
    G -->|Yes| H[Forward rows to n8n Webhook & return 202 Accepted]
    G -->|No / Test| I[Prisma Transaction: Save rows with idempotency key + Audit Log]
    I --> J[Return 201 Created]

1.4. n8n Integration & Callback Validation

For automatic integrations (US-COM-005), the workflow follows a Thick Client (Next.js), Thin Coordinator (n8n) architecture:

  1. Zero DB Connections & Zero Code Blocks: n8n does not connect directly to the database or run heavy processing code. Instead, n8n invokes Next.js validation and logic endpoints, using n8n strictly for pipeline orchestration and third-party notifications.
  2. Encapsulated LLM/AI & Model Fallback: All LLM-based checks (semantic anomaly checks) are executed directly inside n8n using native nodes. The workflow uses a Primary Chat Model node (DeepSeek) and a Fallback Chat Model node (Google Gemini) hooked to a LangChain LLM Chain node with failover enabled.
  3. Dynamic Workspace Credential Resolution: During the bootstrap and E2E test runs, the system queries GET /api/v1/credentials from n8n, searches for active credentials matching the DeepSeek and Gemini types (deepSeekApi and googlePalmApi), and dynamically injects their IDs and names into the workflow JSON before deployment.
  4. Webhook Security: Next.js exposes a public-facing but secured callback endpoint /api/sales/batch-save.
  5. Signature Verification: Webhooks from n8n must include the x-n8n-signature header. The server verifies this token against N8N_WEBHOOK_SECRET before executing database updates.
  6. Stalwart SMTP Server: All outbound notifications (such as system error reports or settlement anomalies alerts) are sent by n8n using native SMTP/Email nodes pointing to the Stalwart mail server.
  7. Async Status Polling: The frontend displays a progress UI. If routed through n8n, it polls GET /api/sales/import/status/[key] to check database status and update progress.

2. API Specifications

2.1. POST /api/sales/import (Upload Sales Sheet)

  • Role Restriction: admin | analyst | commercial_leader
  • Headers:
    • Idempotency-Key: Required string
  • Request Body: multipart/form-data with file field containing the spreadsheet.
  • Response:
    • 201 Created (Direct import mode):
      {
        "success": true,
        "code": "IMPORT_SUCCESSFUL",
        "metadata": {
          "count": 45,
          "totalAmount": 1563000.00
        }
      }
      
    • 202 Accepted (n8n mode):
      {
        "success": true,
        "code": "IMPORT_ACCEPTED",
        "metadata": {
          "idempotencyKey": "unique-client-key-123",
          "status": "PROCESSING"
        }
      }
      
    • 400 Bad Request (Validation errors):
      {
        "success": false,
        "error": {
          "code": "IMPORT_VALIDATION_FAILED",
          "details": [
            { 
              "row": 3, 
              "column": "Colaborador", 
              "value": "colaborador_inexistente", 
              "code": "USER_NOT_FOUND", 
              "metadata": { "username": "colaborador_inexistente" } 
            },
            { 
              "row": 4, 
              "column": "Periodo", 
              "value": "2026/06", 
              "code": "INVALID_PERIOD_FORMAT", 
              "metadata": { "expected": "YYYY-MM" } 
            }
          ]
        }
      }
      

2.2. POST /api/sales/batch-save (n8n Webhook Callback)

  • Security Check: Header x-n8n-signature === process.env.N8N_WEBHOOK_SECRET
  • Request Body:
    {
      "idempotencyKey": "unique-client-key-123",
      "uploaderId": 1,
      "sales": [
        { "username": "colaborador_mde", "hotelCode": "EST-MDE", "period": "2026-06", "amount": 15000.00, "salesCount": 3 }
      ]
    }
    
  • Response: 201 Created or 400 Bad Request.

2.3. GET /api/sales/import/status/[key] (Poll Status)

  • Response:
    {
      "idempotencyKey": "unique-client-key-123",
      "status": "SUCCESS" // PROCESSING | SUCCESS | FAILED
    }
    

3. UI Design Specifications

We will create a premium drag-and-drop loading interface at /sales/import:

  1. Interactive Drop Zone: Elegant border animation on dragover. Shows file metadata upon dropping.
  2. Template Download Link: Sleek, visible button to download the pre-formatted Excel template directly.
  3. Real-time Progress Indicator: Fluid CSS progress bar tracking parse/upload state.
  4. Inconsistency Panel: If the API returns validation errors, displays them in a sleek, scrollable log table with warning icons.
  5. Permissions Enforcement: Renders standard unauthorized page if role is not permitted.

4. Headless Puppeteer Verification Plan

We will create a new test script prisma/test-phase4-ui.js verifying:

  1. Role Enforcement: colaborador_mde is blocked from accessing the page and endpoint.
  2. Missing Header Validation: Upload fails if Idempotency-Key is missing.
  3. File Validation: Uploading an Excel file with negative values or fake users displays validation errors.
  4. Successful Direct Import: Uploading a valid Excel file imports rows, saves them, and shows success.
  5. Idempotency Prevention: Re-uploading with the same key returns the success message without modifying/inserting additional database records.
  6. n8n Webhook Callback Integrity: POSTing to /api/sales/batch-save with an invalid signature is blocked (401), while a valid signature is processed.