fastreact

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

fastreact - FastAPI + React full-stack webapp

fastreact - FastAPI + React 全栈Web应用

Build a production-shaped full-stack web app from a mockup to a running Docker Compose stack. Backend: FastAPI, uv, SQLModel, Postgres, Alembic, JWT + Google OAuth, boto3 (S3). Frontend: Vite, React, TypeScript, shadcn/ui + Tailwind, TanStack Router (file-based) / Query / Table, Zod, Axios. Infra: Docker Compose (postgres + backend + frontend), seeded test users, agent-browser E2E.
从原型到可运行的Docker Compose栈,构建具备生产环境雏形的全栈Web应用。 **后端:**FastAPI、uv、SQLModel、Postgres、Alembic、JWT + Google OAuth、boto3(S3)。 **前端:**Vite、React、TypeScript、shadcn/ui + Tailwind、TanStack Router(基于文件)/Query/Table、Zod、Axios。 **基础设施:**Docker Compose(postgres + 后端 + 前端)、预生成测试用户、agent-browser端到端测试。

When to use

适用场景

  • "Spin up / bootstrap / create a full-stack webapp", "FastAPI + React", "Python backend + React frontend".
  • An admin panel, client portal, dashboard, or internal tool with auth + RBAC + file upload + S3.
  • API-first backend with a typed SPA; local docker dev with seeded users.
  • "快速启动/初始化/创建全栈Web应用"、"FastAPI + React"、"Python后端 + React前端"。
  • 带有身份验证+RBAC+文件上传+S3功能的管理面板、客户门户、仪表板或内部工具。
  • API优先的后端搭配类型化单页应用;带有预生成用户的本地Docker开发环境。

Scope

范围

This skill handles scaffolding, conventions, and local setup for a FastAPI+React+Postgres+S3 webapp. It does NOT: deploy to cloud, generate raster brand art itself (delegates to
vd:marketing-design
), or design HTML pages itself (delegates to
vd:opendesign
). For pure UI-token/Tailwind work use
vd:uiuxdesign
. Never put secrets in tracked files; always a gitignored
.env
.
此技能负责FastAPI+React+Postgres+S3 Web应用的脚手架搭建、规范制定和本地环境配置。 不包含:部署到云端、自行生成光栅品牌图(委托给
vd:marketing-design
)、自行设计HTML页面(委托给
vd:opendesign
)。纯UI令牌/Tailwind相关工作请使用
vd:uiuxdesign
。切勿将密钥存入已追踪文件;务必使用被git忽略的
.env
文件。

Workflow (numbered)

工作流程(编号)

1. Mockup first (design before code)

1. 先做原型(先设计后编码)

Lock the look before writing app code. Save artifacts under the injected
Visuals:
path (fall back to a temp dir only when no
Visuals:
path was injected) in a
mockup-{ts}-{app-slug}/
subdir, where
{app-slug}
is a kebab-case name for the app/feature.
  1. Brand/logo (raster): use
    marketing-design
    (
    design logo
    /
    create CIP
    ) for the mark + favicons. Engine: Codex
    gpt-image-2
    via ChatGPT, falls back to Gemini. To stay faithful to an existing logo, pass it as a reference image (
    codex exec -i <ref>
    or the cip
    --logo
    ).
  2. HTML page mockups: use
    opendesign
    for the screens (login, dashboard, tables, detail) plus an
    index.html
    gallery and ONE source-of-truth
    theme.css
    (color tokens, type scale, spacing, components). marketing-design defers HTML/dashboards to opendesign.
  3. Get approval on direction (style, screens) with concise preview options before building.
  4. Treat the approved
    theme.css
    + screens as the contract: the frontend MUST match them. Details:
    references/design-mockup-workflow.md
    .
在编写应用代码前确定视觉风格。将产物保存到注入的
Visuals:
路径下(仅当未注入
Visuals:
路径时才回退到临时目录)的
mockup-{ts}-{app-slug}/
子目录中,其中
{app-slug}
是应用/功能的短横线命名。
  1. **品牌/Logo(光栅图):**使用
    marketing-design
    design logo
    /
    create CIP
    )生成标识+网站图标。引擎:通过ChatGPT调用Codex
    gpt-image-2
    ,回退方案为Gemini。如需贴合现有Logo,请传入参考图片(
    codex exec -i <ref>
    或使用cip的
    --logo
    参数)。
  2. **HTML页面原型:**使用
    opendesign
    生成页面(登录页、仪表板、表格页、详情页),并生成一个
    index.html
    预览页和一份唯一的权威
    theme.css
    (颜色令牌、字体层级、间距、组件样式)。营销设计模块会将HTML/仪表板设计委托给开放设计模块。
  3. 在开始构建前,通过简洁的预览选项获取风格、页面设计方向的确认。
  4. 将已确认的
    theme.css
    +页面设计视为契约:前端必须严格匹配该设计。 详情:
    references/design-mockup-workflow.md

2. Scaffold the project

2. 搭建项目骨架

Run the scaffolder (idempotent, never overwrites existing files):
bash
bash scripts/scaffold.sh <project-dir> <app-name>
It creates
backend/
,
frontend/
,
docker-compose.yml
,
Makefile
,
.gitignore
,
.env.example
. Then write the real
.env
(gitignored) with DB + JWT + AWS/S3 + Google OAuth + seed creds. Structure + conventions:
references/project-structure.md
.
运行脚手架工具(幂等性,不会覆盖现有文件):
bash
bash scripts/scaffold.sh <project-dir> <app-name>
该脚本会创建
backend/
frontend/
docker-compose.yml
Makefile
.gitignore
.env.example
。 随后编写真实的
.env
文件(被git忽略),填入数据库、JWT、AWS/S3、Google OAuth以及预生成用户的凭证。 结构与规范:
references/project-structure.md

3. Build the backend (API-first)

3. 构建后端(API优先)

Implement under
backend/app/
:
apis/v1
thin routers,
services
stateless logic,
clients
I/O seams,
models
SQLModel tables,
schemas
Pydantic contracts,
core
config/db/security/exceptions/permissions,
dependencies
DI,
middleware
,
tasks/seed
. One Alembic migration per change. Auth = bcrypt + JWT (HS256) + optional Google OAuth (domain allowlist). S3 = boto3 wrapper in
clients/s3.py
. Verify:
uv sync && uv run python -c "import app.main" && uv run pytest
. Auth/RBAC/S3 patterns:
references/auth-rbac.md
.
backend/app/
下实现:
apis/v1
轻量路由、
services
无状态逻辑、
clients
IO层、
models
SQLModel数据表、
schemas
Pydantic契约、
core
配置/数据库/安全/异常/权限、
dependencies
依赖注入、
middleware
中间件、
tasks/seed
种子数据。每次变更对应一个Alembic迁移脚本。身份验证=bcrypt + JWT(HS256)+ 可选Google OAuth(域名白名单)。S3功能=在
clients/s3.py
中封装boto3。验证命令:
uv sync && uv run python -c "import app.main" && uv run pytest
。 身份验证/RBAC/S3模式:
references/auth-rbac.md

4. Build the frontend (feature slices)

4. 构建前端(功能切片)

src/app/routes
(TanStack file-based:
_protected
layout,
login
,
403/500
);
src/features/<slice>
(schemas.ts + queries.ts + components/);
src/components/{ui,layout}
;
src/lib
(api-client, query-client, permissions, utils);
src/config/env.ts
(Zod). Port the approved
theme.css
into
src/index.css
+ Tailwind tokens (map shadcn HSL vars to the brand palette). Match the mockups exactly. Verify:
npx tsc --noEmit && npm run build
.
src/app/routes
(TanStack基于文件的路由:
_protected
布局、
login
登录页、
403/500
错误页);
src/features/<slice>
(schemas.ts + queries.ts + components/组件);
src/components/{ui,layout}
src/lib
(API客户端、查询客户端、权限、工具函数);
src/config/env.ts
(Zod验证)。将已确认的
theme.css
迁移到
src/index.css
+ Tailwind令牌(将shadcn的HSL变量映射到品牌调色板)。严格匹配原型设计。验证命令:
npx tsc --noEmit && npm run build

5. Run locally with Docker Compose

5. 使用Docker Compose本地运行

make up
builds + starts postgres, then backend (migrate + seed on entrypoint), then frontend (nginx). Pick host ports that are free (
lsof -iTCP:<port>
; common conflicts with other local stacks).
make logs
,
make seed
,
make clean
(down -v resets DB). Local setup + entrypoint:
references/local-setup.md
.
make up
命令会构建并启动postgres,然后启动后端(入口处执行迁移+种子数据),最后启动前端(nginx)。选择空闲的主机端口(使用
lsof -iTCP:<port>
查询;常见冲突端口包括其他本地栈占用的端口)。
make logs
查看日志、
make seed
生成种子数据、
make clean
重置环境(down -v会重置数据库)。本地搭建与入口脚本:
references/local-setup.md

6. Seed + verify end-to-end

6. 种子数据+端到端验证

Seed deterministic test users per role. Verify the real flow in the browser via
vd:web-e2e
(scaffold
.e2e/config.json
from its compose-spa example: readyz gate, form login, persistent profile per role) - login → core feature → RBAC - and curl the API (incl. real S3 upload/delete). For frontend layout work, run desktop and mobile viewport checks against the Docker stack and verify no horizontal overflow, hidden action controls, stale bundles, or console errors. The
agent-browser
CLI works as a lighter alternative when traces aren't needed. Loop on fixes until the stack is healthy and the flow passes.
为每个角色生成确定性测试用户。通过
vd:web-e2e
在浏览器中验证完整流程(从其compose-spa示例中搭建
.e2e/config.json
:就绪检查、表单登录、每个角色的持久化配置)——登录→核心功能→RBAC验证——并通过curl调用API(包括真实的S3上传/删除)。对于前端布局工作,在Docker栈上运行桌面和移动端视口检查,验证无横向溢出、无隐藏操作控件、无陈旧包、无控制台错误。当不需要追踪信息时,
agent-browser
CLI可作为轻量替代方案。循环修复问题直到栈健康且流程验证通过。

Reusable assets

可复用资产

  • scripts/scaffold.sh
    - generates the project skeleton (run it; do not hand-create dirs).
  • references/project-structure.md
    - exact backend + frontend trees + naming conventions.
  • references/local-setup.md
    - docker-compose, Dockerfiles, entrypoint, Makefile, ports, seed.
  • references/auth-rbac.md
    - JWT + Google OAuth, role model, permission deps, S3 key scheme.
  • references/design-mockup-workflow.md
    - marketing-design + opendesign then theme port.
  • references/gotchas.md
    - the bugs that recur in this stack. READ before frontend↔backend integration.
  • references/deployment.md
    - AWS deploy: EC2+compose, SSM/Ansible, RDS, ALB, ECR, OIDC; security floor + pre-apply checklist.
  • scripts/scaffold.sh
    - 生成项目骨架(直接运行,不要手动创建目录)。
  • references/project-structure.md
    - 精确的后端+前端目录结构+命名规范。
  • references/local-setup.md
    - Docker Compose配置、Dockerfile、入口脚本、Makefile、端口配置、种子数据。
  • references/auth-rbac.md
    - JWT + Google OAuth、角色模型、权限依赖、S3密钥方案。
  • references/design-mockup-workflow.md
    - 营销设计+开放设计流程,以及主题迁移步骤。
  • references/gotchas.md
    - 该技术栈中反复出现的问题。在前后端集成前务必阅读。
  • references/deployment.md
    - AWS部署方案:EC2+Compose、SSM/Ansible、RDS、ALB、ECR、OIDC;安全基线+部署前检查清单。

Hard rules (this stack bites here; see references/gotchas.md)

硬性规则(该技术栈的常见坑点;详见references/gotchas.md)

  1. FormData uploads: never set
    Content-Type: multipart/form-data
    manually; in the axios request interceptor delete the default JSON header when
    data instanceof FormData
    so the browser sets the boundary. The backend
    UploadFile
    param name MUST match the FormData key (
    files
    /
    file
    ).
  2. Zod and the backend contract: read the backend Pydantic schema before writing the Zod schema. IDs are ints (use
    z.coerce.string()
    if the UI wants strings); use
    nullable()
    not
    optional()
    when the key is always present but may be null. A parse mismatch surfaces as "could not load".
  3. TanStack route nesting: a
    foo.tsx
    that has children (
    foo.$id.tsx
    ,
    foo.bar.tsx
    ) MUST be a layout that renders
    <Outlet/>
    ; put the page body in
    foo.index.tsx
    . Otherwise the child route renders the parent's page.
  4. Brand lockup grid: if the wordmark stacks under the icon via CSS grid, the
    .wm
    wrapper needs
    display:contents
    so the
    <b>
    /
    <span>
    become grid items, else the tagline renders inline.
  5. Ports: other local stacks squat 5173/5432/8000/8080; pick free host ports in compose and set CORS +
    VITE_API_BASE_URL
    to match the chosen frontend origin/backend port.
  6. Secrets:
    .env
    is gitignored; scan staged files for key patterns (
    AKIA…
    ,
    GOCSPX-
    ) before any push.
  7. Tables and search: every table needs loading, empty, filtered-empty, and error states, plus a body frame that keeps pagination pinned. Client-side search is only acceptable when the full result set is loaded and small; otherwise add backend
    q
    , filter, sort, limit, and offset params.
  8. Admin filters: use a compact toolbar with search plus select/dropdown filters for role, company, status, and action. Avoid long flat pill rows that wrap badly on mobile.
  9. Avatar consistency: expose
    avatar_url
    from auth/user schemas when available, capture Google
    picture
    , and render one shared Avatar primitive everywhere (topbar, profile, user tables, audit rows). Fallback initials must use one deterministic color function.
  10. Responsive verification: after login, table, profile, or shell changes, run local browser E2E in desktop and mobile widths before shipping. Check screenshots, not just typecheck/build.
  1. **FormData上传:**切勿手动设置
    Content-Type: multipart/form-data
    ;在axios请求拦截器中,当
    data instanceof FormData
    时删除默认的JSON头,让浏览器自动设置边界。后端
    UploadFile
    参数名称必须与FormData的键名一致(
    files
    /
    file
    )。
  2. **Zod与后端契约:**编写Zod schema前先阅读后端的Pydantic schema。ID为整数(如果UI需要字符串,使用
    z.coerce.string()
    );当键始终存在但可能为null时,使用
    nullable()
    而非
    optional()
    。解析不匹配会表现为“无法加载”。
  3. **TanStack路由嵌套:**包含子路由(
    foo.$id.tsx
    foo.bar.tsx
    )的
    foo.tsx
    必须是渲染
    <Outlet/>
    的布局组件;将页面内容放在
    foo.index.tsx
    中。否则子路由会渲染父组件的页面内容。
  4. **品牌标识网格布局:**如果通过CSS网格让文字标识堆叠在图标下方,
    .wm
    容器需要设置
    display:contents
    ,让
    <b>
    /
    <span>
    成为网格项,否则标语会显示为行内元素。
  5. **端口配置:**其他本地栈常占用5173/5432/8000/8080端口;在Compose中选择空闲的主机端口,并设置CORS +
    VITE_API_BASE_URL
    以匹配所选的前端源/后端端口。
  6. 密钥管理:
    .env
    文件被git忽略;在任何推送前扫描暂存文件中的密钥模式(
    AKIA…
    GOCSPX-
    )。
  7. **表格与搜索:**每个表格需要加载、空数据、过滤后空数据、错误状态,以及固定分页的主体框架。仅当完整结果集已加载且数据量较小时,才允许客户端搜索;否则需在后端添加
    q
    、过滤、排序、限制、偏移参数。
  8. **管理员筛选:**使用紧凑的工具栏,包含搜索框和角色、公司、状态、操作的下拉筛选器。避免在移动端换行严重的长条形标签行。
  9. **头像一致性:**在身份验证/用户schema中暴露
    avatar_url
    ,获取Google的
    picture
    字段,并在所有位置(顶部导航栏、个人资料、用户表格、审计记录)使用同一个共享的Avatar组件。当无头像时,使用确定性颜色函数生成首字母占位符。
  10. **响应式验证:**登录、表格、个人资料或框架变更后,在本地浏览器中运行桌面和移动端宽度的端到端测试,再进行发布。检查截图,而不仅仅是类型检查/构建结果。