跳到格式说明
知序ZHIXU
首页产品说明价格与套餐文章隐私政策用户协议
登录

Data portability · v1

数据导出与迁入格式

公开的归档结构、校验规则与恢复边界。无需登录即可阅读,附纯合成资料包示例;实际迁入仍须授权、预检和确认。

目录

从应用里导出或迁入身份与权限路由与 DTO文件和恢复协议v1 公开包格式下载字段类型目录限额与合成示例下载并使用纯合成资料包清单和 JSONL 原行示例

协议版本:zhixu.data-package/v1。更新日期:2026-10-17。个人与组织导出使用同一种公开格式;本文说明归档的结构、校验规则和可恢复边界。接口基础路径为 /question-bank/data-transfers。

从应用里导出或迁入

  1. 个人空间在题库页打开“导出与迁入”;组织负责人或管理员在“服务与套餐”中打开“导出组织数据”。
  2. 选择“导出资料”,保留清单和全部数据分片、原文件;迁入时切换到“迁入资料”,先上传文件并完成预检,再核对目标空间和转换清单。
  3. 未完成的任务可在“继续任务”中读取原任务编号。结果不确定时沿用原任务重试,避免重复创建。

迁入会创建新资料,历史考试成绩和个人学习事实仅归档。目标空间、权限和容量仍须满足下文约束。普通使用者可先完成上述操作;后续章节供需要核对协议、字段或开发对接的读者查阅。

身份与权限

使用真实 Accounts JWT、scoped PAT 或 MCP OAuth Authorization: Bearer …。组织本地员工登录不能调用此接口。任务绑定实际用户、认证类型、凭据/连接/授权 ID;换凭据不会取得原任务。服务在创建、状态查询、同键回读、文件下载/Range、上传、确认、重试、每次 worker 事务重新核验当前身份、scope、组织成员/商业读取或写入权限、组织授权和冻结题库集合。包不含令牌、密码或存储地址。

个人导出包含自己可读的个人题库,可选原件、自己的练习/错题档案。组织导出需要当前 owner/admin:成员、岗位及考试需要全组织 all_banks 授权且不允许显式 bankIds。不能通过选题库隐式取得组织全量成员/考试,不能导出员工个人练习。组织保留期限制也适用于已生成的下载包;下载不会延长保留期。

导出 scopes:banks:read;原件增加 sources:read;个人 learning 增加 practice:read;成员/岗位增加 organizations:read;考试增加 organizations:read、exams:read、results:read。迁入需要 banks:write、imports:write,含发布版本增加 banks:publish,含成员/岗位增加 organizations:manage。迁入只接受 all_banks 目标授权。目标组织必须可写、无题库、无岗位、仅有现有真实 owner;个人迁入新建个人题库。

路由与 DTO

响应是直接 JSON DTO,不套 success/data。时间为 UTC ISO 字符串,byteSize 为十进制字符串。失败遵循现有异常格式 {code,message,...}。

方法与路径 输入 成功响应
POST /exports ExportInput TransferJob
GET /exports organizationId?、limit?、before? `{items:TransferJob[],nextCursor:string
GET /exports/:id TransferJob
GET /exports/:id/files `{jobId,manifest:Manifest
GET /exports/:id/files/:fileId 可选单字节 Range 200/206 文件流
POST /imports ImportInput {job:TransferJob,uploads:UploadDescriptor[]}
PUT /imports/:id/files/:fileId application/octet-stream 原始字节 {jobId,fileId,status:'uploaded',byteSize,sha256}
POST /imports/:id/preview 空 body TransferJob;异步 validating
POST /imports/:id/confirm ConfirmInput TransferJob
GET /imports/:id TransferJob
POST /:kind/:id/retry {idempotencyKey};kind=exports/imports TransferJob
POST /imports/:id/verify 空 body `{jobId,status,report:VerificationReport
type ExportInput = {
  organizationId?: string | null;
  bankIds?: string[];
  components?: ('banks'|'sources'|'members'|'positions'|'exams'|'learning')[];
  idempotencyKey: string; // 8..100 chars
}; // default components=['banks','sources']; banks is mandatory

type ImportInput = {organizationId?:string|null;manifest:Manifest;idempotencyKey:string};
type ConfirmInput = {planHash:string;confirmationToken:string;idempotencyKey:string};
type UploadDescriptor = {fileId:string;method:'PUT';url:string;
  headers:{'Content-Type':'application/octet-stream'};byteSize:string;sha256:string};
type TransferJob = {id:string;kind:'export'|'import';status:string;
  schemaVersion:'zhixu.data-package/v1';organizationId:string|null;
  progress:{stage:string;processed:number;total:number|null};snapshotAt:string|null;
  expiresAt:string;manifestHash:string|null;preview:ImportPreview|null;
  report:VerificationReport|null;error:{code:string;message:string;retryable:boolean}|null;
  createdAt:string;updatedAt:string};
type ImportPreview = {planHash:string;confirmationToken:string;expiresAt:string;
  target:{organizationId:string|null;fingerprint:string};counts:Record<string,number>;
  restorableSections:string[];archivedSections:string[];
  transformations:{code:string;count:number;message:string}[];
  blockers:{code:string;message:string}[]};
type VerificationReport = {verifiedAt:string;counts:Record<string,number>;
  restored:Record<string,number>;archived:Record<string,number>;
  transformations:{code:string;count:number;message:string}[];
  differences:{section:string;sourceRef:string;field:string}[];passed:boolean};

organizationId 省略时按现凭据/身份的默认组织,显式 null 表示个人。包内源 scope.organizationId 只作来源元数据,不选择迁入目标。members 自动带入岗位以闭合位置引用。导出分页默认20、最大100。create 同主体同类已有活跃任务会拒绝;retry/verify 按自身 job 串行,不承诺跨 job 的全局并发配额。

首次相同幂等键和相同输入回读原任务,改变 body 返回 TRANSFER_IDEMPOTENCY_CONFLICT。确认 token 有效10分钟,绑定原主体、manifest、目标 fingerprint 和当前 plan;确认重放比较完整原 body(含 token)。已经接受的相同确认不因原10分钟过去而重复执行,任务 TTL 和当前权限仍须有效。

文件和恢复协议

导出 queued → snapshotting → exporting → ready,失败为 failed。GET files 仅 ready 且未过期返回 manifest/文件,包含 delivery-only id:'manifest' 的 JSON descriptor。客户下载 manifest 和全部 JSONL.gz/原件,逐个按实际字节 SHA256 校验并保留文件。

迁入 uploading → validating → awaiting_confirmation → queued/importing → completed。POST imports 后使用返回的认证 PUT 路由上传每个文件,声明字节大小/SHA 来自 immutable manifest,服务器核实际流。确认前 POST preview 并轮询 GET;服务器再次校验全部 JSONL 和原件真实字节/摘要、schema、引用、原选项顺序/答案/版本摘要、容量、目标冲突,才能返回可执行 preview。预检不写业务行。

新确认需要严格剩余24小时+120秒以上的七天任务 TTL;不足会事务持久化 expired 后返回 TRANSFER_CONFIRMATION_TIME_WINDOW,释放创建名额,目标不变。请用新键创建任务。首次确认启动新24小时绝对执行期限。每个最多250行事务内业务行、ID map、cursor 一起提交;generation/token/lease/expiry 在入口和提交前检查。任务崩溃可沿同 job/map 有界恢复,目标题库/组织保持 restoring,完整内容、引用与文件独立再读核对通过才开放。

TRANSFER_VERIFICATION_FAILED 的已确认隔离任务,在原期限/TTL 内、当前权限仍有效时可公开 retry 新键:保留原 IDs/map,从指针和原时间 metadata 修复后再比较;若仍不符则保持隔离。已开放目标不能走此封存恢复。其他可重试失败以 error.retryable 和实际领域判断为准。过期或期限已结束的半成品保持隔离与清理保护,不承诺永久可恢复,也不会自动删业务数据。

POST verify 会排队独立的新核对,返回 verifying 和 report=null,轮询 GET import 获得本轮结果。已完成目标的 verify-only 不重新 seal,不改变开放状态;不能把上次 passed 当实时核对。

所有文件 I/O 包含开始请求到完成,最多120秒;object delete 最多10秒并保留可重试 ledger。下载返回 Content-Length、Content-Disposition、ETag(SHA)、Accept-Ranges、private/no-store。Range 支持单范围及 suffix;bytes=0-99 对8字节文件截断为0-7,首位置>=size、多范围/不安全整数/无效格式返回416及 Content-Range: bytes */size。每次恢复下载重新认证和核验保留期。

v1 公开包格式

type Manifest = {schemaVersion:'zhixu.data-package/v1';packageId:string;capturedAt:string;
  scope:{organizationId:string|null;bankIds:string[]};sections:Record<string,number>;
  restorableSections:string[];archivedSections:string[];
  omitted:{component:string;reason:string}[];files:FileDescriptor[]};
type FileDescriptor = {id:string;section:string;kind:'jsonl-gzip'|'source';filename:string;
  mimeType:string;byteSize:string;sha256:string;rowCount:number};
type JsonlRow = {section:string;sourceRef:string;record:Record<string,unknown>};

所有原 ID 为 UUID,通过 sourceRef 引用;迁入新 ID 持久映射,引用/hash 同步重算。文件名不含路径;不从包中抓取 URL,也不接受内部 objectKey。JSONL gzip 每行一个完整对象,UTF8(非法编码拒绝),必须末尾换行。字段必须完整且只来自以下白名单;可空字段以 null 表示,日期须 canonical UTC ISO(毫秒)。JSON 内容保持原值,整数/布尔值按字段类型,原字节大小为十进制字符串。

每个原件 descriptor 的 id 等于 sources.sourceRef、section=sources、rowCount=0,真实 bytes/SHA/mimeType 对应 sources 行;delivery 文件名 source-<sourceUUID>-<safe original basename> 唯一且≤255 UTF16 units,完整原 originalFilename 保留在 JSONL。manifest 自身 descriptor 不写回 manifest,避免自引用 hash。

section 精确 record 字段
banks id, name, description, status, usageMode, currentBankVersionId, workingRevision, createdAt, updatedAt
questions id, bankId, status, createdSource, currentWorkingVersionId, createdAt, updatedAt
questionVersions id, questionId, versionNo, schemaVersion, questionType, stemJson, explanationJson, answerKeyHash, optionOrderPolicy, optionOrderReason, sourceLocatorJson, contentHash, changeImpact, createdByType, createdById, changeSetId, createdAt
options id, questionId, semantic, createdAt
optionVersions id, questionVersionId, optionId, contentJson, originalPosition, contentHash, createdAt
answerKeys questionVersionId, optionIdsJson, judgeRuleVersion, createdAt
workingItems id, bankId, questionId, questionVersionId, position, included, createdAt, updatedAt
bankVersions id, bankId, versionNo, workingRevision, questionCount, contentDigest, publishedByUserId, publishedByAdminId, publishedAt
bankVersionItems id, bankVersionId, questionId, questionVersionId, position, publishedStatus, createdAt
sources id, bankId, originalFilename, mimeType, byteSize, sha256, status, uploadSource, uploadedAt, createdAt, updatedAt
positions id, name, status, createdAt, updatedAt
members id, employeeNo, displayName, department, positionId, email, phone, role, status, joinedAt, leftAt, createdAt, updatedAt
exams id, status, revision, opensAt, closesAt, configJson, poolJson, paperIdsJson, bankVersionId, participantCount, publishedAt, canceledAt, createdAt, updatedAt
examParticipations id, examId, memberId, employeeNo, displayName, department, positionSnapshotJson, status, attemptNumber, effectiveScore, startedAt, deadlineAt, submittedAt, submitReason, paperJson, answersJson, score, passed, createdAt, updatedAt
examAttempts id, participationId, attemptNumber, revision, startedAt, deadlineAt, submittedAt, submitReason, paperJson, answersJson, score, passed, createdAt
practiceSessions id, bankId, bankVersionId, mode, feedbackMode, requestedCount, actualCount, filtersJson, seed, status, revision, startedAt, submittedAt, abandonedAt, createdAt, updatedAt
sessionQuestions id, sessionId, queueIndex, questionId, questionVersionId, presentedOptionIdsJson, selectionReason, createdAt
attempts id, sessionQuestionId, sessionId, bankId, answerStatus, selectedOptionIdsJson, originalOutcome, answerKeyHash, judgeRuleVersion, clientSubmittedAt, submittedAt, createdAt
questionUserStates id, bankId, questionId, questionVersionId, totalAttempts, correctCount, incorrectCount, skippedCount, lastOutcome, lastAttemptedAt, lastWrongAt, correctStreakAfterError, masteryState, userOverride, disputed, projectionVersion, createdAt, updatedAt

前12个领域(banks 到 members,按领域依赖顺序)可恢复业务。组织考试与终态考试作答、个人练习/错题均仅保存迁入历史档案,不构造或写入正式考试/练习作答。进行中/未开始/取消的考试参与事实被 omitted 明示排除;组织导出不取员工个人学习。当前 active 授权题库闭包在同一 REPEATABLE READ 快照内选取/冻结,后续下载还核冻结 IDs 当前授权。

源 owner/admin 不映射账户或授权,普通迁入成员为 role=member;原 active/pending → pending 需重新激活,suspended/left 保持状态,原身份/角色/时间保存在 lineage。仅源 owner 与真实目标 owner 同工号时 OWNER_RECORD_ARCHIVED_COLLISION:完整源行只归档,不改工号、不建成员、不绑定 owner、不占新容量。其他工号冲突阻断。report.restored.members+report.archived.members 等于源数量。岗位名称/状态及成员位置引用按映射保留。

确认后 lineage 和 archive payload 持久保留;档案不在普通成员/考试列表,也没有独立公开 archive-read API。客户应保留完整下载包。七天结束仅清理临时 export/unconfirmed-import staging payload/交付对象;真实已恢复原件以及 confirmed lineage 保留。业务保留期清理由 lifecycle 独立契约约束;本次不提供生产业务删除入口。

下载字段类型目录

record-fields.json:19 个分区、202 个公开字段(34,120 字节,SHA256 1b16d336c24e28add9073c85e9010c192f7ce9b7f241970442e5404b0f46ad36)。它仅包含字段定义、类型、限额和说明,不含表名、内部实体、账号、客户资料或凭据。该文件是额外的格式参考,不在示例 manifest 的 files 中,不需要作为迁入分片上传。

  • fields[section] 是该分区 record 的完整必填字段名;没有列出的字段不接受。可空字段也不能省略,应显式写 null。
  • fieldTypes[section][field] 提供 type(string / integer / boolean / json)与 nullable;按字段需要增加 maxLength、unsigned、format、日期 precision/canonical。
  • 日期字段的 format=date-time 要求 canonical UTC ISO 字符串并带毫秒,例如 2026-10-14T00:00:00.000Z。原件 byteSize 的 format=unsigned-decimal 是无符号十进制字符串,不能转换为浮点数。
  • restorableSections、archivedSections 和 limits 说明 v1 分类和传输上限。它是公开字段参考,不是完整 JSON Schema;枚举、题目/答案、引用、顺序、内容摘要、目标容量和权限等语义校验仍由实际 API 的正常预检决定。

限额与合成示例

总行数1,000,000、题库10,000、文件10,000、总交付字节5GiB;manifest8MiB;每行1MiB;每 gzip 分片最多1,000行,压缩/展开分别≤16MiB;单原件≤20MiB(沿已有原件上传限额)。这些是公开上限,不代表已做满容量性能验收。导出SQL批次500、迁入事务250,七天任务 TTL、24小时执行期限、120秒 CAS lease。源文件 hold 每次最多5分钟且不超过执行绝对期限,复制后 artifact 独立,不延长组织保留期。

公共合成包包含21rows/11files:1题固定 C-A-B 顺序、A 正确身份、两版解析、working 与两个合法 published versions、纯合成原JSON。没有客户数据、账户绑定或正式作答。manifest 与各文件摘要按实际字节生成;题目、发布版本和引用图按同一规则校验。静态 ZIP 仅方便下载,客户解压后使用 manifest+files,API 不解析 ZIP 上传。

示例内容完全合成,供检查格式与在授权测试空间体验迁入。实际迁入仍须按下面步骤上传、预检、确认和核对;不会使用示例中的源标识覆盖现有题库。

下载并使用纯合成资料包

下载合成示例 ZIP(10,075 字节)。ZIP 仅用于集中下载,当前页面和 API 都不接受直接上传 ZIP。先解压,不重新压缩其中的 JSONL.gz;再选择 manifest.json 和全部 11 个数据分片/原件。

ZIP 的 SHA256:

698301b6fba92b6c55ed5118b4af2e2faaf26f90c85c31536f80a5ee813f0b18

也可以逐个保存下表文件到同一目录。浏览器可能给重名下载加后缀;迁入按实际长度和 SHA256 匹配文件,不依赖本地改名或 File.type。

文件 内容 原字节长度 SHA256
manifest.json 资料清单 4394 5b9d201897b4eacdfec575723ed02410c561923e6ed186bd5b843d7f6079ba72
part-000001.jsonl.gz banks:1 行 299 3e1409ab04086aa02f36d79e6b6efd6537a30c1a339648b9ab30c669096f02b6
part-000002.jsonl.gz sources:1 行 273 ee52dd03b464514524ccbed0fec8f969a79b67c74df7ec709dae4fddf14cba30
part-000003.jsonl.gz questions:1 行 177 7b90ee68aaf8b515105f4020efe3ef8a5a10dd1e6fa446652e5fb45b4a3744a3
part-000004.jsonl.gz options:3 行 162 a3c30a885c4438f6aaab75b9dcfc8cfda49f88792737cb39d51fc5aa3f14f625
part-000005.jsonl.gz questionVersions:2 行 660 b03fe6dc8e1cdc25a79d374e02890dd27ca9b759e443db726fb0dc094b594d7f
part-000006.jsonl.gz optionVersions:6 行 430 73ba1ce448477441896c5292f5dfe452a5e4287eeec13b929440690d63568c24
part-000007.jsonl.gz answerKeys:2 行 178 4c51dc64684048eafbb5424253b5065b5430562c473d44f8720f83d819d80f58
part-000008.jsonl.gz bankVersions:2 行 316 7c83407c6387735a6f90cb0a0aa97bd4ed94ae28b12a1d2366497f4da16f094a
part-000009.jsonl.gz bankVersionItems:2 行 195 32a358a7a1bc8f6b80c540d3265e5238376ec20e3e323f5dc9af94f43a640a09
part-000010.jsonl.gz workingItems:1 行 178 03124c4bbb7379f281228d94b1a8cfc5025481b9dcb3c13b3f7c5564fd34909e
source-00000000-0000-4000-8000-000000000003-minimal-source.json sources:0 行,原文件 151 7570b1a38b91d6777f24ac2aa9de9b5ad4a1c2f56aa0c699d50a30899250389b
  1. 登录知序,进入明确选定的个人测试空间;或使用满足空组织与服务条件、且已授权的目标组织。源 manifest 中的 scope 只是来源说明,不替你选择目标。
  2. 打开“导出与迁入”,选中解压后的 manifest.json,再多选全部数据分片和原 JSON。页面逐个核对原字节摘要并上传,不能仅上传 ZIP 或解压后的 JSONL 文本。
  3. 开始预检,等待状态进入 awaiting_confirmation。核对当前目标、转换/归档清单和 blockers;预检没有写入业务资料。通过后在十分钟内显式确认。
  4. 等待后台处理完成,读取本轮核对报告。核对 restored、archived、differences 与 passed,不能把之前的 passed 代替本轮结果。

原件与 gzip 文件的 SHA256 都计算实际文件字节。JSONL 内容或压缩参数改变,即使题目文字看似相同,文件 SHA 也可能改变;不能只修改清单中的 SHA 绕过内容、答案身份、版本和引用校验。

Linux/macOS 可对每个文件执行 shasum -a 256 文件名;Windows PowerShell 可执行 Get-FileHash -Algorithm SHA256 文件名,再与上表和 manifest 对照。题目 contentHash、answerKeyHash、题库 contentDigest 属于内容/版本校验,不是 gzip 文件 SHA,不能互换。

清单和 JSONL 原行示例

以下是下载包中真实清单;不包含令牌、账号绑定、存储地址或客户资料。生成新来源包时请以完整导出或公开示例结构为起点;是否受支持由正常预检决定,未知 schema、字段、状态或摘要不会被静默接受。

展开完整 manifest.json
{
  "schemaVersion": "zhixu.data-package/v1",
  "packageId": "00000000-0000-4000-8000-000000000100",
  "capturedAt": "2026-10-14T00:00:00.000Z",
  "scope": {
    "organizationId": null,
    "bankIds": [
      "00000000-0000-4000-8000-000000000001"
    ]
  },
  "sections": {
    "banks": 1,
    "sources": 1,
    "questions": 1,
    "options": 3,
    "questionVersions": 2,
    "optionVersions": 6,
    "answerKeys": 2,
    "bankVersions": 2,
    "bankVersionItems": 2,
    "workingItems": 1
  },
  "restorableSections": [
    "banks",
    "sources",
    "questions",
    "options",
    "questionVersions",
    "optionVersions",
    "answerKeys",
    "bankVersions",
    "bankVersionItems",
    "workingItems"
  ],
  "archivedSections": [],
  "omitted": [
    {
      "component": "members,positions,exams,learning",
      "reason": "This synthetic personal package contains no identities or activity facts"
    }
  ],
  "files": [
    {
      "id": "part-000001",
      "section": "banks",
      "kind": "jsonl-gzip",
      "filename": "part-000001.jsonl.gz",
      "mimeType": "application/gzip",
      "byteSize": "299",
      "sha256": "3e1409ab04086aa02f36d79e6b6efd6537a30c1a339648b9ab30c669096f02b6",
      "rowCount": 1
    },
    {
      "id": "part-000002",
      "section": "sources",
      "kind": "jsonl-gzip",
      "filename": "part-000002.jsonl.gz",
      "mimeType": "application/gzip",
      "byteSize": "273",
      "sha256": "ee52dd03b464514524ccbed0fec8f969a79b67c74df7ec709dae4fddf14cba30",
      "rowCount": 1
    },
    {
      "id": "part-000003",
      "section": "questions",
      "kind": "jsonl-gzip",
      "filename": "part-000003.jsonl.gz",
      "mimeType": "application/gzip",
      "byteSize": "177",
      "sha256": "7b90ee68aaf8b515105f4020efe3ef8a5a10dd1e6fa446652e5fb45b4a3744a3",
      "rowCount": 1
    },
    {
      "id": "part-000004",
      "section": "options",
      "kind": "jsonl-gzip",
      "filename": "part-000004.jsonl.gz",
      "mimeType": "application/gzip",
      "byteSize": "162",
      "sha256": "a3c30a885c4438f6aaab75b9dcfc8cfda49f88792737cb39d51fc5aa3f14f625",
      "rowCount": 3
    },
    {
      "id": "part-000005",
      "section": "questionVersions",
      "kind": "jsonl-gzip",
      "filename": "part-000005.jsonl.gz",
      "mimeType": "application/gzip",
      "byteSize": "660",
      "sha256": "b03fe6dc8e1cdc25a79d374e02890dd27ca9b759e443db726fb0dc094b594d7f",
      "rowCount": 2
    },
    {
      "id": "part-000006",
      "section": "optionVersions",
      "kind": "jsonl-gzip",
      "filename": "part-000006.jsonl.gz",
      "mimeType": "application/gzip",
      "byteSize": "430",
      "sha256": "73ba1ce448477441896c5292f5dfe452a5e4287eeec13b929440690d63568c24",
      "rowCount": 6
    },
    {
      "id": "part-000007",
      "section": "answerKeys",
      "kind": "jsonl-gzip",
      "filename": "part-000007.jsonl.gz",
      "mimeType": "application/gzip",
      "byteSize": "178",
      "sha256": "4c51dc64684048eafbb5424253b5065b5430562c473d44f8720f83d819d80f58",
      "rowCount": 2
    },
    {
      "id": "part-000008",
      "section": "bankVersions",
      "kind": "jsonl-gzip",
      "filename": "part-000008.jsonl.gz",
      "mimeType": "application/gzip",
      "byteSize": "316",
      "sha256": "7c83407c6387735a6f90cb0a0aa97bd4ed94ae28b12a1d2366497f4da16f094a",
      "rowCount": 2
    },
    {
      "id": "part-000009",
      "section": "bankVersionItems",
      "kind": "jsonl-gzip",
      "filename": "part-000009.jsonl.gz",
      "mimeType": "application/gzip",
      "byteSize": "195",
      "sha256": "32a358a7a1bc8f6b80c540d3265e5238376ec20e3e323f5dc9af94f43a640a09",
      "rowCount": 2
    },
    {
      "id": "part-000010",
      "section": "workingItems",
      "kind": "jsonl-gzip",
      "filename": "part-000010.jsonl.gz",
      "mimeType": "application/gzip",
      "byteSize": "178",
      "sha256": "03124c4bbb7379f281228d94b1a8cfc5025481b9dcb3c13b3f7c5564fd34909e",
      "rowCount": 1
    },
    {
      "id": "00000000-0000-4000-8000-000000000003",
      "section": "sources",
      "kind": "source",
      "filename": "source-00000000-0000-4000-8000-000000000003-minimal-source.json",
      "mimeType": "application/json",
      "byteSize": "151",
      "sha256": "7570b1a38b91d6777f24ac2aa9de9b5ad4a1c2f56aa0c699d50a30899250389b",
      "rowCount": 0
    }
  ]
}

下面是第一个 gzip 分片解压后唯一一行的 JSON 对象(为阅读换行显示,原 JSONL 中整条对象占一行,文件末尾为 LF):

{
  "section": "banks",
  "sourceRef": "00000000-0000-4000-8000-000000000001",
  "record": {
    "id": "00000000-0000-4000-8000-000000000001",
    "name": "迁移格式合成示例",
    "description": "纯合成资料;固定选项顺序与两版解析",
    "status": "active",
    "usageMode": "practice_and_exam",
    "currentBankVersionId": "00000000-0000-4000-8000-000000000011",
    "workingRevision": 2,
    "createdAt": "2026-10-14T00:00:00.000Z",
    "updatedAt": "2026-10-14T00:00:00.000Z"
  }
}

section 与该分片的 descriptor 一致;sourceRef 等于 record 的原主键。answerKeys 的原主键为 questionVersionId,其他分区为 id。迁入为新资源生成新 ID,并保持同包引用、题目/答案身份和发布版本闭合。选项使用 originalPosition 表示原顺序;发布/工作顺序分别用 position,不按显示字母重新排序。

示例中一个题目有两版题目内容和两个发布版本,三个选项的原顺序为 C、A、B,正确身份为 A。完整图谱已按同一题目策略和引用校验生成,不代表曾有员工完成过考试或作答。

知序ZHIXU
首页产品说明价格与套餐文章隐私政策用户协议

让题库有序,让进步可见。

成都一个蘑科技有限公司 · 2026