diff --git a/CHANGELOG.md b/CHANGELOG.md index 040104aa7..340d97e18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog - Veza +## [v0.971] - 2026-03-02 + +### Removed +- Gamification phantom features (components, MSW if any) — reporté v1.3 + +### Added +- WEBRTC_CALLS feature flag with Beta badge and tooltip on CallButton +- docs/V1_LIMITATIONS.md +- docs/API_VERSIONING_POLICY.md +- Migration 936: WEBRTC_CALLS flag +- GET /api/v1/feature-flags for authenticated users (client-visible flags) +- adminService.getClientFeatureFlags() +- MSW handler for GET /api/v1/feature-flags + +### Changed +- CallButton: Badge "Beta", tooltip "Fonctionne mieux sur le même réseau local" +- ChatRoom: fetches WEBRTC_CALLS, shows CallButton only when enabled +- FEATURE_STATUS: Gamification → Abandonné v1.0, WebRTC → Beta LAN only +- PROJECT_STATE: dernier tag v0.971, prochaine v0.981 + +--- + ## [v0.951] - 2026-03-02 ### Added diff --git a/VERSION b/VERSION index 233eed873..e07468e8c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.951 +0.971 diff --git a/apps/web/src/features/chat/components/CallButton.tsx b/apps/web/src/features/chat/components/CallButton.tsx index 4b648ca17..16bc5000d 100644 --- a/apps/web/src/features/chat/components/CallButton.tsx +++ b/apps/web/src/features/chat/components/CallButton.tsx @@ -1,4 +1,6 @@ import { Button } from '@/components/ui/button'; +import { Badge } from '@/components/ui/badge'; +import { Tooltip } from '@/components/ui/tooltip'; import { Phone } from 'lucide-react'; interface CallButtonProps { @@ -15,15 +17,18 @@ export function CallButton({ disabled = false, }: CallButtonProps) { return ( - + + + ); } diff --git a/apps/web/src/features/chat/components/ChatRoom.tsx b/apps/web/src/features/chat/components/ChatRoom.tsx index 0f51df513..ac8981ab0 100644 --- a/apps/web/src/features/chat/components/ChatRoom.tsx +++ b/apps/web/src/features/chat/components/ChatRoom.tsx @@ -15,6 +15,7 @@ import { import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; import { useUser } from '@/features/auth/hooks/useUser'; +import { adminService } from '@/services/adminService'; interface ChatRoomProps { conversationId: string; @@ -28,11 +29,19 @@ export const ChatRoom: React.FC = ({ conversationId }) => { const webrtc = useWebRTC({ sendMessage: sendRawMessage }); const messagesEndRef = useRef(null); const [showSearch, setShowSearch] = useState(false); + const [webrtcEnabled, setWebrtcEnabled] = useState(true); const [highlightedMessageId, setHighlightedMessageId] = useState< string | null >(null); const highlightTimeoutRef = useRef | null>(null); + useEffect(() => { + adminService.getClientFeatureFlags().then((flags) => { + const webrtc = flags.find((f) => f.name === 'WEBRTC_CALLS'); + setWebrtcEnabled(webrtc?.enabled ?? true); + }).catch(() => setWebrtcEnabled(true)); + }, []); + // Cleanup highlight timeout on unmount useEffect(() => { return () => { @@ -167,7 +176,7 @@ export const ChatRoom: React.FC = ({ conversationId }) => { ) : (
- {isDM && targetUserId && ( + {isDM && targetUserId && webrtcEnabled && ( { return HttpResponse.json({ feature_flags: [ @@ -309,6 +309,20 @@ export const handlersAdmin = [ { name: 'ROLE_MANAGEMENT', enabled: true, description: 'Enable role management' }, { name: 'PLAYLIST_SHARE', enabled: true, description: 'Enable playlist sharing' }, { name: 'PLAYLIST_RECOMMENDATIONS', enabled: true, description: 'Enable playlist recommendations' }, + { name: 'WEBRTC_CALLS', enabled: true, description: 'WebRTC audio calls — Beta' }, + ], + }); + }), + + // v0.971: Client feature flags (authenticated users) + http.get('*/api/v1/feature-flags', () => { + return HttpResponse.json({ + feature_flags: [ + { name: 'HLS_STREAMING', enabled: true }, + { name: 'ROLE_MANAGEMENT', enabled: true }, + { name: 'PLAYLIST_SHARE', enabled: true }, + { name: 'PLAYLIST_RECOMMENDATIONS', enabled: true }, + { name: 'WEBRTC_CALLS', enabled: true }, ], }); }), diff --git a/apps/web/src/services/adminService.ts b/apps/web/src/services/adminService.ts index 978d70c9c..bb8d635a5 100644 --- a/apps/web/src/services/adminService.ts +++ b/apps/web/src/services/adminService.ts @@ -106,6 +106,12 @@ export const adminService = { return response.data?.feature_flags ?? []; }, + /** v0.971: Client-visible flags for any authenticated user (e.g. WEBRTC_CALLS) */ + getClientFeatureFlags: async () => { + const response = await apiClient.get<{ feature_flags: { name: string; enabled: boolean }[] }>('/feature-flags'); + return response.data?.feature_flags ?? []; + }, + toggleFeatureFlag: async (name: string, enabled: boolean) => { await apiClient.put(`/admin/feature-flags/${encodeURIComponent(name)}`, { enabled }); return { success: true }; diff --git a/docs/API_VERSIONING_POLICY.md b/docs/API_VERSIONING_POLICY.md new file mode 100644 index 000000000..de2b58762 --- /dev/null +++ b/docs/API_VERSIONING_POLICY.md @@ -0,0 +1,33 @@ +# Politique de versioning API — Veza v1.0 + +**Référence** : v0.971 +**Contrat stable** : `/api/v1/` + +## 1. Routes stables vs beta + +| Type | Exemple | Engagement | +|------|---------|------------| +| **Stable** | `/api/v1/tracks`, `/api/v1/auth/*`, `/api/v1/playlists`, `/api/v1/marketplace/*` | Rétro-compatibilité garantie pour v1.x | +| **Beta** | Fonctionnalités derrière feature flag (ex. WEBRTC_CALLS) | Peut évoluer sans préavis en v1.x | + +## 2. Politique de dépréciation + +- Les routes dépréciées conservent un header `X-API-Deprecated: true` et une date de fin de vie dans la réponse. +- Période de dépréciation : minimum 6 mois avant suppression. +- Documentation : `API_REFERENCE.md` et Swagger reflètent le statut des routes. + +## 3. Headers de version + +- `X-API-Version: v1` — optionnel, le path `/api/v1/` suffit. +- `Accept: application/vnd.veza.v1+json` — supporté pour content negotiation. + +## 4. Engagement rétro-compatibilité v1.x + +- Aucun breaking change sur les routes stables pendant v1.x. +- Les ajouts (nouveaux champs, nouvelles routes) sont rétro-compatibles. +- En cas de breaking change : nouvelle version majeure (v2). + +## 5. Breaking changes v0.803 → v1.0 + +- **Pagination cursor** : certains endpoints utilisent `cursor` / `next_cursor` au lieu de `page` / `limit` (v0.931). +- Voir `CHANGELOG.md` pour la liste complète des changements. diff --git a/docs/FEATURE_STATUS.md b/docs/FEATURE_STATUS.md index fe76d06db..5ee50e725 100644 --- a/docs/FEATURE_STATUS.md +++ b/docs/FEATURE_STATUS.md @@ -1,6 +1,6 @@ # Statut des fonctionnalités — Veza -**Dernière mise à jour** : février 2026 — v0.803 livrée (Sécurité, Compliance, Modération, Maintenance, Annonces, Feature flags) +**Dernière mise à jour** : mars 2026 — v0.971 (Phantom: gamification supprimé, WebRTC Beta) Ce document décrit le statut réel des fonctionnalités par rapport au code. @@ -34,7 +34,12 @@ Ce document décrit le statut réel des fonctionnalités par rapport au code. |---------|-------------|--------| | **Studio** (Cloud File Browser) | Supprimé | Dossier supprimé | | **Education** | Supprimé | Dossier supprimé | -| **Gamification** (achievements, leaderboard) | MSW handlers | api_manager archivé (internal/api/archive/), MSW uniquement | + +## Abandonné v1.0 (reporté versions futures) + +| Feature | Version cible | +|---------|---------------| +| **Gamification** (achievements, leaderboard, XP) | v1.3 — supprimé v0.971 (phantom) | ## Fonctionnalités désactivées (feature flags) @@ -50,6 +55,7 @@ Ce document décrit le statut réel des fonctionnalités par rapport au code. | Feature | Limitation | Version cible | |---------|------------|--------------| | **Go Live** (streaming vidéo) | Livré v0.703 — page /live/go-live, stream key, OBS instructions | — | +| **Appels WebRTC** | Beta — fonctionne mieux sur le même réseau local (TURN/STUN v1.1) | v1.1 (flag WEBRTC_CALLS) | | **2FA SMS** | Option « Envoyer par SMS » pendant la vérification 2FA — requiert infra Twilio + users.phone_number | v0.104 | | **Passkeys / WebAuthn** | Login sans mot de passe — requiert go-webauthn, table webauthn_credentials, frontend navigator.credentials | v0.104 | diff --git a/docs/PROJECT_STATE.md b/docs/PROJECT_STATE.md index 114d87858..a944e4323 100644 --- a/docs/PROJECT_STATE.md +++ b/docs/PROJECT_STATE.md @@ -1,4 +1,4 @@ -# État du projet Veza — Février 2026 +# État du projet Veza — Mars 2026 **Document opérationnel** : Où en sommes-nous, quelles sont les prochaines étapes. @@ -8,10 +8,10 @@ | Élément | Valeur | |---------|--------| -| **Dernier tag** | v0.803 | +| **Dernier tag** | v0.971 | | **Branche courante** | `main` | -| **Phase** | Phase 8 — Polish & Scale | -| **Prochaine version** | v0.901 | +| **Phase** | Phase 9 — v1.0 Launch | +| **Prochaine version** | v0.981 (Beta) | --- diff --git a/docs/V1_LIMITATIONS.md b/docs/V1_LIMITATIONS.md new file mode 100644 index 000000000..80c698bc5 --- /dev/null +++ b/docs/V1_LIMITATIONS.md @@ -0,0 +1,21 @@ +# Limitations v1.0 — Veza + +Ce document liste les fonctionnalités **non incluses** dans la v1.0 et leur version cible. + +| Feature | Limitation | Version cible | +|---------|------------|---------------| +| **WebRTC TURN/STUN** | Appels audio fonctionnent mieux sur le même réseau local. Pas de serveur TURN pour NAT symétrique. | v1.1 | +| **2FA SMS** | Envoi code par SMS pendant vérification 2FA — requiert infra Twilio. | v1.1 | +| **Passkeys / WebAuthn** | Login sans mot de passe. | v1.2 | +| **Live RTMP réel** | Streaming vidéo live — infrastructure RTMP/TLS. | v1.2 | +| **Gamification** | XP, achievements, leaderboards — supprimé v0.971. | v1.3 | +| **Studio** | Cloud File Browser — abandonné. | — | +| **Education** | Cours, certificats — abandonné. | — | +| **Mobile app** | Apps natives iOS/Android — abandonné pour v1.0. | — | +| **Redis HA** | Haute disponibilité Redis (Sentinel, clustering). | v1.1 | +| **PostgreSQL replication** | Read replicas, streaming replication. | v1.1 | + +## Notes + +- WebRTC : flag `WEBRTC_CALLS` activé par défaut, badge "Beta" sur le bouton d'appel. +- Gamification : composants et handlers MSW supprimés en v0.971 (Phantom). diff --git a/veza-backend-api/internal/api/routes_core.go b/veza-backend-api/internal/api/routes_core.go index 7bd010c16..8a85be907 100644 --- a/veza-backend-api/internal/api/routes_core.go +++ b/veza-backend-api/internal/api/routes_core.go @@ -317,6 +317,11 @@ func (r *APIRouter) setupCoreProtectedRoutes(v1 *gin.RouterGroup) { reportHandlerForUser := handlers.NewReportHandler(reportServiceForUser) protected.POST("/reports", reportHandlerForUser.CreateReport) + // v0.971: Client-visible feature flags (e.g. WEBRTC_CALLS for CallButton) + featureFlagSvc := services.NewFeatureFlagService(r.db.GormDB, r.logger) + featureFlagHandler := handlers.NewFeatureFlagHandler(featureFlagSvc) + protected.GET("/feature-flags", featureFlagHandler.List) + audit := protected.Group("/audit") { audit.GET("/logs", auditHandler.SearchLogs()) diff --git a/veza-backend-api/migrations/936_webrtc_flag.sql b/veza-backend-api/migrations/936_webrtc_flag.sql new file mode 100644 index 000000000..3d6176b64 --- /dev/null +++ b/veza-backend-api/migrations/936_webrtc_flag.sql @@ -0,0 +1,4 @@ +-- v0.971: WEBRTC_CALLS feature flag (Beta, works best on same network) +INSERT INTO feature_flags (name, enabled, description) VALUES + ('WEBRTC_CALLS', true, 'WebRTC audio calls — Beta, works best on same network') +ON CONFLICT (name) DO NOTHING;