api-patterns

A set of rules for designing web API endpoints, including shared request and response definitions, input checks, authentication, database access, and error handling. Zod is a TypeScript library that checks whether data matches a defined shape.

In plain words
What is it for?
Use it when building or reviewing API handlers, defining shared data contracts, validating requests and responses, enforcing permissions, and recording changes.
Why use it?
It reduces inconsistent API behavior, invalid inputs, missing access checks, unsafe database access, and accidental exposure of database errors.

Cursor rule for Cursor

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add rules/yudefine/nuxt-supabase-starter/api-patterns
Clone the repo
git clone --depth 1 https://github.com/YuDefine/nuxt-supabase-starter

Made for: Cursor.

Per session 0 Nothing until a file matches its globs; then the whole rule loads.
When invoked 3,887 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.00000 $0.03887
Opus 5 $0.00000 $0.01944
Sonnet 5 $0.00000 $0.00777
Haiku 4.5 $0.00000 $0.00389

Measured 2d ago against content hash 7fd24239bec8, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

api-patterns scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

template/.cursor/rules/api-patterns.mdc · 224 lines

How it starts

The opening of the file, as written. The whole thing — 224 lines — stays where its author put it; the contents beside it link to each section on GitHub.

API Patterns

MUST define request/response contracts in shared/schemas/* and derive exported types from the same module MUST use Zod validation for all API inputs — getValidatedQuery(event, schema.parse) / readValidatedBody(event, schema.parse) MUST call requireAuth() or requireRole() before any business logic MUST use getSupabaseWithContext(event) for request-scoped database access

Helper 名依 modules.auth 而異:本檔以 getSupabaseWithContext(event) 為 canonical 名。當 consumer 的 .claude/hub.json modules.authbetter-authnuxt-auth-utils 時,等價 helper 是 getAuthedSupabase(event) —— 那些 auth stack 下 Supabase 不簽 JWT,auth.uid() 恆 null,helper 只驗 session 不做授權,名字必須說實話。兩者回傳形狀相同({ client, user })。見 [[auth-data-path-consistency]] § Server 側:RLS policy 的前提條件。 MUST parse outgoing handler payloads with response schema parse() before returning NEVER use getServerSupabaseClient() as the default path in request handlers — reserve it for privileged system tasks MUST log mutations to audit table — 表名與欄位慣例見 db-schema/<variant>/audit-schema.md MUST use unified response format { data, pagination? } NEVER return raw database errors to client — use handleDbError() + createError() with user-friendly message MUST const log = useLogger(event) as first line — see logging.md for evlog patterns

Reference: docs/api/API_DESIGN_GUIDE.md — 完整 API 設計指南含進階模式

本檔為 starter template 的預設規則,複製出去後依專案實際使用調整。

OWASP API Authorization

requireAuth() / requireRole()(垂直權限)不足以擋 OWASP API Top 10 的授權類風險 — 一個 authenticated 使用者仍可能存取別人的物件、寫入不該由 client 設定的欄位、或濫用端點。每個 state-changing / 敏感讀取 endpoint MUST 同時具備 authz + input-shape + abuse-control 三層:

Authz 層

  • Object-level authorization(BOLA / IDOR)MUST 對 request 帶的每個 resource id(:id、body 內 targetId 等)驗證當前使用者是否真的有權存取該筆 row(ownership / tenant / role scope),NEVER 只因為 id 存在就回傳 / 修改。做法:查詢時把 scope 條件放進 WHERE(.eq('tenant_id', user.tenantId) / .eq('owner_id', user.id)),或先 fetch 再比對再操作。BOLA 是最常見的 API 漏洞 — requireAuth() 過了不代表這個 user 能碰這筆 row。
  • Property-level authorization(BOPLA / mass assignment)MUST明確的欄位 allowlist 決定使用者能讀 / 寫哪些欄位,NEVER 直接把 readBody() 整包 spread 進 .update() / .insert()update({ ...body }))。做法:Zod schema 只 .pick() 允許的欄位,或手動列 { title: body.title, note: body.note }。防止使用者偷塞 role / is_admin / tenant_id / price / status不該由 client 設定的欄位(mass assignment),也防止 response 回傳不該給該 role 看的欄位(over-exposure)。

Read the full file on GitHub · 224 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 224 lines · 0 tokens per session scan A 7fd24239bec8

Subscribe to this mod's changes

api-patterns is a cursor rule published in the GitHub repository YuDefine/nuxt-supabase-starter (45 stars, last pushed 4d ago), licensed MIT. It costs nothing until one of its globs matches a file; then it loads 3,887 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.