Repository navigation
Description
epic:#27261#1 · marchtian · session_017ihL2c5z3q4h8inrn5kwqV
Filing gate: ③ (maintainer-directed). 田騏 2026-10-30 13:15Z in the epic PM thread: 「立卡 OData v2 方言」.
Ruling-ref: 6486145005 (Tier B = declarative OData), correction 6509311454 (the v4 card built a dialect seam "so a v2 card can follow without rework"), 「同意」 2026-10-29 22:01Z (generic parts open source here; vendor-specific drivers out of this repository)
Dedupe (open AND closed): "OData v2 dialect driver-odata" → none this work (#27741 is the v4 card, closed).
Reader: the epic PM (#27261, closed) dispatches it on the maintainer's word.
type: Feature
维护者速读
- 做什么: 在
@objectstack/driver-odata现有的方言接缝上加一个 OData v2 方言,version: '2.0'的数据源就能用同一个驱动读写。v2 至今仍是 SAP Gateway / S/4HANA 大部分标准服务、旧版 Dynamics CRM(OrganizationData.svc)和 SharePoint 2013 REST 的协议。 - 放在哪: v2 是公开的协议标准(微软开放规范),不是某个厂商的扩展,所以放在本仓库的 driver-odata 里,与 v4 并列。SAP 自己的东西,比如 CSRF 令牌握手、
sap-client参数、sap:*注解,按「同意」裁定仍然留在仓库外,由厂商插件提供。 - 工作量: 约 M,主要是响应封装、
$metadata的 Association、过滤函数和字面量写法、计数参数。spec 的类型矩阵要补几种 v2 才有的 EDM 类型,所以要做契约复核。 - 需要您做的: 无。
Task
-
config.ts:versionaccepts'2.0'beside'4.0'(default stays4.0); the describe drops "Only 4.0 is shipped". -
dialect-v2.tsbesidedialect-v4.ts, behind the samedialect.tsinterface. Each bullet below is v2 first, then its v4 equivalent:- Response envelope:
{ d: { results, __count, __next } }(verbose JSON,$format=json/Accept: application/json), where v4 usesvalue/@odata.count/@odata.nextLink. - Count:
$inlinecount=allpages, where v4 uses$count=true. $metadata: EDMX 1.0 / CSDL v2. Navigation goes throughAssociation/AssociationSetwithRelationship+FromRole/ToRole, and aReferentialConstraintsits on the Association.#27745's$metadataimport must read both, so lookups come out the same.- Filter functions and literals:
substringof('x', Field)where v4 hascontains;startswith/endswithare the same.- Literals:
datetime'…',datetimeoffset'…',time'PT…',guid'…',123L,1.5M,1.0d,1.0f. $filterprecedence is unchanged; keep thenot (LIST)rule from driver-odata: a declarative OData v4 datasource driver (plugin-published id, pushdown for $filter/$orderby/$top/$skip/$count, the engine floor for the rest) — epic #27261 P2 #27741.
- Literals:
- Key predicates: typed literals in keys, for example
Orders(guid'…')andItems(1L). - Writes: the same operation set the v4 dialect supports, with v2's
MERGE/X-HTTP-Methodwhere the service needs it. Read the v4 dialect first and match its scope.
- Response envelope:
-
packages/spec/src/data/type-compat.ts:DIALECT_ALIASES.odatagains the v2-only EDM primitivesedm.datetime(→datetime) andedm.time(→time). This touches the published spec, so a contract review is owed. - Tests: a recorded v2 fixture service (Northwind's public v2 endpoint shape, the way driver-odata: a declarative OData v4 datasource driver (plugin-published id, pushdown for $filter/$orderby/$top/$skip/$count, the engine floor for the rest) — epic #27261 P2 #27741 recorded v4) runs the conformance kit (objectql: publish a driver conformance kit that out-of-repo plugin drivers run in their own CI, so a contract change here is caught there — epic #27261 P2 #27744) and the 11 shared case-sets through the v2 dialect. The
$metadataimport is pinned on a v2 document. - Guide:
content/docs/data-modeling/odata-datasources.mdxsays v2 is supported, with theversion: '2.0'line and the SAP-specific things that stay out of the repository.
Clause-②: yes (widening) expected (version accepts 2.0; the alias table grows) · Metadata-protocol: added expected (a new accepted value of version), so the changeset level follows AGENTS.md · CONTRACT_REVIEW_TIER review owed for packages/spec/src/**.
Activity
objectstack-fleet commentedon Oct 30, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 可对外的 API | none | P②
Triage: p2 ·
domain:server·area:data·pm:queue· 2026-10-30T14:04Z⛔ Not a claim.
pm:queue.Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
domain:server#4 · os-elon-musk · session_016WV4d1Np3hU7RQnA13YZcL
Claim: PM loop · 2026-10-30T14:10Z · triage first touch 6524734159
Session:
session_016WV4cykf9LVyVYxnw1NL95(card thread; seatsession_016WV4d1Np3hU7RQnA13YZcL)Account:
os-elon-muskBranch:
claude/project-thread-9mtiyfWorktree:
objectstack-issue-28125Domain:
domain:serverSeat:
domain:server#4File surface:
packages/drivers/driver-odata/**(the v2 dialect beside v4 on the #27741 dialect seam),packages/spec/src/data/type-compat.ts(DIALECT_ALIASES.odatagainsedm.datetimeandedm.timeonly), the spec field that acceptsversion: '2.0'if the dialect is selected there, regenerated spec artifacts,content/docs/data-modeling/odata-datasources.mdx, and (test-only, amended 14:23Z)packages/services/service-datasource/src/__tests__/external-object-draft-odata-metadata.test.tswith a new fixture__fixtures__/northwind-v2-metadata.xml, their tests,.changeset/*; ⛔ no otherpackages/specfile, no SAP-specific mechanics (per the 2026-10-29 ruling), no governed pathContainer & model:
M,mode:thread,model: default (TIER_DEFAULT),effort: high; contract review owed (packages/spec/src/**)Clause-②: yes (widening) —
versionaccepts2.0and the alias table grows; the dev confirms from the diffMetadata-protocol: added
Responsibility: an OData v2 service cannot be used as an external datasource; the platform path that covers it is a v2 dialect on the dialect seam the v4 card built for this purpose; reached by every deployment that points a datasource at a standard OData v2 service.
Thread-read: 6524734159
Premise: holds (card at
origin/main062a2323; #27741 closed with the dialect seam onmain)Serial constraints cleared: no open PR on the OData driver or
spec/src/data/type-compat.tsright now.objectstack-fleet commentedon Oct 30, 2026
domain:server#4 · os-elon-musk · session_016WV4cykf9LVyVYxnw1NL95
os-dev-report
{ "issue": 28125, "status": "done", "branch": "claude/project-thread-9mtiyf", "pr": "https://github.com/objectstack-ai/objectstack/pull/28177", "session": "session_016WV4cykf9LVyVYxnw1NL95", "premise_still_valid": true, "summary": "OData v2 dialect (dialect-v2.ts: odataV2Dialect, parseCsdlV2) on the #27741 dialect seam, selected by driver config version '2.0' (default stays 4.0). Every card checklist item: verbose JSON envelope (d.results/__count/__next, __metadata ETag, __deferred stubs dropped), $inlinecount, substringof + typed literals (datetime/datetimeoffset/time/guid, L/M/d/f), typed key predicates incl. composite round-trip, writes POST / MERGE tunnelled via X-HTTP-Method / DELETE, EDMX 1.0 Associations + AssociationSets read into the v4 navigation shape. spec type-compat DIALECT_ALIASES.odata gains edm.datetime->datetime and edm.time->time only. Seam gains 4 OPTIONAL members (readValue/writeValue/keyValue/updateRequest), v4 dialect untouched in behaviour. Guide odata-datasources.mdx gains an 'OData v2 services' section incl. what stays out (SAP CSRF, sap-client, sap:*). No SAP-specific mechanics. Arm/kind from the diff: Clause-② yes (widening), Metadata-protocol added; changeset driver-odata minor + spec minor.", "tests": "Before (origin/main 062a2323 sources, new tests kept): driver-odata 627 red / 732 green (the whole v4 suite), dialect-v2.test.ts unloadable; service-datasource v2 import 5 red; spec type-compat 1 red ('unknown' vs 'datetime'). After: driver-odata 1383 green (v2: case-sets 336, kit 276, recorded driver 15, dialect 24), service-datasource 1074 green, spec src/data 4591 green. In-process service gained a strict v2 mode (refuses $count, contains, bare temporal literals, PATCH). 14 ablations via scripts/ablation-replace.mjs, each red, each restored blob == HEAD; one extra control (spec alias vs service-datasource test) stayed green because service-datasource reads spec dist — the alias pin is the spec test. Finding met: kit 'temporal: every row, as stored' — a date field over v2 Edm.DateTime read as ISO datetime; fixed by reading the date under a field declared date (driver records declared field types in registerExternalObject).", "gates": "After whole-tree turbo build (exit 0): dispatch-gates --commands at head 667660ad derived 117 families, all exit 0; --ran: 117 derived, 117 run, 0 NOT-MEASURED. pnpm lint exit 0; typecheck driver-odata / service-datasource / spec exit 0. spec check:generated: 14/14 up to date. Head 15 commits behind origin/main, none touching the diff's files. CI: read from PR #28177 check-runs.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "contract_review": "owed (packages/spec/src/** touched: type-compat.ts aliases)", "surface": "within claim 6524866087 as amended by the seat (service-datasource external-object-draft-odata-metadata.test.ts + __fixtures__/northwind-v2-metadata.xml, test-only)", "mcp_calls": "0 — GitHub reads via curl through the proxy; no MCP write", "api_writes": "2 — fleet-write relay pr_create (-> #28177), this comment; git push is not a REST write", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed — the transport still sends Prefer: odata.maxpagesize on a v2 GET; v2 services ignore it (RFC 7240 §2), documented, transport untouched", "carrier: none · noted, not filed — v2 fixtures written from the services' published shape; the container cannot reach services.odata.org, so nothing was recorded live" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
domain:server#4 · os-elon-musk · session_016WV4d1Np3hU7RQnA13YZcL
ACCEPT → PR #28177 comment 6527146053 · head
667660ad· 2026-10-30T15:56Z · landing sent (contract review PASS, record 6526958904;Skills-docs: updated here, addendum 6526989624).objectstack-fleet commentedon Oct 30, 2026
domain:server#4 · os-elon-musk · session_016WV4d1Np3hU7RQnA13YZcL
Landed · 2026-10-30T16:42Z
d3598573(merge queue)completedbyFixes #28125State:
pm:dispatchedremoved in this stroke.