Commit graph

677 commits

Author SHA1 Message Date
senke
2964cec09a chore(dx): add .cursorrules and design system audit documentation 2026-02-05 14:20:06 +01:00
senke
fded6f7b64 refactor(ui): decompose ProfileForm into atomic sub-components (Avatar, Identity, Social, Actions, Security) 2026-02-05 14:16:01 +01:00
senke
c377b57e6a docs(storybook): final comparison 67%→0%, contract update, silent toasts in Storybook 2026-02-05 13:39:59 +01:00
senke
634adbca13 chore(storybook): add test:storybook script for local audit 2026-02-05 13:39:56 +01:00
senke
9a27c5ef63 ci(storybook): add audit workflow and exit 1 on audit failures 2026-02-05 13:39:53 +01:00
senke
8e8bf7202e chore(storybook): set MSW onUnhandledRequest to 'error' to block unhandled network requests 2026-02-05 13:22:03 +01:00
senke
37895e6fef chore(storybook): reclassify story hierarchy (App/Pages, Layouts, UI, Features, Docs/Failures) and enable autodocs 2026-02-05 13:21:54 +01:00
senke
3e8480a312 docs(storybook): clarify global decorator guarantees nav/auth context (Phase 3)
All stories run under AuthProvider and MemoryRouter; no story should
crash on missing useContext for auth or router.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 13:08:45 +01:00
senke
e772d81226 refactor(storybook): remove duplicate providers from stories (Phase 2)
Stories no longer wrap with QueryClientProvider, ToastProvider,
ThemeProvider, or MemoryRouter; global StorybookDecorator provides them.
- Route-specific pages use parameters.router.initialEntries
  (ResetPasswordPage, VerifyEmailPage) or minimal MemoryRouter+Route
  where useParams is needed (TrackDetailPage, PlaylistDetailPage).
- Stories that seeded query cache use useQueryClient() from global
  decorator (FollowButton, CollaboratorManagement, CommentSection).
- Navbar, AuthLayout, DashboardLayout, Header, and 25+ story files
  simplified to layout divs only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 13:08:17 +01:00
senke
75c9a4fcd4 feat(storybook): global StorybookDecorator in decorators.tsx (Phase 2)
Single decorator provides: I18nextProvider(i18n), ThemeProvider,
QueryClientProvider(retry:false), ToastProvider, AudioProvider,
AuthProvider, MemoryRouter. Stories can set parameters.router.initialEntries
for route-specific views. preview.tsx uses StorybookDecorator only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 13:01:49 +01:00
senke
11021a2c3a chore(storybook): audit script filter sb-manager/sb-addons + comparison report
- Filter requestfailed to ignore /sb-manager/, /sb-addons/, /index.json,
  /project.json so the audit counts only app/API failures.
- Add STORYBOOK_AUDIT_COMPARISON.md: before 641 stories / 1250 errors,
  after 0 app errors (Phase 1 validated).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 12:41:08 +01:00
senke
b8a8234069 docs(storybook): document MSW/same-origin contract in preview
Storybook must be run via npm run storybook so VITE_API_URL stays
relative and VITE_STORYBOOK is set; avoids accidental real API calls.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 12:28:04 +01:00
senke
4d82136038 fix(storybook): mark ErrorBoundary error stories for audit allowlist
WithError and WithCustomFallback set parameters.storybookAudit.expectConsoleErrors
so audit/CI can treat their console errors as intentional (failure demo).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 12:17:50 +01:00
senke
f8b4bc3b52 fix(storybook): mock dicebear and transparenttextures in MSW
Prevent external asset requests during Storybook so no network
dependency and deterministic rendering. Return 1x1 SVG placeholder.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 12:17:14 +01:00
senke
7545998830 fix(storybook): fix auth/me shape and add dashboard, sessions, roles handlers
- auth/me: return data.user so authService.getCurrentUser() gets response.data.user
- Add GET /api/v1/dashboard for dashboardService (stats, recent_activity, library_preview)
- Add GET /api/v1/sessions/stats for sessionsApi
- Add GET /api/v1/roles and /roles/:id for admin views
- Remove console.log from audit/stats handler

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 12:16:56 +01:00
senke
fde40585a1 fix(storybook): disable logger network send in Storybook
Set VITE_STORYBOOK=true for storybook dev/build so the logger never
sends POST to /logs/frontend in the isolated UI environment. Prevents
94+ failed network requests in audit and keeps Storybook hermetic.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-05 12:16:23 +01:00
senke
765497ea31 fix(storybook): remediate crashes and improve mock stability
- Add global AuthProvider and QueryClientProvider
- Fix Loader2 reference error in CommentThread
- Fix coverUrl crash in ProductCard
- Fix double-slash URL bug in logger
- Improve MSW handlers and environment config
2026-02-04 19:33:00 +01:00
senke
83b9ce2192 fix(frontend): remove redundant api version path in logger endpoint 2026-02-04 10:18:47 +01:00
senke
e7da63479a fix(storybook): add global AuthProvider to preview.tsx 2026-02-04 10:17:19 +01:00
senke
b26593a000 fix(storybook): update MSW handlers to be cookie-compatible and add missing logs endpoint 2026-02-04 10:15:11 +01:00
senke
60acef5147 feat(storybook): integrate msw for data mocking 2026-02-04 01:01:45 +01:00
senke
158e343e50 chore(storybook): add audit report (clean pass) 2026-02-04 00:55:10 +01:00
senke
9b4e66cd43 chore(storybook): improve configuration and cleanup 2026-02-04 00:44:40 +01:00
senke
0e9b206389 stabilisation: fix commit 2026-02-03 09:56:11 +01:00
senke
c38a189207 refactor(cart): migrate CheckoutView and MarketplaceView to useCartStore and fix stories 2026-02-03 09:50:51 +01:00
senke
0bcf56c41a refactor(cart): migrate CartView and CartItem to useCartStore 2026-02-03 09:46:01 +01:00
senke
54def06bde refactor(cart): migrate Navbar to useCartStore and remove CartProvider decorator 2026-02-03 09:42:59 +01:00
senke
01c4e1bff3 refactor(cart): migrate WishlistView to useCartStore 2026-02-03 09:40:54 +01:00
senke
f9ded822dc chore(test): disable broken storybook plugin in vitest config 2026-02-03 09:37:16 +01:00
senke
a91117aec0 docs(cart): list all CartContext consumers 2026-02-03 09:32:21 +01:00
senke
c73165196c feat(storybook): complete comprehensive ui coverage for auth, player, tracks, and groups 2026-02-02 20:55:57 +01:00
senke
d42a7b3c24 feat(storybook): complete UI coverage with Batches 26-30
- Batch 26 (Tracks List/Grid): added stories for row, grid, sort, toggle, skeleton, empty states.
- Batch 27 (Dashboard): added stories for ActivityGraph, TrackList widget.
- Batch 28 (Education): added stories for CourseCard, MyCoursesView, QuizModal, CertificateModal.
- Batch 29 (Inventory): added stories for EquipmentCard, InventoryView.
- Batch 30 (Seller/Live): added stories for SellerDashboardView, FlashSaleModal, LiveStreamDetailView, TipStreamerModal.
- Verified build and fixed AudioProvider/service dependencies.
2026-02-02 20:47:47 +01:00
senke
5ed179cfa8 feat(storybook): add stories for Auth, Player, Tracks, Dashboard (Batches 22-25)
- Batch 22 (Auth/Settings): OAuthButtons, PasswordStrengthIndicator, ThemeSwitcher, TwoFactorSettings
- Batch 23 (Player): TimeDisplay, RepeatShuffleButtons, NextPreviousButtons, QualitySelector
- Batch 24 (Tracks): LikeButton, TrackFilters, TrackStatsDisplay
- Batch 25 (Dashboard): StatCard
- Fixed build issues with sonner dependencies.
2026-02-02 20:42:51 +01:00
senke
38acc2326d feat(storybook): add stories for Feedback and Playlist components (Batches 20-21)
- Batch 20 (Feedback): Alert, Toast
- Batch 21 (Playlists): PlaylistCard, PlaylistHeader, AddTrackToPlaylistModal
- Verified successful build.
2026-02-02 20:38:52 +01:00
senke
f4424d6267 feat(storybook): add stories for Social, Notifications, and Modals (Batches 17-19)
- Batch 17 (Social): PostCard, CommentItem
- Batch 18 (Notifications): NotificationItem, NotificationBell, NotificationMenu
- Batch 19 (Modals): CreatorModal
- Fix: remove duplicate import in api.ts
- Verified successful build.
2026-02-02 20:33:45 +01:00
senke
b0be0068c8 feat(storybook): achieve total UI coverage (Batches 13-16)
- Batch 13 (Library/Profile): UploadModal, FollowButton
- Batch 14 (Settings): AccountSettings, NotificationSettings
- Batch 15 (Layout): DashboardLayout, Header, Sidebar
- Batch 16 (Search): SearchBar, Search
- Verified successful build of all stories.
2026-02-02 20:29:46 +01:00
senke
27c6e6b67f feat(storybook): expanded coverage for feature components (batches 10-12)
- Batch 10 (Auth): AuthButton, AuthInput, LoginForm, RegisterForm
- Batch 11 (Chat): ChatMessage, ChatInput, TypingIndicator
- Batch 12 (Player/Tracks): PlayPauseButton, VolumeControl, ProgressBar, TrackCard
- Achieved extensive functional component coverage.
2026-02-02 20:19:10 +01:00
senke
2c9c39a8a1 feat(storybook): complete UI component coverage (batches 6-9)
- Batch 6: FAB, FormField, FloatingInput, AvatarUpload
- Batch 7: Modal, ConfirmationDialog, ImageViewerModal, ErrorDisplay, LoadingState
- Batch 8: DataList, WaveformVisualizer, OptimizedImage, VirtualizedList
- Batch 9: ImageCropper, LoadingSpinner, FocusTrap
- Achieved total coverage for src/components/ui
2026-02-02 19:50:45 +01:00
senke
7587253741 feat(storybook): expanded coverage for visual and feedback components (batch 5)
- Added stories for: Spinner, KodoEmptyState, HelpText, AstralBackground
- Increased coverage for utility and visual components
2026-02-02 19:46:27 +01:00
senke
b6079ff7e8 feat(storybook): expanded coverage for structural components (batch 4)
- Added stories for: Label, Skeleton, ScrollArea, Toast, Collapsible, Sidebar
- Covered layout and feedback components
2026-02-02 19:44:58 +01:00
senke
f5fca6557a feat(storybook): expanded coverage for complex form & data components (batch 3)
- Added stories for: DatePicker, Select, RadioGroup, FileUpload, Table
- Achieved high coverage for core UI components
2026-02-02 19:41:12 +01:00
senke
4322f26fbb feat(storybook): expanded coverage for complex UI components (batch 2)
- Added stories for: Accordion, Tabs, Textarea, Tooltip, Dialog, DropdownMenu
- Covered various interactive states and sub-components
2026-02-02 19:39:50 +01:00
senke
f597e8792a feat(storybook): expanded coverage for core UI components (batch 1)
- Added stories for: Button, Avatar, Switch, Slider, Alert, Progress
- Consolidated Button component to src/components/ui/button.tsx
- Removed legacy src/components/Button.tsx
2026-02-02 19:37:52 +01:00
senke
31c9f2af0c feat: global update including storybook setup and backend fixes
- Web: Setup Storybook, added addons, configured Tailwind, added stories for UI components.
- Backend: Updated API router, database, workers, and auth in common.
- Stream Server: Removed SQLx queries and updated auth.
- Docs & Scripts: Updated documentation and recovery scripts.
2026-02-02 19:34:14 +01:00
senke
ef217b96c7 feat(auth): add centralized AuthProvider component
Created AuthProvider React component to centralize auth initialization
logic and eliminate race conditions.

Features:
- Single source of truth for auth initialization
- Checks for tokens on mount (TokenStorage.hasTokens())
- Calls refreshUser() if tokens exist
- Shows loading screen while auth initializing
- Always sets ready state (prevents stuck loading)
- Comprehensive error handling and logging
- Optional custom loading component prop

Benefits:
- Eliminates race condition: router no longer renders before auth ready
- Centralizes auth logic (was scattered in App.tsx, interceptors)
- Reusable across different app entry points
- Clean separation of concerns

Usage:

Impact: Reduces auth-related race conditions, improves code maintainability.

Fixes: P3.1 from audit AUDIT_TEMP_29_01_2026.md
2026-01-29 23:42:26 +01:00
senke
e814bd2235 config(prod): add frontend production environment file
Created .env.production for frontend with absolute API URLs for
production deployment.

Configuration:
- VITE_API_URL: https://api.veza.com/api/v1
- VITE_WS_URL: wss://api.veza.com/ws
- VITE_STREAM_URL: https://api.veza.com/stream
- VITE_UPLOAD_URL: https://api.veza.com/upload
- VITE_API_VERSION: v1

Features:
- Absolute URLs (required for production, no Vite proxy)
- HTTPS/WSS for secure connections
- Validation alerting enabled
- Deployment notes included

Usage:
- Local testing: Update URLs to local domains, npm run build, npm run preview
- Production: Update to real domains, ensure CORS configured

Impact: Frontend can now be deployed to production with proper API URLs.

Fixes: P2.2 from audit AUDIT_TEMP_29_01_2026.md
2026-01-29 23:23:04 +01:00
senke
0d7586692f config(dev): add Vite proxy for API requests
Added proxy configuration to forward /api requests to backend
on localhost:8080 during development.

Benefits:
- Eliminates CORS errors in dev (requests are same-origin)
- No need for CORS_ALLOWED_ORIGINS in dev environment
- Matches production behavior (frontend and API on same domain)
- Simplifies local development setup

Configuration:
- Target: http://localhost:8080
- changeOrigin: true (modifies Host header)
- secure: false (allows self-signed certs in dev)

Impact: Dev environment more stable, no CORS configuration needed.

Fixes: P2.1 from audit AUDIT_TEMP_29_01_2026.md
2026-01-29 23:22:32 +01:00
senke
236fbe2826 fix(auth): prevent race condition on app initialization
Added isAuthReady state to prevent router from rendering before auth
state is initialized. This eliminates login redirect loops and ensures
deterministic auth behavior.

Changes:
- Added isAuthReady state (default: false)
- New useEffect to initialize auth before rendering
- Waits for refreshUser() to complete if tokens exist
- Shows loading screen while auth is initializing
- Always sets isAuthReady=true in finally block

Loading screen:
- Simple centered spinner with "Chargement..." text
- Uses Tailwind classes for styling
- Matches app theme (bg-background, text-muted-foreground)

Behavior:
- App loads → Check for tokens → If yes, await refreshUser()
- Only after auth check completes, render router
- Prevents "flash of login page" for authenticated users
- Eliminates race condition: router no longer renders before auth ready

Impact: Fixes intermittent login loops, improves UX on page refresh.

Fixes: P1.2 from audit AUDIT_TEMP_29_01_2026.md
2026-01-29 23:19:01 +01:00
senke
3a99bfe1a3 fix(csrf): add retry mechanism for 403 CSRF errors
Added response interceptor to handle 403 errors caused by expired or
invalid CSRF tokens. When a mutation fails with 403, the interceptor:

1. Detects if error is CSRF-related (checks error message for csrf/token/forbidden)
2. Refreshes the CSRF token via csrfService.ensureToken()
3. Updates request headers with new token
4. Retries the request once

Features:
- Only retries once per request (via _csrfRetry flag)
- Skips retry for /csrf-token and /auth/* endpoints
- Logs all CSRF refresh attempts for debugging
- Falls through to original error if refresh fails
- Handles both error.error and error.message formats

TypeScript fixes:
- Cast originalRequest to any for _csrfRetry property
- Safely access error data with type checking

Impact: Eliminates 403 errors on POST/PUT/DELETE when CSRF token expires.
Users no longer need to manually refresh page to get new CSRF token.

Fixes: P1.3 from audit AUDIT_TEMP_29_01_2026.md
2026-01-29 23:18:08 +01:00
senke
aae5a75e08 fix(auth): limit refresh token attempts to prevent infinite loops
Added refresh attempt counter with MAX_REFRESH_ATTEMPTS=3 to prevent
infinite refresh loops when token refresh repeatedly fails.

Changes:
- Added refreshAttempts counter and MAX_REFRESH_ATTEMPTS constant
- Check counter before attempting refresh, logout if max reached
- Increment counter on each refresh attempt
- Reset counter to 0 on successful refresh
- Log attempt number in all refresh-related logs
- Show user-friendly error message after max attempts

Behavior:
- After 3 failed refresh attempts, user is logged out automatically
- Prevents infinite 401 → refresh → 401 loops
- Uses logoutLocal() to avoid triggering another API call
- Displays clear error message: "Session expired after multiple attempts"

Impact: Eliminates infinite refresh loops, improves UX on persistent auth failures.

Fixes: P1.4 from audit AUDIT_TEMP_29_01_2026.md
2026-01-29 23:16:37 +01:00