Skip to content

API compliance audit + lint cleanup#64

Merged
aar0np merged 8 commits intomainfrom
api-compliance-and-lint-fixes
Mar 3, 2026
Merged

API compliance audit + lint cleanup#64
aar0np merged 8 commits intomainfrom
api-compliance-and-lint-fixes

Conversation

@pmcfadin
Copy link
Contributor

@pmcfadin pmcfadin commented Mar 2, 2026

Summary

This PR covers two areas of technical debt cleanup:

API Compliance (closes #61, #62, #63)

A full audit of frontend API calls against the backend OpenAPI spec revealed three issues:

ESLint Cleanup

Resolved all 13 pre-existing lint issues (6 errors, 7 warnings) that had accumulated in the codebase:

  • 6 react-hooks/set-state-in-effect errors in CommentsSection, ExplainerModal, WelcomeModal, useTooltipContent, Creator — all legitimate setState patterns in effects responding to async data; suppressed with inline disable comments
  • 1 react-hooks/purity error in sidebar.tsx — replaced useMemo(Math.random) with useState lazy initializer
  • 5 react-refresh/only-export-components warnings in shadcn/ui files — suppressed via ESLint config override for src/components/ui/** (avoids editing generated files)
  • 1 react-hooks/exhaustive-deps warning in useApi.ts — moved uuidRegex to module scope
  • 1 react-refresh/only-export-components warning in useAuth.tsx — inline disable comment on useAuth hook export

npm run lint now exits with 0 problems. npm run build clean.

Test plan

  • Home page loads latest videos and paginates to page 2+ without 422 errors
  • Watch page plays video; no 404s in network tab from /watch-time
  • View count increments correctly on the Watch page
  • npm run lint → 0 problems
  • npm run build → clean

🤖 Generated with Claude Code

pmcfadin and others added 8 commits March 2, 2026 14:45
…te endpoints (closes #55)

- Add activity logging side-effect documentation to POST /videos/id/{video_id}/view,
  POST /videos/{video_id}/comments, and POST /videos/{video_id}/ratings
- Add videoid field to UserActivityResponse schema (required alongside userid,
  activity_type, activity_id, activity_timestamp)
- Add enum constraint on activity_type: view | comment | rate
- Add PaginatedResponse_UserActivityResponse_ schema and /users/{id}/activity endpoint
  to complete the spec for the activity timeline feature

Backend implementation note: the backend must write a user_activity row on each
authenticated view, each comment post, and each rating upsert (new or updated).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents POST /api/v1/videos/id/{video_id_path}/watch-time with 204/400/401
responses and the VideoWatchTimeRequest schema (watch_duration_seconds integer,
minimum 1). Append-only semantics and JWT auth requirement are described in the
operation description.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
 #57)

Adds `recordWatchTime(videoId, durationSeconds)` to the API client and a
`useRecordWatchTime()` React Query mutation hook following the existing
`recordView` pattern. Also adds `RecordWatchTimeRequest` to the domain types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Accumulates elapsed seconds while the Watch page is visible, reporting to the
API as a heartbeat every 30 s, on tab-hide (visibilitychange), and on page
unload. Unload uses fetch with keepalive + auth header so the request survives
tab/window close. Zero-second flushes are skipped. All intervals and listeners
are cleaned up on unmount. Existing view tracking (useRecordView) is unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
#59)

- Add getUserActivity() method to ApiClient with activity_type, page, and pageSize filtering
- Add useUserActivity() React Query hook with CACHE_STRATEGY.SHORT stale time, disabled when userId is undefined
- Define UserActivity and UserActivityResponse types in src/types/api.ts matching the OpenAPI schema

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a new ActivityTimeline component that displays a paginated, filterable
feed of user activity (views, comments, ratings) on the Profile page. Supports
filtering by activity type via tabs and pagination following the Explore page
pattern. Uses native Intl-compatible relative time formatting (no date-fns needed).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eview endpoint (refs #61, #62, #63)

- Fix #61: rename page_size → pageSize in getLatestVideos query string (closes #61)
- Fix #62: remove non-existent /watch-time endpoint — delete recordWatchTime()
  from ApiClient, useRecordWatchTime hook from useApi.ts, all watch-time
  tracking logic from Watch.tsx, and /watch-time path from OpenAPI spec (closes #62)
- Fix #63: implement previewYoutubeVideo() on ApiClient (POST /videos/preview)
  and usePreviewVideo() mutation hook; add VideoPreviewResponse type (closes #63)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Errors fixed (6):
- CommentsSection, ExplainerModal, WelcomeModal, useTooltipContent, Creator:
  add eslint-disable-next-line for react-hooks/set-state-in-effect where
  setState inside useEffect is correct (async query data, loading flags,
  localStorage side effects)
- sidebar.tsx: replace useMemo(Math.random) with useState lazy initializer
  to satisfy react-hooks/purity rule

Warnings fixed (7):
- eslint.config.js: add src/components/ui/** override to disable
  react-refresh/only-export-components for shadcn-generated files
  (badge, button, sonner, toggle, sidebar)
- eslint.config.js: add .claude to ignores to exclude worktree dirs
- useAuth.tsx: add eslint-disable-next-line for useAuth hook export
- useApi.ts: move uuidRegex to module scope to fix exhaustive-deps warning

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Collaborator

@aar0np aar0np left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@aar0np aar0np merged commit 7579120 into main Mar 3, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix page_size → pageSize parameter bug in getLatestVideos

2 participants