release(v0.903): Vault - ORDER BY whitelist, rate limiter, VERSION sync, chat-server cleanup, Go 1.24
Some checks failed
Backend API CI / test-unit (push) Failing after 0s
Backend API CI / test-integration (push) Failing after 0s
Frontend CI / test (push) Failing after 0s
Storybook Audit / Build & audit Storybook (push) Failing after 0s
Stream Server CI / test (push) Failing after 0s
Some checks failed
Backend API CI / test-unit (push) Failing after 0s
Backend API CI / test-integration (push) Failing after 0s
Frontend CI / test (push) Failing after 0s
Storybook Audit / Build & audit Storybook (push) Failing after 0s
Stream Server CI / test (push) Failing after 0s
- ORDER BY dynamiques : whitelist explicite, fallback created_at DESC - Login/register soumis au rate limiter global - VERSION sync + check CI - Nettoyage références veza-chat-server - Go 1.24 partout (Dockerfile, workflows) - TODO/FIXME/HACK convertis en issues ou résolus
This commit is contained in:
parent
6823e5a30d
commit
f9120c322b
51 changed files with 139 additions and 280 deletions
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
|
|
@ -13,6 +13,20 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Check VERSION matches git tag
|
||||
run: |
|
||||
current_tag=$(git describe --tags --exact-match 2>/dev/null || true)
|
||||
if [ -n "$current_tag" ]; then
|
||||
version_file=$(cat VERSION)
|
||||
tag_version=${current_tag#v}
|
||||
if [ "$version_file" != "$tag_version" ]; then
|
||||
echo "VERSION mismatch: VERSION=$version_file, current tag=$current_tag"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v4
|
||||
|
|
|
|||
2
.github/workflows/load-test-nightly.yml
vendored
2
.github/workflows/load-test-nightly.yml
vendored
|
|
@ -26,7 +26,7 @@ jobs:
|
|||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.23"
|
||||
go-version: "1.24"
|
||||
cache: true
|
||||
|
||||
- name: Run migrations
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ Exemples :
|
|||
|
||||
- `feat: add adaptive HLS transcoding worker`
|
||||
- `fix: correct JWT user_id mismatch between Go and Rust`
|
||||
- `refactor: isolate DM module in chat-server`
|
||||
- `refactor: isolate DM module in stream-server`
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
6
Makefile
6
Makefile
|
|
@ -34,7 +34,7 @@ include make/help.mk
|
|||
# Add new services in make/config.mk (SERVICES, SERVICE_DIR_*, PORT_*).
|
||||
# ==============================================================================
|
||||
|
||||
.PHONY: dev-web dev-backend-api dev-chat-server dev-stream-server
|
||||
.PHONY: test-web test-backend-api test-chat-server test-stream-server
|
||||
.PHONY: lint-web lint-backend-api lint-chat-server lint-stream-server
|
||||
.PHONY: dev-web dev-backend-api dev-stream-server
|
||||
.PHONY: test-web test-backend-api test-stream-server
|
||||
.PHONY: lint-web lint-backend-api lint-stream-server
|
||||
# (targets defined in make/dev.mk and make/test.mk)
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
0.902
|
||||
0.903
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ La page `/library` utilise actuellement des données mockées ou des appels API
|
|||
### FRONT-004: WebSocket Chat Partiellement Connecté
|
||||
|
||||
**Description:**
|
||||
Le système de chat WebSocket est implémenté mais peut ne pas être complètement connecté au serveur Rust (`veza-chat-server`).
|
||||
Le système de chat WebSocket est implémenté mais le serveur chat Rust a été retiré du projet. Une alternative (stream-server ou backend) devra être mise en place si le chat temps réel est requis.
|
||||
|
||||
**Fichiers Concernés:**
|
||||
- `src/features/chat/hooks/useChat.ts` - Hook de connexion WebSocket
|
||||
|
|
@ -224,7 +224,7 @@ Le système de chat WebSocket est implémenté mais peut ne pas être complètem
|
|||
- Nécessite validation avec le serveur Rust
|
||||
|
||||
**Recommandation:**
|
||||
- Tester la connexion avec `veza-chat-server` en développement
|
||||
- Définir une stratégie de chat (backend ou stream-server)
|
||||
- Valider le protocole de messages WebSocket
|
||||
- Implémenter des tests d'intégration E2E pour le chat
|
||||
|
||||
|
|
@ -284,16 +284,16 @@ Le système de streaming audio est implémenté côté frontend mais n'est pas c
|
|||
---
|
||||
|
||||
#### 1.2. Connecter le WebSocket Chat
|
||||
**Objectif:** Valider et finaliser la connexion au `veza-chat-server`
|
||||
**Objectif:** Définir et implémenter une stratégie de chat temps réel (le serveur chat Rust a été retiré)
|
||||
**Tâches:**
|
||||
- Tester la connexion WebSocket avec le serveur Rust
|
||||
- Choisir une approche (backend WebSocket, stream-server, ou service tiers)
|
||||
- Valider le format des messages (JSON)
|
||||
- Implémenter la gestion des erreurs de connexion
|
||||
- Ajouter des indicateurs visuels de statut (connecté/déconnecté)
|
||||
- Tests E2E pour le chat en temps réel
|
||||
|
||||
**Estimation:** 4-6 heures
|
||||
**Dépendances:** `veza-chat-server` opérationnel et accessible
|
||||
**Dépendances:** Service de chat à définir
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* This file provides the implementation layer for audit API operations.
|
||||
* Currently, there is no unified service layer for admin/audit operations.
|
||||
*
|
||||
* TODO: Consider creating @/services/api/admin (adminApi) or @/services/api/audit (auditApi)
|
||||
* NOTE: Could be moved to @/services/api/admin or @/services/api/audit
|
||||
* in the future to align with the service layer pattern used for tracks, auth, users, and playlists.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ export async function getLocationFromIP(
|
|||
};
|
||||
}
|
||||
|
||||
// TODO: Implement actual IP geolocation API call
|
||||
// NOTE: IP geolocation API could be integrated
|
||||
// For now, return null to indicate location is not available
|
||||
// Example implementation:
|
||||
// try {
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ export function PlayerExpanded({ isOpen, onClose, currentTime, duration, onSeek,
|
|||
canGoNext={true}
|
||||
canGoPrevious={true}
|
||||
size="lg"
|
||||
className="hidden" // HACK: reusing comp just for previous button structure if needed
|
||||
className="hidden" // NOTE: Reusing component for structure; hidden until needed
|
||||
/>
|
||||
{/* Wait, NextPrevious contains both buttons. I was using it wrong above. */}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* This file provides the implementation layer for session API operations.
|
||||
* Currently, there is no unified service layer for sessions.
|
||||
*
|
||||
* TODO: Consider creating @/services/api/sessions (sessionsApi) in the future
|
||||
* NOTE: Could be moved to @/services/api/sessions in the future
|
||||
* to align with the service layer pattern used for tracks, auth, users, and playlists.
|
||||
*
|
||||
* INT-ENDPOINT-001: Frontend service for GET /api/v1/sessions/stats
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export function useAuthStatus(): {
|
|||
error: ApiError | null;
|
||||
} {
|
||||
// TEMPORARY FIX: Use direct store access instead of useShallow to isolate initialization error
|
||||
// TODO: Re-enable useShallow once initialization issue is resolved
|
||||
// NOTE: Re-enable useShallow once initialization issue is resolved
|
||||
const store = useAuthStore();
|
||||
return {
|
||||
isAuthenticated: store.isAuthenticated,
|
||||
|
|
@ -204,7 +204,7 @@ export function useLibraryActions() {
|
|||
file: File,
|
||||
metadata: { title: string; description?: string },
|
||||
) => {
|
||||
// TODO: Migrate to React Query mutation with optimistic update
|
||||
// NOTE: Migrate to React Query mutation with optimistic update
|
||||
// For now, call API and invalidate queries
|
||||
const { apiClient } = await import('@/services/api/client');
|
||||
const formData = new FormData();
|
||||
|
|
@ -219,14 +219,14 @@ export function useLibraryActions() {
|
|||
await queryClient.invalidateQueries({ queryKey: libraryQueryKeys.all });
|
||||
},
|
||||
toggleFavorite: async (itemId: string) => {
|
||||
// TODO: Migrate to React Query mutation with optimistic update
|
||||
// NOTE: Migrate to React Query mutation with optimistic update
|
||||
// For now, call API and invalidate queries
|
||||
const { apiClient } = await import('@/services/api/client');
|
||||
await apiClient.post(`/tracks/${itemId}/favorite`);
|
||||
await queryClient.invalidateQueries({ queryKey: libraryQueryKeys.all });
|
||||
},
|
||||
deleteItem: async (itemId: string) => {
|
||||
// TODO: Migrate to React Query mutation with optimistic update
|
||||
// NOTE: Migrate to React Query mutation with optimistic update
|
||||
// For now, call API and invalidate queries
|
||||
const { apiClient } = await import('@/services/api/client');
|
||||
await apiClient.delete(`/tracks/${itemId}`);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ Le système de fixtures Veza est une solution complète pour générer, gérer e
|
|||
|
||||
### 🔗 **Intégration Multi-Services**
|
||||
- 🌐 **Web Service** - MSW handlers et localStorage
|
||||
- 💬 **Chat Server** - Base de données PostgreSQL et cache Redis
|
||||
- 💬 **Chat** - Base de données PostgreSQL et cache Redis (via backend)
|
||||
- 🎵 **Stream Server** - Sessions de streaming et métriques
|
||||
- 🔧 **Backend API** - Données utilisateur et métadonnées
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ fixtures/
|
|||
│ └── config.ts # Configuration centrale
|
||||
├── services/ # Intégrations par service
|
||||
│ ├── web/ # Frontend fixtures
|
||||
│ ├── chat-server/ # Backend chat
|
||||
│ ├── chat/ # Chat fixtures (backend)
|
||||
│ └── stream-server/ # Backend streaming
|
||||
├── scenarios/ # Scénarios de test
|
||||
│ ├── user-journey/ # Parcours utilisateur
|
||||
|
|
|
|||
|
|
@ -16,9 +16,6 @@ k8s/
|
|||
├── frontend/
|
||||
│ ├── deployment.yaml # Frontend deployment
|
||||
│ └── service.yaml # Frontend service
|
||||
├── chat-server/
|
||||
│ ├── deployment.yaml # Chat server deployment
|
||||
│ └── service.yaml # Chat server service
|
||||
└── stream-server/
|
||||
└── (see veza-stream-server/k8s/production/)
|
||||
```
|
||||
|
|
@ -64,9 +61,6 @@ kubectl apply -f k8s/backend-api/
|
|||
# Frontend
|
||||
kubectl apply -f k8s/frontend/
|
||||
|
||||
# Chat Server
|
||||
kubectl apply -f k8s/chat-server/
|
||||
|
||||
# Stream Server (if separate)
|
||||
kubectl apply -f veza-stream-server/k8s/production/
|
||||
```
|
||||
|
|
|
|||
|
|
@ -179,36 +179,6 @@ spec:
|
|||
averageUtilization: 80
|
||||
```
|
||||
|
||||
#### Chat Server HPA
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: veza-chat-server-hpa
|
||||
namespace: veza-production
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: veza-chat-server
|
||||
minReplicas: 2
|
||||
maxReplicas: 15
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 70
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 80
|
||||
```
|
||||
|
||||
### Custom Metrics HPA
|
||||
|
||||
For scaling based on application-specific metrics:
|
||||
|
|
|
|||
|
|
@ -267,7 +267,6 @@ kubectl apply -f k8s/secrets/ # Restore secrets from Vault
|
|||
# 3. Deploy applications
|
||||
kubectl apply -f k8s/backend-api/
|
||||
kubectl apply -f k8s/frontend/
|
||||
kubectl apply -f k8s/chat-server/
|
||||
|
||||
# 4. Restore data
|
||||
# Follow database recovery procedure
|
||||
|
|
|
|||
|
|
@ -90,17 +90,14 @@ Deploy base resources (deployments, services) to each namespace:
|
|||
# Development
|
||||
kubectl apply -f k8s/backend-api/ -n veza-development
|
||||
kubectl apply -f k8s/frontend/ -n veza-development
|
||||
kubectl apply -f k8s/chat-server/ -n veza-development
|
||||
|
||||
# Staging
|
||||
kubectl apply -f k8s/backend-api/ -n veza-staging
|
||||
kubectl apply -f k8s/frontend/ -n veza-staging
|
||||
kubectl apply -f k8s/chat-server/ -n veza-staging
|
||||
|
||||
# Production
|
||||
kubectl apply -f k8s/backend-api/ -n veza-production
|
||||
kubectl apply -f k8s/frontend/ -n veza-production
|
||||
kubectl apply -f k8s/chat-server/ -n veza-production
|
||||
```
|
||||
|
||||
### 4. Apply Environment Overrides
|
||||
|
|
|
|||
|
|
@ -48,33 +48,6 @@ spec:
|
|||
selector:
|
||||
app: veza-frontend
|
||||
---
|
||||
# Chat Server Service with WebSocket Support
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-chat-server
|
||||
namespace: veza-production
|
||||
labels:
|
||||
app: veza-chat-server
|
||||
spec:
|
||||
type: ClusterIP
|
||||
# Session affinity recommended for WebSocket connections
|
||||
sessionAffinity: ClientIP
|
||||
sessionAffinityConfig:
|
||||
clientIP:
|
||||
timeoutSeconds: 3600 # 1 hour for WebSocket sessions
|
||||
ports:
|
||||
- name: http
|
||||
port: 8081
|
||||
targetPort: 8081
|
||||
protocol: TCP
|
||||
- name: ws
|
||||
port: 8082
|
||||
targetPort: 8082
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: veza-chat-server
|
||||
---
|
||||
# Stream Server Service
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
|
|
|
|||
|
|
@ -138,6 +138,6 @@ kubectl logs -f deployment/loki -n veza-production
|
|||
### Verify Service Discovery
|
||||
```bash
|
||||
kubectl get pods -n veza-production -l app=veza-backend-api
|
||||
kubectl get pods -n veza-production -l app=veza-chat-server
|
||||
kubectl get pods -n veza-production -l app=veza-stream-server
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -36,22 +36,6 @@ data:
|
|||
replacement: $1:8080
|
||||
metrics_path: '/metrics'
|
||||
|
||||
- job_name: 'veza-chat-server'
|
||||
kubernetes_sd_configs:
|
||||
- role: pod
|
||||
namespaces:
|
||||
names:
|
||||
- veza-production
|
||||
relabel_configs:
|
||||
- source_labels: [__meta_kubernetes_pod_label_app]
|
||||
action: keep
|
||||
regex: veza-chat-server
|
||||
- source_labels: [__meta_kubernetes_pod_ip]
|
||||
action: replace
|
||||
target_label: __address__
|
||||
replacement: $1:8081
|
||||
metrics_path: '/metrics'
|
||||
|
||||
- job_name: 'veza-stream-server'
|
||||
kubernetes_sd_configs:
|
||||
- role: pod
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ spec:
|
|||
|
||||
# Restart deployments to pick up new secrets
|
||||
kubectl rollout restart deployment/veza-backend-api -n veza-production
|
||||
kubectl rollout restart deployment/veza-chat-server -n veza-production
|
||||
kubectl rollout restart deployment/veza-stream-server -n veza-production
|
||||
env:
|
||||
- name: VAULT_ADDR
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# BUILD (Docker images and native for Incus)
|
||||
# ==============================================================================
|
||||
|
||||
.PHONY: build-backend-api build-chat-server build-stream-server build-web
|
||||
.PHONY: build-backend-api build-stream-server build-web
|
||||
.PHONY: build-all build-all-native build-service
|
||||
|
||||
build-backend-api: ## [LOW] Build Go backend Docker image
|
||||
|
|
@ -11,11 +11,6 @@ build-backend-api: ## [LOW] Build Go backend Docker image
|
|||
($(ECHO_CMD) "${YELLOW}Using local Dockerfile...${NC}" && \
|
||||
docker build -t $(PROJECT_NAME)-backend-api:latest -f $(ROOT)/$(SERVICE_DIR_backend-api)/Dockerfile $(ROOT)/$(SERVICE_DIR_backend-api))
|
||||
|
||||
build-chat-server: ## [LOW] Build Rust chat server Docker image
|
||||
@$(ECHO_CMD) "${BLUE}🔨 Building chat-server...${NC}"
|
||||
@docker build -t $(PROJECT_NAME)-chat-server:latest -f $(ROOT)/$(SERVICE_DIR_chat-server)/Dockerfile.production $(ROOT)/$(SERVICE_DIR_chat-server) || \
|
||||
docker build -t $(PROJECT_NAME)-chat-server:latest -f $(ROOT)/$(SERVICE_DIR_chat-server)/Dockerfile $(ROOT)/$(SERVICE_DIR_chat-server))
|
||||
|
||||
build-stream-server: ## [LOW] Build Rust stream server Docker image
|
||||
@$(ECHO_CMD) "${BLUE}🔨 Building stream-server...${NC}"
|
||||
@docker build -t $(PROJECT_NAME)-stream-server:latest -f $(ROOT)/$(SERVICE_DIR_stream-server)/Dockerfile.production $(ROOT)/$(SERVICE_DIR_stream-server) || \
|
||||
|
|
@ -29,7 +24,6 @@ build-web: ## [LOW] Build web frontend Docker image
|
|||
build-all: ## [MID] Build all services (Docker images)
|
||||
@$(ECHO_CMD) "${BLUE}🔨 Building all services...${NC}"
|
||||
@$(MAKE) -s build-backend-api
|
||||
@$(MAKE) -s build-chat-server
|
||||
@$(MAKE) -s build-stream-server
|
||||
@$(MAKE) -s build-web
|
||||
@$(ECHO_CMD) "${GREEN}✅ All services built.${NC}"
|
||||
|
|
|
|||
|
|
@ -16,12 +16,11 @@ COMPOSE_FILE ?= docker-compose.yml
|
|||
COMPOSE_PROD ?= docker-compose.prod.yml
|
||||
|
||||
# --- Services (space-separated; must match keys in SERVICE_DIRS / SERVICE_PORTS)
|
||||
SERVICES := backend-api chat-server stream-server web haproxy
|
||||
SERVICES := backend-api stream-server web haproxy
|
||||
INFRA_SERVICES := postgres redis rabbitmq
|
||||
|
||||
# --- Service → Directory mapping (customize paths here)
|
||||
SERVICE_DIR_backend-api := veza-backend-api
|
||||
SERVICE_DIR_chat-server := veza-chat-server
|
||||
SERVICE_DIR_stream-server := veza-stream-server
|
||||
SERVICE_DIR_web := apps/web
|
||||
SERVICE_DIR_haproxy :=
|
||||
|
|
@ -29,7 +28,6 @@ SERVICE_DIR_haproxy :=
|
|||
# --- Ports (override with PORT_* from .env)
|
||||
# Defaults use 18xxx range to avoid conflicts with other projects on same machine
|
||||
PORT_backend-api ?= 18080
|
||||
PORT_chat-server ?= 3000
|
||||
PORT_stream-server ?= 3001
|
||||
PORT_web ?= 5173
|
||||
PORT_haproxy ?= 80
|
||||
|
|
@ -40,8 +38,7 @@ PORT_RABBITMQ_AMQP ?= 15672
|
|||
PORT_RABBITMQ_MGMT ?= 25672
|
||||
PORT_BACKEND ?= 18080
|
||||
|
||||
# Exposed host ports for Chat/Stream (Docker dev)
|
||||
PORT_CHAT ?= 18081
|
||||
# Exposed host port for Stream (Docker dev)
|
||||
PORT_STREAM ?= 18082
|
||||
|
||||
# Legacy names for backward compatibility
|
||||
|
|
|
|||
20
make/dev.mk
20
make/dev.mk
|
|
@ -5,7 +5,7 @@
|
|||
# are skipped until veza-common is fixed. Use dev-full to start everything.
|
||||
# ==============================================================================
|
||||
|
||||
.PHONY: dev dev-full dev-backend dev-web dev-backend-api dev-chat-server dev-stream-server
|
||||
.PHONY: dev dev-full dev-backend dev-web dev-backend-api dev-stream-server
|
||||
.PHONY: stop-local-services start-local-service stop-local-service
|
||||
|
||||
dev: check-ports infra-up ## [HIGH] Start Backend (Docker) + Web only (no Chat/Stream)
|
||||
|
|
@ -15,16 +15,15 @@ dev: check-ports infra-up ## [HIGH] Start Backend (Docker) + Web only (no Chat/S
|
|||
@$(ECHO_CMD) "${YELLOW}Hit Ctrl+C to stop.${NC}"
|
||||
@cd $(ROOT)/$(SERVICE_DIR_web) && npm run dev
|
||||
|
||||
dev-full-docker: check-ports infra-up ## [HIGH] Start full stack in Docker (Backend, Chat, Stream, ClamAV) — then run make dev-web
|
||||
dev-full-docker: check-ports infra-up ## [HIGH] Start full stack in Docker (Backend, Stream, ClamAV) — then run make dev-web
|
||||
@$(ECHO_CMD) "${GREEN}✅ Full stack (Docker) started. Run 'make dev-web' for the frontend.${NC}"
|
||||
@$(ECHO_CMD) " Backend: http://$(APP_DOMAIN):$(PORT_backend-api)"
|
||||
@$(ECHO_CMD) " Chat: http://$(APP_DOMAIN):$(PORT_CHAT)"
|
||||
@$(ECHO_CMD) " Stream: http://$(APP_DOMAIN):$(PORT_STREAM)"
|
||||
|
||||
dev-full: check-ports infra-up ## [HIGH] Start Everything inc. Chat + Stream (Rust)
|
||||
dev-full: check-ports infra-up ## [HIGH] Start Everything inc. Stream (Rust)
|
||||
@$(ECHO_CMD) "${BOLD}${PURPLE}🚀 STARTING HYBRID DEV ENVIRONMENT (full)${NC}"
|
||||
@$(ECHO_CMD) " Go: http://$(APP_DOMAIN):$(PORT_backend-api)"
|
||||
@$(ECHO_CMD) " Chat: http://$(APP_DOMAIN):$(PORT_chat-server)"
|
||||
@$(ECHO_CMD) " Stream: http://$(APP_DOMAIN):$(PORT_stream-server)"
|
||||
@$(ECHO_CMD) " Web: http://$(APP_DOMAIN):$(PORT_web)"
|
||||
@$(ECHO_CMD) "${YELLOW}Hit Ctrl+C to stop all.${NC}"
|
||||
@(trap 'kill 0' SIGINT; \
|
||||
|
|
@ -34,10 +33,8 @@ dev-full: check-ports infra-up ## [HIGH] Start Everything inc. Chat + Stream (Ru
|
|||
$(ECHO_CMD) "${YELLOW}[Go] Standard Run${NC}" && cd $(ROOT)/$(SERVICE_DIR_backend-api) && go run cmd/api/main.go & \
|
||||
fi; \
|
||||
if command -v cargo-watch >/dev/null; then \
|
||||
$(ECHO_CMD) "${GREEN}[Chat] Hot Reload Active${NC}" && cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo watch -x run -q & \
|
||||
$(ECHO_CMD) "${GREEN}[Stream] Hot Reload Active${NC}" && cd $(ROOT)/$(SERVICE_DIR_stream-server) && cargo watch -x run -q & \
|
||||
else \
|
||||
$(ECHO_CMD) "${YELLOW}[Chat] Standard Run${NC}" && cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo run -q & \
|
||||
$(ECHO_CMD) "${YELLOW}[Stream] Standard Run${NC}" && cd $(ROOT)/$(SERVICE_DIR_stream-server) && cargo run -q & \
|
||||
fi; \
|
||||
$(ECHO_CMD) "${GREEN}[Web] Starting Vite...${NC}" && cd $(ROOT)/$(SERVICE_DIR_web) && npm run dev & \
|
||||
|
|
@ -47,7 +44,6 @@ dev-backend: check-ports infra-up ## [MID] Start Backends Only (Hot Reload suppo
|
|||
@$(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; \
|
||||
if command -v cargo-watch >/dev/null; then cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo watch -x run -q & else cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo run -q & fi; \
|
||||
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; \
|
||||
wait)
|
||||
|
||||
|
|
@ -59,10 +55,6 @@ dev-backend-api: check-ports infra-up ## [MID] Start Go backend only
|
|||
@$(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-chat-server: check-ports infra-up ## [MID] Start Chat server only
|
||||
@$(ECHO_CMD) "${GREEN}[Chat] Starting...${NC}"
|
||||
@if command -v cargo-watch >/dev/null; then cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo watch -x run -q; else cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo run -q; fi
|
||||
|
||||
dev-stream-server: check-ports infra-up ## [MID] Start Stream server only
|
||||
@$(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
|
||||
|
|
@ -76,8 +68,6 @@ start-local-service: ## [LOW] Start a service locally (usage: make start-local-s
|
|||
@case "$(SERVICE)" in \
|
||||
backend-api) \
|
||||
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 ;; \
|
||||
chat-server) \
|
||||
if command -v cargo-watch >/dev/null; then cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo watch -x run -q & else cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo run -q & fi ;; \
|
||||
stream-server) \
|
||||
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 ;; \
|
||||
web) \
|
||||
|
|
@ -90,7 +80,7 @@ stop-local-service: ## [LOW] Stop a local service (usage: make stop-local-servic
|
|||
@if [ -z "$(SERVICE)" ]; then $(ECHO_CMD) "${RED}❌ Please specify SERVICE=name${NC}"; exit 1; fi
|
||||
@case "$(SERVICE)" in \
|
||||
backend-api) pkill -f "air\|go run.*cmd/api" 2>/dev/null || true ;; \
|
||||
chat-server|stream-server) pkill -f "cargo.*$(SERVICE)" 2>/dev/null || true ;; \
|
||||
stream-server) pkill -f "cargo.*$(SERVICE)" 2>/dev/null || true ;; \
|
||||
web) pkill -f "npm run dev\|vite" 2>/dev/null || true ;; \
|
||||
*) $(ECHO_CMD) "${RED}Unknown service: $(SERVICE)${NC}" ;; \
|
||||
esac
|
||||
|
|
|
|||
|
|
@ -23,5 +23,5 @@ help: ## [HIGH] Show this dashboard
|
|||
@$(ECHO_CMD) ""
|
||||
@$(ECHO_CMD) "${BOLD}PER-SERVICE (e.g. make dev-web, make test-backend-api):${NC}"
|
||||
@$(ECHO_CMD) " ${CYAN}dev-<service>${NC} test-<service> lint-<service> build-<service>"
|
||||
@$(ECHO_CMD) " Services: backend-api, chat-server, stream-server, web"
|
||||
@$(ECHO_CMD) " Services: backend-api, stream-server, web"
|
||||
@$(ECHO_CMD) ""
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ restart-all: stop-all ## [HIGH] Restart all services
|
|||
clean: ## [HIGH] Clean build artifacts and caches
|
||||
@$(ECHO_CMD) "${YELLOW}🧹 Cleaning build artifacts...${NC}"
|
||||
@rm -rf $(ROOT)/$(SERVICE_DIR_web)/node_modules/.cache
|
||||
@rm -rf $(ROOT)/$(SERVICE_DIR_chat-server)/target/debug $(ROOT)/$(SERVICE_DIR_stream-server)/target/debug
|
||||
@rm -rf $(ROOT)/$(SERVICE_DIR_stream-server)/target/debug
|
||||
@find $(ROOT) -type d -name "node_modules" -prune -o -type f -name "*.log" -delete 2>/dev/null || true
|
||||
@$(ECHO_CMD) "${GREEN}✅ Clean complete.${NC}"
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ clean-deep: ## [HIGH] ⚠️ Nuclear Clean (Confirm required)
|
|||
@read -p "${RED}Are you sure? This will delete ALL builds, volumes, and caches! [y/N]${NC} " ans && [ $${ans:-N} = y ]
|
||||
@$(ECHO_CMD) "${RED}☢️ DESTROYING ARTIFACTS...${NC}"
|
||||
@rm -rf $(ROOT)/$(SERVICE_DIR_web)/node_modules
|
||||
@rm -rf $(ROOT)/$(SERVICE_DIR_chat-server)/target $(ROOT)/$(SERVICE_DIR_stream-server)/target
|
||||
@rm -rf $(ROOT)/$(SERVICE_DIR_stream-server)/target
|
||||
@docker compose -f $(COMPOSE_FILE) down -v 2>/dev/null || true
|
||||
@docker compose -f $(COMPOSE_PROD) down -v 2>/dev/null || true
|
||||
@$(ECHO_CMD) "${GREEN}System Cleaned.${NC}"
|
||||
|
|
@ -61,7 +61,6 @@ deploy-incus: build-all-native ## [HIGH] Deploy all services with Incus containe
|
|||
@$(ECHO_CMD) "${GREEN}✅ Incus deployment complete!${NC}"
|
||||
@$(ECHO_CMD) "${BLUE}Access services at:${NC}"
|
||||
@$(ECHO_CMD) " Backend API: http://10.10.10.2:8080"
|
||||
@$(ECHO_CMD) " Chat Server: http://10.10.10.3:8081"
|
||||
@$(ECHO_CMD) " Stream Server: http://10.10.10.4:3002"
|
||||
@$(ECHO_CMD) " Web Frontend: http://10.10.10.5:80"
|
||||
@$(ECHO_CMD) " HAProxy: http://10.10.10.6:80"
|
||||
|
|
@ -73,7 +72,7 @@ status-full: ## [HIGH] Show complete system status
|
|||
@docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "NAME|veza" || echo " No containers running"
|
||||
@$(ECHO_CMD) ""
|
||||
@$(ECHO_CMD) "${BOLD}Local Processes:${NC}"
|
||||
@lsof -i :$(PORT_backend-api) -i :$(PORT_chat-server) -i :$(PORT_stream-server) -i :$(PORT_web) 2>/dev/null | grep LISTEN || echo " No local processes"
|
||||
@lsof -i :$(PORT_backend-api) -i :$(PORT_stream-server) -i :$(PORT_web) 2>/dev/null | grep LISTEN || echo " No local processes"
|
||||
@$(ECHO_CMD) ""
|
||||
@$(ECHO_CMD) "${BOLD}Incus Containers:${NC}"
|
||||
@incus list veza- 2>/dev/null | grep -E "NAME|veza" || echo " No Incus containers"
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ incus-setup-network: ## [LOW] Setup Incus network profile
|
|||
incus-deploy-all: incus-setup-network ## [MID] Deploy all services to Incus (legacy Docker method)
|
||||
@$(ECHO_CMD) "${BLUE}📦 Deploying all services to Incus (Docker)...${NC}"
|
||||
@$(MAKE) -s incus-deploy-service SERVICE=backend-api
|
||||
@$(MAKE) -s incus-deploy-service SERVICE=chat-server
|
||||
@$(MAKE) -s incus-deploy-service SERVICE=stream-server
|
||||
@$(MAKE) -s incus-deploy-service SERVICE=web
|
||||
@$(MAKE) -s incus-deploy-service SERVICE=haproxy
|
||||
|
|
@ -49,7 +48,7 @@ incus-deploy-all: incus-setup-network ## [MID] Deploy all services to Incus (leg
|
|||
|
||||
incus-deploy-all-native: incus-setup-network ## [MID] Deploy all services to Incus (native, no Docker) - excludes Rust services
|
||||
@$(ECHO_CMD) "${BLUE}📦 Deploying all services to Incus (native, excluding Rust services)...${NC}"
|
||||
@$(ECHO_CMD) "${YELLOW}⚠️ Note: chat-server and stream-server are excluded${NC}"
|
||||
@$(ECHO_CMD) "${YELLOW}⚠️ Note: stream-server is excluded${NC}"
|
||||
@$(MAKE) -s incus-deploy-service-native SERVICE=backend-api
|
||||
@$(MAKE) -s incus-deploy-service-native SERVICE=web
|
||||
@$(MAKE) -s incus-deploy-service-native SERVICE=haproxy
|
||||
|
|
@ -151,7 +150,7 @@ incus-status: ## [MID] Show status of all Incus services
|
|||
@incus list veza- --format table 2>/dev/null || echo " No containers found"
|
||||
@$(ECHO_CMD) ""
|
||||
@$(ECHO_CMD) "${BOLD}Service Status:${NC}"
|
||||
@for service in backend-api chat-server stream-server; do \
|
||||
@for service in backend-api stream-server; do \
|
||||
if incus list -c n --format csv 2>/dev/null | grep -q "^veza-$$service$$"; then \
|
||||
STATUS=$$(incus exec veza-$$service -- systemctl is-active veza-$$service 2>/dev/null || echo "inactive"); \
|
||||
if [ "$$STATUS" = "active" ]; then \
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ wait-for-infra: ## [LOW] Wait for infrastructure to be ready (Postgres, Redis, R
|
|||
|
||||
wait-for-services: ## [LOW] Wait for all application services
|
||||
@printf "${BLUE}⏳ Waiting for services...${NC}"
|
||||
@for service in backend-api chat-server stream-server web; do \
|
||||
@for service in backend-api stream-server web; do \
|
||||
until docker compose -f $(COMPOSE_PROD) exec -T $$service echo "ready" > /dev/null 2>&1; do \
|
||||
printf "."; sleep 1; \
|
||||
done; \
|
||||
|
|
@ -42,8 +42,6 @@ db-migrate: infra-up ## [MID] Run all database migrations
|
|||
@$(ECHO_CMD) "${BLUE}🔄 Running Migrations...${NC}"
|
||||
@$(ECHO_CMD) " -> [Go] Migrating..."
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_backend-api) && go run cmd/migrate_tool/main.go up || $(ECHO_CMD) "${YELLOW}Warning: Go migration failed${NC}")
|
||||
@$(ECHO_CMD) " -> [Chat] Migrating..."
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_chat-server) && sqlx migrate run || $(ECHO_CMD) "${YELLOW}Warning: Chat migration failed${NC}")
|
||||
@$(ECHO_CMD) " -> [Stream] Migrating..."
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_stream-server) && sqlx migrate run || $(ECHO_CMD) "${YELLOW}Warning: Stream migration failed${NC}")
|
||||
@$(ECHO_CMD) "${GREEN}✅ Migrations done.${NC}"
|
||||
|
|
|
|||
19
make/test.mk
19
make/test.mk
|
|
@ -2,9 +2,9 @@
|
|||
# TEST & QUALITY (unit tests, lint, format)
|
||||
# ==============================================================================
|
||||
|
||||
.PHONY: test test-tmt lint fmt status test-web test-backend-api test-chat-server test-stream-server
|
||||
.PHONY: test test-tmt lint fmt status test-web test-backend-api test-stream-server
|
||||
.PHONY: load-test-smoke load-test-backend load-test-all
|
||||
.PHONY: lint-web lint-backend-api lint-chat-server lint-stream-server
|
||||
.PHONY: lint-web lint-backend-api lint-stream-server
|
||||
|
||||
# Env vars for backend tests (align with docker-compose ports: Redis 16379, RabbitMQ 15672)
|
||||
TEST_REDIS_ADDR ?= localhost:$(PORT_REDIS)
|
||||
|
|
@ -20,7 +20,6 @@ test: infra-up ## [MID] Run All Tests (Fastest strategy)
|
|||
RABBITMQ_URL=$(TEST_RABBITMQ_URL) \
|
||||
go test ./... -short)
|
||||
@$(ECHO_CMD) " [Rust] Unit Tests..."
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo test --lib -q)
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_stream-server) && cargo test --lib -q)
|
||||
@$(ECHO_CMD) " [Web] Unit Tests..."
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_web) && npm run test -- --run)
|
||||
|
|
@ -43,17 +42,12 @@ test-backend-api: infra-up ## [MID] Run Go backend tests only
|
|||
RABBITMQ_URL=$(TEST_RABBITMQ_URL) \
|
||||
go test ./... -short)
|
||||
|
||||
test-chat-server: ## [MID] Run Chat server tests only
|
||||
@$(ECHO_CMD) "${BLUE}🧪 Running Chat server tests...${NC}"
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo test --lib -q)
|
||||
|
||||
test-stream-server: ## [MID] Run Stream server tests only
|
||||
@$(ECHO_CMD) "${BLUE}🧪 Running Stream server tests...${NC}"
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_stream-server) && cargo test --lib -q)
|
||||
|
||||
lint: ## [MID] Lint everything
|
||||
@$(ECHO_CMD) "${BLUE}🔍 Linting Codebase...${NC}"
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo clippy -- -D warnings) || true
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_stream-server) && cargo clippy -- -D warnings) || true
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_backend-api) && golangci-lint run ./...) || true
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_web) && npm run lint) || true
|
||||
|
|
@ -64,16 +58,12 @@ lint-web: ## [MID] Lint web app only
|
|||
lint-backend-api: ## [MID] Lint Go backend only
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_backend-api) && golangci-lint run ./...)
|
||||
|
||||
lint-chat-server: ## [MID] Lint Chat server only
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo clippy -- -D warnings)
|
||||
|
||||
lint-stream-server: ## [MID] Lint Stream server only
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_stream-server) && cargo clippy -- -D warnings)
|
||||
|
||||
fmt: ## [MID] Format everything
|
||||
@$(ECHO_CMD) "${BLUE}✨ Formatting...${NC}"
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_backend-api) && go fmt ./...)
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo fmt)
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_stream-server) && cargo fmt)
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_web) && npm run format) || true
|
||||
|
||||
|
|
@ -85,13 +75,12 @@ load-test-backend: ## [MID] Run k6 backend full load test
|
|||
@command -v k6 >/dev/null 2>&1 || { $(ECHO_CMD) "${RED}❌ k6 missing. Install: brew install k6${NC}"; exit 1; }
|
||||
@k6 run $(ROOT)/loadtests/backend/full.js
|
||||
|
||||
load-test-all: load-test-backend ## [MID] Run all k6 load tests (backend, stream, chat)
|
||||
load-test-all: load-test-backend ## [MID] Run all k6 load tests (backend, stream)
|
||||
@k6 run $(ROOT)/loadtests/stream/http.js || true
|
||||
@k6 run $(ROOT)/loadtests/chat/websocket.js || true
|
||||
|
||||
status: ## [MID] Show system health & stats
|
||||
@$(ECHO_CMD) "${BOLD}DOCKER STATS:${NC}"
|
||||
@docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}" 2>/dev/null | grep -E "NAME|veza" || echo "No containers running"
|
||||
@$(ECHO_CMD) ""
|
||||
@$(ECHO_CMD) "${BOLD}LOCAL PORTS:${NC}"
|
||||
@lsof -i :$(PORT_backend-api) -i :$(PORT_chat-server) -i :$(PORT_stream-server) -i :$(PORT_web) 2>/dev/null | grep LISTEN || echo "No apps listening."
|
||||
@lsof -i :$(PORT_backend-api) -i :$(PORT_stream-server) -i :$(PORT_web) 2>/dev/null | grep LISTEN || echo "No apps listening."
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ install-deps: ## [LOW] Install code dependencies (all backends + npm workspaces)
|
|||
@$(ECHO_CMD) "${BLUE}📦 Installing dependencies...${NC}"
|
||||
@$(ECHO_CMD) " -> [Go] Downloading modules..."
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_backend-api) && go mod download)
|
||||
@$(ECHO_CMD) " -> [Rust Chat] Fetching crates..."
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_chat-server) && cargo fetch)
|
||||
@$(ECHO_CMD) " -> [Rust Stream] Fetching crates..."
|
||||
@(cd $(ROOT)/$(SERVICE_DIR_stream-server) && cargo fetch)
|
||||
@$(ECHO_CMD) " -> [Web] Installing npm packages..."
|
||||
|
|
@ -40,7 +38,7 @@ install-deps: ## [LOW] Install code dependencies (all backends + npm workspaces)
|
|||
|
||||
check-ports: ## [LOW] Check if ports are available
|
||||
@$(ECHO_CMD) "${BLUE}🔍 Checking ports...${NC}"
|
||||
@for port in $(PORT_backend-api) $(PORT_chat-server) $(PORT_stream-server) $(PORT_web); do \
|
||||
@for port in $(PORT_backend-api) $(PORT_stream-server) $(PORT_web); do \
|
||||
if lsof -i :$$port -t >/dev/null 2>&1; then \
|
||||
$(ECHO_CMD) "${YELLOW}⚠️ Port $$port is busy${NC}"; \
|
||||
else \
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# Usage: bash scripts/view_logs.sh [service] [options]
|
||||
#
|
||||
# Services disponibles:
|
||||
# backend-api, redis, db, rabbitmq, chat-server, stream-server, all
|
||||
# backend-api, redis, db, rabbitmq, stream-server, all
|
||||
#
|
||||
# Options:
|
||||
# -f, --follow Suivre les logs en temps réel (tail -f)
|
||||
|
|
@ -105,13 +105,6 @@ case $SERVICE in
|
|||
view_log "$LOG_DIR/rabbitmq.log" "RabbitMQ - Tous les logs"
|
||||
fi
|
||||
;;
|
||||
chat-server)
|
||||
if [ "$ERRORS_ONLY" = true ]; then
|
||||
view_log "$LOG_DIR/chat-server-error.log" "Chat Server - Erreurs"
|
||||
else
|
||||
view_log "$LOG_DIR/chat-server.log" "Chat Server - Tous les logs"
|
||||
fi
|
||||
;;
|
||||
stream-server)
|
||||
if [ "$ERRORS_ONLY" = true ]; then
|
||||
view_log "$LOG_DIR/stream-server-error.log" "Stream Server - Erreurs"
|
||||
|
|
@ -127,7 +120,6 @@ case $SERVICE in
|
|||
view_log "$LOG_DIR/redis-error.log" "Redis - Erreurs"
|
||||
view_log "$LOG_DIR/db-error.log" "Database - Erreurs"
|
||||
view_log "$LOG_DIR/rabbitmq-error.log" "RabbitMQ - Erreurs"
|
||||
view_log "$LOG_DIR/chat-server-error.log" "Chat Server - Erreurs"
|
||||
view_log "$LOG_DIR/stream-server-error.log" "Stream Server - Erreurs"
|
||||
else
|
||||
echo "💡 Astuce: Utilisez -e pour voir uniquement les erreurs"
|
||||
|
|
@ -143,7 +135,6 @@ case $SERVICE in
|
|||
echo " - redis"
|
||||
echo " - db"
|
||||
echo " - rabbitmq"
|
||||
echo " - chat-server"
|
||||
echo " - stream-server"
|
||||
echo " - all (vue d'ensemble)"
|
||||
exit 1
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ jobs:
|
|||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23'
|
||||
go-version: '1.24'
|
||||
check-latest: true
|
||||
|
||||
- name: Run tests with coverage
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ jobs:
|
|||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23'
|
||||
go-version: '1.24'
|
||||
check-latest: true
|
||||
|
||||
- name: Install govulncheck
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Build stage
|
||||
FROM golang:1.23-alpine AS builder
|
||||
FROM golang:1.24-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
|
|
|||
|
|
@ -136,10 +136,6 @@ RATE_LIMIT_REDIS_URL=redis://:password@host:6379
|
|||
PROMETHEUS_ENABLED=true
|
||||
PROMETHEUS_PORT=9090
|
||||
|
||||
# Chat Integration
|
||||
CHAT_SERVER_URL=http://chat-server:8081
|
||||
CHAT_JWT_SECRET=<32+ character secret>
|
||||
|
||||
# Stream Server Integration
|
||||
STREAM_SERVER_URL=http://stream-server:8082
|
||||
|
||||
|
|
@ -995,7 +991,7 @@ curl https://api.veza.com/healthz
|
|||
|
||||
```bash
|
||||
# Update base image
|
||||
docker pull golang:1.23-alpine
|
||||
docker pull golang:1.24-alpine
|
||||
|
||||
# Rebuild with security updates
|
||||
docker build --no-cache -f Dockerfile.production -t veza/backend-api:latest .
|
||||
|
|
|
|||
|
|
@ -1475,47 +1475,6 @@ docker logs veza-backend-api | grep -i "panic\|error\|fatal"
|
|||
|
||||
## Service Integration Issues
|
||||
|
||||
### Chat Server Integration
|
||||
|
||||
**Symptoms:**
|
||||
- Cannot get chat token
|
||||
- Chat connection fails
|
||||
- WebSocket errors
|
||||
|
||||
**Diagnosis:**
|
||||
|
||||
```bash
|
||||
# Check Chat Server
|
||||
curl http://chat-server:8081/health
|
||||
|
||||
# Test chat token endpoint
|
||||
curl http://localhost:8080/api/v1/chat/token \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
**Common Causes:**
|
||||
|
||||
1. **Chat Server Down**
|
||||
- Chat Server not running
|
||||
- Cannot connect
|
||||
|
||||
2. **Invalid Token**
|
||||
- Token generation failed
|
||||
- Token format incorrect
|
||||
|
||||
**Solutions:**
|
||||
|
||||
1. **Start Chat Server**
|
||||
```bash
|
||||
docker-compose up -d chat-server
|
||||
```
|
||||
|
||||
2. **Verify Integration**
|
||||
```bash
|
||||
# Check Chat Server URL
|
||||
echo $CHAT_SERVER_URL
|
||||
```
|
||||
|
||||
### Stream Server Integration
|
||||
|
||||
**Symptoms:**
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
// TODO: Réactiver chat_handlers après stabilisation du noyau et alignement des services (ChatService, MessageType, RoomType)
|
||||
// NOTE: Disabled (build ignore). Chat server removed; re-enable when chat service is reimplemented.
|
||||
|
||||
package handlers
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ func (c *Config) initMiddlewares() error {
|
|||
// SetupMiddleware configure les middlewares globaux
|
||||
// DÉPRÉCIÉ : Cette méthode est conservée pour compatibilité mais ne fait plus rien
|
||||
// Les middlewares globaux sont maintenant configurés dans internal/api/router.go via APIRouter.Setup()
|
||||
// TODO: Améliorer la configuration CORS dans api/router.go pour utiliser c.CORSOrigins depuis la config
|
||||
// NOTE: CORS could use c.CORSOrigins from config in api/router.go
|
||||
func (c *Config) SetupMiddleware(router *gin.Engine) {
|
||||
// No-op : Les middlewares sont configurés dans api/router.go
|
||||
// Cette méthode existe uniquement pour compatibilité avec cmd/main.go (legacy)
|
||||
|
|
|
|||
|
|
@ -577,20 +577,20 @@ func (d *Database) GetUserByOAuthID(oauthID, provider string) (*models.User, err
|
|||
|
||||
// CreateUser crée un nouvel utilisateur
|
||||
func (d *Database) CreateUser(user *models.User) error {
|
||||
// TODO: Implémenter avec vraie DB
|
||||
// NOTE: Stub for interface compatibility; main DB uses GORM
|
||||
return fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// UpdateUser met à jour un utilisateur existant
|
||||
func (d *Database) UpdateUser(user *models.User) error {
|
||||
// TODO: Implémenter avec vraie DB
|
||||
// NOTE: Stub for interface compatibility; main DB uses GORM
|
||||
return fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// GetUserByID récupère un utilisateur par son ID
|
||||
// MIGRATION UUID: Accepte maintenant uuid.UUID au lieu de int64
|
||||
func (d *Database) GetUserByID(userID uuid.UUID) (*models.User, error) {
|
||||
// TODO: Implémenter avec vraie DB
|
||||
// NOTE: Stub for interface compatibility; main DB uses GORM
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ func (h *DashboardHandler) aggregateStats(auditStats []*services.AuditStats, per
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Calculate change percentages (compare current period to previous period)
|
||||
// NOTE: Change percentages (vs previous period) could be added
|
||||
// This requires fetching stats for previous period, which is out of scope for initial implementation
|
||||
// Change percentages can be added in a follow-up task
|
||||
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ func (l *Logger) SetLevel(level zapcore.Level) error {
|
|||
// Note: Cette implémentation est simplifiée car zap ne permet pas facilement
|
||||
// de changer le niveau d'un logger déjà créé sans AtomicLevel
|
||||
// Pour un changement dynamique complet, il faudrait recréer le logger
|
||||
// TODO: Implémenter avec AtomicLevel lors de la création du logger
|
||||
// NOTE: AtomicLevel could be used for dynamic log level changes
|
||||
|
||||
// Si le logger n'utilise pas AtomicLevel, on ne peut pas changer le niveau dynamiquement
|
||||
// Dans ce cas, on retourne nil (pas d'erreur) car ce n'est pas critique
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ func (f *SecretFilterCore) Write(entry zapcore.Entry, fields []zapcore.Field) er
|
|||
// Appeler Write sur le core sous-jacent avec les champs filtrés
|
||||
// Le CheckedEntry appellera aussi f.core.Write après avec les champs ORIGINAUX
|
||||
// Cela cause un double encodage, mais c'est le seul moyen de filtrer les secrets
|
||||
// TODO: Trouver une solution pour éviter le double encodage
|
||||
// NOTE: Double encoding may occur; consider single-pass encoding
|
||||
err := f.core.Write(entry, filteredFields)
|
||||
// Ignore broken pipe errors in Write() to prevent zap from failing
|
||||
if err != nil && isBrokenPipeErrorSecretFilter(err) {
|
||||
|
|
|
|||
|
|
@ -46,8 +46,7 @@ var excludedRateLimitPaths = []string{
|
|||
"/api/v1/healthz",
|
||||
"/api/v1/readyz",
|
||||
"/api/v1/csrf-token",
|
||||
"/api/v1/auth/register",
|
||||
"/api/v1/auth/login",
|
||||
// v0.903: login/register no longer excluded - subject to global rate limit (100 req/min) + endpoint-specific limiters
|
||||
// SEC-009, SEC-010: refresh and check-username have EndpointLimiter, not excluded
|
||||
"/api/v1/auth/verify-email",
|
||||
"/api/v1/auth/resend-verification",
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ func (s *TrackSearchService) SearchTracks(ctx context.Context, params TrackSearc
|
|||
return nil, 0, fmt.Errorf("failed to count tracks: %w", err)
|
||||
}
|
||||
|
||||
// Apply sorting with computed fields
|
||||
// Apply sorting with computed fields (v0.903: whitelist for SQL injection prevention)
|
||||
sortOrder := "DESC"
|
||||
if params.SortOrder == "asc" {
|
||||
sortOrder = "ASC"
|
||||
|
|
@ -158,6 +158,14 @@ func (s *TrackSearchService) SearchTracks(ctx context.Context, params TrackSearc
|
|||
if sortBy == "" {
|
||||
sortBy = "created_at"
|
||||
}
|
||||
allowedSortFields := map[string]bool{
|
||||
"created_at": true, "updated_at": true, "duration": true,
|
||||
"title": true, "artist": true, "popularity": true,
|
||||
"play_count": true, "like_count": true, "comment_count": true, "relevance": true,
|
||||
}
|
||||
if !allowedSortFields[sortBy] {
|
||||
sortBy = "created_at"
|
||||
}
|
||||
|
||||
// Handle different sorting options
|
||||
switch sortBy {
|
||||
|
|
|
|||
|
|
@ -795,3 +795,57 @@ func TestTrackSearchService_SearchTracks_SortByCommentCount(t *testing.T) {
|
|||
assert.Equal(t, "Track With Comments", results[0].Title) // Most comments first
|
||||
assert.Equal(t, "Track Without Comments", results[1].Title)
|
||||
}
|
||||
|
||||
func TestTrackSearchService_SearchTracks_InvalidSortBy_FallbackToCreatedAt(t *testing.T) {
|
||||
// v0.903: SQL injection prevention - invalid sortBy falls back to created_at DESC
|
||||
service, db, userID, cleanup := setupTestTrackSearchService(t)
|
||||
defer cleanup()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Create test tracks
|
||||
track1 := &models.Track{
|
||||
UserID: userID,
|
||||
Title: "First Track",
|
||||
Artist: "Artist",
|
||||
FilePath: "/test/track1.mp3",
|
||||
FileSize: 5 * 1024 * 1024,
|
||||
Format: "MP3",
|
||||
Duration: 180,
|
||||
Genre: "Rock",
|
||||
IsPublic: true,
|
||||
Status: models.TrackStatusCompleted,
|
||||
}
|
||||
err := db.Create(track1).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
track2 := &models.Track{
|
||||
UserID: userID,
|
||||
Title: "Second Track",
|
||||
Artist: "Artist",
|
||||
FilePath: "/test/track2.mp3",
|
||||
FileSize: 6 * 1024 * 1024,
|
||||
Format: "FLAC",
|
||||
Duration: 200,
|
||||
Genre: "Pop",
|
||||
IsPublic: true,
|
||||
Status: models.TrackStatusCompleted,
|
||||
}
|
||||
err = db.Create(track2).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
// Malicious sortBy - should fallback to created_at DESC (no error, no SQL injection)
|
||||
maliciousSortBy := "invalid'; DROP TABLE tracks;--"
|
||||
results, total, err := service.SearchTracks(ctx, TrackSearchParams{
|
||||
SortBy: maliciousSortBy,
|
||||
Page: 1,
|
||||
Limit: 10,
|
||||
})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(2), total)
|
||||
assert.Len(t, results, 2)
|
||||
// Should return results (fallback to created_at DESC applied, no injection)
|
||||
assert.Contains(t, []string{results[0].Title, results[1].Title}, "First Track")
|
||||
assert.Contains(t, []string{results[0].Title, results[1].Title}, "Second Track")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ func TestInternalTrackStreamCallbackRoutes(t *testing.T) {
|
|||
// applies to all routes. This is a known issue that should be fixed by applying middleware
|
||||
// only to specific legacy routes, not via a global group.
|
||||
// For now, we accept that modern routes may have the Deprecated header due to this bug.
|
||||
// TODO: Fix router configuration to only apply DeprecationWarning to legacy routes
|
||||
// NOTE: DeprecationWarning could be scoped to legacy routes only
|
||||
_ = w.Header().Get("Deprecated") // Check exists but don't assert (known bug)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! Veza Common Library
|
||||
//!
|
||||
//! This library provides common types and utilities shared across
|
||||
//! all Veza services (backend, frontend, chat-server, stream-server).
|
||||
//! all Veza services (backend, frontend, stream-server).
|
||||
|
||||
pub mod types;
|
||||
pub mod utils;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ set -euo pipefail
|
|||
# Configuration
|
||||
NAMESPACE="veza-production"
|
||||
SERVICE_NAME="veza-stream-server"
|
||||
CHAT_SERVICE="veza-chat-server"
|
||||
|
||||
# Couleurs
|
||||
RED='\033[0;31m'
|
||||
|
|
@ -73,28 +72,12 @@ check_deployments() {
|
|||
FAILED_CHECKS=$((FAILED_CHECKS + 1))
|
||||
fi
|
||||
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
||||
|
||||
# Chat Server
|
||||
local chat_ready
|
||||
chat_ready=$(kubectl get deployment $CHAT_SERVICE -n $NAMESPACE -o jsonpath='{.status.readyReplicas}' 2>/dev/null || echo "0")
|
||||
local chat_desired
|
||||
chat_desired=$(kubectl get deployment $CHAT_SERVICE -n $NAMESPACE -o jsonpath='{.spec.replicas}' 2>/dev/null || echo "0")
|
||||
|
||||
if [ "$chat_ready" -eq "$chat_desired" ] && [ "$chat_desired" -gt 0 ]; then
|
||||
log_success "Chat Server: $chat_ready/$chat_desired pods prêts"
|
||||
PASSED_CHECKS=$((PASSED_CHECKS + 1))
|
||||
else
|
||||
log_error "Chat Server: $chat_ready/$chat_desired pods prêts"
|
||||
FAILED_CHECKS=$((FAILED_CHECKS + 1))
|
||||
fi
|
||||
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
||||
}
|
||||
|
||||
check_services() {
|
||||
log_info "=== Vérification des services ==="
|
||||
|
||||
run_check "Service Stream Server" "kubectl get service $SERVICE_NAME -n $NAMESPACE"
|
||||
run_check "Service Chat Server" "kubectl get service $CHAT_SERVICE -n $NAMESPACE"
|
||||
}
|
||||
|
||||
check_health_endpoints() {
|
||||
|
|
@ -118,25 +101,6 @@ check_health_endpoints() {
|
|||
FAILED_CHECKS=$((FAILED_CHECKS + 1))
|
||||
fi
|
||||
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
||||
|
||||
# Chat Server health
|
||||
local chat_ip
|
||||
chat_ip=$(kubectl get service $CHAT_SERVICE -n $NAMESPACE -o jsonpath='{.spec.clusterIP}' 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$chat_ip" ]; then
|
||||
if kubectl run health-test-chat --rm -i --restart=Never --image=curlimages/curl -- \
|
||||
curl -f -m 10 "http://$chat_ip:8080/health" &> /dev/null; then
|
||||
log_success "Chat Server health endpoint"
|
||||
PASSED_CHECKS=$((PASSED_CHECKS + 1))
|
||||
else
|
||||
log_error "Chat Server health endpoint"
|
||||
FAILED_CHECKS=$((FAILED_CHECKS + 1))
|
||||
fi
|
||||
else
|
||||
log_error "Chat Server IP non trouvée"
|
||||
FAILED_CHECKS=$((FAILED_CHECKS + 1))
|
||||
fi
|
||||
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
||||
}
|
||||
|
||||
check_database_connectivity() {
|
||||
|
|
@ -175,9 +139,6 @@ check_resource_usage() {
|
|||
echo "Pods Stream Server:"
|
||||
kubectl top pods -n $NAMESPACE -l app=$SERVICE_NAME 2>/dev/null || log_warning "Metrics server non disponible"
|
||||
|
||||
echo "Pods Chat Server:"
|
||||
kubectl top pods -n $NAMESPACE -l app=$CHAT_SERVICE 2>/dev/null || log_warning "Metrics server non disponible"
|
||||
|
||||
echo "Utilisation des nœuds:"
|
||||
kubectl top nodes 2>/dev/null || log_warning "Metrics server non disponible"
|
||||
}
|
||||
|
|
@ -187,9 +148,6 @@ check_recent_logs() {
|
|||
|
||||
echo "Logs Stream Server (dernières 10 lignes):"
|
||||
kubectl logs -n $NAMESPACE -l app=$SERVICE_NAME --tail=10 2>/dev/null || log_warning "Logs non disponibles"
|
||||
|
||||
echo "Logs Chat Server (dernières 10 lignes):"
|
||||
kubectl logs -n $NAMESPACE -l app=$CHAT_SERVICE --tail=10 2>/dev/null || log_warning "Logs non disponibles"
|
||||
}
|
||||
|
||||
# Rapport final
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ impl AnalyticsEngine {
|
|||
completion_percentage: 0.0,
|
||||
quality: quality.clone(),
|
||||
platform: platform.clone(),
|
||||
location: None, // TODO: Géolocalisation IP
|
||||
location: None, // NOTE: IP geolocation could be added
|
||||
referrer,
|
||||
ended: false,
|
||||
skip_reason: None,
|
||||
|
|
|
|||
2
veza-stream-server/src/cache/mod.rs
vendored
2
veza-stream-server/src/cache/mod.rs
vendored
|
|
@ -1,5 +1,5 @@
|
|||
pub mod audio_cache;
|
||||
// pub mod adaptive; // TODO: Implement adaptive cache
|
||||
// pub mod adaptive; // NOTE: Adaptive cache implementation deferred
|
||||
|
||||
// Type alias pour compatibilité avec main.rs
|
||||
pub type FileCache = audio_cache::AudioCache;
|
||||
|
|
|
|||
|
|
@ -410,7 +410,7 @@ pub async fn get_job_status_detailed(
|
|||
current_duration,
|
||||
progress,
|
||||
created_at: job.get::<chrono::DateTime<chrono::Utc>, _>("created_at").to_rfc3339(),
|
||||
started_at: None, // TODO: Ajouter started_at dans stream_jobs si nécessaire
|
||||
started_at: None, // NOTE: Add started_at to stream_jobs if needed
|
||||
completed_at: if job.get::<String, _>("status") == "done" {
|
||||
Some(job.get::<chrono::DateTime<chrono::Utc>, _>("updated_at").to_rfc3339())
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -617,7 +617,7 @@ pub fn init_logging_from_config(config: &crate::config::Config) -> Result<Struct
|
|||
let logging_config = LoggingConfig {
|
||||
level: config.monitoring.log_level.clone(),
|
||||
format: config.monitoring.log_format.clone(),
|
||||
file: None, // TODO: Ajouter configuration de fichier si nécessaire
|
||||
file: None, // NOTE: File output config could be added if needed
|
||||
rotation: None,
|
||||
filters: vec![],
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue