Skip to content

feat(docs): add AI Coding Agent instructions for universal starter se…#3

Open
chakrihacker wants to merge 3 commits into
mainfrom
feat/add-orpc
Open

feat(docs): add AI Coding Agent instructions for universal starter se…#3
chakrihacker wants to merge 3 commits into
mainfrom
feat/add-orpc

Conversation

@chakrihacker
Copy link
Copy Markdown
Contributor

@chakrihacker chakrihacker commented Aug 11, 2025

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

flowchart LR
  A["Elysia Server"] --> B["ORPC Handler"]
  B --> C["Auth Middleware"]
  B --> D["DB Middleware"]
  C --> E["User Procedures"]
  D --> E
  E --> F["Me Endpoint"]
Loading

File Walkthrough

Relevant files
Enhancement
7 files
index.ts
Add ORPC handler route to Elysia server                                   
+18/-0   
index.ts
Create ORPC handler with CORS and OpenAPI plugins               
+31/-0   
auth.middleware.ts
Implement Better Auth middleware for ORPC                               
+62/-0   
db.middleware.ts
Create database provider middleware for Prisma                     
+18/-0   
index.ts
Export base middleware combining auth and database             
+8/-0     
me.p.ts
Create user 'me' procedure with authentication                     
+27/-0   
routers.ts
Define app router structure for ORPC procedures                   
+7/-0     
Documentation
1 files
copilot-instructions.md
Add AI coding agent instructions for tech stack                   
+47/-0   
Dependencies
1 files
package.json
Add ORPC dependencies for server and OpenAPI                         
+3/-0     
Configuration changes
1 files
tsconfig.json
Update TypeScript config for modern features                         
+119/-98

Summary by CodeRabbit

  • New Features
    • Added a new RPC API surface with generated OpenAPI documentation and a catch-all route to serve it.
    • Added a bearer-auth–protected “Me” endpoint to return the signed-in user’s id, email, and name.
  • Documentation
    • Added contributor guidelines covering server stack, routing, database access, and RPC patterns.
  • Chores
    • Added runtime dependencies for RPC/OpenAPI and schema validation; modernized TypeScript config.
  • Bug Fixes
    • Removed dev-console logs from email/auth code paths.

- 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.
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Aug 11, 2025

Reviewer's Guide

This 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 server

sequenceDiagram
    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
Loading

Entity relationship diagram for oRPC context types

erDiagram
    InputCtx {
        headers string
    }
    AuthCtx {
        user BAUser
        session BASession
    }
    InputCtx ||--o{ AuthCtx : extends
    AuthCtx {
        headers string
        user BAUser
        session BASession
    }
Loading

File-Level Changes

Change Details Files
Overhaul tsconfig.json to define curated compiler options for environment, bundler, module resolution, and type checking
  • Restructure and group compilerOptions (lib, moduleDetection, jsx, allowJs)
  • Set moduleResolution to bundler, module to Preserve, noEmit and bundler flags
  • Enable strict target ESNext and esModuleInterop, skipLibCheck
  • Adjust stricter flags defaults
tsconfig.json
Integrate oRPC OpenAPI handler into the main server route
  • Import orpcHandler in src/index.ts
  • Add .all('/orpc/*') route delegating requests to orpcHandler.handle
  • Configure route with parse: 'none'
src/index.ts
Add oRPC setup with handler, middleware, routers, and a protected procedure
  • Create OpenAPIHandler with CORS and OpenAPIReference plugins
  • Implement auth.middleware (withBetterAuth, requireAuth, requireRole) and inject sessions
  • Implement db.middleware to provide Prisma client in context
  • Define baseMiddleware combining db and auth layers
  • Add user.me procedure under routers
src/orpc/index.ts
src/orpc/middleware/auth.middleware.ts
src/orpc/middleware/db.middleware.ts
src/orpc/middleware/index.ts
src/orpc/routers.ts
src/orpc/procedures/user/me.p.ts
Add AI Coding Agent instructions documentation
  • Introduce .github/copilot-instructions.md with tech stack and guidelines
  • Outline rules for Elysia, Prisma, and oRPC usage
.github/copilot-instructions.md
Update package.json to include oRPC dependencies
  • Add @orpc/openapi, @orpc/server, and @orpc/zod to dependencies
package.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 11, 2025

Note

Other AI code review bot(s) detected

CodeRabbit 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.

📝 Walkthrough

Walkthrough

Adds 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

Cohort / File(s) Summary
Documentation
.github/copilot-instructions.md
New developer guidelines for server stack (Elysia, Prisma, oRPC, better-auth), coding rules, and examples.
Dependencies
package.json
Adds @orpc/openapi, @orpc/server, @orpc/zod and zod to dependencies.
Server entry / ORPC mount
src/index.ts
Mounts catch-all route /orpc/* that delegates requests to orpcHandler.
ORPC OpenAPI handler
src/orpc/index.ts
New export orpcHandler — OpenAPIHandler configured with OpenAPIReferencePlugin and Zod->JSON schema converter (CORS lines commented out).
Middleware
src/orpc/middleware/*
Adds dbProviderMiddleware (injects Prisma), auth middleware (withBetterAuth, requireAuth, requireRole), and composed baseMiddleware.
Procedures & Router
src/orpc/procedures/user/me.p.ts, src/orpc/routers.ts
Adds meProcedure (GET /user/me, requires auth, returns {id,email,name}) and wires it on appRouter.user.me.
TypeScript config
tsconfig.json
Moves to bundler-focused settings (ESNext target/lib, module: Preserve, moduleResolution: bundler, noEmit, strict, path aliases).
Email/Auth minor cleanup
src/lib/auth.ts, src/lib/email/*
Removed debug console.log calls in email verification and email provider paths; no behavioral 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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~35 minutes

Possibly related PRs

Suggested labels

Review effort 4/5

Poem

I twitch my nose at ORPC’s gate,
Routes and schemas snugly wait.
With DB carrots and auth in paw,
I hop to /user/me and awe.
Zod-checked bites, docs in light—happy night! 🥕🐇

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/add-orpc

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@qodo-code-review
Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 Security concerns

Sensitive information exposure:
Logging of headers and session details in withBetterAuth and meProcedure may expose tokens or user data in logs. Remove or guard logs and avoid printing headers/session contents.
CORS configuration: The current permissive CORS setup may allow unintended cross-origin access. Implement an allowlist using isOriginAllowed or environment-driven configuration.

⚡ Recommended focus areas for review

Debug Logging

Multiple console.log statements emit request headers and session data; this can leak sensitive info and clutter logs. Consider removing or gating behind an environment flag.

		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);

		return next({
			context: {
				// preserve existing context and inject auth data
				...context,
				session: sessionData?.session || null,
				user: sessionData?.user || null,
			},
		});
	});

export const requireAuth = os
	.$context<AuthCtx>()
	.middleware(async ({ context, next }) => {
		console.log({ context });
		if (!context.session || !context.user) {
CORS Origin

The CORSPlugin uses a permissive origin callback returning the incoming origin verbatim, effectively allowing any origin. Validate and restrict origins using allowlist logic.

new CORSPlugin({
	origin: (origin, options) => origin,
	allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"],
}),
Route Parsing

The ORPC route uses parse: "none", passing raw requests to the handler. Confirm this is required and that downstream handlers validate and handle content-type and body parsing safely.

.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",
	},
)

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

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.md file contains general docs that might be better placed under a docs/ 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>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread .github/copilot-instructions.md Outdated
@@ -0,0 +1,47 @@
# AI Coding Agent innstructions – Universal Starter (Server)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (typo): Typo in the word 'innstructions'—should be 'instructions'.

Update the title to use the correct spelling.

Suggested change
# AI Coding Agent innstructions – Universal Starter (Server)
# AI Coding Agent instructions – Universal Starter (Server)

Comment thread src/orpc/procedures/user/me.p.ts Outdated
)
.handler(({ context }) => {
console.log(context);
const user = context.user;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (code-quality): Prefer object destructuring when accessing and using properties. (use-object-destructuring)

Suggested change
const user = context.user;
const {user} = context;


ExplanationObject destructuring can often remove an unnecessary temporary reference, as well as making your code more succinct.

From the Airbnb Javascript Style Guide

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented Aug 11, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Authentication leakage and CORS

The ORPC handler accepts any origin in its CORS plugin and forwards raw request
headers to Better Auth, which risks unintended credential exposure and
cross-origin access beyond the server’s cors() policy. Align ORPC CORS and
authentication header handling with the app’s CORS whitelist and restrict which
headers/cookies are read and propagated to Better Auth to prevent unauthorized
cross-origin session usage.

Examples:

src/orpc/index.ts [9-12]
new CORSPlugin({
	origin: (origin, options) => origin,
	allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"],
}),
src/index.ts [63-68]
const { response } = await orpcHandler.handle(request, {
	prefix: "/orpc",
	context: {
		headers: request.headers,
	},
});

Solution Walkthrough:

Before:

// src/orpc/index.ts
// The ORPC CORS plugin allows any origin by reflecting it.
new CORSPlugin({
  origin: (origin, options) => origin,
  // ...
}),

// src/index.ts
// All request headers are forwarded to the ORPC context.
.all("/orpc/*", async ({ request }) => {
  await orpcHandler.handle(request, {
    context: { headers: request.headers },
  });
  // ...
});

After:

// src/orpc/index.ts
// The ORPC CORS plugin should use the application's existing CORS validation logic.
import { isOriginAllowed } from "@/src/cors";

new CORSPlugin({
  origin: (origin, options) => {
    if (origin && isOriginAllowed(origin)) {
      return origin;
    }
    return false; // Disallow if not on the whitelist
  },
  // ...
}),
Suggestion importance[1-10]: 9

__

Why: This suggestion correctly identifies a critical security vulnerability where the orpcHandler's CORS policy is overly permissive, overriding the main application's policy and potentially exposing user data to malicious websites.

High
Security
Stop sensitive auth logging
Suggestion Impact:The commit removed console logging of headers and session data in withBetterAuth, and also removed an extra context log in requireAuth, aligning with the suggestion to stop sensitive auth logging.

code diff:

-		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);
 
 		return next({
 			context: {
@@ -42,7 +39,6 @@
 export const requireAuth = os
 	.$context<AuthCtx>()
 	.middleware(async ({ context, next }) => {
-		console.log({ context });
 		if (!context.session || !context.user) {
 			throw new ORPCError("UNAUTHORIZED", { message: "Unauthenticated" });

Remove verbose console logging of headers and session data to avoid leaking
sensitive information (tokens, cookies) to server logs. If needed, log only
non-sensitive metadata under a debug flag.

src/orpc/middleware/auth.middleware.ts [18-40]

 export const withBetterAuth = os
 	.$context<InputCtx>()
 	.middleware(async ({ context, next }) => {
 		const headers =
 			context.headers instanceof Headers
 				? context.headers
 				: new Headers(context.headers);
 
-		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);
 
 		return next({
 			context: {
 				// preserve existing context and inject auth data
 				...context,
-				session: sessionData?.session || null,
-				user: sessionData?.user || null,
+				session: sessionData?.session ?? null,
+				user: sessionData?.user ?? null,
 			},
 		});
 	});

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 8

__

Why: This is a valid security suggestion, as logging headers and session data can expose sensitive information like tokens, which is a significant security risk in production environments.

Medium
Harden role authorization checks

Fail fast when no roles are provided and guard when userRoles is empty to avoid
silently allowing access. Also normalize role comparison to a consistent case to
prevent casing bypass.

src/orpc/middleware/auth.middleware.ts [52-62]

 export const requireRole = (roles: string[]) =>
 	os.$context<AuthCtx>().middleware(async ({ context, next }) => {
+		if (!Array.isArray(roles) || roles.length === 0) {
+			throw new ORPCError("INTERNAL_SERVER_ERROR", { message: "No roles configured" });
+		}
 		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))) {
+		const userRoles: string[] = Array.isArray(rolesValue) ? (rolesValue as string[]) : [];
+		if (userRoles.length === 0) {
+			throw new ORPCError("FORBIDDEN", { message: "Forbidden" });
+		}
+		const required = new Set(roles.map(r => r.toLowerCase()));
+		const hasAny = userRoles.some(r => required.has(String(r).toLowerCase()));
+		if (!hasAny) {
 			throw new ORPCError("FORBIDDEN", { message: "Forbidden" });
 		}
 		return next({ context });
 	});
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion improves security by adding case-insensitive role comparison and checks for empty userRoles, making the authorization logic more robust against potential bypasses.

Medium
Possible issue
Prevent unintended 404 responses

Avoid returning a 404 when orpcHandler.handle already produced a valid, falsy
response (e.g., empty body with 204). Explicitly check for undefined instead of
using nullish coalescing. This prevents incorrect 404s and preserves handler
semantics.

src/index.ts [60-75]

 .all(
 	"/orpc/*",
 	async ({ request }: { request: Request }) => {
-		const { response } = await orpcHandler.handle(request, {
+		const result = await orpcHandler.handle(request, {
 			prefix: "/orpc",
 			context: {
 				headers: request.headers,
 			},
 		});
 
-		return response ?? new Response("Not Found", { status: 404 });
+		if (typeof result?.response === "undefined") {
+			return new Response("Not Found", { status: 404 });
+		}
+		return result.response;
 	},
 	{
 		parse: "none",
 	},
 )
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies a potential issue where orpcHandler.handle returning null or undefined would cause a crash, and the proposed change handles this case gracefully, improving robustness.

Low
  • Update

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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 context

Logic 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 tsconfig

You 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 oRPC

Docs 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 handlers

Given 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 ergonomics

Accept 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 typings

Expose 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 reuse

If 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 schema

If 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

📥 Commits

Reviewing files that changed from the base of the PR and between d2bfc08 and 40a6d74.

⛔ Files ignored due to path filters (1)
  • bun.lock is 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 correct

user.me is properly exposed via meProcedure. No functional concerns.

src/index.ts (1)

59-75: Correct ORPC mounting and context propagation

The /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 good

Context typing for headers and composition of dbProviderMiddleware then withBetterAuth is sound.

src/orpc/index.ts (2)

13-29: Ensure bearerAuth is actually required by operations

Defining 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 good

Zod converter and reference plugin are wired correctly; naming/version OK for now.

Comment thread package.json
Comment on lines +13 to +15
"@orpc/openapi": "^1.7.10",
"@orpc/server": "^1.7.10",
"@orpc/zod": "^1.7.10",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

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.

Suggested change
"@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.

Comment thread src/index.ts
Comment on lines +59 to +75
// 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",
},
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Comment thread src/orpc/index.ts
Comment on lines +4 to +6
type BAUser = typeof auth.$Infer.Session.user | null;
type BASession = typeof auth.$Infer.Session.session | null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ 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.

Comment thread src/orpc/middleware/auth.middleware.ts Outdated
Comment thread src/orpc/middleware/auth.middleware.ts Outdated
Comment thread src/orpc/procedures/user/me.p.ts Outdated
Comment thread src/orpc/procedures/user/me.p.ts
Comment thread tsconfig.json
Comment on lines +12 to +14
"paths": {
"@/*": ["./*"]
},
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot Aug 11, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I have prisma folder next to src folder

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧩 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/db for source files
  • @/prisma/schema for Prisma-related files

This gives you clean imports across both directories. After adding baseUrl, restart your TypeScript server/IDE to pick up the changes.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Skipped: comment is from another GitHub bot.

Comment thread tsconfig.json Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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 client

Also 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

📥 Commits

Reviewing files that changed from the base of the PR and between d2bfc08 and 40a6d74.

⛔ Files ignored due to path filters (1)
  • bun.lock is 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.headers and the /orpc prefix 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 CORSPlugin in orpcHandler.

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 requirement

You’ve defined the bearerAuth scheme but haven’t applied it at the root level, so operations won’t automatically require authentication. Update your specGenerateOptions to include:

 specGenerateOptions: {
   info: {
     title: "ORPC Playground",
     version: "1.0.0",
   },
   components: {
     securitySchemes: {
       bearerAuth: {
         type: "http",
         scheme: "bearer",
       },
     },
   },
+  security: [{ bearerAuth: [] }],
 },

• After adding this, verify that OpenAPIReferencePlugin actually honors the top-level security setting.
• If it does not, you’ll need to apply security on each protected operation instead.


10-12: Harden CORS configuration in src/orpc/index.ts

Restrict 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 options

Next steps:
• Confirm in the @orpc/server/plugins documentation whether the option key is allowHeaders or allowedHeaders, and adjust accordingly.

Comment on lines +4 to +6
type BAUser = typeof auth.$Infer.Session.user | null;
type BASession = typeof auth.$Infer.Session.session | null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

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

Comment thread src/orpc/procedures/user/me.p.ts Outdated
Comment thread src/orpc/procedures/user/me.p.ts
Comment thread tsconfig.json
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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" consistently

The 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 Guidelines

Also applies to: 45-47

tsconfig.json (1)

20-21: allowJs contradicts “Always use TypeScript” guideline

If 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 src

If 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 types

Implementation 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

📥 Commits

Reviewing files that changed from the base of the PR and between d2bfc08 and 40a6d74.

⛔ Files ignored due to path filters (1)
  • bun.lock is 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.md are 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 correct

Elysia supports skipping body parsing with parse: 'none'; parse: false isn’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.

Comment thread package.json
Comment on lines +13 to +15
"@orpc/openapi": "^1.7.10",
"@orpc/server": "^1.7.10",
"@orpc/zod": "^1.7.10",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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"
fi

Length 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.

Suggested change
"@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.

Comment thread src/index.ts
Comment on lines +59 to +75
// 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",
},
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ 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.

Comment thread src/orpc/index.ts Outdated
Comment on lines +9 to +12
new CORSPlugin({
origin: (origin, options) => origin,
allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"],
}),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Suggested change
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.

Comment thread src/orpc/index.ts Outdated
Comment thread src/orpc/middleware/auth.middleware.ts Outdated
Comment on lines +26 to +31
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);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

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.

Suggested change
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.

Comment on lines +54 to +60
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" });
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ 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[].

Comment on lines +5 to +18
.$context<{
db?: typeof prisma;
}>()
.middleware(async ({ context, next }) => {
const db = context.db ?? prisma;

return next({
context: {
// preserve existing context while injecting db
...context,
db,
},
});
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ 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.

Comment on lines +5 to +8
export const baseMiddleware = os
.$context<{ headers: Headers | Record<string, string> }>()
.use(dbProviderMiddleware)
.use(withBetterAuth);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

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.

Comment thread src/orpc/procedures/user/me.p.ts Outdated
Comment thread tsconfig.json
Comment on lines +12 to +14
"paths": {
"@/*": ["./*"]
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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:

  1. tsconfig.json (Lines 12–14)
   "paths": {
-    "@/*": ["./*"]
+    "@/*": ["./src/*"]
   },
  1. 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 "@/".

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (5)
tsconfig.json (1)

12-15: Consolidate path aliases to avoid ambiguity

Having 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 changes

Deriving 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 downstream

After 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 outages

If 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 shapes

Avoid 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 shape

Output 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 middleware

With 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

📥 Commits

Reviewing files that changed from the base of the PR and between 40a6d74 and aa57bea.

⛔ Files ignored due to path filters (1)
  • bun.lock is 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 consistent

moduleResolution: "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 wired

Auth middleware precedes the handler, shape is explicit, and error path uses ORPCError consistently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant