Update README files for local-first architecture and production deploy.

Document VITE_DATA_MODE, frontend layers, containerized deploy flow,
and refresh deploy guide with git clone, build flags, and troubleshooting.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-29 16:18:39 +03:00
co-authored by Cursor
parent 5e0af42fce
commit 2a32c61934
2 changed files with 169 additions and 86 deletions
+98 -60
View File
@@ -1,19 +1,34 @@
# Social Graph Builder # Social Graph Builder
Построитель социального графа: импорт контактов, визуализация связей, CRUD. Построитель социального графа: импорт контактов, визуализация связей, CRUD, карта сети.
По умолчанию приложение работает в режиме **local-first**: данные хранятся в браузере (IndexedDB), backend для обычной работы не обязателен.
## Стек ## Стек
| Слой | Технология | | Слой | Технология |
|------|-----------| |------|-----------|
| Backend API | Django 4.2 + Django REST Framework | | Frontend | Vue 3 + Vite + Pinia |
| База данных | SQLite | | Локальное хранилище | IndexedDB (Dexie) |
| Frontend | Vue.js 3 + Vite | | Backend API (опционально) | Django 4.2 + DRF |
| Граф | vis-network | | БД backend | SQLite |
| Состояние | Pinia | | Граф / карта | vis-network |
| Запуск | Docker Compose | | Dev-запуск | Docker Compose |
| Production | Docker Compose + прокси на хосте |
## Быстрый старт ## Режимы данных
Переключатель: `VITE_DATA_MODE` (задаётся при **сборке** фронта).
| Режим | Описание |
|-------|----------|
| `local` (по умолчанию) | IndexedDB в браузере, максимум конфиденциальности |
| `remote` | Django API + SQLite на сервере |
| `hybrid` | зарезервирован для будущей синхронизации |
Пример для production: см. `deploy/.env.prod.example`.
## Быстрый старт (разработка)
```bash ```bash
git clone <repo> git clone <repo>
@@ -21,10 +36,51 @@ cd social-graph
docker compose up --build docker compose up --build
``` ```
- Frontend: http://localhost:5173 - Frontend (Vite): http://localhost:5173
- Backend API: http://localhost:8000/api/ - Backend API: http://localhost:8000/api/ (для `remote` или legacy)
## API endpoints Страницы: `/graph`, `/map`, `/contacts`, `/import`.
## Архитектура frontend
```text
views / components
Pinia store (orchestration)
application/usecases
infrastructure/repositories → local (IndexedDB) | remote (REST)
changelog + syncAdapter (noop, подготовка к sync)
```
## Структура проекта
```text
social-graph/
├── backend/ # Django API (опционально)
│ ├── contacts/
│ ├── config/
│ ├── Dockerfile # dev
│ └── Dockerfile.prod # gunicorn
├── frontend/
│ ├── src/
│ │ ├── application/usecases/
│ │ ├── infrastructure/ # db, repositories, sync, config
│ │ ├── domain/
│ │ ├── views/ # Graph, NetworkMap, Contacts, Import
│ │ ├── stores/
│ │ └── components/
│ ├── Dockerfile # dev (Vite)
│ ├── Dockerfile.prod # build + nginx
│ └── nginx.conf
├── deploy/ # production: Apache, env, инструкции
├── docker-compose.yml # dev
└── docker-compose.prod.yml # production
```
## API endpoints (backend, режим remote)
| Метод | URL | Описание | | Метод | URL | Описание |
|-------|-----|----------| |-------|-----|----------|
@@ -32,65 +88,36 @@ docker compose up --build
| GET/PATCH/DELETE | `/api/contacts/{id}/` | Контакт по ID | | GET/PATCH/DELETE | `/api/contacts/{id}/` | Контакт по ID |
| GET/POST | `/api/relations/` | Список / создание связей | | GET/POST | `/api/relations/` | Список / создание связей |
| DELETE | `/api/relations/{id}/` | Удалить связь | | DELETE | `/api/relations/{id}/` | Удалить связь |
| GET | `/api/graph/` | Граф (nodes + edges для vis.js) | | GET | `/api/graph/` | Граф для vis.js |
| GET | `/api/network-map-graph/` | Граф карты сети |
| GET | `/api/relation-types/` | Типы связей | | GET | `/api/relation-types/` | Типы связей |
| POST | `/api/import/` | Импорт CSV/JSON | | GET | `/api/network-map-choices/` | Справочники карты |
| POST | `/api/import/` | Импорт CSV/JSON (legacy) |
## Формат CSV для импорта В режиме `local` импорт и бэкап выполняются в браузере (экран **Импорт**).
```csv ## Импорт и бэкап (local-first)
name,email,phone,organization,position,notes
Иван Иванов,ivan@example.com,+7-900-000-0001,ООО Ромашка,Директор,
Мария Петрова,maria@example.com,+7-900-000-0002,Газпром,Аналитик,
```
## Формат JSON для импорта - **CSV / JSON** — экран «Импорт», парсинг на клиенте.
- **Экспорт / импорт бэкапа** — JSON или зашифрованный `.sgpkg` (WebCrypto, пароль опционален).
```json ## Production
[
{"name": "Иван Иванов", "email": "ivan@example.com", "organization": "ООО Ромашка"},
{"name": "Мария Петрова", "phone": "+7-900-000-0002"}
]
```
## Структура проекта Подробно: [deploy/README.md](deploy/README.md).
```
social-graph/
├── backend/
│ ├── config/ # Django settings, urls
│ ├── contacts/ # models, serializers, views, urls
│ ├── manage.py
│ ├── requirements.txt
│ └── Dockerfile
├── frontend/
│ ├── src/
│ │ ├── views/ # GraphView, ContactsView, ContactDetailView, ImportView
│ │ ├── components/ # ContactForm
│ │ ├── stores/ # Pinia store (contacts)
│ │ ├── router/ # Vue Router
│ │ ├── api.js # Axios instance
│ │ └── App.vue
│ ├── vite.config.js
│ └── Dockerfile
└── docker-compose.yml
```
## Production (Docker + прокси на хосте)
См. [deploy/README.md](deploy/README.md).
Кратко:
```bash ```bash
git clone <repo> /opt/social-graph && cd /opt/social-graph
cp deploy/.env.prod.example deploy/.env.prod cp deploy/.env.prod.example deploy/.env.prod
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d frontend docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d --build frontend
# прокси на хосте → http://127.0.0.1:8080 (см. deploy/apache/social-graph.conf) # прокси на хосте → http://127.0.0.1:8080
``` ```
Схема: прокси на хосте (Apache/nginx) → контейнер frontend (nginx); backend — только при `VITE_DATA_MODE=remote`.
## Запуск без Docker ## Запуск без Docker
**Backend:** **Backend:**
```bash ```bash
cd backend cd backend
pip install -r requirements.txt pip install -r requirements.txt
@@ -99,20 +126,31 @@ python manage.py runserver
``` ```
**Frontend:** **Frontend:**
```bash ```bash
cd frontend cd frontend
npm install npm install
npm run dev npm run dev
``` ```
> В `vite.config.js` прокси настроен на `http://backend:8000`. > В `vite.config.js` прокси `/api` указывает на `http://backend:8000`.
> При локальном запуске без Docker замените на `http://localhost:8000`. > Без Docker замените на `http://localhost:8000`.
## Планируемые фичи (следующие итерации) Для local-first backend не нужен.
## Тесты
```bash
cd frontend && npm test
# или в контейнере:
docker compose exec frontend npm test -- --run
```
## Планируемые фичи
- [ ] Авторизация (Django auth + JWT) - [ ] Авторизация (Django auth + JWT)
- [ ] Теги/группы контактов - [ ] Теги/группы контактов
- [ ] Экспорт в CSV/JSON - [ ] Синхронизация и shared-workspace
- [ ] Поиск по организации и должности - [ ] Поиск по организации и должности
- [ ] История изменений контакта - [ ] История изменений контакта
- [ ] Импорт из vCard (.vcf) - [ ] Импорт из vCard (.vcf)
+71 -26
View File
@@ -1,30 +1,40 @@
# Production deploy (контейнеры + прокси на хосте) # Production deploy (контейнеры + прокси на хосте)
Схема: ## Схема
```text ```text
[Прокси на хосте :80/:443] [Прокси на хосте :80/:443]
→ frontend-контейнер (nginx :8080 на хосте) → frontend-контейнер (nginx, 127.0.0.1:8080)
→ backend-контейнер (gunicorn :8000, только при remote) → backend-контейнер (gunicorn, 127.0.0.1:8000 только при remote)
``` ```
SPA-маршрутизация (`try_files``index.html`) выполняется **внутри** frontend-контейнера. SPA-маршрутизация (`try_files``index.html`) **внутри** frontend-контейнера (`frontend/nginx.conf`).
## 1. Подготовка ## 1. Клонирование и подготовка
```bash ```bash
git clone <repo-url> /opt/social-graph
cd /opt/social-graph cd /opt/social-graph
git checkout main # или нужная ветка
cp deploy/.env.prod.example deploy/.env.prod cp deploy/.env.prod.example deploy/.env.prod
# отредактируйте deploy/.env.prod при необходимости # отредактируйте deploy/.env.prod
``` ```
## 2. Local-first (только frontend) `deploy/.env.prod` в git не коммитится (секреты и локальные порты).
Рекомендуется для конфиденциальности — данные в браузере (IndexedDB). ## 2. Local-first (рекомендуется)
Данные пользователя — в браузере (IndexedDB). Backend на сервере **не поднимать**.
В `deploy/.env.prod`:
```env
VITE_DATA_MODE=local
```
```bash ```bash
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod build frontend docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d --build frontend
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d frontend
``` ```
Проверка: Проверка:
@@ -41,51 +51,86 @@ curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/
```bash ```bash
sudo a2enmod proxy proxy_http headers sudo a2enmod proxy proxy_http headers
sudo cp deploy/apache/social-graph.conf /etc/apache2/sites-available/social-graph.conf sudo cp deploy/apache/social-graph.conf /etc/apache2/sites-available/social-graph.conf
# ServerName и порты (8080 / 8000) — по вашему .env.prod ```
Отредактируйте `ServerName` и при необходимости порты (`FRONTEND_PORT` / `BACKEND_PORT` из `.env.prod`).
```bash
sudo a2ensite social-graph.conf sudo a2ensite social-graph.conf
sudo apache2ctl configtest sudo apache2ctl configtest
sudo systemctl reload apache2 sudo systemctl reload apache2
``` ```
HTTPS:
```bash
sudo certbot --apache -d your-domain.com
```
### nginx на хосте ### nginx на хосте
См. `deploy/proxy/nginx-host.conf.example`. См. `deploy/proxy/nginx-host.conf.example`.
## 4. Remote mode (frontend + backend) ## 4. Remote mode (frontend + backend)
В `deploy/.env.prod`: Общая БД на сервере. В `deploy/.env.prod`:
```env ```env
VITE_DATA_MODE=remote VITE_DATA_MODE=remote
DJANGO_SECRET_KEY=... DJANGO_SECRET_KEY=длинный-случайный-ключ
ALLOWED_HOSTS=your-domain.com ALLOWED_HOSTS=your-domain.com,www.your-domain.com
``` ```
Пересоберите frontend (режим зашивается при build) и поднимите оба сервиса: Пересоберите frontend (режим зашивается при build) и поднимите оба сервиса:
```bash ```bash
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod build docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod build
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d frontend docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d --build frontend
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod --profile with-backend up -d backend docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod --profile with-backend up -d --build backend
``` ```
В `deploy/apache/social-graph.conf` раскомментируйте блок `ProxyPass /api ...` **перед** `ProxyPass /`. В `deploy/apache/social-graph.conf` раскомментируйте `ProxyPass /api ...` **выше** блока `ProxyPass /`.
```bash
sudo a2enmod proxy proxy_http headers
sudo systemctl reload apache2
```
## 5. Обновление ## 5. Обновление
```bash ```bash
cd /opt/social-graph
git pull git pull
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod build frontend docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d --build frontend
docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod up -d frontend # при remote:
# при remote — также build/up backend # docker compose -f docker-compose.prod.yml --env-file deploy/.env.prod --profile with-backend up -d --build backend
sudo systemctl reload apache2 # или nginx -s reload sudo systemctl reload apache2 # или: sudo nginx -s reload
``` ```
## Порты по умолчанию ## Порты по умолчанию
| Сервис | Хост (loopback) | Внутри контейнера | | Переменная | Значение | Назначение |
|----------|-----------------|-------------------| |------------|----------|------------|
| frontend | 127.0.0.1:8080 | nginx :80 | | `FRONTEND_PORT` | 8080 | nginx в контейнере `sg_frontend` |
| backend | 127.0.0.1:8000 | gunicorn :8000 | | `BACKEND_PORT` | 8000 | gunicorn в контейнере `sg_backend` |
| `FRONTEND_BIND` | 127.0.0.1 | только loopback на хосте |
Наружу открыт только прокси на хосте (80/443). Наружу открыт только прокси (80/443).
## Миграция данных
| Источник | Действие |
|----------|----------|
| CSV/JSON | UI → Импорт |
| Старый Django SQLite | экспорт JSON → Импорт |
| Локальный бэкап `.json` / `.sgpkg` | UI → «Импорт бэкапа» |
## Устранение неполадок
```bash
docker compose -f docker-compose.prod.yml ps
docker logs sg_frontend --tail 50
docker logs sg_backend --tail 50 # если поднят
```
Конфликт имени контейнера с dev: остановите `docker compose down` в том же каталоге перед prod-запуском.