dodalem dokumentacje opisujaca dzialanie store dodalem services do komunikacji z directus dodalem opis dzialania services dodalem mocki danych przygotowania do refaktoryzacji
8.6 KiB
Architektura Danych I Endpointow
Data: 2026-04-29
Cel dokumentu
Ten dokument podsumowuje ustalenia dotyczace architektury danych pomiedzy:
- frontendem Quasar/Vue,
- Directusem jako glownym backendem dla frontendu,
- FastAPI jako integracja ze starym systemem Mayo.
Najwazniejszy problem, ktory rozwiazywalismy:
Ile danych frontend powinien pobierac i trzymac w pamieci oraz jaki ksztalt powinny miec endpointy Directusa, zeby aplikacja byla szybka, czytelna i latwa do dalszej rozbudowy.
Glowne zalozenie
Frontend nie powinien pobierac pelnych danych kazdego produktu na glowna liste.
Glowna lista produktow powinna dostawac lekki obiekt przygotowany specjalnie pod widok listy. Pelna specyfikacja i pelny timeline powinny byc pobierane dopiero wtedy, gdy uzytkownik ich potrzebuje.
To jest dobre rozwiazanie, bo:
- lista produktow bedzie szybciej sie ladowac,
- virtual scroll i lazy loading beda prostsze,
- frontend nie bedzie trzymal w pamieci danych, ktorych uzytkownik moze nigdy nie otworzyc,
- backend moze przygotowac dane dokladnie pod ekran,
- komponenty Vue nie musza znac struktury tabel w Directusie.
Trzy rozne reprezentacje produktu
Ten sam produkt moze miec kilka reprezentacji w aplikacji. To nie jest blad ani niepotrzebna duplikacja. To jest normalny podzial danych pod konkretne widoki.
ProductListItem
Lekki obiekt do glownej listy produktow.
Zawiera tylko dane potrzebne do pokazania karty produktu, filtrowania i szybkiej pracy listy:
{
id: 101,
orderId: '0143/2025/1',
orderNumber: '0143',
orderYear: 2025,
orderIndex: 1,
model: 'Regius Core 6',
client: 'HIENDGUITAR.COM / INDONESIA',
finish: 'S+M',
productionLists: ['CZE-00'],
timelinePreview: {
body: [
{
id: 9001,
code: 'B',
label: 'Bejca',
date: '2026-04-20',
status: 'done',
},
],
neck: [],
},
}
To jest format, z ktorego korzysta karta produktu na glownej stronie.
ProductTimeline
Pelny timeline jednego produktu.
Jest pobierany osobno, np. do prawego drawera albo widoku szczegolowego:
{
productId: 101,
events: [
{
id: 9001,
productId: 101,
partId: 501,
partType: 'BODY',
type: 'operation',
operationId: 1,
operationCode: 'B',
operationName: 'Bejca',
date: '2026-04-20',
note: null,
photosCount: 0,
},
{
id: 9006,
productId: 101,
partId: 501,
partType: 'BODY',
type: 'note',
operationId: null,
operationCode: null,
operationName: null,
date: '2026-04-23',
note: 'Do sprawdzenia rownomiernosc koloru.',
photosCount: 2,
},
],
timelinePreview: {
body: [],
neck: [],
},
}
Pelny timeline zawiera operacje, notatki i pozniej moze zawierac informacje o zdjeciach.
ProductSpecification
Pelna specyfikacja produktu ze starego systemu Mayo.
Nie powinna byc czescia ProductListItem. Jest pobierana dopiero po otwarciu panelu specyfikacji:
{
productId: 101,
orderId: '0143/2025/1',
sourceUrl: 'http://10.8.0.6/mayo2/index.php?...',
lastFetchedAt: '2026-04-22T10:30:00Z',
sections: [
{
key: 'szyjka',
label: 'Szyjka',
fields: [
{
key: 'radius',
label: 'Radius',
values: ['GITARA SETIUS/REGIUS/CUSTOM/ 16'],
},
],
},
],
diff: [],
}
Dlaczego timeline jest w dwoch miejscach
Na glownej liscie produktow potrzebny jest tylko skrot timeline:
timelinePreview
W prawym drawerze albo widoku szczegolowym potrzebna jest pelna historia:
events
Dlatego mamy dwa poziomy danych:
ProductListItem.timelinePreview
szybki skrot na karte produktu
ProductTimeline.events
pelny timeline do szczegolow
To jest dobre rozwiazanie, bo na liscie moze byc duzo produktow. Gdyby kazdy produkt mial pelny timeline, frontend pobieralby i przechowywal duzo danych, ktore czesto nie beda uzyte.
Czy produkt na liscie powinien miec pelna specyfikacje
Nie.
Produkt na liscie nie powinien miec pelnej specyfikacji. Powinien miec tylko informacje potrzebne do pokazania karty:
- numer zamowienia,
- model,
- klient,
- finish,
- listy produkcyjne,
- skrot timeline.
Pelna specyfikacja powinna byc pobierana przez osobny endpoint po kliknieciu produktu albo otwarciu drawera.
Rola backendu Directus
Directus powinien byc glownym API dla frontendu.
Frontend nie powinien skladac produktu z wielu tabel Directusa. Backend powinien przygotowac gotowy ksztalt odpowiedzi pod konkretny ekran.
To oznacza, ze zamiast zmuszac frontend do pobierania:
products
orders
clients
models
parts
events
lists
lepiej utworzyc custom endpoint:
GET /mayo-api/products
ktory zwroci gotowe ProductListItem.
To jest dobre rozwiazanie, bo:
- frontend jest prostszy,
- mniej logiki laczenia danych jest w Vue,
- backend moze zoptymalizowac zapytania SQL,
- jeden endpoint odpowiada jednemu widokowi aplikacji,
- latwiej utrzymac stabilny kontrakt API.
Rola FastAPI
FastAPI nie powinien byc glownym API dla frontendu.
Jego rola to integracja ze starym systemem Mayo:
- pobranie specyfikacji po numerze zamowienia,
- parsowanie strony starego systemu,
- zwrocenie danych Directusowi albo procesowi importu.
Docelowy przeplyw:
frontend -> Directus -> FastAPI -> stary system Mayo
Frontend powinien jak najczesciej rozmawiac tylko z Directusem.
Planowane endpointy
Lista produktow
GET /mayo-api/products
Parametry:
?limit=30&offset=0&search=regius&finish=GLOSS&year=2025&productionList=CZE-00
Cel:
- pobieranie danych do glownej listy,
- obsluga virtual scroll i lazy loading,
- filtrowanie,
- zwrocenie
timelinePreview.
Przykladowa odpowiedz:
{
"items": [],
"pageInfo": {
"limit": 30,
"offset": 0,
"hasMore": true,
"total": 184
}
}
Pelny timeline produktu
GET /mayo-api/products/:id/timeline
Cel:
- pobranie pelnej historii produkcji jednego produktu,
- uzycie w prawym drawerze albo widoku szczegolowym.
Dodanie eventu do timeline
POST /mayo-api/products/:id/timeline/events
Cel:
- dodanie operacji, notatki albo innego wpisu produkcyjnego.
Backend powinien zwrocic:
- utworzony event,
- opcjonalnie nowy
timelinePreview.
Dzieki temu frontend moze od razu:
- dopisac event do pelnego timeline,
- zaktualizowac skrot na karcie produktu.
Pelna specyfikacja produktu
GET /mayo-api/products/:id/specification
Cel:
- pobranie pelnej specyfikacji jednego produktu,
- uzycie w panelu specyfikacji.
Odswiezenie specyfikacji
POST /mayo-api/products/:id/specification/refresh
Cel:
- Directus prosi FastAPI o pobranie aktualnych danych ze starego systemu,
- backend liczy hash/diff,
- zapisuje nowa wersje tylko jesli dane sie zmienily,
- zwraca aktualny stan specyfikacji.
Slowniki
GET /mayo-api/dictionaries
Cel:
- pobranie danych do filtrow i formularzy.
Przyklady:
- modele,
- klienci,
- finisze,
- listy produkcyjne,
- operacje,
- kolory.
Virtual scroll i lazy loading
Glowna lista powinna dzialac na porcjach danych.
Przyklad:
limit = 30
offset = 0
Nastepne pobranie:
limit = 30
offset = 30
Frontend nie powinien pobierac calej bazy tylko dlatego, ze lista nie ma paginacji widocznej dla uzytkownika.
Lista moze wygladac jak jedna ciagla lista, ale technicznie powinna pobierac dane porcjami.
Nazewnictwo productId i orderId
Wazne rozroznienie:
productId
To wewnetrzne ID produktu w Directusie.
orderId
To numer starego systemu Mayo, np.:
0143/2025/1
Nie nalezy uzywac orderId jako productId.
Podzial odpowiedzialnosci
Docelowy przeplyw:
komponent Vue
-> store Pinia
-> service API
-> Axios albo mock JSON
-> Directus
Komponent:
- renderuje UI,
- dostaje dane przez props,
- emituje zdarzenia.
Store:
- trzyma stan,
- trzyma loading/error,
- zarzadza cache,
- decyduje kiedy pobrac dane.
Service API:
- zna endpointy,
- zna Axios,
- normalizuje odpowiedzi backendu.
Backend:
- laczy dane z tabel,
- przygotowuje odpowiedz pod frontend,
- pilnuje spojnosci danych.
Dlaczego to jest dobre rozwiazanie
Ten podzial jest dobry, bo utrzymuje osobne odpowiedzialnosci:
- komponenty nie wiedza nic o Directusie,
- store nie musza znac szczegolow Axiosa,
- services nie przechowuja stanu,
- backend moze zmieniac strukture bazy bez przepisywania calego frontendu,
- mock API pozwala pracowac nad wygladem bez gotowego backendu.
To jest praktyczny kompromis dla MVP: nie jest przesadnie skomplikowany, ale od razu porzadkuje najwazniejsze granice aplikacji.