项目:interview-platform | 版本:v1.0 | 生成日期:2026-10-05 | 依据:源码分析
面试网(interview-platform) 是一个 AI 驱动的程序员面试准备平台,将「题库练习、AI 模拟面试、竞赛评测、学习路径、数据看板」五类核心能力整合在同一产品内。项目的目标是覆盖一名程序员从「知识输入」到「实战演练」再到「薄弱补救」的完整面试备考闭环:
public/knowledge/*.md 知识库文档)。从技术形态上看,这是一个 Next.js 16 全栈单体应用:前端页面、REST API(Route Handlers)、AI 服务调用、数据访问层全部运行在同一个 Next.js 工程内,通过 Prisma 直连 PostgreSQL,以 pnpm 单仓管理。项目已从早期「单一用户 Mock 数据原型」演进为多用户平台,具备完整的认证(NextAuth v4 + 邮箱验证码注册)、RBAC 权限(Role/Permission 模型)、社区社交(关注 / 通知 / 举报 / 分享 / 收藏夹 / 题解 / 评论回复)能力。
目标用户:准备技术面试的程序员(前端 / 后端 / 算法 / 全栈方向),以及希望沉淀题库与题解内容的内容运营者(通过 /admin 后台管理题目、分类、题集、竞赛、学习路径、举报审核)。
权威事实来源说明:本项目的 AGENTS.md 与 CODE_WIKI.md 经人工校正,明确纠正了早期文档的错误认知(如「单用户无认证」「13 个数据模型」「火山方舟 AI」「本地 Docker 沙箱」「GitHub OAuth」等均为过时描述)。本套文档全部结论以 src/ 实际源码为准逐文件核验。
把三类目标用户放到具体使用旅程里,能更直观地看到产品形态:备考者的典型一天是——打开首页看今日一题与连续打卡,进入待复习区清掉艾宾浩斯到期的旧题,再按学习路径推进新章节;遇到吃不准的题先点开三级渐进提示,再进在线判题写代码验证;周末参加一场限时竞赛检验水平,考前一周用 AI 模拟面试(语音或视频模式)练表达。内容运营者则通过 /admin 后台维护题目与分类、策划精选题集、配置竞赛日程、处理举报,其工作成果(题库质量、题集编排)直接决定备考者的体验上限。两类用户通过社区(题解、评论、关注)产生连接:高质量题解既是备考者的"第二答案",也是运营者沉淀内容的抓手。
关于项目演进,仓库 docs/ 目录保留了完整的决策档案:PRD-面试平台功能增强.md、full-feature-expansion-plan.md、占位功能补全计划.md 记录了功能从规划到补全的过程,竞品调研与改进建议.md 保留了对同类产品的分析,development-handover.md 是阶段性交接文档,语音视频面试配置指南.md 与 面试题生成 SOP.md 则对应两个专项能力的落地。对照这些文档与当前源码,可以清晰看到"单用户 Mock 原型 → 认证与多用户 → 社区与内容 → 语音视频面试"的演进主线;阅读时若发现旧文档与源码冲突,一律以源码为准。
| 功能模块 | 主要页面路由 | 后端入口(节选) | 说明 |
|---|---|---|---|
| 题库练习 | /questions、/questions/[id]、/questions/new | src/app/api/questions/route.ts、src/app/api/categories/route.ts | 分类/难度/标签/题型/岗位方向多维筛选;分页、排序;题目内五个标签页(答案/代码/讨论/面试/题解) |
| 个人做题状态 | /questions/[id] | src/app/api/questions/[id]/state/route.ts | 每用户隔离的掌握度(unsolved/learning/mastered)与收藏,落在 UserQuestionState 表 |
| 渐进式提示 | /questions/[id](ProgressiveHints 组件) | src/app/api/questions/[id]/hints/route.ts | 三级 AI 提示(点拨/思路框架/详细思路),按题缓存复用控制 AI 成本 |
| 在线判题 | /questions/[id](CodeTabContent) | src/app/api/questions/[id]/submit/route.ts、src/app/api/run-code/route.ts | src/lib/judge.ts 包装用户代码后调用 Piston 在线沙箱逐用例判题,支持 JS/TS/Python/Java/C++ |
| AI 模拟面试 | /ai/mock-interview | src/app/api/mock-interview/route.ts、src/app/api/mock-interview/[id]/turn/route.ts | DeepSeek SSE 流式多轮对话;文本/语音/视频三种模式;行为面试(behavioral)走本地题库 src/lib/behavioral-questions.ts |
| 语音/视频面试 | /ai/mock-interview(video 视图) | src/app/api/video-interview/*、src/app/api/voice/asr、src/app/api/voice/tts | 火山引擎 RTC + 豆包端到端实时语音大模型(SeedRealtime);ASR/TTS 服务端代理 |
| 竞赛 | /contests、/contests/[id] | src/app/api/contests/route.ts、src/app/api/contests/[id]/submit/route.ts、src/app/api/contests/[id]/leaderboard/route.ts | 周赛/月赛/自定义赛;时间窗校验;含隐藏用例判题;部分通过按比例折算得分 |
| 学习路径 | /learning-paths、/learning-paths/[id] | src/app/api/learning-paths/route.ts、src/app/api/learning-paths/[id]/join/route.ts | 预设路线(isPreset),一键 join 转化为个人学习计划 |
| 学习计划 | /study-plans、/study-plans/[id] | src/app/api/study-plans/* | 私有计划 CRUD、按天编排题目、进度三元组(plan+user+question)唯一 |
| 试卷 | /test-papers、/test-papers/new、/test-papers/[id] | src/app/api/test-papers/* | 自定义组卷(1-100 题)、公开/私有、提交后自动判分并快照答案 |
| 精选题集 | /question-sets、/question-sets/[slug] | src/app/api/question-sets/* | 运营侧编辑的题目合集,slug 访问,浏览计数 |
| 数据看板 | /(首页即 Dashboard)、/report | src/app/api/stats/*、src/app/api/review/due/route.ts | 连续打卡、90 天热力图、能力雷达、分类/难度分布、每日一题、待复习清单 |
| 间隔复习 | 首页待复习区 | src/app/api/review/due、src/app/api/review/schedule、src/lib/review-scheduler.ts | 基于艾宾浩斯固定间隔推导复习计划,按逾期天数排序 |
| 每日一题 | 首页卡片 | src/app/api/daily-question/route.ts | 日期作确定性随机种子;登录用户优先未掌握题目 |
| 搜索 | /search(GlobalSearch 组件) | src/app/api/search/route.ts、src/app/api/search-history/* | 题目/题解/笔记聚合搜索,搜索历史与热搜词 |
| 社区 | /experiences、/users/[id] | src/app/api/follow、src/app/api/notifications、src/app/api/solutions/* | 题解发布/点赞、评论与一层回复、关注、通知(自己不通知自己)、举报、分享短链 /s/[slug] |
| 收藏夹 | /bookmarks | src/app/api/bookmarks/* | 多收藏夹组织,条目唯一约束 |
| 后台管理 | /admin/*(8 个子页) | src/app/api/admin/* | 仪表盘、题目/题集/分类/用户/举报/竞赛/学习路径管理;RBAC 权限点校验 |
| 认证 | /login、/register | src/app/api/auth/*、src/lib/auth.ts | NextAuth v4 Credentials(邮箱密码 bcrypt)+ 邮箱验证码注册(SMTP) |
| 个人设置 | /settings、/profile | src/app/api/user/route.ts、src/app/api/upload/avatar | 资料修改、头像裁剪上传(react-easy-crop + OSS)、密码修改 |
读这张表时抓住一个中枢即可纲举目张:题库(Question)是全站的数据与体验中枢。在线判题、渐进提示、竞赛、试卷、精选题集、学习路径、间隔复习、每日一题、搜索、看板统计——几乎每个模块都是围绕"题目"这一核心实体在不同维度上的组织方式(按难度组织是筛选,按时间组织是竞赛,按编排组织是试卷与路径,按记忆规律组织是复习)。用户与题目的每次交互都会沉淀为状态数据:UserQuestionState 记录掌握度、收藏与复习时间,QuestionEncounter 记录做题轨迹,复习计划则由 src/lib/review-scheduler.ts 基于复习时间与次数按艾宾浩斯固定间隔(1/2/4/7/15/30 天)推导;这些状态反过来驱动首页看板、能力雷达、每日一题的选题与待复习清单,形成"做题 → 产生状态 → 驱动推荐 → 再做题"的自增强闭环。各模块间的调用关系与时序细节见《05-核心流程》。
另一个贯穿全表的观察是AI 能力的克制使用:AI 出现在渐进提示、模拟面试、回答评分、代码点评等增强环节,但每个入口都配有成本护栏(限流、每日场次、按题缓存),行为面试等结构化内容走本地题库而非每次调模型。设计取舍的完整论述见《01-系统架构》的架构决策一节。
| 层 | 选型(版本来自 package.json) | 选型理由(结合源码分析) |
|---|---|---|
| 框架 | Next.js 16.2.7(App Router + Turbopack)、React 19.2.4、TypeScript strict | 前后端同构单体:页面与 API 同仓部署,Route Handlers 直接充当后端;Next.js 16 中间件更名为 proxy.ts(见 src/proxy.ts),params/useParams 均为 Promise 需异步解构 |
| 样式 | Tailwind CSS v4 + CSS 变量设计令牌(src/lib/design-tokens.ts、docs/design/DESIGN.md) | 令牌驱动主题:颜色统一走 var(--xxx) 与 color-mix(),暗色模式用自写 data-theme + localStorage 防闪烁内联脚本(src/app/layout.tsx),未引入 next-themes 以减小依赖 |
| ORM | Prisma 7.8(@prisma/adapter-pg 驱动适配器 + pg 连接池) | Prisma 7 新架构:客户端生成到 src/generated/prisma/,CLI 由 prisma.config.ts 驱动(seed 命令配置于 migrations.seed);类型安全的查询构建器显著降低 43 个模型的手写 SQL 成本 |
| 数据库 | PostgreSQL | 支持 String[] 数组列(如 QuestionEncounter.tags)、Json 列(codeTemplate、试卷答案快照)、@@unique 复合唯一键,契合「每用户状态隔离」的数据建模 |
| 认证 | NextAuth v4.24.14(仅 CredentialsProvider,JWT 会话) | 自建邮箱密码体系(bcryptjs 加盐哈希 + 邮箱验证码),无需第三方 OAuth;JWT 策略免除每请求查库,同时 session 回调按需回查用户保证封禁/头像实时生效 |
| AI | DeepSeek deepseek-chat(OpenAI 兼容协议,服务端 fetch 直连) | 无官方 SDK 依赖、SSE 流式原生支持(src/lib/deepseek.ts + src/lib/sse.ts);成本可控:提示按题缓存(QuestionHint 表)、模拟面试限流 + 每日场次护栏 |
| 代码执行 | Piston 公共执行 API(https://emkc.org/api/v2/piston/execute) | 免自建沙箱容器;src/lib/code-runner.ts 维护 5 种语言的版本映射,src/lib/judge.ts 15 秒超时保护 |
| 语音/视频 | 火山引擎豆包 ASR/TTS(X-Api-Key)+ RTC「AI 音视频互动」SeedRealtime(@volcengine/rtc Web SDK) | 端到端语音大模型直接驱动 AI 面试官,服务端负责 V4 签名与 Token 签发(src/lib/volcengine.ts、src/lib/video-interview.ts),密钥不下发前端 |
| 编辑器 | CodeMirror 6(@codemirror/lang-* 五语言包) | 轻量可扩展的多语言代码编辑器,覆盖判题支持的 JS/TS/Python/Java/C++ |
| 渲染/图表 | react-markdown + remark-gfm + rehype-highlight + rehype-sanitize、Mermaid、Recharts | 题目内容/题解为 Markdown;sanitize 防 XSS;Mermaid 支持题解内图表;Recharts 绘制雷达图/折线图/饼图(src/components/charts/) |
| 数据获取 | SWR 2(客户端)+ 服务端直调(页面组件内 fetch) | SWR 提供缓存/去重/重试(src/lib/swr.ts 统一 fetcher 接入 src/lib/request.ts 的 401 自动登出) |
| 校验 | zod 4(src/lib/schemas.ts + src/lib/validate.ts 的 parseBody) | 高频写接口请求体集中声明式校验,失败统一 400 + {error} |
| 存储 | 阿里云 OSS(STS 临时凭证,可选) | src/lib/oss.ts 通过 sts.assumeRole 签发 1 小时临时上传凭证;next.config.ts 配置 remotePatterns 放行 OSS 域名图片 |
| 邮件 | nodemailer(SMTP) | 注册验证码邮件;未配置 SMTP 时降级为控制台输出验证码(src/lib/mailer.ts),保证本地可联调 |
| 测试 | Vitest 4 + Testing Library + jsdom、@vitest/coverage-v8 | 覆盖率门槛锁定 src/lib/**(statements/lines 40%、functions/branches 30%),守护核心业务逻辑 |
| 工程化 | pnpm 10 workspace、ESLint 9(flat config)、husky + lint-staged、GitHub Actions CI | pre-commit 自动 eslint --fix;CI 串行 lint → typecheck → test |
| 部署 | Docker 多阶段构建(node:22-slim)+ docker-compose,容器内 prisma migrate deploy 后启动 | 单容器交付全栈应用;健康探针 /api/health 无外部依赖;以非 root node 用户运行 |
表中有三处选型体现了明显的取舍意识,值得在概览层面点明(完整论证见《01-系统架构》)。其一,"外部依赖全部可选":除 PostgreSQL 外,AI、邮件、OSS、语音视频都设计了降级路径——未配 DEEPSEEK_API_KEY 时 AI 接口返回 503 并给出配置提示,未配 SMTP 时验证码打印到控制台,OSS 未配置时头像上传不可用但不影响其余功能。这让本地开发、演示乃至最小化部署都不被第三方服务绑架。其二,Prisma 7 的新架构:客户端生成物直接进 src/generated/prisma/ 并纳入工程管理,CLI 行为由 prisma.config.ts 声明——迁移成本换来的是类型安全与驱动适配器(@prisma/adapter-pg)带来的连接池可控。其三,限流用进程内滑动窗口而非 Redis:在单容器部署的前提下,Map + 时间戳数组足够且零依赖,代价是多副本部署时需先外置——这与项目"单实例优先"的整体姿态一致。
interview-platform/
├── src/
│ ├── app/ # App Router:页面路由 + API 路由(全栈单体边界)
│ │ ├── (auth)/ # 路由分组:login/register 共用极简布局(layout.tsx)
│ │ ├── api/ # 后端 REST API:101 个 route.ts,约 49 个模块前缀
│ │ │ ├── ai/ # AI 对话(SSE)/回答评分/代码点评
│ │ │ ├── mock-interview/ # 模拟面试会话与轮次(SSE 流式)
│ │ │ ├── questions/ # 题库 CRUD + state/submit/hints/comments/solutions 子资源
│ │ │ ├── contests/ # 竞赛列表/详情/提交/排行
│ │ │ ├── stats/ # 看板聚合(基础/extended/ability/streak/report)
│ │ │ ├── review/ # 艾宾浩斯到期复习(due/schedule)
│ │ │ ├── auth/ # register/send-code/check-email + [...nextauth]
│ │ │ ├── admin/ # 后台管理(RBAC 保护)
│ │ │ └── ... # bookmarks/contests/notes/notifications/share/...
│ │ ├── questions/ # 题库页面(列表 + 详情 + tabs/ 子组件)
│ │ ├── ai/mock-interview/ # AI 模拟面试页面(1715 行,select/chat/history/video 四视图)
│ │ ├── contests/ # 竞赛列表与赛题详情页
│ │ ├── dashboard/ # 首页仪表盘拆分组件(DashboardComponents.tsx 1120 行)
│ │ ├── learning-paths/ study-plans/ test-papers/ question-sets/ # 学习与组卷
│ │ ├── companies/ experiences/ community 相关 # 公司题库/经验分享
│ │ ├── profile/ settings/ bookmarks/ notifications/ # 个人域
│ │ ├── admin/ # 后台(layout 内置侧栏导航 + role 门禁)
│ │ ├── career/ # 求职指南(服务端组件,读 public/knowledge/*.md)
│ │ ├── layout.tsx # 根布局:暗色防闪烁脚本/TopNav/PWA 注册/Umami 统计
│ │ ├── page.tsx # 首页(Dashboard,"use client" + SWR)
│ │ ├── proxy.ts # Next.js 16 中间件(原 middleware):页面级登录/admin 门禁
│ │ ├── error.tsx / global-error.tsx / not-found.tsx # 错误与 404 边界
│ │ └── robots.ts / sitemap.ts # SEO
│ ├── components/ # UI 组件库
│ │ ├── ui/ # 基础件:Button/Card/Input/Select/Modal/Toast/Table...
│ │ ├── layout/ # TopNav/ThemeToggle/MobileDrawer/UserMenu/GlobalSearch
│ │ ├── charts/ # RadarChart/ProgressLineChart/CategoryPieChart(Recharts)
│ │ ├── auth/ # AuthGuard/LoginForm/RegisterForm
│ │ └── *.tsx # 业务组件:CodeMirrorEditor/CodeRunner/VideoInterviewView/
│ │ # VoiceInput/ProgressiveHints/SolutionList/ShareDialog...
│ ├── lib/ # 服务层:后端业务与基础设施(被 Route Handlers 复用)
│ │ ├── prisma.ts # Prisma 客户端单例(开发态挂 globalThis)
│ │ ├── auth.ts / session.ts # NextAuth 配置 + requireAuth/getCurrentUser/optionalAuth
│ │ ├── permission.ts / admin-auth.ts / jwt.ts # RBAC 权限点 / 后台 Bearer JWT
│ │ ├── deepseek.ts / sse.ts # DeepSeek 调用与 SSE 解析
│ │ ├── judge.ts / code-runner.ts # 判题编排 / Piston 沙箱调用
│ │ ├── review-scheduler.ts / streak.ts # 艾宾浩斯复习 / 打卡统计(上海时区)
│ │ ├── rate-limit.ts # 进程内滑动窗口限流(单实例适用)
│ │ ├── validate.ts / schemas.ts / api-response.ts # zod 校验 / 统一响应
│ │ ├── verify-code.ts / mailer.ts # 邮箱验证码 / SMTP 降级发送
│ │ ├── volcengine.ts / volcengine-voice.ts / video-interview.ts # 语音视频凭证与签名
│ │ ├── oss.ts / oss-upload.ts # OSS STS 凭证 / 服务端上传
│ │ ├── request.ts / swr.ts # 前端请求封装(401 自动登出)/ SWR fetcher
│ │ └── notify.ts # 站内通知(自己不通知自己,失败不阻塞)
│ ├── hooks/ # useAuth/useTheme/useQuestionBasket/useSpeechRecognition...
│ ├── data/ # 题库种子数据(TS 常量,prisma/seed.ts 的数据源)
│ ├── types/ # 共享类型
│ ├── generated/prisma/ # Prisma 生成的客户端代码(禁止手改)
│ └── test/setup.ts # Vitest 全局 setup
├── prisma/
│ ├── schema.prisma # 43 个数据模型(单一事实来源)
│ ├── migrations/ # 22 个迁移目录(含 per-user 状态迁移、RBAC、索引优化)
│ └── seed.ts # 幂等种子脚本:分类 upsert、题目按 title 去重导入
├── public/ # 静态资源:manifest.json(PWA)、sw.js(Service Worker)、
│ # knowledge/(求职指南 Markdown)、icons/
├── docs/ # 历史设计文档(PRD、移动端适配方案、语音视频配置指南等)
├── .github/workflows/ci.yml # CI:install --frozen-lockfile → lint → typecheck → test:run
├── Dockerfile / docker-compose.yml # 多阶段构建 + 单容器编排(端口 4300)
├── next.config.ts # 安全响应头 / CSP-Report-Only / OSS 图片域 / ali-oss 外置
├── prisma.config.ts # Prisma 7 CLI 配置(schema/迁移/seed/datasource)
└── vitest.config.ts # jsdom 环境 + src/lib 覆盖率阈值这份目录的分层约定是理解代码组织的关键:src/app/api/**/route.ts 全部是薄控制器,只做参数提取、鉴权(requireAuth/requirePermission)、限流(rateLimit())、校验(parseBody)四件事,业务逻辑下沉到 src/lib/ 服务层——因此找业务实现先看 lib,找路由契约才看 api;src/components/ 按 ui/(与业务无关的基础件)、layout/(导航外壳)、charts/(图表封装)与根级业务组件四层组织,避免组件互相越界引用;prisma/schema.prisma 是数据结构的单一事实来源,src/generated/prisma/ 为生成物严禁手改,src/data/ 的题库常量仅作为 seed 的数据源而不参与运行时。掌握这些约定后,新增一个业务模块的路径是固定的:schema 加模型 → 迁移 → lib 加服务 → api 加路由 → 页面消费。
环境要求:Node.js 20+(Docker 镜像使用 22)、PostgreSQL、pnpm 10(packageManager 字段已锁定 pnpm@10.34.5)。AI、邮件、OSS、语音视频均为可选外部依赖:只配 DATABASE_URL + AUTH_SECRET 即可启动站点,AI 相关接口会返回 503 并提示配置 DEEPSEEK_API_KEY。
# 1. 安装依赖
pnpm install
# 2. 配置环境变量(复制示例并填写;最少需要 DATABASE_URL、AUTH_SECRET)
cp .env.example .env.local
# 3. 生成 Prisma 客户端并执行迁移(生成物在 src/generated/prisma/)
pnpm prisma generate
pnpm db:migrate # 即 prisma migrate dev
# 4.(可选)填充种子数据:领域分类 + 四大题库题目 + 示例题集/学习路径
pnpm prisma db seed
# 5. 启动开发服务器(Turbopack),访问 http://localhost:3000
pnpm dev常用脚本(package.json scripts):pnpm build / pnpm start(生产)、pnpm lint、pnpm typecheck、pnpm test:run、pnpm test:coverage、pnpm db:studio(Prisma Studio 可视化查库)。提交代码时 husky pre-commit 钩子会对暂存文件自动执行 eslint --fix;推送后 GitHub Actions 按「安装 → Lint → 类型检查 → 单测」流水线验证(.github/workflows/ci.yml)。Docker 部署方式与生产环境变量清单见本套文档第 06 篇。
CODE_WIKI.md 第 3/4 节的 lib/API 索引表。本套文档共 7 篇,全部结论均来自对 src/、prisma/、根配置文件与 CI/Docker 脚本的逐一核验;个别无法从源码确认的事项以「⚠️ 待确认」标注。