# 平台总体设计(草案) > 目标:面向初学者的 OI/CSP 学习知识库 + 日常练习 + 模拟竞赛系统,并提供在线 C++ 编写/编译/调试能力。前后端分离:Next.js + C++(Drogon) + SQLite。 ## 1. 术语与核心对象 - **用户(User)**:注册/登录;拥有积分、等级、学习进度。 - **题目(Problem)**:题面、标签、难度、来源(如 CSP/NOIP/自建)。 - **提交(Submission)**:用户对题目的一次代码提交(含编译/运行结果、耗时、内存、得分)。 - **练习(Practice)**:非比赛场景的做题记录(可以直接通过 submissions 体现)。 - **错题本(WrongBook)**:用户在练习/比赛中未通过的题目集合 + 错因备注。 - **比赛(Contest)**:模拟 CSP/NOIP 的比赛;包含题目列表、开始/结束、计分规则。 - **排名(Leaderboard)**:全站积分排行、比赛排行。 - **知识库(KnowledgeBase)**:学习文章/笔记/专题目录;可关联题目。 ## 2. 技术架构 ### 2.1 前端 - Next.js(App Router) + TypeScript + Tailwind - 负责:题库/题面、编辑器页面、提交列表、错题本、排行、比赛大厅、知识库阅读 ### 2.2 后端 - Drogon (HTTP + JSON) - SQLite(单文件数据库,便于部署) - 模块分层(建议): - `controller/`:HTTP 路由 - `service/`:业务逻辑 - `repo/`:DB 访问(SQL + 映射) - `domain/`:实体与枚举 - `judge/`:编译与判题执行器(后续) ### 2.3 在线编译/运行(安全边界) - MVP:后端在临时目录中调用 `g++` 编译,并用子进程运行,使用 `ulimit`/超时 kill 做基础限制。 - 生产建议:判题/运行必须放在容器或隔离工具(如 nsjail/isolate)中;否则存在逃逸风险。 ## 3. 数据库设计(SQLite) ### 3.1 表清单 1) `users` - `id` INTEGER PK - `username` TEXT UNIQUE - `password_hash` TEXT - `created_at` INTEGER - `rating` INTEGER DEFAULT 0 (综合积分) 2) `problems` - `id` INTEGER PK - `slug` TEXT UNIQUE - `title` TEXT - `statement_md` TEXT - `difficulty` INTEGER - `source` TEXT - `created_at` INTEGER 3) `problem_tags` - `problem_id` INTEGER - `tag` TEXT - PK(`problem_id`,`tag`) 4) `submissions` - `id` INTEGER PK - `user_id` INTEGER - `problem_id` INTEGER - `language` TEXT (先支持 cpp) - `code` TEXT - `status` TEXT (Pending/Compiling/Running/AC/WA/TLE/MLE/RE/CE) - `score` INTEGER - `time_ms` INTEGER - `memory_kb` INTEGER - `created_at` INTEGER 5) `wrong_book` - `user_id` INTEGER - `problem_id` INTEGER - `last_submission_id` INTEGER - `note` TEXT - `updated_at` INTEGER - PK(`user_id`,`problem_id`) 6) `contests` - `id` INTEGER PK - `title` TEXT - `starts_at` INTEGER - `ends_at` INTEGER - `rule_json` TEXT (计分规则/罚时规则) 7) `contest_problems` - `contest_id` INTEGER - `problem_id` INTEGER - `idx` INTEGER - PK(`contest_id`,`problem_id`) 8) `contest_registrations` - `contest_id` INTEGER - `user_id` INTEGER - `registered_at` INTEGER - PK(`contest_id`,`user_id`) 9) `kb_articles` - `id` INTEGER PK - `slug` TEXT UNIQUE - `title` TEXT - `content_md` TEXT - `created_at` INTEGER 10) `kb_article_links` - `article_id` INTEGER - `problem_id` INTEGER - PK(`article_id`,`problem_id`) ### 3.2 积分/排行 - 全站排行:按 `users.rating` 降序。 - rating 更新策略(MVP): - 练习 AC:+difficulty * 常数 - 比赛:按名次发放奖励分(rule_json 可配置) > 该策略后续可替换为 ELO/Codeforces 风格。 ## 4. HTTP API 设计(v1草案) 统一前缀:`/api/v1` ### 4.1 Auth - `POST /auth/register` {username,password} - `POST /auth/login` {username,password} -> {token} - 鉴权:`Authorization: Bearer `(MVP 可用 HMAC JWT) ### 4.2 Problems - `GET /problems?tag=&difficulty=&q=&page=` - `GET /problems/:id` ### 4.3 Submissions - `POST /problems/:id/submit` {language,code} - `GET /submissions?user_id=&problem_id=&page=` - `GET /submissions/:id` ### 4.4 WrongBook - `GET /me/wrong-book` - `PATCH /me/wrong-book/:problemId` {note} - `DELETE /me/wrong-book/:problemId` ### 4.5 Contests - `GET /contests` - `GET /contests/:id` - `POST /contests/:id/register` - `GET /contests/:id/leaderboard` ### 4.6 Leaderboard - `GET /leaderboard/global` ### 4.7 Knowledge Base - `GET /kb/articles` - `GET /kb/articles/:slug` ## 5. 测试策略(TDD) - `repo` 层:用内存 SQLite(`:memory:`)+ 迁移脚本,做 CRUD 单测。 - `service` 层:对积分、错题本更新等写业务单测。 - `controller` 层:Drogon 自带测试/或以 HTTP 集成测试(启动测试服务器,发请求断言 JSON)。 ## 6. 下一步落地顺序(MVP) 1) 用户注册/登录(token) 2) 题库(只读)+ 提交记录入库 3) 在线编译(仅编译 + 返回CE/OK),再扩展到运行 4) 错题本(由 WA/未通过自动写入) 5) 积分与全站排行 6) 比赛(创建/报名/排行榜) 7) 知识库文章与题目关联