Skip to content

Add vibecodex FastAPI production architecture cursorrules#272

Open
yerdaulet-damir wants to merge 3 commits intoPatrickJS:mainfrom
yerdaulet-damir:add-vibecodex-fastapi-production
Open

Add vibecodex FastAPI production architecture cursorrules#272
yerdaulet-damir wants to merge 3 commits intoPatrickJS:mainfrom
yerdaulet-damir:add-vibecodex-fastapi-production

Conversation

@yerdaulet-damir
Copy link
Copy Markdown

@yerdaulet-damir yerdaulet-damir commented Apr 28, 2026

vibecodex — FastAPI Production Architecture Rules

🔗 Repo: https://github.com/yerdaulet-damir/vibecodex

What these rules enforce

Production architecture patterns that prevent the most common "works in dev, breaks in prod" failures when AI writes FastAPI code:

  • Router → Service → Repository — strict 4-layer boundaries, forbidden cross-layer imports listed explicitly
  • Anti-Corruption Layer (ACL) — providers return GenerateResult | ProviderError, never raw dict. Vendor field names never cross the boundary.
  • Per-provider Bulkhead — one httpx.AsyncClient per external provider with explicit Limits. Prevents one slow provider from starving others.
  • Single-Writer Principle — safety-critical mutations happen in exactly one place (prevents double-charge bugs)
  • Protocol-based DI — services accept WalletRepoProtocol, not Session. Makes testing with fakes trivial.
  • File size limits — 400 LOC yellow (plan split), 600 LOC red (block merge)
  • Structured loggingcontextvars threads user_id, provider, request_id through async stacks

Stack

FastAPI 0.111 · SQLAlchemy 2.0 · Pydantic v2 · Python 3.11+

Part of vibecodex — production architecture bible for vibe-coding across FastAPI, Next.js 15, and Go 1.22+.

Summary by CodeRabbit

  • Documentation
    • Added a new FastAPI production architecture ruleset and README: formalizes a 4-layer import model, enforces thin routers and typed service/repository contracts, requires typed provider results and per-provider HTTP client isolation, mandates idempotency for side effects, prescribes structured context propagation and single-writer safety, and defines file-size/LOC decomposition guidance.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3f9ae11b-cd28-4001-82ec-bf1ea3040fcb

📥 Commits

Reviewing files that changed from the base of the PR and between 7ba2d01 and dbe7f52.

📒 Files selected for processing (1)
  • rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules
✅ Files skipped from review due to trivial changes (1)
  • rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules

📝 Walkthrough

Walkthrough

Adds a new Cursor ruleset for a production FastAPI architecture plus a README, and updates the repository README to reference the new "vibecodex FastAPI Production" ruleset (layered model, provider patterns, file-size/LOC policies).

Changes

Cohort / File(s) Summary
Repo README
README.md
Appends a new bullet to the "Rules" index linking to the vibecodex FastAPI Production cursorrules.
FastAPI Production Ruleset
rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules, rules/vibecodex-fastapi-production-cursorrules-prompt-file/README.md
Adds a comprehensive Cursor ruleset and README describing a 4-layer import model (Router → Service → Repository → ORM/HTTP/Storage), explicit allowed/forbidden imports, router/service/repository/provider constraints (typed results, per-provider httpx.AsyncClient bulkheads, idempotency keys, contextvar propagation), single-writer repo rules, file-size/LOC thresholds, package-splitting pattern, and explicit anti-patterns/examples.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Suggested reviewers

  • PatrickJS

Poem

🐰 I hopped through rules both crisp and bright,
Layers aligned, each in its place so tight,
Providers hum, requests kept neat and small,
Exceptions mapped and boundaries stand tall.
Hop on, team — let careful code take flight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately describes the main change: adding a new FastAPI production architecture cursorrules file to the repository.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@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: 2

🧹 Nitpick comments (2)
rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules (2)

130-135: Make the contextvars logging example “copy/paste correct”.

The example uses contextvars.ContextVar[...] but doesn’t show import contextvars. Also, consider adding a short snippet showing how to read these vars inside the logger call (or explicitly instruct Cursor to include structured fields), so implementations are consistent and not ad-hoc.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules`
around lines 130 - 135, The snippet defining provider_var and user_id_var is
missing the import for contextvars and doesn't show how to read those vars when
logging; add "import contextvars" at the top and update examples (or
instructions to Cursor) to read contextvars via provider_var.get() and
user_id_var.get() when emitting logs (or explicitly instruct Cursor to include
those as structured fields) so the sample using provider_var and user_id_var is
copy/paste runnable and consistently produces structured context in logs.

136-140: Single-writer rule is correct but overly specific to one file path.

Hard-coding “repo.hold() may only be called from services/credits/user.py” is brittle if the project reorganizes modules. Consider expressing the constraint in terms of call origin (e.g., “only services layer may call repo.hold; no routers/providers/admin services; enforce via code-review lint/testing”) rather than a single path.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules`
around lines 136 - 140, The rule currently hard-codes the module path
"services/credits/user.py" for the Single-Writer Principle; change it to require
that only the service layer is allowed to call repo.hold() (e.g., "Only
service-layer modules may call repo.hold(); routers, providers, and admin
services must not call repo.hold()"), remove the specific file path, and add
guidance to enforce this via code-review checks, linting or unit/integration
tests that assert call-origin (referencing the symbol repo.hold() and the
"Single-Writer Principle" rule name).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@README.md`:
- Line 151: The new list item "vibecodex FastAPI Production" in the "Backend and
Full-Stack" section is out of alphabetical order; relocate the line "-
[vibecodex FastAPI
Production](./rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules)
- Production architecture rules: Router→Service→Repository, ACL, bulkhead
isolation, single-writer principle" so it appears in the correct alphabetical
position among the other bullets in the "Backend and Full-Stack" list (compare
surrounding entries like the "Python" bullets) to restore alphabetical ordering.

In `@rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules`:
- Around line 19-27: The router's charge handler passes the idempotency value as
key=req.idempotency_key which mismatches the expected idempotency_key parameter
described in Rule 3; update the call in the charge function to pass the
idempotency value with the correct name (e.g.,
idempotency_key=req.idempotency_key) or rename the ChargeRequest/service
parameter consistently so svc.charge(user_id=user_id, amount=req.amount,
idempotency_key=req.idempotency_key) matches the expected signature; ensure
ChargeRequest and svc.charge use the exact same identifier idempotency_key.

---

Nitpick comments:
In `@rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules`:
- Around line 130-135: The snippet defining provider_var and user_id_var is
missing the import for contextvars and doesn't show how to read those vars when
logging; add "import contextvars" at the top and update examples (or
instructions to Cursor) to read contextvars via provider_var.get() and
user_id_var.get() when emitting logs (or explicitly instruct Cursor to include
those as structured fields) so the sample using provider_var and user_id_var is
copy/paste runnable and consistently produces structured context in logs.
- Around line 136-140: The rule currently hard-codes the module path
"services/credits/user.py" for the Single-Writer Principle; change it to require
that only the service layer is allowed to call repo.hold() (e.g., "Only
service-layer modules may call repo.hold(); routers, providers, and admin
services must not call repo.hold()"), remove the specific file path, and add
guidance to enforce this via code-review checks, linting or unit/integration
tests that assert call-origin (referencing the symbol repo.hold() and the
"Single-Writer Principle" rule name).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cb9c7f00-4c43-49f8-b0df-52cc30606796

📥 Commits

Reviewing files that changed from the base of the PR and between fc2ce04 and d7e5509.

📒 Files selected for processing (3)
  • README.md
  • rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules
  • rules/vibecodex-fastapi-production-cursorrules-prompt-file/README.md

Comment thread README.md Outdated
- [Python (Django Best Practices)](./rules/python-django-best-practices-cursorrules-prompt-fi/.cursorrules) - Cursor rules for Python Django development with best practices.
- [Python (FastAPI Best Practices)](./rules/python-fastapi-best-practices-cursorrules-prompt-f/.cursorrules) - Cursor rules for Python FastAPI development with best practices.
- [Python (FastAPI Scalable API)](./rules/python-fastapi-scalable-api-cursorrules-prompt-fil/.cursorrules) - Cursor rules for Python FastAPI development with scalable API integration.
- [vibecodex FastAPI Production](./rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules) - Production architecture rules: Router→Service→Repository, ACL, bulkhead isolation, single-writer principle
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Alphabetical ordering violation in the “Backend and Full-Stack” list.

The new “vibecodex FastAPI Production” entry is inserted between “Python (...)” bullets (around Line 150-154 in the provided snippet). Per the repository guideline, entries within a category should be kept alphabetically ordered, so this item should be moved to its correct position among the “Backend and Full-Stack” rules.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` at line 151, The new list item "vibecodex FastAPI Production" in
the "Backend and Full-Stack" section is out of alphabetical order; relocate the
line "- [vibecodex FastAPI
Production](./rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules)
- Production architecture rules: Router→Service→Repository, ACL, bulkhead
isolation, single-writer principle" so it appears in the correct alphabetical
position among the other bullets in the "Backend and Full-Stack" list (compare
surrounding entries like the "Python" bullets) to restore alphabetical ordering.

…import, single-writer generalization, alphabetical order
Copy link
Copy Markdown
Contributor

@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: 3

🧹 Nitpick comments (1)
rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules (1)

146-150: Clarify the single-writer rule’s scope.

“Admin services must NOT call repo.hold() directly” is too absolute and reads as if admin services are excluded from the service layer entirely. If admin workflows also own writes, this wording will force a second code path or an awkward exception.

Suggested wording
-Only service-layer modules may call repo.hold().
-Routers, providers, and admin services must NOT call repo.hold() directly.
+Only the designated writer service for a domain may call repo.hold().
+Routers and providers must NOT call repo.hold() directly.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules`
around lines 146 - 150, Update the Rule 5 wording to clarify scope: state that
"Only service-layer modules may call repo.hold()" and explicitly allow admin
services that are implemented as part of the service layer to call repo.hold(),
while prohibiting routers, providers, and non-service-layer admin utilities from
calling repo.hold() directly; replace the sentence "Admin services must NOT call
repo.hold() directly" with a clear exception phrase referencing "admin services
implemented in the service layer" and keep the enforcement note (grep
"repo\.hold(") unchanged so reviewers can still detect violations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules`:
- Around line 11-16: The rule blanket-requires user_id: str =
Depends(get_current_user_id) on every non-/auth/* endpoint which incorrectly
forces authentication on public routes (health checks, webhooks, callbacks);
change the rule so that only protected endpoints explicitly declare the
dependency (e.g., routes that call protected services or are in auth-protected
routers) must include user_id: str = Depends(get_current_user_id), while public
endpoints (health check, webhook, callback) must be exempt—update the guidance
text and examples to reference get_current_user_id and clarify that
business-facing routers/methods that need identity call the dependency, whereas
anonymous endpoints do not.
- Around line 67-71: The LOC ranges "0–400" and "400–600" overlap at 400; change
the lower range to be non‑inclusive of 400 so the policy is unambiguous (e.g.,
replace "0–400" with "0–399" so 400 falls into "400–600" as intended). Update
the table entries containing the strings "0–400" and "400–600" accordingly (look
for the exact range tokens in the | LOC | table row).
- Around line 114-126: Module-level AsyncClient instances FAL_HTTP and
OPENAI_HTTP are never closed, risking connection-pool leaks; add explicit
shutdown cleanup that calls await FAL_HTTP.aclose() and await
OPENAI_HTTP.aclose() during application shutdown. Locate where the FastAPI app
lifecycle is managed (startup/shutdown handlers or the app factory) and register
an async shutdown event (or use a lifespan context) that closes each provider
client; ensure the handler is awaited and idempotent so repeated
shutdowns/reloads don't error.

---

Nitpick comments:
In `@rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules`:
- Around line 146-150: Update the Rule 5 wording to clarify scope: state that
"Only service-layer modules may call repo.hold()" and explicitly allow admin
services that are implemented as part of the service layer to call repo.hold(),
while prohibiting routers, providers, and non-service-layer admin utilities from
calling repo.hold() directly; replace the sentence "Admin services must NOT call
repo.hold() directly" with a clear exception phrase referencing "admin services
implemented in the service layer" and keep the enforcement note (grep
"repo\.hold(") unchanged so reviewers can still detect violations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c20446f5-68fe-42d8-9c08-6ec628fe3272

📥 Commits

Reviewing files that changed from the base of the PR and between d7e5509 and 7ba2d01.

📒 Files selected for processing (2)
  • README.md
  • rules/vibecodex-fastapi-production-cursorrules-prompt-file/.cursorrules
✅ Files skipped from review due to trivial changes (1)
  • README.md

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant