C1.2c Preserve Reply-To and copy recipients through Relay mail transport
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
Research direction
Start with community_base/mail/relay.py and community_base/mail/backends/relay.py: RelayMailClient.send() builds the HTTP payload but drops reply_to, cc, and bcc that send() already persists in EmailDelivery.transport_options. Add wire-capture regression tests in tests/mail/test_relay_backend.py, then map the validated options into Relay native fields, rejecting multiple Reply-To values with a sanitized RelayMailError before any request. Done means the captured POST /api/transactional/send JSON preserves the options in their native shapes, the multi-Reply-To case makes zero HTTP requests, and the package suite plus quality gates pass.
Written by the indexing model from the issue text.
Description
Title: C1.2c Preserve Reply-To and copy recipients through Relay mail transport
Repository: community-base
Depends on: C1.2a, C1.2b (both done)
Freeze required: no
Goal
Preserve the recipient routing options already validated and stored by durable mail when the selected backend is Relay. AISHL adoption issue AI-Shipping-Labs/website#2006 requires welcome replies, alternate recipients, and hidden staff copies to survive the transport change.
Confirmed regression
At package v0.5.33, send() validates and persists reply_to, cc, and bcc in EmailDelivery.transport_options, but RelayMailClient.send() omits all three from its HTTP payload. Offline capture of the actual transport request reproduces the omission. No live mail or production data is needed.
Read first
AGENTS.md,docs/PROCESS.md,docs/04-quality-gates.md.docs/01-decisions.md,docs/02-architecture.md.docs/03-playbooks.mdP15 and P16.community_base/mail/service.py,community_base/mail/relay.py.community_base/mail/backends/relay.py,community_base/mail/backends/ses_local.py.tests/mail/test_relay_backend.py,tests/mail/test_ses_local.py.docs/plan/phase-1.md,docs/plan/STATUS.md.
Steps
- Add the
C1.2cplan entry and synchronize its status before implementation; keep the fix on its isolated package branch. - Add capture-wire regression tests and show they fail against the omitted-field implementation.
- Explicitly map validated transport options into Relay native fields: singleton
reply_toas one string;ccandbccas lists. Omit absent or empty options. - Reject more than one Reply-To address before any HTTP request with a sanitized, nonretryable
RelayMailError; do not truncate, silently discard, or put addresses in the error. - Keep existing envelope construction and validation. Never merge the complete
transport_optionsobject into the payload. SES-onlyconfiguration_setand unsupported entries cannot become Relay fields or override core envelope fields. - Document supported Relay option shapes and the multi-Reply-To limitation. Retain SES transport behavior and existing sender, context, idempotency, suppression, and response handling.
- Run package tests and quality gates, then validate both consuming sites against this package change using disposable checkouts and P16. Follow the package PR process and P15 release-before-pin sequence.
Verification
- Capture the actual
POST /api/transactional/sendJSON through the injected transport; assert exact option values and native shapes together with unchanged core envelope fields. - Exercise singleton Reply-To, CC, BCC, combined options, omitted/empty options, SES-only configuration set, and unsupported multiple Reply-To. The last case must record zero HTTP requests.
- Run
timeout 900 uv run pytest tests/mailand the package suite with all extras installed; record collected counts and results. Run every applicable gate indocs/04-quality-gates.md, each command bounded bytimeout 900, plusuv run python scripts/plan.py check. - Record package, AISHL, and DTC results separately. Consumer validation must exercise the changed package, identify its exact revision, and distinguish baseline failures from new failures under P16. AISHL full local Django runs remain prohibited; use its affected-test selection or authoritative cross-repository CI.
- No real email, production credentials, or production database is required. This issue changes the shared package only; the AISHL core Django email backend Reply-To correction is a companion site task.
Done when
- Captured Relay JSON contains singleton
reply_toas a string and preservesccandbccas lists, including the combined-options case. - Missing or empty recipient options leave the ordinary send payload unchanged.
- Only supported recipient options are copied; SES-only configuration sets and unrelated option entries never become Relay fields or override recipient, template, version, context, sender, or idempotency data.
- Multiple Reply-To values fail explicitly with a sanitized, nonretryable error before the transport is called.
- Existing SES option forwarding and normal Relay behavior remain covered and pass.
- Package suite and applicable quality gates pass with collected counts recorded.
- AISHL and DTC validation against the changed package are recorded separately; any blocked validation is explicit and does not count as passing.
- Documentation and plan status match the implementation.
- Reviewed package PR is merged and a new immutable release exists before consumer pin changes.
Docs
community_base/mail/README.md.docs/plan/phase-1.md, generateddocs/plan/STATUS.md.CHANGELOG.mdand package version metadata during the approved P15 release.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- Avg merge
- 1h 5m
- Merged PRs (30d)
- 3
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from DataTalksClub/community-base
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
DataTalksClub/community-base#285 · 1 comment ·
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 25/100
DataTalksClub/community-base#419 · 1 comment ·
-
Difficulty 3/5 1-2 days Newbie friendliness 58/100
DataTalksClub/community-base#417 ·
-
Difficulty 5/5 Over a week Newbie friendliness 12/100
DataTalksClub/community-base#414 · 7 comments ·
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
DataTalksClub/community-base#410 · 1 comment ·
All issues in DataTalksClub/community-base
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
btclib-org/btclib#3062 ·
Maintainers usually reply within 1 day
-
area:evals area:infra enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
jse-avl/support-bot#4 · 1 comment ·
-
bug good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
qte77/agentic-job-offer-to-application-kit#487 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
btclib-org/btclib-wallet#801 · 1 comment ·
Maintainers usually reply within 1 day
-
documentation good first issue
Difficulty 1/5 1-3 hours Newbie friendliness 94/100