Files
ToldoConjunto/skills/toldo-domain-modeling/SKILL.md

3.9 KiB

Agent Skill: toldo-domain-modeling

Metadata

name: toldo-domain-modeling
description: Modelado de dominio CESTA (productos por productor, inventario, ventas, gastos, ajustes con motivo, cuadre QR/efectivo, reportes). Seguir reglas de negocio estrictamente.

When to use

Use this skill when:

  • Modeling entities, value objects, or aggregates
  • Implementing business rules
  • Writing domain logic
  • Creating use cases related to CESTA flows
  • Validating invariants

Core Domain Concepts

Products are unique per producer

Critical Rule: Same product name from different producers = DIFFERENT products.

// CORRECT
Producto { productorId: "A", nombrePresentacion: "Café molido 250gr Santa Ana" }
Producto { productorId: "B", nombrePresentacion: "Café molido 250gr Familia Gonzalez" }

// WRONG - same entity for different producers

Uniqueness constraint: (productorId, nombrePresentacion)

Adjustments require reason

Critical Rule: ALL adjustments MUST have a non-empty motivo.

  • Adjustments to inventory, sales, cash discrepancies, QR discrepancies all require reason
  • Adjustments are tracked separately
  • Must appear marked as "modificado/cambiado" in reports
  • Store cantidadAnterior, cantidadNueva, diferencia, motivo

Inventory Management

  • Initial inventory: Should match previous day's final inventory
  • Differences: If different, record difference and use real inventory
  • Week restocks: Register with producto, cantidad, recibidoPor (person who received)
  • End-of-day: Should match initial inventory minus sold products

Sales

  • Lines with: productoId, cantidad, precioUnitario, formaPago (EFECTIVO | QR)
  • Track separately for cash and QR reconciliation
  • Each sale line has subtotal

Expenses (Gastos)

  • Track during day: tape, pens, bags, transportation, etc.
  • Include in reconciliation

Cash Reconciliation (Cuadre)

saldoEsperadoEfectivo = baseInicial + totalVentasEfectivo - totalGastosEfectivo
descuadreEfectivo = saldoRealEfectivo - saldoEsperadoEfectivo (or vice versa, track clearly)
totalVentas = totalVentasEfectivo + totalVentasQR
  • Separate cash and QR
  • Compare QR registrado vs QR banco
  • Track discrepancies

Reports by Producer

Must include:

  1. Inventory differences vs previous day
  2. Initial inventory (real)
  3. Inventory movements from sales (salidas)
  4. Sales value for producer's products
  5. Total per producer

Consolidated Reports

By date range, week, or month aggregating all data.

Value Objects

Prefer value objects for primitives that have business meaning:

// Money value object
class Money {
  constructor(private readonly cents: number) {}
  add(other: Money): Money { ... }
  subtract(other: Money): Money { ... }
  // ...
}

// Quantity
class Quantity {
  constructor(private readonly value: number) {}
  // ensure non-negative, etc.
}

Domain Invariants

Enforce these invariants:

  • Producto has valid productorId
  • Ajuste always has non-empty motivo
  • Venta has at least one line
  • Cuadre calculations are consistent
  • Inventory movements are traceable
  • Payment methods are only EFECTIVO or QR

TDD for Domain

Always write tests first for domain logic:

  1. Write failing test for rule/invariant
  2. Implement minimal code to pass
  3. Refactor
  4. Repeat

Domain tests should be pure, fast, no I/O, no framework dependencies.

Common Pitfalls

  • ❌ Treating same product name as same product across producers
  • ❌ Allowing adjustments without motivo
  • ❌ Mixing cash and QR totals
  • ❌ Not tracking receivedBy for week restocks
  • ❌ Forgetting to mark adjustments as changed in reports
  • ❌ Losing traceability of modifications

Resources

  • See openspec/changes/add-toldo-poc-capacitor/specs/toldo-poc/spec.md for all scenarios
  • See design.md for full entity definitions
  • Follow all business rules strictly