Files
microdao-daarion/docs/cursor/50_daarion_city_website_integration.md
2026-02-16 07:31:57 -08:00

16 KiB
Raw Permalink Blame History

50 — DAARION.city Website Integration (MicroDAO)

Специфікація інтеграції MicroDAO у офіційний сайт DAARION.city як перший публічний MicroDAO.


1. Purpose & Scope

Документ визначає:

  • як вбудовувати MicroDAO у офіційний сайт DAARION.city,
  • API для публічного каналу міста,
  • UI/UX для публічного каналу на сайті,
  • Authentication flow для користувачів сайту,
  • SEO та метадані для публічного каналу,
  • Embedding/iframe інтеграцію (опційно),
  • Analytics та tracking.

Це перша інтеграція MicroDAO у зовнішній сайт.


2. Architecture Overview

2.1 High-Level Integration

DAARION.city Website (Next.js/React)
     ↓
  Public Channel Embed
     ↓
  MicroDAO API Gateway
     ↓
  MicroDAO Backend Services

2.2 Integration Modes

  • MicroDAO публічний канал вбудовується як React компонент на сайті
  • Використовує MicroDAO API напряму
  • Повний контроль над UI/UX

Mode 2: iframe Embed

  • MicroDAO публічний канал відкривається в iframe
  • Простіша інтеграція, менше контролю
  • Використовується для швидкого прототипування

Mode 3: Full Redirect

  • Посилання з сайту веде на окрему сторінку MicroDAO
  • Найпростіша реалізація
  • Втрачається контекст сайту

3. DAARION.city as First MicroDAO

3.1 Team Setup

DAARION.city має бути створений як перший MicroDAO:

INSERT INTO teams (
  id,
  name,
  slug,
  type,
  mode,
  description,
  created_at
) VALUES (
  'daarion-city',
  'DAARION.city',
  'daarion',
  'city',
  'public',
  'Офіційна спільнота міста DAARION',
  NOW()
);

3.2 Public Channel Setup

Створюється публічний канал для міста:

INSERT INTO channels (
  id,
  team_id,
  title,
  slug,
  type,
  is_public,
  created_at
) VALUES (
  'daarion-city-general',
  'daarion-city',
  'Загальний канал міста',
  'general',
  'public',
  true,
  NOW()
);

3.3 City Agent Setup

Створюється міський агент:

INSERT INTO agents (
  id,
  team_id,
  name,
  role,
  system_prompt,
  memory_scope,
  created_at
) VALUES (
  'daarion-city-agent',
  'daarion-city',
  'Міський Асистент',
  'team_assistant',
  'Ти — міський асистент DAARION.city. Допомагаєш мешканцям та гостям міста.',
  'team',
  NOW()
);

4. Public Channel API

4.1 Get Public Channel Info

GET /api/v1/channels/{slug}/public

Response:

{
  "id": "daarion-city-general",
  "team_id": "daarion-city",
  "title": "Загальний канал міста",
  "slug": "general",
  "description": "Публічний канал для обговорення міських питань",
  "message_count": 1234,
  "member_count": 567,
  "is_public": true,
  "team": {
    "id": "daarion-city",
    "name": "DAARION.city",
    "slug": "daarion"
  }
}

4.2 Get Public Messages

GET /api/v1/channels/{slug}/public/messages?limit=50&before={message_id}

Response:

{
  "messages": [
    {
      "id": "msg-123",
      "sender": {
        "id": "user-456",
        "name": "Олександр",
        "avatar_url": "https://..."
      },
      "body": "Привіт, місто!",
      "created_at": "2024-11-14T10:00:00Z",
      "reactions": []
    }
  ],
  "pagination": {
    "has_more": true,
    "next_cursor": "msg-124"
  }
}

4.3 Post Message (Authenticated)

POST /api/v1/channels/{slug}/public/messages
Authorization: Bearer {token}
Content-Type: application/json

{
  "body": "Повідомлення від користувача"
}

4.4 Register as Viewer/Member

POST /api/v1/channels/{slug}/public/join
Content-Type: application/json

{
  "email": "user@example.com",
  "name": "Ім'я Користувача",
  "viewer_type": "member" | "visitor"
}

Response:

{
  "user_id": "user-789",
  "access_token": "jwt-token",
  "membership": {
    "role": "member",
    "viewer_type": "member"
  }
}

5. UI/UX for Website Integration

5.1 Embedded Widget Component

React Component:

<MicroDAOChannelEmbed
  channelSlug="general"
  teamSlug="daarion"
  apiUrl="https://api.microdao.xyz/v1"
  theme="light"
  showHeader={true}
  allowJoin={true}
/>

Props:

  • channelSlug: slug каналу
  • teamSlug: slug команди
  • apiUrl: URL API Gateway
  • theme: "light" | "dark"
  • showHeader: показувати заголовок каналу
  • allowJoin: дозволити реєстрацію з віджета

5.2 Widget Layout

┌─────────────────────────────────────┐
│  # Загальний канал міста             │
│  DAARION.city                        │
├─────────────────────────────────────┤
│                                     │
│  [Messages List]                    │
│                                     │
│  ┌───────────────────────────────┐ │
│  │ [Input Field]        [Send]   │ │
│  └───────────────────────────────┘ │
│                                     │
│  [Join Button] (if not authenticated)│
└─────────────────────────────────────┘

5.3 Authentication Flow

Step 1: Guest View

  • Користувач бачить повідомлення (read-only)
  • Кнопка "Приєднатися до обговорення"

Step 2: Join Modal

  • Форма: Email, Ім'я, Тип участі (Member/Visitor)
  • Відправка запиту на /api/v1/channels/{slug}/public/join
  • Отримання JWT токену

Step 3: Authenticated View

  • Користувач може писати повідомлення
  • Відображається його профіль
  • Доступ до повної функціональності каналу

6. SEO & Metadata

6.1 Open Graph Tags

<meta property="og:title" content="Загальний канал міста DAARION.city" />
<meta property="og:description" content="Публічний канал для обговорення міських питань" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://daarion.city/channel/general" />
<meta property="og:image" content="https://daarion.city/og-image.png" />

6.2 Twitter Cards

<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Загальний канал міста DAARION.city" />
<meta name="twitter:description" content="Публічний канал для обговорення міських питань" />
<meta name="twitter:image" content="https://daarion.city/twitter-image.png" />

6.3 Structured Data (JSON-LD)

{
  "@context": "https://schema.org",
  "@type": "DiscussionForumPosting",
  "headline": "Загальний канал міста DAARION.city",
  "description": "Публічний канал для обговорення міських питань",
  "author": {
    "@type": "Organization",
    "name": "DAARION.city"
  },
  "datePublished": "2024-11-14T10:00:00Z"
}

7. Security & Privacy

7.1 CORS Configuration

API Gateway має дозволяти запити з https://daarion.city:

const corsOptions = {
  origin: [
    'https://daarion.city',
    'https://www.daarion.city',
    'http://localhost:3000' // для розробки
  ],
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization']
};

7.2 Rate Limiting

Публічний канал має обмеження:

  • Guest (read-only): 100 requests/minute
  • Authenticated (write): 30 messages/minute
  • Join requests: 5 requests/hour per IP

7.3 Content Moderation

  • Автоматична модерація через Agent
  • Фільтрація спаму
  • Блокування токсичного контенту
  • Можливість скарг від користувачів

8. Analytics & Tracking

8.1 Events to Track

type AnalyticsEvent = 
  | { type: 'channel_view', channel_slug: string }
  | { type: 'message_sent', channel_slug: string, user_id: string }
  | { type: 'join_clicked', channel_slug: string }
  | { type: 'join_completed', channel_slug: string, viewer_type: string }
  | { type: 'widget_loaded', channel_slug: string, load_time: number };

8.2 Integration with Analytics

  • Google Analytics 4
  • Plausible Analytics (privacy-friendly)
  • Custom analytics endpoint

9. Implementation Steps

Step 1: Backend Setup

  1. Створити DAARION.city team у БД
  2. Створити публічний канал
  3. Створити міського агента
  4. Налаштувати CORS для daarion.city
  5. Додати rate limiting для публічного каналу

Step 2: API Endpoints

  1. GET /api/v1/channels/{slug}/public — інформація про канал
  2. GET /api/v1/channels/{slug}/public/messages — повідомлення
  3. POST /api/v1/channels/{slug}/public/messages — надіслати повідомлення
  4. POST /api/v1/channels/{slug}/public/join — приєднатися

Step 3: Frontend Widget

  1. Створити React компонент MicroDAOChannelEmbed
  2. Інтегрувати з API
  3. Додати authentication flow
  4. Додати real-time оновлення (WebSocket/SSE)

Step 4: Website Integration

  1. Додати компонент на сторінку daarion.city/channel/general
  2. Налаштувати SEO метадані
  3. Додати analytics tracking
  4. Тестування на production

10. Example Integration Code

10.1 Next.js Page

// pages/channel/[slug].tsx
import { MicroDAOChannelEmbed } from '@/components/MicroDAOChannelEmbed';
import Head from 'next/head';

export default function ChannelPage({ channelSlug }) {
  return (
    <>
      <Head>
        <title>Загальний канал міста DAARION.city</title>
        <meta name="description" content="Публічний канал для обговорення міських питань" />
        {/* Open Graph tags */}
        {/* Twitter Cards */}
      </Head>
      
      <div className="container mx-auto py-8">
        <MicroDAOChannelEmbed
          channelSlug={channelSlug}
          teamSlug="daarion"
          apiUrl={process.env.NEXT_PUBLIC_MICRODAO_API_URL}
          theme="light"
          showHeader={true}
          allowJoin={true}
        />
      </div>
    </>
  );
}

10.2 React Widget Component

// components/MicroDAOChannelEmbed.tsx
import { useState, useEffect } from 'react';
import { useChannelMessages, useJoinChannel } from '@/hooks/useMicroDAO';

export function MicroDAOChannelEmbed({
  channelSlug,
  teamSlug,
  apiUrl,
  theme,
  showHeader,
  allowJoin
}) {
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const { messages, loadMore } = useChannelMessages(channelSlug, apiUrl);
  const { join } = useJoinChannel(channelSlug, apiUrl);

  const handleJoin = async (email: string, name: string, viewerType: string) => {
    const result = await join(email, name, viewerType);
    if (result.access_token) {
      localStorage.setItem('microdao_token', result.access_token);
      setIsAuthenticated(true);
    }
  };

  return (
    <div className={`microdao-widget theme-${theme}`}>
      {showHeader && (
        <div className="widget-header">
          <h2># Загальний канал міста</h2>
          <p>DAARION.city</p>
        </div>
      )}
      
      <div className="messages-list">
        {messages.map(msg => (
          <Message key={msg.id} message={msg} />
        ))}
      </div>

      {isAuthenticated ? (
        <MessageInput channelSlug={channelSlug} apiUrl={apiUrl} />
      ) : (
        allowJoin && <JoinButton onJoin={handleJoin} />
      )}
    </div>
  );
}

11. Testing Checklist

11.1 Backend Tests

  • Публічний канал створено для DAARION.city
  • API endpoints повертають коректні дані
  • CORS налаштовано правильно
  • Rate limiting працює
  • Authentication flow працює

11.2 Frontend Tests

  • Widget завантажується на сайті
  • Повідомлення відображаються коректно
  • Join flow працює
  • Real-time оновлення працюють
  • Responsive design на мобільних

11.3 Integration Tests

  • SEO метадані відображаються
  • Analytics tracking працює
  • Content moderation працює
  • Error handling коректний

12. Integration with Other Docs

Цей документ доповнює:

  • DAARION_city_integration.md — загальна архітектура DAARION.city
  • 47_messaging_channels_and_privacy_layers.md — архітектура каналів
  • 04_ui_ux_onboarding_chat.md — UI/UX специфікація
  • 03_api_core_snapshot.md — API контракти

13. Завдання для Cursor

You are a senior full-stack engineer. Implement DAARION.city website integration using:
- 50_daarion_city_website_integration.md
- DAARION_city_integration.md
- 47_messaging_channels_and_privacy_layers.md
- 03_api_core_snapshot.md

Tasks:
1) Create DAARION.city team in database (type='city', slug='daarion', mode='public').
2) Create public channel for DAARION.city (slug='general', type='public', is_public=true).
3) Create city agent for DAARION.city (role='team_assistant', memory_scope='team').
4) Implement Public Channel API endpoints:
   - GET /api/v1/channels/{slug}/public (channel info)
   - GET /api/v1/channels/{slug}/public/messages (messages with pagination)
   - POST /api/v1/channels/{slug}/public/messages (send message, authenticated)
   - POST /api/v1/channels/{slug}/public/join (register as viewer/member)
5) Configure CORS for daarion.city domain.
6) Add rate limiting for public channel (guest: 100 req/min, authenticated: 30 msg/min, join: 5 req/hour).
7) Create React component MicroDAOChannelEmbed (props: channelSlug, teamSlug, apiUrl, theme, showHeader, allowJoin).
8) Implement authentication flow (guest view → join modal → authenticated view).
9) Add real-time updates (WebSocket/SSE for new messages).
10) Add SEO metadata (Open Graph, Twitter Cards, JSON-LD).
11) Add analytics tracking (channel_view, message_sent, join_clicked, join_completed, widget_loaded).
12) Add content moderation (spam filter, toxic content detection, user reports).

Output:
- list of modified files
- diff
- summary

14. Summary

Інтеграція MicroDAO у офіційний сайт DAARION.city:

  • DAARION.city стає першим MicroDAO типу "city"
  • Публічний канал вбудовується на сайт як React компонент
  • API endpoints для публічного каналу
  • Authentication flow для користувачів сайту
  • SEO та метадані для публічного каналу
  • Analytics та tracking
  • Security (CORS, rate limiting, content moderation)

Це перша інтеграція MicroDAO у зовнішній сайт, яка стане основою для подальших інтеграцій з іншими платформами.


Версія: 1.0
Останнє оновлення: 2024-11-14