13 KiB
13 KiB
Архитектура MVP: ERP для мастеров
🏗️ Общая архитектура
graph TB
subgraph "Frontend"
A[Angular PWA]
B[QR Scanner]
end
subgraph "Backend Services"
C[Go Core Service]
D[Python Document Service]
end
subgraph "Infrastructure"
E[PostgreSQL]
F[Redis Cache]
end
A <--> C
B --> A
C <--> E
C <--> D
D <--> F
style A fill:#ff9999
style C fill:#99ccff
style D fill:#99ff99
style E fill:#ffcc99
style F fill:#cc99ff
🛠️ Технологический стек
Backend (Go)
- Framework: Gin (легкий и быстрый)
- Database: PostgreSQL
- Authentication: JWT
- Validation: validator
- Inter-service Communication: gRPC + Protocol Buffers
- API Documentation: Swagger/OpenAPI
Frontend (Angular PWA)
- Framework: Angular 17+
- Build Tool: Angular CLI
- PWA: @angular/service-worker
- QR Scanner: @zxing/ngx-scanner
- UI: Angular Material + Tailwind CSS
- State Management: NgRx (для сложной логики)
Document Service (Python)
- Framework: FastAPI (быстрый, автоматическая документация)
- PDF Generation: reportlab + weasyprint
- Office Documents: python-docx, openpyxl
- Templates: Jinja2
- Caching: Redis
- Inter-service Communication: gRPC
Infrastructure
- Containerization: Docker
- Orchestration: Docker Compose
- Inter-service Communication: gRPC + Protocol Buffers
- API Gateway: Traefik (опционально)
- Security: HTTPS, CORS, JWT
- Monitoring: Structured logging + Prometheus
📊 Структура базы данных
ER-диаграмма
erDiagram
organizations {
uuid id PK
varchar name
varchar type
jsonb settings
timestamp created_at
}
users {
uuid id PK
uuid organization_id FK
varchar email
varchar role
timestamp created_at
}
storage_locations {
uuid id PK
uuid organization_id FK
uuid parent_id FK
varchar name
varchar address
varchar type
jsonb coordinates
varchar qr_code
timestamp created_at
}
items {
uuid id PK
uuid organization_id FK
varchar name
text description
varchar category
timestamp created_at
}
item_placements {
uuid id PK
uuid organization_id FK
uuid item_id FK
uuid location_id FK
integer quantity
timestamp created_at
}
organizations ||--o{ users : "has"
organizations ||--o{ storage_locations : "has"
organizations ||--o{ items : "has"
organizations ||--o{ item_placements : "has"
storage_locations ||--o{ storage_locations : "parent-child"
storage_locations ||--o{ item_placements : "contains"
items ||--o{ item_placements : "placed_in"
Основные таблицы
-- Организации
CREATE TABLE organizations (
id UUID PRIMARY KEY,
name VARCHAR(255) NOT NULL,
type VARCHAR(100),
settings JSONB,
created_at TIMESTAMP DEFAULT NOW()
);
-- Пользователи
CREATE TABLE users (
id UUID PRIMARY KEY,
organization_id UUID REFERENCES organizations(id),
email VARCHAR(255) UNIQUE NOT NULL,
role VARCHAR(50) DEFAULT 'user',
created_at TIMESTAMP DEFAULT NOW()
);
-- Места хранения
CREATE TABLE storage_locations (
id UUID PRIMARY KEY,
organization_id UUID REFERENCES organizations(id),
parent_id UUID REFERENCES storage_locations(id),
name VARCHAR(255) NOT NULL,
address VARCHAR(100) NOT NULL,
type VARCHAR(50) NOT NULL,
coordinates JSONB,
qr_code VARCHAR(255),
created_at TIMESTAMP DEFAULT NOW()
);
-- Товары
CREATE TABLE items (
id UUID PRIMARY KEY,
organization_id UUID REFERENCES organizations(id),
name VARCHAR(255) NOT NULL,
description TEXT,
category VARCHAR(100),
created_at TIMESTAMP DEFAULT NOW()
);
-- Размещение товаров
CREATE TABLE item_placements (
id UUID PRIMARY KEY,
organization_id UUID REFERENCES organizations(id),
item_id UUID REFERENCES items(id),
location_id UUID REFERENCES storage_locations(id),
quantity INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT NOW()
);
🔌 API Endpoints
Core Service (Go) - REST API
# Аутентификация
POST /api/auth/login
POST /api/auth/register
POST /api/auth/refresh
# Организации
GET /api/organizations/:id
PUT /api/organizations/:id
# Места хранения
GET /api/locations
POST /api/locations
GET /api/locations/:id
PUT /api/locations/:id
DELETE /api/locations/:id
# Товары
GET /api/items
POST /api/items
GET /api/items/:id
PUT /api/items/:id
DELETE /api/items/:id
# Операции
POST /api/operations/place-item
POST /api/operations/move-item
GET /api/operations/search
# Шаблоны
GET /api/templates
POST /api/templates/:id/apply
Document Service (Python) - REST API
# Документы
POST /api/documents/generate-pdf
POST /api/documents/generate-excel
GET /api/documents/:id/status
GET /api/documents/:id/download
# Шаблоны документов
GET /api/templates
POST /api/templates
PUT /api/templates/:id
DELETE /api/templates/:id
🔄 Межсервисная коммуникация
gRPC Services
Core Service → Document Service
service DocumentService {
rpc GenerateQRCode(QRCodeRequest) returns (QRCodeResponse);
rpc GenerateReport(ReportRequest) returns (ReportResponse);
rpc GetDocumentStatus(StatusRequest) returns (StatusResponse);
}
Document Service → Core Service
service CoreService {
rpc GetLocationData(LocationRequest) returns (LocationResponse);
rpc GetItemData(ItemRequest) returns (ItemResponse);
rpc ValidateTemplate(TemplateRequest) returns (TemplateResponse);
}
События (Event-Driven)
message DocumentEvent {
string event_type; // "qr_generated", "report_ready"
string document_id;
string organization_id;
google.protobuf.Timestamp timestamp;
}
🔄 Диаграммы последовательности
Генерация QR-кода
sequenceDiagram
participant F as Frontend
participant C as Core Service
participant D as Document Service
participant R as Redis
F->>C: POST /api/locations/:id/qr-code
C->>D: gRPC GenerateQRCode()
D->>D: Generate QR code
D->>R: Cache document
D->>C: Return document URL
C->>F: Return QR code data
Размещение товара
sequenceDiagram
participant U as User
participant F as Frontend
participant C as Core Service
participant DB as Database
U->>F: Scan QR code
F->>F: Decode location ID
F->>C: GET /api/locations/:id
C->>DB: Query location
DB->>C: Return location data
C->>F: Return location info
F->>U: Show location details
U->>F: Select item & quantity
F->>C: POST /api/operations/place-item
C->>DB: Create placement
DB->>C: Confirm placement
C->>F: Return success
F->>U: Show confirmation
Поиск товара
sequenceDiagram
participant U as User
participant F as Frontend
participant C as Core Service
participant R as Redis
participant DB as Database
U->>F: Search query
F->>C: GET /api/operations/search?q=query
C->>R: Check cache
alt Cache hit
R->>C: Return cached results
else Cache miss
C->>DB: Search items & locations
DB->>C: Return results
C->>R: Cache results
end
C->>F: Return search results
F->>U: Display results
🔐 Безопасность
Аутентификация
- JWT токены с refresh механизмом
- Organization-scope на всех запросах
- Middleware для проверки прав доступа
Валидация данных
- Входная валидация всех параметров
- SQL injection protection через prepared statements
- XSS protection в frontend
HTTPS
- Обязательное использование HTTPS
- Secure cookies для JWT
- CORS настройки для PWA
📱 PWA Особенности
Service Worker
- Кэширование статических ресурсов
- Offline fallback для базовых функций
- Background sync для операций
QR Scanner
- Использование WebRTC для доступа к камере
- Real-time распознавание QR-кодов
- Fallback на ручной ввод
Установка
- Manifest для установки как нативное приложение
- Splash screen и иконки
- Автоматические обновления
🚀 Развертывание
Docker Compose
version: '3.8'
services:
# Core Service (Go)
core-service:
build: ./core-service
ports:
- "8080:8080"
environment:
- DB_HOST=postgres
- JWT_SECRET=your-secret
- DOC_SERVICE_URL=http://doc-service:8000
depends_on:
- postgres
- redis
# Document Service (Python)
doc-service:
build: ./doc-service
ports:
- "8000:8000"
environment:
- REDIS_URL=redis://redis:6379
- CORE_SERVICE_URL=http://core-service:8080
depends_on:
- redis
# Frontend (Angular)
frontend:
build: ./frontend
ports:
- "3000:80"
depends_on:
- core-service
# Database
postgres:
image: postgres:15
environment:
- POSTGRES_DB=erp_mvp
- POSTGRES_USER=erp_user
- POSTGRES_PASSWORD=erp_pass
volumes:
- postgres_data:/var/lib/postgresql/data
# Cache
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
# API Gateway (опционально)
traefik:
image: traefik:v2.10
command:
- --api.insecure=true
- --providers.docker=true
ports:
- "80:80"
- "8081:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
volumes:
postgres_data:
redis_data:
Структура проекта
graph TD
A[erp-mvp/] --> B[core-service/]
A --> C[doc-service/]
A --> D[frontend/]
A --> E[proto/]
A --> F[docker-compose.yml]
B --> B1[cmd/]
B --> B2[internal/]
B --> B3[pkg/]
B --> B4[proto/]
B --> B5[Dockerfile]
C --> C1[app/]
C --> C2[templates/]
C --> C3[proto/]
C --> C4[Dockerfile]
D --> D1[src/]
D --> D2[angular.json]
D --> D3[Dockerfile]
E --> E1[core.proto]
E --> E2[document.proto]
E --> E3[events.proto]
style A fill:#e1f5fe
style B fill:#f3e5f5
style C fill:#e8f5e8
style D fill:#fff3e0
style E fill:#fce4ec
📚 Конкретные библиотеки и фреймворки
Core Service (Go)
// Основные зависимости
go.mod:
- github.com/gin-gonic/gin v1.9.1 // HTTP framework
- github.com/golang-jwt/jwt/v5 v5.0.0 // JWT authentication
- github.com/lib/pq v1.10.9 // PostgreSQL driver
- github.com/go-playground/validator/v10 // Validation
- google.golang.org/grpc v1.58.0 // gRPC client/server
- github.com/swaggo/gin-swagger v1.6.0 // API documentation
- github.com/redis/go-redis/v9 v9.2.1 // Redis client
Document Service (Python)
# requirements.txt
fastapi==0.104.1 # Web framework
uvicorn==0.24.0 # ASGI server
reportlab==4.0.4 # PDF generation
weasyprint==60.1 # HTML to PDF
python-docx==1.1.0 # Word documents
openpyxl==3.1.2 # Excel files
jinja2==3.1.2 # Templates
redis==5.0.1 # Redis client
grpcio==1.59.0 # gRPC
protobuf==4.24.4 # Protocol Buffers
pydantic==2.4.2 # Data validation
Frontend (Angular)
// package.json
{
"dependencies": {
"@angular/core": "^17.0.0",
"@angular/material": "^17.0.0",
"@angular/service-worker": "^17.0.0",
"@zxing/ngx-scanner": "^3.0.0",
"@ngrx/store": "^17.0.0",
"@ngrx/effects": "^17.0.0",
"tailwindcss": "^3.3.0",
"rxjs": "^7.8.0"
}
}
📊 Мониторинг
Логирование
- Go: logrus или zerolog для structured logging
- Python: structlog для structured logging
- Frontend: Angular logging service
- Correlation ID для отслеживания запросов через все сервисы
Метрики
- Prometheus для сбора метрик
- Grafana для визуализации
- Время отклика API по сервисам
- Количество ошибок и их типы
- Активные пользователи и операции
Алерты
- Высокое время отклика (>500ms)
- Высокий процент ошибок (>5%)
- Недоступность сервисов
- Проблемы с генерацией документов