考试备考系统

Polar Sponsor
爱发电 赞助
.NET 9.0

本 skill 适用于从零搭建纯前端、零后端的刷题/备考类 H5 应用,并期望一键部署到 CloudStudio 或 COS 等静态托管服务。凡符合上述场景的考试备考工具(考研、公考、医师资格、法考、语言证书、企业培训等),均可直接复用本框架,通过前置问答配置后快速生成可运行的生产级应用。 模块清单(按需启用) 备考中心 Dashboard(默认落地页:欢迎语 + 模块入口卡) 每日一练(确定性种子抽题,按日更新) 章节刷题(按章浏览,进度按 savedAt 恢复) 模拟题 / 真题模考(计时、交卷、成

QQ( QQ).

功能概述

QQ( QQ).是一项面向实际任务的技能,主要用于Overview. 零建构,零后端,纯前端 H5 考试预览应用程序的可重复使用的蓝图.;使用它来: 为任何考试建立新的预览系统, 或者将一个主题选项概括化。

核心要点

  • 它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。
  • 使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。
  • 该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。

使用与执行

从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;

结果检查与注意事项

若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。

通用备考系统(跨考试可复用框架)

Overview

A reusable blueprint for zero-build, zero-backend, pure-frontend H5 exam-prep apps. Use it to stand up a new prep system for any exam, or to generalize a subject-specific one. It favors silent progress resume (no popups), mobile-friendly folding navigation, a structured exam-result page, and a simple single-file loading architecture (questions.json with 3-tier retry fetch). Concrete subject rules (question bank, whitelist) live in the consuming project.

When to use

  • Scaffolding a new quiz/exam-prep H5 for any subject.
  • Porting a prep tool to a new exam domain.
  • Refactoring an existing prep app toward the conventions below.
  • Wiring whitelist-based login with auto nickname display.

⛔ 前置问题(intake)= 强制第一步(每次生成新系统必问,不可跳过)

硬性规则:本 skill 被调用来「从零搭建 / 生成」一个新的备考系统时,agent 的第一条回复 MUST 是前置问题,用 AskUserQuestion 呈现下方 Q1–Q10。问询确认前,禁止读取模板、禁止写文件、禁止部署。 ⚠️ 反模式教训:曾跳过这步直接开工,导致多处凭默认猜(白名单示例账号、科目划分、模块范围都是 agent 自作主张)。无论用户多急,都必须先问;用户说「直接按默认搭」等同默认确认全部「默认值」项,但仍需先把问题列出来、拿到确认再开工。 这是本 skill 的「前置问题」约定——每次新系统都必须走一遍,不是一次性文档。

Mandatory pre-build intake (run BEFORE coding)

Before scaffolding or refactoring, collect the following. Do not start development/deployment until all required params for the chosen branch are confirmed. Use AskUserQuestion (one or several calls). Reasonable defaults may be proposed but must be marked「默认值」.

Base params (required)

# Question Why it matters
Q1 目标考试类型与名称?(考研 / 公考 / 医师资格 / 法律职业 / 语言证书 / 企业培训 / 其他) 决定科目划分、题型枚举、考点结构
Q2 需要构建多少个考试科目?各科目名称? 数据按科目组织;单科目时全局自动隐藏科目筛选框
Q3 题型清单?(单选 / 多选 / 判断 / 填空 / 简答 / 论述 / 作文 等) 客观题系统判分;主观题只展示采分点 + 参考答案,不判分
Q4 启用哪些功能模块?逐项勾选 动态隐藏未启用模块入口;关闭模块保留历史数据,仅隐藏入口

模块清单(逐项确认启用 / 关闭):

  • 备考中心 dashboard — 默认落地页(欢迎语 + 模块入口卡)
  • 知识卡 knowledge
  • 每日一练 daily
  • 章节刷题 chapter
  • 模拟题 mock
  • 真题模考 real-exam
  • 错题本 mistakes — 建议默认启用(其他模块依赖)
  • 收藏夹 favorites — 建议默认启用(其他模块依赖)

Branch params

Q6 — 白名单数据源(三选一,手机号 SHA-256 哈希比对,白名单不存明文):

  • A. 直接提供手机号清单(推荐,零运维) → 确认格式(纯文本手机号 / 含姓名);用 gen-hash.html 或 crypto.js 生成 SHA-256 哈希后写入 whitelist.json
  • B. 本地 Excel 文件 → 确认模板字段(手机号列、姓名列);人工解析后生成哈希写入 whitelist.json
  • C. 飞书在线文档 → 追问:同步周期、飞书文档链接、变更通知接收人/群;需配套定时脚本(云函数/cron),运维成本高

无论选哪种,最终生成 data/whitelist.json = { "entries": [{ "hash": "sha256hex", "name": "昵称" }] }(兼容旧格式 { "hashes": [...] })。用户登录时手机号经 SHA-256 哈希后与白名单哈希比对,昵称自动从白名单读取,无需用户手填昵称。登录弹窗副标题统一为「输入手机号(仅本地记录,不上传),系统生成你的专属学习档案」。白名单仅存哈希值,不存明文手机号(合规要求)。

Q7 — 是否需要 AI 离线预生成题目?

  • 若需要:确认各章节题量配比;交付前用 AI 工具按大纲批量生成 → 人工审核 → 导入 questions.json;运行时无 AI 调用
  • 若不需要:用户提供题库 JSON

部署方式:默认 CloudStudio sandbox(无需询问)。 用 workbuddy_cloudstudio_deploy 部署干净 dist/(只含 index.html + css/ + js/ + data/)。 仅当用户主动要求自定义域名 / 长期稳定链接时才考虑腾讯云 COS,且必须先读 references/cos-pitfalls.md(5 层 bug 链:createReadStream 空文件、CDN 忽略查询参数、裸路径死循环等)。

Optional params (sensible defaults if user skips)

# Question Default
Q8 主题色色值 / 色系? --c-primary 蓝紫渐变(可改绿/橙等)
Q9 是否提供配套材料(大纲 / 教材 / 真题 / 讲义)? 无
Q10 登录后落地页? 备考中心 dashboard(欢迎语 + 日期 + 模块入口卡);dashboard 未登录也可访问,其他模块需登录

Intake execution rules

  1. 按序逐项询问:可用 AskUserQuestion 一次性或分批问,但当前分支所需参数必须全部确认。
  2. 用户未明确的项:可给合理默认值并标注「默认值」。
  3. 信息收集完成后:输出分层 PRD + 完整前端模板 + 配套运维说明(依 Q6 选择提供对应白名单方案)。
  4. 不得跳过问询直接开发;每次使用本 skill 必须先完成前置问询。

Hard-won pitfalls (must read before coding)

15 real bugs were found and fixed in production. Read references/pitfalls.md for full root-cause + fix. Each has a copy-paste template in references/templates/. Summary:

# Bug Template / Fix
P1 Whitelist login fails on file:// + race auth-whitelist-guard.js + app openLogin guard
P2 Modal won't close (stale JS cache) CSS .hidden,[hidden]{display:none!important} + ?v=N on assets
P3 loadIndex 并发覆盖 已移除 — 无分片/IDB 即无此问题
P4 Bare App global (jsdom crash) Always QuizApp.App; never bare App
P5 knowledge.json written broken (un-escaped quotes) Generate JSON via script (json.dump), never LLM-stream
P6 Mistakes delete-not-conquer; subjective/blank leak in storage-mistake-conquer.js + quiz-submit-conquer.js
P7 Per-page subject dropdowns ≠ global selector app-global-subject.js
P8 IDB 空分片毒缓存 已移除 — 无 IndexedDB 缓存
P9 HTTP 缓存毒化 data/*.json → 硬刷新仍空 fetchJSON:{cache:'no-store'} + URL ?_=Date.now()
P10 真机错误全丢失(无 unhandledrejection 监听) app.js init 首行加全局 error/unhandledrejection 监听
P11 健康自检假阴性 已移除 — 数据一次全量加载,无需 prefetch
P12 空题静默无恢复入口 render() 空态改 state-box 含「刷新页面」「重置缓存并刷新」

| P13 | startPaper 前置操作 S(null → 白屏) | 不要提前设 S.xxx,全部走 startItems 的 opts | | P14 | 错题本收藏按钮 ReferenceError: q is not defined | wireCard 不要引用外部局部变量 q,用 rec.questionData | | P15 | 路由时未开始答题即调 stopTimer() → 崩 | stopTimer() 首行加 if(S && S.timer) 空守卫 |

Architecture template

Single namespace, IIFE modules

(function (global) {
  var App = { /* router, dashboard, login, renderUser */ };
  global.QuizApp = global.QuizApp || {};
  global.QuizApp.App = App;
})(window);

Split feature code into one file per module to keep each under ~400 lines.

Core modules

  • js/app.js — router, dashboard (备考中心, default landing page), login dialog, renderUser (top-right greeting).
  • js/idb.js — DataStore manager (loadData / getSubject / getChapter / findQuestion). Single questions.json fetch with 3-tier retry.
  • js/quiz.js — daily/chapter/mock/exam modes, renderExamComplete (result page), gradeExamSilent (exam exit guard).
  • js/knowledge.js — single-card knowledge view with localStorage progress, sidebar chapter linkage, 3D flip (pure click).
  • js/review.js — shared module for 错题本 + 收藏夹 (single-question paged view with prev/next; no chapter filter).
  • js/auth.js — phone-number whitelist login (SHA-256 hashed compare), auto nickname from whitelist.
  • js/storage.js — LocalStorage wrapper, per-user isolation prefix, progress persistence.
  • js/crypto.js — pure-JS SHA-256 for whitelist compare + user isolation prefix (template: references/templates/crypto-sha256.js).

Data model

Data.subjects[]            // e.g. one subject, or grouped by exam section
  └─ chapters[]            // chapters / units / topics
       └─ questions[]      // { id, type, question, options:[{label,text}], answer, analysis,
                            //   scoringPoints:[{score,point}], referenceAnswer }

Keep progress separate from content: persist progress to LocalStorage keyed by user + module + chapter.

Layout pattern (PC: 侧栏常驻 + 主区; 移动端: 侧栏抽屉)

Desktop: #sidebar fixed left, #main flex right. Mobile: #sidebar is a fixed left drawer triggered by #railToggle, with #railOverlay as backdrop. 章节筛选抽屉已移除——侧栏两级导航替代.

Data loading (simple, single file)

All data lives in one file: data/questions.json. DataStore.loadData() fetches it once (with 3-tier retry: cache-bust → clean URL → 800ms delayed retry) and populates Data.subjects / Data.mockPapers / Data.realPapers. The promise is cached — subsequent calls return the same result.

  • No IndexedDB, no shards, no INDEX_VER. One file, one fetch.
  • Chapters have questions arrays inline — read from DataStore.getChapter() directly.
  • Module entry: DataStore.loadData().then(...) — fire-and-forget on first call, instant after.
  • js/idb.js is ~60 lines (retry logic + query helpers). No references/architecture.md needed.
  • Do NOT use ensureSubject, ensureChapter, loadIndex, or INDEX_VER — these are removed.

备考中心 Dashboard(默认落地页)

DEFAULT_ROUTE = 'dashboard' — 登录后(及未登录时)首先进入备考中心,结构如下:

  1. 登录引导横幅(未登录时顶部显示)—「登录后解锁全部学习功能」+「立即登录」按钮。
  2. Hero 区域 — 👋 你好,{昵称} + 今日日期/星期 + 「开始每日一练 →」CTA(仅登录态)。
  3. 学习模块入口卡 — 网格展示启用的模块(含错题/收藏 badge 计数),点击进入对应模块。

关键点:

  • dashboard 未登录也可访问(展示登录引导横幅 + 模块入口);其他模块需登录。
  • 题数显示兼容骨架态:count != null ? count : questions.length(直接从 questions 数组计算)。

全局科目选择器(侧栏内,P7)

科目下拉放在 #sidebar 内(brand 下方、nav 上方),全站唯一入口。所有模块按所选科目呈现数据。

  • index.html:
  • js/app.js:App.currentSubject + getSubject()/setSubject() 是全局唯一科目来源; renderGlobalSubject() 渲染 #subjbar(