# Analiza modułu Checklist – projekt admin + api

> Data: 2026-04-16

---

## 1. Podsumowanie istniejących modułów i zależności

### Po stronie `api`

#### Tabela `todo_task` – główna encja zadań
Zarządzana przez `api/app/Repositories/Task/TaskRepository.php` (namespace `App\Api\Repositories\Task`).  
Kolumny: `id`, `subcategory_id`, `name`, `description`, `day_of_week`, `execution_time`, `frequency`, `is_mandatory`, `priority`, `requires_photo`.

Walidacja i logika biznesowa: `api/app/Services/OperationalFramework/OperationalActivities/TaskService.php`
- Dozwolone częstotliwości: `DAILY`, `WEEKLY`, `ONCE`
- Dozwolone dni tygodnia: `MONDAY`–`SUNDAY`, `WEEKDAYS`
- Cross-walidacja: DAILY wyklucza `day_of_week`, WEEKLY wymaga `day_of_week`, zaplanowane zadanie wymaga `execution_time`
- Flagi: `is_mandatory`, `requires_photo` jako bool→int

**REST endpoints** (prefiks `/operational-framework`):
- `GET/POST /tasks`
- `PATCH/DELETE /tasks/{id}`
- `GET /tasks/{id}/controllers` + `POST` + `DELETE /tasks/{id}/controllers/{entryId}`
- `GET/POST /levels/{id}/tasks` + `DELETE /levels/{id}/tasks/{taskId}`

#### Tabela `todo_task_controller`
`api/app/Repositories/OperationalFramework/OperationalActivities/TaskControllerRepository.php`  
Kolumny: `id`, `task_id`, `controller_type`, `position_id` (FK → `position`).  
Odpowiedzialność za kontrolę taska – powiązana z pozycją/stanowiskiem.

#### Tabela `todo_task_completion`
`api/app/Repositories/Employee/Task/TodoTaskCompletionRepository.php` i `api/app/Repositories/Owner/OwnerTaskRepository.php`.  
Rejestracja wykonania tasków przez pracowników.

#### Tabela `todo_task_name_alias` / `todo_task_description_alias`
Obsługa wielojęzycznych nazw/opisów tasków przez system aliasów.

#### Tabela `shop_workstation`
`api/app/Repositories/OperationalFramework/Workstation/ShopWorkstationRepository.php`  
Kolumny: `id`, `name`, `description`, `created_at`, `updated_at`.  
REST: `GET/POST /operational-framework/workstations`, `PATCH/DELETE /.../{id}`.

#### Tabela `position_level_task_connection`
`api/app/Repositories/OperationalFramework/OperationalActivities/PositionLevelTaskConnectionRepository.php`  
Pivot łączący poziomy stanowisk z taskami (M:N).

#### Dualizm modeli zadań (!) – ważna uwaga
Istnieją **dwa** repozytoria TaskRepository:
1. `App\Api\Repositories\Task\TaskRepository` → tabela `todo_task` (aktywna, używana przez TaskService)
2. `App\Api\Repositories\OperationalFramework\OperationalActivities\TaskRepository` → tabela `task` (starsza, prawdopodobnie legacy)

Aktywny `TaskController` używa `TaskService`, który korzysta z **pierwszego** repozytorium (`todo_task`).

### Po stronie `admin`

#### Wzorzec komunikacji: admin → API (nie DB)
Repozytoria admin (`App\Admin\Repositories\*`) używają `ApiClient` do wywołań REST API.  
Nie ma bezpośredniego dostępu admina do bazy danych.

#### Istniejący moduł Task w admin
- Controller: `admin/controllers/OperationalFramework/OperationalActivities/TaskController.php`
  Metody: overview, ajaxInsert, ajaxUpdate, ajaxDelete, ajaxGetControllers, ajaxAssignController, ajaxUnassignController.
- Service: `admin/services/OperationalFramework/OperationalActivities/TaskService.php`
- Repository: `admin/repositories/OperationalFramework/OperationalActivities/TaskRepository.php` (via ApiClient)
- Model: `admin/models/OperationalFramework/OperationalActivities/TaskModel.php` – pełny mapping pól tasków
- View: `admin/views/operational_framework/operational_activities/task/overview.twig` (rozbudowana)
  Modals: `task.twig`, `controllers.twig`

#### Routing admin
Rejestracja tras przez RouteCollector w `admin/core/Routes/`.  
Analogicznie `WorkstationRoutes.php` dla workstations.

#### Komponenty UI dostępne do reużycia
- Bootstrap 5 (modale, formularze, tabele, checkboxy)
- Wzorzec tabela + modal (task/overview.twig: filtrowanie, sortowanie, inline badges)
- Wzorzec przypisywania odpowiedzialności: modal `controllers.twig` – dynamiczne dodawanie/usuwanie odpowiedzialnych stanowisk
- Twig layout `layouts/base.twig` z blockami `title`, `head`, `content`

---

## 2. Wskazanie braków w obecnym modelu

### Braki w `api`

| Brak | Opis |
|------|------|
| Brak tabeli `checklist` | Nie istnieje żadna encja grupująca taski w listę kontrolną |
| Brak tabeli `checklist_task` | Brak pivotu M:N między checklistą a taskami |
| Brak endpointów dla checklist | Nie ma żadnych tras REST dla checklisty |
| Brak ChecklistService/Repository | Nie istnieje żadna klasa serwisowa dla checklisty |
| Dualizm tabeli `task` vs `todo_task` | Tabela `task` (starsza) i `todo_task` (aktywna) – brak spójności nazewnictwa |

### Braki w `admin`

| Brak | Opis |
|------|------|
| Brak widoku checklisty | Brak jakiegokolwiek pliku view dla checklisty |
| Brak kontrolera checklisty | Brak `ChecklistController.php` w admin |
| Brak repozytorium checklisty | Brak klienta API dla checklist |
| Brak modelu checklisty | Brak `ChecklistModel.php` |
| Brak tras checklisty | Brak `ChecklistRoutes.php` w admin/core/Routes |

### Model Task – co istnieje

Model `todo_task` jest **w pełni zbudowany**:
- Atrybuty harmonogramu: `frequency`, `day_of_week`, `execution_time`
- Atrybuty wykonania: `is_mandatory`, `requires_photo`, `priority`
- Kategoryzacja: przez `subcategory_id → domain_functional_subcategory → category → section`
- Odpowiedzialność: przez `todo_task_controller` (controller_type + position_id)
- Alias: wielojęzyczne nazwy/opisy

**Checklista NIE powinna duplikować** pól harmonogramu z tasków – `todo_task` już to posiada. Checklista jest szablonem grupującym – nie wykonawczym.

---

## 3. Propozycja modelu danych

### Tabela `checklist`

```sql
CREATE TABLE `checklist` (
  `id`              INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `name`            VARCHAR(255) NOT NULL,
  `description`     TEXT NULL,
  `workstation_id`  INT UNSIGNED NULL,
  `execution_time`  TIME NULL,
  `sort_order`      SMALLINT UNSIGNED NOT NULL DEFAULT 0,
  `is_active`       TINYINT(1) NOT NULL DEFAULT 1,
  `created_at`      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at`      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  CONSTRAINT `fk_checklist_workstation`
    FOREIGN KEY (`workstation_id`) REFERENCES `shop_workstation` (`id`) ON DELETE SET NULL
);
```

**Uzasadnienie pól:**

| Pole | Uzasadnienie |
|------|--------------|
| `name` | Wymagana tożsamość szablonu listy |
| `description` | Kontekst biznesowy, instrukcja dla użytkownika; minimalny koszt implementacji |
| `workstation_id` | Powiązanie z obszarem produkcyjnym (FK → `shop_workstation`), `NULL` = checklista ogólna |
| `execution_time` | Oczekiwana godzina realizacji całej listy jako szablonu (inaczej niż `execution_time` w taskach, gdzie dotyczy konkretnego zadania) |
| `sort_order` | Kolejność wyświetlania list na panelu pracownika; wzorzec stosowany w całym systemie |
| `is_active` | Miękka archiwizacja zamiast fizycznego usunięcia – zachowanie historii przypisań |

### Tabela `checklist_task` (pivot M:N)

```sql
CREATE TABLE `checklist_task` (
  `id`           INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `checklist_id` INT UNSIGNED NOT NULL,
  `task_id`      INT UNSIGNED NOT NULL,
  `sort_order`   SMALLINT UNSIGNED NOT NULL DEFAULT 0,
  `is_mandatory` TINYINT(1) NOT NULL DEFAULT 0,
  `created_at`   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uq_checklist_task` (`checklist_id`, `task_id`),
  CONSTRAINT `fk_ct_checklist` FOREIGN KEY (`checklist_id`) REFERENCES `checklist` (`id`) ON DELETE CASCADE,
  CONSTRAINT `fk_ct_task`      FOREIGN KEY (`task_id`)      REFERENCES `todo_task` (`id`) ON DELETE CASCADE
);
```

**Uzasadnienie pól:**

| Pole | Uzasadnienie |
|------|--------------|
| `sort_order` | Kolejność wyświetlania tasków w obrębie listy – niezależna od globalnej kolejności tasków |
| `is_mandatory` | Kontekstualna obowiązkowość: ten sam task może być obowiązkowy w jednej liście i opcjonalny w innej; nadpisuje `todo_task.is_mandatory` lokalnie |

### Relacje do istniejących tabel

```
checklist.workstation_id    →  shop_workstation.id   (opcjonalna, ON DELETE SET NULL)
checklist_task.checklist_id →  checklist.id          (ON DELETE CASCADE)
checklist_task.task_id      →  todo_task.id          (ON DELETE CASCADE)
```

---

## 4. Dodatkowe parametry checklisty – ocena i uzasadnienie

| Parametr | Decyzja | Uzasadnienie |
|---|---|---|
| `description` | ✅ Iteracja 1 | Pozwala instruować użytkownika o kontekście listy; koszt implementacji minimalny |
| `sort_order` | ✅ Iteracja 1 | Niezbędne przy wielu checklistach widocznych jednocześnie |
| `is_active` | ✅ Iteracja 1 | Archiwizacja zamiast delete – zachowanie historii; wzorzec stosowany w systemie |
| `execution_time` | ✅ Iteracja 1 | Oczekiwana pora realizacji listy jako całości; konfiguracja admina |
| Reguły częstotliwości | ❌ Iteracja 2 | Checklista jest szablonem; taski mają już `frequency`/`day_of_week`. Harmonogram instancji realizacji należy do kontekstu employee/kitchen, nie do szablonu checklisty |
| Przypisanie do typu sklepu / grupy | ❌ Iteracja 2 | Wymaga nowej tabeli relacyjnej i logiki dystrybucji; istotne, ale złożone |
| Domyślna odpowiedzialność za kontrolę | ❌ Iteracja 2 | Odpowiedzialność jest już modelowana przez `todo_task_controller`; powielanie komplikuje model bez wartości w MVP |
| `is_mandatory` zadań w pivotcie | ✅ Iteracja 1 | Kontekstualna obowiązkowość – ten sam task może mieć różną wagę zależnie od listy |
| Kolejność zadań w pivotcie | ✅ Iteracja 1 | Użyteczność UX: pracownik wykonuje zadania w logicznej kolejności |

---

## 5. Propozycja UX kreatora checklisty w `admin`

### Proponowany flow: widok dwukolumnowy (zamiast klasycznego wieloetapowego wizarda)

Inspirowany `task/overview.twig` + `controllers.twig`. Formularz i zarządzanie taskami w jednym widoku/ekranie.

**Sekcja górna / modal – dane checklisty:**
1. Nazwa (wymagana, input text)
2. Opis (textarea, opcjonalnie)
3. Obszar produkcyjny (`workstation_id`) – select z listą `shop_workstation` + opcja „brak / ogólna"
4. Godzina wykonania (`execution_time`) – input type="time", opcjonalna
5. Kolejność (`sort_order`) – number input, domyślnie 0
6. Aktywna – checkbox `is_active` (domyślnie zaznaczony)

**Sekcja tasków (analogia do modalu `controllers.twig`):**
- Tabela przypisanych tasków: kolumny: nazwa taska, kolejność (`sort_order`), obowiązkowy (`is_mandatory`), usuń
- Pod tabelą: dropdown/autocomplete do wyszukiwania i dodawania tasków ze słownika `todo_task`
- Przy każdym tasku: pole `sort_order` (numeryczne) + checkbox `is_mandatory`
- Dodatkowa kolumna informacyjna: odpowiedzialni za kontrolę (odczyt z `todo_task_controller`)

### Komponenty admin możliwe do reużycia

| Komponent | Źródło | Reużycie |
|---|---|---|
| Modal Bootstrap 5 z formularzem | `task/modals/task.twig` | Wzorzec formularza checklisty |
| Tabela z filtrami, badges, akcjami | `task/overview.twig` | Lista checklisty na stronie overview |
| Panel zarządzania relacjami M:N | `task/modals/controllers.twig` | Wzorzec sekcji dodawania/usuwania tasków |
| Route pattern (RouteCollector) | `TaskRoutes.php` | Skopiować dla `ChecklistRoutes.php` |
| ApiClient pattern | `TaskRepository.php` (admin) | Baza dla `ChecklistRepository.php` |
| Model pattern | `TaskModel.php` | Wzorzec dla `ChecklistModel.php` |

### Widoki wzorcowe do naśladowania
1. **`task/overview.twig`** – layout tabeli z filtrami, modals, JS logika CRUD; referencja główna
2. **`task/modals/controllers.twig`** – wzorzec panelu zarządzania relacjami M:N (dodaj/usuń); referencja dla sekcji tasków
3. **`workstation/overview.twig`** – prostszy wzorzec słownika; dobry punkt startowy dla overview checklisty

---

## 6. Rekomendacja zakresu – iteracja pierwsza (MVP)

### Minimalny zakres MVP

**`api` (najpierw):**
1. Migracje DB: tabela `checklist` + `checklist_task`
2. `ChecklistRepository` (tabela `checklist`, operacje CRUD + getAll z JOIN workstation)
3. `ChecklistTaskRepository` (tabela `checklist_task`: assign/unassign task, getByChecklistId z danymi taska i kontrolerami)
4. `ChecklistService` z walidacją (name wymagana, workstation_id opcjonalne FK, execution_time format TIME)
5. `ChecklistController` z metodami: index, show, store, update, destroy, getTasks, assignTask, unassignTask
6. Routing REST pod `/operational-framework/checklists` i `/operational-framework/checklists/{id}/tasks`

**`admin` (po api):**
1. `ChecklistRoutes.php` w `admin/core/Routes/OperationalFramework/`
2. `ChecklistController.php` w `admin/controllers/OperationalFramework/`
3. `ChecklistService.php` w `admin/services/OperationalFramework/`
4. `ChecklistRepository.php` w `admin/repositories/OperationalFramework/` (via ApiClient)
5. `ChecklistModel.php` w `admin/models/OperationalFramework/`
6. Views:
   - `admin/views/operational_framework/checklist/overview.twig`
   - `admin/views/operational_framework/checklist/modals/checklist.twig` (formularz tworzenia/edycji)
   - `admin/views/operational_framework/checklist/modals/tasks.twig` (zarządzanie taskami na liście)

### Kolejność prac

```
1. api: migracje DB (checklist + checklist_task)
2. api: ChecklistRepository + ChecklistTaskRepository
3. api: ChecklistService (walidacja)
4. api: ChecklistController + routing
5. weryfikacja API (swagger / Postman)
6. admin: ChecklistRepository (ApiClient) + ChecklistModel
7. admin: ChecklistService + ChecklistController
8. admin: routing (ChecklistRoutes.php)
9. admin: views (overview + modals)
```

### Co odłożyć na kolejne iteracje

| Feature | Iteracja |
|---|---|
| Reguły częstotliwości checklisty | 2 |
| Przypisanie checklisty do typu sklepu / grupy | 2 |
| Domyślna odpowiedzialność za całą listę | 2 |
| Drag&drop kolejności tasków (zastąpione polem numerycznym w MVP) | 2 |
| Historia przypisań / audyt | 3 |
| Wielojęzyczne nazwy checklisty (alias system) | 3 |

---

## Kluczowe uwagi architektoniczne

1. **Namespace: `OperationalFramework\Checklist`** – zarówno po stronie api jak i admin.

2. **FK do `todo_task`, nie `task`** – aktywna tabela tasków to `todo_task`. Tabela `task` to prawdopodobnie legacy i nie powinna być używana w nowych modułach.

3. **Admin nie ma bezpośredniego dostępu do DB** – wszystkie operacje muszą przejść przez API. `ChecklistRepository` w admin używa `ApiClient`, nie PDO.

4. **Routing admin: RouteCollector** – nowa checklista powinna używać wzorca z `ChecklistRoutes.php` (RouteCollector), nie atrybutów `#[Route]`, dla spójności.

5. **Brak własnego statusu workflow checklisty** – świadoma decyzja domenowa. Lifecycle instancji realizacji checklist należy do kontekstu `employee`/`kitchen`, nie `admin`. Checklista to globalny szablon organizacyjny.

