feat: phase b - retail documents, outbound pipeline, transports, ack monitor, demo #7

Merged
KofTwentyTwo merged 4 commits from feature/phase-b-retail-outbound into develop 2026-10-14 12:09:36 +00:00
KofTwentyTwo commented 2026-10-14 04:08:27 +00:00 (Migrated from github.com)

Summary

Phase (b) of docs/DESIGN.md. Stacked on #6 (and #5); merge those first.

  • Retail: in-house baseline guides and sample maps for 855, 856, 810, 846, 860 (004010 and 005010; 850 from a1/a2). Outbound map engine with SEQUENCE and 856 HL numbering.
  • Outbound: record-change trigger (transactional outbox), edi_outbound_enqueue for an ESB trigger, opt-in "Send As EDI"; outbound worker (map, validate, batch, envelope with control numbers, store) and send worker (retry, backoff, dead letter, edi.send.failed + TRANSPORT exception). The 997/999/TA1 queued by a2 now send.
  • Transports: plugin SPI and registry with per-type validation and "Test Connection"; SFTP push and poll (streamed, .tmp then rename, host key pinned, tested against in-process MINA SSHD); file-gateway OUTBOX via the agreed FileGatewayOutbox facade (stand-in) with onDownloaded delivery; HTTPS out (basic, bearer, HMAC) and POST /qqq/hooks/edi/https/{transport} (outside /qqq/v1). AS2 and email are registered but unavailable until phase c / qbit-email's API.
  • Monitoring: overdue-ack and certificate-expiry alerts via QAlerts; Resend (same control numbers), Resend As New, Cancel.
  • Fixes found by running the demo in Next UI: every child-record-list widget returned 500 (the qbit config, including its Clock, was serialized into widget JSON; runtime services are now @JsonIgnored and a test serializes every widget over core and HTTP). Labels, FK possible values, record labels, field order and a readable home (narrow tables with partner names and humanized ages; no inner horizontal scroll at 390 px).
  • Demo: test-scope EdiDemoServer with Next UI and a synthetic seed (3 partners, 40 inbound documents, outbound 855/856/810/846, reconciled and overdue acks, a dead letter, open exceptions). See docs/DEMO.md.

Screenshots (home, partner, document, exceptions, interchange; light and dark at 390 and 1440 px) were reviewed locally; a remaining horizontal scroll only in Next's own record tab strip (12 child lists on Trading Partner) and the 18-column exceptions list at 1440, both Next components.

Test plan

  • ./mvnw verify: 129 tests, Checkstyle, JaCoCo (about 93% instructions, 98% classes)
  • Round trips for every retail document; trigger, batching, control numbers; sender retries and dead letter; gateway, HTTPS and SFTP; overdue monitor; resend; demo boots and every widget returns 200
  • CircleCI test_only

🤖 Generated with Claude Code

## Summary Phase (b) of `docs/DESIGN.md`. **Stacked on #6 (and #5)**; merge those first. - **Retail:** in-house baseline guides and sample maps for 855, 856, 810, 846, 860 (004010 and 005010; 850 from a1/a2). Outbound map engine with SEQUENCE and 856 HL numbering. - **Outbound:** record-change trigger (transactional outbox), `edi_outbound_enqueue` for an ESB trigger, opt-in "Send As EDI"; outbound worker (map, validate, batch, envelope with control numbers, store) and send worker (retry, backoff, dead letter, `edi.send.failed` + TRANSPORT exception). The 997/999/TA1 queued by a2 now send. - **Transports:** plugin SPI and registry with per-type validation and "Test Connection"; SFTP push and poll (streamed, `.tmp` then rename, host key pinned, tested against in-process MINA SSHD); file-gateway OUTBOX via the agreed `FileGatewayOutbox` facade (stand-in) with `onDownloaded` delivery; HTTPS out (basic, bearer, HMAC) and `POST /qqq/hooks/edi/https/{transport}` (outside `/qqq/v1`). AS2 and email are registered but unavailable until phase c / qbit-email's API. - **Monitoring:** overdue-ack and certificate-expiry alerts via `QAlerts`; Resend (same control numbers), Resend As New, Cancel. - **Fixes found by running the demo in Next UI:** every child-record-list widget returned 500 (the qbit config, including its `Clock`, was serialized into widget JSON; runtime services are now `@JsonIgnore`d and a test serializes every widget over core and HTTP). Labels, FK possible values, record labels, field order and a readable home (narrow tables with partner names and humanized ages; no inner horizontal scroll at 390 px). - **Demo:** test-scope `EdiDemoServer` with Next UI and a synthetic seed (3 partners, 40 inbound documents, outbound 855/856/810/846, reconciled and overdue acks, a dead letter, open exceptions). See `docs/DEMO.md`. Screenshots (home, partner, document, exceptions, interchange; light and dark at 390 and 1440 px) were reviewed locally; a remaining horizontal scroll only in Next's own record tab strip (12 child lists on Trading Partner) and the 18-column exceptions list at 1440, both Next components. ## Test plan - [x] `./mvnw verify`: 129 tests, Checkstyle, JaCoCo (about 93% instructions, 98% classes) - [x] Round trips for every retail document; trigger, batching, control numbers; sender retries and dead letter; gateway, HTTPS and SFTP; overdue monitor; resend; demo boots and every widget returns 200 - [ ] CircleCI `test_only` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.