This commit is contained in:
Jacek
2026-04-18 23:52:11 +02:00
parent e195ffc841
commit 41e491c6b7
26 changed files with 4571 additions and 9456 deletions

View File

@@ -1,3 +1,255 @@
# API
> Endpointy, kontrakty request/response, autentykacja.
## Scope
Dokument opisuje aktualne REST API dostepne przez `api.php` (ordersPRO + slowniki + produkty + kategorie).
## Base URL
- Endpoint techniczny: `/api.php`
- Routing odbywa sie przez query params:
- `endpoint` (np. `orders`, `products`)
- `action` (np. `list`, `get`)
Przyklad:
```text
GET /api.php?endpoint=orders&action=list
```
## Authentication
- Wymagany naglowek: `X-Api-Key: <api_key>`
- Klucz jest porownywany z wartoscia `pp_settings.api_key`
- Brak lub zly klucz:
- HTTP `401`
- payload:
```json
{
"status": "error",
"code": "UNAUTHORIZED",
"message": "Invalid or missing API key"
}
```
## Response format
Sukces:
```json
{
"status": "ok",
"data": {}
}
```
Blad:
```json
{
"status": "error",
"code": "BAD_REQUEST",
"message": "..."
}
```
## Common HTTP/logic errors
- `400 BAD_REQUEST` - brak wymaganych parametrow/body
- `401 UNAUTHORIZED` - brak/zly API key
- `404 NOT_FOUND` - nieznany endpoint/action lub brak rekordu
- `405 METHOD_NOT_ALLOWED` - zla metoda HTTP
- `500 INTERNAL_ERROR` - blad serwera
## Endpoints
### Orders (`endpoint=orders`)
- `GET action=list`
- filtry (opcjonalne): `status`, `paid`, `date_from`, `date_to`, `updated_since`, `number`, `client`
- paginacja: `page` (default 1), `per_page` (default 50, max 100)
- `GET action=get&id={id}`
- `PUT action=change_status&id={id}`
- body JSON:
- `status_id` (required, int)
- `send_email` (optional, bool)
- `PUT action=set_paid&id={id}`
- body JSON optional: `send_email` (bool)
- `PUT action=set_unpaid&id={id}`
### Products (`endpoint=products`)
- `GET action=list`
- filtry:
- `search`, `status`, `promoted`
- `attribute_{attributeId}={valueId}` (np. `attribute_12=37`)
- sortowanie: `sort` (default `id`), `sort_dir` (default `DESC`)
- paginacja: `page`, `per_page` (max 100)
- `GET action=get&id={id}`
- `POST action=create`
- wymagane minimum:
- `languages` (array, co najmniej jeden jezyk z `name`)
- `price_brutto` (number >= 0)
- `PUT action=update&id={id}`
- partial update przez JSON body
- `GET action=variants&id={parentProductId}`
- dla produktu glownego (nie wariantu)
- `POST action=create_variant&id={parentProductId}`
- body:
- `attributes` (required array)
- opcjonalnie pola wariantu (np. `price_brutto`, `quantity`, `sku`, ...)
- `PUT action=update_variant&id={variantId}`
- partial update wariantu
- `DELETE action=delete_variant&id={variantId}`
- `POST action=upload_image`
- body:
- `id` (product id, required)
- `file_name` (required)
- `content_base64` (required)
- `alt` (optional)
- `o` (optional position)
### Dictionaries (`endpoint=dictionaries`)
- `GET action=statuses`
- `GET action=transports`
- `GET action=payment_methods`
- `GET action=attributes`
- `POST action=ensure_attribute`
- body: `name` (required), `type` (optional int), `lang` (optional, default `pl`)
- `POST action=ensure_attribute_value`
- body: `attribute_id` (required), `name` (required), `lang` (optional, default `pl`)
- `POST action=ensure_producer`
- body: `name` (required)
### Categories (`endpoint=categories`)
- `GET action=list`
- zwraca aktywne kategorie w formie flat list:
- `id`
- `parent_id`
- `title`
- tytuly pobierane najpierw w jezyku domyslnym (`pp_langs.start=1`), potem fallback.
## Source of truth (mapa API w kodzie)
### 1) Wejscie i dispatch
- `api.php`
- wykrywa request API przez `$_GET['endpoint']`
- ustawia JSON content-type
- tworzy `medoo` + `SettingsRepository`
- przekazuje sterowanie do `\api\ApiRouter::handle()`
- `autoload/api/ApiRouter.php`
- autentykacja (`X-Api-Key` vs `pp_settings.api_key`)
- walidacja `endpoint` i `action`
- mapowanie endpoint -> kontroler (`getControllerFactories()`)
- helpery odpowiedzi: `sendSuccess()`, `sendError()`
- helpery requestu: `getJsonBody()`, `requireMethod()`
### 2) Endpointy i kontrolery (runtime source)
#### `endpoint=orders`
- plik: `autoload/api/Controllers/OrdersApiController.php`
- akcje:
- `list` (GET)
- `get` (GET)
- `change_status` (PUT)
- `set_paid` (PUT)
- `set_unpaid` (PUT)
#### `endpoint=products`
- plik: `autoload/api/Controllers/ProductsApiController.php`
- akcje:
- `list` (GET)
- `get` (GET)
- `create` (POST)
- `update` (PUT)
- `variants` (GET)
- `create_variant` (POST)
- `update_variant` (PUT)
- `delete_variant` (DELETE)
- `upload_image` (POST)
#### `endpoint=dictionaries`
- plik: `autoload/api/Controllers/DictionariesApiController.php`
- akcje:
- `statuses` (GET)
- `transports` (GET)
- `payment_methods` (GET)
- `attributes` (GET)
- `ensure_attribute` (POST)
- `ensure_attribute_value` (POST)
- `ensure_producer` (POST)
#### `endpoint=categories`
- plik: `autoload/api/Controllers/CategoriesApiController.php`
- akcje:
- `list` (GET)
### 3) Warstwa domenowa pod API (shape danych)
- Orders:
- `Domain\Order\OrderRepository::listForApi()`
- `Domain\Order\OrderRepository::findForApi()`
- `Domain\Order\OrderAdminService` (zmiana statusu/platnosci)
- Products:
- `Domain\Product\ProductRepository::listForApi()`
- `Domain\Product\ProductRepository::findForApi()`
- `Domain\Product\ProductRepository::saveProduct()`
- metody wariantow `*VariantForApi()`
- Dictionaries:
- `Domain\ShopStatus\ShopStatusRepository`
- `Domain\Transport\TransportRepository`
- `Domain\PaymentMethod\PaymentMethodRepository`
- `Domain\Attribute\AttributeRepository`
- `Domain\Producer\ProducerRepository`
- Categories:
- bezposrednio query przez `$GLOBALS['mdb']` w `CategoriesApiController`
### 4) Testy API (behavior source)
- `tests/Unit/api/ApiRouterTest.php`
- `tests/Unit/api/Controllers/OrdersApiControllerTest.php`
- `tests/Unit/api/Controllers/ProductsApiControllerTest.php`
- `tests/Unit/api/Controllers/DictionariesApiControllerTest.php`
### 5) Dokumentacja kontraktu (human source)
- `api-docs/api-reference.json`
- `api-docs/index.html`
Uwaga: dokumentacja z `api-docs/*` moze byc starsza od runtime.
Zrodlem prawdy dla dzialania endpointow jest zawsze:
`api.php` + `autoload/api/ApiRouter.php` + aktualne kontrolery `autoload/api/Controllers/*`.
## Curl examples
Pobranie listy zamowien:
```bash
curl -X GET "https://example.com/api.php?endpoint=orders&action=list&page=1&per_page=20" \
-H "X-Api-Key: YOUR_API_KEY"
```
Zmiana statusu zamowienia:
```bash
curl -X PUT "https://example.com/api.php?endpoint=orders&action=change_status&id=123" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"status_id\": 6, \"send_email\": true}"
```
Dodanie wariantu produktu:
```bash
curl -X POST "https://example.com/api.php?endpoint=products&action=create_variant&id=50" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"attributes\":[{\"attribute_id\":12,\"attribute_value_id\":37}],\"price_brutto\":99.99,\"quantity\":10}"
```

View File

@@ -1,3 +1,192 @@
# ARCHITECTURE
> Struktura klas, modulow, przeplywow i zaleznosci w projekcie.
## Scope
Dokument opisuje aktualna architekture runtime projektu `shopPRO`:
- warstwy aplikacji i ich odpowiedzialnosci,
- przeplywy requestow (admin/front/api),
- Dependency Injection i miejsca wiringu,
- konwencje autoloadera i namespace,
- granice miedzy nowa architektura a pozostalosciami legacy.
## High-level layout
Kod aplikacji jest podzielony na 4 glowne warstwy:
1. `autoload/Domain/` - logika biznesowa i dostep do danych (28 modulow)
2. `autoload/admin/` - panel administracyjny (router + kontrolery + form system)
3. `autoload/front/` - frontend sklepu (router + layout engine + kontrolery/widoki)
4. `autoload/api/` - REST API (`api.php`, `ApiRouter`, kontrolery endpointow)
Komponenty wspoldzielone sa trzymane w `autoload/Shared/`.
## Directory map (runtime)
```text
autoload/
Domain/ # 28 modulow domenowych
Shared/ # Cache, Helpers, Tpl, Html, Email, Image
admin/
App.php # routing + DI factories
Controllers/ # 28 kontrolerow admin
Support/ # formularze/tabele
Validation/ # walidacja formularzy
ViewModels/ # modele widokow
front/
App.php # routing + DI factories + fallback legacy
LayoutEngine.php # silnik layoutu frontend
Controllers/ # 8 kontrolerow frontend
Views/ # 11 statycznych klas widokow
api/
ApiRouter.php # auth + endpoint dispatch
Controllers/ # 4 kontrolery API
```
## Entry points i przeplyw
### Admin (`admin/index.php`)
1. Bootstrap (sesja, DB, autoload)
2. `admin\App::update()` - uruchamia pending migracje
3. `admin\App::special_actions()` - logowanie/wylogowanie/2FA
4. `admin\App::render()`:
- auth gate (lub formularz logowania),
- `route()` -> kontroler + akcja,
- render przez `Shared\Tpl\Tpl`.
### Front (`index.php`)
1. Bootstrap (sesja, DB, autoload, jezyk)
2. Mapowanie URL (redirecty + routes)
3. `front\App::checkUrlParams()`
4. `front\App::route()`:
- artykul/produkt/kategoria,
- nowe kontrolery DI,
- fallback do `front\controls\*` (legacy, jesli istnieje)
5. `front\LayoutEngine::show()` sklada finalny HTML.
### API (`api.php`)
1. Bootstrap (bez sesji biznesowej)
2. Tworzenie `\api\ApiRouter`
3. `ApiRouter::handle()`:
- auth przez `X-Api-Key`,
- walidacja `endpoint` i `action`,
- dispatch do kontrolera API,
- JSON response przez `sendSuccess()` / `sendError()`.
Szczegolowa specyfikacja endpointow: `.paul/docs/API.md`.
## Dependency Injection (manual factories)
DI jest realizowane recznie w mapach factory:
- admin: `autoload/admin/App.php` -> `getControllerFactories()`
- front: `autoload/front/App.php` -> `getControllerFactories()`
- api: `autoload/api/ApiRouter.php` -> `getControllerFactories()`
Wzorzec:
- router tworzy repozytoria domenowe,
- repozytoria sa wstrzykiwane do kontrolerow przez konstruktor,
- kontroler wywoluje metody domenowe i zwraca HTML/JSON.
## Autoloader i namespace rules
Kazdy entry point korzysta z custom autoloadera:
1. `autoload/{namespace}/class.{ClassName}.php` (legacy)
2. `autoload/{namespace}/{ClassName}.php` (nowy format)
Mapowanie namespace -> katalog (case-sensitive na Linux):
- `\Domain\` -> `autoload/Domain/`
- `\Shared\` -> `autoload/Shared/`
- `\admin\` -> `autoload/admin/` (male `a`)
- `\front\` -> `autoload/front/`
- `\api\` -> `autoload/api/`
Nie uzywac `\Admin\` (duze `A`), bo katalog runtime to `admin/`.
## Domain layer (28 modulow)
Aktualne moduly:
`Article`, `Attribute`, `Banner`, `Basket`, `Cache`, `Category`, `Client`, `Coupon`, `CronJob`, `Dashboard`, `Dictionaries`, `Integrations`, `Languages`, `Layouts`, `Newsletter`, `Order`, `Pages`, `PaymentMethod`, `Producer`, `Product`, `ProductSet`, `Promotion`, `Scontainers`, `Settings`, `ShopStatus`, `Transport`, `Update`, `User`.
Zasada: logika biznesowa i dostep do danych sa w Domain, bez duplikowania osobnych warstw "admin service" i "front service" dla tych samych przypadkow (wyjatki tylko tam, gdzie historycznie juz istnieja, np. `OrderAdminService`).
## Admin architecture
- Router: `admin\App`
- Kontrolery: `autoload/admin/Controllers/*.php` (28 klas)
- Form system:
- `admin\ViewModels\Forms\*`
- `admin\Support\Forms\FormRequestHandler`
- `admin\Support\Forms\FormFieldRenderer`
- `admin\Validation\FormValidator`
- template: `admin/templates/components/form-edit.php`
Admin ma pelne DI i nie korzysta z fallbacku na legacy kontrolery.
## Front architecture
- Router: `front\App`
- Layout engine: `front\LayoutEngine`
- Kontrolery DI: `autoload/front/Controllers/*.php` (8 klas)
- Widoki statyczne: `autoload/front/Views/*.php` (11 klas)
Wazne: frontend nadal ma fallback do `\front\controls\*`, wiec architektura jest hybrydowa (new DI + remaining legacy paths).
## API architecture
- Router: `api\ApiRouter`
- Endpointy: `orders`, `products`, `dictionaries`, `categories`
- Kontrolery: `autoload/api/Controllers/*ApiController.php` (4 klasy)
- API jest stateless, autoryzowane naglowkiem `X-Api-Key`
Source-of-truth API to runtime:
- `api.php`
- `autoload/api/ApiRouter.php`
- `autoload/api/Controllers/*`
## Shared components
Najwazniejsze klasy wspoldzielone:
- `Shared\Cache\CacheHandler`, `Shared\Cache\RedisConnection`
- `Shared\Helpers\Helpers`
- `Shared\Tpl\Tpl`
- `Shared\Html\Html`
- `Shared\Email\Email`
- `Shared\Image\ImageManipulator`
## Data and cache conventions
- ORM: Medoo (`$mdb`)
- Prefix tabel: `pp_`
- Cache: Redis, domyslnie TTL `86400`
- Dane cache czesto serializowane (`serialize`/`unserialize`)
- Czyszczenie cache produktu: pattern `shop\\product:{id}:*`
## Security boundaries
- Admin:
- sesja uzytkownika admina,
- CSRF token w akcjach POST,
- 2FA email flow (pending session + verify).
- API:
- `X-Api-Key` porownywany przez `hash_equals()`,
- brak logiki sesyjnej.
- Front:
- sesja klienta + walidacja przeplywow frontendowych.
## Source files
Najwazniejsze pliki do szybkiej orientacji:
- `autoload/admin/App.php`
- `autoload/front/App.php`
- `autoload/front/LayoutEngine.php`
- `autoload/api/ApiRouter.php`
- `.paul/docs/API.md`
- `docs/PROJECT_STRUCTURE.md`

View File

@@ -1,3 +1,228 @@
# DB_SCHEMA
# DB_SCHEMA
> Schemat bazy danych — tabele, kolumny, FK, indeksy.
## Scope
Dokument opisuje praktyczny schema map dla `shopPRO`:
- najwazniejsze tabele i relacje,
- grupowanie po domenach biznesowych,
- kluczowe kolumny i indeksy, ktore maja znaczenie runtime,
- mapowanie tabela -> warstwa Domain.
Pelna lista tabel i historyczne notki migracyjne:
`docs/DATABASE_STRUCTURE.md` (source of truth dla detali kolumnowych).
## Konwencje globalne
- ORM: Medoo (`$mdb`)
- Prefix tabel: `pp_`
- Primary key: najczesciej `id` (INT AUTO_INCREMENT)
- Jezyki/translations: zwykle tabele `*_langs` z kluczem `lang_id`
- Wiele-do-wielu: tabele lacznikowe `*_products`, `*_payment_methods`, itp.
## Core commerce
### Produkty
- `pp_shop_products`
- core produktu i wariantu (`parent_id` dla kombinacji)
- ceny (`price_brutto`, `price_brutto_promo`), stany (`quantity`)
- flagi (`status`, `archive`, `promoted`)
- `pp_shop_products_langs`
- nazwy/opisy per jezyk
- `pp_shop_products_images`
- obrazy produktu
- `pp_shop_products_categories`
- przypisania produkt-kategoria
- `pp_shop_products_attributes`
- przypisania wariantu do wartosci cech
- `pp_shop_products_custom_fields`
- dodatkowe pola produktu
Warstwa: `Domain\Product\ProductRepository`, `Domain\Attribute\AttributeRepository`.
### Kategorie
- `pp_shop_categories`
- drzewo kategorii (`parent_id`), status, kolejnosc
- `pp_shop_categories_langs`
- tresci SEO i opisy kategorii
Warstwa: `Domain\Category\CategoryRepository`.
### Zamowienia
- `pp_shop_orders`
- dane klienta "w momencie zakupu", summary, status/platnosc, daty
- kluczowe pole integracyjne: `updated_at` (polling API)
Warstwa: `Domain\Order\OrderRepository`, `Domain\Order\OrderAdminService`.
### Klienci
- `pp_shop_clients`
- konto klienta i dane adresowe/logowania (uzywane przez ClientRepository)
Warstwa: `Domain\Client\ClientRepository`.
## Slowniki i checkout
### Platnosci
- `pp_shop_payment_methods`
- status, opis, mapowanie Apilo
- limity kwotowe: `min_order_amount`, `max_order_amount`
- COD flag: `is_cod`
Warstwa: `Domain\PaymentMethod\PaymentMethodRepository`.
### Transport
- `pp_shop_transports`
- koszt, status, limity, mapowanie Apilo
- `pp_shop_transport_payment_methods`
- relacja transport <-> platnosc (N:M)
Warstwa: `Domain\Transport\TransportRepository`.
### Statusy zamowien
- `pp_shop_statuses`
- statusy predefiniowane, kolor, mapowanie Apilo
Warstwa: `Domain\ShopStatus\ShopStatusRepository`.
## Marketing i merch
### Promocje i kupony
- `pp_shop_promotion`
- reguly promocji, daty aktywnosci, warunki i zakresy (JSON categories)
- `pp_shop_coupon`
- kupony, licznik uzyc, ograniczenia
Warstwa: `Domain\Promotion\PromotionRepository`, `Domain\Coupon\CouponRepository`.
### Producenci
- `pp_shop_producer`
- `pp_shop_producer_lang`
Warstwa: `Domain\Producer\ProducerRepository`.
### Zestawy produktow
- `pp_shop_product_sets`
- `pp_shop_product_sets_products`
Warstwa: `Domain\ProductSet\ProductSetRepository`.
### Cechy i wartosci
- `pp_shop_attributes`
- `pp_shop_attributes_langs`
- `pp_shop_attributes_values`
- `pp_shop_attributes_values_langs`
Warstwa: `Domain\Attribute\AttributeRepository`.
## CMS i frontend content
### Artykuly
- `pp_articles`
- `pp_articles_langs`
- `pp_articles_pages`
- `pp_articles_images`
- `pp_articles_files`
Warstwa: `Domain\Article\ArticleRepository`.
### Strony i layouty
- `pp_pages`
- `pp_layouts`
- `pp_layouts_pages`
- `pp_layouts_categories`
Warstwa: `Domain\Pages\PagesRepository`, `Domain\Layouts\LayoutsRepository`.
### Banery i kontenery statyczne
- `pp_banners`
- `pp_banners_langs`
- `pp_scontainers`
- `pp_scontainers_langs`
Warstwa: `Domain\Banner\BannerRepository`, `Domain\Scontainers\ScontainersRepository`.
## Ustawienia i system
### Ustawienia aplikacji
- `pp_settings`
- klucze globalne (w tym `api_key` dla REST API)
- `pp_shop_apilo_settings`
- `pp_shop_shoppro_settings`
Warstwa: `Domain\Settings\SettingsRepository`, `Domain\Integrations\IntegrationsRepository`.
### Jezyki i tlumaczenia
- `pp_langs`
- `pp_langs_translations`
Warstwa: `Domain\Languages\LanguagesRepository`.
### Uzytkownicy admina
- `pp_users`
- login, hash hasla, status
- pola 2FA (`twofa_*`)
Warstwa: `Domain\User\UserRepository`.
## Routing i URL mapping
- `pp_routes`
- regex `pattern` -> `destination` query string
- obsluguje trasy encji oraz trasy systemowe
- cache Redis: `pp_routes:all`
Runtime wykorzystanie:
- `index.php`
- `Shared\Helpers\Helpers::htacces()`
- repozytoria encji generujace/odswiezajace trasy.
## Kolejka cron
- `pp_cron_jobs`
- status processing pipeline (`pending`, `processing`, `completed`, `failed`, `cancelled`)
- retry/backoff: `attempts`, `max_attempts`, `scheduled_at`
- indeksy:
- `(status, priority, scheduled_at)`
- `(job_type)`
- `(status)`
- `pp_cron_schedules`
- harmonogramy okresowe (`interval_seconds`, `next_run_at`)
- indeks `(enabled, next_run_at)`
Warstwa: `Domain\CronJob\CronJobRepository`, `Domain\CronJob\CronJobProcessor`.
## Najwazniejsze relacje (FK logiczne)
- Produkt glowny -> wariant: `pp_shop_products.parent_id -> pp_shop_products.id`
- Produkt -> tlumaczenia: `pp_shop_products_langs.product_id -> pp_shop_products.id`
- Produkt -> kategoria: `pp_shop_products_categories.product_id -> pp_shop_products.id`
- Kategoria -> tlumaczenia: `pp_shop_categories_langs.category_id -> pp_shop_categories.id`
- Zamowienie -> klient: `pp_shop_orders.client_id -> pp_shop_clients.id` (opcjonalne)
- Transport <-> platnosc: `pp_shop_transport_payment_methods`
- Cecha -> wartosci -> warianty: `attributes -> values -> shop_products_attributes`
- Producent -> tlumaczenia: `pp_shop_producer_lang.producer_id -> pp_shop_producer.id`
- Kontener -> tlumaczenia: `pp_scontainers_langs.container_id -> pp_scontainers.id`
## Uwaga operacyjna
Ten dokument jest skrotem architektonicznym.
Przy zmianach SQL/migracji zawsze aktualizuj rownolegle:
1. `docs/DATABASE_STRUCTURE.md` (detal techniczny)
2. `.paul/docs/DB_SCHEMA.md` (mapa domenowa i impact runtime)

File diff suppressed because it is too large Load Diff