Commit Graph

668 Commits

Author SHA1 Message Date
Matthieu
d58a8c2479 feat(component-edit) : add inline quantity input for piece slots
Quantity can now be edited directly on the component edit page next to
each piece selector, instead of only being defined in the category.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 13:34:51 +01:00
Matthieu
81f7b1a9ac feat(component-edit) : add link to category edit page from component editor
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 13:32:54 +01:00
Matthieu
98caaa148d feat(mcp) : add McpHeaderAuthenticator with rate limiting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 12:07:32 +01:00
Matthieu
523eed927e feat(mcp) : install symfony/mcp-bundle and configure transports
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 12:02:15 +01:00
Matthieu
9e303426a7 fix(slots) : filter slot select options server-side instead of client-side
PieceSelect, ProductSelect and ComposantSelect were loading up to 200
items then filtering client-side by typeId. If the matching items were
not in the first 200, the dropdown appeared empty.

Now each select component uses API Platform filters (typePiece,
typeProduct, typeComposant) to fetch only relevant items server-side,
with local state to avoid overwriting the global catalog cache.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 11:59:51 +01:00
Matthieu
43bec07bb8 fix(sync) : preserve slot selections when modifying ModelType structure
SkeletonStructureService was deleting all skeleton requirements and
recreating them on every ModelType update. Combined with position-based
matching in sync strategies, any reordering or insertion caused all
existing slots to be orphaned and recreated empty, losing selections.

- SkeletonStructureService: update requirements in-place by matching
  on typeId instead of delete-all/recreate-all
- ComposantSyncStrategy & PieceSyncStrategy: two-pass smart matching
  algorithm (exact typeId+position first, then typeId-only fallback)
  to preserve selectedPiece/selectedComposant/selectedProduct on
  reorder/insertion
- Frontend: check patch result.success before updating local state

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 11:32:14 +01:00
Matthieu
d4fc0f1fee fix(slots) : check API response before updating local state on slot selection
The save functions (savePieceSlotSelection, saveProductSlotSelection,
saveSubcomponentSlotSelection) were not checking result.success before
updating local state and showing success toast. Since useApi.patch()
never throws, the catch block was dead code and errors were silently
ignored while the UI showed success.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 11:31:19 +01:00
Matthieu
0181f18778 docs(submodule) : update frontend pointer with v1.9.1 changelog
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:53:39 +01:00
Matthieu
f8403ddfbc docs(changelog) : add v1.9.1 release notes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:53:21 +01:00
Matthieu
8e0acf4896 chore(release) : bump version to 1.9.1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v1.9.1
2026-03-16 10:40:45 +01:00
Matthieu
aa8e043c83 fix(submodule) : update frontend pointer with slot selection cache fix
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:32:15 +01:00
Matthieu
428da471d1 fix(component-edit) : force reload catalog to display pre-selected slot items
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:32:07 +01:00
Matthieu
b2aff0e414 feat(sync) : add slot selection controllers, custom field sync, and position fallbacks
- Add selectedPieceId support to ComposantPieceSlotController
- Create ComposantProductSlotController and ComposantSubcomponentSlotController
- Add updateCustomFields() to SkeletonStructureService for managing CustomField entities
- Fix position/orderIndex fallback to array index in all 3 sync strategies
- Fix type comparison in ProductSyncStrategy for dual format support
- Update CLAUDE.md with new entities, controllers, and fixtures documentation
- Update frontend submodule with interactive slot selectors

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 16:40:44 +01:00
Matthieu
271844efb1 feat(component-edit) : add interactive slot selectors for pieces, products and subcomponents
Replace read-only selections display with PieceSelect, ProductSelect, ComposantSelect
components that allow changing the assigned item in each slot directly from the edit page.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 16:40:11 +01:00
Matthieu
4072abf7ba feat(sync) : add ModelTypeSyncService orchestrator and controller with tests
Implement the sync orchestrator that delegates to tagged strategies via
AutowireIterator, and the HTTP controller exposing sync-preview and sync
endpoints with transaction wrapping and role-based access control.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 14:17:57 +01:00
Matthieu
089ca43404 feat(sync) : implement PieceSyncStrategy with tests 2026-03-13 14:07:04 +01:00
Matthieu
f09c7e4782 feat(sync) : implement ComposantSyncStrategy with tests 2026-03-13 14:00:59 +01:00
Matthieu
07cad19988 feat(sync) : wire sync flow into category edit pages with confirmation modal 2026-03-13 13:57:58 +01:00
Matthieu
6a20dcce54 feat(sync) : implement ProductSyncStrategy with tests 2026-03-13 13:54:47 +01:00
Matthieu
8dacad7a59 refactor(sync) : remove restrictedMode and add sync service + confirmation modal 2026-03-13 13:49:24 +01:00
Matthieu
6e0be3dbf3 feat(sync) : add DTOs and SyncStrategyInterface
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:47:59 +01:00
Matthieu
f66db3f2f0 test(sync) : extend factories for PieceProductSlot and CustomField with ModelType
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:44:52 +01:00
Matthieu
0864af1439 feat(sync) : migration for PieceProductSlot table and version columns
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:41:56 +01:00
Matthieu
5210e53d73 feat(sync) : add version field and PieceProductSlot entity
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:38:13 +01:00
Matthieu
3f07162b94 docs(sync) : add implementation plan for ModelType sync
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 12:16:19 +01:00
Matthieu
57615b3e9d docs(sync) : address spec review feedback — atomicity, matching, M2M migration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 12:02:27 +01:00
Matthieu
46694d11d9 docs(sync) : add ModelType sync design spec
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:57:27 +01:00
Matthieu
44cfa25eca feat(composant) : add ComposantPieceSlotController for slot quantity PATCH
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:22:43 +01:00
Matthieu
7ea4cc8c12 chore(submodule) : update frontend pointer
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:22:01 +01:00
Matthieu
bb300a7ca7 feat(composant) : add virtual getStructure() rebuilding legacy JSON from slot tables
Exposes structure as a computed property from pieceSlots, productSlots,
and subcomponentSlots relations, including slotId for frontend quantity
persistence.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:21:17 +01:00
Matthieu
556da6e451 fix(custom-fields) : include customFields and customFieldValues in product normalization
normalizeProduct() had customFields hardcoded to [] and was missing
customFieldValues entirely, unlike normalizeComposant and normalizePiece.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:20:28 +01:00
Matthieu
8871440c9a fix(custom-fields) : populate customFields in ModelType structure from relations
getStructure() was returning hardcoded empty customFields arrays after
the JSON-to-tables migration. Now reads from the relational CustomField
entities via serializeCustomFields() for all three categories.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:19:42 +01:00
Matthieu
5912216a89 fix(piece) : persist slot quantity on blur and send prix as string
- Save composant piece slot quantity via PATCH on blur
- Pass slotId through hierarchy and selection entries
- Send prix as string (not number) to match backend expectation
- Show quantity in view mode when > 1
- Allow quantity edit for all pieces (not just root-level)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:19:09 +01:00
Matthieu
139ba183de fix(custom-fields) : include orphan values with embedded definitions in edit pages
After JSON-to-tables migration, custom field definitions not linked to
a ModelType were invisible on edit pages because buildCustomFieldInputs
only mapped over structure definitions. Now also includes values whose
embedded customField definition has no matching structure entry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:18:47 +01:00
Matthieu
6f1756e82e fix(fixtures) : add INSERT statements for new relational tables
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 08:31:02 +01:00
Matthieu
55bed90ac7 test(normalization) : add tests for skeleton requirements, composant slots, piece-product relation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 08:25:00 +01:00
Matthieu
a6139d7090 feat(normalization) : drop structure and productIds JSON columns
- Remove Composant.structure property, getter/setter
- Remove Piece.productIds property, setProductIds()
- Update fixtures to remove dropped columns
- Add migrations to drop both columns

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 08:19:54 +01:00
Matthieu
8ed5f90b63 feat(structure) : read composant structure from slot relations instead of JSON
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:23:56 +01:00
Matthieu
5194543d16 feat(composant) : create composant slot tables and migrate data from structure JSON
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:20:31 +01:00
Matthieu
c01b71fe06 feat(composant) : add composant slot entities for structure normalization
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:15:42 +01:00
Matthieu
5336dfc09d feat(skeleton) : drop skeleton JSON columns from model_types
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:11:14 +01:00
Matthieu
9fef009610 feat(skeleton) : remove skeleton JSON field references — use structure API field directly
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:11:07 +01:00
Matthieu
77c5d25cea feat(skeleton) : wire skeleton writes to SkeletonStructureService
ModelType.setStructure() now stores data in pendingStructure instead of
writing to JSON columns. A new ModelTypeProcessor intercepts API Platform
POST/PUT/PATCH operations and delegates skeleton writes to
SkeletonStructureService, which persists to relation tables.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:03:32 +01:00
Matthieu
e2326064ba feat(skeleton) : expose skeleton relations via API and create SkeletonStructureService
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:58:18 +01:00
Matthieu
100e24725c feat(skeleton) : create skeleton requirement tables and migrate data from JSON
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:54:14 +01:00
Matthieu
515bae189e feat(skeleton) : add skeleton requirement entities for ModelType
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:48:39 +01:00
Matthieu
333f2a88af feat(machine) : exposer structure composant + pièces résolues dans la vue machine
- normalizeComposant : inclure structure du composant dans la réponse
- enrichStructureWithPieceData : résoudre selectedPieceId vers les
  données complètes de la pièce catalogue (nom, référence, prix, etc.)
- Update submodule : affichage pièces incluses + quantité machine

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:23:55 +01:00
Matthieu
4a3bceffa1 feat(machine) : afficher quantité pièces + pièces incluses des composants
- MachinePiecesCard : passer isEditMode au PieceItem + forward event update
- useMachineHierarchy : mapper quantity depuis le backend + construire
  les pièces de structure du composant en lecture seule
- useMachineDetailUpdates : PATCH MachinePieceLink.quantity + fix reference null
- ComponentItem : séparer pièces liées / pièces incluses par défaut
- useEntityDocuments : skip chargement documents pour pièces de structure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:22:20 +01:00
Matthieu
eccbc1bd56 chore(frontend) : update submodule — fix quantity save on composant edit
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:02:55 +01:00
Matthieu
50d8dde6d5 fix(piece) : include structure in composant edit PATCH payload for quantity persistence 2026-03-12 15:02:09 +01:00