generated from coulomb/repo-seed
1058 lines
34 KiB
Markdown
1058 lines
34 KiB
Markdown
# HybridmailBinectSpecification.md
|
||
|
||
## 1. Document Status
|
||
|
||
**Document:** HybridmailBinectSpecification.md
|
||
**Project:** hybridmail-connect
|
||
**Provider Flavor:** Binect
|
||
**Parent Specification:** HybridmailAdapterSpecification.md
|
||
**Target Integration:** coordination-engine
|
||
**Adapter Contract:** AdapterInterfaceSpecification.md v1.0
|
||
**Status:** Draft v1.0
|
||
**Primary Scope:** Binect-specific hybrid-mail provider flavor for document upload, validation, attachments, preview, sending, and status mapping.
|
||
|
||
## 2. Purpose
|
||
|
||
This document specifies the Binect provider flavor for `hybridmail-connect`.
|
||
|
||
The Binect flavor implements the generic hybrid-mail adapter model for the Binect API. It maps Binect’s document-centric API workflow into the provider-neutral hybrid-mail model used by `coordination-engine`.
|
||
|
||
The purpose of this document is to capture:
|
||
|
||
* Binect-specific provider capabilities.
|
||
* Binect-specific workflow stages.
|
||
* Binect document, attachment, preview, sending, and status concepts.
|
||
* Binect validation semantics.
|
||
* Binect print and shipping option mapping.
|
||
* Binect evidence event mapping.
|
||
* Binect-specific limitations and assumptions.
|
||
* Binect-specific MVP boundaries.
|
||
|
||
The Binect flavor MUST remain compatible with the generic `HybridmailAdapterSpecification.md` and MUST NOT leak Binect-specific terminology into the core coordination model except through explicitly mapped provider metadata.
|
||
|
||
## 3. Grounding Summary
|
||
|
||
The public Binect API material indicates the following relevant features:
|
||
|
||
* Binect provides a REST API for digital business-letter dispatch.
|
||
* The API supports document upload.
|
||
* Attachments can be added to letters.
|
||
* Supported attachment formats include `pdf`, `rtf`, `txt`, `png`, `jpg`, `jpeg`, `bmp`, `gif`, and `ps`.
|
||
* Attachment size is limited to 20 MB according to the public FAQ.
|
||
* The API supports setting print and shipping options.
|
||
* The API supports preview retrieval.
|
||
* The API supports sending after preparation.
|
||
* The API supports document and shipping status queries.
|
||
* Serial or child document status handling is relevant.
|
||
* Validation includes address position, address format, and restricted-area checks.
|
||
* Binect handles full-service physical dispatch including printing, enveloping/franking, and handover to Deutsche Post.
|
||
* Binect publicly positions the API as a way to integrate digital business-letter dispatch into DMS, CRM, and other software systems.
|
||
|
||
These facts define the baseline for this provider flavor.
|
||
|
||
## 4. Provider Flavor Identity
|
||
|
||
```yaml
|
||
HybridmailProviderFlavorDescriptor:
|
||
provider_name: binect
|
||
provider_label: Binect API
|
||
provider_family: hybridmail
|
||
adapter_contract_version: "1.0"
|
||
parent_specification: HybridmailAdapterSpecification.md
|
||
deployment_mode: external
|
||
```
|
||
|
||
## 5. Binect Capability Descriptor
|
||
|
||
The Binect flavor MUST expose a capability descriptor.
|
||
|
||
```yaml
|
||
HybridmailProviderFlavorDescriptor:
|
||
provider_name: binect
|
||
provider_version: provider_specific
|
||
supported_file_types:
|
||
- pdf
|
||
- postscript
|
||
supported_attachment_file_types:
|
||
- pdf
|
||
- rtf
|
||
- txt
|
||
- png
|
||
- jpg
|
||
- jpeg
|
||
- bmp
|
||
- gif
|
||
- ps
|
||
attachment_max_size_mb: 20
|
||
supports_single_letter: true
|
||
supports_bulk: true
|
||
supports_serial_letters: true
|
||
supports_attachments: true
|
||
supports_preview: true
|
||
supports_webhooks: provider_specific
|
||
supports_polling: true
|
||
supports_registered_mail: provider_specific
|
||
supports_delivery_confirmation: provider_specific
|
||
supports_return_mail: provider_specific
|
||
supports_address_correction: provider_specific
|
||
supports_international_mail: provider_specific
|
||
supports_cancellation: provider_specific
|
||
supports_staging: provider_specific
|
||
supports_idempotency: adapter_managed
|
||
supports_rate_limits: provider_specific
|
||
supports_cost_calculation: true
|
||
supports_document_status: true
|
||
supports_shipping_status: true
|
||
supports_child_document_status: true
|
||
supported_print_options:
|
||
color_mode: provider_specific
|
||
simplex_duplex: provider_specific
|
||
envelope_selection: provider_specific
|
||
address_position: true
|
||
attachment_starts_on_new_sheet: true
|
||
supported_postal_products:
|
||
- standard
|
||
- provider_specific
|
||
limitations:
|
||
- Public Binect documentation confirms status queries but does not establish ordinary postal final-delivery proof for all products.
|
||
- Public documentation confirms validation and preview concepts but implementation must rely on the live Binect Swagger/API for exact field names.
|
||
- Idempotency should be enforced by hybridmail-connect if not provided natively by the Binect endpoint used.
|
||
- Cancellation semantics must be treated as provider-specific and time-sensitive.
|
||
```
|
||
|
||
## 6. Binect-Specific Conceptual Workflow
|
||
|
||
The Binect flavor uses a document-centric workflow.
|
||
|
||
```text
|
||
create/upload document
|
||
→ validate document
|
||
→ optionally add attachments
|
||
→ set or confirm print/shipping options
|
||
→ optionally retrieve preview
|
||
→ create/send sending
|
||
→ query document status
|
||
→ query shipping/sending status
|
||
→ receive or poll further status updates
|
||
```
|
||
|
||
The adapter MUST preserve this distinction:
|
||
|
||
```text
|
||
Document preparation is not sending.
|
||
Sending is not postal handover.
|
||
Postal handover is not final physical delivery proof.
|
||
```
|
||
|
||
## 7. Binect Object Mapping
|
||
|
||
## 7.1 Generic to Binect Mapping
|
||
|
||
| Generic hybrid-mail concept | Binect flavor concept |
|
||
| --------------------------- | --------------------------------------------------------------------------- |
|
||
| `HybridmailLetter` | Letter-level abstraction composed from Binect document plus sending context |
|
||
| `HybridmailDocumentRef` | Binect document |
|
||
| `HybridmailAttempt` | Binect document upload and/or sending operation |
|
||
| `HybridmailBatch` | Binect serial/bulk document or sending group |
|
||
| `PostalRecipient` | Address extracted from document or provided as metadata if supported |
|
||
| `HybridmailOptions` | Binect print and shipping options |
|
||
| `HybridmailPreview` | Binect preview/brief view |
|
||
| `HybridmailTimeline` | Aggregated Binect document and shipping status history |
|
||
|
||
## 7.2 BinectDocument
|
||
|
||
```yaml
|
||
BinectDocument:
|
||
binect_document_id: string
|
||
hybridmail_letter_id: string?
|
||
coordination_case_id: string?
|
||
participant_id: string?
|
||
provider_status: string?
|
||
normalized_status: string
|
||
original_file_ref: ResourceRef
|
||
file_type: pdf | ps | unknown
|
||
page_count: integer?
|
||
sheet_count: integer?
|
||
price_estimate: MoneyAmount?
|
||
validation_result: BinectValidationResult?
|
||
preview_refs:
|
||
- BinectPreviewRef
|
||
attachment_refs:
|
||
- BinectAttachmentRef
|
||
created_at: timestamp
|
||
updated_at: timestamp?
|
||
metadata: object?
|
||
```
|
||
|
||
## 7.3 BinectAttachment
|
||
|
||
```yaml
|
||
BinectAttachment:
|
||
binect_attachment_id: string
|
||
binect_document_id: string
|
||
attachment_file_ref: ResourceRef
|
||
file_type: pdf | rtf | txt | png | jpg | jpeg | bmp | gif | ps | unknown
|
||
file_size_bytes: integer?
|
||
starts_on_new_sheet: boolean?
|
||
provider_status: string?
|
||
validation_result: BinectValidationResult?
|
||
created_at: timestamp
|
||
metadata: object?
|
||
```
|
||
|
||
### Attachment Handling Rule
|
||
|
||
The Binect flavor SHOULD default `starts_on_new_sheet` to `true` if no explicit instruction is provided, because the public FAQ states that attachments start on a new sheet by default.
|
||
|
||
If duplex printing is used and the primary document has an odd number of pages, the adapter SHOULD be prepared for provider-side blank-page insertion semantics. Blank pages may affect sheet count and preview/status display, but should not be treated as billable unless the provider reports otherwise.
|
||
|
||
## 7.4 BinectSending
|
||
|
||
```yaml
|
||
BinectSending:
|
||
binect_sending_id: string
|
||
binect_document_id: string?
|
||
hybridmail_letter_id: string
|
||
coordination_case_id: string?
|
||
participant_id: string?
|
||
provider_status: string?
|
||
normalized_status: string
|
||
shipping_options: BinectShippingOptions?
|
||
print_options: BinectPrintOptions?
|
||
submitted_at: timestamp?
|
||
status_checked_at: timestamp?
|
||
child_document_statuses:
|
||
- BinectChildDocumentStatus
|
||
metadata: object?
|
||
```
|
||
|
||
## 7.5 BinectChildDocumentStatus
|
||
|
||
For serial documents or bulk processing, child document statuses MUST be represented individually.
|
||
|
||
```yaml
|
||
BinectChildDocumentStatus:
|
||
parent_document_id: string
|
||
child_document_id: string
|
||
participant_id: string?
|
||
provider_status: string?
|
||
normalized_status: string
|
||
evidence_event_refs:
|
||
- string
|
||
updated_at: timestamp?
|
||
metadata: object?
|
||
```
|
||
|
||
Batch-level success MUST NOT be treated as success for every child document unless each child status supports that interpretation.
|
||
|
||
## 8. Binect Validation Model
|
||
|
||
Binect validation results MUST be mapped into the generic `HybridmailValidationResult`.
|
||
|
||
The public material indicates validation of:
|
||
|
||
* address position
|
||
* address format
|
||
* restricted areas
|
||
* upload/print suitability
|
||
|
||
```yaml
|
||
BinectValidationResult:
|
||
document_id: string
|
||
provider_validation_state: string?
|
||
validation_state: pending | passed | action_required | failed | unknown
|
||
issues:
|
||
- BinectValidationIssue
|
||
price_estimate: MoneyAmount?
|
||
validated_at: timestamp?
|
||
raw_provider_response_ref: string?
|
||
```
|
||
|
||
```yaml
|
||
BinectValidationIssue:
|
||
provider_issue_code: string?
|
||
issue_code: string
|
||
severity: info | warning | action_required | fatal
|
||
category: format | page_size | address | address_position | address_format | restricted_area | margins | file_size | page_count | attachment | postage | country | provider_policy | unknown
|
||
message: string
|
||
page_number: integer?
|
||
bounding_box: object?
|
||
fixable: boolean?
|
||
```
|
||
|
||
## 9. Binect Validation Issue Mapping
|
||
|
||
| Binect validation concern | Generic validation category | Normalized issue code |
|
||
| ------------------------- | --------------------------- | --------------------------- |
|
||
| Address position invalid | `address_position` | `address_position_invalid` |
|
||
| Address format invalid | `address_format` | `address_format_invalid` |
|
||
| Restricted area violation | `restricted_area` | `restricted_area_violation` |
|
||
| Unsupported file type | `format` | `unsupported_file_type` |
|
||
| File too large | `file_size` | `file_too_large` |
|
||
| Attachment invalid | `attachment` | `attachment_invalid` |
|
||
| Postal option invalid | `postage` | `unsupported_product` |
|
||
| Provider policy rejection | `provider_policy` | `provider_policy_rejected` |
|
||
| Unknown validation issue | `unknown` | `unknown_validation_issue` |
|
||
|
||
Validation failure MUST emit:
|
||
|
||
```text
|
||
payload.validation_failed
|
||
```
|
||
|
||
Validation success MUST emit:
|
||
|
||
```text
|
||
payload.validation_passed
|
||
```
|
||
|
||
Validation warnings MAY emit `payload.validation_passed` with warning metadata if the provider still allows sending.
|
||
|
||
## 10. Binect Print and Shipping Options
|
||
|
||
The Binect flavor MUST map Binect options into the generic `HybridmailOptions`.
|
||
|
||
```yaml
|
||
BinectPrintOptions:
|
||
color_mode: color | grayscale | provider_default | unknown
|
||
print_sides: simplex | duplex | provider_default | unknown
|
||
attachment_starts_on_new_sheet: boolean?
|
||
paper_type: provider_specific?
|
||
metadata: object?
|
||
```
|
||
|
||
```yaml
|
||
BinectShippingOptions:
|
||
postage_product: standard | provider_specific
|
||
country_scope: domestic | international | unknown
|
||
dispatch_mode: manual_review | auto_send | submit_later | scheduled
|
||
desired_dispatch_date: date?
|
||
sender_profile_ref: string?
|
||
return_mail_handling: none | provider_processed | physical_return | digital_return_info | unknown
|
||
metadata: object?
|
||
```
|
||
|
||
Provider-native option names MUST be preserved in metadata.
|
||
|
||
The normalized model MUST avoid assuming support for a product unless the live provider capability descriptor confirms it.
|
||
|
||
## 11. Binect Preview Model
|
||
|
||
Binect preview retrieval MUST map to `HybridmailPreview`.
|
||
|
||
```yaml
|
||
BinectPreviewRef:
|
||
preview_id: string
|
||
binect_document_id: string
|
||
preview_type: pdf | png | image | metadata | unknown
|
||
preview_uri: string?
|
||
generated_at: timestamp
|
||
expires_at: timestamp?
|
||
raw_provider_response_ref: string?
|
||
```
|
||
|
||
Preview availability MUST emit an operational event, normally:
|
||
|
||
```text
|
||
delivery.payload.available
|
||
```
|
||
|
||
Preview availability MUST NOT be interpreted as postal delivery evidence.
|
||
|
||
## 12. Binect Status Model
|
||
|
||
Because provider-native statuses may differ across endpoints, the Binect flavor MUST preserve raw provider status and map it to normalized status.
|
||
|
||
```yaml
|
||
BinectStatusRecord:
|
||
status_record_id: string
|
||
binect_document_id: string?
|
||
binect_sending_id: string?
|
||
child_document_id: string?
|
||
provider_status: string
|
||
normalized_status: string
|
||
status_scope: document | sending | child_document | shipping | unknown
|
||
observed_at: timestamp
|
||
raw_provider_response_ref: string?
|
||
```
|
||
|
||
## 13. Normalized Binect Status Categories
|
||
|
||
The Binect flavor SHOULD map native statuses into these normalized categories:
|
||
|
||
```text
|
||
document.created
|
||
document.uploaded
|
||
document.validation_pending
|
||
document.validation_passed
|
||
document.validation_failed
|
||
document.preview_available
|
||
document.ready_for_sending
|
||
sending.submitted
|
||
sending.processing
|
||
sending.production_started
|
||
sending.production_completed
|
||
sending.handed_to_postal_service
|
||
sending.failed
|
||
sending.cancelled
|
||
sending.status_unknown
|
||
shipping.status_unknown
|
||
shipping.undeliverable
|
||
shipping.return_received
|
||
```
|
||
|
||
Where Binect status granularity is insufficient, the adapter MUST use the nearest weaker event and preserve the raw status in metadata.
|
||
|
||
Example:
|
||
|
||
```text
|
||
If the provider status only says "sent" and does not distinguish production completion from postal handover,
|
||
the adapter SHOULD map it conservatively and document the chosen interpretation.
|
||
```
|
||
|
||
## 14. Binect-to-Generic Event Mapping
|
||
|
||
| Binect workflow event | Generic event | Evidence interpretation |
|
||
| --------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------- |
|
||
| Document upload accepted | `delivery.payload.accepted` | Digital submission accepted |
|
||
| Document rejected on upload | `delivery.payload.rejected` | Attempt failed before validation/send |
|
||
| Validation passed | `payload.validation_passed` | Document is provider-processable |
|
||
| Validation failed | `payload.validation_failed` | Document/action must be corrected |
|
||
| Price calculated on upload | metadata on validation/upload event | Cost signal, not delivery evidence |
|
||
| Attachment added | `delivery.payload.accepted` with attachment metadata | Attachment accepted into document context |
|
||
| Attachment rejected | `payload.validation_failed` | Attachment must be corrected |
|
||
| Preview generated | `delivery.payload.available` | Operational review evidence |
|
||
| Options set | metadata event or `delivery.payload.available` | Operational readiness |
|
||
| Sending submitted | `delivery.payload.submitted` | Provider instructed to send |
|
||
| Document/sending processing | `delivery.production.started` | Provider production chain began |
|
||
| Production completed | `delivery.production.completed` | Printed/enveloped/franked if provider status supports this |
|
||
| Handover to post | `delivery.postal.handed_over` | Strong dispatch evidence |
|
||
| Shipping status unknown | `delivery.postal.status_unknown` | Final delivery unclear |
|
||
| Undeliverable/returned | `delivery.postal.undeliverable` or `delivery.postal.return_received` | Strong negative evidence |
|
||
| Child document status | per-child mapped event | Required for serial/bulk cases |
|
||
|
||
## 15. Evidence Grading Rules
|
||
|
||
### 15.1 Document Upload Accepted
|
||
|
||
```yaml
|
||
event_type: delivery.payload.accepted
|
||
evidence_grade:
|
||
strength: weak
|
||
actor_certainty: none
|
||
authority_certainty: none
|
||
payload_certainty: medium
|
||
interaction_certainty: none
|
||
timing_certainty: medium
|
||
channel_certainty: medium
|
||
non_repudiation_strength: low
|
||
notes:
|
||
- Binect accepted the document upload or document creation step.
|
||
- This does not prove validation, sending, production, postal handover, or delivery.
|
||
```
|
||
|
||
### 15.2 Binect Validation Passed
|
||
|
||
```yaml
|
||
event_type: payload.validation_passed
|
||
evidence_grade:
|
||
strength: medium
|
||
actor_certainty: none
|
||
authority_certainty: none
|
||
payload_certainty: high
|
||
interaction_certainty: none
|
||
timing_certainty: high
|
||
channel_certainty: high
|
||
non_repudiation_strength: low
|
||
notes:
|
||
- Document passed Binect validation for further processing.
|
||
- This does not prove sending or postal handover.
|
||
```
|
||
|
||
### 15.3 Binect Validation Failed
|
||
|
||
```yaml
|
||
event_type: payload.validation_failed
|
||
evidence_grade:
|
||
strength: negative
|
||
actor_certainty: none
|
||
authority_certainty: none
|
||
payload_certainty: high
|
||
interaction_certainty: none
|
||
timing_certainty: high
|
||
channel_certainty: high
|
||
non_repudiation_strength: low
|
||
notes:
|
||
- Document is not processable without correction or replacement.
|
||
- The validation issue category should be included.
|
||
```
|
||
|
||
### 15.4 Preview Available
|
||
|
||
```yaml
|
||
event_type: delivery.payload.available
|
||
evidence_grade:
|
||
strength: weak
|
||
actor_certainty: none
|
||
authority_certainty: none
|
||
payload_certainty: medium
|
||
interaction_certainty: none
|
||
timing_certainty: high
|
||
channel_certainty: high
|
||
non_repudiation_strength: low
|
||
notes:
|
||
- Binect preview is available for review.
|
||
- Preview availability is operational evidence, not postal dispatch evidence.
|
||
```
|
||
|
||
### 15.5 Sending Submitted
|
||
|
||
```yaml
|
||
event_type: delivery.payload.submitted
|
||
evidence_grade:
|
||
strength: medium
|
||
actor_certainty: none
|
||
authority_certainty: none
|
||
payload_certainty: high
|
||
interaction_certainty: none
|
||
timing_certainty: high
|
||
channel_certainty: high
|
||
non_repudiation_strength: low
|
||
notes:
|
||
- Binect sending was submitted.
|
||
- This does not prove production completion or postal handover.
|
||
```
|
||
|
||
### 15.6 Production Started
|
||
|
||
```yaml
|
||
event_type: delivery.production.started
|
||
evidence_grade:
|
||
strength: medium
|
||
actor_certainty: none
|
||
authority_certainty: none
|
||
payload_certainty: high
|
||
interaction_certainty: none
|
||
timing_certainty: medium
|
||
channel_certainty: high
|
||
non_repudiation_strength: low
|
||
notes:
|
||
- Binect status indicates processing/production has started.
|
||
- The exact native status should be preserved in metadata.
|
||
```
|
||
|
||
### 15.7 Postal Handover
|
||
|
||
```yaml
|
||
event_type: delivery.postal.handed_over
|
||
evidence_grade:
|
||
strength: strong
|
||
actor_certainty: none
|
||
authority_certainty: none
|
||
payload_certainty: high
|
||
interaction_certainty: none
|
||
timing_certainty: high
|
||
channel_certainty: high
|
||
non_repudiation_strength: medium
|
||
notes:
|
||
- Binect status indicates handover into the physical postal delivery chain.
|
||
- This is strong dispatch evidence.
|
||
- It does not prove recipient receipt or reading.
|
||
```
|
||
|
||
### 15.8 Return or Undeliverable
|
||
|
||
```yaml
|
||
event_type: delivery.postal.return_received
|
||
evidence_grade:
|
||
strength: negative
|
||
actor_certainty: none
|
||
authority_certainty: none
|
||
payload_certainty: high
|
||
interaction_certainty: none
|
||
timing_certainty: high
|
||
channel_certainty: high
|
||
non_repudiation_strength: medium
|
||
notes:
|
||
- Binect or downstream status indicates the physical letter was returned or undeliverable.
|
||
- This is strong negative delivery evidence.
|
||
```
|
||
|
||
## 16. Binect Evidence Assessment
|
||
|
||
The Binect flavor SHOULD provide a Binect-native evidence assessment.
|
||
|
||
```yaml
|
||
BinectEvidenceAssessment:
|
||
hybridmail_letter_id: string
|
||
binect_document_id: string?
|
||
binect_sending_id: string?
|
||
participant_id: string?
|
||
category: success | fail | undef
|
||
subclass: string
|
||
confidence: low | medium | high
|
||
strongest_signal: string?
|
||
evidence_summary:
|
||
- string
|
||
recommended_coordination_interpretation: string?
|
||
```
|
||
|
||
### 16.1 Binect Adapter Success Subclasses
|
||
|
||
```text
|
||
success.document_uploaded
|
||
success.validation_passed
|
||
success.preview_available
|
||
success.sending_submitted
|
||
success.production_started
|
||
success.production_completed
|
||
success.handed_to_postal_service
|
||
success.return_info_processed
|
||
```
|
||
|
||
### 16.2 Binect Adapter Fail Subclasses
|
||
|
||
```text
|
||
fail.upload_rejected
|
||
fail.validation_failed
|
||
fail.address_position_invalid
|
||
fail.address_format_invalid
|
||
fail.restricted_area_violation
|
||
fail.attachment_invalid
|
||
fail.unsupported_file_type
|
||
fail.file_too_large
|
||
fail.options_invalid
|
||
fail.sending_rejected
|
||
fail.production_failed
|
||
fail.cancelled
|
||
fail.return_received
|
||
fail.undeliverable
|
||
```
|
||
|
||
### 16.3 Binect Adapter Undef Subclasses
|
||
|
||
```text
|
||
undef.pending
|
||
undef.uploaded_only
|
||
undef.validation_pending
|
||
undef.ready_but_not_sent
|
||
undef.preview_available_only
|
||
undef.submitted_for_sending
|
||
undef.processing
|
||
undef.production_status_unknown
|
||
undef.handed_to_postal_service_but_delivery_unproven
|
||
undef.shipping_status_unknown
|
||
undef.no_final_status_expected
|
||
undef.child_status_partial
|
||
undef.conflicting_evidence
|
||
undef.channel_degraded
|
||
```
|
||
|
||
## 17. Binect Workflow States
|
||
|
||
The Binect flavor SHOULD support these normalized workflow states:
|
||
|
||
```text
|
||
created
|
||
upload_requested
|
||
uploaded
|
||
upload_failed
|
||
validation_pending
|
||
validation_passed
|
||
validation_failed
|
||
attachment_pending
|
||
attachment_added
|
||
attachment_failed
|
||
options_pending
|
||
options_set
|
||
preview_pending
|
||
preview_available
|
||
ready_for_sending
|
||
send_requested
|
||
sending_submitted
|
||
processing
|
||
production_started
|
||
production_completed
|
||
handed_to_postal_service
|
||
shipping_status_unknown
|
||
return_received
|
||
undeliverable
|
||
cancelled
|
||
failed
|
||
unknown
|
||
```
|
||
|
||
These states are Binect-flavor states, not coordination result states.
|
||
|
||
## 18. Binect Idempotency and Duplicate Send Prevention
|
||
|
||
Duplicate physical send prevention is mandatory.
|
||
|
||
If the Binect endpoint used does not provide native idempotency, `hybridmail-connect` MUST implement adapter-managed idempotency.
|
||
|
||
Idempotency scope SHOULD include:
|
||
|
||
```text
|
||
coordination_case_id
|
||
participant_id
|
||
delivery_id
|
||
payload_id
|
||
payload_integrity_hash
|
||
provider_flavor
|
||
target postal recipient
|
||
shipping options
|
||
```
|
||
|
||
A repeated `delivery.submit_letter` request with the same idempotency key MUST NOT create a second physical send.
|
||
|
||
If the repeated request refers to a changed payload or changed address, the adapter MUST reject it as an idempotency conflict unless a new idempotency key is provided.
|
||
|
||
## 19. Binect Attachments
|
||
|
||
The Binect flavor MUST support attachments according to provider capability.
|
||
|
||
Supported attachment formats from public FAQ:
|
||
|
||
```text
|
||
pdf
|
||
rtf
|
||
txt
|
||
png
|
||
jpg
|
||
jpeg
|
||
bmp
|
||
gif
|
||
ps
|
||
```
|
||
|
||
Maximum attachment size from public FAQ:
|
||
|
||
```text
|
||
20 MB
|
||
```
|
||
|
||
The adapter SHOULD validate attachment file type and size before submission where possible.
|
||
|
||
Attachment events SHOULD be mapped as:
|
||
|
||
| Attachment event | Generic event |
|
||
| ----------------------------- | ---------------------------------------------------- |
|
||
| Attachment accepted | `delivery.payload.accepted` with attachment metadata |
|
||
| Attachment rejected | `payload.validation_failed` |
|
||
| Attachment validation warning | `payload.validation_passed` with warning metadata |
|
||
|
||
## 20. Binect Cost and Price Handling
|
||
|
||
The public Binect FAQ states that price calculation occurs when uploading the letter.
|
||
|
||
The Binect flavor SHOULD capture provider cost information when available.
|
||
|
||
```yaml
|
||
BinectCostEstimate:
|
||
binect_document_id: string
|
||
amount_net: number?
|
||
amount_gross: number?
|
||
currency: string?
|
||
tax_amount: number?
|
||
page_count: integer?
|
||
sheet_count: integer?
|
||
postage_product: string?
|
||
calculated_at: timestamp?
|
||
raw_provider_response_ref: string?
|
||
```
|
||
|
||
Cost calculation is operational metadata and MUST NOT be treated as delivery evidence.
|
||
|
||
## 21. Binect Status Polling and Webhooks
|
||
|
||
The Binect flavor MUST support polling if status endpoints are available.
|
||
|
||
The Binect flavor MAY support webhooks if available in the provider configuration.
|
||
|
||
```yaml
|
||
BinectStatusPollingConfig:
|
||
enabled: boolean
|
||
initial_delay_seconds: integer
|
||
interval_seconds: integer
|
||
max_duration_seconds: integer
|
||
terminal_statuses:
|
||
- string
|
||
```
|
||
|
||
Polling MUST be idempotent and MUST preserve status history.
|
||
|
||
Late status changes MUST be recorded.
|
||
|
||
## 22. Binect Raw Event Preservation
|
||
|
||
The Binect flavor SHOULD preserve raw provider responses or references to them.
|
||
|
||
```yaml
|
||
RawBinectEventRef:
|
||
raw_event_id: string
|
||
source: api_response | status_poll | webhook | preview | validation | operator
|
||
endpoint: string?
|
||
storage_ref: string?
|
||
received_at: timestamp
|
||
redacted: boolean
|
||
```
|
||
|
||
Normalized events SHOULD reference raw Binect event data where available.
|
||
|
||
## 23. Binect Channel Health
|
||
|
||
```yaml
|
||
BinectChannelHealth:
|
||
provider_name: binect
|
||
provider_account_ref: string?
|
||
status: healthy | degraded | failing | unknown
|
||
authentication_status: valid | expired | missing | insufficient | unknown
|
||
upload_status: healthy | degraded | unavailable | unknown
|
||
validation_status: healthy | degraded | unavailable | unknown
|
||
preview_status: healthy | degraded | unavailable | unknown
|
||
sending_status: healthy | delayed | unavailable | unknown
|
||
status_api_status: healthy | degraded | unavailable | unknown
|
||
cutoff_status: before_cutoff | after_cutoff | no_production_day | unknown
|
||
known_degradations:
|
||
- string
|
||
```
|
||
|
||
Health events SHOULD map to:
|
||
|
||
```text
|
||
system.provider.degraded
|
||
system.provider.unavailable
|
||
system.adapter.health_changed
|
||
```
|
||
|
||
## 24. Security Requirements
|
||
|
||
The Binect flavor MUST:
|
||
|
||
* protect Binect API credentials.
|
||
* use secure transport.
|
||
* avoid logging document contents.
|
||
* protect postal recipient data.
|
||
* preserve idempotency.
|
||
* prevent duplicate physical sends.
|
||
* separate test and production configuration.
|
||
* protect previews, because previews may contain full document content.
|
||
* validate file type and size before upload where possible.
|
||
* apply tenant/account separation where applicable.
|
||
|
||
## 25. Privacy Requirements
|
||
|
||
The Binect flavor SHOULD:
|
||
|
||
* store payload references instead of payload content where possible.
|
||
* support metadata-only mode after provider submission.
|
||
* mask postal address data in logs.
|
||
* support configurable retention of raw provider responses.
|
||
* support configurable retention of previews.
|
||
* separate operational diagnostics from coordination evidence.
|
||
* document provider-side retention limitations.
|
||
* support deletion or anonymization workflows where legally possible.
|
||
|
||
## 26. Reliability Requirements
|
||
|
||
The Binect flavor MUST support:
|
||
|
||
* idempotent submit requests.
|
||
* duplicate status event detection.
|
||
* out-of-order status handling.
|
||
* polling-based status recovery.
|
||
* retryable upload failures.
|
||
* non-retryable validation failures.
|
||
* provider timeout handling.
|
||
* validation issue preservation.
|
||
* preview retrieval failure handling.
|
||
* child-document partial-status handling.
|
||
* correlation preservation.
|
||
* dead-letter handling for unprocessable provider responses.
|
||
|
||
## 27. Minimal API Surface
|
||
|
||
The Binect flavor SHOULD implement or expose these conceptual operations through `hybridmail-connect`.
|
||
|
||
### 27.1 Adapter Contract Operations
|
||
|
||
```text
|
||
GET /adapter/descriptor
|
||
GET /adapter/health
|
||
POST /adapter/actions
|
||
POST /adapter/events/provider
|
||
GET /adapter/events
|
||
GET /adapter/letters/{id}/timeline
|
||
GET /adapter/letters/{id}/assessment
|
||
```
|
||
|
||
### 27.2 Binect Flavor Operations
|
||
|
||
```text
|
||
POST /binect/documents
|
||
POST /binect/documents/{id}/attachments
|
||
PUT /binect/documents/{id}/options
|
||
GET /binect/documents/{id}/preview
|
||
POST /binect/sendings
|
||
GET /binect/documents/{id}/status
|
||
GET /binect/sendings/{id}/status
|
||
GET /binect/letters/{id}/timeline
|
||
GET /binect/letters/{id}/assessment
|
||
GET /binect/channel-health
|
||
```
|
||
|
||
The exact provider endpoint names MUST be implemented according to the live Binect Swagger/API. The conceptual operations above define the adapter-facing semantic model.
|
||
|
||
## 28. Example End-to-End Flow
|
||
|
||
### 28.1 Single Binect Letter
|
||
|
||
1. `coordination-engine` creates a coordination case.
|
||
2. A PDF payload is registered.
|
||
3. Policy selects `hybridmail-connect` with provider flavor `binect`.
|
||
4. `coordination-engine` sends `delivery.submit_letter`.
|
||
5. `hybridmail-connect` creates a Binect document upload operation.
|
||
6. Binect accepts the document.
|
||
7. The adapter emits `delivery.payload.accepted`.
|
||
8. Binect validates the document.
|
||
9. If validation passes, the adapter emits `payload.validation_passed`.
|
||
10. Optional attachments are uploaded.
|
||
11. Print and shipping options are set or confirmed.
|
||
12. A preview is requested if policy requires review.
|
||
13. The adapter emits `delivery.payload.available` for preview availability.
|
||
14. The sending is submitted.
|
||
15. The adapter emits `delivery.payload.submitted`.
|
||
16. Status polling reports processing/production.
|
||
17. The adapter emits `delivery.production.started` and later stronger production or postal events if supported.
|
||
18. If status indicates postal handover, the adapter emits `delivery.postal.handed_over`.
|
||
19. `coordination-engine` evaluates whether handover is sufficient for the case policy.
|
||
|
||
### 28.2 Validation Failure
|
||
|
||
1. Binect rejects the document due to address position, address format, or restricted-area violation.
|
||
2. The adapter emits `payload.validation_failed`.
|
||
3. The validation issue is preserved with category and severity.
|
||
4. `coordination-engine` marks the participant delivery as action-required or failed for the attempt.
|
||
5. Policy requests correction, alternate generation, or fallback channel.
|
||
|
||
### 28.3 Serial / Bulk Document
|
||
|
||
1. A serial or bulk document is submitted.
|
||
2. Binect returns parent and child statuses.
|
||
3. The adapter records parent status.
|
||
4. The adapter creates or updates `BinectChildDocumentStatus` records.
|
||
5. The adapter emits per-child evidence events.
|
||
6. `coordination-engine` aggregates participant-level completion and does not treat parent-level acceptance as universal delivery success.
|
||
|
||
## 29. Binect MVP Scope
|
||
|
||
The first Binect flavor implementation should include:
|
||
|
||
1. Binect provider flavor descriptor.
|
||
2. Adapter descriptor integration.
|
||
3. Binect credential/config handling.
|
||
4. Document upload.
|
||
5. Attachment upload.
|
||
6. Print/shipping option setting.
|
||
7. Preview retrieval.
|
||
8. Sending submission.
|
||
9. Document status polling.
|
||
10. Sending/shipping status polling.
|
||
11. Validation result mapping.
|
||
12. Child document status mapping where exposed.
|
||
13. Evidence event generation.
|
||
14. Letter timeline.
|
||
15. Binect evidence assessment.
|
||
16. Adapter-managed idempotency.
|
||
|
||
### MVP Required Binect Events
|
||
|
||
```text
|
||
delivery.payload.accepted
|
||
delivery.payload.rejected
|
||
payload.validation_passed
|
||
payload.validation_failed
|
||
delivery.payload.available
|
||
delivery.payload.submitted
|
||
delivery.production.started
|
||
delivery.production.completed
|
||
delivery.postal.handed_over
|
||
delivery.postal.status_unknown
|
||
delivery.postal.undeliverable
|
||
delivery.postal.return_received
|
||
system.provider.degraded
|
||
system.provider.unavailable
|
||
```
|
||
|
||
Where a provider status is unavailable or not semantically clear, the adapter MUST emit the weakest safe event and preserve the raw status.
|
||
|
||
## 30. Binect MVP Acceptance Criteria
|
||
|
||
The Binect flavor MVP is acceptable when it can:
|
||
|
||
1. Accept a coordination-compatible `delivery.submit_letter` request.
|
||
2. Upload or simulate upload of a Binect document.
|
||
3. Preserve correlation and idempotency.
|
||
4. Prevent duplicate physical sends for duplicate idempotency keys.
|
||
5. Add supported attachments.
|
||
6. Set or preserve print/shipping options.
|
||
7. Retrieve or simulate a preview.
|
||
8. Submit sending.
|
||
9. Poll and normalize document status.
|
||
10. Poll and normalize sending/shipping status.
|
||
11. Map validation success to `payload.validation_passed`.
|
||
12. Map address/layout validation failure to `payload.validation_failed`.
|
||
13. Map sending submission to `delivery.payload.submitted`.
|
||
14. Map postal handover only when semantically supported by provider status.
|
||
15. Provide a Binect letter timeline.
|
||
16. Provide a Binect evidence assessment.
|
||
17. Integrate with `coordination-engine` without overclaiming physical delivery or human awareness.
|
||
|
||
## 31. Open Questions
|
||
|
||
1. Which exact Binect native statuses should map to `delivery.production.started`, `delivery.production.completed`, and `delivery.postal.handed_over`?
|
||
2. Does the relevant Binect account/API configuration expose webhooks, or is polling the required baseline?
|
||
3. Which postal products are available for the target Binect customer/account?
|
||
4. Which cancellation states are possible after upload but before sending or production?
|
||
5. Which fields in the live Swagger/API represent child-document status for serial documents?
|
||
6. How should provider price calculation be represented when a document is uploaded but not yet sent?
|
||
7. Which preview formats are available in the target environment?
|
||
8. Are return-mail or undeliverable events available through API status, manual import, or a separate process?
|
||
9. Are registered-mail or delivery-confirmation products available in the target Binect configuration?
|
||
10. Should Binect-specific validation issues update a central contact/address quality registry?
|
||
|
||
## 32. Non-Goals
|
||
|
||
The Binect flavor is not:
|
||
|
||
* a document authoring system.
|
||
* a PDF renderer by default.
|
||
* a legal notice system by itself.
|
||
* a postal carrier.
|
||
* a general Binect UI replacement.
|
||
* the owner of coordination case success.
|
||
* the owner of contract, payment, or signature result semantics.
|
||
|
||
It integrates Binect hybrid-mail capabilities into the coordination framework.
|
||
|
||
## 33. Summary
|
||
|
||
`HybridmailBinectSpecification.md` defines the Binect provider flavor for `hybridmail-connect`.
|
||
|
||
The Binect flavor models Binect as a document-centric hybrid-mail provider with:
|
||
|
||
* document upload
|
||
* validation
|
||
* attachments
|
||
* print and shipping options
|
||
* preview
|
||
* sending
|
||
* document and shipping status
|
||
* serial/child document status
|
||
* production and postal evidence mapping
|
||
|
||
The key rule is:
|
||
|
||
> Binect events are provider, document, production, and postal-chain evidence. They are not automatic coordination result satisfaction. hybridmail-connect reports Binect-channel facts and uncertainty. coordination-engine evaluates intended results.
|
||
|