feat: District Portals API (DB-based, no hardcodes)
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
This commit is contained in:
451
docs/tasks/TASK_PHASE_DISTRICT_PORTALS_v1.md
Normal file
451
docs/tasks/TASK_PHASE_DISTRICT_PORTALS_v1.md
Normal file
@@ -0,0 +1,451 @@
|
||||
# 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
|
||||
|
||||
Reference in New Issue
Block a user