feat(db-hardening): Add database persistence, backups, and MinIO assets storage

Database Hardening:
- Add docker-compose.db.yml with persistent PostgreSQL volume
- Add automatic DB backups every 12h (7 days, 4 weeks, 6 months retention)
- Add MinIO S3-compatible storage for assets

Assets Migration:
- Add MinIO client (lib/assets_client.py) for upload/delete
- Update upload endpoint to use MinIO (with local fallback)
- Add migration 043_asset_urls_to_text.sql for full HTTPS URLs
- Simplify normalizeAssetUrl for S3 URLs

Recovery:
- Add seed_full_city_reset.py for emergency city recovery
- Add DB_RESTORE.md with backup restore instructions
- Add SEED_RECOVERY.md with recovery procedures
- Add INFRA_ASSETS_MINIO.md with MinIO setup guide

Task: TASK_PHASE_DATABASE_HARDENING_AND_ASSETS_MIGRATION_v1
This commit is contained in:
Apple
2025-12-02 01:56:39 -08:00
parent 0e743e5629
commit 8e8f95e9ef
11 changed files with 1541 additions and 33 deletions

230
docs/SEED_RECOVERY.md Normal file
View File

@@ -0,0 +1,230 @@
# SEED_RECOVERY — Аварійне відновлення міста
## Коли використовувати
Цей процес використовується коли:
- База даних була повністю втрачена
- Немає доступних бекапів
- Потрібно швидко відновити мінімально робочий стан DAARION City
---
## Крок 1: Переконатися що база порожня
```bash
# Перевірити чи є дані
docker exec daarion-postgres psql -U postgres -d daarion -c "SELECT COUNT(*) FROM microdao;"
# Якщо є дані - очистити (ОБЕРЕЖНО!)
docker exec daarion-postgres psql -U postgres -d daarion -c "TRUNCATE TABLE microdao, agents, city_rooms CASCADE;"
```
---
## Крок 2: Застосувати міграції
```bash
cd /opt/microdao-daarion
# Застосувати всі міграції
for f in migrations/*.sql; do
echo "Applying: $f"
docker exec -i daarion-postgres psql -U postgres -d daarion < "$f" 2>&1 | grep -v "ERROR\|NOTICE" || true
done
```
---
## Крок 3: Запустити seed-скрипт
```bash
# Встановити змінні оточення
export DATABASE_URL="postgresql://postgres:postgres@localhost:5432/daarion"
# Запустити seed
python3 scripts/seed_full_city_reset.py
```
Очікуваний вивід:
```
🏙️ DAARION City Emergency Recovery
============================================================
🔗 Connecting to database...
✅ Connected
📦 Seeding MicroDAOs...
✅ DAARION DAO
✅ Energy Union
✅ GreenFood DAO
✅ Soul Retreat Hub
✅ Seeded 4 MicroDAOs
🤖 Seeding core agents (NODE1)...
✅ DAARWIZZ
✅ Helion
✅ GreenFood Bot
✅ Soul Bot
✅ Seeded 4 core agents
🔗 Linking agents to MicroDAOs...
✅ Linked daarwizz → dao_daarion
✅ Linked helion → dao_energy
✅ Linked greenfood → dao_greenfood
✅ Linked soul → dao_soul
✅ Linked agents to MicroDAOs
============================================================
✅ Recovery complete!
MicroDAOs: 4
Agents: 4
📝 Next steps:
1. Run migrations if needed
2. Run scripts/sync-node2-dagi-agents.py for NODE2 agents
3. Upload logos/banners to MinIO if not already done
============================================================
```
---
## Крок 4: Відновити DAGI-агентів NODE2
```bash
python3 scripts/sync-node2-dagi-agents.py
```
Це додасть ~50 DAGI-агентів для NODE2 з `config/agents_city_mapping.yaml`.
---
## Крок 5: Перевірити відновлення
### Перевірка MicroDAOs
```bash
docker exec daarion-postgres psql -U postgres -d daarion -c "
SELECT slug, name, district, is_platform
FROM microdao
ORDER BY pinned_weight;
"
```
Очікуваний результат:
```
slug | name | district | is_platform
--------------+-----------------+----------+-------------
daarion | DAARION DAO | Core | t
energy-union | Energy Union | Energy | t
greenfood | GreenFood DAO | Green | t
soul-retreat | Soul Retreat Hub| Soul | t
```
### Перевірка агентів
```bash
docker exec daarion-postgres psql -U postgres -d daarion -c "
SELECT COUNT(*) as total,
COUNT(*) FILTER (WHERE node_id = 'node-1-hetzner-gex44') as node1,
COUNT(*) FILTER (WHERE node_id = 'node-2-macbook-m4max') as node2
FROM agents;
"
```
### Перевірка через API
```bash
# MicroDAOs
curl -s "https://daarion.space/api/city/microdao?limit=4" | python3 -m json.tool | head -20
# Agents
curl -s "https://daarion.space/api/city/agents?limit=5" | python3 -m json.tool | head -20
```
---
## Крок 6: Завантажити логотипи/банери в MinIO (якщо потрібно)
Якщо логотипи ще не завантажені в MinIO:
1. Відкрити MinIO Console: `http://localhost:9001` (або `https://minio.daarion.space`)
2. Створити bucket `daarion-assets` (якщо не існує)
3. Завантажити файли:
- `microdao/logo/daarion.png`
- `microdao/logo/energy-union.png`
- `microdao/logo/greenfood.png`
- `microdao/logo/soul-retreat.png`
4. Встановити public read policy для bucket
Або використати MinIO CLI:
```bash
# Встановити mc (MinIO Client)
# https://min.io/docs/minio/linux/reference/minio-mc.html
# Налаштувати alias
mc alias set local http://localhost:9000 assets-admin <password>
# Завантажити файли
mc cp ./assets/logos/daarion.png local/daarion-assets/microdao/logo/daarion.png
mc cp ./assets/logos/energy-union.png local/daarion-assets/microdao/logo/energy-union.png
# ... і т.д.
```
---
## Що відновлюється
### ✅ Відновлюється seed-скриптом:
- 4 базові MicroDAOs (DAARION, Energy Union, GreenFood, Soul)
- 4 core агентів NODE1 (DAARWIZZ, Helion, GreenFood Bot, Soul Bot)
- Зв'язки агентів з MicroDAOs
### ❌ НЕ відновлюється автоматично:
- City Rooms (потрібно запустити `scripts/seed_city_rooms.py`)
- DAGI-агенти NODE2 (потрібно запустити `scripts/sync-node2-dagi-agents.py`)
- Node cache дані (відновляться через heartbeat)
- Логотипи/банери файли (потрібно завантажити в MinIO)
---
## Швидкий чекліст
- [ ] База даних створена та порожня
- [ ] Всі міграції застосовані
- [ ] `seed_full_city_reset.py` виконано успішно
- [ ] `sync-node2-dagi-agents.py` виконано (для NODE2)
- [ ] Логотипи завантажені в MinIO
- [ ] API повертає дані
- [ ] Frontend відображає MicroDAOs та агентів
---
## Troubleshooting
### Помилка: "relation does not exist"
Міграції не застосовані. Запустити Крок 2.
### Помилка: "duplicate key value"
Дані вже існують. Seed-скрипт використовує `ON CONFLICT`, тому це нормально.
### Помилка: "connection refused"
PostgreSQL не запущений:
```bash
docker compose -f docker-compose.db.yml up -d db
```
### Логотипи не відображаються
1. Перевірити що файли в MinIO
2. Перевірити що bucket має public read policy
3. Перевірити що URL в БД правильні:
```bash
docker exec daarion-postgres psql -U postgres -d daarion -c "SELECT slug, logo_url FROM microdao;"
```