# Directus Mayo API Extension Data aktualizacji: 2026-05-20 ## Cel Ten dokument opisuje aktualny stan budowy custom API w Directus dla frontendu Duck Prod Manager. Extension znajduje sie w: ```txt directus/extensions/directus-extension-mayo-api ``` Endpoint Directus extension ma miec identyfikator: ```txt mayo-api ``` Dlatego publiczne sciezki beda dostepne pod prefiksem: ```txt /mayo-api ``` ## Aktualny stan Katalog extension jest przygotowany i zawiera scaffold Directus endpoint extension. Istniejace pliki: ```txt directus/extensions/directus-extension-mayo-api/README.md directus/extensions/directus-extension-mayo-api/package.json directus/extensions/directus-extension-mayo-api/src/index.js directus/extensions/directus-extension-mayo-api/old/index.js.old directus/extensions/directus-extension-mayo-api/old/old_index.js.old ``` `src/index.js` rejestruje obecnie pierwsze dwa endpointy: - `GET /mayo-api/products` - `GET /mayo-api/dictionaries` Stare pliki w `old/` sa tylko materialem referencyjnym. Nie traktujemy ich jako aktywnej implementacji. ## Zalozona architektura Nie umieszczamy wszystkich endpointow w jednym pliku. `src/index.js` ma pelnic role glownego routera: - eksportuje Directus endpoint extension, - ustawia `id: 'mayo-api'`, - importuje pliki endpointow, - rejestruje endpointy, - nie zawiera zapytan SQL ani logiki biznesowej. Kazdy endpoint ma miec osobny plik w katalogu `routes/`. Logika wspolna powinna byc rozbita na: - `repositories/` - zapytania do bazy Directus, - `serializers/` - mapowanie danych z DB na format frontendu, - `utils/` - drobne helpery techniczne. ## Proponowana struktura plikow ```txt directus/extensions/directus-extension-mayo-api/src/ index.js routes/ products.get.js dictionaries.get.js product-timeline.get.js # do zrobienia product-timeline-event.post.js # do zrobienia product-specification.get.js # do zrobienia product-specification-refresh.post.js # do zrobienia repositories/ products.repository.js dictionaries.repository.js timeline.repository.js # do zrobienia specification.repository.js # do zrobienia serializers/ product.serializer.js timeline.serializer.js specification.serializer.js # do zrobienia dictionaries.serializer.js utils/ async-handler.js http-error.js # do zrobienia, jesli bedzie potrzebny pagination.js order-search.js ``` ## Endpointy wymagane przez frontend ### 1. Lista produktow ```http GET /mayo-api/products ``` Status: zaimplementowany w pierwszym etapie. Parametry query: ```js { limit, offset, search, orderSearch, model, client, finish, productionList, year, } ``` `orderSearch` przychodzi z frontendu jako JSON string. Oczekiwana odpowiedz: ```js { items: [], pageInfo: { limit, offset, hasMore, total, }, } ``` Element `items` powinien miec ksztalt produktu uzywany przez frontend: ```js { id, orderId, orderNumber, orderYear, orderIndex, model, client, finish, productionLists, timelinePreview: { body: [], neck: [], }, } ``` ### 2. Slowniki ```http GET /mayo-api/dictionaries ``` Status: zaimplementowany w pierwszym etapie. Oczekiwana odpowiedz: ```js { models: [], clients: [], finishes: [], productionLists: [], operations: [], colors: [], } ``` ### 3. Timeline produktu ```http GET /mayo-api/products/:id/timeline ``` Status: do zrobienia. Oczekiwana odpowiedz: ```js { productId, events: [], timelinePreview: { body: [], neck: [], }, } ``` ### 4. Dodanie eventu timeline ```http POST /mayo-api/products/:id/timeline/events ``` Status: do zrobienia. Oczekiwana odpowiedz: ```js { event: {}, timelinePreview: { body: [], neck: [], }, } ``` ### 5. Specyfikacja produktu ```http GET /mayo-api/products/:id/specification ``` Status: do zrobienia. Preferowana odpowiedz: ```js { productId, orderId, sourceUrl, lastFetchedAt, sections: [], diff: [], } ``` Frontend akceptuje tez ksztalt: ```js { productId, orderId, sourceUrl, lastFetchedAt, specification: { sections: [], }, diff: [], } ``` ### 6. Odswiezenie specyfikacji produktu ```http POST /mayo-api/products/:id/specification/refresh ``` Status: do zrobienia. Odpowiedz powinna miec taki sam ksztalt jak `GET /specification`, ale z aktualnym `lastFetchedAt` i ewentualnym `diff`. ## Kolejnosc implementacji Rekomendowana kolejnosc: 1. `GET /mayo-api/products` 2. `GET /mayo-api/dictionaries` 3. `GET /mayo-api/products/:id/timeline` 4. `POST /mayo-api/products/:id/timeline/events` 5. `GET /mayo-api/products/:id/specification` 6. `POST /mayo-api/products/:id/specification/refresh` Pierwsze dwa endpointy odblokowuja glowny ekran frontendu. ## Co zostalo zrobione - Przeanalizowano `notes/api_services.md`. - Przeanalizowano frontendowe implementacje HTTP w `frontend/src/services/*HttpApi.js`. - Przeanalizowano store Pinia, zeby ustalic realne parametry i ksztalt danych. - Ustalono liste 6 endpointow wymaganych przez obecny frontend. - Ustalono, ze `index.js` bedzie tylko routerem/rejestratorem endpointow. - Ustalono docelowa hierarchie plikow extension. - Utworzono ten dokument jako aktualny opis stanu prac nad Directus extension. - Utworzono katalogi `routes/`, `repositories/`, `serializers/`, `utils/`. - Wypelniono `src/index.js` rejestracja pierwszych endpointow. - Zaimplementowano `GET /mayo-api/products`. - Zaimplementowano `GET /mayo-api/dictionaries`. - Zweryfikowano nazwy kolekcji na podstawie `snapshot(6).json` i `db_schema.dbml`. - Uruchomiono `npm run build` w katalogu extension. Build zakonczyl sie poprawnie. - Dodano `README.md` dla extension. - Dodano `license: "UNLICENSED"` w `package.json`, zeby extension bylo oznaczone jako pakiet wewnetrzny. - Uruchomiono `npm run validate` w katalogu extension. Walidacja zakonczyla sie poprawnie. - Dodano `mayo-api.http` z requestami REST Client do manualnego testowania endpointow. - Przebudowano `db_schema.dbml` pod nowa baze Directus: poprawione nazwy, tabele slownikowe zamiast enumow. - Dostosowano aktywne repository extension do nowego schematu. - Uwzgledniono relacje `mayo_product_production_lists.order_item_id -> mayo_order_items.id`. ## Decyzje implementacyjne - Aktywna implementacja ignoruje katalog `directus/extensions/directus-extension-mayo-api/old`. - Pierwsza implementacja byla oparta o stary schemat Directus, ktory zawieral literowki: - `mayo_order_porducts` - `mayo_lisst_products` - `mayo_color` - `db_schema.dbml` zostal przebudowany jako propozycja nowego schematu: - enumy zostaly zamienione na tabele slownikowe, - literowki zostaly poprawione, - nazwy kolekcji zostaly doprecyzowane pod Directus. - Nowa baza Directus zostala utworzona zgodnie z `db_schema.dbml`, z jedna celowa zmiana: - `mayo_product_production_lists.order_item_id` wskazuje na `mayo_order_items.id`. - Extension zostal dostosowany do nowych nazw kolekcji i relacji `order_item_id`. - `GET /products` buduje `timelinePreview` z `mayo_production_events`, `mayo_product_parts`, `mayo_part_types` i `mayo_production_operations`. - `GET /products` filtruje po `model`, `client`, `year`, `productionList`, `finish` i `orderSearch`. - `GET /dictionaries` pobiera finish z tabeli slownikowej `mayo_finishes`. - Kod operacji pochodzi z `mayo_production_operations.code`. - Uruchomiono `npm run build` po dostosowaniu do nowego schematu. Build zakonczyl sie poprawnie. - Uruchomiono `npm run validate` po dostosowaniu do nowego schematu. Walidacja zakonczyla sie poprawnie. ## Proponowane nowe nazwy kolekcji Stare nazwy i ich proponowane odpowiedniki: ```txt mayo_color -> mayo_colors mayo_lisst_products -> mayo_product_production_lists mayo_lists -> mayo_production_lists mayo_models -> mayo_product_models mayo_operations -> mayo_production_operations mayo_order_porducts -> mayo_order_items mayo_part_events -> mayo_production_events mayo_parts -> mayo_product_parts ``` Enumy zostaly zastapione tabelami: ```txt mayo_models_neck_construction -> mayo_neck_constructions mayo_parts_part_type -> mayo_part_types mayo_parts_finish -> mayo_finishes ``` ## Do zrobienia - Zaimplementowac `GET /mayo-api/products/:id/timeline`. - Zaimplementowac `POST /mayo-api/products/:id/timeline/events`. - Zaimplementowac `GET /mayo-api/products/:id/specification`. - Zaimplementowac `POST /mayo-api/products/:id/specification/refresh`. - Sprawdzic na realnych danych, czy `finish` na karcie produktu ma byc pojedynczym enumem, czy agregatem z `top_finish` i `back_finish`. - Przetestowac frontend z `VITE_USE_MOCK_API=false`.