Skip to content

Add editable trainer-since metadata - #62

Merged
OwenTanzer merged 2 commits into
mainfrom
codex/issue-25-trainer-since
Jul 22, 2026
Merged

Add editable trainer-since metadata#62
OwenTanzer merged 2 commits into
mainfrom
codex/issue-25-trainer-since

Conversation

@OwenTanzer

Copy link
Copy Markdown
Owner

Summary

Completes the reopened scope of #25 by making trainer tenure an explicit, editable profile value instead of deriving it permanently from account creation time.

  • add a month/year Trainer since field to Account Settings
  • persist the value independently from the instructor account audit timestamp
  • return it from account creation, login, account refresh, and account update endpoints
  • keep the browser session synchronized after edits and refreshes
  • render the chosen value consistently on Trainer History
  • centralize validation and local-safe month formatting in a shared helper

Why

Trainer History previously used instructors.created_at as a cosmetic proxy for tenure. That value answers when the application account was created, not when the instructor began training, so experienced trainers who joined the app later could not correct the displayed date.

The new trainer_since value uses month precision (YYYY-MM), matching the product requirement while preserving created_at unchanged for audit and debugging purposes.

Data migration

The schema adds an instructor_profiles table keyed by instructor ID.

  • existing instructors are backfilled from the month portion of created_at
  • new instructors receive an explicit trainer-since month during account creation
  • INSERT OR IGNORE ... SELECT keeps the deployment schema idempotent
  • account reads retain a created_at fallback for defensive compatibility
  • updates use an upsert so profiles remain repairable if a legacy row is absent

A separate profile table avoids a non-idempotent ALTER TABLE in the schema file, which is intentionally rerun during every Worker deployment.

Client compatibility

Persisted browser sessions from before this field existed are normalized on load. If they contain the existing createdAt value, its month is used temporarily; the normal account refresh then replaces it with the server-authoritative profile value.

Date formatting constructs a local-noon calendar date from the year and month, avoiding UTC boundary shifts.

User impact

Instructors can now open Account Settings, choose the correct start month and year, and save it without changing their login name, profile photo, or account creation timestamp. Trainer History immediately reflects the corrected tenure.

Validation

  • npm test — 24 tests passed
  • npm run build — production TypeScript/Vite build passed
  • npm run lint — passed with three pre-existing warnings
  • npm --prefix worker run typecheck — passed
  • git diff --check — passed
  • schema creation, existing-instructor backfill, and repeated execution verified against an isolated in-memory SQLite database

The local Wrangler D1 runner could not execute on this Windows ARM64 host because its bundled workerd binary does not support that platform; the SQL itself was validated directly with SQLite instead.

Closes #25

@OwenTanzer

Copy link
Copy Markdown
Owner Author

The implementation is otherwise coherent, but Trainer since currently accepts future months.
The shared validator checks only YYYY-MM shape and a valid month number. The Worker uses that validator, the database constraint likewise permits any four-digit year, and the has no max value. An instructor can therefore save something like 2035-06, and Trainer History will display “Trainer since June 2035.”
That is invalid for a tenure start field and should be rejected at both boundaries:
Add max={currentLocalMonth} to the month input.
Have the Worker reject trainerSince values later than the current month.
Add tests covering the current month as valid and the next month as invalid.
The rest looks strong:
tenure is correctly separated from account creation timestamps;
legacy instructors are idempotently backfilled;
missing profile rows retain a defensive created_at fallback;
profile updates use an upsert;
old browser sessions are normalized and later refreshed from the server;
month display avoids UTC date shifting.
CI is fully green across tests, lint, build, dependency installation, and Worker type-checking.

Copy link
Copy Markdown
Owner Author

Addressed the requested future-month guard in 79f6620.

  • The shared trainer-since validator now accepts valid YYYY-MM values only through the current month, so the Worker rejects future tenure dates server-side.
  • The Account Settings month input now uses the current local month as its max.
  • Tests explicitly cover the current month as valid, the following month as invalid, and local-month derivation near a day boundary.

Validation after the change:

  • npm test — 25/25 passed
  • npm run build — passed
  • npm run lint — passed with the same three pre-existing warnings
  • npm --prefix worker run typecheck — passed
  • git diff --check — passed

@OwenTanzer
OwenTanzer marked this pull request as ready for review July 22, 2026 17:42
@OwenTanzer
OwenTanzer merged commit be717f8 into main Jul 22, 2026
1 check passed
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.

Instructor account settings: editable name + profile photo (wire profile_photo_key); rename stale "All Folders" heading

1 participant