# CRM Cases — Iteracja 1: Obszary odpowiedzialności konsultanta

## Data: 2026-04-27

---

## 1. Analiza obecnego rozwiązania

### Zarządzanie stanowiskami (`position`)

| Element                | Lokalizacja                                                                 |
|------------------------|-----------------------------------------------------------------------------|
| Tabela DB              | `position` (kolumny: id, app_type, name, description)                       |
| API Controller         | `api/app/Controllers/OperationalFramework/OrganisationalStructure/PositionController.php` |
| API Service            | `api/app/Services/OperationalFramework/OrganisationalStructure/PositionService.php` |
| API Routes             | `api/v1/Routes/OperationalFramework/OrganisationalStructure/PositionRoutes.php` |
| Admin Controller       | `admin/controllers/OperationalFramework/OrganisationalStructure/PositionController.php` |
| Admin Repository       | `admin/repositories/OperationalFramework/OrganisationalStructure/PositionRepository.php` |
| Admin View             | `admin/views/operational_framework/organisational_structure/position/overview.twig` |

### Typy stanowisk (`app_type`)
Stanowiska rozróżniają się przez pole `app_type` o wartościach:
`EMPLOYEE | PANEL | ADMIN | CONSULTANT`

Filtrowanie po typie odbywa się zarówno po stronie widoku (select w nagłówku),
jak i po stronie API (query param `?app_type=CONSULTANT`).

---

## 2. Decyzja architektoniczna: słownik w kodzie

**Wybrane rozwiązanie:** statyczna klasa `ConsultantResponsibilityArea` w `api/app/Support/Consultant/`

**Uzasadnienie:**

- Obszary to zamknięty zestaw wartości domenowych (jak `ALLOWED_APP_TYPES` w `PositionService`).
- Nie wymagają dynamicznego zarządzania przez CRUD — nie ma UI do ich edycji.
- Klucze maszynowe (snake_case) są stabilne i wersjonowane razem z kodem.
- Migracja do DB jest zawsze możliwa i niedestruktywna — wystarczy zamienić `ConsultantResponsibilityArea::all()` na odczyt z tabeli.

**Tabela `position_consultant_areas`** przechowuje wyłącznie *przypisanie*:
`position_id` ↔ `area_key`. Słownik pozostaje w kodzie.

---

## 3. Zakres zmian

### API
| Plik | Akcja |
|------|-------|
| `app/Support/Consultant/ConsultantResponsibilityArea.php` | Nowy — słownik obszarów |
| `app/Repositories/Consultant/PositionConsultantAreaRepository.php` | Nowy — operacje na `position_consultant_areas` |
| `app/Services/Consultant/ConsultantAreaService.php` | Nowy — logika biznesowa |
| `app/Controllers/Consultant/ConsultantAreaController.php` | Nowy — 3 endpointy |
| `v1/Routes/Consultant/ConsultantRoutes.php` | Zmodyfikowany — dodane 3 trasy |
| `documentation/migrations/2026_04_27_position_consultant_areas.sql` | Nowy — migracja |

### Admin
| Plik | Akcja |
|------|-------|
| `repositories/Consultant/PositionConsultantAreaRepository.php` | Nowy — proxy do API |
| `services/Consultant/PositionConsultantAreaService.php` | Nowy |
| `controllers/OperationalFramework/OrganisationalStructure/PositionController.php` | Zmodyfikowany — 3 nowe route handlery |
| `views/.../position/overview.twig` | Zmodyfikowany — przycisk "Obszary" dla CONSULTANT + JS + include |
| `views/.../position/modals/consultant_areas_modal.twig` | Nowy — modal z checkboxami |

### Panel
| Plik | Akcja |
|------|-------|
| `models/Consultant/ConsultantAreaModel.php` | Nowy |
| `repositories/Consultant/ConsultantAreaRepository.php` | Nowy |
| `services/Consultant/ConsultantAreaService.php` | Nowy |

---

## 4. Endpointy API

| Metoda | Ścieżka | Opis |
|--------|---------|------|
| `GET` | `/consultant/responsibility-areas` | Słownik obszarów (re-używalny przez admin i panel) |
| `GET` | `/positions/{id}/consultant-areas` | Obszary przypisane do stanowiska |
| `PUT` | `/positions/{id}/consultant-areas` | Zapis obszarów dla stanowiska (pełne zastąpienie) |

**Przykładowe body PUT:**
```json
{ "areas": ["strategy", "product", "sales"] }
```

**Przykładowa odpowiedź GET `/consultant/responsibility-areas`:**
```json
{
  "success": true,
  "data": [
    { "key": "strategy",              "label": "Strategia" },
    { "key": "product",               "label": "Produkt" },
    { "key": "operational_activities","label": "Działania operacyjne" },
    { "key": "sales",                 "label": "Sprzedaż" },
    { "key": "app_development",       "label": "Rozwój aplikacji" },
    { "key": "social_media",          "label": "Social media" }
  ]
}
```

---

## 5. Zachowanie istniejących funkcjonalności

- Dla stanowisk `EMPLOYEE`, `PANEL`, `ADMIN` widok pozostaje bez zmian.
- Przycisk "Obszary odpowiedzialności" (ikona `bi-tags`) pojawia się **wyłącznie** gdy `position.getAppType() == 'CONSULTANT'`.
- Istniejące CRUD stanowisk, poziomów, kompetencji — niezmienione.

---

## 6. Kolejne iteracje (CRM Cases)

Przygotowany fundament umożliwia wdrożenie:

1. **Panel** — wybór tematu interakcji (select oparty na `ConsultantAreaService::getAvailableAreas()`)
2. **Routing** — przypisanie interakcji do konsultanta na podstawie `position_consultant_areas`
3. **CRM Case** — tabela `consultant_case` z polami: `area_key`, `position_id`, `shop_id`, `status`, `created_at`
4. **Widok konsultanta** — lista spraw według obszarów odpowiedzialności

