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.
This commit is contained in:
61
docs/data-model/month-closures.md
Normal file
61
docs/data-model/month-closures.md
Normal file
@@ -0,0 +1,61 @@
|
||||
---
|
||||
type: SQLite Table
|
||||
title: month_closures
|
||||
description: One row per employee per calendar month tracking the confirm -> lock workflow that gates payroll.
|
||||
resource: backend/src/db/index.ts
|
||||
tags: [data-model, sqlite, payroll]
|
||||
timestamp: 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](./employees.md) |
|
||||
| `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](./attendance-events.md)). 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](./payroll.md) 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
|
||||
|
||||
- [payroll](./payroll.md)
|
||||
- [attendance_events](./attendance-events.md) — `hasOpenSessionInPeriod` gate
|
||||
- [Closure API](/docs/api/closure-routes.md)
|
||||
Reference in New Issue
Block a user