Documentation Index
Fetch the complete documentation index at: https://mintlify.com/AdriP-maker/JAAR_Antigravity/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Every time a cobrador (collector) registers a payment, SIMAP Digital automatically calculates a commission and splits it between two parties: the cobrador and the development team. This mechanism is defined in requirement RF-17 and implemented in comisionesService.js.
The commission system exists to incentivize the cobrador to collect regularly and accurately. Because rural water boards in Panama typically rely on a single volunteer treasurer, attaching a small monetary reward to each successful collection creates a concrete motivation to maintain up-to-date records — even when operating in offline-only conditions.
Default configuration
Commission settings are stored in the same config table in IndexedDB that holds the tariff configuration. The defaults are:
| Setting | Default value | Description |
|---|
comisionPorPago | B/.1.00 | Fixed commission generated by each payment |
splitCobrador | 0.40 (40%) | Cobrador’s share of each commission |
splitDevs | 0.60 (60%) | Development team’s share |
These are loaded by getComisionesConfig() in comisionesService.js:
export async function getComisionesConfig() {
const cfg = await getConfig();
return {
splitDevs: cfg.splitDevs || 0.60,
splitCobrador: cfg.splitCobrador || 0.40,
comisionPorPago: cfg.comisionPorPago || 1.00,
};
}
How commissions are calculated
When calculateComisiones() runs, it:
- Fetches all payment records from the
pagos table in IndexedDB.
- Sums the
monto field of every record (falling back to the base cuotaDiaria if monto is absent for older rows).
- Multiplies total collected by
splitDevs and splitCobrador respectively to produce each party’s earnings.
const devShare = montoReal * config.splitDevs; // 60%
const cobradorShare = montoReal * config.splitCobrador; // 40%
The function returns a summary object:
{
totalRecaudado: number, // sum of all payment amounts
devShare: number, // developers' total share
cobradorShare: number, // cobrador's total earnings
pagosCount: number, // total number of payment records
config: { splitDevs, splitCobrador, comisionPorPago }
}
Commission is always calculated on the full tariff amount (e.g. B/.3.00), never on a discounted amount. If a resident redeems SIMAP Points for a B/.1.50 discount, the cobrador still earns commission on B/.3.00. This is specified in CU-11 (FA-2) and RF-20 of the requirements document.
Split examples at different commission rates
The table below shows cobrador earnings across three different admin-configured commission levels, using the standard B/.3.00 monthly quota:
| Commission per payment | Cobrador split | Cobrador earns | Dev team earns |
|---|
| B/.1.00 (default) | 40% | B/.0.40 | B/.0.60 |
| B/.1.00 | 50% | B/.0.50 | B/.0.50 |
| B/.1.50 | 40% | B/.0.60 | B/.0.90 |
| B/.1.50 | 50% | B/.0.75 | B/.0.75 |
| B/.0.50 | 40% | B/.0.20 | B/.0.30 |
Validation rule: splitDevs + splitCobrador must equal exactly 1.0 (100%). Attempting to save a configuration where they don’t sum to 1.0 returns { success: false, error: 'Los porcentajes deben sumar 100% (1.0)' }.
Practical example: a full collection day
A cobrador completes 10 payments on a single field visit, all standard monthly quotas (B/.3.00 each):
| Metric | Value |
|---|
| Payments registered | 10 |
| Total collected | B/.30.00 |
| Commission per payment | B/.1.00 |
| Total commission pool | B/.10.00 |
| Cobrador share (40%) | B/.4.00 |
| Dev team share (60%) | B/.6.00 |
The cobrador earns B/.4.00 for that single day of collections — a direct incentive to visit residents promptly and keep the ledger current.
ComisionesPage: what the cobrador sees
The cobrador accesses their earnings dashboard at the /comisiones route (CU-12). The page shows:
- Total acumulado histórico — all commissions earned since account creation.
- Total del mes actual — earnings in the current calendar month.
- Total de pagos procesados — count of payments the cobrador has registered.
- Promedio de comisión por pago — useful for estimating a future collection trip’s value.
- Desglose mensual — a table broken down by month with columns for:
- Mes (month)
- Cantidad de Pagos (payment count)
- Monto Total Cobrado (total amount collected)
- Comisión Ganada (cobrador’s earnings)
The table is sorted from most recent month to oldest. The cobrador can also filter by date range and export the data as CSV.
If no commissions have been recorded yet, the page shows: “Aún no tienes comisiones registradas. Comienza a registrar pagos para generar ingresos.”
Admin configuration: adjusting the split
The admin configures commission splits at /puntos-admin (CU-13). The workflow is:
- Admin opens
/puntos-admin and views the current split (e.g. 60/40).
- Admin enters new percentages — for example, 65% devs / 35% cobrador.
- The system validates that the values sum to exactly 100%.
- On confirmation,
updateComisionesConfig(splitDevs, splitCobrador) is called:
export async function updateComisionesConfig(splitDevs, splitCobrador) {
if (splitDevs + splitCobrador !== 1.0) {
return { success: false, error: 'Los porcentajes deben sumar 100% (1.0)' };
}
const cfg = await getConfig();
cfg.splitDevs = splitDevs;
cfg.splitCobrador = splitCobrador;
await db.config.put({ key: 'general', ...cfg });
return { success: true };
}
- The new split is saved to the
config table in IndexedDB and takes effect for all future payments.
- An audit log entry is written:
"Cambio de split: 60/40 → 65/35 por [admin] el [fecha/hora]".
- Historical commission records are not retroactively modified.
Database structure
Commission data is stored inside the main config table (key 'general') as part of the unified configuration object in IndexedDB. Related tables in the Dexie schema:
| Table | Key(s) | Relevant fields |
|---|
config | key ('general') | comisionPorPago, splitCobrador, splitDevs |
pagos | ++idPago, usuarioId, tipo, mesTarget, fecha | monto, cobradorId, fecha — source records for commission calculation |
auditoria | ++id, timestamp, accion, user_id, afectado_id | Logs every split change with before/after values |
The comisionesService.js derives all totals on demand by querying db.pagos.toArray() and applying the current config split, rather than storing a separate per-payment commission record. This keeps the offline write path simple — one write to pagos plus one to pendingSync per payment.