docs : fix task ordering — category editor before machine page

normalizeStructureForEditor is used by useMachineDetailCustomFields.
Must clean it (Task 6) before migrating the machine page (Task 7).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-04 12:49:41 +02:00
parent 1348fa9963
commit f2eff89e00

View File

@@ -753,7 +753,56 @@ git commit -m "refactor(custom-fields) : migrate product and piece pages to unif
---
## Task 6: Migrate machine page — `MachineCustomFieldsCard`, `MachineInfoCard`, `useMachineDetailCustomFields`
## Task 6: Clean category editor files (`componentStructure*.ts`)
**WHY BEFORE MACHINE PAGE:** `normalizeStructureForEditor` is used by `useMachineDetailCustomFields.ts`. If we change it after migrating the machine page, the machine page would break. So clean this first.
**Files:**
- Modify: `frontend/app/shared/model/componentStructure.ts`
- Modify: `frontend/app/shared/model/componentStructureSanitize.ts`
- Modify: `frontend/app/shared/model/componentStructureHydrate.ts`
- [ ] **Step 1: Read the three files and identify custom field code**
The custom field code in these files handles the category editor (defining fields on a ModelType skeleton). It's the `sanitizeCustomFields` and `hydrateCustomFields` functions, plus custom field handling in `normalizeStructureForEditor` and `normalizeStructureForSave`.
- [ ] **Step 2: Replace custom field sanitize/hydrate with the unified module**
In `componentStructure.ts`, replace the custom field handling in `normalizeStructureForEditor`:
```typescript
// OLD
const sanitizedCustomFields = sanitizeCustomFields(source.customFields)
const customFields = sanitizedCustomFields.map((field) => { ... })
// NEW
import { mergeDefinitionsWithValues } from '~/shared/utils/customFields'
const customFields = mergeDefinitionsWithValues(source.customFields, [])
```
**`optionsText` is now included** in `CustomFieldInput` (added in the type definition). `mergeDefinitionsWithValues` already computes `optionsText` from `options.join('\n')`, so all category editor textareas (`v-model="field.optionsText"`) will work without changes.
- [ ] **Step 3: Run lint + typecheck**
```bash
cd frontend && npm run lint:fix && npx nuxi typecheck
```
- [ ] **Step 4: Verify TWO things**
1. Open `/component-category/{id}/edit` — check that custom fields are displayed, can be added/removed/reordered, and save correctly.
2. Open `/machine/{id}` — check that the machine page still works (it uses `normalizeStructureForEditor` via `useMachineDetailCustomFields.ts`).
- [ ] **Step 5: Commit**
```bash
git add frontend/app/shared/model/componentStructure.ts frontend/app/shared/model/componentStructureSanitize.ts frontend/app/shared/model/componentStructureHydrate.ts
git commit -m "refactor(custom-fields) : clean category editor structure files"
```
---
## Task 7: Migrate machine page — `MachineCustomFieldsCard`, `MachineInfoCard`, `useMachineDetailCustomFields`
**Depends on:** Task 6 (category editor cleaned — `normalizeStructureForEditor` already uses new types)
**Files:**
- Modify: `frontend/app/components/machine/MachineCustomFieldsCard.vue`
@@ -811,13 +860,13 @@ const customFields = filterByContext(
Keep recursive calls (lines 201-209) and constructeur/product/document logic (lines 212-263) unchanged.
- [ ] **Step 3: Run lint + typecheck**
- [ ] **Step 4: Run lint + typecheck**
```bash
cd frontend && npm run lint:fix && npx nuxi typecheck
```
- [ ] **Step 4: Verify**
- [ ] **Step 5: Verify**
Open a machine page (`/machine/{id}`) that has:
- Machine-level custom fields
@@ -825,7 +874,7 @@ Open a machine page (`/machine/{id}`) that has:
- Components with machineContextOnly fields
Check display, edit, and save for all three.
- [ ] **Step 5: Commit**
- [ ] **Step 6: Commit**
```bash
git add frontend/app/components/machine/MachineCustomFieldsCard.vue frontend/app/components/machine/MachineInfoCard.vue frontend/app/composables/useMachineDetailCustomFields.ts
@@ -834,9 +883,11 @@ git commit -m "refactor(custom-fields) : migrate machine page to unified module"
---
## Task 7: Migrate hierarchy components (`ComponentItem.vue`, `PieceItem.vue`)
## Task 8: Migrate hierarchy components (`ComponentItem.vue`, `PieceItem.vue`)
**Data contract decision:** The parent (`useMachineDetailCustomFields.transformComponentCustomFields`) already pre-merges custom fields into `component.customFields` (a `CustomFieldInput[]`). The Item components should NOT re-merge — they display the pre-merged data directly and use the API composable only for saves/updates.
**Depends on:** Task 7 (machine page — parent pre-merges custom fields into `CustomFieldInput[]`)
**Data contract:** The parent (`useMachineDetailCustomFields.transformComponentCustomFields`) already pre-merges custom fields into `component.customFields` (a `CustomFieldInput[]`). The Item components should NOT re-merge — they display the pre-merged data directly and use the API composable only for saves/updates.
**Files:**
- Modify: `frontend/app/components/ComponentItem.vue`
@@ -852,11 +903,11 @@ import { resolveFieldKey, resolveFieldName, ... } from '~/shared/utils/entityCus
With:
```typescript
import { useCustomFields } from '~/composables/useCustomFields'
import { fieldKey, formatValueForDisplay, hasDisplayableValue, type CustomFieldInput } from '~/shared/utils/customFields'
import { fieldKey, formatValueForDisplay, hasDisplayableValue, mergeDefinitionsWithValues, type CustomFieldInput } from '~/shared/utils/customFields'
```
Key changes:
1. **Remove `useEntityCustomFields`** — the parent already pre-merges. Use `props.component.customFields` directly (already `CustomFieldInput[]` after Task 6)
1. **Remove `useEntityCustomFields`** — the parent already pre-merges. Use `props.component.customFields` directly (already `CustomFieldInput[]` after Task 7)
2. **For display:** use `hasDisplayableValue(field)` and `formatValueForDisplay(field)` instead of `resolveFieldXxx()` wrappers
3. **For edits/saves:** use `useCustomFields()` directly (the HTTP layer) instead of `useEntityCustomFields().updateCustomField`
4. **For context fields** (`component.contextCustomFields` + `component.contextCustomFieldValues`): merge locally with `mergeDefinitionsWithValues` — these are NOT pre-merged by the parent since they come as separate arrays
@@ -886,52 +937,6 @@ git commit -m "refactor(custom-fields) : migrate ComponentItem and PieceItem to
---
## Task 8: Clean category editor files (`componentStructure*.ts`)
**Files:**
- Modify: `frontend/app/shared/model/componentStructure.ts`
- Modify: `frontend/app/shared/model/componentStructureSanitize.ts`
- Modify: `frontend/app/shared/model/componentStructureHydrate.ts`
- [ ] **Step 1: Read the three files and identify custom field code**
The custom field code in these files handles the category editor (defining fields on a ModelType skeleton). It's the `sanitizeCustomFields` and `hydrateCustomFields` functions, plus custom field handling in `normalizeStructureForEditor` and `normalizeStructureForSave`.
- [ ] **Step 2: Replace custom field sanitize/hydrate with `normalizeDefinitions` from the unified module**
In `componentStructure.ts`, replace the custom field handling in `normalizeStructureForEditor`:
```typescript
// OLD
const sanitizedCustomFields = sanitizeCustomFields(source.customFields)
const customFields = sanitizedCustomFields.map((field) => { ... })
// NEW
import { mergeDefinitionsWithValues } from '~/shared/utils/customFields'
const customFields = mergeDefinitionsWithValues(source.customFields, [])
```
**`optionsText` is now included** in `CustomFieldInput` (added in the type definition). `mergeDefinitionsWithValues` already computes `optionsText` from `options.join('\n')`, so all category editor textareas (`v-model="field.optionsText"`) will work without changes.
**Important:** `normalizeStructureForEditor` is also used by `useMachineDetailCustomFields.ts` (imported as `normalizeStructureForEditor` from `~/shared/modelUtils`). Make sure the change doesn't break the machine detail page — it should be fine since the new output includes the same `options` array plus the `optionsText` string.
- [ ] **Step 3: Run lint + typecheck**
```bash
cd frontend && npm run lint:fix && npx nuxi typecheck
```
- [ ] **Step 4: Verify**
Open `/component-category/{id}/edit` — check that custom fields are displayed, can be added/removed/reordered, and save correctly.
- [ ] **Step 5: Commit**
```bash
git add frontend/app/shared/model/componentStructure.ts frontend/app/shared/model/componentStructureSanitize.ts frontend/app/shared/model/componentStructureHydrate.ts
git commit -m "refactor(custom-fields) : clean category editor structure files"
```
---
## Task 9: Delete old files + final cleanup
**Files:**