RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/Cursor rules/AsharibAli/ramadan-prompting-nights

Cursor rule

.cursor/rules/api.mdc

[object Object]

Cursor rules

Quality

78/100

Scores the file, not the repository.

Length

1,222 words

15 headings · 7 code blocks

Repository

29

— · pushed 46 days ago

Last changed

3 days ago

First indexed 3 days ago.
AsharibAli/ramadan-prompting-nights/.cursor/rules/api.mdcRawGitHub
1---
2description:
3globs: apps/api/**/*.ts
4alwaysApply: false
5---
6# Backend API Architecture and Development Guidelines
7 
8You are an expert TypeScript backend engineer specializing in building modern, type-safe APIs. Your expertise covers Hono for HTTP routing, Drizzle ORM for database operations, and React Query for frontend integration.
9 
10<core_architecture>
11 
12<tech_stack>
13- **Server & Routing**: Hono
14- **Database ORM**: Drizzle with PostgreSQL
15- **Frontend Integration**: React Query
16- **Authentication**: Clerk
17- **Validation**: Zod with zValidator
18</tech_stack>
19 
20<project_structure>
21apps/
22 ├── api/
23 │ ├── src/
24 │ │ ├── modules/ # Feature-based modules
25 │ │ │ ├── [module]/ # e.g., posts, webhooks
26 │ │ │ │ ├── [module].routes.ts # Route definitions
27 │ │ │ │ └── [module].service.ts # Business logic & DB operations
28 │ │ ├── pkg/ # Shared utilities and middleware
29 │ │ └── index.ts # Main application setup
30 └── web/
31 └── src/
32 └── api/
33 └── [module].api.ts # React Query hooks
34 
35packages/
36 └── db/
37 ├── src/
38 │ ├── schema.ts # Database schema definitions
39 │ ├── types.ts # Shared TypeScript types
40 │ ├── index.ts # Main exports
41 │ └── util/ # Database utilities
42</project_structure>
43 
44<module_development_guidelines>
45### 1. Database layer
46- If the request needs a new column or addition database fields start by creating and updating schema.ts
47- Leverage types.ts inside packages/db to create new zod schemas for the newly created tables or columns and eg:
48```
49export type Post = InferSelectModel<typeof schema.posts>;
50export type NewPost = InferInsertModel<typeof schema.posts>;
51 
52export const postInsertSchema = createInsertSchema(schema.posts).omit({ userId: true });
53export const postSelectSchema = createSelectSchema(schema.posts);
54```
55 
56 
57### 2. Service Layer ([module].service.ts)
58- Implement business logic
59- Handle database operations using Drizzle
60- Return strongly typed responses
61- Keep services focused and modular
62- Import db from the `packages/db`
63 
64Example service implementation:
65```ts
66`[module].service.ts`
67import { db, eq, items} from "@repo/db"
68 
69export const moduleService = {
70 async getItems() {
71 return db.select().from(items);
72 },
73
74 async createItem(data: NewItem) {
75 return db.insert(items).values(data).returning();
76 }
77};
78```
79 
80 
81### 3. Route Layer ([module].routes.ts)
82- Define endpoints using Hono router
83- Implement request validation using zValidator. You can leverage the created zod schemas from drizzle zod.
84- Apply authentication middleware where needed
85- Structure routes logically by resource
86- **Use custom error classes instead of manual status responses** - Import from `@/pkg/errors` and throw appropriate errors
87- **Avoid wrapping route handlers in try-catch blocks** - let error middleware handle exceptions
88- Delegate all business logic and error handling to the service layer
89 
90Example route implementation:
91```ts
92import { NotFoundError } from "@/pkg/errors";
93 
94const moduleRoutes = new Hono()
95 .use(auth(),requireAuth)
96 .get("/", async (c) => {
97 const items = await moduleService.getItems();
98 return c.json(items);
99 })
100 .post("/", zValidator("json", insertSchema), async (c) => {
101 const data = c.req.valid("json");
102 const userId = getUserId(c);
103 const result = await moduleService.createItem({ ...data, userId });
104 // If results could be undefined or otherwise, throw proper error
105 if (!result){
106 throw new NotFoundError("Item not found");
107 }
108 return c.json(result);
109 });
110 
111
112```
113 
114After the route is created, you must add it to the `apps/api/src/index.ts` route so its accessable by the frontend.
115 
116</module_development_guidelines>
117 
118<frontend_integration>
119When fetching data from the backend api on the client, use the following guidelines
120`post.api.ts`
121```ts
122import { apiRpc, getApiClient, InferRequestType, callRpc } from "./client";
123 
124const $createPost = apiRpc.posts.$post;
125// Simple get
126export async function getPosts() {
127 const client = await getApiClient();
128 
129 return callRpc(client.posts.$get());
130}
131// Safely leverage the typed params elsewhere within the nextjs application
132export type CreatePostParams = InferRequestType<typeof $createPost>["json"];
133export async function createPost(params: CreatePostParams) {
134 const client = await getApiClient();
135 
136 return callRpc(client.posts.$post({ json: params }));
137}
138```
139</frontend_integration>
140<package_management>
141 
142- Use `pnpm` as the primary package manager for the project
143- Install dependencies using `pnpm add [package-name]`
144- Install dev dependencies using `pnpm add -D [package-name]`
145- Install workspace dependencies using `pnpm add -w [package-name]`
146</package_management>
147 
148<development_guidelines>
149### Running Scripts
150- Use `bun` as the runtime environment and script runner
151- Execute scripts defined in package.json using `bun run [script-name]`
152- Run TypeScript files directly using `bun [file.ts]`
153 
154### Monorepo
155The project use turbo repo. To run everything, use the `turbo dev` script from the root folder.
156 
157### Type Safety
158- Use Drizzle schemas for database types
159- Share types between frontend and backend using a shared package
160- Leverage zod for runtime validation
161 
162### Error Handling
163- **Use custom error classes instead of manual JSON responses** - Import and throw errors from `@/pkg/errors/error`
164- Available error classes: `NotFoundError`, `BadRequestError`, `UnauthorizedError`, `ForbiddenError`, `ConflictError`, `UnprocessableEntityError`, `InternalServerError`, `TooManyRequestsError`
165- **NEVER return manual status responses** like `return c.json({error: "message"}, 401)` - always throw proper error classes
166- Implement consistent error handlers across all routes
167- Handle edge cases by throwing appropriate error classes
168- Use the logger from the package @repo/logger with object inside, i.e `logger.error({...})` instead of `console.error`
169 
170#### Error Class Usage Examples:
171```ts
172// ❌ DON'T DO THIS
173if (!user) {
174 return c.json({ error: "User not found" }, 404);
175}
176 
177// ✅ DO THIS INSTEAD
178import { NotFoundError, BadRequestError, ConflictError } from "@/pkg/errors";
179 
180if (!user) {
181 throw new NotFoundError("User not found");
182}
183 
184if (email && await userExists(email)) {
185 throw new ConflictError("User with this email already exists");
186}
187 
188if (!isValidInput(data)) {
189 throw new BadRequestError("Invalid input data provided");
190}
191```
192 
193### Authentication & Authorization
194- Use Clerk middleware for authentication
195- Implement role-based access control where needed
196- Validate user permissions at the route level
197- Keep authentication logic in middleware
198 
199### API Design Principles
200- Follow RESTful conventions
201- Use consistent naming patterns
202- Implement proper request validation
203- Structure endpoints by resource/module
204- Keep routes clean and delegate logic to services
205 
206### Database Operations
207- Use Drizzle for all database interactions
208- Implement proper migrations
209- Handle transactions when needed
210- Write efficient queries
211- Use appropriate indexes
212</development_guidelines>
213 
214<dev_workflow>
215### Creating a New Module for different buisness logic
2161. Create module directory in api/src/modules/[module]
2172. Define routes in [module].routes.ts
2183. Implement service logic in [module].service.ts
2194. Add route to main application in index.ts
2205. Create frontend integration in web/src/api/[module].api.ts
221</dev_workflow>
222 
223### Testing Requirements
224- If needed use vitest to create testing files inside of the modules, [module].test.ts
225-
226### Code Quality
227- For methods with more than one argument, use object destructuring: `function myMethod({ param1, param2 }: MyMethodParams) {...}`.
228</best_practices>
229 
230 
231<example_api_workflow>
232Here's a complete example of a typical module:
233 
234(if required) create new schemas.
235// packages/db/schema.ts
236.. new schema files
237 
238Then:
239```ts
240// posts.service.ts
241import { db, posts, type NewPost } from "@repo/db";
242 
243export const postService = {
244 async getPosts() {
245 return db.select().from(posts);
246 },
247 
248 async createPost(post: NewPost) {
249 return db.insert(posts).values(post).returning();
250 }
251};
252 
253// posts.routes.ts
254import { Hono } from "hono";
255import { auth, requireAuth, getUserId } from "@/pkg/middleware/clerk-auth";
256import { postService } from "./post.service";
257import { zValidator } from "@/pkg/util/validator-wrapper";
258import { postInsertSchema } from "@repo/db";
259 
260export const postRoutes = new Hono()
261 .use(auth(),requireAuth)
262 .get("/", async (c) => {
263 const posts = await postService.getPosts();
264 return c.json(posts);
265 })
266 .post("/", zValidator("json", postInsertSchema), async (c) => {
267 const data = c.req.valid("json");
268 const userId = getUserId(c);
269 const post = await postService.createPost({ ...data, userId });
270 return c.json(post);
271 });
272```
273 
274- Use the RPC-style API client for type-safe API calls
275- Leverage `InferRequestType` for parameter typing
276- Export plain async functions for API operations
277- Optionally create React Query hooks when needed
278```ts
279// posts.api.ts (Frontend)
280import { apiRpc, getApiClient, InferRequestType, callRpc } from "./client";
281 
282const $createPost = apiRpc.posts.$post;
283 
284export async function getPosts() {
285 const client = await getApiClient();
286 return callRpc(client.posts.$get());
287}
288 
289export async function createPost(params: InferRequestType<typeof $createPost>["json"]) {
290 const client = await getApiClient();
291 return callRpc(client.posts.$post({ json: params }));
292 return response.json();
293}
294```
295</example_api_workflow>
296 
297 
298 

Commands it names

  • pnpm
  • pnpm add [package-name]
  • pnpm add -D [package-name]
  • pnpm add -w [package-name]
  • bun
  • bun run [script-name]
  • bun [file.ts]
  • turbo dev

Sections

  • Backend API Architecture and Development Guidelines
  • 1. Database layer
  • 2. Service Layer ([module].service.ts)
  • 3. Route Layer ([module].routes.ts)
  • Running Scripts
  • Monorepo
  • Type Safety
  • Error Handling
  • Authentication & Authorization
  • API Design Principles
  • Database Operations
  • Creating a New Module for different buisness logic
  • Testing Requirements
  • Code Quality

What it covers

setuptesttypessecuritydatabaseapimonorepo

Stack — with the evidence

typescript

(1.00)

turborepo

(1.00)

monorepo

(1.00)

biome

(1.00)

vitest

(0.95)

pnpm

(0.85)

node

(0.70)

react

(0.70)

nextjs

(0.70)

hono

(0.70)

drizzle

(0.70)

postgres

(0.70)

tailwind

(0.70)

vercel

(0.70)

javascript

(0.60)

Glob targeting

  • apps/api/**/*.ts

Format

Cursor rules

The most expressive format here. Many small .mdc files, each with frontmatter declaring when it should load, so a rule about migrations only enters context when a migration is open. Costs the most to maintain and only one editor reads it.

What the corpus says about it

Repository

Owner
AsharibAli
Language
—
License
—
Archived
no

All configs in this repo

Also in AsharibAli/ramadan-prompting-nights

Diff this repo’s formats

One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?

The other instruction files in this repository
RepositoryFormatStackCoversScoreChanged
AsharibAli/ramadan-prompting-nights.cursor/rules/db.mdc · 29Cursor rulestypescriptturborepo+13no sections44/1003 days ago
AsharibAli/ramadan-prompting-nights.cursor/rules/frontend.mdc · 29Cursor rulestypescriptturborepo+13setuptestlint-formatstyle+791/1003 days ago
Diff against .cursor/rules/db.mdc Diff against .cursor/rules/frontend.mdc

Similar configs

Same format, overlapping stack, ranked by quality.

Same format, overlapping stack, ranked by quality
RepositoryFormatStackCoversScoreChanged
hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126Cursor rulesgobun+5setupbuildtestlint-format+6100/1003 days ago
TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45Cursor rulestypescriptpytest+15testlint-formatstylearch+5100/1003 days ago
markstev/mark-starter.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+14setuptestlint-formatstyle+699/1003 days ago
Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+13setuptestlint-formatstyle+799/1003 days ago
dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+15setuptestlint-formatstyle+799/1003 days ago
deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1Cursor rulestypescriptnextjs+5setuptestlint-formatstyle+799/1003 days ago
langflow-ai/langflow.cursor/rules/docs_development.mdc · 153kCursor rulespythonnode+16setupbuildtestlint-format+797/1003 days ago
TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45Cursor rulestypescriptpytest+15teststyletesting-strategysecurity+397/1003 days ago
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack