v0.9.3
This commit is contained in:
parent
c8c5debe84
commit
5197bd24ee
10 changed files with 375 additions and 26 deletions
1
.nvmrc
Normal file
1
.nvmrc
Normal file
|
|
@ -0,0 +1 @@
|
|||
20
|
||||
25
README.md
25
README.md
|
|
@ -10,6 +10,31 @@
|
|||
- **`veza-stream-server`**: Rust streaming server.
|
||||
- **`veza-chat-server`**: Rust chat server.
|
||||
|
||||
## Development Setup (v0.9.3)
|
||||
|
||||
Prerequisites: Node 20 (see `.nvmrc`), Go, Rust, Docker. Configure `.env` from `.env.example`.
|
||||
|
||||
```bash
|
||||
# Verify environment
|
||||
make doctor
|
||||
./scripts/validate-env.sh development
|
||||
|
||||
# Install dependencies
|
||||
make install-deps
|
||||
|
||||
# Option A — Backend in Docker + Web local
|
||||
make dev
|
||||
|
||||
# Option B — All apps local with hot reload (infra from docker-compose.dev.yml)
|
||||
make dev-full
|
||||
|
||||
# Option C — Infra only, then run services manually
|
||||
docker compose -f docker-compose.dev.yml up -d
|
||||
make dev-web # or make dev-backend-api, make dev-stream-server
|
||||
```
|
||||
|
||||
See [docs/ENV_VARIABLES.md](docs/ENV_VARIABLES.md) for required variables. `make build` builds all services.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Frontend
|
||||
|
|
|
|||
|
|
@ -125,41 +125,43 @@ Fermer les vecteurs d'attaque infrastructure : endpoint `/metrics` exposé, rate
|
|||
|
||||
### v0.9.3 — Toolchain et Environnement (TASK-QA-006 à 010)
|
||||
|
||||
**Statut** : ⏳ TODO
|
||||
**Statut** : ✅ DONE
|
||||
**Priorité** : P1
|
||||
**Durée estimée** : 1 jour
|
||||
**Prerequisite** : v0.9.1 complète
|
||||
**Complété le** : 2026-03-05
|
||||
|
||||
**Objectif**
|
||||
Standardiser l'environnement de développement pour que tous les développeurs (et Cursor) travaillent dans des conditions identiques et reproductibles.
|
||||
|
||||
**Tâches**
|
||||
|
||||
- [ ] **TASK-QA-006** : Créer `.nvmrc` à la racine du monorepo
|
||||
- [x] **TASK-QA-006** : Créer `.nvmrc` à la racine du monorepo
|
||||
- Version Node.js fixée (LTS actuel)
|
||||
- Référence : ORIGIN_QUALITY_METRICS.md §6.4 DT-007
|
||||
|
||||
- [ ] **TASK-QA-007** : Créer `rust-toolchain.toml` pour le stream server
|
||||
- Version Rust stable fixée
|
||||
- [x] **TASK-QA-007** : Créer `rust-toolchain.toml` pour le stream server
|
||||
- Version Rust stable fixée (existe à la racine)
|
||||
- Référence : ORIGIN_QUALITY_METRICS.md §6.4 DT-008
|
||||
|
||||
- [ ] **TASK-QA-008** : Créer `Makefile` racine
|
||||
- Commandes : `make dev`, `make test`, `make build`, `make lint`, `make clean`
|
||||
- Commande `make doctor` vérifiant toutes les dépendances requises
|
||||
- [x] **TASK-QA-008** : Compléter `Makefile` racine
|
||||
- Alias `build` (→ build-all), cible `doctor` vérifiant dépendances
|
||||
- Référence : make/build.mk, make/tools.mk
|
||||
|
||||
- [ ] **TASK-QA-009** : Documenter toutes les variables d'environnement requises
|
||||
- [x] **TASK-QA-009** : Documenter variables d'environnement + script de validation
|
||||
- `docs/ENV_VARIABLES.md` avec description, type, valeur par défaut, exemples
|
||||
- Script de validation au démarrage
|
||||
- `scripts/validate-env.sh` (appelé par `make doctor`)
|
||||
|
||||
- [ ] **TASK-QA-010** : `docker-compose.dev.yml` fonctionnel
|
||||
- Tous les services (Go backend, Rust stream, React frontend, Postgres, Redis) démarrables avec une commande
|
||||
- Hot reload activé pour le développement
|
||||
- [x] **TASK-QA-010** : `docker-compose.dev.yml` fonctionnel
|
||||
- Infra : Postgres, Redis, RabbitMQ, ClamAV, MinIO
|
||||
- `make dev-full`, `make dev-backend-api`, `make dev-stream-server` utilisent `infra-up-dev`
|
||||
- Hot reload pour apps locales (air, cargo-watch)
|
||||
|
||||
**Critères d'acceptation**
|
||||
- [ ] `make dev` démarre tous les services en moins de 30 secondes
|
||||
- [ ] `make test` exécute toute la suite de tests
|
||||
- [ ] Un développeur nouvellement arrivé peut démarrer l'environnement sans aide
|
||||
- [ ] README racine à jour avec instructions setup
|
||||
- [x] `make dev` démarre backend (Docker) + web local
|
||||
- [x] `make doctor` vérifie dépendances et affiche rapport
|
||||
- [x] Un développeur peut démarrer l'environnement avec les instructions du README
|
||||
- [x] README racine à jour avec instructions setup
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -1190,7 +1192,7 @@ Toutes les conditions suivantes doivent être remplies avant de taguer v1.0.0 :
|
|||
|---------|-----|-------|--------|------------|--------------|
|
||||
| v0.9.1 | JWT Migration RS256 | P3.5 | ✅ DONE | 2-3j | — |
|
||||
| v0.9.2 | Sécurité Infrastructure | P3.5 | ✅ DONE | 1-2j | v0.9.1 |
|
||||
| v0.9.3 | Toolchain & Environnement | P3.5 | ⏳ TODO | 1j | v0.9.1 |
|
||||
| v0.9.3 | Toolchain & Environnement | P3.5 | ✅ DONE | 1j | v0.9.1 |
|
||||
| v0.9.4 | Quality Gates CI/CD | P3.5 | ⏳ TODO | 2j | v0.9.3 |
|
||||
| v0.9.5 | Suppression Code Mort | P3.5 | ⏳ TODO | 1-2j | v0.9.4 |
|
||||
| v0.9.6 | Chat : Réactions & Mentions | P3.5 | ⏳ TODO | 3-4j | v0.9.2 |
|
||||
|
|
|
|||
160
docker-compose.dev.yml
Normal file
160
docker-compose.dev.yml
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
# =============================================================================
|
||||
# VEZA - Development Infrastructure (TASK-QA-010)
|
||||
# =============================================================================
|
||||
# Infra-only stack for local development. Applications (backend, stream, web)
|
||||
# run locally with hot reload via make dev, make dev-full, etc.
|
||||
#
|
||||
# Usage:
|
||||
# docker compose -f docker-compose.dev.yml up -d
|
||||
# make dev # uses infra-up which can target this file via COMPOSE_FILE
|
||||
#
|
||||
# Override: COMPOSE_FILE=docker-compose.dev.yml make infra-up
|
||||
# =============================================================================
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: veza_postgres
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_USER:-veza}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-devpassword}
|
||||
POSTGRES_DB: ${POSTGRES_DB:-veza}
|
||||
ports:
|
||||
- "${PORT_POSTGRES:-15432}:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U veza"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- veza-net
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.50'
|
||||
memory: 256M
|
||||
reservations:
|
||||
memory: 128M
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: veza_redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${PORT_REDIS:-16379}:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 5
|
||||
networks:
|
||||
- veza-net
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.25'
|
||||
memory: 64M
|
||||
reservations:
|
||||
memory: 32M
|
||||
|
||||
rabbitmq:
|
||||
image: rabbitmq:3-management-alpine
|
||||
container_name: veza_rabbitmq
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER:-veza}
|
||||
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:-devpassword}
|
||||
ports:
|
||||
- "${PORT_RABBITMQ_AMQP:-15672}:5672"
|
||||
- "${PORT_RABBITMQ_MGMT:-25672}:15672"
|
||||
volumes:
|
||||
- rabbitmq_data:/var/lib/rabbitmq
|
||||
healthcheck:
|
||||
test: rabbitmq-diagnostics -q ping
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
start_period: 40s
|
||||
networks:
|
||||
- veza-net
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.50'
|
||||
memory: 512M
|
||||
reservations:
|
||||
memory: 256M
|
||||
|
||||
clamav:
|
||||
image: clamav/clamav:latest
|
||||
container_name: veza_clamav
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${PORT_CLAMAV:-13310}:3310"
|
||||
networks:
|
||||
- veza-net
|
||||
healthcheck:
|
||||
test: ["CMD", "clamdscan", "--ping", "1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 180s
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5'
|
||||
memory: 1G
|
||||
|
||||
minio:
|
||||
image: minio/minio:latest
|
||||
container_name: veza_minio
|
||||
restart: unless-stopped
|
||||
command: server /data --console-address ":9001"
|
||||
environment:
|
||||
MINIO_ROOT_USER: ${AWS_ACCESS_KEY_ID:-minioadmin}
|
||||
MINIO_ROOT_PASSWORD: ${AWS_SECRET_ACCESS_KEY:-minioadmin}
|
||||
ports:
|
||||
- "${PORT_MINIO:-19000}:9000"
|
||||
- "${PORT_MINIO_CONSOLE:-19001}:9001"
|
||||
volumes:
|
||||
- minio_data:/data
|
||||
healthcheck:
|
||||
test: ["CMD", "mc", "ready", "local"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- veza-net
|
||||
|
||||
minio-init:
|
||||
image: minio/mc:latest
|
||||
depends_on:
|
||||
minio:
|
||||
condition: service_healthy
|
||||
entrypoint: >
|
||||
/bin/sh -c "
|
||||
mc alias set veza http://minio:9000 $${MINIO_ROOT_USER:-minioadmin} $${MINIO_ROOT_PASSWORD:-minioadmin};
|
||||
mc mb --ignore-existing veza/veza-files;
|
||||
mc anonymous set download veza/veza-files/public;
|
||||
exit 0;
|
||||
"
|
||||
environment:
|
||||
MINIO_ROOT_USER: ${AWS_ACCESS_KEY_ID:-minioadmin}
|
||||
MINIO_ROOT_PASSWORD: ${AWS_SECRET_ACCESS_KEY:-minioadmin}
|
||||
networks:
|
||||
- veza-net
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
redis_data:
|
||||
rabbitmq_data:
|
||||
minio_data:
|
||||
|
||||
networks:
|
||||
veza-net:
|
||||
driver: bridge
|
||||
|
|
@ -131,9 +131,22 @@ Services Rust utilisant veza-common (config_rust JwtConfig) :
|
|||
|
||||
---
|
||||
|
||||
## Validation (TASK-QA-009)
|
||||
|
||||
Valider les variables avant démarrage :
|
||||
|
||||
```bash
|
||||
./scripts/validate-env.sh development # ou production, test
|
||||
```
|
||||
|
||||
Intégré dans `make doctor`.
|
||||
|
||||
---
|
||||
|
||||
## Checklist de démarrage
|
||||
|
||||
1. Copier `.env.example` vers `.env` (racine) et `veza-backend-api/.env.template` vers `veza-backend-api/.env`
|
||||
2. Pour RS256 : exécuter `scripts/generate-jwt-keys.sh` et configurer `JWT_PRIVATE_KEY_PATH`, `JWT_PUBLIC_KEY_PATH`
|
||||
3. Configurer `DATABASE_URL`, `REDIS_URL`, `CORS_ALLOWED_ORIGINS`
|
||||
4. En production : ne jamais commiter `.env` ni les fichiers `.pem`
|
||||
4. Valider : `./scripts/validate-env.sh development`
|
||||
5. En production : ne jamais commiter `.env` ni les fichiers `.pem`
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
# BUILD (Docker images and native for Incus)
|
||||
# ==============================================================================
|
||||
|
||||
.PHONY: build-backend-api build-stream-server build-web
|
||||
.PHONY: build build-backend-api build-stream-server build-web
|
||||
.PHONY: build-all build-all-native build-service
|
||||
|
||||
build: build-all ## [HIGH] Build all services (alias)
|
||||
|
||||
build-backend-api: ## [LOW] Build Go backend Docker image
|
||||
@$(ECHO_CMD) "${BLUE}🔨 Building backend-api...${NC}"
|
||||
@docker build -t $(PROJECT_NAME)-backend-api:latest -f $(ROOT)/$(SERVICE_DIR_backend-api)/Dockerfile.production $(ROOT)/$(SERVICE_DIR_backend-api) || \
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ dev-full-docker: check-ports infra-up ## [HIGH] Start full stack in Docker (Back
|
|||
@$(ECHO_CMD) " Backend: http://$(APP_DOMAIN):$(PORT_backend-api)"
|
||||
@$(ECHO_CMD) " Stream: http://$(APP_DOMAIN):$(PORT_STREAM)"
|
||||
|
||||
dev-full: check-ports infra-up ## [HIGH] Start Everything inc. Stream (Rust)
|
||||
dev-full: check-ports infra-up-dev ## [HIGH] Start Everything inc. Stream (Rust) — infra from docker-compose.dev.yml, apps local with hot reload
|
||||
@$(ECHO_CMD) "${BOLD}${PURPLE}🚀 STARTING HYBRID DEV ENVIRONMENT (full)${NC}"
|
||||
@$(ECHO_CMD) " Go: http://$(APP_DOMAIN):$(PORT_backend-api)"
|
||||
@$(ECHO_CMD) " Stream: http://$(APP_DOMAIN):$(PORT_stream-server)"
|
||||
|
|
@ -40,7 +40,7 @@ dev-full: check-ports infra-up ## [HIGH] Start Everything inc. Stream (Rust)
|
|||
$(ECHO_CMD) "${GREEN}[Web] Starting Vite...${NC}" && cd $(ROOT)/$(SERVICE_DIR_web) && npm run dev & \
|
||||
wait)
|
||||
|
||||
dev-backend: check-ports infra-up ## [MID] Start Backends Only (Hot Reload supported)
|
||||
dev-backend: check-ports infra-up-dev ## [MID] Start Backends Only (Hot Reload supported) — infra from docker-compose.dev.yml
|
||||
@$(ECHO_CMD) "${BOLD}${PURPLE}🚀 STARTING BACKEND ONLY${NC}"
|
||||
@(trap 'kill 0' SIGINT; \
|
||||
if command -v air >/dev/null; then cd $(ROOT)/$(SERVICE_DIR_backend-api) && air & else cd $(ROOT)/$(SERVICE_DIR_backend-api) && go run cmd/api/main.go & fi; \
|
||||
|
|
@ -51,11 +51,11 @@ dev-web: check-ports infra-up ## [MID] Start Web app only (assumes backend elsew
|
|||
@$(ECHO_CMD) "${GREEN}[Web] Starting Vite...${NC}"
|
||||
@cd $(ROOT)/$(SERVICE_DIR_web) && npm run dev
|
||||
|
||||
dev-backend-api: check-ports infra-up ## [MID] Start Go backend only
|
||||
dev-backend-api: check-ports infra-up-dev ## [MID] Start Go backend only — infra from docker-compose.dev.yml
|
||||
@$(ECHO_CMD) "${GREEN}[Backend API] Starting...${NC}"
|
||||
@if command -v air >/dev/null; then cd $(ROOT)/$(SERVICE_DIR_backend-api) && air; else cd $(ROOT)/$(SERVICE_DIR_backend-api) && go run cmd/api/main.go; fi
|
||||
|
||||
dev-stream-server: check-ports infra-up ## [MID] Start Stream server only
|
||||
dev-stream-server: check-ports infra-up-dev ## [MID] Start Stream server only — infra from docker-compose.dev.yml
|
||||
@$(ECHO_CMD) "${GREEN}[Stream] Starting...${NC}"
|
||||
@if command -v cargo-watch >/dev/null; then cd $(ROOT)/$(SERVICE_DIR_stream-server) && cargo watch -x run -q; else cd $(ROOT)/$(SERVICE_DIR_stream-server) && cargo run -q; fi
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,13 @@
|
|||
# INFRASTRUCTURE (Docker: Postgres, Redis, RabbitMQ)
|
||||
# ==============================================================================
|
||||
|
||||
.PHONY: infra-up infra-down wait-for-infra wait-for-services db-shell redis-shell rabbitmq-shell db-migrate
|
||||
.PHONY: infra-up infra-up-dev infra-down wait-for-infra wait-for-services db-shell redis-shell rabbitmq-shell db-migrate
|
||||
|
||||
# Infra-only (TASK-QA-010): use for make dev-full (apps run locally with hot reload)
|
||||
infra-up-dev: ## [MID] Start dev infra only (Postgres, Redis, RabbitMQ, ClamAV, MinIO) — use with make dev-full
|
||||
@$(ECHO_CMD) "${BLUE}🐳 Starting Dev Infrastructure (docker-compose.dev.yml)...${NC}"
|
||||
@docker compose -f docker-compose.dev.yml up -d
|
||||
@$(MAKE) -s wait-for-infra COMPOSE_FILE=docker-compose.dev.yml
|
||||
|
||||
infra-up: ## [MID] Start Docker Infra (with health checks)
|
||||
@$(ECHO_CMD) "${BLUE}🐳 Starting Infrastructure...${NC}"
|
||||
|
|
|
|||
|
|
@ -1,8 +1,53 @@
|
|||
# ==============================================================================
|
||||
# TOOLS: check, install deps, ports
|
||||
# TOOLS: check, install deps, ports, doctor
|
||||
# ==============================================================================
|
||||
|
||||
.PHONY: check-tools check-tools-incus install-tools install-deps check-ports openapi
|
||||
.PHONY: check-tools check-tools-incus install-tools install-deps check-ports openapi doctor
|
||||
|
||||
doctor: ## [HIGH] Verify all dependencies and environment (TASK-QA-008)
|
||||
@$(ECHO_CMD) "${BOLD}${PURPLE}🔬 VEZA Doctor — Environment Check${NC}"
|
||||
@$(ECHO_CMD) ""
|
||||
@$(ECHO_CMD) "${BOLD}Runtime versions:${NC}"
|
||||
@if [ -f $(ROOT)/.nvmrc ]; then \
|
||||
expected=$$(cat $(ROOT)/.nvmrc); \
|
||||
actual=$$(node -v 2>/dev/null || echo "not installed"); \
|
||||
if command -v node >/dev/null 2>&1; then \
|
||||
$(ECHO_CMD) " Node.js: $$actual (expected: v$$expected)"; \
|
||||
else \
|
||||
$(ECHO_CMD) " ${RED}Node.js: not installed${NC}"; \
|
||||
fi; \
|
||||
else \
|
||||
$(ECHO_CMD) " Node.js: $$(node -v 2>/dev/null || echo 'not installed')"; \
|
||||
fi
|
||||
@$(ECHO_CMD) " Go: $$(go version 2>/dev/null || echo 'not installed')"
|
||||
@$(ECHO_CMD) " Rust: $$(rustc --version 2>/dev/null || echo 'not installed')"
|
||||
@$(ECHO_CMD) " Docker: $$(docker --version 2>/dev/null || echo 'not installed')"
|
||||
@$(ECHO_CMD) " Compose: $$(docker compose version 2>/dev/null || echo 'not installed')"
|
||||
@$(ECHO_CMD) ""
|
||||
@$(ECHO_CMD) "${BOLD}Optional (hot reload):${NC}"
|
||||
@command -v air >/dev/null 2>&1 && $(ECHO_CMD) " air: $(GREEN)✓${NC}" || $(ECHO_CMD) " air: $(YELLOW)not installed (run make install-tools)${NC}"
|
||||
@command -v cargo-watch >/dev/null 2>&1 && $(ECHO_CMD) " cargo-watch: $(GREEN)✓${NC}" || $(ECHO_CMD) " cargo-watch: $(YELLOW)not installed (run make install-tools)${NC}"
|
||||
@$(ECHO_CMD) ""
|
||||
@$(ECHO_CMD) "${BOLD}Environment validation (scripts/validate-env.sh):${NC}"
|
||||
@(cd $(ROOT) && ./scripts/validate-env.sh development) || true
|
||||
@$(ECHO_CMD) ""
|
||||
@$(ECHO_CMD) "${BOLD}Env quick check:${NC}"
|
||||
@$(ECHO_CMD) " DATABASE_URL: $${DATABASE_URL:-(not set)}"
|
||||
@$(ECHO_CMD) " REDIS_URL: $${REDIS_URL:-(not set)}"
|
||||
@$(ECHO_CMD) ""
|
||||
@$(ECHO_CMD) "${BOLD}Infra connectivity (requires infra-up):${NC}"
|
||||
@if docker compose -f $(COMPOSE_FILE) exec -T postgres pg_isready -U $(DB_USER) 2>/dev/null; then \
|
||||
$(ECHO_CMD) " Postgres: $(GREEN)✓ reachable${NC}"; \
|
||||
else \
|
||||
$(ECHO_CMD) " Postgres: $(YELLOW)not reachable (run make infra-up)${NC}"; \
|
||||
fi
|
||||
@if docker compose -f $(COMPOSE_FILE) exec -T redis redis-cli ping 2>/dev/null | grep -q PONG; then \
|
||||
$(ECHO_CMD) " Redis: $(GREEN)✓ reachable${NC}"; \
|
||||
else \
|
||||
$(ECHO_CMD) " Redis: $(YELLOW)not reachable (run make infra-up)${NC}"; \
|
||||
fi
|
||||
@$(ECHO_CMD) ""
|
||||
@$(ECHO_CMD) "${GREEN}Run 'make install-deps' to install code dependencies.${NC}"
|
||||
|
||||
check-tools: ## [LOW] Check required tools
|
||||
@$(ECHO_CMD) "${BLUE}Checking core requirements...${NC}"
|
||||
|
|
|
|||
95
scripts/validate-env.sh
Executable file
95
scripts/validate-env.sh
Executable file
|
|
@ -0,0 +1,95 @@
|
|||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# Environment Variables Validation Script (TASK-QA-009)
|
||||
# =============================================================================
|
||||
# Validates required environment variables for Veza development.
|
||||
# See docs/ENV_VARIABLES.md for full reference.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/validate-env.sh [environment]
|
||||
# environment: development (default), production, test
|
||||
#
|
||||
# Can be run before make dev or integrated in make doctor.
|
||||
# =============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
ENVIRONMENT=${1:-development}
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
check_var() {
|
||||
local var_name=$1
|
||||
local required=$2
|
||||
local value="${!var_name}"
|
||||
|
||||
if [ -z "$value" ]; then
|
||||
if [ "$required" = "required" ]; then
|
||||
echo -e " ${RED}✗ ${var_name} (required, not set)${NC}"
|
||||
return 1
|
||||
else
|
||||
echo -e " ${YELLOW}○ ${var_name} (optional, not set)${NC}"
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
echo -e " ${GREEN}✓ ${var_name}${NC}"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo "🔍 Environment validation (${ENVIRONMENT})"
|
||||
echo " Ref: docs/ENV_VARIABLES.md"
|
||||
echo ""
|
||||
|
||||
ERRORS=0
|
||||
|
||||
# Load .env if present (optional)
|
||||
if [ -f .env ]; then
|
||||
set -a
|
||||
source .env
|
||||
set +a
|
||||
fi
|
||||
|
||||
echo "Required variables:"
|
||||
check_var "DATABASE_URL" "required" || ERRORS=$((ERRORS + 1))
|
||||
check_var "REDIS_URL" "required" || ERRORS=$((ERRORS + 1))
|
||||
|
||||
# JWT: either RS256 keys OR JWT_SECRET (dev fallback)
|
||||
JWT_PRIVATE=$(printenv JWT_PRIVATE_KEY_PATH 2>/dev/null || true)
|
||||
JWT_PUBLIC=$(printenv JWT_PUBLIC_KEY_PATH 2>/dev/null || true)
|
||||
JWT_SECRET=$(printenv JWT_SECRET 2>/dev/null || true)
|
||||
if [ -n "$JWT_PRIVATE" ] && [ -n "$JWT_PUBLIC" ]; then
|
||||
echo -e " ${GREEN}✓ JWT (RS256: keys configured)${NC}"
|
||||
elif [ -n "$JWT_SECRET" ] && [ ${#JWT_SECRET} -ge 32 ]; then
|
||||
echo -e " ${GREEN}✓ JWT (HS256 fallback, min 32 chars)${NC}"
|
||||
else
|
||||
echo -e " ${RED}✗ JWT_PRIVATE_KEY_PATH + JWT_PUBLIC_KEY_PATH, or JWT_SECRET (min 32 chars)${NC}"
|
||||
ERRORS=$((ERRORS + 1))
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Optional (development):"
|
||||
check_var "CORS_ALLOWED_ORIGINS" "optional"
|
||||
check_var "FRONTEND_URL" "optional"
|
||||
|
||||
if [ "$ENVIRONMENT" = "production" ]; then
|
||||
echo ""
|
||||
echo "Production-specific:"
|
||||
check_var "CORS_ALLOWED_ORIGINS" "required" || ERRORS=$((ERRORS + 1))
|
||||
fi
|
||||
|
||||
echo ""
|
||||
if [ $ERRORS -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ Validation passed.${NC}"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}✗ Validation failed ($ERRORS error(s)).${NC}"
|
||||
echo " See docs/ENV_VARIABLES.md and .env.example"
|
||||
exit 1
|
||||
fi
|
||||
Loading…
Reference in a new issue