Loading...
Loading...
LOAD THIS SKILL when: reviewing code before PR, user mentions 'code review', 'review', 'pre-PR check', 'code quality audit'. Contains project-specific review checklist covering TRPC, TanStack, Drizzle, security, performance, and Effect patterns.
npx skill4agent add blogic-cz/agent-tools code-reviewbun run checkgit log -5 --oneline && git diff HEAD~5..HEAD --statgit diff main..HEAD --stattrpc-patterns// ✅ Correct - Using RouterOutputs/RouterInputs
type SessionData = RouterOutputs["adminAuthSessions"]["listTokens"]["sessions"][0];
// ❌ Wrong - Manual type definitions
type SessionData = { sessionId: string; ... };// ✅ Correct - Using error helpers
throw notFoundError("Project not found");
// ❌ Wrong - Manual TRPCError
throw new TRPCError({ code: "NOT_FOUND", message: "..." });// ✅ Correct - protectedMemberAccessProcedure for org-scoped
export const router = {
getOrgData: protectedMemberAccessProcedure
.input(z.object({ organizationId: z.string() }))
.query(...)
}
// ❌ Wrong - Manual membership check in protectedProcedure// ✅ Correct - Inline simple schemas with common types
role: z.enum([OrganizationRoles.Owner, OrganizationRoles.Admin]);
// ❌ Wrong - Hardcoded enum values
role: z.enum(["owner", "admin"]);// ✅ Correct - Single query with JOINs
const result = await db.select({...}).from(membersTable)
.innerJoin(organizationsTable, eq(...))
.leftJoin(projectsTable, eq(...))
// ❌ Wrong - Multiple separate queries (N+1)
const orgs = await db.select().from(organizationsTable);
const members = await db.select().from(membersTable);tanstack-frontend// ✅ Correct - TRPC v11 pattern with .queryOptions()
const { data } = useSuspenseQuery(trpc.organization.getById.queryOptions({ id }));
// ❌ Wrong - Old pattern (doesn't exist in v11)
const { data } = trpc.organization.getById.useQuery({ id });// ✅ Correct - Prefetch critical data with await
loader: async ({ context, params }) => {
await context.queryClient.prefetchQuery(
context.trpc.organization.getById.queryOptions({ id: params.id })
);
// Secondary data - void for optimization
void context.queryClient.prefetchQuery(
context.trpc.analytics.getStats.queryOptions({ id: params.id })
);
}
// ❌ Wrong - Sequential await (slow)
await context.queryClient.prefetchQuery(...);
await context.queryClient.prefetchQuery(...);
await context.queryClient.prefetchQuery(...);
// ❌ Wrong - All void (component will suspend)
void context.queryClient.prefetchQuery(...); // critical data!// ✅ Correct - Props type naming
type Props = { isOpen: boolean; onClose: () => void; };
// ❌ Wrong - Component-specific props naming
type DeleteMemberModalProps = { ... };// ✅ Correct - Cache invalidation
await queryClient.invalidateQueries({
queryKey: trpc.organization.queryKey(),
});packages/services/src/packages/common/src/utils.ts@/path@project/*apps/web-app/src??||Bun.file()Bun.spawn()contact-form.tsxContactForm.tsxtypeinterface@project/loggerconsole.log/errorindex.tspackages/*/src/index.tsexport *../packages/console.log/error@project/loggergrep -iE "api[_-]?key|password|secret|token"protectedProcedureprotectedMemberAccessProcedure@/infrastructure/errorsbadRequestError()unauthorizedError()forbiddenError()notFoundError()Promise.all()awaitPromise.all()fetchQueryprefetchQuerypackages/services/src/__tests__/effect-tspackages/services/effect-runtime.tsEffect.genContext.Tag// ✅ Correct - Service with @project namespace
export class MyService extends Context.Tag("@project/MyService")<...>() {}
// ❌ Wrong - Missing namespace
export class MyService extends Context.Tag("MyService")<...>() {}// ✅ Correct - Effect.fn for tracing
const doSomething = Effect.fn("MyService.doSomething")(
function* (params) { ... }
);
// ❌ Wrong - No tracing
const doSomething = (params) => Effect.gen(function* () { ... });// ✅ Correct - Schema.TaggedError
export class MyError extends Schema.TaggedError<MyError>()("MyError", {...}) {}
// ❌ Wrong - Data.TaggedError (less Schema interop)
export class MyError extends Data.TaggedError("MyError")<{...}> {}// ✅ Correct - ManagedRuntime for TRPC
import { runtime } from "@/infrastructure/effect-runtime";
await runtime.runPromise(Effect.gen(function* () { ... }));
// ❌ Wrong - Inline provide per request
await Effect.runPromise(effect.pipe(Effect.provide(ServiceLive)));/scan-effect-solutionsQuery: "React useEffect cleanup best practices"
Query: "TRPC v11 queryOptions pattern"1. context7-resolve-library-id(libraryName: "tanstack-query")
2. context7-get-library-docs(context7CompatibleLibraryID: "...", topic: "prefetchQuery").useQuery.queryOptionsRouterInputsRouterOutputs# Code Review Report
**Scope:** [What was reviewed]
**Date:** [Current date]
---
## CRITICAL ISSUES
[List with file:line, description, fix]
---
## MAJOR ISSUES
[List with file:line, description, fix]
---
## MINOR ISSUES
[List with file:line, brief description]
---
## POSITIVE OBSERVATIONS
- [Good patterns found]
---
## SUMMARY
**Assessment:** [APPROVE / NEEDS_WORK / REJECT]
**Next steps:** [Specific actions]
## Quick Stats
- Files reviewed: [N]
- Issues: Critical: [N], Major: [N], Minor: [N]bun run checktrpc-patternstanstack-frontendeffect-tsscan-effect-solutionsproduction-troubleshooting