# Analiza: Opisy i obowiązki obszarów odpowiedzialności konsultantów

## Kluczowa korekta modelu domenowego

**Obszary odpowiedzialności należą do STANOWISKA, nie do konsultanta.**

- Stanowisko `consultant_marketing` → obszary: `social_media`, `operational_activities`
  (przechowywane w `position_consultant_areas`)
- Konsultant → membership → wybór stanowiska → **automatyczne dziedziczenie** obszarów (bez kopiowania)
- Edytowalne per konsultant są **wyłącznie OPISY i OBOWIĄZKI** (dane informacyjne dla panelu)

---

## Zakres zmian

- **`api`** — DDL, repozytorium, serwis, kontroler, endpointy
- **`admin`** — repozytorium (ApiClient), serwis, kontroler AJAX, modal w widoku
- Słownik `ConsultantResponsibilityArea` pozostaje hardkodowany

---

## Model danych (DDL)

```sql
-- 1. Globalny szablon obszaru (punkt startowy "wczytaj z szablonu")
CREATE TABLE consultant_area_templates (
    id          INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    area_key    VARCHAR(50) NOT NULL UNIQUE,
    description TEXT        NOT NULL DEFAULT '',
    created_at  DATETIME    NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at  DATETIME    NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- 2. Obowiązki szablonu globalnego
CREATE TABLE consultant_area_template_duties (
    id          INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    template_id INT UNSIGNED NOT NULL,
    content     TEXT         NOT NULL,
    sort_order  SMALLINT UNSIGNED NOT NULL DEFAULT 0,
    FOREIGN KEY (template_id) REFERENCES consultant_area_templates (id) ON DELETE CASCADE
);

-- 3. EDYTOWALNY OPIS obszaru per konsultant (NIE przypisanie obszaru!)
--    Rekord powstaje dopiero przy pierwszej edycji.
--    Brak rekordu = obszar dziedziczony ze stanowiska, ale bez własnego opisu.
CREATE TABLE consultant_area_descriptions (
    id            INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    membership_id INT UNSIGNED NOT NULL COMMENT 'FK do user_membership.id',
    area_key      VARCHAR(50)  NOT NULL,
    description   TEXT         NOT NULL DEFAULT '',
    created_at    DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at    DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uq_member_area (membership_id, area_key)
);

-- 4. Obowiązki per konsultant (kopia z szablonu, edytowalne niezależnie)
CREATE TABLE consultant_area_description_duties (
    id             INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    description_id INT UNSIGNED NOT NULL,
    content        TEXT         NOT NULL,
    sort_order     SMALLINT UNSIGNED NOT NULL DEFAULT 0,
    FOREIGN KEY (description_id) REFERENCES consultant_area_descriptions (id) ON DELETE CASCADE
);
```

### Zmiany vs poprzednia (błędna) iteracja

| Poprzednio (`consultant_area_assignments`) | Aktualnie (`consultant_area_descriptions`) |
|---|---|
| Przechowywało **przypisanie obszaru + dane** | Przechowuje **tylko dane** dla obszaru już dziedziczonego |
| Wymagało jawnego POST-a aby przypisać obszar | Brak rekordu = pusty stan, pierwszy zapis tworzy rekord |
| Można było usunąć przypisanie | Można usunąć tylko opis — obszar zostaje (z założenia stanowiska) |

---

## Endpointy API

### Szablony globalne (admin)
| Metoda | Ścieżka | Opis |
|---|---|---|
| `GET` | `/admin/consultant-area-templates` | Lista szablonów |
| `GET` | `/admin/consultant-area-templates/{key}` | Szablon |
| `PUT` | `/admin/consultant-area-templates/{key}` | Upsert |

### Opisy per konsultant (admin)
| Metoda | Ścieżka | Opis |
|---|---|---|
| `GET` | `/admin/consultant-memberships/{id}/area-descriptions` | Wszystkie obszary konsultanta (ze stanowiska) z opisami |
| `PUT` | `/admin/consultant-memberships/{id}/area-descriptions/{key}` | Upsert opisu i obowiązków |
| `POST` | `/admin/consultant-memberships/{id}/area-descriptions/{key}/init-from-template` | Wczytaj z szablonu |
| `DELETE` | `/admin/consultant-area-descriptions/{id}` | Usuń opis (powrót do pustego stanu) |

### Odczyt publiczny (panel/consultant)
| Metoda | Ścieżka | Opis |
|---|---|---|
| `GET` | `/consultant-memberships/{id}/area-descriptions` | Obszary konsultanta do prezentacji w panelu |

---

## Flow

### Etap 1 — szablon globalny (admin)
1. `/external-collaborators` → przycisk „Szablony obszarów"
2. Modal listuje wszystkie obszary ze słownika + status (czy mają szablon)
3. `PUT /admin/consultant-area-templates/{key}` (upsert + DELETE+INSERT duties)

### Etap 2 — edycja opisu konsultanta (admin)
1. Przy konsultancie przycisk z ikoną listy
2. `GET /admin/consultant-memberships/{id}/area-descriptions` — JOIN
   `membership_position_level → position_consultant_areas` + LEFT JOIN opisu
3. Per obszar karta z: opisem, listą obowiązków, „Wczytaj z szablonu", „Usuń", „Zapisz"
4. `PUT /admin/consultant-memberships/{id}/area-descriptions/{key}` — upsert.
   Jeśli payload pusty, serwis pre-fill z szablonu globalnego

### Odczyt w panelu
- `GET /consultant-memberships/{id}/area-descriptions`
- Zwraca: `[{ area_key, description_id|null, description, duties: [string,...] }]`
- Front renderuje sekcję per obszar (jak w mockupie)

---

## Pliki

### API
- `app/Repositories/Consultant/ConsultantAreaDescriptionRepository.php`
- `app/Services/Consultant/ConsultantAreaDescriptionService.php`
- `app/Controllers/Consultant/AdminConsultantAreaDescriptionController.php`
- `v1/Routes/Consultant/ConsultantRoutes.php` (sekcje AREA TEMPLATES + AREA DESCRIPTIONS)
- `storage/migrations/consultant_area_templates_and_assignments.sql`

### Admin
- `repositories/Consultant/ConsultantAreaDescriptionRepository.php`
- `services/Consultant/ConsultantAreaDescriptionService.php`
- `controllers/Consultant/AreaDescriptionController.php`
- `core/Routes/Consultant/ConsultantRoutes.php`
- `views/user/external_collaborator/overview.twig` — modal `areaDescriptionsModal`

### USUNIĘTE (poprzednia iteracja)
- `*/Repositories/Consultant/ConsultantAreaAssignmentRepository.php`
- `*/Services/Consultant/ConsultantAreaAssignmentService.php`
- `*/Controllers/Consultant/{AdminConsultantAreaAssignmentController,AreaAssignmentController}.php`
