feat: rebuild CSP practice workflow, UX and automation

这个提交包含在:
Codex CLI
2026-02-13 15:49:05 +08:00
父节点 d33deed4c5
当前提交 e2ab522b78
修改 105 个文件,包含 15669 行新增428 行删除

查看文件

@@ -0,0 +1,48 @@
#include <catch2/catch_test_macros.hpp>
#include "csp/db/sqlite_db.h"
#include "csp/services/problem_workspace_service.h"
#include <sqlite3.h>
TEST_CASE("problem workspace service drafts and solution jobs") {
auto db = csp::db::SqliteDb::OpenMemory();
csp::db::ApplyMigrations(db);
csp::db::SeedDemoData(db);
REQUIRE(sqlite3_exec(
db.raw(),
"INSERT INTO users(username,password_salt,password_hash,created_at)"
" VALUES('tester','salt','hash',0)",
nullptr,
nullptr,
nullptr) == SQLITE_OK);
sqlite3_stmt* stmt = nullptr;
REQUIRE(sqlite3_prepare_v2(db.raw(), "SELECT id FROM problems ORDER BY id LIMIT 1",
-1, &stmt, nullptr) == SQLITE_OK);
REQUIRE(sqlite3_step(stmt) == SQLITE_ROW);
const int64_t pid = sqlite3_column_int64(stmt, 0);
sqlite3_finalize(stmt);
REQUIRE(pid > 0);
csp::services::ProblemWorkspaceService svc(db);
REQUIRE(svc.ProblemExists(pid));
svc.SaveDraft(1, pid, "cpp", "int main(){return 0;}", "1 2\n");
const auto draft = svc.GetDraft(1, pid);
REQUIRE(draft.has_value());
REQUIRE(draft->language == "cpp");
REQUIRE(draft->code.find("main") != std::string::npos);
const auto job_id = svc.CreateSolutionJob(pid, 1, 3);
REQUIRE(job_id > 0);
const auto latest = svc.GetLatestSolutionJob(pid);
REQUIRE(latest.has_value());
REQUIRE(latest->id == job_id);
REQUIRE(latest->status == "queued");
REQUIRE(latest->max_solutions == 3);
const auto solutions = svc.ListSolutions(pid);
REQUIRE(solutions.empty());
}