Files
eatme/docs/data-model/month-closures.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.4 KiB

type, title, description, resource, tags, timestamp
type title description resource tags timestamp
SQLite Table month_closures One row per employee per calendar month tracking the confirm -> lock workflow that gates payroll. backend/src/db/index.ts
data-model
sqlite
payroll
2026-08-16T00:00:00Z

month_closures

Tracks where a given employee's given month is in the confirm/lock workflow. Rows are created lazily — the first time the employee opens that period — not proactively for every employee/month combination.

Schema

Column Type Description
id INTEGER PK autoincrement
employee_id INTEGER references employees
period TEXT YYYY-MM
status TEXT waiting_employee | confirmed | locked
employee_confirmed_at TEXT | NULL set on confirm
locked_at TEXT | NULL set on lock, cleared on reopen

UNIQUE (employee_id, period).

State machine

waiting_employee --employee confirms--> confirmed
confirmed --admin locks--> locked
locked --admin reopens--> confirmed   (undoes a premature lock)
  • Confirm (confirmClosure, backend/src/services/closure.ts): employee-only action, blocked while any session in that period is still open (see attendance_events). Idempotent — confirming an already-confirmed month is a no-op, not an error.
  • Lock (lockClosure, called from lockAndFinalizePayroll in backend/src/services/payroll.ts): admin-only, requires confirmed, re-checks for an open session (defensive — time may have passed since confirm), freezes the payroll row.
  • Reopen (reopenPayroll): undoes a lock made before the numbers were actually right (e.g. the hourly rate wasn't set yet) — back to confirmed, with the payroll row reset to draft. Only possible while payroll status is ready, not once paid — that's the point past which a mistake has to be corrected some other way, not silently rewritten.

Unlike the source Google Apps Script this was ported from (gscript/ClosureService.js), there's no separate MANAGER_APPROVED state — that system modeled independent ADMIN/MANAGER/ACCOUNTANT roles; this app has one owner-admin, so "manager approves" and "admin locks" collapse into a single action here.

Related