Šķîþ ţö ḿàîñ çöñţéñţ

Ƒ-04: Ţĥé çöñţéñţ-ḿöđéļ ŵîŕé šçĥéḿà

Šüḿḿàŕý

Ţĥé çöñţéñţ ḿöđéļ ĥàš éẋàçţļý öñé çàñöñîçàļ ŵîŕé ŕéþŕéšéñţàţîöñ: ţĥé þŕöţöƃüƒ ḿéššàĝéš îñ core/proto/content/v1/content.proto (þŕöţö þàçķàĝé neokapi.content.v1), çöñṽéŕţéđ ţö àñđ ƒŕöḿ core/model ƃý core/plugin/protoconvert. Éṽéŕý šüŕƒàçé ţĥàţ šéŕîàļîžéš Þàŕţš, Ƃļöçķš, öŕ Ŕüñš éîţĥéŕ îḿþöŕţš ţĥîš šçĥéḿà öŕ îš àñ éẋþļîçîţļý-ļàƃéļéđ þŕöĵéçţîöñ: à ļöššý, þüŕþöšé-ƃüîļţ šĥàþé ţĥàţ îš ñéṽéŕ à ḿöđéļ çöñţŕàçţ. À ĝüàŕđ ţéšţ ŕéĵéçţš ñéŵ Ƃļöçķ, Ŕüñ, öŕ Šéĝḿéñţ ḿéššàĝé đéƒîñîţîöñš öüţšîđé ţĥé çàñöñîçàļ þàçķàĝé.

Çöñţéẋţ

À çöñţéñţ ḿöđéļ ţĥàţ çŕöššéš þŕöçéšš ƃöüñđàŕîéš (þļüĝîñ šüƃþŕöçéššéš, ĝéñéŕàţéđ ƒŕöñţéñđ ţýþéš, ĴŠÖÑ öñ đîšķ) îñṽîţéš à šéçöñđ đéƒîñîţîöñ öƒ îţšéļƒ àţ éṽéŕý çŕöššîñĝ. Ţŵö đéƒîñîţîöñš đŕîƒţ, àñđ ţĥé đŕîƒţ îš šîļéñţ: éàçĥ šîđé ķééþš çöḿþîļîñĝ ŵĥîļé ţĥé ƒîéļđš ţĥéý đîšàĝŕéé àƃöüţ ǫüîéţļý ṽàñîšĥ. Ţĥé ŕéḿéđý îš à šîñĝļé đéƒîñîţîöñ þļüš à ţéšţ ţĥàţ ƒàîļš ŵĥéñ à šéçöñđ öñé àþþéàŕš.

Đéçîšîöñ

Ţĥé çàñöñîçàļ šçĥéḿà

core/proto/content/v1/content.proto đéƒîñéš ţĥé çöḿþļéţé, šýḿḿéţŕîç ḿéššàĝé šéţ ƒöŕ ţĥé ḿöđéļ: PartMessage, BlockMessage, ţĥé RunMessage đîšçŕîḿîñàţéđ üñîöñ (TextRunMessage, PlaceholderRunMessage, PcOpenRunMessage, PcCloseRunMessage, SubRunMessage, PluralRunMessage, SelectRunMessage), OverlayMessage ŵîţĥ SpanMessage / AnchorMessage / VariantMessage, SegmentMessage àñđ TargetEntry, SkeletonMessage àñđ SkeletonPartMessage, DisplayHintMessage, LayerMessage, DataMessage, GroupStartMessage àñđ GroupEndMessage, MediaMessage, AnnotationEntry, ţĥé ļîĝĥţŵéîĝĥţ ContentBlock, àñđ ContentRef.

Ţĥéšé ḿéššàĝéš àŕé þŕöṽéñ çŕöšš-ļàñĝüàĝé îñ þŕöđüçţîöñ ƃý ţĥé Ĵàṽà ƃŕîđĝé þļüĝîñ. Ķééþîñĝ ţĥéḿ îñ à đéđîçàţéđ þàçķàĝé ŕàţĥéŕ ţĥàñ îñšîđé à þļüĝîñ þŕöţö ḿàķéš ţĥé ḿöđéļ šçĥéḿà à ƒîŕšţ-çļàšš àŕţîƒàçţ ŕàţĥéŕ ţĥàñ ñöḿîñàļļý à þļüĝîñ đéţàîļ. Ţĥé ƃŕîđĝé šéŕṽîçé þŕöţö (core/plugin/proto/v2/neokapi_bridge.proto) îḿþöŕţš ţĥé çàñöñîçàļ þàçķàĝé àñđ ķééþš öñļý ţĥé BridgeService đéƒîñîţîöñ àñđ îţš ŕéǫüéšţ/ŕéšþöñšé éñṽéļöþéš; ţĥé ĝéñéŕàţéđ Ĝö þàçķàĝé ŕé-éẋþöŕţš ţĥé çöñţéñţ ţýþéš àš àļîàšéš, šö þļüĝîñ ĥöšţš çöḿþîļé üñçĥàñĝéđ.

core/plugin/protoconvert îš ţĥé çàñöñîçàļ çöñṽéŕţéŕ: éṽéŕý ḿéššàĝé ķîñđ ĥàš à šýḿḿéţŕîç XToProto / ProtoToX þàîŕ, àñđ îţš ţéšţ šüîţé (îñ þàŕţîçüļàŕ ţĥé çöḿþàţ çöŕþüš îñ core/plugin/protoconvert/compat_test.go) îš ţĥé çöḿþàţîƃîļîţý öŕàçļé. Ḿöđéļ ţö þŕöţö ţö ḿöđéļ îš îđéñţîţý ƒöŕ éṽéŕý Ŕüñ ķîñđ, ƒöŕ öṽéŕļàýš, ƒöŕ ḿüļţî-ļöçàļé ţàŕĝéţš, šéĝḿéñţàţîöñ, šķéļéţöñ ŕ郚, đîšþļàý ĥîñţš, àñđ ŕéĝîšţéŕéđ àññöţàţîöñš.

Ţĥŕéé ţĥîñĝš đö ñöţ çŕöšš ţĥîš šçĥéḿà: ţàŕĝéţ ṽàŕîàñţ ţöñé àñđ çĥàññéļ (ţàŕĝéţš àŕé ķéýéđ ƃý ļöçàļé îñ TargetEntry), þéŕ-ţàŕĝéţ šţàţüš, öŕîĝîñ, àñđ šçöŕé, àñđ ţĥé ƃļöçķ'š đüŕàƃļé Unit ķéý (Ƒ-03). À þŕöţöçöļ ţĥàţ ñééđš ţĥéḿ çàŕŕîéš ţĥéḿ îñ îţš öŵñ éñṽéļöþé ŕàţĥéŕ ţĥàñ ŵîđéñîñĝ ţĥé çàñöñîçàļ ḿéššàĝéš.

Çàñöñîçàļ ĴŠÖÑ

Ţĥé çàñöñîçàļ ĴŠÖÑ ƒöŕ ţĥé çöñţéñţ ḿöđéļ îš þŕöţöĵšöñ öƒ ţĥé çàñöñîçàļ þŕöţö, ŵîţĥ ţĥé ƒîẋéđ öþţîöñš îñ core/proto/content/v1/json.go (MarshalJSON, MarshalJSONIndent, UnmarshalJSON):

  • ļöŵéŕÇàḿéļÇàšé þŕöţöĵšöñ ĴŠÖÑ ñàḿéš (pc_open ƃéçöḿéš "pcOpen"); þŕöţö-ñàḿé šþéļļîñĝš àŕé àççéþţéđ öñ üñḿàŕšĥàļ ƃüţ ñéṽéŕ éḿîţţéđ;
  • üñþöþüļàţéđ ƒîéļđš öḿîţţéđ; ƃýţéš àš ƃàšé64 šţŕîñĝš; int32 àš ĴŠÖÑ ñüḿƃéŕš;
  • đéţéŕḿîñîšţîç öüţþüţ: þŕöţöĵšöñ ŕàñđöḿîžéš îţš ŵĥîţéšþàçé, šö ƃöţĥ ḿàŕšĥàļ ĥéļþéŕš ŕé-šéŕîàļîžé ţĥŕöüĝĥ encoding/json, ŵĥîçĥ þŕéšéŕṽéš þŕöţöĵšöñ'š šţàƃļé ƒîéļđ öŕđéŕ;
  • üñķñöŵñ ƒîéļđš îĝñöŕéđ öñ üñḿàŕšĥàļ, šö àñ öļđéŕ çöñšüḿéŕ ŕéàđš à ñéŵéŕ þŕöđüçéŕ'š öüţþüţ.

Ţĥé éñçöđîñĝ îš ļöçķéđ ƃý ĝöļđéñ ƒîļéš üñđéŕ core/proto/content/v1/testdata/: ḿàŕšĥàļļîñĝ ḿüšţ ŕéþŕöđüçé ţĥé çĥéçķéđ-îñ ƃýţéš, àñđ ţĥé çĥéçķéđ-îñ ƃýţéš ḿüšţ ķééþ đéçöđîñĝ ţö ţĥé šàḿé ḿéššàĝéš. À ƒàîļüŕé ţĥéŕé îš à ŵîŕé-çöḿþàţîƃîļîţý ƃŕéàķ, ñöţ à ƒöŕḿàţţîñĝ ñîţ.

core/model'š öŵñ ĴŠÖÑ šţŕüçţ ţàĝš ƒöļļöŵ ţĥé šàḿé çàḿéļÇàšé çöñṽéñţîöñ. model.AltTranslation.UnmarshalJSON àđđîţîöñàļļý àççéþţš ţĥé šñàķé_çàšé šþéļļîñĝ ţĥàţ ŕéļéàšéđ ƃŕîđĝé ƃüîļđš éḿîţ, ŵîţĥ çàḿéļÇàšé ŵîññîñĝ ŵĥéŕé à đöçüḿéñţ çàŕŕîéš ƃöţĥ.

Ţĥé ḿöđéļ'š îñ-þŕöçéšš Ŕüñ ĴŠÖÑ (model.Run.MarshalJSON, ƒļàţ {"text":"literal"} ţéẋţ ŕüñš) îš à đîšţîñçţ, šţàƃļé éñçöđîñĝ üšéđ îñšîđé þŕöĵéçţîöñš šüçĥ àš ţĥé çöñţéñţ ţŕéé, KBF, àñđ ƒļöŵ ţŕàçéš. Ţĥé ŵîŕé ƒöŕḿ ñéšţš ţĥé ţéẋţ þàýļöàđ àš {"text":{"text":"literal"}}. Ţĥé ţŵö àŕé ñöţ îñţéŕçĥàñĝéàƃļé, àñđ ñéîţĥéŕ îš à ƃüĝ îñ ţĥé öţĥéŕ.

Ĝéñéŕàţéđ àŕţîƒàçţš

scripts/gen-contract-types, đŕîƒţ-ĝàţéđ ƃý make check-contract-types îñ ţĥé ŕéƒéŕéñçé-đàţà-đŕîƒţ ŵöŕķƒļöŵ, đéŕîṽéš ţŵö àŕţîƒàçţš ƒŕöḿ ţĥé çàñöñîçàļ šçĥéḿà:

  • ŢýþéŠçŕîþţ ţýþéš: packages/contract-types/src/content.gen.ts: ţĥé ŵîŕé šĥàþéš àš ţĥéý àþþéàŕ îñ çàñöñîçàļ þŕöţöĵšöñ, ŕéñđéŕéđ ƒŕöḿ ţĥé þŕöţö đéšçŕîþţöŕš, ŵîţĥ RunMessage àñđ ContentRef àš đîšçŕîḿîñàţéđ üñîöñš; þļüš ţĥé model.Run ĴŠÖÑ àñđ ţĥé çöñţéñţ-ţŕéé þŕöĵéçţîöñ šĥàþéš, ŕéƒļéçţéđ ƒŕöḿ ţĥé Ĝö šţŕüçţš. Ƒŕöñţéñđ þàçķàĝéš îḿþöŕţ ţĥéšé ŕàţĥéŕ ţĥàñ ĥàñđ-ḿîŕŕöŕîñĝ ţĥé ḿöđéļ.
  • ĴŠÖÑ Šçĥéḿà: core/proto/content/v1/content.schema.json (đŕàƒţ 2020-12), ĝéñéŕàţéđ ƒŕöḿ ţĥé þŕöţö đéšçŕîþţöŕš ƒöŕ ñöñ-þŕöţö çöñšüḿéŕš. Ţĥé þŕöţöĵšöñ ĝöļđéñ ƒîļéš àŕé ţĥé ƃîñđîñĝ çöñţŕàçţ; ţĥé šçĥéḿà îš à ĝéñéŕàţéđ çöñṽéñîéñçé.

Þŕöĵéçţîöñš

À þŕöĵéçţîöñ îš à ļöššý, þüŕþöšé-ƃüîļţ šéŕîàļîžàţîöñ. Îţ ḿüšţ ƃé ļàƃéļéđ àš šüçĥ ŵĥéŕé îţ îš đéƒîñéđ, àñđ îţ îš ñéṽéŕ ţĥé ḿöđéļ çöñţŕàçţ:

  • core/editor.BlockIndex: ŕüñš ƒļàţţéñéđ ţö þļàîñ àñđ ĤŢḾĻ šţŕîñĝš ƒöŕ éđîţöŕ ļîšţîñĝš; ṽéŕšîöñéđ îñđéþéñđéñţļý ƃý îţš öŵñ ṽéŕšîöñ ƒîéļđ.
  • core/editor.ContentTree: ţĥé ŕüñ-ñàţîṽé àñàţöḿý ţŕéé ƃéĥîñđ ţĥé îñ-ƃŕöŵšéŕ éẋþļöŕéŕš.
  • core/structrec.Record: ţĥé ƒļàţ àñçĥöŕ ŕéçöŕđ ƃéĥîñđ îñšþéçţîöñ, çöñṽéŕšîöñ, àñđ ŕéţŕîéṽàļ éẋþöŕţ.

Ţĥé ƒŕàḿéŵöŕķ đéƒîñéš öñé éñṽéļöþé öƒ îţš öŵñ: ţĥé šýñç ŵîŕé, core/proto/sync/v1/sync.proto, ŵĥöšé SyncBlock àñđ SyncSegmentList àŕé àļļöŵ-ļîšţéđ îñ ţĥé ĝüàŕđ ƃý ḿéššàĝé ñàḿé. Îţ àđđš îţéḿ šçöþîñĝ, ĥàšĥéš, ţĥé ƃļöçķ'š đüŕàƃļé unit ķéý àñđ *_json éšçàþéš àŕöüñđ çàñöñîçàļ þàýļöàđš, àñđ core/venue (BlockToProto / ProtoToBlock) đéļéĝàţéš éṽéŕý ŕüñ àñđ šéĝḿéñţ çöñṽéŕšîöñ ţö protoconvert. Àñ éñṽéļöþé àđđš çöñţéẋţ àŕöüñđ çàñöñîçàļ þàýļöàđš; îţ ñéṽéŕ ŕéđéƒîñéš ţĥéḿ.

Çöḿþàţîƃîļîţý þöļîçý

  • Ƒîéļđ ñüḿƃéŕš îñ neokapi.content.v1 àŕé ƒŕöžéñ: ñéṽéŕ ŕéñüḿƃéŕéđ, ñéṽéŕ ŕéþüŕþöšéđ. Ŕéḿöṽéđ ƒîéļđš ƃéçöḿé reserved.
  • Ƒîéļđ ñàḿéš àŕé šţàƃļé, ƃéçàüšé þŕöţöĵšöñ àñđ çŕöšš-ļàñĝüàĝé þééŕš đéþéñđ öñ ţĥéḿ.
  • Ñéŵ ƒîéļđš àþþéñđ ŵîţĥ ƒŕéšĥ ñüḿƃéŕš.
  • Þŕöţö þàçķàĝé ḿöṽéš đö ñöţ àƒƒéçţ ţĥé ŵîŕé: éñçöđîñĝ đéþéñđš öñ ƒîéļđ ñüḿƃéŕš àñđ ţýþéš öñļý. Ƒüļļý-ǫüàļîƒîéđ ḿéššàĝé ñàḿéš ḿàţţéŕ šöļéļý ƒöŕ google.protobuf.Any þàçķîñĝ àñđ đéšçŕîþţöŕ-ƃàšéđ ŕéƒļéçţîöñ, ñéîţĥéŕ öƒ ŵĥîçĥ îš üšéđ öñ ţĥéšé ḿéššàĝéš, àñđ ţĥé ĝüàŕđ ţéšţ ķééþš îţ ţĥàţ ŵàý ƃý ķééþîñĝ ţĥé đéƒîñîţîöñš îñ öñé þļàçé.

Éñƒöŕçéḿéñţ

core/proto/content/guard_test.go ŵàļķš éṽéŕý .proto îñ ţĥé ŕéþöšîţöŕý àñđ ƒàîļš öñ àñý ḿéššàĝé ŵĥöšé ñàḿé đéƒîñéš Ƃļöçķ, Ŕüñ, öŕ Šéĝḿéñţ çöñţéñţ öüţšîđé ţĥé çàñöñîçàļ ƒîļé. Ţĥé ḿàţçĥ îš öñ ḿéššàĝé ñàḿéš (àñýţĥîñĝ éñđîñĝ îñ Run, Block, öŕ Segment, ƃàŕé öŕ ŵîţĥ àñ s, List, öŕ Message šüƒƒîẋ), šö à ŕéǫüéšţ/ŕéšþöñšé éñṽéļöþé ñàḿéđ SegmentRequest đöéš ñöţ ţŕîþ îţ ŵĥîļé à BlockMessage îñ ţĥé ŵŕöñĝ ƒîļé đöéš. Àĝéñţ ŵöŕķţŕééš üñđéŕ .claude àŕé šķîþþéđ, šîñçé à ŵĥöļé çĥéçķöüţ öƒ ţĥîš ŕéþöšîţöŕý îš ţĥé šàḿé ƒîļé ŕàţĥéŕ ţĥàñ à šéçöñđ đéƒîñîţîöñ öƒ îţ.

Àñ éẋþļîçîţ àļļöŵļîšţ ḿàþš à þŕöţö ƒîļé ţö ţĥé šþéçîƒîç ḿéššàĝé ñàḿéš îţ ḿàý đéƒîñé, éàçĥ éñţŕý àñ éñṽéļöþé àŕöüñđ çàñöñîçàļ þàýļöàđš. À šéçöñđ çĥéçķ ƒàîļš ŵĥéñ àñ àļļöŵļîšţéđ ḿéššàĝé đîšàþþéàŕš, šö ţĥé àļļöŵļîšţ šĥŕîñķš îñ šţéþ ŵîţĥ ţĥé çöđé ŕàţĥéŕ ţĥàñ àççüḿüļàţîñĝ šţàļé éẋéḿþţîöñš.

Çöñšéǫüéñçéš

  • Ţĥéŕé îš öñé þļàçé ţö çĥàñĝé ţĥé çöñţéñţ ḿöđéļ'š šéŕîàļîžàţîöñ, àñđ öñé ţéšţ ţĥàţ ñöţîçéš ŵĥéñ šöḿéöñé àđđš à šéçöñđ.
  • Ƒŕöñţéñđ ţýþéš àñđ ĴŠÖÑ Šçĥéḿà çàññöţ đŕîƒţ ƒŕöḿ Ĝö, ƃéçàüšé ƃöţĥ àŕé ĝéñéŕàţéđ àñđ đŕîƒţ-ĝàţéđ îñ ÇÎ.
  • À ŵîŕé-çöḿþàţîƃîļîţý ƃŕéàķ àññöüñçéš îţšéļƒ àš à ĝöļđéñ-ƒîļé ƒàîļüŕé àţ ţĥé ḿöḿéñţ öƒ ţĥé çĥàñĝé, ŕàţĥéŕ ţĥàñ àš à đéçöđé éŕŕöŕ îñ àñöţĥéŕ þŕöçéšš ŵééķš ļàţéŕ.
  • Àđđîñĝ à ƒîéļđ îš çĥéàþ àñđ šàƒé (àþþéñđ à ñüḿƃéŕ, ŕéĝéñéŕàţé), ŵĥîļé ŕéñàḿîñĝ öŕ ŕéñüḿƃéŕîñĝ öñé îš à đéļîƃéŕàţé, ṽîšîƃļé ƃŕéàķ.
  • Çöñšüḿéŕš ţĥàţ ñééđ à šĥàþé ţĥé çàñöñîçàļ šçĥéḿà đöéš ñöţ çàŕŕý ŵŕîţé à ļàƃéļéđ þŕöĵéçţîöñ îñšţéàđ öƒ ŵîđéñîñĝ ţĥé çöñţŕàçţ, ŵĥîçĥ ķééþš ţĥé çöñţŕàçţ šḿàļļ.

Šéé àļšö