refactor(frontend): one entry-type taxonomy (#534) #641

Merged
claude-bot merged 2 commits from refactor/534-entry-type-taxonomy into main 2026-09-14 03:25:58 +00:00
Collaborator

The wiki's 13 entry types lived in separate copies across the frontend. Adding a fourteenth, or renaming one, meant finding every copy, and missing one left a type unlabelled or uncoloured on a single screen.

What was consolidated

#534 counted four copies. There were more:

Data Copies Where
Singular labels 5 WikiArticle, CampaignStoryline, WikiProposals, WikiNewEntry (TYPE_LABELS), CampaignDetail (LORE_TYPE_LABELS)
{value, label} option list 1 WorkbenchResultActions (LORE_TYPE_OPTIONS)
Plural labels 1 LorePicker
Colour classes 3 WikiArticle, WikiProposals, CampaignDetail
Key-list arrays 4 LORE_TYPES

Each group was compared and found identical in content and order. They're all now in src/entryTypes.js, a sibling of vocabulary.js, which exports ENTRY_TYPE_LABELS, ENTRY_TYPE_PLURAL_LABELS, ENTRY_TYPE_COLOURS and ENTRY_TYPES.

Behaviour-preserving by design

Call sites import with aliases (ENTRY_TYPE_LABELS as TYPE_LABELS), so every usage line and every ?? type fallback is untouched. No label text, colour class or option order changes. Tailwind's content glob (./src/**/*.{js,jsx,ts,tsx}) covers the new .js file, so the colour classes still reach the production CSS.

Test

entryTypes.test.js asserts that the singular, plural and colour maps share one key set, in one order. That's the invariant that stops a future type from being added to one map and not the others.

On review I removed two things from the first commit:

  • an entryTypeLabel() helper with no call site
  • an ENTRY_TYPES assertion that could not fail, since ENTRY_TYPES is Object.keys(ENTRY_TYPE_LABELS) (#441's pattern)

Verification

Full frontend suite 67 files / 870 tests passed, eslint src clean.

No CHANGELOG entry: nothing user-visible changes.

Refs #534 (one of five items; the issue stays open). This PR touches no files that #640 does.

🤖 Generated with Claude Code

The wiki's 13 entry types lived in separate copies across the frontend. Adding a fourteenth, or renaming one, meant finding every copy, and missing one left a type unlabelled or uncoloured on a single screen. ## What was consolidated #534 counted four copies. There were more: | Data | Copies | Where | |---|---|---| | Singular labels | 5 | `WikiArticle`, `CampaignStoryline`, `WikiProposals`, `WikiNewEntry` (`TYPE_LABELS`), `CampaignDetail` (`LORE_TYPE_LABELS`) | | `{value, label}` option list | 1 | `WorkbenchResultActions` (`LORE_TYPE_OPTIONS`) | | Plural labels | 1 | `LorePicker` | | Colour classes | 3 | `WikiArticle`, `WikiProposals`, `CampaignDetail` | | Key-list arrays | 4 | `LORE_TYPES` | Each group was compared and found identical in content and order. They're all now in `src/entryTypes.js`, a sibling of `vocabulary.js`, which exports `ENTRY_TYPE_LABELS`, `ENTRY_TYPE_PLURAL_LABELS`, `ENTRY_TYPE_COLOURS` and `ENTRY_TYPES`. ## Behaviour-preserving by design Call sites import with aliases (`ENTRY_TYPE_LABELS as TYPE_LABELS`), so every usage line and every `?? type` fallback is untouched. No label text, colour class or option order changes. Tailwind's content glob (`./src/**/*.{js,jsx,ts,tsx}`) covers the new `.js` file, so the colour classes still reach the production CSS. ## Test `entryTypes.test.js` asserts that the singular, plural and colour maps share one key set, in one order. That's the invariant that stops a future type from being added to one map and not the others. On review I removed two things from the first commit: - an `entryTypeLabel()` helper with no call site - an `ENTRY_TYPES` assertion that could not fail, since `ENTRY_TYPES` *is* `Object.keys(ENTRY_TYPE_LABELS)` (#441's pattern) ## Verification Full frontend suite **67 files / 870 tests passed**, `eslint src` clean. No CHANGELOG entry: nothing user-visible changes. Refs #534 (one of five items; the issue stays open). This PR touches no files that #640 does. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Consolidate the wiki entry-type label maps that were copy-pasted,
character-identical, across WikiArticle, CampaignStoryline,
WikiProposals, WikiNewEntry (TYPE_LABELS) and CampaignDetail
(LORE_TYPE_LABELS), plus the plural variant in LorePicker
(ENTRY_TYPE_LABELS) and the colour maps duplicated in WikiArticle,
WikiProposals and CampaignDetail (all three identical), into a new
webapp/frontend/src/entryTypes.js, sibling to vocabulary.js. Also
folded in the four duplicate LORE_TYPES key-list arrays and a
{value,label} option list in WorkbenchResultActions that encoded the
same 13 types. Behaviour, label text, colour classes, and rendered
order are unchanged; call sites now import from entryTypes.js instead
of declaring their own copy. Added entryTypes.test.js to assert the
label/plural/colour maps share one key set in one order, so a future
entry type can't be added to one map and missed in another.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
refactor(frontend): drop the unused entryTypeLabel helper (#534)
All checks were successful
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 56s
CI / Backend lint (ruff) (pull_request) Successful in 25s
CI / Bot/backend version sync (pull_request) Successful in 23s
CI / Bot tests and audit (pull_request) Successful in 1m59s
CI / Docker image build (pull_request) Successful in 31s
CI / Frontend tests, audit, and build (pull_request) Successful in 2m44s
CI / Backend migration, tests, and audit (pull_request) Successful in 9m10s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Successful in 14m8s
152c61026b
It had no call site outside its own test, and the key-order test's
ENTRY_TYPES assertion held by construction (ENTRY_TYPES is
Object.keys(ENTRY_TYPE_LABELS)), so it could not fail. Both removed; the
plural/colour key-set assertions, which can fail, stay.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
claude-bot deleted branch refactor/534-entry-type-taxonomy 2026-09-14 03:25:58 +00:00
Sign in to join this conversation.
No description provided.