feat(docs): add AI Coding Agent instructions for universal starter se…#3
feat(docs): add AI Coding Agent instructions for universal starter se…#3chakrihacker wants to merge 3 commits into
Conversation
- Added ORPC dependencies to package.json. - Implemented ORPC handler in src/orpc/index.ts with CORS and OpenAPI plugins. - Created authentication middleware for ORPC to manage user sessions and roles. - Developed database middleware to provide Prisma instance to ORPC context. - Defined user-related procedures, including a 'me' endpoint to fetch user details. - Established appRouter to organize ORPC procedures. - Updated tsconfig.json for improved module resolution and TypeScript features.
Reviewer's GuideThis PR refactors the TypeScript configuration for bundler and environment settings, integrates a type-safe oRPC layer (OpenAPI handler, middleware, routers, and procedures) into the Elysia server, updates package dependencies, and adds AI Coding Agent instructions in documentation. Sequence diagram for oRPC request handling in Elysia serversequenceDiagram
participant Client
participant ElysiaApp
participant orpcHandler
participant Middleware
participant Procedure
Client->>ElysiaApp: HTTP request to /orpc/user/me
ElysiaApp->>orpcHandler: Pass request with headers
orpcHandler->>Middleware: Apply dbProviderMiddleware
Middleware->>Middleware: Inject db
orpcHandler->>Middleware: Apply withBetterAuth
Middleware->>Middleware: Inject user/session
orpcHandler->>Procedure: Call meProcedure
Procedure->>Middleware: Apply requireAuth
Middleware-->>Procedure: Check authentication
Procedure->>orpcHandler: Return user info
orpcHandler->>ElysiaApp: Response
ElysiaApp->>Client: Response
Entity relationship diagram for oRPC context typeserDiagram
InputCtx {
headers string
}
AuthCtx {
user BAUser
session BASession
}
InputCtx ||--o{ AuthCtx : extends
AuthCtx {
headers string
user BAUser
session BASession
}
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughAdds ORPC server integration: new ORPC handler, middleware (auth and DB), a user/me procedure, and router wiring. Mounts a catch-all /orpc/* route in the server entry, introduces ORPC-related dependencies and OpenAPI handler, adds documentation for server patterns, and updates TypeScript config. Minor console-log removals in email/auth code. No breaking public API changes. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Elysia
participant ORPC as orpcHandler
participant MW as baseMiddleware
participant Auth as better-auth
participant DB as Prisma
participant Proc as user.me
Client->>Elysia: GET /orpc/user/me
Elysia->>ORPC: delegate request (prefix "/orpc", headers)
ORPC->>MW: run dbProviderMiddleware
MW->>DB: provide prisma in context
ORPC->>MW: run withBetterAuth
MW->>Auth: getSession(headers)
Auth-->>MW: session, user
ORPC->>Proc: execute requireAuth + handler
Proc->>Proc: validate context.user
Proc-->>ORPC: { id, email, name }
ORPC-->>Elysia: return response
Elysia-->>Client: 200 OK JSON
Estimated code review effort🎯 4 (Complex) | ⏱️ ~35 minutes Possibly related PRs
Suggested labels
Poem
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
There was a problem hiding this comment.
Hey @chakrihacker - I've reviewed your changes - here's some feedback:
- There are a lot of console.log debug statements in your oRPC auth middleware and handlers—consider removing or gating them before merging.
- The tsconfig changes introduce many commented-out duplicates and reordering that could confuse future maintainers—trim it down to only the strictly necessary overrides.
- The
.github/copilot-instructions.mdfile contains general docs that might be better placed under adocs/folder or trimmed to just the essentials for this repo.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- There are a lot of console.log debug statements in your oRPC auth middleware and handlers—consider removing or gating them before merging.
- The tsconfig changes introduce many commented-out duplicates and reordering that could confuse future maintainers—trim it down to only the strictly necessary overrides.
- The `.github/copilot-instructions.md` file contains general docs that might be better placed under a `docs/` folder or trimmed to just the essentials for this repo.
## Individual Comments
### Comment 1
<location> `.github/copilot-instructions.md:1` </location>
<code_context>
+# AI Coding Agent innstructions – Universal Starter (Server)
+
+## 📌 Tech Stack
</code_context>
<issue_to_address>
Typo in the word 'innstructions'—should be 'instructions'.
Update the title to use the correct spelling.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
# AI Coding Agent innstructions – Universal Starter (Server)
=======
# AI Coding Agent instructions – Universal Starter (Server)
>>>>>>> REPLACE
</suggested_fix>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| @@ -0,0 +1,47 @@ | |||
| # AI Coding Agent innstructions – Universal Starter (Server) | |||
There was a problem hiding this comment.
issue (typo): Typo in the word 'innstructions'—should be 'instructions'.
Update the title to use the correct spelling.
| # AI Coding Agent innstructions – Universal Starter (Server) | |
| # AI Coding Agent instructions – Universal Starter (Server) |
| ) | ||
| .handler(({ context }) => { | ||
| console.log(context); | ||
| const user = context.user; |
There was a problem hiding this comment.
suggestion (code-quality): Prefer object destructuring when accessing and using properties. (use-object-destructuring)
| const user = context.user; | |
| const {user} = context; |
Explanation
Object destructuring can often remove an unnecessary temporary reference, as well as making your code more succinct.From the Airbnb Javascript Style Guide
PR Code Suggestions ✨Explore these optional code suggestions:
|
|||||||||||||||||
There was a problem hiding this comment.
Actionable comments posted: 11
♻️ Duplicate comments (2)
.github/copilot-instructions.md (1)
1-1: Fix typo in the title (“innstructions” → “instructions”)Same as the earlier bot comment; please correct the spelling.
-# AI Coding Agent innstructions – Universal Starter (Server) +# AI Coding Agent instructions – Universal Starter (Server)src/orpc/procedures/user/me.p.ts (1)
17-17: Prefer destructuring when reading context
Use object destructuring for brevity and clarity.Apply this diff:
- const user = context.user; + const { user } = context;
🧹 Nitpick comments (9)
src/orpc/middleware/db.middleware.ts (2)
4-18: Middleware looks solid; consider making db required for downstream contextLogic is correct and preserves existing context while injecting a Prisma client. To improve downstream type-safety, you can make db non-optional after this middleware by exporting a narrowed context type.
Example refinement:
export const dbProviderMiddleware = os - .$context<{ - db?: typeof prisma; - }>() + .$context<{ db?: typeof prisma }>() .middleware(async ({ context, next }) => { const db = context.db ?? prisma; return next({ context: { // preserve existing context while injecting db ...context, - db, + db, // now guaranteed for downstream }, }); });And optionally export a helper type downstream can use:
export type DBContext = { db: typeof prisma };
2-2: Path alias consistency with tsconfigYou import from "@/src/lib/db". If you switch tsconfig paths to map "@/" -> ["src/"], you can simplify imports to "@/lib/db" and avoid the redundant "src" segment.
Proposed change here:
-import { prisma } from "@/src/lib/db"; +import { prisma } from "@/lib/db";See related tsconfig suggestion in the tsconfig.json comment.
.github/copilot-instructions.md (2)
45-47: Prefer consistent casing for oRPCDocs and code mix “oRPC” and “ORPC.” Use one style consistently (e.g., “oRPC”) to match package naming (@orpc/*).
1-45: Add a note on secrets/PII in logs and handlersGiven auth/db guidance, include a short rule to avoid logging headers, tokens, or user PII. This aligns the docs with the new middlewares that process sessions.
Example addition under General Rules:
- Do not log raw headers, tokens, or user PII; guard debug logs behind an environment flag and scrub sensitive values.
src/orpc/middleware/auth.middleware.ts (1)
52-62: Optional: tighten requireRole ergonomicsAccept ReadonlyArray and short-circuit if no required roles passed to avoid accidental universal denial.
-export const requireRole = (roles: string[]) => +export const requireRole = (roles: ReadonlyArray<string>) => os.$context<AuthCtx>().middleware(async ({ context, next }) => { + if (!roles.length) return next({ context }); const rolesValue = (context.user as unknown as { roles?: unknown })?.roles; const userRoles: string[] = Array.isArray(rolesValue) ? (rolesValue as string[]) : []; if (!roles.some((r) => userRoles.includes(r))) { throw new ORPCError("forbidden".toUpperCase() as "FORBIDDEN", { message: "Forbidden" }); } return next({ context }); });tsconfig.json (1)
19-21: Optional: remove JSX/allowJs if not needed for a server-only project"jsx": "react-jsx" and "allowJs": true are unnecessary if you don’t compile React or JS files. Dropping them tightens config and avoids surprises.
src/orpc/routers.ts (1)
3-7: Export router type for reuse and safer typingsExpose the router type so downstream code (clients, tests, handlers) can reference it.
Add alongside the router:
export type AppRouter = typeof appRouter;src/orpc/middleware/index.ts (1)
5-8: Consider making headers optional for broader reuseIf you plan to reuse baseMiddleware outside HTTP contexts, allow headers to be optional. This reduces friction for non-request-driven calls.
Example:
.$context<{ headers?: Headers | Record<string, string> }>()src/orpc/procedures/user/me.p.ts (1)
10-12: Refine email validation in output schemaIf email is always a valid email, enforce it in the schema.
Apply this diff:
- email: z.string(), + email: z.string().email(),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (10)
.github/copilot-instructions.md(1 hunks)package.json(1 hunks)src/index.ts(2 hunks)src/orpc/index.ts(1 hunks)src/orpc/middleware/auth.middleware.ts(1 hunks)src/orpc/middleware/db.middleware.ts(1 hunks)src/orpc/middleware/index.ts(1 hunks)src/orpc/procedures/user/me.p.ts(1 hunks)src/orpc/routers.ts(1 hunks)tsconfig.json(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (7)
src/orpc/middleware/index.ts (2)
src/orpc/middleware/db.middleware.ts (1)
dbProviderMiddleware(4-18)src/orpc/middleware/auth.middleware.ts (1)
withBetterAuth(18-40)
src/orpc/middleware/db.middleware.ts (1)
src/lib/db.ts (1)
prisma(4-4)
src/orpc/routers.ts (1)
src/orpc/procedures/user/me.p.ts (1)
meProcedure(5-27)
src/index.ts (1)
src/orpc/index.ts (1)
orpcHandler(7-31)
src/orpc/procedures/user/me.p.ts (2)
src/orpc/middleware/index.ts (1)
baseMiddleware(5-8)src/orpc/middleware/auth.middleware.ts (1)
requireAuth(42-50)
src/orpc/index.ts (2)
src/orpc/routers.ts (1)
appRouter(3-7)src/lib/open-api.ts (2)
prefix(8-24)reference(9-24)
src/orpc/middleware/auth.middleware.ts (1)
src/lib/auth.ts (1)
auth(8-47)
🪛 LanguageTool
.github/copilot-instructions.md
[grammar] ~1-~1: Ensure spelling is correct
Context: # AI Coding Agent innstructions – Universal Starter (Server) ## 📌 Tech S...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🔇 Additional comments (5)
src/orpc/routers.ts (1)
3-7: Router wiring looks correctuser.me is properly exposed via meProcedure. No functional concerns.
src/index.ts (1)
59-75: Correct ORPC mounting and context propagationThe /orpc/* route delegates to orpcHandler with parse: "none" and forwards Headers. This is the right shape for ORPC.
src/orpc/middleware/index.ts (1)
5-8: Base middleware composition looks goodContext typing for headers and composition of dbProviderMiddleware then withBetterAuth is sound.
src/orpc/index.ts (2)
13-29: Ensure bearerAuth is actually required by operationsDefining the security scheme is great. Confirm that operations (e.g., GET /user/me) include a security requirement so OpenAPI consumers know auth is needed. If the plugin doesn’t set it globally, attach it per operation or set a global security block.
7-31: OpenAPI handler setup looks goodZod converter and reference plugin are wired correctly; naming/version OK for now.
| "@orpc/openapi": "^1.7.10", | ||
| "@orpc/server": "^1.7.10", | ||
| "@orpc/zod": "^1.7.10", |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add zod dependency to satisfy @orpc/zod peer requirement
@orpc/zod typically expects zod as a peer dependency. Without zod installed you'll get peer warnings or runtime import errors when using @orpc/zod validators.
Suggested addition:
"dependencies": {
"@elysiajs/swagger": "^1.3.1",
"@orpc/openapi": "^1.7.10",
"@orpc/server": "^1.7.10",
"@orpc/zod": "^1.7.10",
+ "zod": "^3.23.8",
"@plunk/node": "^3.0.3",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "@orpc/openapi": "^1.7.10", | |
| "@orpc/server": "^1.7.10", | |
| "@orpc/zod": "^1.7.10", | |
| "@orpc/openapi": "^1.7.10", | |
| "@orpc/server": "^1.7.10", | |
| "@orpc/zod": "^1.7.10", | |
| "zod": "^3.23.8", |
🤖 Prompt for AI Agents
In package.json around lines 13 to 15, @orpc/zod is listed but zod itself is
missing; add zod as a direct dependency (matching the major version expected by
@orpc/zod, e.g. a ^3.x release) to the dependencies block so the peer
requirement is satisfied and runtime/peer warnings are avoided.
| // Orpc | ||
| .all( | ||
| "/orpc/*", | ||
| async ({ request }: { request: Request }) => { | ||
| const { response } = await orpcHandler.handle(request, { | ||
| prefix: "/orpc", | ||
| context: { | ||
| headers: request.headers, | ||
| }, | ||
| }); | ||
|
|
||
| return response ?? new Response("Not Found", { status: 404 }); | ||
| }, | ||
| { | ||
| parse: "none", | ||
| }, | ||
| ) |
There was a problem hiding this comment.
CORS duplication/mismatch: Elysia CORS vs ORPC CORSPlugin
Global CORS is already applied via @elysiajs/cors, while orpcHandler also installs a CORSPlugin. This can set duplicate and potentially conflicting CORS headers. Additionally, @elysiajs/cors methods exclude HEAD/PATCH but ORPC allows them, risking failed preflight for PATCH.
Action:
- Prefer a single CORS source. Remove CORSPlugin from orpcHandler (recommended), or align both to use the same allowlist.
- Align Elysia CORS to include HEAD and PATCH.
I’ll propose the CORSPlugin removal in src/orpc/index.ts. For this file, adjust Elysia CORS config to include methods:
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"]🤖 Prompt for AI Agents
In src/index.ts around lines 59 to 75, global CORS applied via @elysiajs/cors
currently omits HEAD and PATCH while the orpcHandler installs its own CORSPlugin
causing duplicate/conflicting headers; remove the duplicate by keeping a single
CORS source and, for this file, update the Elysia CORS config to include the
missing methods so preflight covers ORPC: set methods to
["GET","POST","PUT","DELETE","OPTIONS","HEAD","PATCH"] and ensure no other
ORPC-specific CORSPlugin is applied elsewhere.
| type BAUser = typeof auth.$Infer.Session.user | null; | ||
| type BASession = typeof auth.$Infer.Session.session | null; | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Type extraction for BASession/BAUser is brittle
Using typeof on auth.$Infer.Session parts is fragile. Derive types from getSession to stay in sync with the auth API.
-type BAUser = typeof auth.$Infer.Session.user | null;
-type BASession = typeof auth.$Infer.Session.session | null;
+type SessionResponse = Awaited<ReturnType<typeof auth.api.getSession>>;
+type BAUser = SessionResponse["user"] | null;
+type BASession = SessionResponse["session"] | null;🤖 Prompt for AI Agents
In src/orpc/middleware/auth.middleware.ts around lines 4 to 6, the current type
extraction using typeof on auth.$Infer.Session is brittle; replace it by
deriving types from the actual getSession function so they stay in sync with the
auth API: import getSession, use Awaited<ReturnType<typeof getSession>> to
obtain the resolved session shape, then declare BASession as that resolved
type's session field (plus null if needed) and BAUser as the resolved type's
user field (plus null if needed); update imports accordingly and remove the
existing typeof-based type aliases.
| "paths": { | ||
| "@/*": ["./*"] | ||
| }, |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Paths mapping likely won’t work without baseUrl
TypeScript only applies "paths" when "baseUrl" is set. Add baseUrl and consider mapping to "src/*" so imports can be "@/lib/db" instead of "@/src/lib/db".
"paths": {
- "@/*": ["./*"]
+ "@/*": ["src/*"]
},Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In tsconfig.json around lines 12 to 14, add a "baseUrl" and change the paths
mapping to point at your source directory; for example set "baseUrl": "./" (or
"src" if you prefer) and update the mapping to "@/*": ["src/*"] so imports like
"@/lib/db" resolve correctly; after updating tsconfig restart the TS server/IDE
to pick up the change.
There was a problem hiding this comment.
I have prisma folder next to src folder
There was a problem hiding this comment.
Ask❓
I have prisma folder next to src folder
Answer:
If your Prisma folder sits alongside src (e.g., project-root/prisma and project-root/src), your current tsconfig paths mapping "@/": ["./"] will not let you import from prisma using "@/...". A few options:
Option A: Keep prisma outside src and add an alias for it
- In tsconfig.json:
- Ensure baseUrl is set (required for paths to work).
- Add a separate path alias for prisma.
Example:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/": ["src/"],
"@prisma/": ["prisma/"]
}
}
}
- Then you can import:
import { PrismaClient } from "@prisma/client";
import schema from "@prisma/schema.prisma"; // if you actually need schema path access
Option B: Move prisma under src
- If you prefer a single alias root, move prisma into src (e.g., src/prisma) and keep:
"paths": { "@/": ["src/"] } - Pros: simpler aliasing; Cons: Prisma CLI defaults assume prisma at project root.
Option C: Keep prisma at root and reference it with relative paths where needed
- Use relative imports for rare cases where you need files from prisma dir (usually not needed at runtime).
- Runtime code generally doesn’t import from prisma folder; it imports @prisma/client which is generated into node_modules/.prisma.
Important notes:
- Prisma CLI looks for prisma/schema.prisma by default at project root. If you move it, update your Prisma commands with --schema path/to/schema.prisma in package.json scripts.
- For Better Auth and ORPC code, you shouldn’t need to import from the prisma folder itself—only your Prisma client instance (e.g., from src/lib/db). Ensure src/lib/db.ts imports PrismaClient from @prisma/client, not from prisma/.
- After changing tsconfig, restart your TypeScript server/IDE for the path mappings to take effect.
Minimal change recommendation:
- Keep prisma at the project root.
- Add baseUrl and a prisma alias:
"baseUrl": ".",
"paths": {
"@/": ["src/"],
"@prisma/": ["prisma/"]
} - Continue importing your Prisma client from src/lib/db to keep a clean boundary.
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check the project structure to understand the layout
echo "=== Project Structure ==="
fd -t d -d 2 . | head -20
echo -e "\n=== Looking for prisma folder ==="
fd -t d "^prisma$" -d 1
echo -e "\n=== Looking for src folder ==="
fd -t d "^src$" -d 1
echo -e "\n=== Files in root directory ==="
ls -la | grep -E "^d|^-" | head -15
Length of output: 1361
@chakrihacker, thanks for clarifying! With your prisma/ folder at the root alongside src/, your current path mapping "@/*": ["./*"] is actually appropriate. However, you still need to add baseUrl for TypeScript to recognize the paths configuration:
"baseUrl": "./",
"paths": {
"@/*": ["./*"]
},Without baseUrl, TypeScript ignores the paths mapping entirely. With this setup, you can import like:
@/src/lib/dbfor source files@/prisma/schemafor Prisma-related files
This gives you clean imports across both directories. After adding baseUrl, restart your TypeScript server/IDE to pick up the changes.
There was a problem hiding this comment.
Skipped: comment is from another GitHub bot.
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (2)
.github/copilot-instructions.md (1)
1-1: Fix title typo and standardize casing (“ORPC”).
- “innstructions” → “instructions”
- Use consistent “ORPC” casing to match the rest of the codebase.
Apply:
-# AI Coding Agent innstructions – Universal Starter (Server) +# AI Coding Agent instructions – Universal Starter (Server)And for consistency:
-- **RPC Layer**: [oRPC](https://orpc.dev/) – lightweight, type-safe RPC between server and client +- **RPC Layer**: [ORPC](https://orpc.dev/) – lightweight, type-safe RPC between server and clientAlso applies to: 6-6
src/orpc/procedures/user/me.p.ts (1)
17-17: Prefer destructuring for brevity and clarity- const user = context.user; + const { user } = context;
🧹 Nitpick comments (4)
src/orpc/middleware/db.middleware.ts (1)
5-7: Consider refining db to be non-optional for downstream handlers.Right now the context type declares db as optional, but this middleware guarantees it will exist. If ORPC allows context type refinement, return a context where db is non-optional so downstream code can rely on it without extra narrowing.
If the framework supports it, adjust the generic or exported types to ensure db is required after this middleware. Otherwise, keep as-is but be consistent in downstream null-checks.
Also applies to: 11-18
src/orpc/routers.ts (1)
3-7: Mark router as const to preserve literal types.This helps downstream type inference if you introspect routes.
-export const appRouter = { +export const appRouter = { user: { me: meProcedure, }, -}; +} as const;src/orpc/middleware/index.ts (1)
1-8: Reuse InputCtx for consistency across middlewares.Avoid re-declaring the headers context shape; import and use InputCtx so changes propagate in one place.
-import { os } from "@orpc/server"; -import { withBetterAuth } from "./auth.middleware"; +import { os } from "@orpc/server"; +import { withBetterAuth, type InputCtx } from "./auth.middleware"; import { dbProviderMiddleware } from "./db.middleware"; export const baseMiddleware = os - .$context<{ headers: Headers | Record<string, string> }>() + .$context<InputCtx>() .use(dbProviderMiddleware) .use(withBetterAuth);src/orpc/procedures/user/me.p.ts (1)
9-14: Strengthen output schema (email format + strict object)
- Validate email format.
- Make the output object strict to prevent accidental extra fields.
- .output( - z.object({ - id: z.string(), - email: z.string(), - name: z.string().nullable(), - }), - ) + .output( + z + .object({ + id: z.string(), + email: z.string().email(), + name: z.string().nullable(), + }) + .strict(), + )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (10)
.github/copilot-instructions.md(1 hunks)package.json(1 hunks)src/index.ts(2 hunks)src/orpc/index.ts(1 hunks)src/orpc/middleware/auth.middleware.ts(1 hunks)src/orpc/middleware/db.middleware.ts(1 hunks)src/orpc/middleware/index.ts(1 hunks)src/orpc/procedures/user/me.p.ts(1 hunks)src/orpc/routers.ts(1 hunks)tsconfig.json(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (7)
src/orpc/index.ts (2)
src/orpc/routers.ts (1)
appRouter(3-7)src/lib/open-api.ts (2)
prefix(8-24)reference(9-24)
src/orpc/middleware/index.ts (2)
src/orpc/middleware/db.middleware.ts (1)
dbProviderMiddleware(4-18)src/orpc/middleware/auth.middleware.ts (1)
withBetterAuth(18-40)
src/orpc/procedures/user/me.p.ts (2)
src/orpc/middleware/index.ts (1)
baseMiddleware(5-8)src/orpc/middleware/auth.middleware.ts (1)
requireAuth(42-50)
src/orpc/middleware/db.middleware.ts (1)
src/lib/db.ts (1)
prisma(4-4)
src/index.ts (1)
src/orpc/index.ts (1)
orpcHandler(7-31)
src/orpc/routers.ts (1)
src/orpc/procedures/user/me.p.ts (1)
meProcedure(5-27)
src/orpc/middleware/auth.middleware.ts (1)
src/lib/auth.ts (1)
auth(8-47)
🪛 LanguageTool
.github/copilot-instructions.md
[grammar] ~1-~1: Ensure spelling is correct
Context: # AI Coding Agent innstructions – Universal Starter (Server) ## 📌 Tech S...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🔇 Additional comments (6)
package.json (1)
13-15: ORPC deps look good and version-aligned.The added @orpc/* dependencies are consistent (^1.7.10) and match their usage in the new ORPC integration.
src/index.ts (1)
59-75: ORPC route integration verified
- Headers are correctly forwarded with
context.headersand the/orpcprefix is applied.parse: "none"prevents double-parsing, which is intentional.- A 404 fallback (
response ?? new Response("Not Found", { status: 404 })) is in place.- CORS preflight (OPTIONS) is covered by the included
CORSPlugininorpcHandler.All checks pass; no changes needed.
src/orpc/procedures/user/me.p.ts (1)
5-8: LGTM: Authenticated “me” procedure wiring and return shape
- Correctly composes base middleware with requireAuth.
- Clear route and minimal, accurate response mapping.
Also applies to: 22-27
src/orpc/index.ts (3)
7-14: LGTM: OpenAPI handler and plugin wiring
- Clean setup with CORS and Zod-to-JSON schema conversion.
- Uses appRouter as the single source of truth.
Also applies to: 30-31
15-28: Add default OpenAPI security requirementYou’ve defined the
bearerAuthscheme but haven’t applied it at the root level, so operations won’t automatically require authentication. Update yourspecGenerateOptionsto include:specGenerateOptions: { info: { title: "ORPC Playground", version: "1.0.0", }, components: { securitySchemes: { bearerAuth: { type: "http", scheme: "bearer", }, }, }, + security: [{ bearerAuth: [] }], },• After adding this, verify that
OpenAPIReferencePluginactually honors the top-levelsecuritysetting.
• If it does not, you’ll need to applysecurityon each protected operation instead.
10-12: Harden CORS configuration in src/orpc/index.tsRestrict origins to a whitelist and explicitly allow auth headers.
--- a/src/orpc/index.ts +++ b/src/orpc/index.ts @@ -9,7 +9,13 @@ export const orpcHandler = new OpenAPIHandler(appRouter, { new CORSPlugin({ - origin: (origin, options) => origin, + origin: (origin) => { + // Allow non-browser or server-to-server requests + if (!origin) return true; + // Only permit origins listed in the env var + const whitelist = process.env.CORS_ORIGINS?.split(",").map(o => o.trim()); + return whitelist?.includes(origin) ? origin : false; + }, allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"], + allowHeaders: ["Authorization", "Content-Type"], }),• File: src/orpc/index.ts
• Section: CORSPlugin optionsNext steps:
• Confirm in the @orpc/server/plugins documentation whether the option key isallowHeadersorallowedHeaders, and adjust accordingly.
| type BAUser = typeof auth.$Infer.Session.user | null; | ||
| type BASession = typeof auth.$Infer.Session.session | null; | ||
|
|
There was a problem hiding this comment.
Remove sensitive logging and harden session typing and retrieval.
- Avoid logging headers or full context; they can include Authorization tokens, cookies, and PII.
- Infer types from getSession robustly via Awaited<ReturnType<...>>.
- Make getSession resilient; treat failures as unauthenticated instead of throwing.
Suggested changes:
- type BAUser = typeof auth.$Infer.Session.user | null;
- type BASession = typeof auth.$Infer.Session.session | null;
+ type GetSessionResult = Awaited<ReturnType<typeof auth.api.getSession>>;
+ type BAUser = GetSessionResult["user"] | null;
+ type BASession = GetSessionResult["session"] | null;- console.log("withBetterAuth context headers", headers);
-
- // Server-side Better Auth API (no client in middlewares)
- const sessionData = await auth.api.getSession({ headers }); // server API call
- console.log("withBetterAuth sessionData", sessionData);
+ // Server-side Better Auth API (no client in middlewares)
+ const sessionData = await auth.api
+ .getSession({ headers })
+ .catch(() => null); // fail closed without leaking- console.log({ context });Also applies to: 26-31, 45-45
There was a problem hiding this comment.
Actionable comments posted: 11
🧹 Nitpick comments (6)
.github/copilot-instructions.md (2)
1-1: Fix typo in title"innstructions" → "instructions".
-# AI Coding Agent innstructions – Universal Starter (Server) +# AI Coding Agent instructions – Universal Starter (Server)
6-6: Standardize naming: use "ORPC" consistentlyThe project and packages use the "ORPC" name (@orpc/*). Standardize "oRPC" → "ORPC" in the doc.
-- **RPC Layer**: [oRPC](https://orpc.dev/) – lightweight, type-safe RPC between server and client +- **RPC Layer**: [ORPC](https://orpc.dev/) – lightweight, type-safe RPC between server and client @@ -## 4. oRPC Guidelines +## 4. ORPC GuidelinesAlso applies to: 45-47
tsconfig.json (1)
20-21: allowJs contradicts “Always use TypeScript” guidelineIf JS files aren’t intended, set allowJs to false to enforce TS-only code.
- "allowJs": true, + "allowJs": false,Also applies to: 67-70
src/orpc/middleware/auth.middleware.ts (1)
2-2: Optional: simplify import path once alias maps to srcIf you adopt the suggested tsconfig alias change ("@/" → "./src/"), this can be simplified.
-import { auth } from "@/src/lib/auth"; +import { auth } from "@/lib/auth";src/orpc/routers.ts (1)
3-7: LGTM; optionally freeze router shape for stronger typesImplementation is correct. Optionally add as const for literal keys/types, and export a Router type for consumers.
-export const appRouter = { +export const appRouter = { user: { me: meProcedure, }, -}; +} as const; + +export type AppRouter = typeof appRouter;src/orpc/procedures/user/me.p.ts (1)
9-13: Tighten the output schema for stronger validation.
- Consider z.string().email() for email.
- If ids are UUIDs, z.string().uuid() helps catch mistakes.
- z.object({ - id: z.string(), - email: z.string(), - name: z.string().nullable(), - }), + z.object({ + id: z.string(), // or z.string().uuid() if applicable + email: z.string().email(), + name: z.string().nullable(), + }),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (10)
.github/copilot-instructions.md(1 hunks)package.json(1 hunks)src/index.ts(2 hunks)src/orpc/index.ts(1 hunks)src/orpc/middleware/auth.middleware.ts(1 hunks)src/orpc/middleware/db.middleware.ts(1 hunks)src/orpc/middleware/index.ts(1 hunks)src/orpc/procedures/user/me.p.ts(1 hunks)src/orpc/routers.ts(1 hunks)tsconfig.json(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (7)
src/orpc/routers.ts (1)
src/orpc/procedures/user/me.p.ts (1)
meProcedure(5-27)
src/orpc/middleware/auth.middleware.ts (1)
src/lib/auth.ts (1)
auth(8-47)
src/index.ts (1)
src/orpc/index.ts (1)
orpcHandler(7-31)
src/orpc/middleware/index.ts (2)
src/orpc/middleware/db.middleware.ts (1)
dbProviderMiddleware(4-18)src/orpc/middleware/auth.middleware.ts (1)
withBetterAuth(18-40)
src/orpc/procedures/user/me.p.ts (2)
src/orpc/middleware/index.ts (1)
baseMiddleware(5-8)src/orpc/middleware/auth.middleware.ts (1)
requireAuth(42-50)
src/orpc/middleware/db.middleware.ts (1)
src/lib/db.ts (1)
prisma(4-4)
src/orpc/index.ts (2)
src/orpc/routers.ts (1)
appRouter(3-7)src/lib/open-api.ts (1)
prefix(8-24)
🪛 LanguageTool
.github/copilot-instructions.md
[grammar] ~1-~1: Ensure spelling is correct
Context: # AI Coding Agent innstructions – Universal Starter (Server) ## 📌 Tech S...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🔇 Additional comments (5)
.github/copilot-instructions.md (1)
12-15: Ignore path-alias adjustment
The repository’s tsconfig currently maps"@/*"→"./*", and all code imports (e.g.import { prisma } from "@/src/lib/db") match this setup. The examples in.github/copilot-instructions.mdare already aligned—no change to the/src/prefix is needed.Likely an incorrect or invalid review comment.
src/index.ts (2)
63-68: Remove friction: context pass-through looks correct.Passing raw request headers into the ORPC context matches baseMiddleware’s expectation (Headers | Record<string,string>) and enables server-side session resolution. LGTM.
73-74: Elysia route parse option is correctElysia supports skipping body parsing with
parse: 'none';parse: falseisn’t a valid option.• File: src/index.ts (lines 73–74)
• No changes required.src/orpc/index.ts (1)
13-31: OpenAPI plugin configuration looks solid.Zod schema conversion and securitySchemes wiring are consistent. LGTM.
src/orpc/middleware/index.ts (1)
5-8: Good baseline middleware composition.
- headers shape matches withBetterAuth’s expectations.
- dbProviderMiddleware runs first, then auth. Order is sensible. LGTM.
| "@orpc/openapi": "^1.7.10", | ||
| "@orpc/server": "^1.7.10", | ||
| "@orpc/zod": "^1.7.10", |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Add missing peer dependency "zod" and keep ORPC packages aligned
@orpc/zod typically peers with zod. I don't see "zod" in dependencies; without it, runtime/type generation can break. Also, keeping all @orpc/* packages on the same version is wise to avoid subtle mismatches.
Proposed additions:
"dependencies": {
"@elysiajs/swagger": "^1.3.1",
"@orpc/openapi": "^1.7.10",
"@orpc/server": "^1.7.10",
"@orpc/zod": "^1.7.10",
+ "zod": "^3.23.8",
"@plunk/node": "^3.0.3",Run this to verify usage and presence:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Check if zod is declared in package.json:"
rg -n '"zod"\s*:' package.json || echo "MISSING: zod not declared in package.json"
echo
echo "Scan for zod usage in source:"
rg -n 'from\s+[\'"]zod[\'"]|import\s+\*\s+as\s+z\s+from\s+[\'"]zod[\'"]|@orpc/zod|ZodToJsonSchemaConverter' -S src || echo "No explicit zod-related imports found in src/"Length of output: 432
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Verifying 'zod' in package.json dependencies:"
rg -n '"zod"\s*:' package.json || echo "MISSING: zod not declared in package.json"
echo
echo "Scanning source for @orpc/zod imports:"
if ! rg -n "@orpc/zod" -S src; then
echo "No @orpc/zod imports found"
fi
echo
echo "Scanning source for direct zod imports:"
if ! rg -n "import .*from ['\"]zod['\"]" -S src && ! rg -n "require(['\"]zod['\"])" -S src; then
echo "No direct ES Module or CommonJS imports of zod found"
fiLength of output: 652
Add missing “zod” dependency
We’re importing ZodToJsonSchemaConverter from @orpc/zod (src/orpc/index.ts) and z from "zod" (src/orpc/procedures/user/me.p.ts), but zod isn’t declared in package.json. To satisfy the peer dependency and prevent runtime/type-generation breaks, add it alongside the aligned ORPC packages (all at ^1.7.10).
• File: package.json
• Section: dependencies
"dependencies": {
"@elysiajs/swagger": "^1.3.1",
"@orpc/openapi": "^1.7.10",
"@orpc/server": "^1.7.10",
"@orpc/zod": "^1.7.10",
+ "zod": "^3.23.8",
"@plunk/node": "^3.0.3",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "@orpc/openapi": "^1.7.10", | |
| "@orpc/server": "^1.7.10", | |
| "@orpc/zod": "^1.7.10", | |
| "dependencies": { | |
| "@elysiajs/swagger": "^1.3.1", | |
| "@orpc/openapi": "^1.7.10", | |
| "@orpc/server": "^1.7.10", | |
| "@orpc/zod": "^1.7.10", | |
| "zod": "^3.23.8", | |
| "@plunk/node": "^3.0.3", | |
| // ...other dependencies... | |
| } |
🤖 Prompt for AI Agents
In package.json around lines 13 to 15, add the missing "zod" dependency to the
dependencies section to satisfy the peer import and align versions; add an entry
"zod": "^1.7.10" alongside "@orpc/openapi", "@orpc/server", and "@orpc/zod" so
the package declares zod at the same ^1.7.10 version.
| // Orpc | ||
| .all( | ||
| "/orpc/*", | ||
| async ({ request }: { request: Request }) => { | ||
| const { response } = await orpcHandler.handle(request, { | ||
| prefix: "/orpc", | ||
| context: { | ||
| headers: request.headers, | ||
| }, | ||
| }); | ||
|
|
||
| return response ?? new Response("Not Found", { status: 404 }); | ||
| }, | ||
| { | ||
| parse: "none", | ||
| }, | ||
| ) |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid double CORS; centralize policy and ensure OPTIONS is handled.
- The app already applies @elysiajs/cors globally. The ORPC handler also enables CORS via CORSPlugin (see src/orpc/index.ts). Two CORS layers can emit conflicting headers (e.g., Access-Control-Allow-Origin), especially since ORPC currently echoes any origin, while the app uses isOriginAllowed.
- Recommendation: choose a single source of truth for CORS.
- Option A (simplest): Remove CORSPlugin from ORPC and rely on app-level CORS.
- Option B: Reuse the same origin check in ORPC (see suggested diff in src/orpc/index.ts comment) and consider scoping app-level CORS to non-/orpc routes if needed.
Also ensure OPTIONS is allowed for preflight on ORPC (missing in allowMethods in src/orpc/index.ts). See diff there.
| new CORSPlugin({ | ||
| origin: (origin, options) => origin, | ||
| allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"], | ||
| }), |
There was a problem hiding this comment.
Include OPTIONS in allowed methods to unblock CORS preflight.
CORS preflight requests use OPTIONS. Not including it can break cross-origin calls to ORPC endpoints.
- allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"],
+ allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"],📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| new CORSPlugin({ | |
| origin: (origin, options) => origin, | |
| allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"], | |
| }), | |
| new CORSPlugin({ | |
| origin: (origin, options) => origin, | |
| allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"], | |
| }), |
🤖 Prompt for AI Agents
In src/orpc/index.ts around lines 9 to 12, the CORS allowMethods list is missing
the HTTP OPTIONS verb required for CORS preflight; update the CORSPlugin
configuration to include "OPTIONS" in the allowMethods array (e.g., add
"OPTIONS" to the existing list) so preflight requests are permitted.
| console.log("withBetterAuth context headers", headers); | ||
|
|
||
| // Server-side Better Auth API (no client in middlewares) | ||
| const sessionData = await auth.api.getSession({ headers }); // server API call | ||
| console.log("withBetterAuth sessionData", sessionData); | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid logging sensitive headers and harden getSession
Console-logging headers can leak Authorization/cookies. Also wrap getSession in try/catch to prevent auth outages from failing all requests.
- console.log("withBetterAuth context headers", headers);
-
- // Server-side Better Auth API (no client in middlewares)
- const sessionData = await auth.api.getSession({ headers }); // server API call
- console.log("withBetterAuth sessionData", sessionData);
+ // Server-side Better Auth API (no client in middlewares)
+ let sessionData: Awaited<ReturnType<typeof auth.api.getSession>> | null = null;
+ try {
+ sessionData = await auth.api.getSession({ headers }); // server API call
+ } catch (e) {
+ // Optionally log at debug level without sensitive data
+ // console.debug("getSession failed");
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| console.log("withBetterAuth context headers", headers); | |
| // Server-side Better Auth API (no client in middlewares) | |
| const sessionData = await auth.api.getSession({ headers }); // server API call | |
| console.log("withBetterAuth sessionData", sessionData); | |
| // Server-side Better Auth API (no client in middlewares) | |
| let sessionData: Awaited<ReturnType<typeof auth.api.getSession>> | null = null; | |
| try { | |
| sessionData = await auth.api.getSession({ headers }); // server API call | |
| } catch (e) { | |
| // Optionally log at debug level without sensitive data | |
| // console.debug("getSession failed"); | |
| } |
🤖 Prompt for AI Agents
In src/orpc/middleware/auth.middleware.ts around lines 26 to 31, remove the
console.log that prints raw headers to avoid leaking Authorization/cookies;
instead either remove the log or log a redacted/safe indicator (no header
values). Wrap the call to auth.api.getSession({ headers }) in a try/catch so any
thrown error is caught, log only non-sensitive error information, set
sessionData to null or an empty session on failure, and allow request processing
to continue rather than letting auth errors fail all requests.
| const rolesValue = (context.user as unknown as { roles?: unknown })?.roles; | ||
| const userRoles: string[] = Array.isArray(rolesValue) | ||
| ? (rolesValue as string[]) | ||
| : []; | ||
| if (!roles.some((r) => userRoles.includes(r))) { | ||
| throw new ORPCError("FORBIDDEN", { message: "Forbidden" }); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Stricter role extraction and validation
Avoid double type assertions; ensure roles is an array of strings before using includes.
- const rolesValue = (context.user as unknown as { roles?: unknown })?.roles;
- const userRoles: string[] = Array.isArray(rolesValue)
- ? (rolesValue as string[])
- : [];
+ const rolesValue = context.user && (context.user as any).roles;
+ const userRoles: string[] =
+ Array.isArray(rolesValue) && rolesValue.every((r) => typeof r === "string")
+ ? (rolesValue as string[])
+ : [];🤖 Prompt for AI Agents
In src/orpc/middleware/auth.middleware.ts around lines 54 to 60, the code uses a
double type assertion and assumes roles is already an array of strings; change
it to safely extract and validate roles: read context.user.roles with a single
type-safe check, verify Array.isArray(rolesValue) and that every element is a
string (filter or map to strings only), then assign userRoles to that validated
array (or empty array if invalid), and keep the existing permission check; this
removes the unsafe cast and ensures includes() operates on a true string[].
| .$context<{ | ||
| db?: typeof prisma; | ||
| }>() | ||
| .middleware(async ({ context, next }) => { | ||
| const db = context.db ?? prisma; | ||
|
|
||
| return next({ | ||
| context: { | ||
| // preserve existing context while injecting db | ||
| ...context, | ||
| db, | ||
| }, | ||
| }); | ||
| }); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Make db required post-middleware and align types for stronger safety.
- Today db is declared optional in the input context, but you always inject a value. Keeping it optional forces downstream code to treat it as possibly undefined.
- Prefer: empty input context and inject a required db, or keep optional on input but ensure the output context has db as required.
Option 1 (recommended): make db required after this middleware
-export const dbProviderMiddleware = os
- .$context<{
- db?: typeof prisma;
- }>()
- .middleware(async ({ context, next }) => {
- const db = context.db ?? prisma;
- return next({
- context: {
- // preserve existing context while injecting db
- ...context,
- db,
- },
- });
- });
+export const dbProviderMiddleware = os
+ .$context<{}>()
+ .middleware(async ({ context, next }) => {
+ // If you still want to honor an upstream-injected db (eg tests), read it
+ const maybeDb = (context as { db?: typeof prisma }).db;
+ const db = maybeDb ?? prisma;
+ return next({
+ context: {
+ ...context,
+ db, // now guaranteed present for downstream handlers
+ },
+ });
+ });Option 2: keep current shape but export a shared type alias to avoid value-coupled types
- In src/lib/db.ts add:
export type DbClient = typeof prisma - Then here use import type { DbClient } from "@/src/lib/db" and declare db?: DbClient.
Either option improves type clarity; Option 1 also improves ergonomics in downstream code.
🤖 Prompt for AI Agents
In src/orpc/middleware/db.middleware.ts around lines 5 to 18, the middleware
currently types the incoming context as having an optional db but always injects
a prisma instance, which forces downstream code to treat db as possibly
undefined; change the types so the middleware produces a context with a required
db: either (recommended) update the middleware generic to accept an empty input
context and return context with db: typeof prisma (make db required for
downstream handlers), or (alternate) add a shared DbClient type in src/lib/db.ts
(export type DbClient = typeof prisma), import it here and change the
middleware/output context to have db: DbClient (non-optional); ensure the
middleware signature and returned context type reflect db as required so
downstream code no longer needs null checks.
| export const baseMiddleware = os | ||
| .$context<{ headers: Headers | Record<string, string> }>() | ||
| .use(dbProviderMiddleware) | ||
| .use(withBetterAuth); |
There was a problem hiding this comment.
Remove PII-heavy logging in withBetterAuth.
The composed withBetterAuth (see src/orpc/middleware/auth.middleware.ts) logs headers and session data. This can leak PII and secrets to logs.
To fix in src/orpc/middleware/auth.middleware.ts, remove console logs:
- console.log("withBetterAuth context headers", headers);
...
- console.log("withBetterAuth sessionData", sessionData);Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/orpc/middleware/auth.middleware.ts (where withBetterAuth is implemented,
the spots that log headers and session data), remove any
console.log/console.debug/console.info calls that print request headers, session
objects, tokens or other PII/secrets; instead either remove the logs entirely or
replace them with a non-PII message (e.g., "auth middleware invoked") or a log
that only records a correlation id or masked fields. Ensure no other Logger
calls in that file emit full header or session contents and, if needed, mask
sensitive fields before logging.
| "paths": { | ||
| "@/*": ["./*"] | ||
| }, |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Map @ alias to src for cleaner imports
Doc encourages absolute imports from src. Remap "@/" to "./src/" so imports are "@/lib/..." instead of "@/src/lib/...".
- "paths": {
- "@/*": ["./*"]
- },
+ "paths": {
+ "@/*": ["./src/*"]
+ },Quick scan to estimate impact:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Imports that will need rewriting if alias maps to ./src/*:"
rg -n "from\s+['\"]@/src/" src || echo "No imports using @/src/ found."Length of output: 450
Remap @ alias to src and update import paths
To streamline imports, update your tsconfig.json and remove redundant src/ segments from existing imports:
- tsconfig.json (Lines 12–14)
"paths": {
- "@/*": ["./*"]
+ "@/*": ["./src/*"]
},-
Imports to update
After this change, any import of the form@/src/...must become@/.... Specifically:•
src/index.ts(line 4)- import { auth } from "@/src/lib/auth"; + import { auth } from "@/lib/auth";
•
src/orpc/middleware/db.middleware.ts(line 2)- import { prisma } from "@/src/lib/db"; + import { prisma } from "@/lib/db";
•
src/orpc/middleware/auth.middleware.ts(line 2)- import { auth } from "@/src/lib/auth"; + import { auth } from "@/lib/auth";
•
src/lib/auth.ts(line 5)- import { prisma } from "@/src/lib/db"; + import { prisma } from "@/lib/db";
These updates ensure @/… always points into your src directory without a double-src path.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In tsconfig.json around lines 12–14, change the path mapping from "@/*": ["./*"]
to "@/*": ["src/*"] so the "@" alias points into the src directory; then update
imports that currently use "@/src/..." to "@/..." in the listed files:
src/index.ts (line 4), src/orpc/middleware/db.middleware.ts (line 2),
src/orpc/middleware/auth.middleware.ts (line 2), and src/lib/auth.ts (line 5) —
replace each occurrence of "@/src/" with "@/".
…gs; add zod dependency
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (5)
tsconfig.json (1)
12-15: Consolidate path aliases to avoid ambiguityHaving both "@/" → "./" and "@src/" → "./src/" is redundant and encourages "@/src/..." patterns. Prefer mapping "@" directly to src and drop "@src" to simplify imports.
- "paths": { - "@/*": ["./*"], - "@src/*": ["./src/*"] - }, + "paths": { + "@/*": ["./src/*"] + },Follow-up: update imports like "@/src/lib/..." to "@/lib/...".
src/orpc/middleware/auth.middleware.ts (4)
4-6: Make session/user types resilient to auth API changesDeriving types from auth.$Infer.Session is brittle. Infer from the actual getSession return for better stability.
-type BAUser = typeof auth.$Infer.Session.user | null; -type BASession = typeof auth.$Infer.Session.session | null; +type GetSessionResult = Awaited<ReturnType<typeof auth.api.getSession>>; +type BAUser = GetSessionResult["user"] | null; +type BASession = GetSessionResult["session"] | null;
39-46: Narrow context after auth check for better DX downstreamAfter asserting presence, pass a narrowed non-null user/session so downstream handlers don’t need redundant checks.
- if (!context.session || !context.user) { + if (!context.session || !context.user) { throw new ORPCError("UNAUTHORIZED", { message: "Unauthenticated" }); - } - return next({ context }); + } + return next({ + context: { + ...context, + user: context.user!, + session: context.session!, + }, + });
21-28: Harden getSession call to avoid taking down requests on auth outagesIf auth.api.getSession throws (network/outage), the whole request fails. Catch and treat as anonymous.
- // Server-side Better Auth API (no client in middlewares) - const sessionData = await auth.api.getSession({ headers }); // server API call + // Server-side Better Auth API (no client in middlewares) + let sessionData: Awaited<ReturnType<typeof auth.api.getSession>> | null = null; + try { + sessionData = await auth.api.getSession({ headers }); // server API call + } catch { + sessionData = null; // treat as unauthenticated on failure + }
48-56: Safer role extraction to avoid invalid data shapesAvoid double-casting and ensure roles is a string[] before using includes.
- const rolesValue = (context.user as unknown as { roles?: unknown })?.roles; - const userRoles: string[] = Array.isArray(rolesValue) - ? (rolesValue as string[]) - : []; + const rolesValue = context.user && (context.user as any).roles; + const userRoles: string[] = + Array.isArray(rolesValue) && rolesValue.every((r) => typeof r === "string") + ? (rolesValue as string[]) + : [];
🧹 Nitpick comments (2)
src/orpc/procedures/user/me.p.ts (2)
10-14: Strengthen contract: validate email shapeOutput uses z.string() for email; consider z.string().email() to assert a valid email in the API contract.
- email: z.string(), + email: z.string().email(),
16-21: Eliminate unreachable null-check by narrowing context in middlewareWith requireAuth in the chain, user should be guaranteed non-null. Instead of checking again here, narrow types in requireAuth so downstream handlers see user/session as defined.
If you accept: update requireAuth to return next with non-null user/session; then you can drop the extra check here.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (9)
.github/copilot-instructions.md(1 hunks)package.json(1 hunks)src/lib/auth.ts(0 hunks)src/lib/email/email-service.ts(0 hunks)src/lib/email/providers/resend.ts(0 hunks)src/orpc/index.ts(1 hunks)src/orpc/middleware/auth.middleware.ts(1 hunks)src/orpc/procedures/user/me.p.ts(1 hunks)tsconfig.json(1 hunks)
💤 Files with no reviewable changes (3)
- src/lib/auth.ts
- src/lib/email/email-service.ts
- src/lib/email/providers/resend.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- package.json
- src/orpc/index.ts
- .github/copilot-instructions.md
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/orpc/procedures/user/me.p.ts (2)
src/orpc/middleware/index.ts (1)
baseMiddleware(5-8)src/orpc/middleware/auth.middleware.ts (1)
requireAuth(39-46)
src/orpc/middleware/auth.middleware.ts (1)
src/lib/auth.ts (1)
auth(8-46)
🔇 Additional comments (2)
tsconfig.json (1)
52-57: Bundler-mode settings look consistentmoduleResolution: "bundler", verbatimModuleSyntax, and baseUrl are aligned with a no-emit bundler setup.
src/orpc/procedures/user/me.p.ts (1)
6-27: LGTM: protected me endpoint is correctly wiredAuth middleware precedes the handler, shape is explicit, and error path uses ORPCError consistently.
User description
…rver
PR Type
Enhancement
Description
Integrate ORPC with Better Auth and Prisma
Add authentication and database middleware for ORPC
Create user procedures with 'me' endpoint
Add AI coding agent documentation
Diagram Walkthrough
File Walkthrough
7 files
Add ORPC handler route to Elysia serverCreate ORPC handler with CORS and OpenAPI pluginsImplement Better Auth middleware for ORPCCreate database provider middleware for PrismaExport base middleware combining auth and databaseCreate user 'me' procedure with authenticationDefine app router structure for ORPC procedures1 files
Add AI coding agent instructions for tech stack1 files
Add ORPC dependencies for server and OpenAPI1 files
Update TypeScript config for modern featuresSummary by CodeRabbit