
DANGER

``

WARNING

WARNING
plain
检查一下刚才那个任务,看看有没有问题。plain
只读审查 POST /tasks 的当前 diff。
目标:确认实现符合已批准 Spec。
范围:schemas/task.py、api/tasks.py、service/tasks.py、repo/tasks.py、tests/api/test_tasks.py。
重点:router 不查库、repo 不 commit、Pydantic from_attributes、201/422 测试。
禁止:不要修改文件,不要扩展需求,不要建议新增依赖。
输出:问题、证据文件/符号、风险等级、建议修复。
plain
---
name: python-architecture-explorer
description: Explore a Python codebase, trace dependencies, and return evidence. Never edit files.
model: fast
readonly: true
is_background: false
---
You are a read-only Python architecture explorer.
When invoked:
1. Identify relevant packages and entry points.
2. Trace api → service → repo → model/test dependencies.
3. Cite file paths and symbols as evidence.
4. List uncertainties and missing context.
5. Do not propose code changes until the parent agent confirms the module map.plain
---
name: python-test-verifier
description: Run Python quality checks and summarize failures without editing source code.
model: fast
readonly: true
is_background: true
---
Run the project verification commands defined in AGENTS.md.
Return:
- command and exit status
- concise failure summary
- affected files/tests
- likely root cause
- whether the failure predates the current diff
Do not modify tests or source files.WARNING



plain
搜索 refund / refund_order
↓
定位 payments/refund_service.py
↓
查看调用方和事务边界
↓
追踪 inventory/repository.py
↓
查找库存恢复事件或消息处理器
↓
读取相关测试与失败日志
↓
形成模块地图和根因假设
↓
用户确认后再修改WARNING
plain
请先不要修改代码。请调查“退款后库存没有恢复”的实现链路。
请输出:
1. 相关模块和文件列表。
2. 从 API 入口到退款 service、库存恢复逻辑的调用链。
3. 每个判断的代码证据。
4. 可能遗漏的异步任务、事件消费者、配置开关和测试。
5. 你仍然不确定的问题。
只有我确认模块地图后,才能进入实施计划。

plain
帮我重构这个项目的用户模块,顺便优化一下样式,
有问题你自己看着办。plain
请只重构 @src/features/user/UserCard.tsx。
目标:拆出 Avatar、UserMeta 两个子组件。
约束:保持现有 props 不变;不得修改 API 类型;
必须复用 @src/ui/Button.tsx。
验收:现有测试通过,并补充长昵称和空头像用例。
- ``
- ````
- ``
INFO
- ``
- ``
- ``````
WARNING
markdown
# my_api Agent Guide
## Tech Stack
- Python 3.12, FastAPI, SQLAlchemy 2.0 async, Pydantic v2.
- Dependency management: uv.
## Commands
- Install: uv sync
- Run API: uv run uvicorn my_api.main:app --reload
- Lint: uv run ruff check .
- Type check: uv run mypy src/my_api
- Tests: uv run pytest
## Architecture
- api/: HTTP routes and request/response boundary.
- service/: business orchestration and transaction boundaries.
- repo/: SQLAlchemy queries and persistence.
- schemas/: Pydantic input/output models.
- models/: SQLAlchemy ORM models.
## Safety
- Do not add dependencies without approval.
- Do not edit migrations unless requested.
- Do not change public API behavior without tests.
``````markdown
---
description: FastAPI route conventions for src/my_api/api
alwaysApply: false
globs: src/my_api/api/**/*.py
---
# FastAPI 路由规则
- 路由函数必须声明 response_model 或返回类型注解。
- 路由层只处理 HTTP 边界:参数、鉴权、状态码、调用 service。
- 禁止在路由层直接 import repo 或 SQLAlchemy model。
- 数据库会话通过 Depends(get_session) 注入,并传给 service。
- 新增 endpoint 必须补 pytest 测试。
``````
plain
my-api/
├── AGENTS.md
├── pyproject.toml
├── .cursor/
│ └── rules/
│ ├── 00-project-basics.mdc
│ ├── 10-fastapi-routes.mdc
│ ├── 20-repository-sqlalchemy.mdc
│ ├── 30-pytest-async.mdc
│ └── 90-release-checklist.mdc
├── src/my_api/
│ ├── api/
│ ├── service/
│ ├── repo/
│ ├── models/
│ ├── schemas/
│ └── main.py
└── tests/markdown
---
description: Project-wide Python engineering baseline
alwaysApply: true
globs:
---
# Project Baseline
- 使用 Python 3.12;包管理器是 uv,不要建议 pip install 或 poetry 命令。
- 新增依赖前,先说明原因、影响范围和替代方案,并等待用户确认。
- 代码风格以 pyproject.toml 中的 ruff、mypy、pytest 配置为准。
- 多文件修改后,提醒用户运行:uv run ruff check .、uv run mypy src/my_api、uv run pytest。
- 不要修改 alembic 迁移文件,除非任务明确要求。markdown
---
description: FastAPI route layer conventions for src/my_api/api
alwaysApply: false
globs: src/my_api/api/**/*.py
---
# API Layer Rules
- 路由函数必须声明 response_model 或返回类型注解;出参使用 schemas/ 下的 Pydantic v2 模型。
- 路由层只做 HTTP 边界工作:参数解析、认证授权、调用 service、选择状态码。
- 禁止在路由层直接 import repo 或 SQLAlchemy model。
- 数据库会话通过 Depends(get_session) 注入,并传给 service。
- 业务异常使用 AppError 子类;不要在各个路由里散落手写 JSONResponse。markdown
---
description: SQLAlchemy 2.0 async repository conventions
alwaysApply: false
globs: src/my_api/repo/**/*.py
---
# Repository Rules
- repo 层只封装 SQLAlchemy 查询与持久化,不处理 HTTP 状态码。
- 使用 SQLAlchemy 2.0 style:select(User),不要写 session.query(User)。
- 会话类型是 AsyncSession;async 函数里不要调用同步 Session。
- repo 内部不要 commit;事务边界由 service 或依赖层统一处理。
- 避免 N+1 查询;需要关联数据时使用 selectinload 或显式批量查询。markdown
---
description: pytest and pytest-asyncio conventions
alwaysApply: false
globs: tests/**/*.py
---
# Test Rules
- 测试文件名使用 test_*.py,目录结构尽量镜像 src/my_api。
- 异步测试使用 pytest.mark.asyncio;不要在测试里手动 asyncio.run。
- API 测试通过 async_client fixture 发请求,不直接调用路由函数。
- 数据准备使用 factory 或 fixture;每个测试必须独立,不依赖执行顺序。
- 断言覆盖行为和边界:状态码、响应 schema、数据库副作用、异常分支。markdown
---
description: Manual release checklist for API changes
alwaysApply: false
globs:
---
# Release Checklist
- 是否新增或修改公开 API?如果是,更新 OpenAPI 描述和 changelog。
- 是否涉及数据库结构?如果是,确认 alembic migration 与回滚策略。
- 是否有新环境变量?如果是,更新 .env.example 和部署文档。
- 最终回复里列出已运行或建议运行的 ruff、mypy、pytest 命令。
plain
请在 Python FastAPI 项目中新增 GET /users/by-email?email=... 接口。
范围:
- 修改 src/my_api/api/users.py
- 必要时修改 src/my_api/service/users.py、src/my_api/repo/users.py、src/my_api/schemas/user.py
- 添加 tests/api/test_users_by_email.py
规则:
- 遵守 @10-fastapi-routes
- 涉及 repo 查询时遵守 @20-repository-sqlalchemy
- 写测试时遵守 @30-pytest-async
验收:
- 找到用户返回 200 和 UserOut
- 找不到返回 404,错误码是 USER_NOT_FOUND
- email 参数格式非法返回 422
- 最终说明建议运行哪些命令验证python
from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.ext.asyncio import AsyncSession
from my_api.db import get_session
from my_api.schemas.user import UserOut
from my_api.service.users import get_user_by_email
router = APIRouter(prefix="/users", tags=["users"])
@router.get(
"/by-email",
response_model=UserOut,
status_code=status.HTTP_200_OK,
)
async def read_user_by_email(
email: str = Query(..., min_length=3, max_length=320),
session: AsyncSession = Depends(get_session),
) -> UserOut:
return await get_user_by_email(session=session, email=email)python
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from my_api.models.user import User
async def fetch_user_by_email(session: AsyncSession, email: str) -> User | None:
stmt = select(User).where(User.email == email)
result = await session.execute(stmt)
return result.scalar_one_or_none()python
``````````import pytest
from httpx import AsyncClient
pytestmark = pytest.mark.asyncio
async def test_get_user_by_email_returns_user(
async_client: AsyncClient,
user_factory,
) -> None:
user = await user_factory(email="ada@example.com")
response = await async_client.get("/users/by-email", params={"email": user.email})
assert response.status_code == 200
assert response.json()["email"] == "ada@example.com"
async def test_get_user_by_email_returns_404_when_missing(
async_client: AsyncClient,
) -> None:
response = await async_client.get("/users/by-email", params={"email": "missing@example.com"})
assert response.status_code == 404
assert response.json()["code"] == "USER_NOT_FOUND"

INFO
plain
---
description: All important Python rules
alwaysApply: true
globs: "**/*.py"
---
- 所有代码必须使用同步函数,因为同步代码更简单。
- 所有 IO 必须使用 async / await。
- 所有函数必须捕获 Exception 并返回 None,避免程序崩溃。
- 永远不要修改测试。
- 所有新功能必须补测试。
- 不要新增任何依赖。
- 数据访问可以直接写在 FastAPI router 中,减少文件数量。
- 必须严格遵守 service / repo 分层。
- 代码必须优雅、性能必须最好。plain
# 00-project-basics.mdc (Always)
- Python 3.12,包管理使用 uv。
- 不新增依赖,除非用户确认。
- 验证命令以 pyproject.toml 为准。
# 10-api-layer.mdc (globs: src/my_api/api/**/*.py)
- router 只处理 HTTP 边界并调用 service。
- router 不直接 import repo 或 ORM model。
# 20-repository.mdc (globs: src/my_api/repo/**/*.py)
- 使用 AsyncSession 和 SQLAlchemy 2.0 select()。
- repo 不 commit,事务边界由 service 管理。
# 30-tests.mdc (globs: tests/**/*.py)
- 新增行为必须补测试。
- 不通过删除测试、skip 或放宽断言来修复失败。DANGER
TIP

WARNING
| 任务 | 模型档位 | 上下文范围 | 修改轮次 | 测试结果 | 人工修复时间 |
|---|---|---|---|---|---|
| UserCard 组件 | 平衡 | 3 个文件 + 规则 | 1 | 通过 | 8 分钟 |
| 登录重构 | 旗舰 | 12 个文件 + Spec | 3 | 第 2 轮通过 | 35 分钟 |
| 文案替换 | 轻量 | 当前文件 | 1 | 不需要 | 1 分钟 |

plain
``src/my_api/
├── api/
│ └── tasks.py
├── service/
│ └── tasks.py
├── repo/
│ └── tasks.py
├── models/
│ └── task.py
├── schemas/
│ └── task.py
└── db.py
tests/
└── api/
└── test_tasks.pyINFO
plain
@src/my_api/api/tasks.py @src/my_api/service/tasks.py @src/my_api/repo/tasks.py
@src/my_api/models/task.py @src/my_api/schemas/task.py @tests/api/test_tasks.py
@10-fastapi-routes @20-repository-sqlalchemy @30-pytest-async
请先阅读下面 Spec,先给实现计划,不要立即改文件。
# Spec: Create Task API
## Background
当前项目是 Python FastAPI 后端,采用 api / service / repo / schemas / models 分层。
Task 模型已存在,当前需要补齐创建任务的 HTTP API。
项目使用 SQLAlchemy 2.0 async、Pydantic v2、pytest-asyncio 和 uv。
## Goal
新增 POST /tasks 接口:客户端提交 title 和可选 description,服务端创建 Task,并返回 TaskOut。
## Scope
允许修改:
- src/my_api/schemas/task.py
- src/my_api/api/tasks.py
- src/my_api/service/tasks.py
- src/my_api/repo/tasks.py
- tests/api/test_tasks.py
## Non Goal
本轮不做:
- 不新增鉴权逻辑。
- 不修改 Task ORM 模型。
- 不新增或修改 alembic migration。
- 不引入新依赖。
- 不重构 tasks 以外的模块。
## Constraints
- router 只处理 HTTP 边界和依赖注入,不直接 import SQLAlchemy model 或 repo。
- service 负责业务编排和事务边界。
- repo 只封装 SQLAlchemy 2.0 async 查询/写入,不在 repo 内 commit。
- 使用 Pydantic v2,输出 schema 支持从 ORM 对象校验。
- 如果发现必须修改模型或迁移文件,先停止并说明原因。
## Acceptance
- title 为空或超过长度限制时返回 422。
- 创建成功返回 201,响应包含 id、title、description、status、created_at。
- 测试覆盖成功创建和非法 title。
- 建议验证命令:uv run ruff check .、uv run mypy src/my_api、uv run pytest tests/api/test_tasks.py。
## Risks
- Task 模型字段可能和预期不一致,例如 status 默认值或 created_at 来源。
- 测试 fixture 名称可能不是 async_client。
- commit / refresh 的事务边界可能和项目现有 db 依赖策略冲突。
## Open Questions
- 如果 Task.status 不是字符串 open,而是枚举或数据库默认值,请先指出。
- 如果项目已有统一错误响应格式,请沿用,不要自造格式。
## Deliverables
请最终输出:
- 修改文件清单。
- 关键实现说明。
- 建议运行的验证命令。
- 未验证项和潜在风险。


plain
你先不要改文件。请先基于以下信息给出实现计划。
任务目标:
- 新增 POST /tasks 接口,创建任务并返回 TaskOut。
上下文:
- @src/my_api/api/tasks.py
- @src/my_api/service/tasks.py
- @src/my_api/repo/tasks.py
- @src/my_api/schemas/task.py
- @tests/api/test_tasks.py
规则:
- @10-fastapi-routes
- @20-repository-sqlalchemy
- @30-pytest-async
请先输出:
1. 你认为需要修改的文件列表。
2. 每个文件的修改点。
3. 你不会修改哪些文件,以及原因。
4. 需要我确认的风险点。
5. 建议的测试命令。
我确认后,你再开始改代码。plain
计划确认。现在开始实现,但请遵守:
- 只修改你刚才列出的文件。
- 每个文件只做和 POST /tasks 相关的改动。
- 如果发现必须修改模型或迁移文件,先停止并说明原因,不要直接改。
- 生成或更新测试后,在最终回复中列出建议运行的 ruff、mypy、pytest 命令。plain
以下是 pytest 失败日志。请只分析和本次 POST /tasks 改动相关的问题。
限制:
- 不要重写无关 fixture。
- 不要跳过测试。
- 不要放宽断言来让测试通过。
- 如果失败来自既有测试环境,请说明证据。
失败日志:
<粘贴 pytest 输出>TIP
python
# src/my_api/schemas/task.py
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field
class TaskCreate(BaseModel):
title: str = Field(..., min_length=1, max_length=120)
description: str | None = Field(default=None, max_length=1000)
class TaskOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
title: str
description: str | None
status: str
created_at: datetimepython
# src/my_api/api/tasks.py
from fastapi import APIRouter, Depends, status
from sqlalchemy.ext.asyncio import AsyncSession
from my_api.db import get_session
from my_api.schemas.task import TaskCreate, TaskOut
from my_api.service.tasks import create_task
router = APIRouter(prefix="/tasks", tags=["tasks"])
@router.post("", response_model=TaskOut, status_code=status.HTTP_201_CREATED)
async def create_task_endpoint(
payload: TaskCreate,
session: AsyncSession = Depends(get_session),
) -> TaskOut:
return await create_task(session=session, payload=payload)python
# src/my_api/service/tasks.py
from sqlalchemy.ext.asyncio import AsyncSession
from my_api.repo.tasks import insert_task
from my_api.schemas.task import TaskCreate, TaskOut
async def create_task(session: AsyncSession, payload: TaskCreate) -> TaskOut:
task = await insert_task(session=session, payload=payload)
await session.commit()
await session.refresh(task)
return TaskOut.model_validate(task)python
````# src/my_api/repo/tasks.py
from sqlalchemy.ext.asyncio import AsyncSession
from my_api.models.task import Task
from my_api.schemas.task import TaskCreate
async def insert_task(session: AsyncSession, payload: TaskCreate) -> Task:
task = Task(
title=payload.title,
description=payload.description,
status="open",
)
session.add(task)
await session.flush()
return taskpython
# tests/api/test_tasks.py
import pytest
from httpx import AsyncClient
pytestmark = pytest.mark.asyncio
async def test_create_task_returns_201(async_client: AsyncClient) -> None:
response = await async_client.post(
"/tasks",
json={"title": "Write Cursor tutorial", "description": "Use Python example"},
)
assert response.status_code == 201
body = response.json()
assert body["id"] is not None
assert body["title"] == "Write Cursor tutorial"
assert body["description"] == "Use Python example"
assert body["status"] == "open"
assert "created_at" in body
async def test_create_task_rejects_empty_title(async_client: AsyncClient) -> None:
response = await async_client.post("/tasks", json={"title": ""})
assert response.status_code == 422

plain
请按 AI Review Pipeline 审查你刚才的修改,不要继续改代码。
请逐项输出:
1. Scope Check:实际修改文件是否都在 Spec Scope 内?有没有越界?
2. Diff Review:每个文件的关键改动是什么?为什么需要?
3. Static Analysis:建议运行哪些 ruff 命令?你预期可能有什么 lint 风险?
4. Type Check:哪些返回类型、schema、AsyncSession 类型需要重点检查?
5. Tests:哪些测试覆盖了 Acceptance?还缺哪些边界?
6. Security / Policy:有没有新增依赖、敏感字段、权限绕过、外部数据误信?
7. Human Review:哪些点必须由人确认?
8. Rule Update:这次是否暴露了需要沉淀到 .cursor/rules 的重复问题?
````````````
````````

DANGER

INFO

评论与讨论
如果这篇文章对你有帮助,或你对实现细节有不同判断,可以直接在这里继续讨论。