feat(rooms): Add city-lobby with DAARWIZZ + fix API proxy

- Created city-lobby room as main public chat with DAARWIZZ
- Fixed /api/city/rooms proxy to use correct backend path (/api/v1/city/rooms)
- Updated district rooms with zone keys (leadership, system, engineering, etc.)
- Set MicroDAO lobbies as primary rooms
- Created seed_city_rooms.py script
- Created TASK_PHASE_CITY_ROOMS_AND_PUBLIC_CHAT_v1.md

Total: 35 rooms, 31 public, 10 districts
This commit is contained in:
Apple
2025-12-01 08:47:37 -08:00
parent 2f8e471e03
commit 0039be5dc0
3 changed files with 532 additions and 1 deletions

View File

@@ -0,0 +1,334 @@
# TASK_PHASE_CITY_ROOMS_AND_PUBLIC_CHAT_v1
Проєкт: DAARION.city
Мета:
1) оживити "Кімнати Міста" (City Rooms) карта + список;
2) додати головний публічний чат з DAARWIZZ;
3) дозволити створювати кімнати всередині MicroDAO з перемикачем Public/Private.
---
## 0. Поточний стан
UI (за скріншотами):
- MicroDAO:
- є список MicroDAO з картками (DAARION DAO, Energy Union, GreenFood, Soul…).
- всередині MicroDAO є блок "Orchestrator Team Chat", але кімнати явно не підключені.
- City Rooms:
- вкладка "Мапа" показує сітку районів (Leadership Hall, System Control, Engineering, Marketing, Finance, Web3, Security, Vision, R&D, Memory, Welcome/General).
- вкладка "Список" показує "Кімнати не знайдено".
- Matrix / gateway:
- Matrix-інтеграція вже є (див. існуючі `matrix-architecture`/`gateway` доки).
- Є публічні кімнати, але вони не підв'язані до city-service Rooms API.
---
## 1. Scope
### Включено
1. **Нова модель "кімнати міста" (City Rooms)** в бекенді:
- з прив'язкою до MicroDAO / району / Matrix roomId.
2. **API для кімнат**:
- список, створення, оновлення visibility (Public/Private), отримання деталей.
3. **Головна кімната "City Lobby" з DAARWIZZ**:
- спеціальний флаг `is_city_default`.
4. **MicroDAO Rooms**:
- список кімнат MicroDAO;
- кнопка `+ Створити кімнату` з перемикачем Public/Private.
5. **City Rooms UI**:
- вкладка "Список" реальні кімнати з фільтрами;
- вкладка "Мапа" tiles прив'язані до реальних кімнат (по district).
### Виключено
- Повна CrewAI-логіка (запуск декількох агентів як команди) це окремий Task 3.
- Управління правами Matrix-кімнат (залишаємо базове: створює gateway, ACL мінімальні).
---
## 2. Backend модель "кімнати"
### 2.1. Схема БД
Створити міграцію `migrations/043_city_rooms.sql`:
```sql
-- City Rooms table for DAARION.city
-- Supports: city rooms, microdao rooms, crew rooms, district rooms
CREATE TABLE IF NOT EXISTS city_rooms (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
slug text UNIQUE NOT NULL,
title text NOT NULL,
description text,
room_type text NOT NULL, -- 'city', 'microdao', 'crew', 'district'
visibility text NOT NULL DEFAULT 'private', -- 'public', 'microdao', 'private'
microdao_id text NULL REFERENCES microdaos(id),
district_key text NULL, -- 'leadership', 'security', 'engineering', etc.
matrix_room_id text NULL,
is_city_default boolean NOT NULL DEFAULT false,
is_microdao_default boolean NOT NULL DEFAULT false,
orchestrator_agent_id text NULL REFERENCES agents(id),
icon text NULL,
color text NULL,
created_by text NULL REFERENCES users(id),
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
archived_at timestamptz NULL
);
CREATE INDEX IF NOT EXISTS idx_city_rooms_microdao ON city_rooms (microdao_id);
CREATE INDEX IF NOT EXISTS idx_city_rooms_district ON city_rooms (district_key);
CREATE INDEX IF NOT EXISTS idx_city_rooms_visibility ON city_rooms (visibility);
CREATE INDEX IF NOT EXISTS idx_city_rooms_type ON city_rooms (room_type);
CREATE INDEX IF NOT EXISTS idx_city_rooms_archived ON city_rooms (archived_at) WHERE archived_at IS NULL;
COMMENT ON TABLE city_rooms IS 'Кімнати міста DAARION - для чатів, команд, районів';
COMMENT ON COLUMN city_rooms.room_type IS 'Тип кімнати: city (міська), microdao, crew (команда), district (район)';
COMMENT ON COLUMN city_rooms.visibility IS 'Видимість: public (всім), microdao (членам MicroDAO), private (запрошеним)';
COMMENT ON COLUMN city_rooms.is_city_default IS 'Головна кімната міста (City Lobby з DAARWIZZ)';
COMMENT ON COLUMN city_rooms.is_microdao_default IS 'Головна кімната MicroDAO';
```
### 2.2. Repo / models / routes
* У `models_city.py`:
* додати `CityRoom` / `CityRoomSummary` з полями вище.
* У `repo_city.py`:
* `get_city_rooms(filter_by_visibility, filter_by_microdao, filter_by_district)`
* `get_city_room_by_slug(slug)`
* `create_city_room(...)`
* `update_city_room_visibility(slug, visibility)`
* У `routes_city.py`:
* `GET /api/v1/city/rooms`
* query params: `visibility`, `microdao_slug`, `district`.
* `POST /api/v1/city/rooms`
* body: `{ title, description?, room_type, visibility, microdao_slug?, district_key? }`.
* `PATCH /api/v1/city/rooms/{slug}`
* змінити: `title`, `description`, `visibility`, `archived_at`.
### 2.3. Matrix інтеграція
Для створення нової кімнати:
* при `POST /api/v1/city/rooms`:
* бекенд:
* викликає gateway / internal service:
* напр. `POST /internal/matrix/create-room` з payload:
* `{ "slug": "...", "title": "...", "visibility": "public|private" }`;
* отримує `matrix_room_id`.
* записує `matrix_room_id` в `city_rooms`.
Фактичний URL/сервіс знайти в існуючих доках `gateway` / `matrix-architecture` і використати.
---
## 3. Seed даних
### 3.1. City Lobby з DAARWIZZ
Створити `scripts/seed_city_rooms.py`:
* Якщо немає кімнати `slug = 'city-lobby'`:
* створити запис:
```json
{
"slug": "city-lobby",
"title": "DAARION City Lobby",
"description": "Головний публічний чат з DAARWIZZ.",
"room_type": "city",
"visibility": "public",
"is_city_default": true,
"orchestrator_agent_id": "daarwizz"
}
```
* Викликати Matrix-gateway для створення відповідної Matrix-кімнати.
* Прив'язати до MicroDAO DAARION (якщо потрібно через окрему таблицю або поле).
### 3.2. Default кімнати MicroDAO (по 1 на платформу)
Для кожної з платформ:
* `daarion` (DAARION DAO)
* `energy-union` (Energy Union)
* `greenfood` (GreenFood DAO)
* `soul` (Soul Retreat Hub)
створити room:
```json
{
"slug": "microdao-<slug>-lobby",
"title": "<Name> Lobby",
"room_type": "microdao",
"visibility": "microdao",
"microdao_id": "...",
"is_microdao_default": true
}
```
### 3.3. District Rooms (10 районів)
Для кожного району з `agents_city_mapping.yaml`:
* leadership → "Leadership Hall"
* system → "System Control Center"
* engineering → "Engineering Lab"
* marketing → "Marketing Hub"
* finance → "Finance Office"
* web3 → "Web3 District"
* security → "Security Bunker"
* vision → "Vision Studio"
* rnd → "R&D Laboratory"
* memory → "Memory Vault"
створити room:
```json
{
"slug": "district-<key>",
"title": "<Name>",
"room_type": "district",
"visibility": "public",
"district_key": "<key>"
}
```
---
## 4. Frontend MicroDAO сторінка
Файли: `apps/web/src/app/microdao/page.tsx`, `apps/web/src/app/microdao/[slug]/page.tsx` та пов'язані компоненти.
### 4.1. API hook
Створити хук:
```ts
// apps/web/src/hooks/useMicrodaoRooms.ts
import useSWR from 'swr';
import { fetcher } from '@/lib/fetcher';
export function useMicrodaoRooms(slug: string) {
return useSWR(slug ? `/api/city/rooms?microdao_slug=${slug}` : null, fetcher);
}
```
(через існуючий proxy `/api/...` до бекенду).
### 4.2. Блок "Кімнати MicroDAO"
На сторінці MicroDAO:
* додати секцію під Branding / перед "Orchestrator Team Chat":
Макет:
* Заголовок: `Кімнати MicroDAO`
* Кнопка праворуч: `+ Створити кімнату`
* Список карток:
```
[ DAARION DAO Lobby ] [ Leadership Crew ] [ Security Council ]
```
### 4.3. Модалка "Створити кімнату"
Поля:
* Назва кімнати
* Опис (опційно)
* Тип (read-only: `MicroDAO`)
* Перемикач: `Публічна кімната`
* якщо вимкнено → `visibility = 'microdao'` (лише члени MicroDAO);
* якщо увімкнено → `visibility = 'public'`.
On submit → `POST /api/city/rooms`.
---
## 5. Frontend City Rooms сторінка
Файл: `apps/web/src/app/city/page.tsx` або `apps/web/src/app/city/rooms/page.tsx` (подивитись фактичний).
### 5.1. Вкладка "Список"
* Використати `GET /api/city/rooms?visibility=public` за замовчанням.
* Відображати таблицею/картками:
Поля:
* Назва
* Тип / District / MicroDAO
* Іконки:
* Public / MicroDAO / Private
* Лічильник:
* `X агентів` (опційно, якщо буде окремий endpoint; на MVP можна не показувати).
### 5.2. Вкладка "Мапа"
* Для tile'ів районів (Leadership Hall, Security Bunker, Web3 District, …):
* під'єднати відповідні `city_rooms` через `district_key`.
* Клік по tile → переходить на `/city/rooms/[slug]` або відкриває чат.
---
## 6. Frontend головний CTA з DAARWIZZ
На головній сторінці `apps/web/src/app/page.tsx`:
* додати основну кнопку (у hero-секції):
`Поспілкуватися з DAARWIZZ`
* дія:
* `router.push('/city/rooms/city-lobby')`
* або відкриває вбудований чат-віджет, якщо він уже реалізований.
---
## 7. Acceptance Criteria
1. `GET /api/v1/city/rooms` повертає список кімнат (мінімум: `city-lobby` + 4 MicroDAO лобі + 10 district rooms).
2. На сторінці MicroDAO:
* видно блок "Кімнати MicroDAO";
* кнопка `+ Створити кімнату` створює запис у БД;
* нова кімната з'являється у списку без перезавантаження.
3. На сторінці City Rooms:
* вкладка "Список" показує реальні кімнати;
* вкладка "Мапа" не показує помилок, tile'и районів прив'язані до відповідних кімнат (або до лобі за замовчанням).
4. При переході на `/city/rooms/city-lobby` відкривається чат з DAARWIZZ (Matrix roomId збережений у `city_rooms`).
5. Нові кімнати MicroDAO мають коректний visibility:
* без галочки не видно у `?visibility=public`;
* з галочкою видно у публічному списку.
---
## 8. Наступні кроки (Task 3)
Після реалізації цього таска:
- ти матимеш головний публічний чат з DAARWIZZ на головній;
- кожне MicroDAO зможе створювати свої кімнати з вибором публічності;
- сторінка "Кімнати Міста" перестане бути пустою й стане справжнім лобі міста.
А керування агентами (створення/видалення, Crew-кімнати) винесемо в наступний Task 3:
- Глобальна кнопка "Створити агента" на `/agents`
- Локальна кнопка "Додати агента цієї ноди" в Node Cabinet
- Видалення/архівація агента в кабінеті агента
- Групи агентів = кімнати команд (CrewAI)