Files
eatme/docs/data-model/payroll.md
Michal Pemcak 94933cac5c Update OKF docs bundle, README, and CLAUDE.md for today's features
Documents the shift planning and closure/payroll modules (new tables,
routes, stores), the dark redesign, and the docker-compose-broken-host
workaround. Adds CLAUDE.md pointing agents at docs/. Translates README to
English and keeps host-specific infrastructure details out of the repo.
2026-08-16 18:41:11 +02:00

2.5 KiB
Raw Permalink Blame History

type, title, description, resource, tags, timestamp
type title description resource tags timestamp
SQLite Table payroll Computed + admin-adjusted pay per employee per month — base hours pay, tips, bonus, other, and payment status. backend/src/db/index.ts
data-model
sqlite
payroll
2026-08-16T00:00:00Z

payroll

One row per employee per period, created the first time the admin either saves a draft adjustment or locks the month.

Schema

Column Type Description
id INTEGER PK autoincrement
employee_id INTEGER references employees
period TEXT YYYY-MM
worked_minutes INTEGER snapshotted at last save/lock, not live
base_amount REAL worked hours × the rate active on each shift's own date — see pay_rates
tips_amount / bonus_amount / other_amount REAL admin-entered, default 0
final_amount REAL sum of the four amounts above
status TEXT draft | ready | paid
payment_date TEXT | NULL set when marked paid
updated_at TEXT ISO 8601 UTC

UNIQUE (employee_id, period).

Status lifecycle

draft --admin locks the month closure--> ready --admin marks paid--> paid
ready --admin reopens--> draft
  • draft: editable. saveDraftAdjustments (backend/src/services/payroll.ts) recomputes base_amount / worked_minutes fresh from attendance_events on every save, and requires the linked month_closures row to be at least confirmed (not still waiting_employee).
  • ready: frozen. Set by lockAndFinalizePayroll, which locks the closure in the same call. saveDraftAdjustments refuses to touch a non-draft row — this is what turns "already locked" into the right error message instead of the generic "not confirmed yet" one (a real bug caught by payroll.test.ts: the two checks used to overlap).
  • paid: terminal. Set by markPaid, stamps today's date. Not reopenable — a mistake past this point needs a manual correction, not a silent rewrite.

This collapses the source system's four-stage accountant pipeline (READY_FOR_ACCOUNTANT / PROCESSING / PROCESSED / PAID in gscript/PayrollService.js) down to two — ready and paid — since there's no separate accountant role here for the intermediate stages to mean anything.

Related