项目结构
了解路由、业务工作流、适配器、内容和配置分别属于哪里。
VibeAny 使用 Next.js App Router,并在展示层、应用工作流、领域逻辑和基础设施之间设置了明确边界。理解这些边界可以加快定制速度,也能避免服务商专属代码扩散到整个应用。
顶层布局
src/
app/ Next.js pages, layouts, route handlers, and global CSS
proxy.ts Locale handling, auth redirects, and API rate limits
interfaces/ HTTP, CLI, MCP, cron, and webhook adapters
features/ Presentation-facing UI and API wrappers
application/ Use cases, ports, actor context, policies, and orchestration
entities/ Pure domain models, types, and algorithms
infrastructure/ Database and provider adapters implementing application ports
shared/ Shared UI, providers, hooks, stores, types, and helpers
lib/ Low-level integration and configuration modules
i18n/ Locale messages, loaders, schemas, and validation scripts
content/blog/ Localized MDX blog content
drizzle/ Reviewed SQL migrations and Drizzle metadata
scripts/ Setup, preflight, release, and maintenance commands
tests/unit/ Fast Vitest tests
tests/integration/ Database-backed integration tests
tests/e2e/ Playwright browser tests路由
应用路由位于 src/app。支持语言环境的页面使用 src/app/[locale] segment,因此公开 URL 会以 /en、/zh 或 /es 开头。
圆括号中的 route group 只用于组织文件,不会增加 URL segment:
| 源文件 | 公开路由 |
|---|---|
src/app/[locale]/(marketing)/page.tsx | /en |
src/app/[locale]/(marketing)/pricing/page.tsx | /en/pricing |
src/app/[locale]/(auth)/signup/page.tsx | /en/signup |
src/app/[locale]/(auth)/login/page.tsx | /en/login |
src/app/[locale]/dashboard/page.tsx | /en/dashboard |
src/app/api/(billing)/payments/webhook/route.ts | /api/payments/webhook |
src/app/api/auth/[...all]/route.ts | /api/auth/* |
根文件 src/app/page.tsx 会将 / 重定向到已配置的默认语言。src/proxy.ts 负责语言路由、保护 /dashboard 和 /account,并对 API 应用速率限制。
路由文件应保持精简。在其中解析传输层输入并返回传输层响应,但要把业务决策放在应用用例中。
应用边界
entities/
纯业务规则放在这一层。这里的代码不应访问网络、数据库、文件系统或框架 API。积分发放和订阅状态类型就是其中的例子。
application/
用例负责协调用户或系统操作。Port 描述用例所需的能力,但不指定 Stripe、Creem、PostgreSQL、Resend 或其他具体服务商。
infrastructure/
适配器在这里实现应用 Port。数据库存储库、支付网关、邮件投递、存储和模型服务商都属于这一层。不要让服务商 SDK 对象泄漏到页面或领域实体中。
features/
Feature 文件夹包含面向展示层的组件、Hook、数据结构定义和轻量 API 包装层。它们可以调用应用层行为,但不应演变成第二个领域层或持久化层。
shared/
可复用 UI 和框架辅助代码放在这里。兼容 shadcn 的 UI 组件位于 src/shared/ui,components.json 会将 shadcn 的 ui alias 映射到该目录。
lib/
这个目录包含仍被广泛使用的底层集成和配置,包括身份认证、数据库设置、SEO 和产品目录。新的业务编排仍应优先使用应用 Port 和用例。
常见定制位置
| 任务 | 主要位置 |
|---|---|
| 修改产品标识、域名或支持邮箱 | src/lib/config/brand.ts |
| 重写落地页、SEO 和法律文案 | src/i18n/locales/*/marketing.json 和 legal.json |
| 调整落地页 section 顺序 | src/features/marketing/ui/home-content.tsx |
| 修改套餐、积分包和服务商 ID | src/lib/config/products.ts 和环境变量 |
| 修改颜色和主题 token | src/app/globals.css |
| 替换 Logo 和浏览器图标 | public/logo.svg 和 public/icon.svg |
| 添加本地化营销页面 | src/app/[locale]/(marketing)/<slug>/page.tsx |
| 添加共享 UI | src/shared/ui |
| 修改数据库表 | src/lib/db/schema.ts,然后生成迁移 |
| 添加服务商 | 一个应用 Port、一个基础设施适配器,以及组合装配代码 |
典型请求路径
以支付结账为例:公开路由先验证 HTTP 输入,展示层包装器调用应用用例,基础设施再选择已配置的支付网关。服务商 Webhook 进入系统后,也通过同一适配器边界完成验证和标准化;之后,应用代码记录与服务商无关的账单状态。
Next.js route
-> feature or interface adapter
-> application use case and port
-> infrastructure provider adapter
-> external provider or PostgreSQL正是因为有这层分离,切换当前启用的支付服务商时,不需要重写结账 UI 或订阅领域模型。
添加代码前
- 判断这项改动属于展示、编排、纯领域规则,还是外部副作用。
- 将代码放入负责该职责的层,而不是距离最近的现有文件。
- 在其他地方导入服务商 SDK 之前,先复用已有的应用 Port。
- 在同一边界添加聚焦的测试。
- 运行相关测试,然后在发布前执行
npm run typecheck:all和npm run build。