Backend:
- GET /api/v1/districts - list all districts from DB
- GET /api/v1/districts/{slug} - district detail with lead agent, core team, rooms, nodes
repo_city methods:
- get_districts() - SELECT FROM microdaos WHERE dao_type='district'
- get_district_by_slug()
- get_district_lead_agent() - with fallback to orchestrator
- get_district_core_team()
- get_district_agents()
- get_district_rooms() - by slug prefix
- get_district_nodes()
- get_district_stats()
Task doc: TASK_PHASE_DISTRICT_PORTALS_v1.md
452 lines
11 KiB
Markdown
452 lines
11 KiB
Markdown
# TASK_PHASE_DISTRICT_PORTALS_v1
|
||
|
||
Version: 1.0
|
||
Status: Ready
|
||
Priority: High (City → District → MicroDAO контур)
|
||
|
||
---
|
||
|
||
# 1. МЕТА
|
||
|
||
Зробити **District-и повноцінними "порталами платформ"** у DAARION.city:
|
||
|
||
- окремі сторінки District-ів (SOUL, GREENFOOD, ENERGYUNION),
|
||
- прив'язка до існуючих District-протоколів,
|
||
- інтеграція з Rooms, Matrix, Presence, Chat Widget,
|
||
- відображення MicroDAO всередині District-а.
|
||
|
||
Результат:
|
||
користувач, заходячи на DAARION.space, може:
|
||
|
||
- потрапити в місто (/city),
|
||
- з міста — в District-портал (/soul, /greenfood, /energy-union),
|
||
- з District — у відповідні MicroDAO / кімнати / агентів.
|
||
|
||
---
|
||
|
||
# 2. ВИХІДНІ ДАНІ
|
||
|
||
Уже є:
|
||
|
||
- Foundation-документи:
|
||
- `GREENFOOD_District_Protocol_v1.md`
|
||
- `ENERGYUNION_District_Protocol_v1.md`
|
||
- `SOUL_District_Protocol_v1.md`
|
||
- `District_Interface_Architecture_v1.md`
|
||
- Таблиця `microdaos` з полем `dao_type = 'district'` (SOUL, GREENFOOD, ENERGYUNION).
|
||
- Rooms Layer:
|
||
- District rooms для:
|
||
- SOUL (soul-lobby, soul-events, soul-masters, ...)
|
||
- GREENFOOD (greenfood-lobby, ... )
|
||
- ENERGYUNION (energyunion-lobby, energyunion-compute, ...)
|
||
- Matrix + Chat:
|
||
- `rooms.matrix_room_id` заповнено,
|
||
- Chat API працює,
|
||
- Presence API працює.
|
||
- Frontend:
|
||
- City Layer /city, /city/{slug}
|
||
- Agents, Nodes, MicroDAO базові сторінки
|
||
|
||
---
|
||
|
||
# 3. SCOPE
|
||
|
||
1. Backend District API:
|
||
- `GET /api/v1/districts`
|
||
- `GET /api/v1/districts/{slug}`
|
||
2. Frontend routing:
|
||
- `/districts` (список всіх District-ів)
|
||
- `/districts/[slug]` (універсальний портал)
|
||
- короткі alias-роути:
|
||
- `/soul` → SOUL District
|
||
- `/greenfood` → GREENFOOD District
|
||
- `/energy-union` → ENERGYUNION District
|
||
3. UI District-порталу:
|
||
- header (назва, опис, тип, lead agent),
|
||
- District rooms (список кімнат + переходи),
|
||
- host agents (lead/core team) + presence,
|
||
- chat widget (District lobby room),
|
||
- список MicroDAO всередині District-а.
|
||
4. Інтеграція з City Layer:
|
||
- посилання з City → District.
|
||
|
||
---
|
||
|
||
# 4. МОДУЛЬ 1 — BACKEND: DISTRICT API (CITY-SERVICE)
|
||
|
||
## 4.1. `GET /api/v1/districts`
|
||
|
||
Повертає список всіх District-ів.
|
||
|
||
Приблизний вихід:
|
||
|
||
```json
|
||
[
|
||
{
|
||
"id": "uuid",
|
||
"slug": "soul",
|
||
"name": "SOUL Retreat District",
|
||
"description": "Wellness / Retreat / Metahuman",
|
||
"dao_type": "district",
|
||
"lead_agent": {
|
||
"id": "agent_id_soul",
|
||
"name": "SOUL"
|
||
},
|
||
"rooms": [
|
||
{
|
||
"id": "uuid",
|
||
"slug": "soul-lobby",
|
||
"name": "SOUL Lobby"
|
||
}
|
||
],
|
||
"microdaos_count": 0
|
||
},
|
||
{
|
||
"id": "uuid",
|
||
"slug": "greenfood",
|
||
"name": "GREENFOOD District",
|
||
"description": "ERP / Supply Chains / Food",
|
||
"dao_type": "district",
|
||
"lead_agent": {
|
||
"id": "agent_id_greenfood",
|
||
"name": "ERP GREENFOOD"
|
||
},
|
||
"rooms": [ ... ],
|
||
"microdaos_count": 0
|
||
},
|
||
{
|
||
"id": "uuid",
|
||
"slug": "energy-union",
|
||
"name": "Energy Union District",
|
||
"description": "DePIN / Energy / Compute",
|
||
"dao_type": "district",
|
||
"lead_agent": {
|
||
"id": "agent_id_helion",
|
||
"name": "Helion"
|
||
},
|
||
"rooms": [ ... ],
|
||
"microdaos_count": 0
|
||
}
|
||
]
|
||
```
|
||
|
||
Логіка:
|
||
|
||
- брати записи з `microdaos` де `dao_type = 'district'`;
|
||
- підвантажити lead-agent (згідно District-протоколів);
|
||
- підтягнути ключові кімнати (lobby тощо) через `rooms` та `district_id` / зв'язки.
|
||
|
||
## 4.2. `GET /api/v1/districts/{slug}`
|
||
|
||
Подробиці District-а.
|
||
|
||
Приблизний вихід:
|
||
|
||
```json
|
||
{
|
||
"id": "uuid",
|
||
"slug": "soul",
|
||
"name": "SOUL Retreat District",
|
||
"description": "Wellness / Retreat / Metahuman District",
|
||
"dao_type": "district",
|
||
"lead_agent": {
|
||
"id": "agent_id_soul",
|
||
"name": "SOUL",
|
||
"dais_id": "dais_soul"
|
||
},
|
||
"core_team": [
|
||
{
|
||
"id": "agent_spirit",
|
||
"name": "Spirit",
|
||
"role": "Guidance"
|
||
},
|
||
{
|
||
"id": "agent_logic",
|
||
"name": "Logic",
|
||
"role": "Information"
|
||
}
|
||
],
|
||
"rooms": [
|
||
{
|
||
"id": "room_id_lobby",
|
||
"slug": "soul-lobby",
|
||
"name": "SOUL Lobby",
|
||
"matrix_room_id": "!room:matrix..."
|
||
},
|
||
{
|
||
"id": "room_id_events",
|
||
"slug": "soul-events",
|
||
"name": "Events"
|
||
}
|
||
],
|
||
"microdaos": [
|
||
{
|
||
"id": "microdao_id_1",
|
||
"slug": "soul-hub-1",
|
||
"name": "Retreat Hub #1"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
Якщо District не знайдено → 404.
|
||
|
||
---
|
||
|
||
# 5. МОДУЛЬ 2 — FRONTEND API КЛІЄНТ
|
||
|
||
У `apps/web/src/lib/api/districts.ts`:
|
||
|
||
```ts
|
||
export type DistrictSummary = {
|
||
id: string;
|
||
slug: string;
|
||
name: string;
|
||
description: string;
|
||
daoType: "district";
|
||
leadAgent: {
|
||
id: string;
|
||
name: string;
|
||
};
|
||
rooms: {
|
||
id: string;
|
||
slug: string;
|
||
name: string;
|
||
}[];
|
||
microdaosCount: number;
|
||
};
|
||
|
||
export type DistrictDetail = {
|
||
id: string;
|
||
slug: string;
|
||
name: string;
|
||
description: string;
|
||
daoType: "district";
|
||
leadAgent: {
|
||
id: string;
|
||
name: string;
|
||
daisId?: string;
|
||
};
|
||
coreTeam: {
|
||
id: string;
|
||
name: string;
|
||
role: string;
|
||
}[];
|
||
rooms: {
|
||
id: string;
|
||
slug: string;
|
||
name: string;
|
||
matrixRoomId?: string;
|
||
}[];
|
||
microdaos: {
|
||
id: string;
|
||
slug: string;
|
||
name: string;
|
||
}[];
|
||
};
|
||
|
||
export async function getDistricts(): Promise<DistrictSummary[]> { ... }
|
||
|
||
export async function getDistrictBySlug(slug: string): Promise<DistrictDetail> { ... }
|
||
```
|
||
|
||
---
|
||
|
||
# 6. МОДУЛЬ 3 — ROUTING
|
||
|
||
## 6.1. `/districts` (список)
|
||
|
||
Файл: `apps/web/src/app/districts/page.tsx`
|
||
|
||
Повинен:
|
||
|
||
- завантажити `getDistricts()`;
|
||
- показати карточки District-ів:
|
||
- SOUL
|
||
- GREENFOOD
|
||
- ENERGY UNION
|
||
- кожна картка:
|
||
- назва
|
||
- опис
|
||
- lead agent (ім'я + presence)
|
||
- кнопка/посилання "Перейти до District".
|
||
|
||
## 6.2. `/districts/[slug]` (портал District-а)
|
||
|
||
Файл: `apps/web/src/app/districts/[slug]/page.tsx`
|
||
|
||
Логіка:
|
||
|
||
- прочитати `params.slug`;
|
||
- викликати `getDistrictBySlug(slug)`;
|
||
- якщо 404 → `notFound()`.
|
||
|
||
---
|
||
|
||
# 7. МОДУЛЬ 4 — UI DISTRICT-ПОРТАЛУ
|
||
|
||
Структура сторінки `/districts/[slug]`:
|
||
|
||
## 7.1. Header
|
||
|
||
- Назва District-а (`name`)
|
||
- Опис (`description`)
|
||
- Badge: "District"
|
||
- Breadcrumb:
|
||
- `City / Districts / {DistrictName}`
|
||
|
||
## 7.2. Lead Agent + Core Team
|
||
|
||
Секція "District Agents":
|
||
|
||
- Lead Agent:
|
||
- аватар,
|
||
- ім'я (SOUL / GREENFOOD / Helion),
|
||
- PresenceDot (online/offline/away),
|
||
- кнопка "Кабінет агента".
|
||
|
||
- Core Team (якщо є):
|
||
- список агентів (Spirit, Logic, Energia тощо),
|
||
- ролі (Guidance, Information, Energy, Scheduler...),
|
||
- presence.
|
||
|
||
## 7.3. Rooms
|
||
|
||
Секція "District Rooms":
|
||
|
||
- список кімнат District-а:
|
||
- назва,
|
||
- опис (якщо є),
|
||
- scope tag (lobby / events / labs / providers / compute / guidance / etc.),
|
||
- кнопка "Відкрити кімнату" → `/city/{slug}` або окремий `/rooms/{slug}`, залежно від моделі.
|
||
- Для lobby-кімнати:
|
||
- окремий акцент: "Головний портал District-а".
|
||
|
||
(Якщо кімнати реалізовані як `rooms.scope = 'district'`, на UI використовувати їх метадані з БД.)
|
||
|
||
## 7.4. MicroDAO
|
||
|
||
Секція "MicroDAO цього District-а":
|
||
|
||
- таблиця/карточки:
|
||
- назва MicroDAO,
|
||
- тип (якщо є),
|
||
- кнопка "Відкрити MicroDAO" → `/microdao/{slug}`.
|
||
|
||
## 7.5. Chat (District Lobby)
|
||
|
||
- Внизу чи праворуч: Chat Widget, прив'язаний до **District Lobby Room**:
|
||
- отримати lobby room з `rooms` (наприклад, slug `soul-lobby`, `greenfood-lobby`, `energyunion-lobby`);
|
||
- чат працює через `/api/v1/chat/rooms/{room_id}`.
|
||
- Неавторизованим показувати "Увійти, щоб писати".
|
||
|
||
---
|
||
|
||
# 8. МОДУЛЬ 5 — SHORTCUT ROUTES
|
||
|
||
Щоб було зручно заходити на платформи:
|
||
|
||
- `/soul` → редірект або пряма сторінка, що використовує `getDistrictBySlug("soul")`.
|
||
- `/greenfood` → `getDistrictBySlug("greenfood")`.
|
||
- `/energy-union` → `getDistrictBySlug("energy-union")`.
|
||
|
||
Реалізація:
|
||
|
||
- створити файли:
|
||
- `apps/web/src/app/soul/page.tsx`
|
||
- `apps/web/src/app/greenfood/page.tsx`
|
||
- `apps/web/src/app/energy-union/page.tsx`
|
||
|
||
Які просто рендерять той самий компонент, що й `/districts/[slug]`, з фіксованим `slug`.
|
||
|
||
---
|
||
|
||
# 9. ІНТЕГРАЦІЯ З CITY LAYER
|
||
|
||
На сторінці `/city` або в City Square:
|
||
|
||
- для портальних точок (District Portals):
|
||
- додати кнопки/картки:
|
||
- "SOUL Retreat District"
|
||
- "GREENFOOD District"
|
||
- "Energy Union District"
|
||
- клік → переходить на:
|
||
- `/soul`
|
||
- `/greenfood`
|
||
- `/energy-union`
|
||
|
||
---
|
||
|
||
# 10. SMOKE-ТЕСТИ
|
||
|
||
Після завершення:
|
||
|
||
1. `/districts`:
|
||
- показує 3 District-и (SOUL, GREENFOOD, ENERGYUNION).
|
||
|
||
2. `/districts/soul`:
|
||
- рендериться без помилок,
|
||
- видно SOUL як lead agent + presence,
|
||
- видно Spirit/Logic (як core team, якщо додані),
|
||
- видно список rooms (soul-lobby, soul-events, soul-guidance...),
|
||
- чат-простір для lobby.
|
||
|
||
3. `/districts/greenfood`:
|
||
- рендериться,
|
||
- видно ERP GREENFOOD agent,
|
||
- rooms згідно GREENFOOD_District_Protocol,
|
||
- microDAO (якщо є) у списку.
|
||
|
||
4. `/districts/energy-union`:
|
||
- рендериться,
|
||
- видно Helion, Energia,
|
||
- rooms (lobby, compute, providers, labs...),
|
||
- чат-простір.
|
||
|
||
5. `/soul`, `/greenfood`, `/energy-union`:
|
||
- відкривають відповідні портали District-ів.
|
||
|
||
6. City → District:
|
||
- з City UI є лінки, які ведуть на District Portals.
|
||
|
||
---
|
||
|
||
# 11. ФІНАЛЬНИЙ ЗВІТ
|
||
|
||
Після виконання:
|
||
|
||
Створити файл:
|
||
|
||
`docs/debug/district_portals_report_<DATE>.md`
|
||
|
||
І включити в нього:
|
||
|
||
- список District-ів з `/api/v1/districts`,
|
||
- приклади `GET /api/v1/districts/{slug}`,
|
||
- скрін/опис `/districts`, `/districts/soul`, `/districts/greenfood`, `/districts/energy-union`,
|
||
- підтвердження, що `/soul`, `/greenfood`, `/energy-union` працюють.
|
||
|
||
---
|
||
|
||
# 12. PROMPT ДЛЯ CURSOR
|
||
|
||
```text
|
||
Виконай TASK_PHASE_DISTRICT_PORTALS_v1.md.
|
||
|
||
Фокус:
|
||
1) Backend: /api/v1/districts, /api/v1/districts/{slug}
|
||
2) Frontend: /districts, /districts/[slug], /soul, /greenfood, /energy-union
|
||
3) District UI: lead agent, core team, rooms, microDAO list, chat (lobby room)
|
||
4) Інтеграція з City Layer (/city → District Portals)
|
||
|
||
Після завершення створи:
|
||
docs/debug/district_portals_report_<DATE>.md
|
||
```
|
||
|
||
---
|
||
|
||
**Target Date**: Immediate
|
||
**Priority**: High
|
||
**Dependencies**: City Layer complete, Matrix rooms synced
|
||
|