11 KiB
Commit Snapshot (commits.snapshot_json) - Cấu Trúc Hiện Tại
Tài liệu này mô tả commit snapshot đang được lưu trong BackEndGo.commits.snapshot_json (JSONB) và được FrontEndAdmin tạo ra khi bấm Commit trong /editor.
Mục tiêu: nhìn vào đây là hiểu commit snapshot gồm những phần nào, ý nghĩa ra sao, và source/operation có vai trò gì.
Nguồn tham chiếu trong code:
- Type snapshot:
FrontEndAdmin/src/uhm/types/sections.ts(EditorSnapshot) - Build snapshot khi commit:
FrontEndAdmin/src/uhm/lib/editor/snapshot/editorSnapshot.ts(buildEditorSnapshot)
1) Schema tổng quan (v2)
Hiện tại snapshot mới được ghi với schema_version: 2 và đã bỏ hẳn section (vì flow BEGo đã có commits.project_id).
export type CommitSnapshotV2 = {
schema_version: 2;
// GeoJSON draft để render map + làm nguồn dựng geometries/link_scopes
editor_feature_collection?: FeatureCollection;
// Operation-based rows
entities?: EntitySnapshot[];
geometries?: GeometrySnapshot[];
link_scopes?: LinkScopeSnapshot[];
// Wiki list (tiptap JSON hoặc reference)
wikis?: WikiSnapshot[];
// Join table inside snapshot: links between entities and wikis (project-level)
entity_wikis?: EntityWikiLinkSnapshot[];
};
2) operation có những giá trị nào?
Trong commit snapshot hiện tại có 4 nơi dùng operation:
entities[].operation:
create|update|delete|reference
geometries[].operation:
create|update|delete|reference
link_scopes[].operation:
reference
wikis[].operation:
create|update|delete|reference
Ghi chú về semantics:
create/update/delete: bản ghi bị thay đổi trong commit nàyreference: bản ghi được đưa vào snapshot để làm đầu mối nối (link) (vd: geometry↔entity, entity↔wiki), không phải “không đổi”
Ngoài ra snapshot có entity_wikis[] để nối entity <-> wiki.
3) Sơ đồ trực quan (Mermaid)
classDiagram
class CommitSnapshotV2 {
+number schema_version
+FeatureCollection editor_feature_collection?
+EntitySnapshot[] entities?
+GeometrySnapshot[] geometries?
+LinkScopeSnapshot[] link_scopes?
+WikiSnapshot[] wikis?
+EntityWikiLinkSnapshot[] entity_wikis?
}
class FeatureCollection {
+string type // "FeatureCollection"
+Feature[] features
}
class Feature {
+string type // "Feature"
+FeatureProperties properties
+Geometry geometry
}
class FeatureProperties {
+string|number id
+string type?
+number time_start?
+number time_end?
+string[] binding?
+string entity_id?
+string[] entity_ids?
+string entity_name?
+string[] entity_names?
+string entity_type_id?
}
class EntitySnapshot {
+string id
+string source? // inline|ref
+Ref ref?
+string operation? // create|update|delete|reference
+string name?
+string slug?
+string description?
+string type_id?
+number status?
+number is_deleted?
+string base_updated_at?
+string base_hash?
}
class GeometrySnapshot {
+string id
+string source? // inline|ref
+Ref ref?
+string operation? // create|update|delete|reference
+string type?
+Geometry draw_geometry?
+string[] binding?
+number time_start?
+number time_end?
+BBox bbox?
+number is_deleted?
+string base_updated_at?
+string base_hash?
}
class BBox {
+number min_lng
+number min_lat
+number max_lng
+number max_lat
}
class LinkScopeSnapshot {
+string geometry_id
+string operation // reference
+string[] entity_ids
+string base_links_hash?
}
class WikiSnapshot {
+string id
+string source? // inline|ref
+Ref ref?
+string operation? // create|update|delete|reference
+string title
+any doc
+string updated_at?
+number is_deleted?
}
class EntityWikiLinkSnapshot {
+string entity_id
+string wiki_id
+string operation? // reference|delete
+number is_deleted?
}
class Ref {
+string id
}
CommitSnapshotV2 --> FeatureCollection
FeatureCollection --> Feature
Feature --> FeatureProperties
CommitSnapshotV2 --> EntitySnapshot
CommitSnapshotV2 --> GeometrySnapshot
CommitSnapshotV2 --> LinkScopeSnapshot
CommitSnapshotV2 --> WikiSnapshot
CommitSnapshotV2 --> EntityWikiLinkSnapshot
4) Ý nghĩa từng phần
4.1 (Bỏ) section
Từ schema_version: 2, snapshot không còn field section.
Nguồn chuẩn để biết commit thuộc project nào là commits.project_id (record/endpoint context), không phải snapshot.
4.2 editor_feature_collection
GeoJSON FeatureCollection là nguồn để:
- render map trong editor
- build
geometries[]+link_scopes[]khi commit
Trong thực tế, nó là “bản đồ draft state” của commit.
4.3 entities[]
entities[] là tập các entity rows kèm source/operation. Trong buildEditorSnapshot hiện tại, nó được dựng từ:
pending entitiestạo trong editor:source: "inline",operation: "create"
projectEntityRefs(entity được user “pin” vào project từ thanh search):source: "ref",ref: {id},operation: "reference"
- Các entity IDs đang được gắn vào geometries trong
editor_feature_collection(nếu chưa có trong list):source: "ref",ref: {id},operation: "reference"
- Các entity IDs xuất hiện trong
entity_wikis[]:source: "ref",ref: {id},operation: "reference"
=> Nghĩa là: entities[] trong commit snapshot hiện tại hoạt động như một “danh sách entity liên quan tới project”, không nhất thiết phải gắn vào một geometry cụ thể.
4.4 geometries[]
Mỗi Feature trong editor_feature_collection.features[] sẽ sinh ra một GeometrySnapshot row:
id:String(feature.properties.id)draw_geometry: lấy từfeature.geometrytype:feature.properties.type || getDefaultTypeIdForFeature(feature)binding: normalize từfeature.properties.bindingtime_start/time_endbbox: tính từ geometryis_deleted: 0
operation được suy ra dựa vào changes + so sánh với snapshot trước:
create: feature mớiupdate: feature thay đổi- (không có
operation): feature không đổi (không delta trong commit) delete: feature bị xoá khỏi draft (FE sẽ thêm 1 row{ id, operation:"delete", is_deleted:1 })
4.5 link_scopes[]
FE build link scopes từ GeoJSON features:
geometry_id = String(feature.properties.id)operation = "reference"entity_idslấy từfeature.properties.entity_idshoặcentity_id
Chỉ add scope nếu entity_ids.length > 0.
4.6 wikis[]
wikis[] là danh sách wiki của project tại thời điểm commit.
Type hiện tại:
export type WikiSnapshot = {
id: string;
source?: "inline" | "ref";
ref?: { id: string };
operation?: "create" | "update" | "delete" | "reference";
title: string;
doc: unknown; // tiptap JSON doc (inline) hoặc null (reference)
updated_at?: string;
is_deleted?: number;
};
Quy ước FE đang dùng:
- Wiki tạo mới trong editor:
operation: "create",doclà tiptap JSON. - Wiki sửa:
operation: "update",doclà tiptap JSON. - Wiki không đổi so với snapshot trước: thường không có
operation(không delta). - Wiki add từ thanh search (wiki đã tồn tại trong DB):
source:"ref",ref:{id},operation:"reference",doccó thể lànull.
Ghi chú quan trọng:
- Hiện tại FE chưa generate “delete rows” cho wikis (khác với geometries). Khi bạn remove một wiki khỏi list thì snapshot mới sẽ đơn giản là không còn wiki đó nữa.
4.7 entity_wikis[] (bảng nối Entity ↔ Wiki)
entity_wikis[] là bảng nối trong snapshot để thể hiện “wiki nào thuộc entity nào” ở mức project/commit.
export type EntityWikiLinkSnapshot = {
entity_id: string;
wiki_id: string;
operation?: "reference" | "delete";
is_deleted?: number;
};
FE hiện dùng panel “Entity ↔ Wiki” để toggle link:
- Tick checkbox =>
{ operation:"reference", is_deleted:0 } - Untick checkbox =>
{ operation:"delete", is_deleted:1 }
5) Ví dụ JSON (rút gọn)
Ví dụ dưới đây thể hiện:
- 1 geometry gắn entity
e_1 - 1 entity ref “pin” vào project (
e_2) dù chưa gắn geometry - 1 wiki inline và 1 wiki reference (search từ DB)
{
"schema_version": 2,
"editor_feature_collection": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"id": "g_1",
"type": "city",
"time_start": 1200,
"time_end": 1300,
"entity_ids": ["e_1"],
"entity_names": ["Ha Noi"]
},
"geometry": { "type": "Point", "coordinates": [105.8, 21.0] }
}
]
},
"entities": [
{ "id": "e_2", "operation": "reference", "name": "Pinned Entity", "is_deleted": 0 },
{ "id": "e_1", "operation": "reference", "name": "Ha Noi", "type_id": "city", "status": 1, "is_deleted": 0 }
],
"geometries": [
{
"id": "g_1",
"operation": "update",
"type": "city",
"draw_geometry": { "type": "Point", "coordinates": [105.8, 21.0] },
"binding": [],
"time_start": 1200,
"time_end": 1300,
"bbox": { "min_lng": 105.8, "min_lat": 21.0, "max_lng": 105.8, "max_lat": 21.0 },
"is_deleted": 0
}
],
"link_scopes": [{ "geometry_id": "g_1", "operation": "reference", "entity_ids": ["e_1"] }],
"wikis": [
{
"id": "w_inline_1",
"source": "inline",
"operation": "create",
"title": "Overview",
"doc": { "type": "doc", "content": [{ "type": "paragraph" }] }
},
{
"id": "019d...wiki_from_db",
"source": "ref",
"ref": { "id": "019d...wiki_from_db" },
"operation": "reference",
"title": "Existing Wiki (DB)",
"doc": null
}
],
"entity_wikis": [
{ "entity_id": "e_1", "wiki_id": "w_inline_1", "operation": "reference", "is_deleted": 0 }
]
}
6) Các điểm cần chốt khi muốn đi xa hơn với “ref”
Để source:"ref" thực sự “lấy từ bên ngoài snapshot”, cần thống nhất:
- Wiki DB format:
- BackEndGo
wikis.contenthiện làTEXT, trong khi editor wiki dùng TipTap JSON (doc). - Nếu muốn
refload content khi cần, phải chốt format lưu trữ (JSON string / HTML / Markdown).
- Semantics
operation:"reference":
referenceđược dùng theo nghĩa “đầu mối để nối (link)” và thường đi kèmsource:"ref"(ref tới DB/global).- Các bản ghi inline không thay đổi nên không có
operation(không delta).