Files
microdao-daarion/docs/tasks/TASK_PHASE_CITY_ROOMS_FINISH_v2.md
2026-02-16 08:45:48 -08:00

6.3 KiB
Raw Permalink Blame History

TASK_PHASE_CITY_ROOMS_FINISH_v2

Title

TASK_PHASE_CITY_ROOMS_FINISH_v2 — MicroDAO Rooms + City Lobby CTA + Online Stats Fix

1. Overview

Finish the DAARION City chat layer:

  1. City Rooms page:

    • Map + List already work.
    • Fix NaN for online users count.
  2. MicroDAO Rooms:

    • Each MicroDAO must have its own rooms section.
    • Ability to create new rooms from MicroDAO cabinet.
  3. City Lobby CTA:

    • Main public chat with DAARWIZZ should be accessible directly from the homepage and top navigation.

All changes must use existing architecture: city-service (FastAPI + Postgres) and apps/web (Next.js / React).


2. Current State (as of 2025-12-01)

  • Backend:

    • scripts/seed_city_rooms.py creates ~31 rooms (district rooms, lobbies, city lobby, etc.).
    • city-service exposes /api/v1/city/rooms (already used by UI).
    • Rooms table already contains:
      • id
      • slug
      • name (title)
      • description
      • zone (district key)
      • room_type (e.g. city, district, microdao, etc.)
      • is_public (bool)
      • microdao_id (nullable, for MicroDAO rooms)
  • Frontend:

    • /city (City Rooms):
      • Map tab: grid of districts, shows total rooms and online counters.
      • List tab: renders all rooms with description.
      • At the bottom: summary cards: Kімнат: 31, Онлайн: NaN.
    • MicroDAO pages (/microdao/[slug]):
      • Currently have no dedicated "MicroDAO Rooms" section.
    • Homepage (/):
      • No direct CTA to "DAARION City Lobby".

3. Goals

  1. Fix online counter:

    • Never show NaN on the City Rooms page.
  2. MicroDAO Rooms UI:

    • On /microdao/[slug] display:
      • List of rooms belonging to this MicroDAO.
      • Button "Створити кімнату".
  3. City Lobby CTA:

    • On homepage and/or main menu:
      • Button "Поспілкуватися з DAARWIZZ" that opens DAARION City Lobby.

4. Backend Tasks

4.1. Room model & repository

Files:

  • services/city-service/models_city.py
  • services/city-service/repo_city.py
  • services/city-service/routes_city.py
  1. Ensure Room model exposes needed fields:
class CityRoomSummary(BaseModel):
    id: str
    slug: str
    name: str
    description: Optional[str]
    zone: Optional[str]
    room_type: str
    microdao_id: Optional[str]
    is_public: bool
    members_online: int = 0  # ← must always be integer (0 by default)
  1. Repo method for city rooms:

    • get_all_rooms() must:
      • Return members_online as integer (use COALESCE(..., 0)).
  2. Repo method for MicroDAO rooms: Add/verify method:

async def get_microdao_rooms(microdao_id: str) -> List[dict]:
    """Get rooms for specific MicroDAO"""
    # WHERE microdao_id = $1 AND is_public = true OR owner_type = 'microdao'
  1. API routes:
    • Verify endpoint: GET /api/v1/city/rooms returns members_online: int.
    • Verify endpoint: GET /city/microdao/{slug}/rooms returns MicroDAO rooms.
    • Add endpoint for room creation:
class CreateRoomRequest(BaseModel):
    title: str
    description: Optional[str]
    room_type: str = "microdao"
    is_public: bool = False

@router.post("/city/microdao/{slug}/rooms")
async def create_microdao_room(slug: str, body: CreateRoomRequest):
    # Create room for MicroDAO
  1. Online stats summary:
    • Add/verify endpoint: GET /api/v1/city/rooms/summary
    • Returns: {"rooms_total": int, "online_total": int}

5. Frontend Tasks

Files:

  • apps/web/src/app/city/page.tsx
  • apps/web/src/app/microdao/[slug]/page.tsx
  • apps/web/src/app/page.tsx (homepage)
  • apps/web/src/components/microdao/MicrodaoRoomsSection.tsx (new)

5.1. Fix NaN online stats

  1. In city/page.tsx:
    • Ensure online count uses fallback:
const onlineTotal = summary?.online_total ?? 0;
// or
const onlineTotal = Number(summary?.online_total) || 0;
  1. If API returns null or undefined, display 0.

5.2. MicroDAO Rooms section

In apps/web/src/app/microdao/[slug]/page.tsx:

  1. Add API call:
const rooms = await fetchMicrodaoRooms(slug); // GET /city/microdao/{slug}/rooms
  1. Render new section:
<section className="space-y-4">
  <div className="flex items-center justify-between">
    <h2 className="text-xl font-semibold">Кімнати MicroDAO</h2>
    <Button onClick={openCreateRoomModal}>
      <Plus className="w-4 h-4 mr-2" />
      Створити кімнату
    </Button>
  </div>

  {rooms.length === 0 ? (
    <p className="text-muted-foreground">
      Ще немає кімнат. Створіть першу кімнату для цієї платформи.
    </p>
  ) : (
    <div className="grid gap-3">
      {rooms.map((room) => (
        <MicrodaoRoomCard key={room.slug} room={room} />
      ))}
    </div>
  )}
</section>
  1. MicrodaoRoomCard component:

    • title
    • description
    • room_type (badge)
    • visibility (Public/Private badge)
    • members_online
  2. "Create Room" modal:

    • Назва кімнати (title, required)
    • Опис (optional)
    • Тип (select: Lobby, Governance, Project, Crew)
    • Видимість (switch: Public / Private, default = Private)
    • On submit → POST /city/microdao/{slug}/rooms

5.3. City Lobby CTA

  1. On homepage (apps/web/src/app/page.tsx):
<section className="py-12 text-center">
  <h2 className="text-2xl font-bold mb-4">
    Головний публічний чат DAARION City
  </h2>
  <p className="text-muted-foreground mb-6">
    Поспілкуватися з DAARWIZZ та іншими громадянами міста.
  </p>
  <Link href="/city?room=city-lobby">
    <Button size="lg" className="gap-2">
      <MessageCircle className="w-5 h-5" />
      Поспілкуватися з DAARWIZZ
    </Button>
  </Link>
</section>
  1. Optionally add to navigation header:
    • New item: "City Lobby" → /city?room=city-lobby

6. Acceptance Criteria

  1. City Rooms page shows:

    • Correct number of rooms.
    • Online count is integer (0 allowed), never NaN.
  2. MicroDAO page (/microdao/daarion, etc.) shows:

    • "Кімнати MicroDAO" section.
    • Ability to create a room.
    • Newly created room appears in list.
  3. Homepage shows:

    • CTA "Поспілкуватися з DAARWIZZ".
    • Clicking the button opens City Lobby room.
  4. All routes work both on NODE1 and NODE2.