Repository navigation
Release 2.1.0: PIN tablet terminals - #36
Conversation
Add PIN identification and explicit device-bound clock-in/out alongside QR, HR credential management, shared lockout, atomic retries and terminal audit. Ship the additive migration, restricted runtime-role and audit tooling, regression coverage and release/upgrade documentation. Refs #33; RFID remains a separately planned extension. Signed-off-by: Patrick Schiller <p@trickschiller.de>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c049bdb600
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| device.terminal, | ||
| now, | ||
| ); | ||
| const schedule = await this.schedules.resolveForEmployee(employeeId); |
There was a problem hiding this comment.
Resolve schedules on the booking transaction
During a burst of PIN bookings, each interactive transaction can occupy a pool connection while waiting on the global advisory lock; the lock holder then calls resolveForEmployee(), which uses the main PrismaService rather than tx and therefore needs another connection. If the waiting transactions have exhausted the pool, the only transaction able to proceed waits for a connection held by those blocked transactions, causing pool timeouts and failed bookings. Resolve the schedule through the existing transaction client.
Useful? React with 👍 / 👎.
| if (error instanceof ApiError && error.code === 'TERMINAL_DEVICE_REVOKED') { | ||
| storeTerminalDeviceToken(null); | ||
| } |
There was a problem hiding this comment.
Clear unrecognized device tokens as well
When a stored kiosk token no longer exists in the database—for example after a restore, device-table cleanup, or corrupted local storage—the guard returns TERMINAL_DEVICE_INVALID, not TERMINAL_DEVICE_REVOKED. This handler consequently leaves the token in storage, and KioskPage keeps rendering only the retry path instead of returning to pairing, so the kiosk cannot recover without manually clearing browser storage. Clear both invalid and revoked device-token responses, as the previous status-based handling did.
Useful? React with 👍 / 👎.
Summary
Release 2.1.0 lets Team employees identify at a paired tablet with their personal number and a separate PIN, then explicitly confirm clock-in or clock-out. HR chooses QR/PIN per terminal and manages one-time PIN generation, reset, disable and unlock. Existing QR and the 2.0.1 personnel access controls remain supported.
Linked issue
Refs #33 (PIN-first increment). RFID remains separately planned; this PR does not close the remaining RFID scope.
Changes
argon20.44.0), shared lockout/rate budgets, short-lived device-bound grants and transactional bookings with identical retries.How was this tested?
Local: 279 API E2E, 178 Web, 88 shared-domain and 27 Ops tests; 9 Chromium cases against the newly built 2.1.0 Dockerstack. Lint/typecheck, host/Docker builds, release metadata and
pnpm verify:apipass. Local functional acceptance and full release were authorized on 11 October 2026. Fresh migrations pass; existing synthetic pilot volumes are retained and backed up.Release notes
PIN tablet terminals and HR audit in 2.1.0; curated notes in RELEASE_NOTES.md.
Upgrade impact
20260930090000_terminal_pin_credentials; existing terminals stay QR-only.Checklist