El historial y sus filtros
Qué se puede filtrar del historial de una cuenta, con qué semántica exacta — y las dos casillas que no dicen lo que parecen.
Ámbito: Plataforma. Esta página describe la semántica de filtrado del libro, la misma que alimenta el historial de la app de Tikin. En
api.tikin.isel historial se lee con listar movimientos, que hoy expone un subconjunto de estos filtros con nombres propios (kind,created_at[gte],created_at[lte]); cuando el resto llegue al API de tenants se anuncia en el changelog.
Hasta el 9-sep-2026 el historial aceptaba filtros y los descartaba en silencio: alguien marcaba "solo de salida" y seguía viendo sus entradas, sin un error en ninguna parte. Desde hoy los filtros se aplican dentro de la consulta al libro, no sobre la página ya traída — filtrar después de paginar devuelve páginas incompletas, y una página incompleta es la forma más callada de esconder plata.
Lo que se puede pedir
| Filtro | Qué acota | Semántica |
|---|---|---|
direction | Entradas o salidas | CREDIT (entra) | DEBIT (sale) |
from / to | El rango de fechas | Semiabierto [from, to): from inclusive, to exclusivo |
tipos | El tipo de movimiento | Tuplas operacion:proposito:direccion, separadas por coma |
role | La pata del asiento | PRINCIPAL | FEE | ADJUSTMENT |
asset | La moneda | COPM, DUSD |
limit / offset | La página | offset para quien pagina por número de página; el cursor sigue siendo el camino correcto |
El rango es semiabierto a propósito. Con un to inclusive, un movimiento del
último día del rango entra o no según la hora a la que ocurrió — el mismo filtro
da dos respuestas distintas. Con [from, to) la regla es una: para "todo agosto"
se pide from=2026-08-01 y to=2026-09-01.
Un filtro ilegible es 400, no una lista sin filtrar. Una fecha que no parsea
o una tupla mal escrita se rechazan. Descartarlas en silencio devolvería el
historial completo — exactamente lo que quien filtró cree que acaba de excluir.
Las tuplas de tipo
El tipo se pide como tuplas operacion:proposito:direccion, con * en
cualquier campo para decir "cualquiera":
tipos=TRANSFER:bono:CREDIT,PAYOUT:*:DEBITTRANSFER:bono:CREDIT— los bonos recibidos.PAYOUT:*:DEBIT— todo retiro, sea cual sea su propósito.- En
proposito, el literalnullpide exactamente los asientos sin propósito, que no es lo mismo que*. - Tope de 32 tuplas: es la lista de casillas de una pantalla, no una consulta analítica.
Son tuplas y no tres listas sueltas porque las listas se cruzan y mienten.
Pedir "bonos recibidos" y "transferencias enviadas" con tres listas independientes
—operaciones [TRANSFER], propósitos [bono, transferencia], direcciones
[CREDIT, DEBIT]— también trae bonos enviados, que nadie pidió. La tupla
mantiene juntos los tres campos que solo significan algo juntos.
Traducir las casillas de una pantalla a estas tuplas es de quien conoce esa pantalla: el libro sabe de operaciones y propósitos, no de etiquetas de una UI.
Las dos casillas que no dicen lo que parecen
Dos límites verificados contra el libro de producción, declarados acá porque una casilla que miente es peor que una casilla que falta:
cash_withdrawal devuelve vacío. El retiro en efectivo se distingue por el
propósito retiro_efectivo, y hoy no hay ni un asiento con ese propósito en
el libro. La casilla no está rota: responde la verdad, que es "ninguno". Lo
tentador —y lo incorrecto— sería hacerla caer a "todos los retiros": mostraría
transferencias bancarias bajo la etiqueta de efectivo.
add_funds incluye las reversiones. Es un superconjunto de
reverse_cash_withdrawal: la plata que vuelve de un retiro reversado entra por
PAYIN y en el historial se pinta igual que cualquier otro ingreso. Se filtra
igual porque se muestra igual — un filtro que no coincide con la etiqueta que la
fila exhibe es peor que no filtrar.
Por qué el role importa para paginar
Un asiento tiene patas: la PRINCIPAL, la FEE, la ADJUSTMENT. Sin acotar el
rol, el limit cuenta patas que el consumidor descarta después, y una página
de 10 llega con 9 filas. De ahí salían las "28 transacciones" de una cuenta que
tenía 369: dos lecturas de la primera página, las dos de tamaño irregular, y un
"¿hay más?" derivado de totales que siempre decían que no.