# Changelog - Veza ## [v0.603] - 2026-02-23 ### Added - Automatic Stripe Connect transfer after successful payment (webhook Hyperswitch) - Platform commission configurable via PLATFORM_FEE_RATE (default 10 %) - Migration 115 seller_transfers for transfer tracking - GET /sell/transfers endpoint for seller transfer history - Transfer History card in SellerDashboard - Unit tests: transfer success, multi-seller, transfer-fails ### Changed - ProcessPaymentWebhook now triggers seller transfers after license creation - PAYOUT_MANUAL.md updated for automatic transfer flow - Pre-v0.501 docs archived to docs/archive/ --- ## [v0.602] - 2026-02-23 ### Added - Stripe Connect seller payout (onboarding, balance) - seller_stripe_accounts migration (114) - Commerce E2E tests (backend integration: product -> order -> review -> invoice) - docs/SMOKE_TEST_V0602.md - docs/PAYOUT_MANUAL.md (manual payout procedure for v0.603) ### Changed - interceptors.ts split: auth.ts and error.ts extracted (facade < 30 LOC) - Grafana dashboards enriched with real Prometheus metrics - sanitizer.go: fix invalid regex backreference for object/embed tags (Go regexp has no \1) ### Infrastructure - Commerce Prometheus metrics (orders_total, checkout_duration) --- ## [v0.601] - 2026-02-23 ### Added - Blue-green deployment via HAProxy (backend-api-blue/green, stream-server-blue/green, deploy-blue-green.sh) - 3 Grafana dashboards: api-overview, chat-overview, commerce-overview - Alertmanager config with Slack/email receivers, wired to Prometheus - Hyperswitch LIVE_MODE configuration (HYPERSWITCH_LIVE_MODE env) - OAuth Discord and Spotify unit tests (GetAuthURL, GetUserInfo, GetAvailableProviders) - docs/MIGRATIONS.md documenting squash script and baseline procedure ### Changed - handler.go split into 4 sub-handlers: track_crud_handler, track_social_handler, track_search_handler, track_analytics_handler (~163 LOC facade) - interceptors.ts split into modules: interceptors/utils, interceptors/request, interceptors/response - squash_migrations.sh: baseline_v0601.sql, migrations 001-113, output to file ### Infrastructure - docker-compose.prod.yml: blue-green services, Alertmanager (port 9093) - config/alertmanager/alertmanager.yml - config/prometheus.yml: alertmanager_config --- ## [v0.503] - 2026-02-22 ### Added - HLS streaming end-to-end: backend serving routes (master.m3u8, quality playlists, segments) behind HLS_STREAMING feature flag - Redis-backed chat rate limiter with sliding window (sorted sets) and automatic in-memory fallback - ChatPresenceService with Redis-backed online/offline/heartbeat tracking (2min TTL) - PostgreSQL full-text search on messages: tsvector column, GIN index, auto-update trigger - MSW handlers for HLS endpoints (info, status, playlists) - HLS player integration in frontend: useHLSPlayer connected to useAudioPlayerLifecycle with ABR quality switching - StreamService.GetHLSStatus and TriggerHLSTranscode methods ### Changed - Chat rate limiter now uses Redis sliding window with in-memory fallback (was purely in-memory) - Chat message search now uses PostgreSQL ts_rank ordering (was ILIKE pattern matching) - Hub constructor now accepts ChatPresenceService for presence tracking ### Removed - veza-chat-server/ directory (deprecated Rust chat server) - All chat-server references from CI/CD workflows, monitoring, proxy config, Incus scripts, GitHub templates ### Infrastructure - Shared HLS volume between backend and stream-server in all docker-compose files - HLS_STREAMING and HLS_STORAGE_DIR environment variables added to backend service --- ## [v0.502] - 2026-02-22 ### Added - **Chat Server (Go)**: Full WebSocket chat server integrated into veza-backend-api at `/api/v1/ws` - **WebSocket Hub**: Client management with room-based broadcasting and user indexing - **Message Handlers**: SendMessage, EditMessage, DeleteMessage with ownership checks - **Room Handlers**: JoinConversation, LeaveConversation with permission enforcement - **History/Search/Sync**: Cursor-based FetchHistory, ILIKE SearchMessages, SyncMessages - **Real-time Features**: Typing indicators, read receipts, delivered status, message reactions - **WebRTC Signaling**: CallOffer, CallAnswer, ICECandidate, CallHangup, CallReject relay - **PermissionService**: CanRead, CanSend, CanJoin, CanModerate based on room_members - **RateLimiter**: Per-user per-action sliding window (in-memory) - **ChatPubSubService**: Redis PubSub for multi-instance broadcasting with in-memory fallback - **4 database migrations** (109-112): read_receipts, delivered_status, message_reactions, messages extra columns - **3 new GORM models**: ReadReceipt, DeliveredStatus, MessageReaction - **ChatMessageRepository enriched**: cursor pagination, search, soft delete - **ValidateChatToken**: JWT validation for WebSocket authentication - **15 unit tests**: Hub, message handlers, real-time handlers - **CHAT_FEATURE_PARITY.md**: 25-feature checklist (all OK or IMPROVED vs Rust) ### Changed - Frontend env.ts: WS_URL auto-derived from API_URL (no separate VITE_WS_URL needed) - Frontend types/index.ts: Added EditMessage, DeleteMessage, FetchHistory, SearchMessages, SyncMessages, MessageEdited, MessageDeleted, SearchResults, SyncChunk - MSW handler: chat/token returns ws_url: '/api/v1/ws' - WSUrl in ChatService.GenerateToken changed from `/ws` to `/api/v1/ws` ### Removed - **Rust chat server** (`veza-chat-server`) removed from docker-compose.yml, staging.yml, prod.yml - VITE_WS_URL environment variable from Docker frontend configs (auto-derived) - Dev hack for `127.0.0.1:8081` in useChat.ts ### Infrastructure - Docker: Single backend binary serves both REST API and Chat WebSocket - Redis PubSub: Enables horizontal scaling of chat (improvement over single-instance Rust) --- ## [v0.501] - 2026-02-22 ### Added - **HLS Multi-bitrate Streaming**: 3-tier adaptive bitrate (128k, 256k, 320k) with hls.js ABR - **Waveform Generation**: Async FFmpeg + audiowaveform pipeline with S3 storage and Redis cache - **WaveformDisplay Component**: Interactive SVG waveform with seek support - **Cloud Storage MVP**: Full folder/file management with 5GB quota per user - **Cloud Upload Modal**: Drag-and-drop with progress and quota validation - **Cloud File Preview**: Inline audio player for cloud files - **Gear Public Profiles**: is_public toggle, public endpoint, GearShowcase component - **Gear Image Gallery**: Multi-image support with carousel viewer - **Gear Search**: ILIKE-based search with frontend SearchBar - **MinIO Integration**: S3-compatible storage in all environments - **Prometheus Streaming Metrics**: 4 new counters (transcode duration, segments served, active connections, errors) - **useHLSPlayer Hook**: hls.js integration with ABR quality selection - **Container Scanning**: Trivy CI workflow for Docker images - **6 new database migrations** (103-108): waveform, cloud, gear images ### Changed - QualitySelector updated to 256kbps medium tier - Track handler split into 4 focused files (handler, upload, HLS, waveform) - Production console.log replaced with structured logger - Gear handler extended with search and image endpoints ### Infrastructure - MinIO added to docker-compose (dev, staging, prod) - HLS segment cache headers (immutable, 1-year max-age) - Migration squash script and MIGRATIONS.md documentation --- ## [v0.404] - 2026-02-22 ### Security - Ephemeral JWT stream-token endpoint for HLS/WebSocket auth (SEC-03) - SSRF protection: webhook URLs require HTTPS only (SEC-07) - IDOR fix in GetUploadStatus with ownership verification (SEC-06) - Hyperswitch webhook secret required in production (SEC-08) - Password reset tokens hashed with SHA-256 before storage (INF-10) - Docker hybrid compose removed (SEC-04) - CI credentials moved to GitHub Secrets (SEC-10) - JWT_SECRET added to stream-server in production compose (SEC-05) - Go version unified to 1.24 across Dockerfile and CI (SEC-09) - CD pipeline fixed (vars.* in conditions, Dockerfile.production) (SEC-01) - Redis authentication enabled in production compose (SEC-02) ### Infrastructure - Redis-backed rate limiter with in-memory fallback (INF-01) - PostgreSQL aligned to v16 in test environment (INF-02) - Frontend CI: lint, typecheck, build steps added (INF-03) - Backend CI: go vet + gofmt check added (INF-04) - Rust CI with clippy for chat and stream servers (INF-05) - CodeQL SAST scanning for Go and TypeScript (INF-06) - Complete staging compose with chat, stream, Caddy reverse proxy (INF-07) - Prometheus alerting rules for critical conditions (INF-08) - Docker healthchecks on all services (INF-09) ### Code Quality - 40 fmt.Printf replaced with zap structured logging (CLN-03) - ~45 `any` types eliminated in frontend production code (CLN-04) - TypeScript unified to 5.9.3 across all packages (CLN-06) - ~1600 LOC dead code removed (CLN-01) - gorilla/websocket replaced with coder/websocket (INT-06) - commerceService mock data replaced with real API calls (CLN-02) - Protobuf definitions centralized in proto/ directory (CLN-07) ### Documentation - ADR-001: Go+Rust architecture decision (CLN-08) - ADR-002: Chat server Rust->Go migration plan (INT-01) - FEATURE_STATUS.md aligned with actual code state (CLN-05) - PROJECT_STATE.md updated with v0.404 metrics (FIN-02) ### Testing - 5 cross-service E2E integration tests (INT-03) - 51 unit tests added across Rust services (INT-05) - 2 skipped backend tests fixed, 11 clarified (INT-04) ### Integration - HLS transcoding triggered after track upload (INT-02) --- ## [v0.402] - 2026-02-21 ### Added - **Lot P1 — Checkout Hyperswitch production-ready** - Return URL with `order_id` for success/error pages - CheckoutSuccessView, CheckoutErrorView, CheckoutCompletePage - Route `/checkout/complete` (protected) - Webhook: handle `cancelled` status in ProcessPaymentWebhook - CheckoutPaymentForm (Hyperswitch) in Cart when `client_secret` returned - marketplaceService.getOrder(orderId) - **Lot P2 — Codes promo / réductions** - Migrations 099 (promo_codes), 100 (orders discount fields) - PromoCode model, ValidatePromoCode, validatePromoCodeTx - GET /commerce/promo/:code - CreateOrder and Checkout accept `promo_code` (percent/fixed) - PromoCodeModal connected to validatePromoCode API - Cart: PromoCodeModal, OrderSummary with discount, promo_code at checkout - MSW handlers for promo, orders/:id, checkout with promo_code - Stories: CheckoutSuccessView, CheckoutErrorView, PromoCodeModal ### Changed - CreateOrder signature: promoCode string parameter - Cart.Checkout: promoCode parameter - OrderSummary integrated in Cart with discount support --- ## [v0.401] - 2026-02-22 ### Added - **Lot M1 — Produits & Catalogue** - Migrations 095-097 : products enrichment (bpm, musical_key, category), product_previews, product_images - ProductPreview, ProductImage models, CreateProduct/UpdateProduct accept bpm, musical_key, category - POST /marketplace/products/:id/preview (audio preview upload) - PUT /marketplace/products/:id/images - GET /marketplace/products/:id/preview (stream audio) - ListProducts filters: bpm, musical_key, category - CreateProductView connected to enriched API, BPM/Key/Category filters in MarketplaceHome - ProductDetailView: playable preview, image gallery - Rich text description (sanitization backend, toolbar Bold/List frontend) - **Lot M2 — Licences & Droits** - Migration 098 : product_licenses (license_type, price_cents, terms_text) - ProductLicense model, SetProductLicenses, GetProductLicenses - CreateProduct/UpdateProduct accept licenses array - GET /marketplace/licenses/mine (user's purchased licenses with download_url) - LicenceCard, LicenceDetailsModal: license_type, price_cents, terms_text - LicensesView in PurchasesPage with download links - **Lot M3 — Seller dashboard enrichi** - GET /sell/stats/evolution (day/week/month) - GET /sell/stats/top-products - GET /sell/sales (real sales data) - commerceService: getSales, getSellerStatsEvolution, getSellerTopProducts (real API) - SalesEvolutionChart (Recharts LineChart) - Top Products section with real revenue/sales_count - Conversion rate: N/A when no tracking ### Changed - Marketplace products: bpm, musical_key, category, previews, images, licenses - SellerDashboardView: real data, evolution chart, top products from API --- ## [v0.303] - 2026-02-22 ### Added - **Lot C2 — Chat appels WebRTC 1-to-1** - Chat Server : signalisation CallOffer, CallAnswer, ICECandidate, CallHangup, CallReject - WebSocketManager.send_to_user pour livraison 1-to-1 - RateLimitAction::CallSignaling (60 req/min) - Frontend : useWebRTC hook, CallButton, IncomingCallModal, ActiveCallBar - Appels audio 1-to-1 dans conversations DM --- ## [v0.302] - 2026-02-21 ### Added - **Lot S2 — Groupes avancés** - Demander à rejoindre (groupes privés), approbation/rejet par admin - Inviter membres par email ou user_id - Rôles assign/revoke (admin, moderator, member) - Feed type=groups (posts des membres des groupes) - GET /social/groups/mine - Migrations 069, 089, 092 - **Lot N1 — Notifications push Web** - POST /notifications/push/subscribe, PushService (webpush-go) - Envoi push sur follow/like/comment/message (selon préférences) - GET/PUT /notifications/preferences - Migrations 090, 093 - Frontend : subscribePush, PushPreferencesSection, badge document.title - **Lot P2 — Présence enrichie** - PUT /users/me/presence (status_message, track_id, track_title, invisible) - Rich presence : sync track en cours via usePresenceSync - Mode invisible (GetPresenceForViewer masque pour les autres) - PresenceBadge statusMessage tooltip - Migrations 091, 094 ### Changed - NotificationService : SetPushService, envoi push post-CreateNotification - Shared NotificationService avec PushService pour profile, track, comment handlers ### Deferred (v0.303) - **Lot C2** : Livré en v0.303 --- ## [v0.301] - 2026-02-20 ### Added - **Lot P0 — Chat Server** - Protocole typing aligné : `{ type: 'Typing', conversation_id, is_typing }` - Limitation JWT auth (query param) documentée pour v0.302 - **Lot C1 — Chat avancé** - Typing indicators end-to-end (UserTyping, setUserTyping) - Read receipts (MarkAsRead, MessageRead, « Vu à HH:mm ») - Delivered status (Delivered, MessageDelivered) - **Lot P1 — Présence** - Migration 088 user_presence (status, last_seen_at, status_message) - PresenceService, GET /users/:id/presence - Mise à jour last_seen_at sur chaque requête authentifiée - PresenceBadge, usePresence, intégration ChatSidebar - **Lot S1 — Social enrichi** - Feed connecté à socialService.getFeed (remplace trackService.list) - Backend : enrichissement actor_name, actor_avatar, track dans GetGlobalFeed - SocialViewFeedItem : posts texte + posts avec track (mini player) - Pagination cursor (next_cursor), useInfiniteQuery, Load More - GET /social/explore (trending + suggested_users), onglet Explore - Filtres feed : all | following | groups (param type, OptionalAuth pour following) ### Changed - useSocialView : socialService.getFeed, useInfiniteQuery, feedFilter - SocialView : onglet Explore, filtres feed - AuthMiddleware : SetPresenceService, UpdatePresence sur RequireAuth ### Documented - FEATURE_STATUS, PROJECT_STATE mis à jour pour v0.301 --- ## [v0.203] - 2026-02-20 ### Added - **Lot L — Social Trending** - GET /social/trending (extraction hashtags posts 7 jours, agrégation) - Cache Redis 15 min (clé trending:hashtags) - SocialViewTrending connecté à l’API (Loading, Error, Empty fallback) - MSW handler GET */api/v1/social/trending - **Lot K — Recherche enrichie** - Migration 086 pg_trgm pour fuzzy search - TrackSearchService : similarity() sur title/artist/album (PostgreSQL), fallback ILIKE (SQLite) - query_parser.go : AND, OR, NOT, "phrase exacte" - SearchService + TrackSearchService utilisent le parser - SearchPageHeader : tooltip aide syntaxe - **Lot D1 — Queue collaborative** - Migration 087 queue_sessions, shared_queue_items - Modèles QueueSession, SharedQueueItem - QueueSessionService : Create, Get, Delete, Add/Remove items - POST/GET/DELETE /queue/session, POST/DELETE /queue/session/:token/items - PlayerQueue : bouton Partager, badge Queue partagée, polling 8 s - queueSessionStore, useQueueSync mode session - MSW handlers pour queue session ### Changed - SocialViewTrending : useQuery, skeletons, erreur → fallback tags - TrackSearchService : dialect sqlite → LIKE, postgres → similarity - SearchService : BuildWhereCondition pour requêtes booléennes - PlayerQueue : mode session, partage lien, sync session - useQueueSync : skip sync personnelle quand session active ### Documented - FEATURE_STATUS, PROJECT_STATE mis à jour pour v0.203 --- ## [v0.202] - 2026-02-20 ### Added - **Lot G — Recherche avancée** - Filtre musical_key dans track_search (G1) - Tri pertinence (relevance) dans SearchService (G2) - Autocomplete : GET /search/suggestions, dropdown debounced (G3) - Facettes type (tracks/artistes/playlists/users) dans SearchPage (G4) - Historique recherche localStorage (G5) - **Lot H — Analytics créateur** - GET /analytics/creator/stats, carte Completion Rate (H1) - GET /analytics/creator/charts, graphiques (H2) - Taux de complétion intégré dashboard (H3) - GET /analytics/creator/export CSV/JSON (H4) - **Lot F — Seller dashboard** - GET /sell/stats, connexion commerceService (F1) - Support seller_id=me dans ListProducts (F2) - **Lot C — Player avancé** - Crossfade configurable (1–12 s) depuis Settings (C1) - Gapless préchargement via preloadTrack (C2) - PiP (Picture-in-Picture) si supporté (C3) - **Lot D — Autoplay** - GET /tracks/recommendations (auth), section « À écouter ensuite » dans PlayerQueue (D2) ### Changed - SearchPage : onglets type, suggestions dropdown, historique récent - AnalyticsViewKpiGrid : métrique Completion Rate - AnalyticsViewChart : graphiques creator - SettingsPage : slider crossfade - PlayerQueue : recommandations quand queue vide (authentifié) - PlayerStore : crossfadeSeconds, préchargement ~5 s avant fin ### Documented - D1 (queue collaborative) reporté v0.203+ - V0_202_RELEASE_SCOPE.md, FEATURE_STATUS.md, PROJECT_STATE.md mis à jour --- ## [v0.201] - 2026-02-20 ### Added - **Lot E — Métadonnées enrichies** - BPM : champ dans Track model, UpdateTrack, filtre track_search (E1) - Musical key : champ, input/select édition, affichage TrackDetailPageInfo (E2) - Lyrics : table track_lyrics, GET/PUT /tracks/:id/lyrics, section Paroles avec toggle (E3) - Tags suggérés : GET /tracks/suggested-tags?genre=X, migration tracks.tags, chips + dropdown (E4) ### Changed - Track model : BPM, MusicalKey, Tags (pq.StringArray) - TrackDetailPageInfo : affichage BPM, key, tags - TrackMetadataEditModal : édition BPM, musical_key, tags avec suggestions ### Documented - Lot G (Recherche avancée), H (Analytics), F (Seller), C (Player), D (Queue) reportés v0.202+ --- ## [v0.103] - 2026-02-20 ### Added - **Auth (Lot A)** : OAuth Spotify (A1), page Sessions enrichie avec historique et révocation (A4) - **Profils (Lot B)** : Bannière de profil éditable (B1), section liens sociaux sur profil public (B2), toggle profil privé dans Settings (B3) - **Profil privé** : Vue « Profil privé » sur `/u/:username` quand le profil est masqué ; `is_public` exposé et persisté ### Documented - 2FA SMS et Passkeys/WebAuthn reportés à v0.104 --- ## [v0.102] - 2026-02-20 ### Added - **Queue persistante** : API CRUD (`GET/PUT/POST/DELETE /api/v1/queue`), sync frontend via `useQueueSync`, drag & drop reorder avec @dnd-kit (B3) - **Developer API Keys** : CRUD clés API, X-API-Key middleware, CreateAPIKeyModal, révocation - **Playlists** : activation PLAYLIST_SHARE, PLAYLIST_RECOMMENDATIONS ; boutons Export (JSON/CSV), Duplicate connectés - **Social** : like/comment post connectés à l’API ; profil followers/following count ; badges rôles - **Player** : playback speed (0.5x–2x), Media Session API, waveform dans progress bar ### Changed - **Gear, Live, Queue, Developer** : routes opérationnelles (fin des placeholders Coming Soon) - Feature flags PLAYLIST_SHARE et PLAYLIST_RECOMMENDATIONS activés (true) ### Documented - Go Live (streaming vidéo) : non implémenté, prévu v0.703 — limitation A6 - Social Trending (tags) : statique, report v0.103 pour `GET /social/trending` --- ## [Unreleased] - 2024-12-07 ### Security - **chat-server**: Implemented JWT Authentication Middleware for HTTP API. - Secured `/api/messages` (POST) and `/api/messages/{id}` (GET). - Enforced permission checks (`can_send_message`, `can_read_conversation`). - Patched `sender_id` spoofing vulnerability by enforcing User ID from Token Claims. - **backend**: Resolved `veza_errors_total` metric collision preventing proper monitoring initialization. ### Fixed - **backend**: Fixed `JobWorker` starvation issue by replacing blocking `time.Sleep` with non-blocking scheduler. - **stream-server**: Improved task safety by replacing unsafe `abort()` with graceful `join/await` for monitoring tasks. - **chat-server**: Fixed resource leak by implementing 60s WebSocket inactivity/heartbeat timeout. - **chat-server**: Implemented Graceful Shutdown handling for OS signals (SIGTERM/SIGINT). - **backend-tests**: Fixed `RoomHandler` unit tests. - Refactored `RoomHandler` to use `RoomServiceInterface` for dependency injection. - Updated `CreateRoom` tests to match actual Service signatures. - Fixed `bitrate_handler_test.go` compilation errors. - Resolved global metric registration panics during testing. ### Removed - **backend**: Deleted legacy maintenance code (`migrations_legacy/` and `src/cmd/main.go.legacy`). ### Known Issues - **backend**: Some unit tests (`metrics_test.go`, `profile_handler_test.go`, `system_metrics_test.go`) are disabled due to bitrot/missing dependencies. - **stream-server**: Compilation requires active Database connection (sqlx compile-time verification) or `sqlx-data.json`.