The one entity payroll needs: a standing instruction to pay an employee a
fixed amount, at a fixed cadence, from a given start date, a given number
of times.
Two design decisions worth reviewing here, both documented in
docs/data-model.md:
- Schedule position is `periods_done` (a counter), not a stored
`next_run_at`. Every payday is recomputed as occurrence(start_date,
frequency, n), so a late tick cannot make the schedule drift, and a
contract anchored on the 31st pays 28 Feb then 31 Mar rather than being
permanently pinned to the 28th.
- `periods_done` counts periods *consumed* (paid or deliberately skipped),
not periods successfully paid. A failed payout leaves it untouched so the
next tick retries that payday instead of dropping it.
There is no employee table — an employee is an LNbits account. Only
`employee_username` is copied, and only as a display label so history stays
readable after a rename; authorisation always goes through `employee_id`.
Ordinary migrations, not the migrations_fork.py split: this is an
aiolabs-original extension, so there is no upstream migrations.py to stay
byte-identical with.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018jy52j9GRZ6XKa1Zt21LLj