refactor(status): TermStatus single source of truth (#238 phase 1)#246
Merged
Conversation
Promote the TermStatus value object to the authoritative word-status model
and remove the model's scattered re-definitions across PHP and TypeScript.
Backend:
- TermStatus gains abbreviation/cssClass/colourHex/order/displayName accessors,
static isValid()/values()/isKnownValue()/isIgnoredValue()/isLearningValue(),
and a definitions() exporter (the one ordered status table).
- TermStatusService.getStatuses()/getStatusColor()/isValidStatus()/
is{Learning,Known,Ignored}Status() and StatusHelper now delegate to the VO.
Scheduling members (SCORE_FORMULA_*, calculateScore, makeScoreRandomInsertUpdate)
are deliberately untouched — they are Phase 2 (FSRS).
- Replaced in_array($status,[1,2,3,4,5,98,99]), array_fill_keys([...]) and
=== 5 || === 99 / === 98 checks across Review/Vocabulary/Admin with VO calls.
- New endpoint GET /api/v1/settings/status-definitions returns definitions().
Frontend:
- New shared/stores/statuses.ts is the single TS status source (labels/abbr/
order/class), localized via the shared common.status_* i18n keys.
- text_status_chart.ts, texts_grouped_app.ts, html_utils.ts, term_edit_modal.ts
and the app_data.ts statuses proxy now resolve from it.
No behaviour or wire-format change. Chart colour palettes and the
popover/multi-word presentation lists are left as documented follow-ups.
Tests: +TermStatus VO coverage, +status-definitions endpoint test.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements Phase 1 of #238 — making the word-status model a single source of truth. The FSRS scheduling work (Phase 2) is intentionally not in this PR; it stays parked pending the product decisions in the issue.
What this does
One integer status (1–5 learning, 98 ignored, 99 well-known) was modelled ad-hoc: the literal
[1,2,3,4,5,98,99]and=== 5 || === 99checks recurred across ~11 PHP files, and label/order/class tables were re-defined across ~5 TS files. This collapses all of that onto the existingTermStatusvalue object (backend) + one frontend store, with the model exposed once over the API.Backend
TermStatusis now authoritative. Addedabbreviation(),cssClass(),colourHex(),order(),displayName()(localized), the staticisValid()/values()/isKnownValue()/isIgnoredValue()/isLearningValue()(non-throwing, safe on unvalidated input), anddefinitions()— the single orderedvalue / name / abbr / cssClass / colour / order / isKnown / isLearning / isIgnoredtable.TermStatusService&StatusHelperdelegate to the VO.getStatuses(),getStatusColor(),isValidStatus()and theis{Learning,Known,Ignored}Status()helpers are now thin adapters; the duplicated name/abbr/colour tables are gone.TermStatus::isValid()/values()/isKnownValue()/isIgnoredValue()across the Review, Vocabulary and Admin modules.GET /api/v1/settings/status-definitionsreturnsTermStatus::definitions().Frontend
shared/stores/statuses.tsis the single TS source for status labels/abbr/order/class, localized through the sharedcommon.status_*i18n keys (so PHP and TS resolve identical text from one source).text_status_chart.ts,texts_grouped_app.ts,html_utils.ts,term_edit_modal.tsand theapp_data.tsstatusesproxy now resolve from it.Scope discipline / what's intentionally left
SCORE_FORMULA_*,calculateScore,makeScoreRandomInsertUpdate) — that's Phase 2.statistics_charts.ts,text_status_chart.ts) are left as-is: they diverge from each other and from the CSS--lwt-status*variables, so unifying them is a visual change, not a model cleanup. The reading view already single-sources its colours from CSS.word_popover.ts/multi_word_modal.tskeep their local lists — those encode popover-specific presentation (Bulma button colours, shortKnown/Ignorebadges), not the status model.No behaviour or wire-format change in English; the only user-visible nuance is label normalization toward
"Learned (5)"consistency and localization of previously-hardcoded English labels.Verification
All gates green locally:
phpcs --standard=PSR12,psalm --threads=1,composer test:no-coverage(9093 pass, 43 skipped — the DB-present local run),npm run typecheck,npm run lint,npm test(4432 pass),npm run build:all, andphp bin/check-locales.php(100%). AddedTermStatusVO coverage and astatus-definitionsendpoint test.