TASK_PHASE_CITY_ROOMS_ROUTING_v1¶
Version: 1.0 Status: Ready Priority: High (City Layer UX + Matrix Rooms)
1. МЕТА¶
Зробити так, щоб кожна City Room була доступною за URL:
/city— огляд усіх кімнат/city/{slug}— сторінка конкретної кімнати
Сторінка кімнати має:
- завантажувати дані кімнати з backend (room meta + matrix_room_id),
- показувати присутніх агентів,
- інтегрувати чат (Matrix room),
- показувати presence агентів.
2. ВИХІДНІ ДАНІ¶
Вже є:
- Таблиця
roomsз city-кімнатами (scope = 'city', 8+ кімнат). - Поле
slugабо еквівалент (наприкладcity-general,city-welcomeтощо). matrix_room_idзаповнене (Matrix sync завершений).- Matrix Gateway та Chat API:
GET /api/v1/chat/rooms/{room_id}/messagesPOST /api/v1/chat/rooms/{room_id}/messages- Presence Layer:
GET /api/v1/agents/{agent_id}/presence- Frontend:
- базовий Chat Widget
- компонент PresenceDot
- карта /city вже існує (огляд кімнат).
3. SCOPE¶
- Frontend routing для
/city/{slug}(Next.js, App Router). - API-обгортка для завантаження City Room.
- Сторінка кімнати:
- назва, опис, тип кімнати;
- список ключових агентів (host/moderators);
- presence-індикатори;
- чат-виджет, прив'язаний до room_id / matrix_room_id.
- Обробка помилок:
- 404, якщо кімната не існує;
- fallback UI, якщо Matrix тимчасово недоступний.
4. МОДУЛЬ 1 — BACKEND (CITY-SERVICE) API (якщо ще немає)¶
Перевірити/додати в city-service:
4.1. GET /api/v1/city/rooms¶
Список всіх city-кімнат.
Вихід:
[
{
"id": "uuid",
"slug": "city-general",
"name": "General",
"description": "Головна кімната міста",
"scope": "city",
"matrix_room_id": "!room:matrix.daarion.city",
"host_agents": ["agent_id_1", "agent_id_2"]
},
...
]
4.2. GET /api/v1/city/rooms/{slug}¶
Конкретна кімната за slug.
Вихід:
{
"id": "uuid",
"slug": "city-general",
"name": "General",
"description": "Головна кімната міста",
"scope": "city",
"matrix_room_id": "!room:matrix.daarion.city",
"host_agents": [
{
"id": "agent_id_1",
"name": "DARIO",
"role": "host"
}
]
}
Якщо кімнати немає → 404.
5. МОДУЛЬ 2 — FRONTEND API КЛІЄНТ¶
В apps/web/src/lib/api/city.ts (або створити новий):
export async function getCityRooms(): Promise<CityRoomSummary[]> { ... }
export async function getCityRoomBySlug(slug: string): Promise<CityRoomDetail> { ... }
Де CityRoomDetail містить як мінімум:
- id
- slug
- name
- description
- matrixRoomId
- hostAgents[]
6. МОДУЛЬ 3 — ROUTING: /city/{slug}¶
У apps/web/src/app/city/[slug]/page.tsx:
- Прочитати
params.slug. - Викликати
getCityRoomBySlug(slug). - Якщо 404 → показати
notFound()(Next.js). - Якщо інша помилка → показати error boundary / fallback.
7. МОДУЛЬ 4 — UI СТОРІНКИ КІМНАТИ¶
Макет сторінки /city/{slug}:
7.1. Верхня частина (header)¶
- Назва кімнати (
room.name) - Підназва / опис (
room.description) - Badge:
City Room - Breadcrumb:
City / {room.name}
7.2. Блок "Host Agents"¶
Карточка(и) головних агентів кімнати:
- аватар
- ім'я
- роль (host/moderator)
- PresenceDot (online/away/offline)
- посилання "Перейти в кабінет агента"
Дані брати з host_agents.
7.3. Блок "Room Info" (опціонально)¶
- список тегів (public / governance / help / etc.)
- кількість учасників (якщо є)
7.4. Блок "Chat"¶
Використати Chat Widget, але прив'язати не до Agent/Node/MicroDAO, а до ROOM:
- якщо вже є універсальний
<AgentChatWidget>з режимами entityType, можна: - додати
entityType="room" entityId = room.id- якщо ні — створити
CityRoomChatWidget, який: - бере
room.id→/api/v1/chat/rooms/{room.id}/messages - дозволяє надсилати повідомлення в кімнату
Для неавторизованих:
- "Увійдіть, щоб писати у міську кімнату".
8. МОДУЛЬ 5 — ІНТЕГРАЦІЯ З /city¶
На сторінці /city:
- у списку/мапі кімнат:
- додати посилання на
/city/{slug}. - клік по кімнаті → відкриває
/city/{slug}.
9. ОБРОБКА ПОМИЛОК¶
- Якщо
/api/v1/city/rooms/{slug}повертає 404: -
Next.js
notFound()→ стандартна 404-сторінка. -
Якщо помилка backend (500):
-
показати повідомлення "Кімната тимчасово недоступна".
-
Якщо немає
matrix_room_id: - показати банер "Matrix ще синхронізується, чат скоро з'явиться".
10. SMOKE-ТЕСТИ¶
Після завершення:
/city:-
список/мапа містить 8+ кімнат.
-
/city/general: - сторінка відкривається;
- видно назву, опис;
- видно host-агентів (наприклад, DARIO/DARIA);
-
видно presence.
-
/city/welcome,/city/leadership-hall,/city/builders,/city/security,/city/announcements: -
усі відкриваються без 404.
-
Chat:
- у кімнаті
/city/generalможливо:- побачити історію повідомлень;
- відправити нове повідомлення (як авторизований користувач).
11. FINISH-АРТЕФАКТ¶
Після виконання Cursor створює:
docs/debug/city_rooms_routing_report_<DATE>.md
Зі змістом:
- список slug'ів city-кімнат;
- приклади успішних HTTP-викликів:
GET /api/v1/city/roomsGET /api/v1/city/rooms/{slug}- скріншот або опис перевірки
/city/{slug}; - підтвердження роботи чату в принаймні одній кімнаті.
12. PROMPT ДЛЯ CURSOR¶
Виконай TASK_PHASE_CITY_ROOMS_ROUTING_v1.md.
Фокус:
1) Backend: /api/v1/city/rooms, /api/v1/city/rooms/{slug} (якщо ще немає)
2) Frontend: Next.js routing /city/[slug]
3) UI: сторінка кімнати (host agents, presence, chat)
4) Інтеграція з існуючими чат/Matrix/PRESENCE шарами
Після завершення створи:
docs/debug/city_rooms_routing_report_<DATE>.md
Target Date: Immediate Priority: High Dependencies: Matrix integration complete, Chat API working