feat: add MicroDAO balance checks and DAARION.city integration

- Update Wallet Service: balance checks (1 DAARION for create, 0.01 for usage)
- Update DAOFactory Service: use new balance checks
- Add DB migration: teams type field and city_links table
- Add DAARION.city seed data
- Create teams API routes with balance validation
- Add DAARION.city remote repository
- Add sync scripts and documentation
This commit is contained in:
Apple
2025-11-15 08:56:14 -08:00
parent c552199eed
commit 582ab75b03
13 changed files with 994 additions and 25 deletions

185
DAARION_CITY_REPO.md Normal file
View File

@@ -0,0 +1,185 @@
# Робота з репозиторієм DAARION.city
## 🔗 Підключені репозиторії
### 1. MicroDAO (поточний проєкт)
- **Remote:** `origin`
- **URL:** `git@github.com:IvanTytar/microdao-daarion.git`
- **Призначення:** Код та документація MicroDAO
### 2. DAARION.city
- **Remote:** `daarion-city`
- **URL:** `git@github.com:DAARION-DAO/daarion-ai-city.git`
- **Призначення:** Офіційний сайт та код DAARION.city
---
## 📋 Команди для роботи з DAARION.city
### Перевірка статусу
```bash
# Перевірити доступні гілки
git ls-remote --heads daarion-city
# Перевірити поточний remote
git remote -v
```
### Клонування/Оновлення
```bash
# Клонувати репозиторій DAARION.city (якщо потрібно окремо)
git clone git@github.com:DAARION-DAO/daarion-ai-city.git
# Оновити інформацію про remote
git fetch daarion-city
```
### Створення гілки для DAARION.city
```bash
# Створити локальну гілку, що відстежує remote
git checkout -b daarion-city-main --track daarion-city/main
# Або створити нову гілку для змін
git checkout -b feature/console-integration daarion-city/main
```
### Push змін до DAARION.city
```bash
# Push поточної гілки до DAARION.city
git push daarion-city <branch-name>
# Push з встановленням upstream
git push -u daarion-city <branch-name>
```
### Створення Pull Request
```bash
# 1. Створити гілку зі змінами
git checkout -b feature/microdao-integration daarion-city/main
# 2. Внести зміни
# ... редагування файлів ...
# 3. Коміт та push
git add .
git commit -m "feat: integrate MicroDAO console"
git push -u daarion-city feature/microdao-integration
# 4. Створити PR через GitHub UI або CLI
gh pr create --repo DAARION-DAO/daarion-ai-city --base main --head feature/microdao-integration
```
---
## 🔄 Синхронізація між репозиторіями
### Варіант 1: Копіювання файлів
Якщо потрібно скопіювати файли з MicroDAO до DAARION.city:
```bash
# 1. Клонувати DAARION.city (якщо ще не клоновано)
cd /tmp
git clone git@github.com:DAARION-DAO/daarion-ai-city.git
cd daarion-ai-city
# 2. Скопіювати потрібні файли
cp -r /path/to/MicroDAO/src/components/console ./src/components/
cp /path/to/MicroDAO/src/pages/ConsolePage.tsx ./src/pages/
# 3. Коміт та push
git add .
git commit -m "feat: add MicroDAO console components"
git push origin main
```
### Варіант 2: Git Subtree (для спільних компонентів)
Якщо потрібно тримати спільні компоненти синхронізованими:
```bash
# Додати subtree з MicroDAO до DAARION.city
cd /path/to/daarion-ai-city
git subtree add --prefix=src/shared/microdao git@github.com:IvanTytar/microdao-daarion.git main --squash
# Оновити subtree
git subtree pull --prefix=src/shared/microdao git@github.com:IvanTytar/microdao-daarion.git main --squash
```
---
## 🎯 Типові сценарії
### Сценарій 1: Додати Console компонент до DAARION.city
```bash
# 1. У проєкті MicroDAO 3
cd "/Users/apple/Desktop/MicroDAO/MicroDAO 3"
# 2. Створити гілку для змін
git checkout -b feature/console-component
# 3. Створити компонент
# ... створення компонента ...
# 4. Коміт у MicroDAO
git add .
git commit -m "feat: create Console component"
git push origin feature/console-component
# 5. Клонувати DAARION.city (якщо потрібно)
cd /tmp
git clone git@github.com:DAARION-DAO/daarion-ai-city.git
cd daarion-ai-city
# 6. Скопіювати компонент
cp -r "/Users/apple/Desktop/MicroDAO/MicroDAO 3/src/components/console" ./src/components/
# 7. Коміт та push до DAARION.city
git add .
git commit -m "feat: integrate MicroDAO Console component"
git push origin main
```
### Сценарій 2: Оновити документацію в обох репозиторіях
```bash
# 1. Оновити документацію в MicroDAO
cd "/Users/apple/Desktop/MicroDAO/MicroDAO 3"
# ... редагування ...
git add docs/
git commit -m "docs: update integration guide"
git push origin main
# 2. Скопіювати оновлену документацію до DAARION.city
cd /tmp/daarion-ai-city
cp -r "/Users/apple/Desktop/MicroDAO/MicroDAO 3/docs/daarion" ./docs/
git add docs/
git commit -m "docs: sync DAARION documentation from MicroDAO"
git push origin main
```
---
## 🔐 Права доступу
Перевірка прав доступу:
```bash
# Перевірити доступ до DAARION.city
git ls-remote --heads daarion-city
# Якщо помилка "Permission denied", потрібно:
# 1. Перевірити SSH ключ на GitHub
# 2. Перевірити права доступу до репозиторію DAARION-DAO/daarion-ai-city
```
---
## 📝 Примітки
- **Не push'ити безпосередньо в main** — краще створювати гілки та PR
- **Синхронізація файлів** — можна використовувати скрипти або вручну копіювати
- **Версіонування** — зберігати версії компонентів для сумісності
---
**Останнє оновлення:** 2024-11-14

179
IMPLEMENTATION_PLAN.md Normal file
View File

@@ -0,0 +1,179 @@
# План реалізації: Console + DAARION.city + Створення MicroDAO
## 📋 Поточний стан проєкту
### ✅ Що вже є:
- Базова структура React + TypeScript
- Wallet Service (перевірка балансів DAAR/DAARION)
- DAOFactory Service (створення DAO)
- PDP Service (перевірка політик)
- БД міграції (teams, channels, messages)
- Onboarding компоненти
### ❌ Що потрібно додати:
- Console UI (адмін-панель)
- Перевірка стейкінгу (замість балансу)
- Таблиця `staking` в БД
- Поле `type` в таблиці `teams` (city, platform, community)
- DAARION.city як перше MicroDAO (seed дані)
- Створення MicroDAO з перевіркою стейкінгу
- Admin роль з перевіркою 0.01 DAARION
---
## ❓ Питання для уточнення
### 1. Console / Адмін-панель
**Q1.1:** Що таке "console консоль"?
- [ ] Окрема сторінка `/console` на сайті DAARION.city?
- [ ] Вбудований віджет на існуючій сторінці?
- [ ] Окремий піддомен `console.daarion.city`?
**Q1.2:** Які функції мають бути в console?
- [ ] Створення нового MicroDAO
- [ ] Перегляд списку існуючих MicroDAO
- [ ] Управління DAARION.city як SuperDAO
- [ ] Перегляд міських платформ (GREENFOOD, EnergyUnion)
- [ ] Wallet інтерфейс (баланси, стейкінг)
- [ ] Інші функції?
**Q1.3:** Технічний стек для console?
- [ ] React компонент на існуючому сайті DAARION.city?
- [ ] Який фреймворк? (Next.js, Vite, інше)
- [ ] Чи є вже існуючий код console?
---
### 2. Порог для створення MicroDAO
**Q2.1:** Уточнення порогу
- В документації: "1 DAAR **або** 0.01 DAARION"
- Ти кажеш: "мінімум **1 DAARION у стейкінгу**"
**Питання:**
- [ ] Правильно: **1 DAARION у стейкінгу** (не просто баланс)?
- [ ] Чи можна альтернатива: 1 DAAR у стейкінгу?
**Q2.2:** Перевірка стейкінгу
- Де зберігається інформація про стейкінг? (таблиця `staking`?)
- Як перевіряється стейкінг перед створенням MicroDAO?
- Чи потрібна перевірка через Wallet Service або on-chain?
---
### 3. Роль Admin та 0.01 DAARION
**Q3.1:** Роль Admin
- [ ] Це роль в конкретному MicroDAO?
- [ ] Чи це глобальна роль в DAARION.city?
**Q3.2:** 0.01 DAARION для Admin
- [ ] Це мінімум для отримання ролі Admin?
- [ ] Це мінімум для запрошення інших користувачів?
- [ ] Це мінімум для постійного використання (maintenance fee)?
**Q3.3:** Перевірка перед запрошенням
- [ ] Перевіряється баланс або стейкінг?
- [ ] Чи потрібна перевірка при кожному запрошенні?
---
### 4. Міські платформи
**Q4.1:** Які саме міські платформи вже існують?
- [ ] GREENFOOD
- [ ] EnergyUnion
- [ ] WaterUnion
- [ ] Інші?
**Q4.2:** Як вони об'єднані?
- [ ] Через `city_links` таблицю?
- [ ] Чи вони вже створені як MicroDAO типу "platform"?
- [ ] Чи потрібно їх створити зараз?
**Q4.3:** Відображення в console
- [ ] Як окремий розділ "Міські платформи"?
- [ ] Чи як частина дерева MicroDAO?
---
### 5. UI для створення MicroDAO
**Q5.1:** Форма чи діалог?
- [ ] Форма з полями (назва, опис, тип)
- [ ] Діалог з агентом (як в onboarding)
- [ ] Інше?
**Q5.2:** Які поля обов'язкові?
- [ ] Назва
- [ ] Опис
- [ ] Тип (community, guild, lab, personal)
- [ ] Інші?
---
## 🎯 Пропозиція плану реалізації
### Фаза 1: Backend Foundation
1. ✅ Додати таблицю `staking` в БД
2. ✅ Додати поле `type` в таблицю `teams` (city, platform, community, guild, lab, personal)
3. ✅ Додати таблицю `city_links` (parent_team_id, child_team_id, relation_type)
4. ✅ Оновити Wallet Service для перевірки стейкінгу
5. ✅ Оновити DAOFactory Service для перевірки стейкінгу (1 DAARION)
6. ✅ Додати seed дані для DAARION.city (type='city', slug='daarion')
### Фаза 2: Console UI
1. ✅ Створити сторінку `/console`
2. ✅ Компонент "Створити MicroDAO" (з перевіркою стейкінгу)
3. ✅ Компонент "Список MicroDAO" (включаючи DAARION.city)
4. ✅ Компонент "Міські платформи" (якщо є)
5. ✅ Компонент "Wallet" (баланси, стейкінг)
### Фаза 3: Створення MicroDAO
1. ✅ API endpoint `POST /api/v1/teams` (з перевіркою стейкінгу)
2. ✅ UI форма/діалог для створення
3. ✅ Автоматичне створення DAO через DAOFactory
4. ✅ Автоматичне призначення ролі Owner
### Фаза 4: Admin роль та запрошення
1. ✅ Перевірка 0.01 DAARION для ролі Admin
2. ✅ API endpoint для запрошення користувачів
3. ✅ Перевірка стейкінгу перед запрошенням
---
## 🚀 Швидкий старт (після відповідей)
Після отримання відповідей на питання, я можу:
1. **Створити міграції БД** для:
- Таблиця `staking`
- Поле `type` в `teams`
- Таблиця `city_links`
- Seed дані для DAARION.city
2. **Оновити сервіси**:
- Wallet Service (перевірка стейкінгу)
- DAOFactory Service (перевірка 1 DAARION staked)
- PDP Service (політики для стейкінгу)
3. **Створити Console UI**:
- Сторінка `/console`
- Компоненти для створення MicroDAO
- Компоненти для перегляду списку
4. **Інтегрувати все разом**
---
## 📝 Наступні кроки
**Зараз:** Відповісти на питання вище
**Після відповідей:** Я створю детальний план реалізації та почну розробку
---
**Останнє оновлення:** 2024-11-14

160
IMPLEMENTATION_QUESTIONS.md Normal file
View File

@@ -0,0 +1,160 @@
# Питання для початку реалізації
## 1. Console / Адмін-панель
### 1.1 Що таке "console консоль"?
- Це окрема сторінка на `daarion.city/console`?
- Чи це вбудований віджет на існуючій сторінці?
- Чи це окремий піддомен `console.daarion.city`?
### 1.2 Які функції мають бути в console?
- Створення нового MicroDAO
- Перегляд списку існуючих MicroDAO
- Управління DAARION.city як SuperDAO
- Перегляд міських платформ (GREENFOOD, EnergyUnion, тощо)
- Wallet інтерфейс (баланси, стейкінг)
- Інші функції?
### 1.3 Технічний стек для console
- Це React компонент на існуючому сайті DAARION.city?
- Який фреймворк використовується (Next.js, Vite, інше)?
- Чи є вже існуючий код console, який потрібно розширити?
---
## 2. DAARION.city як перше MicroDAO + SuperDAO
### 2.1 Міські платформи
Які саме міські платформи вже існують та об'єднані з DAARION.city?
- GREENFOOD
- EnergyUnion
- WaterUnion
- Інші?
### 2.2 Як вони об'єднані?
- Через `city_links` таблицю з `parent_team_id = daarion-city`?
- Чи вони вже створені як MicroDAO типу "platform"?
- Чи потрібно їх створити зараз?
### 2.3 Відображення в console
- Як мають відображатися міські платформи в console?
- Як окремий розділ "Міські платформи"?
- Чи як частина дерева MicroDAO?
---
## 3. Створення MicroDAO користувачами
### 3.1 Порог для створення
**Уточнення:** В документації написано "1 DAAR або 0.01 DAARION", але ти кажеш "мінімум 1 DAARION у стейкінгу".
**Питання:**
- Правильно: **1 DAARION у стейкінгу** (не просто баланс)?
- Чи можна альтернатива: 1 DAAR у стейкінгу?
### 3.2 Перевірка стейкінгу
- Де зберігається інформація про стейкінг? (БД таблиця `staking`?)
- Як перевіряється стейкінг перед створенням MicroDAO?
- Чи потрібна перевірка через Wallet Service або on-chain?
### 3.3 UI для створення MicroDAO
- Це форма з полями (назва, опис, тип)?
- Чи діалог з агентом (як в `08_agent_first_onboarding.md`)?
- Які поля обов'язкові?
### 3.4 Після створення
- Автоматично створюється DAO через DAOFactory?
- Автоматично створюються токени GOV/UTIL/REP?
- Яка роль у створеного MicroDAO отримує користувач? (Owner?)
---
## 4. Роль Admin та 0.01 DAARION
### 4.1 Роль Admin
- Це роль в конкретному MicroDAO?
- Чи це глобальна роль в DAARION.city?
### 4.2 0.01 DAARION для Admin
- Це мінімум для отримання ролі Admin?
- Чи це мінімум для запрошення інших користувачів?
- Чи це мінімум для постійного використання (maintenance fee)?
### 4.3 Перевірка перед запрошенням
- Перевіряється баланс або стейкінг?
- Чи потрібна перевірка при кожному запрошенні?
---
## 5. Wallet та Staking
### 5.1 Інтеграція з Wallet
- Wallet Service вже реалізований?
- Як перевіряються баланси DAAR/DAARION?
- Чи потрібна інтеграція з on-chain контрактами?
### 5.2 Staking
- Де зберігається інформація про стейкінг? (таблиця `staking`?)
- Як перевіряється стейкінг для доступу?
- Чи потрібна інтеграція зі смарт-контрактами?
---
## 6. Технічні деталі
### 6.1 API Endpoints
- Чи є вже реалізовані API endpoints для:
- Створення MicroDAO
- Перевірки стейкінгу
- Wallet операцій
- Інші?
### 6.2 База даних
- Чи є вже міграції для:
- `teams` (MicroDAO)
- `staking`
- `wallets`
- `city_links`
- Інші?
### 6.3 PDP (Policy Decision Point)
- Чи потрібно інтегрувати перевірки стейкінгу в PDP?
- Які саме політики потрібні:
- `policy.microdao.create` (1 DAARION staked)
- `policy.admin.invite` (0.01 DAARION)
- Інші?
---
## 7. Пріоритети реалізації
Що реалізувати першим?
**Варіант A:**
1. Console UI (базова структура)
2. DAARION.city як перше MicroDAO (БД setup)
3. Створення MicroDAO користувачами (з перевіркою стейкінгу)
4. Admin роль та запрошення
**Варіант B:**
1. Backend: DAARION.city setup + API endpoints
2. Frontend: Console UI
3. Інтеграція Wallet/Staking перевірок
4. Створення MicroDAO flow
**Варіант C:**
Інший порядок?
---
## 8. Додаткові питання
- Чи є вже існуючий код console, який потрібно розширити?
- Чи потрібна інтеграція з існуючим сайтом DAARION.city?
- Які саме міські платформи вже працюють і потрібно їх відобразити?
- Чи є вже реалізований Wallet Service або потрібно створювати з нуля?
---
**Очікування:** Відповіді на ці питання допоможуть створити точний план реалізації та почати розробку.

120
IMPLEMENTATION_SUMMARY.md Normal file
View File

@@ -0,0 +1,120 @@
# Підсумок реалізації: Backend для MicroDAO
## ✅ Що зроблено
### 1. Wallet Service оновлено
-`hasEnoughForMicroDaoCreate()` - перевірка 1 DAARION на балансі (для створення MicroDAO)
-`hasEnoughForAdminRole()` - перевірка 1 DAARION на балансі (для ролі Admin)
-`hasEnoughForMicroDaoUsage()` - перевірка 0.01 DAARION на балансі (для використання сервісу)
-`getDaarionBalance()` - отримання балансу DAARION
- ✅ Legacy методи залишено для сумісності
### 2. DAOFactory Service оновлено
- ✅ Використовує `hasEnoughForMicroDaoCreate()` замість старого методу
- ✅ Перевірка 1 DAARION на балансі перед створенням MicroDAO
- ✅ Помилка: `INSUFFICIENT_BALANCE: Need 1 DAARION on balance to create MicroDAO`
### 3. Міграція БД створена
-`000010_teams_type_and_city_links.sql`
- ✅ Додано поле `type` в таблицю `teams` (city, platform, community, guild, lab, personal)
- ✅ Додано поле `parent_team_id` для ієрархічної структури
- ✅ Створено таблицю `city_links` для зв'язків між DAARION.city та платформами
- ✅ Seed дані для DAARION.city (id='daarion-city', type='city', slug='daarion')
### 4. API Endpoints створено
-`POST /api/v1/teams` - створення MicroDAO (з перевіркою 1 DAARION)
-`GET /api/v1/teams` - список teams/MicroDAO
-`GET /api/v1/teams/:teamId` - отримання team/MicroDAO
-`POST /api/v1/teams/:teamId/members` - запрошення користувача (з перевірками балансу)
### 5. Типи оновлено
-`Team` interface - додано поля `type`, `parent_team_id`, `slug`
-`CreateTeamRequest` interface - додано поля `type`, `slug`, `mode`
### 6. Логіка запрошення
- ✅ Admin може запросити користувача тільки якщо має 1 DAARION на балансі
- ✅ Для ролі Admin: запрошений користувач має мати 1 DAARION на балансі
- ✅ Для ролі Member: запрошений користувач має мати 0.01 DAARION на балансі
---
## 📋 Правила доступу (підсумок)
### Створення MicroDAO
- **Потрібно:** 1 DAARION на балансі (не стейкінг)
- **Результат:** Роль Admin у створеному MicroDAO
### Додавання Admin
- **Потрібно:**
- Поточний користувач: 1 DAARION на балансі
- Запрошений користувач: 1 DAARION на балансі
- **Результат:** Роль Admin у MicroDAO
### Запрошення Member
- **Потрібно:**
- Поточний користувач: 1 DAARION на балансі (Admin)
- Запрошений користувач: 0.01 DAARION на балансі
- **Результат:** Роль Member у MicroDAO
### Використання сервісу MicroDAO
- **Потрібно:** 0.01 DAARION на балансі
- **Результат:** Доступ до функцій MicroDAO
---
## 🔄 Наступні кроки
### Frontend (Console UI)
1. [ ] Створити сторінку `/console`
2. [ ] Компонент "Створити MicroDAO" (з перевіркою балансу)
3. [ ] Компонент "Список MicroDAO" (включаючи DAARION.city)
4. [ ] Компонент "Wallet" (баланси, перевірка доступу)
5. [ ] Компонент "Запросити користувача" (з перевірками балансу)
### Backend (доповнення)
1. [ ] Інтеграція з реальною БД (замість заглушок)
2. [ ] Створення team record при створенні MicroDAO
3. [ ] Створення team_member record при запрошенні
4. [ ] Отримання user_id з email при запрошенні
---
## 📝 Файли, які були змінені/створені
### Створені:
- `supabase/migrations/000010_teams_type_and_city_links.sql`
- `src/api/http/teams.routes.ts`
- `IMPLEMENTATION_SUMMARY.md`
### Оновлені:
- `src/services/wallet/wallet.service.ts`
- `src/services/wallet/wallet.interface.ts`
- `src/services/dao-factory/dao-factory.service.ts`
- `src/types/api.ts`
- `src/app.ts`
- `supabase/migrations/README.md`
---
## 🧪 Тестування
Для тестування потрібно:
1. **Застосувати міграцію:**
```bash
psql -d microdao -f supabase/migrations/000010_teams_type_and_city_links.sql
```
2. **Перевірити API endpoints:**
- `POST /api/v1/teams` - створення MicroDAO
- `POST /api/v1/teams/:teamId/members` - запрошення користувача
3. **Перевірити перевірки балансу:**
- Створення без достатнього балансу → помилка 403
- Запрошення Admin без достатнього балансу → помилка 403
- Запрошення Member без достатнього балансу → помилка 403
---
**Останнє оновлення:** 2024-11-14

77
scripts/sync-to-daarion-city.sh Executable file
View File

@@ -0,0 +1,77 @@
#!/bin/bash
# Скрипт для синхронізації файлів з MicroDAO до DAARION.city репозиторію
# Використання: ./scripts/sync-to-daarion-city.sh [component-name]
set -e
MICRODAO_DIR="/Users/apple/Desktop/MicroDAO/MicroDAO 3"
DAARION_CITY_DIR="/tmp/daarion-ai-city"
COMPONENT=${1:-"console"}
echo "🔄 Синхронізація компонента '$COMPONENT' до DAARION.city..."
# Перевірка наявності MicroDAO проєкту
if [ ! -d "$MICRODAO_DIR" ]; then
echo "❌ Помилка: MicroDAO проєкт не знайдено в $MICRODAO_DIR"
exit 1
fi
# Клонування/оновлення DAARION.city репозиторію
if [ ! -d "$DAARION_CITY_DIR" ]; then
echo "📦 Клонування DAARION.city репозиторію..."
git clone git@github.com:DAARION-DAO/daarion-ai-city.git "$DAARION_CITY_DIR"
else
echo "📥 Оновлення DAARION.city репозиторію..."
cd "$DAARION_CITY_DIR"
git fetch origin
git checkout main
git pull origin main
fi
# Створення гілки для змін
BRANCH_NAME="sync/microdao-${COMPONENT}-$(date +%Y%m%d-%H%M%S)"
cd "$DAARION_CITY_DIR"
git checkout -b "$BRANCH_NAME"
# Копіювання файлів залежно від компонента
case $COMPONENT in
console)
echo "📋 Копіювання Console компонентів..."
mkdir -p "$DAARION_CITY_DIR/src/components/console"
cp -r "$MICRODAO_DIR/src/components/console"/* "$DAARION_CITY_DIR/src/components/console/" 2>/dev/null || true
if [ -f "$MICRODAO_DIR/src/pages/ConsolePage.tsx" ]; then
cp "$MICRODAO_DIR/src/pages/ConsolePage.tsx" "$DAARION_CITY_DIR/src/pages/"
fi
;;
api)
echo "📋 Копіювання API клієнтів..."
mkdir -p "$DAARION_CITY_DIR/src/api"
cp -r "$MICRODAO_DIR/src/api"/* "$DAARION_CITY_DIR/src/api/" 2>/dev/null || true
;;
docs)
echo "📋 Копіювання документації..."
mkdir -p "$DAARION_CITY_DIR/docs/daarion"
cp -r "$MICRODAO_DIR/docs/daarion"/* "$DAARION_CITY_DIR/docs/daarion/" 2>/dev/null || true
;;
*)
echo "❌ Невідомий компонент: $COMPONENT"
echo "Доступні компоненти: console, api, docs"
exit 1
;;
esac
# Коміт та push
cd "$DAARION_CITY_DIR"
git add .
git commit -m "feat: sync MicroDAO $COMPONENT component" || echo " Немає змін для коміту"
echo "✅ Синхронізація завершена!"
echo "📝 Гілка: $BRANCH_NAME"
echo ""
echo "Наступні кроки:"
echo "1. Перевірити зміни: cd $DAARION_CITY_DIR && git diff main"
echo "2. Push гілку: git push -u origin $BRANCH_NAME"
echo "3. Створити PR через GitHub UI"

View File

@@ -0,0 +1,156 @@
/**
* Teams Routes (MicroDAO)
* Based on: api-mvp.md, updated for MicroDAO creation with balance checks
*
* Endpoints:
* - POST /api/v1/teams - Create MicroDAO (requires 1 DAARION on balance)
* - GET /api/v1/teams - List teams/MicroDAO
* - GET /api/v1/teams/:teamId - Get team/MicroDAO by ID
* - POST /api/v1/teams/:teamId/members - Invite member (requires balance check)
*/
import { Router } from 'express';
import { walletService } from '../../services/wallet/wallet.service';
import { daoFactoryService } from '../../services/dao-factory/dao-factory.service';
import type { CreateTeamRequest } from '../../../types/api';
export const teamsRoutes = Router();
// POST /api/v1/teams - Create MicroDAO
teamsRoutes.post('/', async (req, res) => {
try {
const userId = (req as any).userId;
const input: CreateTeamRequest = req.body;
// 1. Check wallet balance - need 1 DAARION on balance
const hasEnough = await walletService.hasEnoughForMicroDaoCreate(userId);
if (!hasEnough) {
res.status(403).json({
error: 'INSUFFICIENT_BALANCE',
message: 'Need 1 DAARION on balance to create MicroDAO',
required: { daarion: 1.0 },
});
return;
}
// 2. Create MicroDAO through DAOFactory
const daoResult = await daoFactoryService.createDao(userId, {
name: input.name,
description: input.description,
type: input.mode === 'confidential' ? 'private' : 'public',
level: 'A4', // User-created MicroDAO are A4 level
});
// 3. TODO: Create team record in database
// For now, return DAO result
res.status(201).json({
id: daoResult.daoId,
name: input.name,
description: input.description,
mode: input.mode || 'public',
type: input.type || 'community',
created_at: new Date().toISOString(),
});
} catch (error: any) {
res.status(400).json({
error: error.message?.includes('INSUFFICIENT_BALANCE') ? 'INSUFFICIENT_BALANCE' : 'BAD_REQUEST',
message: error.message,
});
}
});
// GET /api/v1/teams - List teams/MicroDAO
teamsRoutes.get('/', async (req, res) => {
try {
const userId = (req as any).userId;
// TODO: Get teams from database
// For now, return empty list
res.json({ teams: [] });
} catch (error: any) {
res.status(500).json({
error: 'INTERNAL_ERROR',
message: error.message,
});
}
});
// GET /api/v1/teams/:teamId - Get team/MicroDAO by ID
teamsRoutes.get('/:teamId', async (req, res) => {
try {
const { teamId } = req.params;
// TODO: Get team from database
res.status(404).json({
error: 'NOT_FOUND',
message: `Team ${teamId} not found`,
});
} catch (error: any) {
res.status(500).json({
error: 'INTERNAL_ERROR',
message: error.message,
});
}
});
// POST /api/v1/teams/:teamId/members - Invite member
teamsRoutes.post('/:teamId/members', async (req, res) => {
try {
const userId = (req as any).userId; // Current user (admin)
const { teamId } = req.params;
const { email, role = 'member' } = req.body;
// 1. Check if current user is admin (has 1 DAARION)
const isAdmin = await walletService.hasEnoughForAdminRole(userId);
if (!isAdmin) {
res.status(403).json({
error: 'ACCESS_DENIED',
message: 'Need 1 DAARION on balance to invite members',
});
return;
}
// 2. Check invited user balance based on role
// TODO: Get invited user ID from email
const invitedUserId = `user_${email}`; // Placeholder
if (role === 'admin') {
// Admin role requires 1 DAARION
const hasEnough = await walletService.hasEnoughForAdminRole(invitedUserId);
if (!hasEnough) {
res.status(403).json({
error: 'INSUFFICIENT_BALANCE',
message: 'Invited user needs 1 DAARION on balance to be Admin',
required: { daarion: 1.0 },
});
return;
}
} else {
// Member role requires 0.01 DAARION
const hasEnough = await walletService.hasEnoughForMicroDaoUsage(invitedUserId);
if (!hasEnough) {
res.status(403).json({
error: 'INSUFFICIENT_BALANCE',
message: 'Invited user needs 0.01 DAARION on balance to use MicroDAO',
required: { daarion: 0.01 },
});
return;
}
}
// 3. TODO: Create team member record in database
res.status(201).json({
team_id: teamId,
user_id: invitedUserId,
email,
role,
status: 'invited',
});
} catch (error: any) {
res.status(400).json({
error: 'BAD_REQUEST',
message: error.message,
});
}
});

View File

@@ -14,6 +14,7 @@ import { pdpRoutes } from './api/http/pdp.routes';
import { vendorRoutes } from './api/http/vendor.routes';
import { platformsRoutes } from './api/http/platforms.routes';
import { agentsRoutes } from './api/http/agents.routes';
import { teamsRoutes } from './api/http/teams.routes';
const app = express();
@@ -24,6 +25,7 @@ app.use(contextMiddleware);
// Routes
app.use('/api/v1/dao', daoRoutes);
app.use('/api/v1/teams', teamsRoutes);
app.use('/api/v1/wallet', walletRoutes);
app.use('/api/v1/pdp', pdpRoutes);
app.use('/api/v1/platforms', platformsRoutes);

View File

@@ -18,12 +18,13 @@ import { registryService } from '../registry/registry.service';
export class DaoFactoryService {
/**
* Create a new MicroDAO (A3 or A4)
* Requires: 1 DAARION on balance (not staked)
*/
async createDao(userId: string, input: CreateDaoInput): Promise<{ daoId: string }> {
// 1. Check wallet balance
const hasEnough = await walletService.hasEnoughForDaoCreate(userId);
// 1. Check wallet balance - need 1 DAARION on balance
const hasEnough = await walletService.hasEnoughForMicroDaoCreate(userId);
if (!hasEnough) {
throw new Error('INSUFFICIENT_BALANCE: Need 1 DAAR or 0.01 DAARION');
throw new Error('INSUFFICIENT_BALANCE: Need 1 DAARION on balance to create MicroDAO');
}
// 2. Check PDP policy

View File

@@ -1,12 +1,20 @@
/**
* Wallet Service Interface
* Based on: core-services-mvp.md
* Based on: core-services-mvp.md, updated for MicroDAO requirements
*/
import type { Balance } from '../../domain/wallet/types';
export interface WalletService {
getBalances(userId: string): Promise<Balance[]>;
getDaarionBalance(userId: string): Promise<number>;
// MicroDAO access checks (balance-based, no staking)
hasEnoughForMicroDaoCreate(userId: string): Promise<boolean>; // 1 DAARION
hasEnoughForAdminRole(userId: string): Promise<boolean>; // 1 DAARION
hasEnoughForMicroDaoUsage(userId: string): Promise<boolean>; // 0.01 DAARION
// Legacy methods (deprecated)
hasEnoughForDaoCreate(userId: string): Promise<boolean>;
hasEnoughForVendorRegister(userId: string): Promise<boolean>;
hasEnoughForPlatformCreate(userId: string): Promise<boolean>;

View File

@@ -20,38 +20,62 @@ export class WalletService implements IWalletService {
}
/**
* Check if user has enough tokens to create a DAO
* Requires: 1 DAAR OR 0.01 DAARION
* Check if user has enough DAARION to create a MicroDAO
* Requires: 1 DAARION on balance (not staked)
*/
async hasEnoughForMicroDaoCreate(userId: string): Promise<boolean> {
const balances = await this.getBalances(userId);
const daarion = balances.find(b => b.symbol === 'DAARION');
return daarion ? parseFloat(daarion.amount) >= 1.0 : false;
}
/**
* Check if user has enough DAARION to be Admin
* Requires: 1 DAARION on balance (not staked)
*/
async hasEnoughForAdminRole(userId: string): Promise<boolean> {
return this.hasEnoughForMicroDaoCreate(userId);
}
/**
* Check if user has enough DAARION to use MicroDAO service
* Requires: 0.01 DAARION on balance (not staked)
*/
async hasEnoughForMicroDaoUsage(userId: string): Promise<boolean> {
const balances = await this.getBalances(userId);
const daarion = balances.find(b => b.symbol === 'DAARION');
return daarion ? parseFloat(daarion.amount) >= 0.01 : false;
}
/**
* Get DAARION balance for user
*/
async getDaarionBalance(userId: string): Promise<number> {
const balances = await this.getBalances(userId);
const daarion = balances.find(b => b.symbol === 'DAARION');
return daarion ? parseFloat(daarion.amount) : 0;
}
// Legacy methods (deprecated, kept for backward compatibility)
/**
* @deprecated Use hasEnoughForMicroDaoCreate instead
*/
async hasEnoughForDaoCreate(userId: string): Promise<boolean> {
const balances = await this.getBalances(userId);
const daar = balances.find(b => b.symbol === 'DAAR');
const daarion = balances.find(b => b.symbol === 'DAARION');
// Check: 1 DAAR OR 0.01 DAARION
const hasEnoughDaar = daar && parseFloat(daar.amount) >= 1.0;
const hasEnoughDaarion = daarion && parseFloat(daarion.amount) >= 0.01;
return hasEnoughDaar || hasEnoughDaarion;
return this.hasEnoughForMicroDaoCreate(userId);
}
/**
* Check if user has enough staked DAARION for vendor registration
* Requires: 0.01 DAARION staked
* @deprecated Not used in current implementation
*/
async hasEnoughForVendorRegister(userId: string): Promise<boolean> {
const staked = await walletAdapter.getStakedDaarion(userId);
return staked >= 0.01;
return this.hasEnoughForMicroDaoUsage(userId);
}
/**
* Check if user has enough staked DAARION for platform creation
* Requires: 1 DAARION staked
* @deprecated Not used in current implementation
*/
async hasEnoughForPlatformCreate(userId: string): Promise<boolean> {
const staked = await walletAdapter.getStakedDaarion(userId);
return staked >= 1.0;
return this.hasEnoughForMicroDaoCreate(userId);
}
}

View File

@@ -12,15 +12,21 @@ export interface User {
export interface Team {
id: string;
name: string;
slug: string;
description: string | null;
mode: 'public' | 'confidential';
type?: 'city' | 'platform' | 'community' | 'guild' | 'lab' | 'personal';
parent_team_id?: string | null;
created_at: string;
updated_at: string;
}
export interface CreateTeamRequest {
name: string;
slug?: string;
description?: string;
type?: 'community' | 'guild' | 'lab' | 'personal';
mode?: 'public' | 'confidential';
}
export interface UpdateTeamRequest {

View File

@@ -0,0 +1,50 @@
-- 000010_teams_type_and_city_links.sql
-- Add type field to teams and city_links table for DAARION.city integration
-- Up
-- Add type field to teams table
alter table teams
add column if not exists type text check (type in ('city', 'platform', 'community', 'guild', 'lab', 'personal'));
-- Add index for type
create index if not exists idx_teams_type on teams(type);
-- Add parent_team_id for hierarchical structure (DAARION.city -> platforms -> microDAO)
alter table teams
add column if not exists parent_team_id text references teams(id) on delete set null;
-- Add index for parent_team_id
create index if not exists idx_teams_parent_team_id on teams(parent_team_id);
-- Create city_links table for explicit relationships
create table if not exists city_links (
id text primary key,
parent_team_id text not null references teams(id) on delete cascade,
child_team_id text not null references teams(id) on delete cascade,
relation_type text not null check (relation_type in ('platform', 'microdao', 'subdao')),
created_at timestamptz not null default now(),
unique (parent_team_id, child_team_id)
);
create index if not exists idx_city_links_parent_team_id on city_links(parent_team_id);
create index if not exists idx_city_links_child_team_id on city_links(child_team_id);
-- Insert DAARION.city as first MicroDAO (type='city')
insert into teams (id, name, slug, mode, type, parent_team_id, created_at)
values (
'daarion-city',
'DAARION.city',
'daarion',
'public',
'city',
null,
now()
)
on conflict (slug) do nothing;
-- Down
drop table if exists city_links cascade;
alter table teams drop column if exists parent_team_id;
alter table teams drop column if exists type;

View File

@@ -17,7 +17,8 @@ SQL-міграції для схеми бази даних microDAO/DAARION.city
7. `000007_embassy.sql` - Embassy Module (identities, webhooks, oracles)
8. `000008_access_keys_capabilities.sql` - Access Keys, Capabilities, Bundles
9. `000009_audit_outbox.sql` - Audit Log, Outbox Events
10. `seeds.sql` - Seed data для bundles, capabilities та bundle mappings (запускати після всіх міграцій)
10. `000010_teams_type_and_city_links.sql` - Teams type field, city_links, DAARION.city seed
11. `seeds.sql` - Seed data для bundles, capabilities та bundle mappings (запускати після всіх міграцій)
---