docs: format OneTalk DOM card collection plan

This commit is contained in:
YBF
2026-09-17 11:47:47 +08:00
parent 459a9b4b77
commit 3ab77357dd
@@ -23,21 +23,32 @@
### Task 1: DOM reader and legacy reader removal
**Files:**
- Create: `apps/chrome-extension/src/onetalk/main-page/card-observer/dom-card-reader.ts`
- Delete: `apps/chrome-extension/src/onetalk/main-page/card-observer/react-card-reader.ts`
- Modify: `apps/chrome-extension/src/onetalk/main-page/card-observer/entry.ts`
- Test: `apps/chrome-extension/test/onetalk-rendered-card-reader.test.js`
**Interfaces:**
- Produces: `readOneTalkRenderedCardFromDom(pageWindow, card): OneTalkRenderedCardObservation | null`.
- Consumes: `readConversationSelection`, `normalizeOneTalkProductUrl`, rendered-card validators and fingerprint creator.
- [ ] **Step 1: Replace Fiber fixtures with DOM fixtures and red tests.**
```js
assert.equal(readOneTalkRenderedCardFromDom(page, cardWith({ cardMessageId: "m-1", wrapperMessageId: "m-2" })), null);
assert.equal(
readOneTalkRenderedCardFromDom(
page,
cardWith({ cardMessageId: "m-1", wrapperMessageId: "m-2" }),
),
null,
);
assert.equal(readOneTalkRenderedCardFromDom(page, quoteCard({ cardType: 8 })), null);
assert.equal(readOneTalkRenderedCardFromDom(page, productCard({ rawUrl: "https://bad.example" })), null);
assert.equal(
readOneTalkRenderedCardFromDom(page, productCard({ rawUrl: "https://bad.example" })),
null,
);
```
- [ ] **Step 2: Run the focused reader test and confirm the missing DOM reader fails.**
@@ -50,7 +61,8 @@ node --experimental-strip-types --test apps/chrome-extension/test/onetalk-render
```ts
const messageId = cardMessageId ?? wrapperMessageId;
if (!messageId || (cardMessageId && wrapperMessageId && cardMessageId !== wrapperMessageId)) return null;
if (!messageId || (cardMessageId && wrapperMessageId && cardMessageId !== wrapperMessageId))
return null;
if (!sameOptionalConversation(cardInfo, wrapperInfo)) return null;
```
@@ -59,8 +71,14 @@ Construct only exact `rendered_inquiry`, `rendered_product`, or `rendered_order`
- [ ] **Step 4: Rewrite entry to scan cards and react only to DOM mutations.**
```ts
for (const card of cardsForMutation(record)) publish(readOneTalkRenderedCardFromDom(pageWindow, card));
observer.observe(document.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: ["data-expinfo", "src", "style"] });
for (const card of cardsForMutation(record))
publish(readOneTalkRenderedCardFromDom(pageWindow, card));
observer.observe(document.documentElement, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ["data-expinfo", "src", "style"],
});
```
Remove `setInterval`, wrapper rescans, React imports, and the deleted reader file.
@@ -74,18 +92,23 @@ node --experimental-strip-types --test apps/chrome-extension/test/onetalk-render
### Task 2: Remove Fiber-only base evidence from local boundaries
**Files:**
- Modify: `apps/chrome-extension/src/onetalk/page-bridge/{main.ts,model.ts}`
- Modify: `apps/chrome-extension/src/onetalk/service-worker/{rendered-card-coordinator.ts,storage.ts}`
- Test: `apps/chrome-extension/test/{onetalk-page-bridge,onetalk-rendered-card-coordinator,onetalk-sync-storage}.test.js`
**Interfaces:**
- `onetalk.page.rendered-card-observed` contains `{ channelAccountId, observations }` only.
- `OneTalkRenderedCardCoordinator.observe(observations)` persists and flushes observations without base evidence.
- [ ] **Step 1: Add bridge and ledger tests that accept an observation-only message and reject legacy base-evidence fields.**
```js
assert.deepEqual(decodeOneTalkPageMessage({ source, version, type, channelAccountId, observations }), expected);
assert.deepEqual(
decodeOneTalkPageMessage({ source, version, type, channelAccountId, observations }),
expected,
);
assert.equal("baseDirection" in pendingRecord, false);
```
@@ -113,12 +136,14 @@ node --experimental-strip-types --test apps/chrome-extension/test/onetalk-page-b
### Task 3: Remove approved server audit columns without data cleanup
**Files:**
- Modify: `apps/server/src/database/schema/onetalk.ts`
- Modify: `apps/server/src/onetalk/rendered-card-{model,repository,service}.ts`
- Create: generated `apps/server/drizzle/0015_*.sql` and matching `drizzle/meta` files
- Test: `apps/server/test/onetalk-rendered-card-{migration,repository,flow}.test.ts`
**Interfaces:**
- Stored row retains key, `renderedCardContent`, `renderedCardContentFingerprint`, `renderedCardObservedAtMs`, and `conflictCount`.
- Same content stays duplicate; different content increments `conflictCount` and returns conflict without overwriting JSON.
@@ -157,6 +182,7 @@ pnpm --filter @trade-message-center/server db:check
### Task 4: Contract-preserving integration verification
**Files:**
- Test: existing contract, read-projection, extension and server suites
- [ ] **Step 1: Add read projection regressions for all three base kinds and reject mismatched supplement kinds.**