文件
csp/docs/平台总体设计.md
2026-02-12 08:56:48 +00:00

4.9 KiB
原始文件 Blame 文件历史

平台总体设计(草案)

目标:面向初学者的 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 (综合积分)
  1. problems
  • id INTEGER PK
  • slug TEXT UNIQUE
  • title TEXT
  • statement_md TEXT
  • difficulty INTEGER
  • source TEXT
  • created_at INTEGER
  1. problem_tags
  • problem_id INTEGER
  • tag TEXT
  • PK(problem_id,tag)
  1. 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
  1. wrong_book
  • user_id INTEGER
  • problem_id INTEGER
  • last_submission_id INTEGER
  • note TEXT
  • updated_at INTEGER
  • PK(user_id,problem_id)
  1. contests
  • id INTEGER PK
  • title TEXT
  • starts_at INTEGER
  • ends_at INTEGER
  • rule_json TEXT (计分规则/罚时规则)
  1. contest_problems
  • contest_id INTEGER
  • problem_id INTEGER
  • idx INTEGER
  • PK(contest_id,problem_id)
  1. contest_registrations
  • contest_id INTEGER
  • user_id INTEGER
  • registered_at INTEGER
  • PK(contest_id,user_id)
  1. kb_articles
  • id INTEGER PK
  • slug TEXT UNIQUE
  • title TEXT
  • content_md TEXT
  • created_at INTEGER
  1. 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 <token>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 层:对积分、错题本更新等写业务单测。
  • controllerDrogon 自带测试/或以 HTTP 集成测试(启动测试服务器,发请求断言 JSON

6. 下一步落地顺序MVP

  1. 用户注册/登录token
  2. 题库(只读)+ 提交记录入库
  3. 在线编译(仅编译 + 返回CE/OK,再扩展到运行
  4. 错题本(由 WA/未通过自动写入)
  5. 积分与全站排行
  6. 比赛(创建/报名/排行榜)
  7. 知识库文章与题目关联