Files

128 lines
3.9 KiB
Markdown

# Agent Skill: toldo-domain-modeling
## Metadata
```yaml
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.
```typescript
// 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)
```typescript
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:
```typescript
// 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