Skip to content

feat(time-tracking): lock and unlock time from a sign-off panel - #227

Merged
ponbac merged 3 commits into
masterfrom
t3/kleer-lock-reports
Oct 30, 2026
Merged

ponbac merged 3 commits into
masterfrom
t3/kleer-lock-reports

Conversation

@ponbac

@ponbac ponbac commented Oct 30, 2026

Copy link
Copy Markdown
Owner

What and why

Week and month ends are hard deadlines for locking time, but Toki could only warn about it and link out to Kleer. The warnings also missed days without entries, and they showed at the same volume whatever the urgency.

This adds locking to Toki. A sign-off panel beside the entries reviews what's due and locks it with one click. It replaces the "previous week/month unlocked" alerts.

How

Toki works out two recurring deadlines from the person's schedule: the last scheduled day of each week and each month. Anything due or overdue becomes one lock. The panel stays out of the way until then, and gets louder only as a deadline passes.

Attention levels

flowchart TD
    A{Lock due?} -->|No| B{Due tomorrow?}
    B -->|No| C[Clear: one quiet line]
    B -->|Yes| D[Soon: same line with a dot]
    A -->|Due today| E[Due: full panel, tinted header, nav dot]
    A -->|Week has ended| F[Overdue: amber header, nav dot, daily toast]
    A -->|Month has ended| G[Month overdue: red header, red nav dot, daily toast]
    E --> H[Lock]
    F --> H
    G --> H
    H --> I[Panel closes, back to the quiet line]
Loading

Clicking a day jumps the list to it, so a short day can be fixed with the review still open. Animations play once and stop, today is never flagged, and the toast shows at most once a day and never on the time tracking page.

Changes

  • POST /time-tracking/lock and POST /time-tracking/unlock go through the existing provider-neutral ports. Neither is in the curated agent OpenAPI, so no MCP tool is needed.
  • Kleer refuses a range crossing a month end, so the adapter sends one request per month. If a later month fails the earlier one stays locked; locking is idempotent, so a retry finishes it.
  • Kleer accepts a reversed range and acts on it, so the service rejects it with a 400.
  • Kleer answers 200 for days it refuses to unlock, so the service reads the statuses back and returns stillLocked. The UI warns about those days.
  • The frontend only unlocks runs of approved days. Two certified days opened when a mixed range was unlocked, and that is unexplained.
  • Locked and certified read the same in the UI.
  • The nav dot runs on every page, so it reads day statuses and schedule only. Hours on an unscheduled weekend don't count there until the time tracking page has loaded entries.

Kleer findings are in .docs/kleer.md.

Limitations

  • Production Kleer has not been exercised. All lock and unlock testing was against test-api.kleer.se, including whether the service account may lock.
  • Kleer records the integration account, not the person, as registration-user on the events it locks.
  • Reminders are in-app only. There is no push notification on the due day.

Checks

  • Automated: cargo fmt --check, cargo clippy on kleer and toki-api, cargo test -p kleer -p toki-api (825 passed), bun tsc, bun lint, bun run test (338 passed), bun run build.
  • New tests cover month splitting, reversed ranges, still-locked reporting, the deadline rules and the attention levels.
  • Manual, against the Kleer test API: locked week 44 across the month end from the panel, undid it, confirmed a reversed range returns 400, and confirmed a certified day comes back in stillLocked.
  • Manual, in a browser with temporary scenario data since removed: every attention level in dark mode, some in light mode, and clear and due at phone width. Motion was only checked through still screenshots.

🤖 Generated with Claude Code

Replace the unlocked-period alerts with a panel beside the entries that reviews what's due and locks it in Kleer. It stays one quiet line until a week or month lock is due, then escalates up to a nav dot and a daily toast when overdue.

The Kleer adapter splits ranges at month ends because Kleer refuses a range across months. Unlock reads statuses back because Kleer answers success for days it refuses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ponbac
ponbac marked this pull request as ready for review October 30, 2026 21:20
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-30T21:27:28.861598Z cc311b3 Manual request
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 80a2ef8f29

ℹ️ 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".

ponbac and others added 2 commits October 30, 2026 22:26
…he timeline

The lock button could fire before a browsed period's statuses arrived, which also made Undo reopen days that were already locked. In day mode the timeline ignored the day picked in the sign-off panel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ponbac

ponbac commented Oct 30, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: cc311b35a7

ℹ️ 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".

@ponbac
ponbac merged commit 225ff39 into master Oct 30, 2026
10 checks passed
@ponbac
ponbac deleted the t3/kleer-lock-reports branch October 30, 2026 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant