Commit graph

1563 commits

Author SHA1 Message Date
senke
41eacaf97d ci: add npm audit and govulncheck to main CI (P3.4)
- Add govulncheck to backend-go job
- Add npm audit --audit-level=high to frontend job
- Both use || true to avoid blocking CI on existing vulns

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 22:15:22 +01:00
senke
3b2ff9faa8 test(web): add unit tests for chat feature (P3.3)
- ChatMessages: fix mock structure, align with store shape (messages Record, conversations)
- ChatInput: add tests for render, submit, disabled state
- ChatMessage: add tests for content, reactions, addReaction
- fix ChatMessage.tsx: remove stray // ... comment

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 22:15:13 +01:00
senke
a6bafcbcc5 feat(web): externalize feature flags via VITE_FEATURE_* env vars (P3.2)
- Parse VITE_FEATURE_* from env with fallback to current defaults
- Add all flags to .env.example and ENV_CONFIG.md
- parseFeatureEnv accepts true/1/yes for enabled

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 22:11:38 +01:00
senke
55fbeb9e48 feat(stream): add JWT revocation persistante Redis (P3.1)
- Add SessionRevocationStore trait with InMemoryRevocationStore and RedisRevocationStore
- Wire Redis store when REDIS_URL in config.cache, fallback in-memory
- Session revocation by session_id persists across restarts when using Redis

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 22:10:07 +01:00
senke
27722db148 feat(chat): add JWT revocation persistante Redis (P3.1)
- Add JwtRevocationStore trait with InMemoryRevocationStore and RedisRevocationStore
- Wire Redis store when REDIS_URL is set (fallback in-memory if Redis unavailable)
- JWT blacklist persists across restarts when using Redis

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 22:06:25 +01:00
senke
48ccb8527d fix(chat): restore compilation - add reactions module, imports, request_id param
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 22:04:11 +01:00
senke
bbbe557eca ci: add npm audit, govulncheck, cargo audit to CI
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 21:33:27 +01:00
senke
430cc5eef6 fix(security): validate exec.Command paths in Go services
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 21:32:38 +01:00
senke
816676906a docs: mark veza-mobile as abandoned, document ghost features
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 21:31:22 +01:00
senke
51869a3649 fix(deps): upgrade gin to 1.11
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 21:31:00 +01:00
senke
f52858f14b fix(security): validate OAuth redirect URL against allowlist, require auth for internal transcode endpoint
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 21:28:26 +01:00
senke
ceec16fbd5 fix(security): upgrade axios to fix CVE
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:51:39 +01:00
senke
7f63bc6641 fix(security): remove hardcoded credentials from stream server auth
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:50:17 +01:00
senke
44ddd3b858 chore(incus): add env template, document setup
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:49:01 +01:00
senke
d7bb127920 fix(security): stop tracking veza-stream-server/.env and config/incus env files
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:48:51 +01:00
senke
a1ce2d0c9f docs: baseline pré-remédiation
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 19:48:01 +01:00
senke
c458b7c597 fix(tests): cycle 20 – PlaylistForm flaky tests
- fireEvent.change/click au lieu de userEvent pour create/update/custom onSubmit
- description max length: fireEvent pour éviter timeout (2001 chars)
- expect.objectContaining pour assertions plus résilientes
- RAPPORT: cycle 20

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 09:51:44 +01:00
senke
1e2093f79b fix(tests): cycle 19 – playlistService MSW et handlers
- Supprimer handler wildcard playlists* qui masquait les spécifiques
- Réordonner: search et recommendations avant :id (évite id=search/recommendations)
- Handlers: GET recommendations, POST :id/share, search avec query empty
- list items: ajout title
- create: body.title → data.title/name, track_count, like_count
- Tests: addTrack(plId,trackId), removeTrack, createShareLink(plId)
- Assertions: getRecommendations.playlists, update retourne objet
- RAPPORT: cycle 19

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 09:48:36 +01:00
senke
ccc233e1ea fix(tests): cycles 12–18 – corrections services, mocks et design tokens
- chatService: getChannels → getServers
- commerceService: getOrders/getOrderDetails/getSalesStats → getPurchases/getSellerStats
- marketplaceService: mock réponse, params API, getDownloadLink → listOrders
- config/env.test: vi.stubEnv, import dynamique
- useAuth.test: mock useAuthStore
- TrackStatsDisplay, UploadQuota: mock du bon service (analyticsService, uploadService)
- TrackListEmpty, TrackListRow, TrackSearch: design tokens, assertions
- trackDownloadService, chunkedUploadService: MSW/server.use
- trackListService, trackSearchService, trackShareService: assertions
- ErrorBoundary, LoginForm, PlaylistErrorBoundary, PlaylistRecommendations
- RAPPORT_RESOLUTION_TESTS_CYCLE1.md

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 09:43:55 +01:00
senke
ef430d9f16 style(ui): pixel-perfect alignment for Sidebar, Header, Player via Spotify/Discord standard
- PlayerBarGlass: use semantic tokens (--player-glass-bg, --player-glass-border)
- Replace arbitrary OKLCH with CSS vars; backdrop-blur-md; rounded-xl
- Transitions: duration-[var(--duration-*)], ease-[var(--ease-out)]
- Sidebar: add border-r border-[var(--sidebar-border)] for depth
- Header: border-[var(--glass-border)] for subtle separation
- index.css: add --player-glass-bg, --player-glass-border (light + dark)
- visual baselines updated (0% diff Playwright)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 23:09:24 +01:00
senke
47f2c7c30b feat(ui): DeveloperDashboard skeleton, EmptyState, ErrorDisplay, Header transitions
- DeveloperDashboardViewSkeleton: premium skeleton for loading state
- EmptyState for API keys when none exist (variant card, Create action)
- ErrorDisplay with retry on fetch failure
- Header: duration-[var(--duration-fast)] on all interactive elements
- DeveloperDashboardView: table row hover, copy button transitions

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 22:59:51 +01:00
senke
c65da4fea6 refactor(ui): Design tokens - gradients, duration, textarea
- Replace cyan/magenta/purple gradients with primary/secondary
- duration-200/300 → duration-[var(--duration-normal)]
- Textarea: min-h-[100px] → min-h-24
- SearchPageHeader, DashboardPage, PlaylistHeader
- UserProfilePageHeader/Hero, PlaylistDetailPageHero
- SocialViewFeedItem, WishlistView, PostCard, ProductCard, CourseCard
- SearchPageResults, MarketplaceHome

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 22:56:30 +01:00
senke
2c6e5fddb1 refactor(ui): SearchPageHeader use primary/secondary tokens
- Replace cyan-400/magenta-500 with from-primary to-secondary
- Add duration token for clear button transition

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 22:53:15 +01:00
senke
149e616183 refactor(ui): Design tokens in PlaylistCard + TrackCard polish
- PlaylistCard: duration tokens, primary/secondary gradient (KŌDŌ)
- TrackCard: hover:-translate-y-0.5, ease-out token
- Remove arbitrary purple-500/pink-500, duration-200/300

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 22:52:57 +01:00
senke
557e254931 feat(ui): Header search navigates to /search on Enter
- Press Enter in header search → navigate to /search?q=query
- Add role=search, aria-label, focus-visible ring
- Use duration token for transition

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 22:52:31 +01:00
senke
95e31646cb feat(ui): Sidebar refactor, premium skeletons, ContentFadeIn transitions
- Sidebar: useSidebarNavigation hook, ARIA, token-based layout
- Layout: lg:ml-main-expanded/collapsed (replace arbitrary ml-64)
- TrackCardSkeleton + PlaylistCardSkeleton: KŌDŌ tokens, min-heights for CLS
- ContentFadeIn: 200ms fade-in with --ease-out
- TrackGrid, PlaylistList, LibraryPage: integrate skeletons + fade-in
- Player: player-bar subcomponents, useAudioAnalyser
- Tests: TrackGrid wrapper (QueryClient, ToastProvider)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 22:51:51 +01:00
senke
0f25d3c551 fix(webhooks): add DB migration and avoid 500 toast on developer portal
Backend:
- Add migrations/075_create_webhooks.sql: webhooks + webhook_failures tables
- Fixes GET /webhooks 500 (relation "webhooks" did not exist)

Frontend:
- Skip toast for 5xx on /webhooks so developer portal shows empty state
  instead of 'Une erreur serveur s'est produite' when table is missing

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 21:11:32 +01:00
senke
ae4e184fad fix(web): silence console for expected failures (CSRF, webhooks 5xx)
- csrf: no log when backend returns HTML (wrong server / not running)
- webhookService: no log for 5xx on list webhooks
- api client: no log for 5xx on /webhooks (main + queued request)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 19:51:20 +01:00
senke
ee3225a75d fix(web): reduce webhook/CSRF console noise
- webhookService: treat parsed error.code (500) as 5xx and log at DEBUG
- csrf: log 'backend may not be running' at DEBUG instead of WARN

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 19:48:48 +01:00
senke
dcaaeec962 fix(web): close Create API Key modal after successful key creation
- handleCreateKey now returns the new key so the modal receives result
- Modal handles undefined result and api_key shape; no more TypeError on result.key
- On error, parent still shows toast and rethrows so modal stays on step 1

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 19:46:32 +01:00
senke
d744715f38 fix(web): rename duplicate status variable in api client error handler
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 19:38:54 +01:00
senke
8f3b562edb fix(web): reduce developer portal console errors
- CSRF: hint uses VITE_BACKEND_PORT instead of hardcoded 8080
- Proxy: add /swagger to Vite dev server for Swagger doc.json (fixes YAMLException)
- playerService: validate media URL before load to avoid Invalid URI errors
- usePlayer: log invalid URL/network audio errors at DEBUG level
- SwaggerUI: log HTML-instead-of-JSON parse errors at DEBUG
- webhookService: log 5xx backend errors at DEBUG
- api client: log 5xx /webhooks errors at DEBUG (reduces duplicate noise)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 19:38:13 +01:00
senke
f979c6fa8f fix(web): reduce console noise when backend unavailable
- Skip retry for ERR_BAD_RESPONSE / HTML instead of JSON (wrong server)
- Log only first API retry attempt instead of all 3
- CSRF: friendly warn when wrong server, avoid duplicate logs
- App init: skip CSRF warn when wrong server (already shown)
- API client: skip CSRF refresh error log when wrong server
- ReactQuerySync: INFO → DEBUG for enable/disable messages

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 19:29:10 +01:00
senke
64fbb81ddf ui(design): Phase 3 - rounded tokens, min-w/min-h, stories, NavigationProgress
- rounded-[var(--radius-xl/md/lg/sm)] → rounded-xl, rounded-md, rounded-lg, rounded-sm
- Timeline: min-w-[200px] → min-w-50
- AddEquipmentView, MetadataForm: min-h-[100px] → min-h-25
- NavigationProgress: shadow-[...] → shadow-button-primary-glow
- Stories: ActivityGraph, StatCard, NotificationBell, LoadingState, ScrollArea, Skeleton, FileUploadZone
- Reduced arbitrary values from ~60+ to 11 (5 files, exceptions documented)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 19:24:07 +01:00
senke
4b9d0a341d ui(design): migrate ImageCropper, PlaybackSummary to layout tokens
- ImageCropper: h-[80vh] → h-layout-modal-sm (80vh)
- PlaybackSummary: h-[200px] → min-h-50 (scale Tailwind)
- Add h-layout-modal-sm utility class

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 14:07:19 +01:00
senke
298a90c763 ui(design): migrate layout arbitrary values to tokens - Phase 1
- Add layout tokens: h-layout-chat, h-layout-chat-main, h-layout-stream, h-layout-modal-full
- ChatPage: use h-layout-chat and h-layout-chat-main instead of calc(100vh-6.25rem/6rem)
- LiveStreamDetailView: use h-layout-stream
- Modal full size: use h-layout-modal-full
- ChatRoom empty state: use h-layout-lyrics-sm (50vh)
- ChatInput attachment: min-w-36 instead of min-w-[150px]
- Update DESIGN_TOKENS.md and add AUDIT_UI_SPOTIFY_DISCORD_20260210.md

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 14:06:30 +01:00
senke
a7209770bf fix(web): detect wrong server (HTML instead of JSON) and reduce console noise
- Detect when API returns HTML (e.g. another app on port 8080): show clear
  toast and reject so callers get an error instead of broken state
- Gate verbose API request/response/slow/error logs on VITE_DEBUG so
  console is quiet by default in dev; set VITE_DEBUG=true for full logs
- Avoid double toast and HTML dump in logs for wrong-server errors
- .env.example: clarify VITE_DEBUG enables API request/response logging

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 13:52:23 +01:00
senke
02edc2584b fix(ui): SearchPageHeader input text-foreground for theme consistency
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 09:55:21 +01:00
senke
0c020a03cd feat(ui): semantic tokens on library, chat, dashboard, search
PlaylistDetailView: hero border, overlay, sort buttons, table header, row hover → border-border, bg-background/50, hover:bg-muted/50
ChatMessage: action buttons hover, own/other bubbles, attachment preview, context menu, modal → muted/border/foreground
ChatRoom: header bar, channel item hover, input pill → bg-card/90 border-border, hover:bg-muted/50, bg-muted/30
TrackList: play icon and title when not current → text-foreground
SearchPageHeader: title, search container, input, clear button → text-foreground, bg-card/80 border-border, hover:bg-muted/50
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 09:53:17 +01:00
senke
335b51521d feat(ui): semantic tokens on track detail and profile pages
Track detail: cover border, overlay, action cards, stats cards, skeleton; tabs list and count badge; back button hover; info metadata row, waveform container, metadata card → border-border, bg-card/80, bg-muted/*
Profile: skeleton card and tabs; tabs list, count badges, card borders; track/playlist/post cards (aspect-video bg, titles, overlay); header card, stats strip, divider → border-border, bg-card/80, text-foreground, muted

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 09:51:02 +01:00
senke
4f387d03ef feat(ui): semantic tokens on Dashboard and Marketplace
Dashboard: stat cards (title hover, value), activity rows, recent tracks skeleton and list (hover, borders, text), quick actions (card bg, icon bg, label hover) → foreground/muted/border
Marketplace: skeleton filter bar and cards, glass filters card, search input, filter/clear buttons, active filter badges and remove buttons, expanded filters section → card/80, border, muted, foreground
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 09:49:07 +01:00
senke
60d451ec52 feat(ui): semantic tokens in RolesPage, SettingsPage, Toast, QueueView
- SecuritySettings: row bg-white/5 → bg-muted/30
- Toast: close button hover:bg-black/10 → hover:bg-muted/50
- QueueView: autoplay toggle thumb bg-white → bg-background
- RolesPage: cards/headers border-white/5, bg-black/40 → border-border, bg-card/80; headings text-white → text-foreground; row hover, inputs, badge → semantic
- SettingsPage: wrapper and tabs border/bg → border-border, bg-card/80, bg-muted/20; section cards; System Config title text-foreground

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 09:45:30 +01:00
senke
51804f89b7 feat(ui): semantic tokens in settings views + XPBar
Gamification:
- XPBar: track bg-kodo-void → bg-muted (gold gradient and pattern kept)

Settings:
- CloudIntegrationView, BackupsView: toggle thumb bg-white → bg-background
- AccessibilitySettingsView: hover:bg-white/5 → hover:bg-muted/50
- AppearanceSettingsView: density option hover + kodo-magenta → primary
- IntegrationsView: icon container bg-white → bg-muted/50
- DeleteAccount*: labels/titles text-white → text-foreground, destructive btn → text-destructive-foreground, disabled → bg-muted
- ChangeEmailModal, DataExportModal: titles, labels, text → text-foreground; DataExport input bg-kodo-void → bg-muted
- SessionManagement, LoginHistory, SecuritySettings: headings text-white → text-foreground, row hover → hover:bg-muted/50
- TwoFactorSetupStep2: QR container bg-white → bg-card
- LoginHistory: table cell text-white → text-foreground

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 09:43:22 +01:00
senke
8f525fc8ca docs(ui): document typography utility classes in DESIGN_TOKENS
- Add table for .text-display, .text-heading-1..4, .text-body-lg, .text-body, .text-caption, .text-label
- Update hierarchy section to reference utility classes instead of raw Tailwind

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 09:38:09 +01:00
senke
928585eacb feat(ui): semantic tokens in admin views (audit logs, users, dashboard)
- AdminAuditLogsView: border/divide/bg white/5 → border-border, bg-muted/*
- AdminSettingsView: toggle indicators bg-white → bg-background
- AdminUsersView: glass cards, table, pagination → border-border, bg-muted/*
- UserTableRow: text-white → text-foreground, hover states → muted/50
- AdminDashboardHeader: text-white, divider, button → foreground/border/muted
- AdminDashboardTabs: tabs list, cards, table → semantic tokens
- AdminDashboardTabs: remove unused React import

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 09:37:16 +01:00
senke
3abac7b6a1 feat(ui): semantic tokens in modal, button, card, alert
- Modal: title text-white → text-foreground
- Button: secondary/ghost/glass use bg-muted/30, border-border
- Card: spotlight bg-black/40 → bg-card/80; surface border-white/* → border-border
- Alert: AlertTitle text-white → text-foreground

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 09:29:48 +01:00
senke
fa8cef26f0 feat(ui): semantic tokens in loading states, header, sidebar, navbar
- LoadingState: bg-kodo-slate → bg-muted for skeleton variant
- PlayerLoading: fullScreen overlay bg-black/50 → bg-background/80 backdrop-blur-sm
- Header: bg-white/5 → bg-muted/30, border-white/* → border-border, focus:ring-ring
- Sidebar: overlay bg-black/60 → bg-background/80, hover:text-white → hover:text-foreground
- Navbar: text-white → text-foreground, ring-white/5 → ring-border

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 09:28:43 +01:00
senke
b5006fe38f fix: resolve TypeScript errors from UI polish subagents
- Remove 12 unused imports (React, Activity, Upload, useRef, isSubmitting)
- Fix framer-motion Variants type with satisfies + as const on ease arrays
- Fix AchievementCard: variant="gaming" → variant="elevated"
- Fix NotificationMenuDropdown: error ?? null for type narrowing

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 00:52:48 +01:00
senke
186301d4ba fix: add override modifier to ErrorBoundary.render()
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 00:49:59 +01:00
senke
b38cc2544d feat(ui): education, gamification, developer, admin views polish
Education:
- CourseCard: lessons count badge, progress bar, backdrop-blur on badges
- EducationView: framer-motion stagger on grid
- Filters: interactive color-coded pills (Beginner/Intermediate/Advanced)
- MyCoursesView: stagger animation, semantic token migration

Gamification:
- LeaderboardView: gold/silver/bronze podium styling with glow + accents
- AchievementCard: shine sweep animation on hover, lift effect
- AchievementsView: stagger animation with filter re-animation
- XPBar: semantic token fix

Developer dashboard:
- API key copy-to-clipboard with icon toggle
- Status indicator badges with animated pulse dot

Commerce/Admin:
- WishlistView: stagger animation, hover lift
- PurchasesView: stagger on list items
- Admin views: consistent headers, semantic tokens (text-white → text-foreground)

18 files modified, all text-white → text-foreground migrations

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-10 00:48:45 +01:00