# Programme Management Screen API (matches your screenshot UI)

**Base URL:** `http://YOUR_HOST:8000/api/v1/admin`  
**Auth:** `Authorization: Bearer <admin_jwt_token>`

Your screenshot hierarchy:

```
Level (tabs: Level 1, Level 2, + Add Level)
  └── Module (tabs: Module 1..5, + Add Module, Delete Module)
        └── Week (Week 1..13, + Add Week)
              └── Session (Session 1, Session 2, + Add Session)
                    └── Task / Assessment (+ Add Task)
```

Backend table names: `programme_levels` → `programme_modules` → `programme_weeks` → `programme_sessions` → `programme_assessments`

---

## 1) Load page (one call — recommended)

Use this when the admin opens **Programme Management** screen.

| Action | Method | Endpoint |
|--------|--------|----------|
| Load all levels + full tree | `GET` | `/programme/levels` |

**Response shape (simplified):**
```json
[
  {
    "id": 1,
    "slug": "beginner",
    "display_name": "Beginner",
    "sort_order": 0,
    "modules_count": 3,
    "weeks_count": 39,
    "sessions_count": 111,
    "assessments_count": 242,
    "modules": [
      {
        "id": 10,
        "kind": "foundations",
        "display_name": "Foundations",
        "sort_order": 0,
        "weeks_count": 13,
        "sessions_count": 37,
        "assessments_count": 80,
        "weeks": [
          {
            "id": 100,
            "week_index": 0,
            "display_label": "Intro Week",
            "sessions": [
              {
                "id": 200,
                "session_number": 1,
                "title": "Session 1",
                "admin_checked": false,
                "assessments": [
                  { "id": 300, "sort_order": 0, "title": "Assessment 1" }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
]
```

**Stats cards on screenshot** (compute on frontend):
- Weeks → `module.weeks_count`
- Sessions → `module.sessions_count`
- Tasks → `module.assessments_count`

---

## 2) UI button → API mapping (screenshot)

### Top: **+ Add Level**
| Method | Endpoint | Body |
|--------|----------|------|
| `POST` | `/programme/levels` | see below |

```json
{
  "slug": "custom",
  "display_name": "Level 1",
  "sort_order": 0
}
```

`slug` allowed: `beginner`, `hb`, `intermediate`, `hi`, `advanced`, `custom`

---

### **+ Add Module** (inside selected level)
| Method | Endpoint | Body |
|--------|----------|------|
| `POST` | `/programme/modules` | see below |

```json
{
  "level_id": 1,
  "kind": "foundations",
  "display_name": "Module 1",
  "sort_order": 0
}
```

`kind` allowed (max 1 per level): `foundations`, `developmental`, `creativity`

---

### **Delete Module**
| Method | Endpoint |
|--------|----------|
| `DELETE` | `/programme/modules/{module_id}` |

---

### **+ Add Week** (inside selected module)
| Method | Endpoint | Body |
|--------|----------|------|
| `POST` | `/programme/weeks` | see below |

```json
{
  "module_id": 10,
  "week_index": 1,
  "display_label": "Week 1"
}
```

`week_index`: `0` = Intro Week, `1`–`12` = Week 1–12

---

### Delete week (trash on week row)
| Method | Endpoint |
|--------|----------|
| `DELETE` | `/programme/weeks/{week_id}` |

---

### **+ Add Session** (inside expanded week)
| Method | Endpoint | Body |
|--------|----------|------|
| `POST` | `/programme/sessions` | see below |

```json
{
  "week_id": 100,
  "session_number": 1,
  "title": "Session 1",
  "admin_checked": false
}
```

---

### Delete session
| Method | Endpoint |
|--------|----------|
| `DELETE` | `/programme/sessions/{session_id}` |

---

### **+ Add Task** (Assessment in API)
| Method | Endpoint | Body |
|--------|----------|------|
| `POST` | `/programme/assessments` | see below |

```json
{
  "session_id": 200,
  "title": "Assessment 1",
  "sort_order": 0
}
```

---

### Delete task
| Method | Endpoint |
|--------|----------|
| `DELETE` | `/programme/assessments/{assessment_id}` |

---

## 3) Optional: create everything in ONE request

For building a full custom level like your screenshot in one save:

| Method | Endpoint |
|--------|----------|
| `POST` | `/programme/levels/full` |

```json
{
  "slug": "custom",
  "display_name": "My Custom Level",
  "sort_order": 0,
  "modules": [
    {
      "kind": "foundations",
      "display_name": "Module 1",
      "sort_order": 0,
      "weeks": [
        {
          "week_index": 0,
          "display_label": "Intro Week",
          "sessions": [
            {
              "session_number": 1,
              "title": "Session 1",
              "admin_checked": false,
              "assessments": [
                { "title": "Assessment 1", "sort_order": 0 },
                { "title": "Assessment 2", "sort_order": 1 }
              ]
            },
            {
              "session_number": 2,
              "title": "Session 2",
              "assessments": [
                { "title": "Assessment 1", "sort_order": 0 }
              ]
            }
          ]
        },
        {
          "week_index": 1,
          "display_label": "Week 1",
          "sessions": []
        }
      ]
    }
  ]
}
```

---

## 4) Update (Edit icon on screenshot)

| Item | Method | Endpoint | Body |
|------|--------|----------|------|
| Level | `PUT` | `/programme/levels/{level_id}` | `{ "display_name": "...", "sort_order": 0 }` |
| Module | `PUT` | `/programme/modules/{module_id}` | `{ "display_name": "...", "sort_order": 0 }` |
| Week | `PUT` | `/programme/weeks/{week_id}` | `{ "display_label": "Week 2", "week_index": 2 }` |
| Session | `PUT` | `/programme/sessions/{session_id}` | `{ "title": "...", "session_number": 1 }` |
| Task | `PUT` | `/programme/assessments/{assessment_id}` | `{ "title": "...", "sort_order": 0 }` |

---

## 5) Frontend copy-paste (axios)

```ts
import { axios } from '@/lib/axios';

const BASE = '/v1/admin/programme';

// LOAD SCREEN
export const loadProgrammeScreen = () =>
  axios.get(`${BASE}/levels`);

// ADD LEVEL
export const addLevel = (body: { slug: string; display_name: string; sort_order?: number }) =>
  axios.post(`${BASE}/levels`, body);

// ADD MODULE
export const addModule = (body: { level_id: number; kind: string; display_name: string; sort_order?: number }) =>
  axios.post(`${BASE}/modules`, body);

// ADD WEEK
export const addWeek = (body: { module_id: number; week_index: number; display_label: string }) =>
  axios.post(`${BASE}/weeks`, body);

// ADD SESSION
export const addSession = (body: { week_id: number; session_number: number; title: string; admin_checked?: boolean }) =>
  axios.post(`${BASE}/sessions`, body);

// ADD TASK (assessment)
export const addTask = (body: { session_id: number; title: string; sort_order: number }) =>
  axios.post(`${BASE}/assessments`, body);

// DELETE
export const deleteModule = (id: number) => axios.delete(`${BASE}/modules/${id}`);
export const deleteWeek = (id: number) => axios.delete(`${BASE}/weeks/${id}`);
export const deleteSession = (id: number) => axios.delete(`${BASE}/sessions/${id}`);
export const deleteTask = (id: number) => axios.delete(`${BASE}/assessments/${id}`);

// FULL TREE (one shot)
export const addLevelFullTree = (body: unknown) =>
  axios.post(`${BASE}/levels/full`, body);
```

Or use existing file: `src/features/admin/api/programme.ts` (same endpoints).

---

## 6) User app (after admin saves)

Users read the same DB:

| Method | Endpoint |
|--------|----------|
| `GET` | `/api/v1/user/programme/catalog` |
| `GET` | `/api/v1/user/programme/track` |

No extra API needed for users when admin uses the screen above.
