Conversation
|
Note Reviews pausedUse the following commands to manage reviews:
WalkthroughThe PR upgrades dependencies (Next/React/Effect), enables TypeScript strictNullChecks, converts many page/route props to Promise-wrapped params/searchParams and awaits cookies()/headers(), widens several RefObject types to allow null, and applies small API route export/type adjustments. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant NextApp as Next App Router
participant Page as Page/Route Module
participant Svc as Data/Service
User->>NextApp: HTTP Request
NextApp->>Page: Invoke handler/component with props (params/searchParams as Promise)
Note right of Page: Await props.params / props.searchParams
Page->>Svc: Fetch data using resolved params
Svc-->>Page: Data/Result
Page-->>NextApp: Response/JSX/Redirect
NextApp-->>User: HTML/JSON
sequenceDiagram
autonumber
participant RC as Server Component/Action
participant NH as next/headers
RC->>NH: cookies()
NH-->>RC: Promise<CookieStore>
RC->>RC: await cookies() → cookieStore
RC->>RC: cookieStore.get/set/delete(...)
RC->>NH: headers()
NH-->>RC: Promise<Headers>
RC->>RC: await headers() → read header values
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (7)
apps/web/app/api/utils.ts (1)
11-14: Remove sensitive logs (Authorization header and full user object).Logging bearer tokens and user objects is a security/compliance risk.
Apply:
- console.log("auth header: ", c.req.header("authorization")); + // removed @@ - console.log("User: ", user); + // removedAlso applies to: 39-41
packages/database/auth/auth-options.ts (1)
98-103: Do not log verification codes or email contentsLogging identifier/token (and rendered email) is a secrets/PII leak risk in production.
- console.log({ identifier, token }); const { OTPEmail } = await import("../emails/otp-email"); const email = OTPEmail({ code: token, email: identifier }); - console.log({ email }); await sendEmail({ email: identifier, subject: `Your Cap Verification Code`, react: email, });apps/web/app/s/[videoId]/_components/CapVideoPlayer.tsx (1)
310-315: Duplicate event listener registration causes double-calls and leaksloadedmetadata is added twice; only one remove occurs in cleanup. Remove the duplicate add.
video.addEventListener("loadeddata", handleLoadedData); video.addEventListener("canplay", handleCanPlay); video.addEventListener("loadedmetadata", handleLoadedMetadataWithTracks); video.addEventListener("load", handleLoad); video.addEventListener("play", handlePlay); video.addEventListener("error", handleError as EventListener); - video.addEventListener("loadedmetadata", handleLoadedMetadataWithTracks);apps/web/app/api/playlist/route.ts (2)
245-247: Remove any-casts on route handlers; type to Request -> Promise.Avoid any per project guidelines.
-export const GET = handler as any; -export const HEAD = handler as any; +export const GET: (req: Request) => Promise<Response> = handler; +export const HEAD: (req: Request) => Promise<Response> = handler;
169-180: Guard mp4 requests when source isn’t desktopMP4.When videoType === "mp4" but the source isn’t desktopMP4, prefix remains undefined and listObjects may run on an unintended path.
Add an early guard:
} else if (video.source.type === "desktopMP4") { yield* Effect.log( `Returning path ${`${video.ownerId}/${video.id}/result.mp4`}`, ); return yield* s3 .getSignedObjectUrl(`${video.ownerId}/${video.id}/result.mp4`) .pipe(Effect.map(HttpServerResponse.redirect)); } + if (urlParams.videoType === "mp4") { + return yield* Effect.fail(new HttpApiError.NotFound()); + }apps/web/app/api/releases/macos/route.ts (1)
5-7: Align with API route guidelines (HttpApi + handler export).Per repo guidelines, implement routes with @effect/platform HttpApi/HttpApiBuilder, translate errors with HttpApiError.*, and export only the handler from apiToHandler(ApiLive). This route is hand-rolled and bypasses middleware/dependency provisioning.
I can sketch an HttpApi route that wraps the Octokit call and maps failures to transport errors if you want to migrate this endpoint now.
Also applies to: 9-12
apps/web/app/(org)/invite/[inviteId]/page.tsx (1)
72-73: Type error: removetypeofon a type-only import.
userSelectPropsis imported as a type;typeof userSelectPropsis invalid. Cast to the type directly.- user={user as typeof userSelectProps | null} + user={user as userSelectProps | null}
🧹 Nitpick comments (34)
apps/web/app/s/[videoId]/page.tsx (4)
98-101: Narrow Props types for better safety (encode videoId, use Record for searchParams).Avoid broad index signatures and the downstream cast. This tightens types where they’re consumed.
type Props = { - params: Promise<{ [key: string]: string | string[] | undefined }>; - searchParams: Promise<{ [key: string]: string | string[] | undefined }>; + params: Promise<{ videoId: string }>; + searchParams: Promise<Record<string, string | string[] | undefined>>; };
129-133: Prefer a single headers() call and fall back to the standard Referer header.Reduces duplicate awaits and improves robustness when x-referrer isn’t present.
- const referrer = (await headers()).get("x-referrer") || ""; + const h = await headers(); + const referrer = h.get("x-referrer") ?? h.get("referer") ?? "";
313-319: Confirm Effect.flatten semantics (Option → NoSuchElementException).This relies on flatten converting None to a NoSuchElementException (caught below). If flatten doesn’t do this in your Effect version, this could pass an undefined video through and crash later.
If needed, replace with an explicit Option → Effect conversion for clarity and type safety (example approach):
- Convert Option to Effect explicitly (e.g., Effect.fromOption / someOrFail)
- Then map to the { needsPassword: false, video } shape
Would you like me to propose an exact patch tailored to your Effect version?
345-347: Don’t rethrow notFound(); return an Effect instead.Throwing is redundant since notFound() already throws. Returning an Effect keeps the pipeline consistent.
- NoSuchElementException: () => { - throw notFound(); - }, + NoSuchElementException: () => Effect.sync(notFound),apps/web/components/pages/HomePage/Features.tsx (3)
105-116: Avoid shadowing component name with local aliasThe inner destructuring aliases RiveComponent to CapAIArt, shadowing the component’s own identifier and inviting mistakes. Rename the alias.
-const CapAIArt = memo(() => { - const { RiveComponent: CapAIArt } = useRive({ +const CapAIArt = memo(() => { + const { RiveComponent: CapAIRive } = useRive({ src: "/rive/bento.riv", artboard: "capai", animations: ["in"], autoplay: true, layout: new Layout({ fit: Fit.Contain, }), }); - return <CapAIArt className="w-full max-w-[550px] mx-auto h-[300px]" />; + return <CapAIRive className="w-full max-w-[550px] mx-auto h-[300px]" />; });
157-158: Remove inline JSX comments per repo guidelinesInline JSX comments violate the no-comments guideline for TS/JS files. Please remove them.
Also applies to: 172-173, 186-187, 201-203
1-1: Optional: Rename file to kebab-caseFile path uses PascalCase segments. The repo guideline prefers kebab-case filenames for TS/JS modules (components stay PascalCase in code). Consider features.tsx (and directory names likewise) for consistency.
apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx (1)
105-106: Ref type should not include null in the generic parameterWith strictNullChecks, React.RefObject already exposes current: T | null. Using RefObject<FolderHandle | null> makes current’s type (FolderHandle | null) | null and can break compatibility with React.Ref parameters.
- {} as Record< - (typeof FolderOptions)[number]["value"], - React.RefObject<FolderHandle | null> - >, + {} as Record< + (typeof FolderOptions)[number]["value"], + React.RefObject<FolderHandle> + >,Confirm NormalFolder/BlueFolder/RedFolder/YellowFolder forwardRef typings accept React.Ref. If any were changed to Ref<FolderHandle | null>, align them back to Ref.
apps/web/tsconfig.json (1)
17-17: strictNullChecks is redundant when strict is trueTypeScript enables strictNullChecks under "strict": true. Keeping both can be confusing.
- "strictNullChecks": true,packages/ui/package.json (1)
18-26: Treat React as a peerDependency in UI libraryFor @cap/ui, depend on the app’s React to avoid duplicate bundles and mismatched hooks. Move react and react-dom to peerDependencies (keep them in devDependencies for local builds).
Run the same workspace version audit script shared earlier to confirm single React/React‑DOM versions across the repo after this change.
packages/database/package.json (1)
29-47: Unify React/Next versions and use peerDependencies in libraries
- Ensure React, React-DOM and Next are declared with the exact same version across all package.json (apps/web pins “19.1.1” vs “^19.1.1” elsewhere).
- In library packages (e.g. @cap/database, @cap/ui, @cap/utils), move react/react-dom (and next if only for types) into peerDependencies —and keep them in devDependencies for local builds.
apps/web/app/api/video/delete/route.ts (1)
31-34: Map PolicyDenied to Forbidden to match declared errors.Declared errors include Forbidden; handler currently returns Unauthorized.
Apply:
- PolicyDenied: () => new HttpApiError.Unauthorized(), + PolicyDenied: () => new HttpApiError.Forbidden(),apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx (2)
41-45: Align ref types across components (accept null)The FolderOptions component signatures should accept React.Ref<FolderHandle | null> to match folderRefs’ type and avoid type friction.
- (riveFile: RiveFile | undefined, - ref: React.Ref<FolderHandle>, + (riveFile: RiveFile | undefined, + ref: React.Ref<FolderHandle | null>, ) => <NormalFolder riveFile={riveFile} ref={ref} />, ... - (riveFile: RiveFile | undefined, - ref: React.Ref<FolderHandle>, + (riveFile: RiveFile | undefined, + ref: React.Ref<FolderHandle | null>, ) => <BlueFolder riveFile={riveFile} ref={ref} />, ... - (riveFile: RiveFile | undefined, - ref: React.Ref<FolderHandle>, + (riveFile: RiveFile | undefined, + ref: React.Ref<FolderHandle | null>, ) => <RedFolder riveFile={riveFile} ref={ref} />, ... - (riveFile: RiveFile | undefined, - ref: React.Ref<FolderHandle>, + (riveFile: RiveFile | undefined, + ref: React.Ref<FolderHandle | null>, ) => <YellowFolder riveFile={riveFile} ref={ref} />,Also applies to: 51-53, 59-61, 67-69
172-175: Avoid unnecessary non-null castThe option.component expects RiveFile | undefined, so casting forces a stronger type than needed.
- riveFile as RiveFile, + riveFile,apps/web/app/(org)/dashboard/layout.tsx (1)
66-68: Reuse a single cookie store instanceMinor perf/readability improvement: avoid multiple awaits to cookies().
- const theme = (await cookies()).get("theme")?.value ?? "light"; - const sidebar = (await cookies()).get("sidebarCollapsed")?.value ?? "false"; - const referClicked = (await cookies()).get("referClicked")?.value ?? "false"; + const cookieStore = await cookies(); + const theme = cookieStore.get("theme")?.value ?? "light"; + const sidebar = cookieStore.get("sidebarCollapsed")?.value ?? "false"; + const referClicked = cookieStore.get("referClicked")?.value ?? "false";packages/database/auth/auth-options.ts (1)
140-144: Reuse cookie store; confirm deletions take effect in this contextConsolidate cookie access, and verify that delete() here actually persists (NextAuth event handlers may not attach to a response).
const { cookies } = await import("next/headers"); - const dubId = (await cookies()).get("dub_id")?.value; - const dubPartnerData = (await cookies()).get( - "dub_partner_data", - )?.value; + const cookieStore = await cookies(); + const dubId = cookieStore.get("dub_id")?.value; + const dubPartnerData = cookieStore.get("dub_partner_data")?.value; ... - (await cookies()).delete("dub_id"); + cookieStore.delete("dub_id"); if (dubPartnerData) { - (await cookies()).delete("dub_partner_data"); + cookieStore.delete("dub_partner_data"); }Please verify cookie deletions persist for clients after sign-in completes (e.g., by checking Set-Cookie headers or observing cookie presence post-redirect).
Also applies to: 159-162
apps/web/app/s/[videoId]/_components/CapVideoPlayer.tsx (2)
66-67: Use ReturnType for browser-safe timeout refsAvoid NodeJS.Timeout in browser bundles.
- const retryTimeout = useRef<NodeJS.Timeout | null>(null); + const retryTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);
97-114: Remove inline comments per codebase conventionThe repository disallows inline comments in TS/TSX. Please remove these comment lines.
Also applies to: 198-214, 216-220, 262-267, 320-331
apps/web/app/(org)/dashboard/_components/Navbar/Items.tsx (3)
35-35: Drop unused RefObject import (and use React.Ref for icon prop)RefObject isn’t needed if the icon prop accepts a generic React.Ref.
-import { cloneElement, RefObject, useRef, useState } from "react"; +import { cloneElement, useRef, useState } from "react";
456-460: Loosen icon ref typing to React.Ref to match useRefThis avoids friction between RefObject vs MutableRefObject from useRef.
- icon: React.ReactElement<{ - ref: RefObject<CogIconHandle | null>; + icon: React.ReactElement<{ + ref: React.Ref<CogIconHandle | null>; className: string; size: number; }>;
465-465: Optional: make local ref nullableAlign with the prop type and typical forwardRef patterns.
- const iconRef = useRef<CogIconHandle>(null); + const iconRef = useRef<CogIconHandle | null>(null);apps/web/app/(org)/dashboard/_components/Navbar/Top.tsx (2)
31-32: Remove unused RefObject importNot needed if MenuItem icon prop uses React.Ref.
- useRef, - useState, - RefObject, + useRef, + useState,
322-326: Loosen MenuItem icon ref typing to React.RefConsistent with useRef and various icon components.
- icon: React.ReactElement<{ - ref: RefObject<DownloadIconHandle | null>; + icon: React.ReactElement<{ + ref: React.Ref<DownloadIconHandle | null>; className: string; size: number; }>;apps/web/app/(org)/dashboard/_components/Navbar/SpaceDialog.tsx (1)
54-58: Remove inline comments per repository rulesInline and block comments are disallowed in TS/TSX; please remove these lines.
- // Reset spaceName when dialog opens or space changes ... - // If the user removed the icon, send a removeIcon flag ... - {/* Space Members Input */}Also applies to: 186-189, 235-235
apps/web/app/api/videos/[videoId]/retry-transcription/route.ts (1)
10-19: PreserveVideoIdbranding instead of casting.Casting the awaited params to
{ videoId: Video.VideoId }sidesteps the branding check we previously had when the type flowed directly from the handler signature. We can keep the stronger type guarantees by re-branding the string returned from the params promise before proceeding.Apply this diff to restore the branded validation:
- const { videoId } = (await props.params) as { videoId: Video.VideoId }; + const params = await props.params; + const videoId = Video.VideoId.make(params.videoId);apps/web/components/pages/_components/ComparePlans.tsx (1)
59-61: Tighten RefObject types; adjust useRef generics to include null.RefObject already models current: T | null. Prefer RefObject and make useRef generic include null for strictNullChecks.
- commercialArtRef: React.RefObject<CommercialArtRef | null>; - proArtRef: React.RefObject<ProArtRef | null>; + commercialArtRef: React.RefObject<CommercialArtRef>; + proArtRef: React.RefObject<ProArtRef>;Also update initial refs:
- const commercialArtRef = useRef<CommercialArtRef>(null); - const proArtRef = useRef<ProArtRef>(null); + const commercialArtRef = useRef<CommercialArtRef | null>(null); + const proArtRef = useRef<ProArtRef | null>(null);apps/web/app/(org)/dashboard/folder/[id]/page.tsx (1)
17-21: Signature migration to Promise-based params looks correct.Consider branding the id once locally before use if downstream APIs expect FolderId brands.
const id = Folder.FolderId.make(params.id);apps/web/package.json (1)
6-9: Be cautious enabling turbopack for production builds.next build --turbopack is still evolving; confirm it’s stable for your deployment targets or gate behind an env flag.
apps/web/app/(org)/verify-otp/page.tsx (1)
16-22: Validate and constrain next redirect target to prevent open redirects.Limit next to same-origin relative paths (e.g., starting with "/").
- redirect(searchParams.next || "/dashboard"); + const next = (searchParams.next && searchParams.next.startsWith("/")) ? searchParams.next : "/dashboard"; + redirect(next);apps/web/app/api/releases/macos/route.ts (3)
21-46: Select the correct macOS asset by architecture and remove unused arch normalization.Currently, arch is normalized but never used; the code picks the first .dmg, which can return the wrong build. Prefer deterministic selection (Apple Silicon first), then fall back.
Apply:
- if (params.arch === "x86_64") { - params.arch = "x64"; - } + const preferredArchOrder = ["aarch64", "arm64", "universal", "x86_64", "x64"]; @@ - const asset = release.assets.find((asset) => asset.name.endsWith(".dmg")); + const asset = + release.assets.find( + (a) => + a.name.endsWith(".dmg") && + preferredArchOrder.some((arch) => a.name.toLowerCase().includes(arch)), + ) ?? release.assets.find((a) => a.name.endsWith(".dmg"));
47-50: Return a more accurate error status/message.400 suggests a client error; this is a backend fetch failure. Use 502 and a clearer message.
- return Response.json({ error: "Missing required fields" }, { status: 400 }); + return Response.json( + { error: "Failed to fetch latest release" }, + { status: 502 }, + );
9-12: Remove theas anyby giving GET an explicit type.This avoids
anyand keeps strict TypeScript.-export const GET = (async ( - req: Request, - props: { - params: Promise<{ - version: string; - target: string; - arch: string; - }>; - }, -) => { +export async function GET( + req: Request, + props: { + params: Promise<{ + version: string; + target: string; + arch: string; + }>; + }, +) { @@ -}) as any; +}Also applies to: 51-51
apps/web/app/(org)/invite/[inviteId]/page.tsx (1)
14-14: Normalize import path.Double slash is unnecessary and can confuse tooling; use a single slash.
-import { InviteAccept } from ".//InviteAccept"; +import { InviteAccept } from "./InviteAccept";apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/CustomDomainDialog.tsx (1)
142-142: PreferReturnType<typeof setInterval>for browser timers.Line 142: In the browser,
setIntervalresolves tonumber, so storing it asNodeJS.Timeoutcan produce type friction when DOM libs take precedence. Swapping toReturnType<typeof setInterval>keeps both Node and DOM signatures happy.- const pollInterval = useRef<NodeJS.Timeout | undefined>(undefined); + const pollInterval = useRef<ReturnType<typeof setInterval> | undefined>(undefined);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (61)
apps/desktop/package.json(1 hunks)apps/web/actions/videos/password.ts(1 hunks)apps/web/app/(org)/dashboard/_components/Navbar/Items.tsx(2 hunks)apps/web/app/(org)/dashboard/_components/Navbar/SpaceDialog.tsx(1 hunks)apps/web/app/(org)/dashboard/_components/Navbar/Top.tsx(2 hunks)apps/web/app/(org)/dashboard/_components/actions.ts(1 hunks)apps/web/app/(org)/dashboard/caps/components/FoldersDropdown.tsx(1 hunks)apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx(1 hunks)apps/web/app/(org)/dashboard/caps/page.tsx(1 hunks)apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx(1 hunks)apps/web/app/(org)/dashboard/folder/[id]/page.tsx(1 hunks)apps/web/app/(org)/dashboard/layout.tsx(1 hunks)apps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/CustomDomainDialog.tsx(1 hunks)apps/web/app/(org)/dashboard/spaces/[spaceId]/components/VirtualizedVideoGrid.tsx(2 hunks)apps/web/app/(org)/dashboard/spaces/[spaceId]/folder/[folderId]/page.tsx(1 hunks)apps/web/app/(org)/dashboard/spaces/[spaceId]/page.tsx(1 hunks)apps/web/app/(org)/invite/[inviteId]/page.tsx(2 hunks)apps/web/app/(org)/verify-otp/page.tsx(1 hunks)apps/web/app/(site)/[slug]/page.tsx(2 hunks)apps/web/app/(site)/blog/[slug]/page.tsx(2 hunks)apps/web/app/(site)/docs/[...slug]/page.tsx(2 hunks)apps/web/app/(site)/docs/[slug]/page.tsx(2 hunks)apps/web/app/(site)/download/[platform]/route.ts(1 hunks)apps/web/app/(site)/page.tsx(1 hunks)apps/web/app/(site)/tools/convert/[conversionPath]/page.tsx(2 hunks)apps/web/app/api/erpc/route.ts(1 hunks)apps/web/app/api/playlist/route.ts(2 hunks)apps/web/app/api/releases/macos/route.ts(2 hunks)apps/web/app/api/releases/tauri/[version]/[target]/[arch]/route.ts(1 hunks)apps/web/app/api/utils.ts(1 hunks)apps/web/app/api/video/comment/route.ts(1 hunks)apps/web/app/api/video/delete/route.ts(1 hunks)apps/web/app/api/videos/[videoId]/retry-transcription/route.ts(1 hunks)apps/web/app/embed/[videoId]/page.tsx(3 hunks)apps/web/app/robots.ts(1 hunks)apps/web/app/s/[videoId]/_components/CapVideoPlayer.tsx(1 hunks)apps/web/app/s/[videoId]/_components/HLSVideoPlayer.tsx(1 hunks)apps/web/app/s/[videoId]/_components/tabs/Activity/Comments.tsx(1 hunks)apps/web/app/s/[videoId]/_components/tabs/Activity/index.tsx(1 hunks)apps/web/app/s/[videoId]/page.tsx(5 hunks)apps/web/components/features/FeaturePage.tsx(1 hunks)apps/web/components/forms/NewOrganization.tsx(1 hunks)apps/web/components/pages/HomePage/Features.tsx(1 hunks)apps/web/components/pages/HomePage/RecordingModes.tsx(1 hunks)apps/web/components/pages/_components/ComparePlans.tsx(1 hunks)apps/web/components/seo/types.ts(1 hunks)apps/web/lib/features/transform.ts(1 hunks)apps/web/lib/server.ts(3 hunks)apps/web/next.config.mjs(0 hunks)apps/web/package.json(5 hunks)apps/web/tsconfig.json(1 hunks)apps/web/utils/getBootstrapData.ts(1 hunks)apps/workflow-manager/package.json(1 hunks)apps/workflow-runner/package.json(1 hunks)packages/database/auth/auth-options.ts(3 hunks)packages/database/package.json(2 hunks)packages/ui/package.json(1 hunks)packages/utils/package.json(1 hunks)packages/web-api-contract-effect/package.json(1 hunks)packages/web-backend/package.json(1 hunks)packages/web-domain/package.json(1 hunks)
💤 Files with no reviewable changes (1)
- apps/web/next.config.mjs
🧰 Additional context used
📓 Path-based instructions (10)
apps/web/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
apps/web/**/*.{ts,tsx}: Use TanStack Query v5 for all client-side server state and data fetching in the web app
Web mutations should call Server Actions directly and perform targeted cache updates with setQueryData/setQueriesData rather than broad invalidations
Client code should use useEffectQuery/useEffectMutation and useRpcClient from apps/web/lib/EffectRuntime.ts; do not create ManagedRuntime inside components
Files:
apps/web/app/(site)/tools/convert/[conversionPath]/page.tsxapps/web/components/pages/HomePage/RecordingModes.tsxapps/web/app/s/[videoId]/_components/CapVideoPlayer.tsxapps/web/app/(org)/dashboard/caps/components/FoldersDropdown.tsxapps/web/app/(org)/dashboard/folder/[id]/page.tsxapps/web/app/(site)/download/[platform]/route.tsapps/web/components/pages/HomePage/Features.tsxapps/web/app/api/video/comment/route.tsapps/web/app/(org)/dashboard/caps/page.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/components/VirtualizedVideoGrid.tsxapps/web/app/api/utils.tsapps/web/actions/videos/password.tsapps/web/app/s/[videoId]/_components/HLSVideoPlayer.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/page.tsxapps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsxapps/web/app/(site)/blog/[slug]/page.tsxapps/web/lib/features/transform.tsapps/web/app/s/[videoId]/_components/tabs/Activity/Comments.tsxapps/web/app/s/[videoId]/page.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/folder/[folderId]/page.tsxapps/web/app/(org)/dashboard/_components/Navbar/Items.tsxapps/web/app/(site)/[slug]/page.tsxapps/web/app/(org)/dashboard/layout.tsxapps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/CustomDomainDialog.tsxapps/web/app/embed/[videoId]/page.tsxapps/web/lib/server.tsapps/web/app/robots.tsapps/web/app/(org)/verify-otp/page.tsxapps/web/components/seo/types.tsapps/web/components/forms/NewOrganization.tsxapps/web/app/(site)/docs/[...slug]/page.tsxapps/web/app/(org)/dashboard/_components/actions.tsapps/web/components/features/FeaturePage.tsxapps/web/utils/getBootstrapData.tsapps/web/app/(org)/dashboard/_components/Navbar/SpaceDialog.tsxapps/web/app/(org)/invite/[inviteId]/page.tsxapps/web/app/api/releases/macos/route.tsapps/web/app/(site)/page.tsxapps/web/app/s/[videoId]/_components/tabs/Activity/index.tsxapps/web/app/api/erpc/route.tsapps/web/app/api/video/delete/route.tsapps/web/app/api/playlist/route.tsapps/web/app/api/releases/tauri/[version]/[target]/[arch]/route.tsapps/web/app/api/videos/[videoId]/retry-transcription/route.tsapps/web/app/(org)/dashboard/_components/Navbar/Top.tsxapps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsxapps/web/components/pages/_components/ComparePlans.tsxapps/web/app/(site)/docs/[slug]/page.tsx
apps/web/app/**/*.{tsx,ts}
📄 CodeRabbit inference engine (CLAUDE.md)
Prefer Server Components for initial data in the Next.js App Router and pass initialData to client components
Files:
apps/web/app/(site)/tools/convert/[conversionPath]/page.tsxapps/web/app/s/[videoId]/_components/CapVideoPlayer.tsxapps/web/app/(org)/dashboard/caps/components/FoldersDropdown.tsxapps/web/app/(org)/dashboard/folder/[id]/page.tsxapps/web/app/(site)/download/[platform]/route.tsapps/web/app/api/video/comment/route.tsapps/web/app/(org)/dashboard/caps/page.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/components/VirtualizedVideoGrid.tsxapps/web/app/api/utils.tsapps/web/app/s/[videoId]/_components/HLSVideoPlayer.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/page.tsxapps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsxapps/web/app/(site)/blog/[slug]/page.tsxapps/web/app/s/[videoId]/_components/tabs/Activity/Comments.tsxapps/web/app/s/[videoId]/page.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/folder/[folderId]/page.tsxapps/web/app/(org)/dashboard/_components/Navbar/Items.tsxapps/web/app/(site)/[slug]/page.tsxapps/web/app/(org)/dashboard/layout.tsxapps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/CustomDomainDialog.tsxapps/web/app/embed/[videoId]/page.tsxapps/web/app/robots.tsapps/web/app/(org)/verify-otp/page.tsxapps/web/app/(site)/docs/[...slug]/page.tsxapps/web/app/(org)/dashboard/_components/actions.tsapps/web/app/(org)/dashboard/_components/Navbar/SpaceDialog.tsxapps/web/app/(org)/invite/[inviteId]/page.tsxapps/web/app/api/releases/macos/route.tsapps/web/app/(site)/page.tsxapps/web/app/s/[videoId]/_components/tabs/Activity/index.tsxapps/web/app/api/erpc/route.tsapps/web/app/api/video/delete/route.tsapps/web/app/api/playlist/route.tsapps/web/app/api/releases/tauri/[version]/[target]/[arch]/route.tsapps/web/app/api/videos/[videoId]/retry-transcription/route.tsapps/web/app/(org)/dashboard/_components/Navbar/Top.tsxapps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsxapps/web/app/(site)/docs/[slug]/page.tsx
**/*.{ts,tsx,js,jsx,rs}
📄 CodeRabbit inference engine (CLAUDE.md)
Do not add inline, block, or docstring comments in any language; code must be self-explanatory
Files:
apps/web/app/(site)/tools/convert/[conversionPath]/page.tsxapps/web/components/pages/HomePage/RecordingModes.tsxapps/web/app/s/[videoId]/_components/CapVideoPlayer.tsxapps/web/app/(org)/dashboard/caps/components/FoldersDropdown.tsxapps/web/app/(org)/dashboard/folder/[id]/page.tsxapps/web/app/(site)/download/[platform]/route.tsapps/web/components/pages/HomePage/Features.tsxapps/web/app/api/video/comment/route.tsapps/web/app/(org)/dashboard/caps/page.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/components/VirtualizedVideoGrid.tsxapps/web/app/api/utils.tsapps/web/actions/videos/password.tsapps/web/app/s/[videoId]/_components/HLSVideoPlayer.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/page.tsxapps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsxapps/web/app/(site)/blog/[slug]/page.tsxapps/web/lib/features/transform.tsapps/web/app/s/[videoId]/_components/tabs/Activity/Comments.tsxapps/web/app/s/[videoId]/page.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/folder/[folderId]/page.tsxpackages/database/auth/auth-options.tsapps/web/app/(org)/dashboard/_components/Navbar/Items.tsxapps/web/app/(site)/[slug]/page.tsxapps/web/app/(org)/dashboard/layout.tsxapps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/CustomDomainDialog.tsxapps/web/app/embed/[videoId]/page.tsxapps/web/lib/server.tsapps/web/app/robots.tsapps/web/app/(org)/verify-otp/page.tsxapps/web/components/seo/types.tsapps/web/components/forms/NewOrganization.tsxapps/web/app/(site)/docs/[...slug]/page.tsxapps/web/app/(org)/dashboard/_components/actions.tsapps/web/components/features/FeaturePage.tsxapps/web/utils/getBootstrapData.tsapps/web/app/(org)/dashboard/_components/Navbar/SpaceDialog.tsxapps/web/app/(org)/invite/[inviteId]/page.tsxapps/web/app/api/releases/macos/route.tsapps/web/app/(site)/page.tsxapps/web/app/s/[videoId]/_components/tabs/Activity/index.tsxapps/web/app/api/erpc/route.tsapps/web/app/api/video/delete/route.tsapps/web/app/api/playlist/route.tsapps/web/app/api/releases/tauri/[version]/[target]/[arch]/route.tsapps/web/app/api/videos/[videoId]/retry-transcription/route.tsapps/web/app/(org)/dashboard/_components/Navbar/Top.tsxapps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsxapps/web/components/pages/_components/ComparePlans.tsxapps/web/app/(site)/docs/[slug]/page.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use strict TypeScript and avoid any; leverage shared types from packages
**/*.{ts,tsx}: Use a 2-space indent for TypeScript code.
Use Biome for formatting and linting TypeScript/JavaScript files by runningpnpm format.
Files:
apps/web/app/(site)/tools/convert/[conversionPath]/page.tsxapps/web/components/pages/HomePage/RecordingModes.tsxapps/web/app/s/[videoId]/_components/CapVideoPlayer.tsxapps/web/app/(org)/dashboard/caps/components/FoldersDropdown.tsxapps/web/app/(org)/dashboard/folder/[id]/page.tsxapps/web/app/(site)/download/[platform]/route.tsapps/web/components/pages/HomePage/Features.tsxapps/web/app/api/video/comment/route.tsapps/web/app/(org)/dashboard/caps/page.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/components/VirtualizedVideoGrid.tsxapps/web/app/api/utils.tsapps/web/actions/videos/password.tsapps/web/app/s/[videoId]/_components/HLSVideoPlayer.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/page.tsxapps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsxapps/web/app/(site)/blog/[slug]/page.tsxapps/web/lib/features/transform.tsapps/web/app/s/[videoId]/_components/tabs/Activity/Comments.tsxapps/web/app/s/[videoId]/page.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/folder/[folderId]/page.tsxpackages/database/auth/auth-options.tsapps/web/app/(org)/dashboard/_components/Navbar/Items.tsxapps/web/app/(site)/[slug]/page.tsxapps/web/app/(org)/dashboard/layout.tsxapps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/CustomDomainDialog.tsxapps/web/app/embed/[videoId]/page.tsxapps/web/lib/server.tsapps/web/app/robots.tsapps/web/app/(org)/verify-otp/page.tsxapps/web/components/seo/types.tsapps/web/components/forms/NewOrganization.tsxapps/web/app/(site)/docs/[...slug]/page.tsxapps/web/app/(org)/dashboard/_components/actions.tsapps/web/components/features/FeaturePage.tsxapps/web/utils/getBootstrapData.tsapps/web/app/(org)/dashboard/_components/Navbar/SpaceDialog.tsxapps/web/app/(org)/invite/[inviteId]/page.tsxapps/web/app/api/releases/macos/route.tsapps/web/app/(site)/page.tsxapps/web/app/s/[videoId]/_components/tabs/Activity/index.tsxapps/web/app/api/erpc/route.tsapps/web/app/api/video/delete/route.tsapps/web/app/api/playlist/route.tsapps/web/app/api/releases/tauri/[version]/[target]/[arch]/route.tsapps/web/app/api/videos/[videoId]/retry-transcription/route.tsapps/web/app/(org)/dashboard/_components/Navbar/Top.tsxapps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsxapps/web/components/pages/_components/ComparePlans.tsxapps/web/app/(site)/docs/[slug]/page.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Use kebab-case for filenames for TypeScript/JavaScript modules (e.g.,user-menu.tsx).
Use PascalCase for React/Solid components.
Files:
apps/web/app/(site)/tools/convert/[conversionPath]/page.tsxapps/web/components/pages/HomePage/RecordingModes.tsxapps/web/app/s/[videoId]/_components/CapVideoPlayer.tsxapps/web/app/(org)/dashboard/caps/components/FoldersDropdown.tsxapps/web/app/(org)/dashboard/folder/[id]/page.tsxapps/web/app/(site)/download/[platform]/route.tsapps/web/components/pages/HomePage/Features.tsxapps/web/app/api/video/comment/route.tsapps/web/app/(org)/dashboard/caps/page.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/components/VirtualizedVideoGrid.tsxapps/web/app/api/utils.tsapps/web/actions/videos/password.tsapps/web/app/s/[videoId]/_components/HLSVideoPlayer.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/page.tsxapps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsxapps/web/app/(site)/blog/[slug]/page.tsxapps/web/lib/features/transform.tsapps/web/app/s/[videoId]/_components/tabs/Activity/Comments.tsxapps/web/app/s/[videoId]/page.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/folder/[folderId]/page.tsxpackages/database/auth/auth-options.tsapps/web/app/(org)/dashboard/_components/Navbar/Items.tsxapps/web/app/(site)/[slug]/page.tsxapps/web/app/(org)/dashboard/layout.tsxapps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/CustomDomainDialog.tsxapps/web/app/embed/[videoId]/page.tsxapps/web/lib/server.tsapps/web/app/robots.tsapps/web/app/(org)/verify-otp/page.tsxapps/web/components/seo/types.tsapps/web/components/forms/NewOrganization.tsxapps/web/app/(site)/docs/[...slug]/page.tsxapps/web/app/(org)/dashboard/_components/actions.tsapps/web/components/features/FeaturePage.tsxapps/web/utils/getBootstrapData.tsapps/web/app/(org)/dashboard/_components/Navbar/SpaceDialog.tsxapps/web/app/(org)/invite/[inviteId]/page.tsxapps/web/app/api/releases/macos/route.tsapps/web/app/(site)/page.tsxapps/web/app/s/[videoId]/_components/tabs/Activity/index.tsxapps/web/app/api/erpc/route.tsapps/web/app/api/video/delete/route.tsapps/web/app/api/playlist/route.tsapps/web/app/api/releases/tauri/[version]/[target]/[arch]/route.tsapps/web/app/api/videos/[videoId]/retry-transcription/route.tsapps/web/app/(org)/dashboard/_components/Navbar/Top.tsxapps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsxapps/web/components/pages/_components/ComparePlans.tsxapps/web/app/(site)/docs/[slug]/page.tsx
apps/web/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
On the client, always use
useEffectQueryoruseEffectMutationfrom@/lib/EffectRuntime; never callEffectRuntime.run*directly in components.
Files:
apps/web/app/(site)/tools/convert/[conversionPath]/page.tsxapps/web/components/pages/HomePage/RecordingModes.tsxapps/web/app/s/[videoId]/_components/CapVideoPlayer.tsxapps/web/app/(org)/dashboard/caps/components/FoldersDropdown.tsxapps/web/app/(org)/dashboard/folder/[id]/page.tsxapps/web/app/(site)/download/[platform]/route.tsapps/web/components/pages/HomePage/Features.tsxapps/web/app/api/video/comment/route.tsapps/web/app/(org)/dashboard/caps/page.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/components/VirtualizedVideoGrid.tsxapps/web/app/api/utils.tsapps/web/actions/videos/password.tsapps/web/app/s/[videoId]/_components/HLSVideoPlayer.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/page.tsxapps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsxapps/web/app/(site)/blog/[slug]/page.tsxapps/web/lib/features/transform.tsapps/web/app/s/[videoId]/_components/tabs/Activity/Comments.tsxapps/web/app/s/[videoId]/page.tsxapps/web/app/(org)/dashboard/spaces/[spaceId]/folder/[folderId]/page.tsxapps/web/app/(org)/dashboard/_components/Navbar/Items.tsxapps/web/app/(site)/[slug]/page.tsxapps/web/app/(org)/dashboard/layout.tsxapps/web/app/(org)/dashboard/settings/organization/components/CustomDomainDialog/CustomDomainDialog.tsxapps/web/app/embed/[videoId]/page.tsxapps/web/lib/server.tsapps/web/app/robots.tsapps/web/app/(org)/verify-otp/page.tsxapps/web/components/seo/types.tsapps/web/components/forms/NewOrganization.tsxapps/web/app/(site)/docs/[...slug]/page.tsxapps/web/app/(org)/dashboard/_components/actions.tsapps/web/components/features/FeaturePage.tsxapps/web/utils/getBootstrapData.tsapps/web/app/(org)/dashboard/_components/Navbar/SpaceDialog.tsxapps/web/app/(org)/invite/[inviteId]/page.tsxapps/web/app/api/releases/macos/route.tsapps/web/app/(site)/page.tsxapps/web/app/s/[videoId]/_components/tabs/Activity/index.tsxapps/web/app/api/erpc/route.tsapps/web/app/api/video/delete/route.tsapps/web/app/api/playlist/route.tsapps/web/app/api/releases/tauri/[version]/[target]/[arch]/route.tsapps/web/app/api/videos/[videoId]/retry-transcription/route.tsapps/web/app/(org)/dashboard/_components/Navbar/Top.tsxapps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsxapps/web/components/pages/_components/ComparePlans.tsxapps/web/app/(site)/docs/[slug]/page.tsx
apps/web/app/api/**/route.ts
📄 CodeRabbit inference engine (CLAUDE.md)
apps/web/app/api/**/route.ts: Place API routes only under apps/web/app/api and implement each route in a route.ts file
Construct API routes with @effect/platform HttpApi/HttpApiBuilder and export only the handler from apiToHandler(ApiLive)
Map domain errors to transport errors with HttpApiError.* and keep error translation exhaustive
Use HttpAuthMiddleware for required auth and provideOptionalAuth for guest routes; avoid duplicate session lookups
Provide dependencies via Layer.provide in API routes instead of manual provideService calls
Files:
apps/web/app/api/video/comment/route.tsapps/web/app/api/releases/macos/route.tsapps/web/app/api/erpc/route.tsapps/web/app/api/video/delete/route.tsapps/web/app/api/playlist/route.tsapps/web/app/api/releases/tauri/[version]/[target]/[arch]/route.tsapps/web/app/api/videos/[videoId]/retry-transcription/route.ts
apps/web/app/api/*
📄 CodeRabbit inference engine (AGENTS.md)
apps/web/app/api/*: API routes in Next.js (apps/web/app/api/*) must use@effect/platform'sHttpApibuilder and follow the existing class/group/endpoint pattern; avoid ad-hoc handlers.
Convert effectful APIs to Next.js handlers usingapiToHandler(ApiLive)and export only the returnedhandler; avoid callingrunPromisedirectly in route files.
Acquire backend services insideEffect.genand wire them usingLayer.provide/HttpApiBuilder.group, translating errors toHttpApiErroras appropriate.
On the server, always run effects throughEffectRuntime.runPromiseafterprovideOptionalAuthto ensure cookies and per-request context are attached.
Files:
apps/web/app/api/utils.ts
apps/web/actions/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
All Groq/OpenAI calls must be implemented in Next.js Server Actions under apps/web/actions; do not place AI calls elsewhere
Files:
apps/web/actions/videos/password.ts
packages/web-api-contract-effect/**
📄 CodeRabbit inference engine (CLAUDE.md)
Update shared HTTP contracts in packages/web-api-contract-effect alongside any API route changes to keep schemas in sync
Files:
packages/web-api-contract-effect/package.json
🧠 Learnings (6)
📚 Learning: 2025-09-22T14:17:47.380Z
Learnt from: CR
PR: CapSoftware/Cap#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-22T14:17:47.380Z
Learning: Applies to **/*.{ts,tsx} : Use strict TypeScript and avoid any; leverage shared types from packages
Applied to files:
apps/web/tsconfig.json
📚 Learning: 2025-09-22T14:19:55.985Z
Learnt from: CR
PR: CapSoftware/Cap#0
File: AGENTS.md:0-0
Timestamp: 2025-09-22T14:19:55.985Z
Learning: Applies to apps/web/app/api/* : On the server, always run effects through `EffectRuntime.runPromise` after `provideOptionalAuth` to ensure cookies and per-request context are attached.
Applied to files:
apps/web/lib/server.ts
📚 Learning: 2025-09-22T14:19:55.985Z
Learnt from: CR
PR: CapSoftware/Cap#0
File: AGENTS.md:0-0
Timestamp: 2025-09-22T14:19:55.985Z
Learning: Applies to apps/web/app/api/* : API routes in Next.js (`apps/web/app/api/*`) must use `effect/platform`'s `HttpApi` builder and follow the existing class/group/endpoint pattern; avoid ad-hoc handlers.
Applied to files:
apps/web/lib/server.ts
📚 Learning: 2025-09-22T14:17:47.380Z
Learnt from: CR
PR: CapSoftware/Cap#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-22T14:17:47.380Z
Learning: Applies to apps/web/app/api/**/route.ts : Construct API routes with effect/platform HttpApi/HttpApiBuilder and export only the handler from apiToHandler(ApiLive)
Applied to files:
apps/web/app/api/erpc/route.tsapps/web/app/api/video/delete/route.tsapps/web/app/api/playlist/route.ts
📚 Learning: 2025-09-22T14:19:55.985Z
Learnt from: CR
PR: CapSoftware/Cap#0
File: AGENTS.md:0-0
Timestamp: 2025-09-22T14:19:55.985Z
Learning: Applies to apps/web/app/api/* : Convert effectful APIs to Next.js handlers using `apiToHandler(ApiLive)` and export only the returned `handler`; avoid calling `runPromise` directly in route files.
Applied to files:
apps/web/app/api/video/delete/route.tsapps/web/app/api/playlist/route.ts
📚 Learning: 2025-09-22T14:17:47.380Z
Learnt from: CR
PR: CapSoftware/Cap#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-22T14:17:47.380Z
Learning: Applies to packages/web-api-contract-effect/** : Update shared HTTP contracts in packages/web-api-contract-effect alongside any API route changes to keep schemas in sync
Applied to files:
packages/web-api-contract-effect/package.jsonpackages/web-backend/package.jsonpackages/web-domain/package.json
🧬 Code graph analysis (21)
apps/web/app/(site)/tools/convert/[conversionPath]/page.tsx (5)
apps/web/app/(site)/docs/[...slug]/page.tsx (1)
generateMetadata(22-74)apps/web/app/embed/[videoId]/page.tsx (1)
generateMetadata(35-113)apps/web/app/(site)/blog/[slug]/page.tsx (1)
generateMetadata(24-68)apps/web/app/(org)/invite/[inviteId]/page.tsx (1)
generateMetadata(20-33)apps/web/app/(site)/[slug]/page.tsx (1)
generateMetadata(10-32)
apps/web/app/(org)/dashboard/folder/[id]/page.tsx (1)
packages/web-domain/src/Folder.ts (3)
Folder(19-27)FolderId(8-8)FolderId(9-9)
apps/web/app/api/video/comment/route.ts (2)
apps/web/app/api/erpc/route.ts (1)
POST(18-18)apps/web/utils/helpers.ts (1)
rateLimitMiddleware(30-64)
apps/web/actions/videos/password.ts (1)
packages/database/crypto.ts (1)
encrypt(63-96)
apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx (1)
apps/web/app/(org)/dashboard/caps/components/Folders.tsx (1)
FolderHandle(7-10)
apps/web/app/(site)/blog/[slug]/page.tsx (5)
apps/web/app/(site)/docs/[...slug]/page.tsx (1)
generateMetadata(22-74)apps/web/app/embed/[videoId]/page.tsx (1)
generateMetadata(35-113)apps/web/app/(org)/invite/[inviteId]/page.tsx (1)
generateMetadata(20-33)apps/web/app/(site)/[slug]/page.tsx (1)
generateMetadata(10-32)apps/web/app/(site)/docs/[slug]/page.tsx (1)
generateMetadata(14-49)
apps/web/app/s/[videoId]/page.tsx (3)
apps/web/app/(site)/docs/[...slug]/page.tsx (1)
generateMetadata(22-74)apps/web/app/embed/[videoId]/page.tsx (1)
generateMetadata(35-113)apps/web/app/(org)/invite/[inviteId]/page.tsx (1)
generateMetadata(20-33)
apps/web/app/(org)/dashboard/spaces/[spaceId]/folder/[folderId]/page.tsx (1)
packages/web-domain/src/Folder.ts (3)
Folder(19-27)FolderId(8-8)FolderId(9-9)
apps/web/app/(org)/dashboard/_components/Navbar/Items.tsx (1)
apps/web/app/(org)/dashboard/_components/AnimatedIcons/Cog.tsx (1)
CogIconHandle(8-11)
apps/web/app/(site)/[slug]/page.tsx (4)
apps/web/app/(site)/docs/[...slug]/page.tsx (1)
generateMetadata(22-74)apps/web/app/embed/[videoId]/page.tsx (1)
generateMetadata(35-113)apps/web/app/(site)/blog/[slug]/page.tsx (1)
generateMetadata(24-68)apps/web/app/(org)/invite/[inviteId]/page.tsx (1)
generateMetadata(20-33)
apps/web/app/embed/[videoId]/page.tsx (2)
apps/web/app/(site)/docs/[...slug]/page.tsx (1)
generateMetadata(22-74)apps/web/app/s/[videoId]/page.tsx (1)
generateMetadata(125-254)
apps/web/app/robots.ts (1)
apps/web/lib/seo-pages.ts (1)
seoPages(31-66)
apps/web/app/(site)/docs/[...slug]/page.tsx (6)
apps/web/app/embed/[videoId]/page.tsx (1)
generateMetadata(35-113)apps/web/app/s/[videoId]/page.tsx (1)
generateMetadata(125-254)apps/web/app/(site)/blog/[slug]/page.tsx (1)
generateMetadata(24-68)apps/web/app/(org)/invite/[inviteId]/page.tsx (1)
generateMetadata(20-33)apps/web/app/(site)/[slug]/page.tsx (1)
generateMetadata(10-32)apps/web/app/(site)/tools/convert/[conversionPath]/page.tsx (1)
generateMetadata(17-55)
apps/web/app/(org)/invite/[inviteId]/page.tsx (2)
apps/web/app/(site)/docs/[...slug]/page.tsx (1)
generateMetadata(22-74)apps/web/app/embed/[videoId]/page.tsx (1)
generateMetadata(35-113)
apps/web/app/api/releases/macos/route.ts (4)
apps/web/app/api/erpc/route.ts (1)
GET(17-17)apps/web/app/api/playlist/route.ts (1)
GET(245-245)apps/web/app/(site)/download/[platform]/route.ts (1)
GET(8-45)apps/web/app/api/releases/tauri/[version]/[target]/[arch]/route.ts (1)
GET(9-71)
apps/web/app/api/erpc/route.ts (3)
apps/web/app/api/playlist/route.ts (1)
GET(245-245)apps/web/app/api/releases/macos/route.ts (1)
GET(9-51)apps/web/app/api/video/comment/route.ts (2)
GET(96-98)POST(91-94)
apps/web/app/api/playlist/route.ts (4)
apps/web/app/embed/[videoId]/page.tsx (1)
dynamic(26-26)apps/web/app/s/[videoId]/page.tsx (1)
dynamic(37-37)apps/web/app/api/settings/billing/usage/route.ts (2)
dynamic(7-7)GET(9-47)apps/web/app/api/erpc/route.ts (1)
GET(17-17)
apps/web/app/(org)/dashboard/_components/Navbar/Top.tsx (1)
apps/web/app/(org)/dashboard/_components/AnimatedIcons/Download.tsx (1)
DownloadIconHandle(9-12)
apps/web/app/(org)/dashboard/folder/[id]/components/SubfolderDialog.tsx (1)
apps/web/app/(org)/dashboard/caps/components/Folders.tsx (1)
FolderHandle(7-10)
apps/web/components/pages/_components/ComparePlans.tsx (2)
apps/web/components/pages/HomePage/Pricing/CommercialArt.tsx (1)
CommercialArtRef(5-8)apps/web/components/pages/HomePage/Pricing/ProArt.tsx (1)
ProArtRef(5-8)
apps/web/app/(site)/docs/[slug]/page.tsx (7)
apps/web/app/(site)/docs/[...slug]/page.tsx (2)
generateMetadata(22-74)DocPage(76-201)apps/web/app/embed/[videoId]/page.tsx (1)
generateMetadata(35-113)apps/web/app/s/[videoId]/page.tsx (1)
generateMetadata(125-254)apps/web/app/(site)/blog/[slug]/page.tsx (1)
generateMetadata(24-68)apps/web/app/(org)/invite/[inviteId]/page.tsx (1)
generateMetadata(20-33)apps/web/app/(site)/[slug]/page.tsx (1)
generateMetadata(10-32)apps/web/app/(site)/tools/convert/[conversionPath]/page.tsx (1)
generateMetadata(17-55)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Vercel Agent Review
- GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
- GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
- GitHub Check: Analyze (rust)
apps/web/app/(org)/dashboard/spaces/[spaceId]/components/VirtualizedVideoGrid.tsx
Show resolved
Hide resolved
|
@coderabbitai don't review this pr |
|
Tip For best results, initiate chat on the files or code changes. @oscartbeaumont Understood! I won't review this PR. The automated review will be skipped for PR #1033. |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/web/app/(org)/dashboard/_components/Navbar/Items.tsx(2 hunks)apps/web/app/(org)/dashboard/_components/Navbar/Top.tsx(2 hunks)apps/web/app/(org)/dashboard/spaces/[spaceId]/components/VirtualizedVideoGrid.tsx(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/web/app/(org)/dashboard/spaces/[spaceId]/components/VirtualizedVideoGrid.tsx
- apps/web/app/(org)/dashboard/_components/Navbar/Items.tsx
🧰 Additional context used
📓 Path-based instructions (6)
apps/web/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
apps/web/**/*.{ts,tsx}: Use TanStack Query v5 for all client-side server state and data fetching in the web app
Web mutations should call Server Actions directly and perform targeted cache updates with setQueryData/setQueriesData rather than broad invalidations
Client code should use useEffectQuery/useEffectMutation and useRpcClient from apps/web/lib/EffectRuntime.ts; do not create ManagedRuntime inside components
Files:
apps/web/app/(org)/dashboard/_components/Navbar/Top.tsx
apps/web/app/**/*.{tsx,ts}
📄 CodeRabbit inference engine (CLAUDE.md)
Prefer Server Components for initial data in the Next.js App Router and pass initialData to client components
Files:
apps/web/app/(org)/dashboard/_components/Navbar/Top.tsx
**/*.{ts,tsx,js,jsx,rs}
📄 CodeRabbit inference engine (CLAUDE.md)
Do not add inline, block, or docstring comments in any language; code must be self-explanatory
Files:
apps/web/app/(org)/dashboard/_components/Navbar/Top.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use strict TypeScript and avoid any; leverage shared types from packages
**/*.{ts,tsx}: Use a 2-space indent for TypeScript code.
Use Biome for formatting and linting TypeScript/JavaScript files by runningpnpm format.
Files:
apps/web/app/(org)/dashboard/_components/Navbar/Top.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Use kebab-case for filenames for TypeScript/JavaScript modules (e.g.,user-menu.tsx).
Use PascalCase for React/Solid components.
Files:
apps/web/app/(org)/dashboard/_components/Navbar/Top.tsx
apps/web/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
On the client, always use
useEffectQueryoruseEffectMutationfrom@/lib/EffectRuntime; never callEffectRuntime.run*directly in components.
Files:
apps/web/app/(org)/dashboard/_components/Navbar/Top.tsx
🧬 Code graph analysis (1)
apps/web/app/(org)/dashboard/_components/Navbar/Top.tsx (1)
apps/web/app/(org)/dashboard/_components/AnimatedIcons/Download.tsx (1)
DownloadIconHandle(9-12)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Vercel Agent Review
- GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
- GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
- GitHub Check: Analyze (rust)
|
@oscartbeaumont I understand. I'll pause the automatic reviews for this PR as requested. ✅ Actions performedReviews paused. |
Me don't like waiting for Next.js to compile. Upgrade to the latest version so we can potentially enable Turbopack in a follow up PR?
This upgrade was mostly done via the Next.js codemod.
Summary by CodeRabbit
Chores
Performance
Bug Fixes
Refactor