feat: close DingTalk delivery audit lifecycle #4

Merged
zheromiku merged 1 commits from feature/message-delivery-audit into main 2026-07-21 12:56:54 +08:00
Owner

Summary

  • add PostgreSQL delivery audit fields, constraints, and tenant/status index
  • transition generated assistant messages to sent/card, sent/markdown, or failed/channel_delivery_failed after real DingTalk delivery
  • expose answer message identity and delivery status on new and replayed QA results
  • suppress already-sent replay delivery on non-streaming and pre-card-failure fallback paths

Data integrity and security

  • PostgreSQL generates delivered_at with NOW()
  • delivery updates require tenant, channel, answer_message_id, and turn correlation match
  • sent cannot be downgraded to failed; failed can be upgraded to sent for a future retry
  • no sessionWebhook, token, raw API response, or raw error text is persisted
  • audit write failures do not turn a successful channel send into a retry/duplicate delivery

Verification

  • target tests: 6 packages, 275 passed, 0 failed
  • go vet on the same 6 packages: PASS
  • git diff --check: PASS
  • independent read-only review: PASS (0 security issues, 0 logic errors)
  • PostgreSQL 16.14 isolated rehearsal: up twice, schema contract, delivery state machine, down preservation, down/up twice, and temporary DB cleanup all PASS

Known limitations

  • production event streaming starts a card before AskEvents; concurrent/redelivered callbacks can still create a duplicate processing card before replay status is known
  • delivery audit write failures are safely logged but do not yet have an asynchronous compensation/retry queue

Not performed

  • not merged
  • not deployed
  • production database remains on the B1.1 schema; migration 000004 has not been applied
## Summary - add PostgreSQL delivery audit fields, constraints, and tenant/status index - transition generated assistant messages to sent/card, sent/markdown, or failed/channel_delivery_failed after real DingTalk delivery - expose answer message identity and delivery status on new and replayed QA results - suppress already-sent replay delivery on non-streaming and pre-card-failure fallback paths ## Data integrity and security - PostgreSQL generates delivered_at with NOW() - delivery updates require tenant, channel, answer_message_id, and turn correlation match - sent cannot be downgraded to failed; failed can be upgraded to sent for a future retry - no sessionWebhook, token, raw API response, or raw error text is persisted - audit write failures do not turn a successful channel send into a retry/duplicate delivery ## Verification - target tests: 6 packages, 275 passed, 0 failed - go vet on the same 6 packages: PASS - git diff --check: PASS - independent read-only review: PASS (0 security issues, 0 logic errors) - PostgreSQL 16.14 isolated rehearsal: up twice, schema contract, delivery state machine, down preservation, down/up twice, and temporary DB cleanup all PASS ## Known limitations - production event streaming starts a card before AskEvents; concurrent/redelivered callbacks can still create a duplicate processing card before replay status is known - delivery audit write failures are safely logged but do not yet have an asynchronous compensation/retry queue ## Not performed - not merged - not deployed - production database remains on the B1.1 schema; migration 000004 has not been applied
zheromiku added 1 commit 2026-07-21 12:54:44 +08:00
zheromiku merged commit 257a55a3f0 into main 2026-07-21 12:56:54 +08:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Weknora/dobotai-platform#4