feat: Implement initial structure for Directus Mayo API extension

- Added main router in src/index.js to register endpoints.
- Implemented GET /mayo-api/products to fetch product list with pagination and filters.
- Implemented GET /mayo-api/dictionaries to fetch various dictionaries for frontend use.
- Created separate files for routes, repositories, serializers, and utilities to maintain clean architecture.
- Added utility functions for async handling, pagination, and order search parsing.
- Introduced serializers for products and dictionaries to format data for frontend consumption.
- Established repository functions for database queries related to products and dictionaries.
- Updated package.json to include license information.
- Created documentation for the API extension detailing current state and future implementation plans.
This commit is contained in:
2026-05-20 22:38:51 +02:00
parent 2005e327f1
commit fb08705883
18 changed files with 1258 additions and 340 deletions

358
notes/directus-api.md Normal file
View File

@@ -0,0 +1,358 @@
# 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`.