# quickform-core **Repository Path**: markets2022/quickform-core ## Basic Information - **Project Name**: quickform-core - **Description**: QuickForm 数据任务核心 SDK —— 零依赖 TypeScript,供 QuickClass 内置 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-19 - **Last Updated**: 2026-09-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: quickform, SDK, lib, Library ## README # quickform-core QuickForm 数据任务核心 SDK —— 从 QuickForm 抽取的**纯数据层**:数据任务的创建/管理 + 数据的写入/查询/导出。 **只管数据,不管展示。** 数据大屏是数据的消费者,由 QuickClass 侧 AI 对话生成,与 SDK 解耦(仅通过 `getTaskSchema` + `listRecords` 两个接口对接)。 > 标准规范:本 README 即接口标准(契约冻结 v1)。完整设计规范见 `docs/设计规范.md`。 ## 背景 - **QuickClass**:老师下载项目包本地 BAT 启动,学生教室局域网访问(Node/Next.js + Prisma + SQLite) - **QuickForm**:数据收集方法论(教师版 Flask 应用,本 SDK 的逻辑来源) - 本 SDK 把 QuickForm 的功能核心抽成可拔插件,内置进 QuickClass: 老师生成互动网页时建数据任务 → 学生提交走同源 HTTP → 课后 AI 按任务 schema 生成数据大屏 ## 场景模型 ``` 老师 → 班级 → 多个活动 → 每个活动一个网页 → 每个网页绑定一个数据任务 ``` 1. QuickClass 生成网页时调 `createTask` → 拿 `taskId` → 存入网页 meta(**关联归 QuickClass 管**) 2. 向网页注入提交组件,学生提交 POST `/api/qf/submit/{taskId}`(QC 同源路由 → SDK.submit) 3. 课后 AI 大屏:`getTaskSchema` 知道字段 → `listRecords` 拿数据 → 生成图表 ## 职责边界(勿越界) | 归属 | 职责 | |---|---| | **quickform-core SDK** | 数据任务 CRUD、数据写入/查询/计数/导出、字段校验、存储、任务开关 | | **QuickClass** | 网页↔taskId 关联(网页 meta)、HTTP 路由封装、提交组件注入、AI 大屏提示词、班级/活动/学生维度的关联查询 | SDK 无业务概念(不知道"班级""学生"是什么)。学生身份 = record 数据里的 `student_name` 字段。 ## 接口(12 个,契约冻结 v1) | 接口 | 签名 | 说明 | |---|---|---| | createTask | `createTask(name, fields?) → TaskInfo` | 建任务;fields 可选(不定义 = 自由 JSON,与 QuickForm 原版一致) | | submit | `submit(taskId, data, meta?) → QfRecord` | 写入一条;任务关闭/校验失败抛错;meta.ip 自动写 `_ip` | | getRecord | `getRecord(taskId, recordId) → QfRecord` | 读单条 | | listRecords | `listRecords(taskId, filter?, page?) → PagedRecords` | 读全部/按字段等值过滤/分页(新提交在前) | | countRecords | `countRecords(taskId, filter?) → number` | 课堂实时进度("交了 35 份还差 5 个") | | updateTask | `updateTask(taskId, {name?, fields?}) → TaskInfo` | 改名;**schema 只允许追加字段** | | deleteTask | `deleteTask(taskId)` | 删任务(级联删数据) | | setTaskStatus | `setTaskStatus(taskId, "open"\|"closed")` | 活动结束关闭收集,防课后乱提交 | | listTasks | `listTasks(keyword?, page?)` | 任务列表/关键词找回 | | clearRecords | `clearRecords(taskId)` | 清空数据重来(演示/重上场景),任务保留 | | exportCsv | `exportCsv(taskId) → string` | UTF-8 BOM CSV,Excel 直开不乱码 | | getTaskSchema | `getTaskSchema(taskId)` | **AI 大屏专用**:返回字段 schema | ### 保留字段(SDK 自动维护,读取时合并进 data) | 键 | 含义 | |---|---| | `_record_id` | 记录主键 | | `_submitted_at` | 提交时间(ISO 8601) | | `_ip` | 提交者 IP(由 QC 路由层捕获,submit meta 传入) | ## 错误码(统一,契约冻结) | 错误码 | 场景 | |---|---| | `TASK_NOT_FOUND` | 任务/记录不存在 | | `TASK_CLOSED` | 任务已关闭收集仍提交 | | `FIELD_REQUIRED` | schema 必填字段缺失 | | `FIELD_TYPE_MISMATCH` | 字段类型不匹配 / select 值不在选项内 | | `TASK_NOT_OPEN` | 预留 | | `SCHEMA_CHANGE_REJECTED` | schema 删除字段/改字段类型(只允许追加) | 所有错误抛 `QfError`(`err.code` / `err.field`)。 ## 存储适配器 SDK 内部只依赖 `StorageAdapter` 契约(`saveTask/getTask/listTasks/updateTask/deleteTask/saveRecord/getRecord/queryRecords/clearRecords`,全异步): - **MemoryAdapter**(内置):内存实现,参考实现 + 单测 - **PrismaAdapter**(QuickClass 仓内实现):见 `docs/prisma-adapter.md`,表 `qf_tasks` / `qf_records`(Prisma model `QfTask`/`QfRecord`,共用 QC 的 `prisma/dev.db`) **数据库铁律**:共用 QuickClass SQLite 文件 + `qf_` 前缀独立表。不建独立 DB(备份两份),不碰 QC 业务表(耦合)。只导出 `qf_` 前缀表即可整体迁移(为云端上报预留)。 ## QuickClass 接入方式(vendor + PR 模式) ``` gitee:markets2022/quickform-core(公开仓)← SDK 唯一源码地,打 tag ↓ cc 改完 SDK 后本地同步:拷贝 → quickclass-gitee 工作区 ↓ cc 推分支 + 提 PR(vendor 目录 + schema.prisma 追加 model + qf 路由) 管老师 review → merge PR(对她是普通 PR) ↓ QC 仓库源码含 SDK → 老师下载源码 zip 天然包含,零感知 ``` - 本仓源码拷入 QC 后位于 `src/lib/quickform-core/`,**QC 仓内只读,不许手改**(改 SDK 回本仓) - 禁止运行时自动拉取(升级丢文件/网络故障点);不发 npm 包(源码直发模式无 npm 环节) ### schema 校验规则 - 任务未定义 `fields` → 自由 JSON 不校验(QuickForm 原版行为) - 定义了 `fields` → required 必填、类型匹配、select 选项校验;**未声明的键放行**(保留灵活性) - 中途改 schema 只允许**追加**字段,删除/改名/改类型拒绝(历史数据永远可读) ## 开发 ```bash # 运行测试(Node >= 22.6,零依赖) npm test # 即:node --experimental-strip-types --test test/ ``` ``` src/ types.ts 类型与 StorageAdapter 契约 errors.ts 错误码 + QfError id.ts taskId(11 位,沿用 QuickForm 2.5 算法)/ recordId validation.ts schema 校验 + 追加-only 校验 core.ts QuickFormCore 主类(12 接口) adapters/memory.ts 内存适配器(参考实现) test/core.test.ts 全接口单测 docs/ 设计规范.md 完整设计规范 prisma-adapter.md QuickClass PrismaAdapter 实现指引 ``` ## 版本策略 - **接口契约冻结 v1**:签名不改名不删,新功能只加接口 - 每次发版打 git tag(v1.x.x),QC 仓 PR 描述登记内置版本 - 修改规范 → `docs/设计规范.md` 顶部版本号 +1 并追加变更记录