Skip to content

Technical Debt Catalog ​

Purpose: Centralized tracking of known technical debt across the platform. Last Updated: March 2026

For actionable work items, create GitHub Issues with the tech-debt label.


πŸ”΄ High Priority ​

0. Security Hardening (Online Preview Exposed) ⚠️ MAXIMUM PRIORITY ​

  • Scope: App is live on the internet in DEV state β€” several security gaps identified during March 2026 audit
  • Context: Solid foundations exist (Helmet, CORS, Mongoose ORM, bcrypt, JWT middleware, rate limiting, SAS tokens, ValidationPipe), but critical gaps remain

0a. Preview Mode Auth Bypass πŸ”΄ CRITICAL ​

  • File: ctrl-audio-front/src/proxy.ts
  • Issue: NEXT_PUBLIC_PREVIEW_MODE=true completely bypasses NextAuth middleware β€” all routes become public
  • Fix: Remove the bypass entirely. Use IP-allowlist or HTTP Basic Auth for staging instead of an env flag that disables auth

0b. JwtAuthGuard Not Global (New Routes Are Public by Default) πŸ”΄ HIGH ​

  • File: ctrl-audio-back/src/app.module.ts (JwtMiddleware applied per-module in configure())
  • Issue: Any new backend module/route added without explicit middleware registration is publicly accessible
  • Fix: Register JwtAuthGuard as a global APP_GUARD, add a @Public() decorator for intentionally open endpoints (health, login, register, etc.). Pattern:
    typescript
    // app.module.ts
    { provide: APP_GUARD, useClass: JwtAuthGuard }
    
    // On public endpoints
    @Public()
    @Get('/health')

0c. No Authorization on Admin Endpoints πŸ”΄ HIGH ​

  • File: ctrl-audio-back/src/modules/user/user.controller.ts (GET /user/count and others)
  • Issue: Authenticated but non-admin users can access admin-only endpoints. RolesGuard stub exists in collaboration module but is commented out
  • Fix: Implement RolesGuard and apply to admin routes

0d. Auth Endpoint Rate Limits Too Permissive 🟠 MEDIUM ​

  • Issue: Global rate limit is 100 req/60s per IP β€” sufficient for general use but too loose for brute-forcing login/register
  • Fix: Add endpoint-specific throttle overrides: @Throttle({ default: { limit: 5, ttl: 60000 } }) on POST /user/login and POST /user/register

0e. Tokens Not Invalidated on Password Change 🟠 MEDIUM ​

  • Issue: When a user changes their password, existing JWTs remain valid for up to 7 days
  • Fix: Add a tokenVersion: number field to the User schema; increment on password change; include in JWT payload; validate in JwtStrategy

0f. File Upload Missing Magic Byte Validation 🟠 MEDIUM ​

  • File: ctrl-audio-back/src/modules/file/ (upload handler)
  • Issue: File type is determined from MIME type string only β€” a malicious file with a renamed extension passes validation
  • Fix: Use the file-type npm package to verify actual file content (magic bytes) matches declared type before processing

0g. No Security / Audit Logging 🟑 LOW ​

  • Issue: No logging for failed login attempts, permission denials, password changes, or file uploads β€” makes incident detection impossible
  • Fix: Add structured log entries (Winston/Pino) for all auth events and permission failures

1. Navigation Workflow Coverage ⚠️ MAXIMUM PRIORITY ​

  • Scope: Core user navigation flows are incomplete or broken
  • Issues: Routing between views, back navigation, deep linking, breadcrumbs
  • Fix: Audit all navigation paths (dashboard β†’ space β†’ project β†’ track β†’ wave), document gaps, fix broken flows
  • Includes: URL identifier routing (shortId/slug), mobile navigation, tab persistence

2. Tailwind CSS v3 β†’ v4 Visual Regression ​

  • Scope: Component backgrounds, spacing, colors broken after migration
  • Issues: Some components have wrong/missing backgrounds, opacity modifiers changed, dark mode behavior different
  • Fix: Visual audit of all key pages, fix broken utility classes
  • Reference: See PLAYER-COMPARISON.md for player-specific issues

3. Wave / Music Player Consolidation ​

  • Scope: wave-dashboard.tsx + new-wave-dashboard.tsx coexist, card.tsx + new-card.tsx, main-panel.tsx + new-main-panel.tsx
  • Also: Player component differences between reference branches and current code
  • Fix: Determine which version is active, remove or archive duplicates, stabilize player

4. Light/Dark Mode ​

  • Scope: Theme follows device preference but may not be fully implemented across all components
  • Issues: Some components may not respect prefers-color-scheme, manual toggle may be missing
  • Fix: Audit all components for theme support, ensure consistent dark/light mode rendering

5. Zero Test Coverage (incl. Performance) ​

  • Scope: No unit or integration tests in frontend. Only 1 spec file in backend.
  • Risk: Refactoring and feature additions are fragile.
  • Plan: Set up Vitest (frontend) and Jest (backend). Start with critical paths: auth, file upload, track CRUD.
  • Performance: Include Lighthouse CI benchmarks, bundle size tracking, load-time assertions

6. s3Url β†’ blobUrl Rename βœ… DONE ​

  • Completed: February 2026 β€” renamed across 32 files (6 backend + 26 frontend)
  • Remaining: Run DB migration script (scripts/migrate-s3url-to-bloburl.js)

7. Type Safety Gaps ​

  • Scope: Many any types throughout frontend types/ directory
  • Examples: TTrack.credits: any, TTrack.attachments: any, INotification.data?: any
  • Fix: Define proper interfaces for all any typed fields

🟑 Medium Priority ​

7b. Broken unit suite: artistSpace.controller.spec.ts (pre-existing, fails on npm test) ​

  • File: ctrl-audio-back/src/modules/artistSpace/artistSpace.controller.spec.ts
  • Issue: da3ba37 (doc-45 attachments) added AttachmentService to ArtistSpaceController's constructor but the spec's RootTestModule providers were never updated β†’ all 6 tests in the suite fail on DI resolution ("Nest can't resolve dependencies… AttachmentService at index [3]"). Noticed 2026-07-05 during the doc-56 S1 build (S1 touches nothing in artistSpace).
  • Fix: add an AttachmentService mock/provider to the spec's testing module (mirror how the other controller deps are stubbed)

8. Inconsistent Error Handling ​

  • Scope: Server actions use different error patterns (some throw, some return empty arrays, some console.error)
  • Partial fix: Backend addRecentAccess now validates ObjectId and has try-catch; WaveSurfer errors suppressed where appropriate; frontend silences non-critical recent-access failures
  • Fix: Create a unified apiCall() wrapper or use React Query error boundaries

9. Console.log Statements ​

  • Scope: ~60+ remaining statements across auth forms, onboarding, account settings, portals/attachments, trash, transfers, share modals
  • Partial fix: Cleaned all console.logs in core navigation flow (dashboard β†’ artist β†’ project β†’ track/wave-player, socket provider, headers, skeletons, url-helpers, upload modals)
  • Fix: Replace remaining with proper logger (Winston/Pino for backend, conditional logger for frontend)

10. Accessibility (a11y) ​

  • Scope: Missing ARIA labels, keyboard navigation incomplete
  • Priority areas: Audio player controls, modal dialogs, form inputs

11. RBAC / Permission Framework ​

  • Scope: Per-entity collaborators[] array with roles β€” no centralized Team entity
  • Phase: Mid-term (after stabilization). Basic collaborator = freemium, Teams = premium
  • Plan: See RBAC-DESIGN.md for planning

15. Fix React Compiler lint violations (64 errors) ​

  • Scope: 5 new React Compiler rules introduced by eslint-config-next@16 β€” currently disabled in eslint.config.mjs
  • Breakdown: set-state-in-effect (44), immutability (10), refs (6), purity (2), incompatible-library (2)
  • Fix: Re-enable rules one at a time, fix violations, validate with eslint .

16. Rename middleware.ts β†’ proxy.ts βœ… DONE ​

  • Completed: February 2026 β€” renamed src/middleware.ts to src/proxy.ts per Next.js 16 convention
  • Remaining: Migrate NextAuth v4 β†’ Auth.js v5 (separate effort, tracked below)

17. Migrate NextAuth v4 β†’ Auth.js v5 ​

  • Scope: Currently using next-auth@4.24.13 with withAuth in proxy.ts
  • Context: NextAuth v4 has open compatibility issues with Next.js 16
  • Fix: Migrate to Auth.js v5 (next-auth@5), create auth.config.ts + auth.ts, update all next-auth imports
  • Reference: Auth.js v5 migration guide

🟒 Low Priority ​

12. API Error Messages ​

  • Scope: Backend error responses are raw/technical
  • Fix: User-facing error messages need polish for production

13. Naming Inconsistency ​

  • Scope: "Wavic", "Sonnance", "ctrl-audio" mixed across docs and code
  • Status: On hold until product name is finalized

14. Legacy Reference Branches ​

  • Scope: _reference/ folder contains 5000+ files from old branches
  • Fix: Archive to a separate repo or branch when no longer needed for comparison

πŸ“ Implementation Notes (Keep in Mind) ​

18. CSS backdrop-filter inside transformed ancestors ​

  • Pattern: position:fixed children inside a parent with transform (e.g., translateZ(0)) are positioned relative to that parent, NOT the viewport. This breaks backdrop-filter blur β€” the blur only affects what's inside the parent's bounds, not the page content behind it.
  • Solution: Place the blurred element as a sibling (Fragment pattern), not a child. Use clip-path:inset(0) to prevent Safari blur edge bleeding. Always set WebkitBackdropFilter inline alongside the Tailwind class.
  • Affected files: beryllium-left-sidebar-fixed.tsx, beryllium-sidebar-expanded.tsx, beryllium-sidebar-drawer.tsx

19. Mongoose populated ref serialization ​

  • Pattern: Calling .toString() on a Mongoose populated object returns [object Object], silently destroying the rich data (name, image, etc.).
  • Solution: Always check typeof ref === 'object' before serializing. If object, serialize only ref._id.toString(). Apply consistently across all controller endpoints that serialize the same field.
  • Affected files: project.controller.ts (findAll, findById, findAllByArtist)

Ctrl-Audio Platform Documentation