docs(packages): fix interface-shape drift in 5 adapter docs#80
Merged
docs(packages): fix interface-shape drift in 5 adapter docs#80
Conversation
4aa8cd7 to
6eb28d7
Compare
After shipping the docs in PR #76 I spot-read them and found real interface drift -- types, method signatures, and import paths that did not match the current source. These would have broken every consumer that copy-pasted the examples. The @vault-2026 technical accuracy review covered the schema sections of core-reference.md but did not cover the adapter package docs, which is where these errors sit. - EmailProvider.sendEmail: type names wrong. Doc said `sendEmail(params: SendEmailParams): Promise<SendEmailResult>`. Actual is `sendEmail(params: EmailParams): Promise<{ id: string }>`. - EmailParams field table wrong: `from` is optional not required, `to` is a single string not array, `cc`/`bcc`/`headers` do not exist in EmailParams. - Documented the full EmailProvider surface (mailing lists, subscribers, campaigns, audiences), which was omitted. - Method calls wrong: doc called `mailService.compose(...)` and `mailService.replyToThread(...)`. Actual methods are `InboxEmailService.composeEmail` and `replyToThread`. - Thread metadata update: doc said `messageCount`, schema has `unreadCount`. - BlobStorage interface signatures wrong: missing `options?` on `put` and `get`, `get` return type was `string | undefined` (actual is `BlobObject | null`), and `generateKey` was missing entirely. - Added BlobObject, BlobPutOptions, and BlobGetOptions types alongside so consumers see the full shape. - InboundAdapter.handleIncoming return type wrong: said `Promise<void>`, actual is `Promise<{ messageId, threadId }>`. - "Inbound email structure" section described a 14-field parsed form as if it were the input type. The actual InboundEmail is 4 fields: `raw: ArrayBuffer`, `from`, `to`, `headers`. The parsed fields land on the message row AFTER the adapter does parsing work. Rewrote with a clear split between input shape and parsed-form schema fields. - Classification section: `ClassificationAdapter` should be `EmailClassifier`, `summary` field does not exist on `EmailClassification` (actual fields are `tags`, `priority`). - Interface name wrong: `ClassificationAdapter` should be `EmailClassifier`. - Method signature wrong: `classify(message: ClassificationInput)` should be `classify(from: string, subject: string, body: string)`. - Result type wrong: `ClassificationResult` with `summary` field should be `EmailClassification` with `tags` and `priority` fields. - Example classifier implementation updated to the correct shape. - Worker example imported `createR2BlobStorage` and `parseInboundEmail` from the package root. Actual exports are `createR2Storage` (from `/storage` subpath) and `parseEmailHeaders` / `hashContent` (from `/parsing` subpath). Also `createR2Storage` takes `{ bucket }` config, not a raw R2Bucket. - `blobStorage.put(parsed.rawEmail)` was missing the required `key` parameter. Rewrote to use `storage.generateKey` and `storage.put(key, raw)`. - `sendEmail` example showed `to: [array]`, actual is a single string. - "Next steps" link list pointed at 5 docs at `./classification.md`, `./imap-quickstart.md`, etc. Only `./classification.md` does not exist in this package -- the rest live in other packages. Replaced with per-package npm links. - pnpm test: 609 passing across 37 files (no code change, same count as before) - pnpm typecheck: clean - pnpm lint: 0 warnings, 0 errors - oxfmt normalized the 5 modified docs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three more core docs had significant accuracy drift that would have misled consumers reading them on npm. These were NOT covered by the prior @vault-2026 schema review (which focused on core-reference.md). ## packages/core/docs/threading.md - The doc described a threading engine that matches messages to threads using In-Reply-To / References / subject fallback. That engine does not exist in the core threading module -- threading.ts only exports generateMessageId, buildReferences, and generateSnippet as header-building blocks. Thread matching is the inbound adapter's responsibility and has a TODO in threading.ts pointing to #13. - The doc claimed "subject matching within the same mailbox (configurable)". Grep for it -- no such feature exists. Subject matching is intentionally NOT part of the design because subject lines collide across unrelated conversations. - The doc claimed "Deleting a thread soft-deletes all its messages". Checked the schema: inbox_message.threadId has ON DELETE CASCADE, which is a hard-delete cascade, not soft-delete. Soft-deleting a thread (setting deletedAt) does NOT cascade to messages. Clarified. - The doc's thread model table was missing columns that exist in the schema: startedAt, updatedAt, archivedAt. Added. ## packages/core/docs/migrations.md - The doc said "13 tables across two domains" and listed 3 newsletter tables as if they were part of migrationSQL. Actually migrationSQL only contains 10 inbox tables. The 3 newsletter tables (platform_audience, platform_subscriber, broadcast_audit) are Drizzle schema exports but are NOT in migrationSQL and are not written to by any shipped service. - The newsletter table names were wrong: doc said mailing_list, subscriber, campaign. Actual names are platform_audience, platform_subscriber, broadcast_audit. - The doc said system folders are "initialized automatically" when a mailbox is created. They are not. The consumer has to explicitly call FolderService.initSystemFolders(mailboxId). - The "Conventions" section said "every table has deletedAt". Two label join tables (inbox_message_label, inbox_thread_label) do not have deletedAt because their delete semantic is direct row removal. ## packages/core/docs/newsletters.md - The entire schema section described a completely different design than what exists in newsletter.ts. The doc had tables mailing_list, subscriber, campaign with fields like status, metadata, scheduledAt, htmlBody -- none of which exist. Actual tables are platform_audience (providerListId, name, description, slug), platform_subscriber (userId, audienceId, providerSubscriberId, subscribedAt), and broadcast_audit (providerCampaignId, subject, contentHash, sentBy, audienceName, recipientCount, sentAt). - The doc described a "status lifecycle" (subscribed -> unsubscribed / bounced / complained) that does not exist because there is no status column on platform_subscriber. - The doc described a campaign lifecycle (draft -> scheduled -> sending -> sent) that does not exist because there is no status column on broadcast_audit (which is an audit log, not a campaign record). - Rewrote to accurately describe: (1) the EmailProvider surface as the authoritative API for mailing lists / subscribers / campaigns, (2) the 3 platform tables as OPTIONAL local mirror / audit tables the consumer may include in their own migrations, (3) that the provider (Resend) owns the authoritative data and the framework does not duplicate it locally by default. ## Verification - pnpm test: 609 passing - pnpm typecheck: clean - pnpm lint: 0 warnings, 0 errors - pnpm format:check: clean on modified files (.claude/settings.json is untracked session state, not part of this PR) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6e36a5d to
09a9af7
Compare
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
After shipping the docs in PR #76 I spot-read them and found real interface drift -- type names, method signatures, field tables, and import paths that did not match the current source. These would have broken every consumer that copy-pasted the examples on npm. The prior @vault-2026 technical accuracy review covered the schema sections of `core-reference.md` but did not cover the adapter package docs, which is where these bugs sit.
What was wrong
`packages/resend/docs/outbound.md`
`packages/cloudflare/docs/blob-storage.md`
`packages/cloudflare/docs/inbound.md`
`packages/workers-ai/docs/classification.md`
`packages/cloudflare/docs/quickstart.md`
Verification
Stack
Chains off `chore/package-readmes` (#76). When #76 merges this branch rebases cleanly onto main.