Backend:
- GET /api/v1/city/rooms - list all city rooms
- GET /api/v1/city/rooms/{slug} - get room by slug with host agents
Frontend:
- Updated /city/[slug] page with host agents section
- Added breadcrumb navigation
- Updated API client to fetch room by slug
- Added rewrite for /api/city/rooms/:slug
Task doc: TASK_PHASE_CITY_ROOMS_ROUTING_v1.md
7.4 KiB
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-сторінка.
- Next.js
-
Якщо помилка 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