Preserve scoped sender and email-header behavior for AISL
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 25/100
Hướng nghiên cứu
First resolve the blocked ownership and write-set allocation, then characterize mailing/services/senders.py, mailing/services/transactional.py, mailing/services/transactional_sender.py, mailing/services/campaign_sender.py, and mailing/ses.py. Run the focused mailing/tests suites with deterministic SES and queue fakes before changing behavior. Done means the listed sender, header, snapshot, safety, and replay controls pass without changing unrelated clients or adding unallocated schema/state.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Preserve scoped sender and email-header behavior for AISL
Status: groomed scope for existing #39 under parent #30 P03/S1. Implementation scope is blocked on allocation of the concrete overlapping write set and agreement on canonical sender/options integration. No source ownership is transferred by this draft. Proposed labels: existing enhancement/community-base; no new label is assumed.
Goal
Carry AISL's existing sender/header/envelope behavior through the native Relay transactional and campaign paths, with one canonical generic sender/options concern and a thin AISL purpose/configuration mapping. Preserve recipient-visible From/Reply-To/subject/plain/HTML/header actions, current clients' APIs/options/history and all existing UI. This is sender/header capability acceptance, not whole template/profile, campaign, calendar or real adoption acceptance.
Donor IDs: AISL-EM-C02,C03,C04,S03; cross-contract J02,J03,A05. Frozen donor f9a3b0432864d40f6f12a85382df4a25c4e3f98f; committed preparation source Relay6d34abf520029cc3bd955467c3cf3f32c97c6ab6 (tree9d00a2d613529a545e71a58a81759e8ab91c8537), with original target cdf3a9a25de8bd63af8ee45285983d28a3aa13a0. No remote freshness or executed preservation claim.
Existing contracts and actual prerequisites
- #1 owns credentials, safe version/render validation and immutable final content/sender snapshots. #2 owns options hashing, request replay/conflict, transactional claim/suppression/eligibility and states. #32 owns BOTH sender paths' accepted/unknown-outcome fencing. Reuse them; no new delivery state, retry engine or mutable snapshot owner.
- #22 owns campaign audience/snapshot/operator actions; this issue changes only its agreed sender/header call boundary. #37 consumes P03 for full calendar/native flow and preserves ordinary/absent-calendar behavior; no MIME/lifecycle implementation here. #29/#35 supply footer/profile contracts without awarding this issue another renderer.
- Before editing coupled source: allocate exact integrated base/write paths, reconcile actual protected model/API/campaign WIP, and agree the narrow canonical sender/options projection and AISL mapping input. Respect existing upstream issue dependencies; do not silently fork or weaken them. Empty tracker assignees and queued peer notices establish no lease release.
- Characterization/stub contract work can precede the complete preservation result under an allocated scope. Sender/header parity evidence is produced during implementation before acceptance; it is not a finished artifact required before assigning that work. Full dynamic template/chrome comparison belongs to #35/parent, not an artificial prerequisite that blocks every scoped S1 backend test.
- Real adoption separately requires #25/D13 sender/domain/client readiness and authorized release/cutover receipts. It is not necessary to access production or import real donor data to implement deterministic S1 capability tests. P07 action/token timing remains a distinct unresolved integration boundary; no live-token freshness proof from an early snapshot.
Bounded implementation
- AISL owns runtime IntegrationSetting/settings/env classification precedence, transactional/promotional purposes and welcome-as-transactional sender selection. Map to an authorized client-scoped native sender ID/options without copying donor classification into Relay. New kind-specific key wins; legacy SES_FROM_EMAIL only when that key is unset, then committed defaults. Preserve historical None/unknown-but-rendered transactional sender fallback in the thin adapter; unknown explicit purposes remain rejected. Do not invent a team kind.
- Relay's canonical sender/options validation and projection carry the selected sender identity/address, Reply-To, CC/BCC, headers/configuration set into the existing immutable request/snapshot/worker/SES paths. Keep tenant/client isolation and default native omitted-option semantics. No arbitrary address override or new endpoint solely for AISL compatibility.
- For AISL, valid welcome-only configured Reply-To is included; invalid/empty configuration is omitted. Campaign/nonwelcome Reply-To remains omitted. This adapter rule must not disable another client's valid native Reply-To or waive native injection/type validation.
- Promotional From and final HTTPS unsubscribe token agree between body and List-Unsubscribe; optional configured mailto and exact one-click List-Unsubscribe-Post remain. Use the agreed canonical final output/action projection; no second token generator or new durable business-input URL exception. All recursive AC6 absolute/scheme-less/bearer-query/signed-URL guards and sanitized top-level return_path exception remain. Legitimate final immutable body/header/history snapshots remain.
- Preserve UTF-8 subject/text/HTML, omission/normalization of empty CC/BCC, configuration-set selection, disabled/test provider short-circuit before client construction, rate/queue isolation, privacy redaction and known versus unknown outcome classes. Do not rewrite selected body content, chrome/footer actions or ordinary attachments. #37 handles native calendar topology; old donor calendar/operator/privacy consumers remain until their accepted replacements.
- Prepared content/options stay frozen and hashed by #1/#2; later sender/config edits cannot mutate prepared messages, and claim checks still block revoked/disabled sender/client/suppression. Replays and conflicts use canonical rules. #32 accepted/unknown results never re-enter automatic provider resend; this issue must not add another SDK/recovery retry path.
Cohesive source and ownership scope
Review surfaces at the bound committed source:
- mailing/services/senders.py: sender ID normalization, configured sender map and client-scoped resolution.
- mailing/services/transactional.py: existing option/header validation and prepared projection; mailing/services/transactional_sender.py consumes options.
- mailing/services/campaign_sender.py: currently uses DEFAULT_FROM_EMAIL and does not carry full S1 metadata; coordinate its exact call boundary with #22/#32 and protected campaign work.
- mailing/ses.py (not mailing/services/ses.py): existing Simple/raw SES payload construction, UTF-8, headers/options/configuration set and ordinary attachments.
- Canonical API/docs and focused existing tests only where this narrow contract changes; no assumed model migration. If new persistent metadata is genuinely necessary, stop for ownership/schema allocation rather than assigning reserved migration0030 or piggybacking model growth.
- AISL email_classification.py/package_mail.py/ses_transport.py are donor anchors and potential separately allocated thin mapping boundaries, not permission to edit that repository from this Relay issue. Agree normalized synthetic mapping inputs and coordinate the existing AISL release owner; source eligibility is a separate handoff.
Keep one business owner and thin API/worker call sites. User-required portable rules apply: DRY, explicit transactions, no ternaries/simple loops, functions<=30/new handwritten files<=300. Do not add arbitrary fragments or invented oversized-file waivers. A genuinely required extracted options concern moves as one cohesive owner and preserves existing public imports/errors; it does not clone validation/model fields.
Acceptance criteria
- Sender precedence and welcome transactional disposition match the exact donor policy, with no team kind or marketing-unsubscribe regression.
- Selected sender is scoped/authorized; other client's same ID cannot resolve into AISL or disclose configuration. Disabled/revoked sender/client behavior remains claim-safe under #2.
- Valid welcome Reply-To and invalid/empty omission, campaign/nonwelcome omission for AISL, and unrelated native clients' valid options all pass characterization and new controls.
- Final promotional body/header token equality, optional mailto, one-click header, configuration set, UTF-8 fields, CC/BCC omission/envelope and ordinary raw/attachment behavior pass exact stub-payload comparisons.
- Recipient-safe synthetic output evidence covers transactional/promotional/welcome and another native client. Subject/plain/HTML/authored action targets are unchanged except the explicitly required preserved sender/header projection; normalization permits only justified MIME encoding/boundaries and fixed synthetic token/clock values. No UI/routes/control changes.
- Wrong scope/type/sender/header injection fails safely before message/job/queue/provider work; disabled/test paths construct no provider client. Errors/logs expose no recipient/context/body/action tokens/credentials/raw provider errors.
- Queue reference→existing worker→SES stub preserves frozen options/content; exact replay and changed-option conflict, claim-time revocation and #32 accepted-then-response-lost never-auto-resend controls pass. No alternative state engine.
- Safe preview/dry-run use canonical no-write/no-queue/no-provider validation; real/test-send retains canonical allowlist/audit behavior. Synthetic tests create no donor live EmailLog/history or actual email; legitimate Relay test audit is not falsely prohibited.
- API/docs truthfully describe the narrow supported contract and existing-client behavior. Fresh independent Tester terminal report binds exact source/test/evidence hashes and commands; PM accepts S1 fidelity. Parent #30 remains open and dependent work is not marked passed.
Required verification after assignment
First characterize affected source behavior and add meaningful unit/service/worker assertions using deterministic SES Stubber/provider fakes and SQS-shaped direct handler input. Compare decoded raw MIME plus envelope when headers select the raw path; a Simple-only assertion cannot prove unsubscribe/header fidelity. Verify negative controls for mismatch tokens, CRLF/header injection, foreign sender, omitted/invalid Reply-To and accepted-then-lost response. Spy on provider-client construction and queue calls, not merely return values. No real AWS/LocalStack service is needed unless actual scope changes AWS-local wiring.
Commands from current Relay process/Makefile, to be run later in the assigned environment, not executed by this grooming:
git diff --check
uv run pytest mailing/tests/test_ses.py mailing/tests/test_transactional_api.py mailing/tests/test_transactional_dry_run.py mailing/tests/test_transactional_sender.py mailing/tests/test_campaign_sender.py
make test
make lint
If an intentional model/schema change is subsequently approved, add repository migration-state and fresh/reverse/reapply gates, including uv run python manage.py makemigrations --check --dry-run. Meaningful PostgreSQL concurrency remains canonical #2/#32 testing where affected; do not duplicate whole unrelated suites. Setup/environment synchronization belongs to the assigned test owner. UI screenshots are N/A if screens are unchanged; recipient payload/render evidence is mandatory for this contract. Follow Relay SWE→independent Tester→PM→focused commit→root integration/push→sole OnCall; no PR authority introduced.
Client migration window, observability and retirement
Real external client: AISL website; other native Relay clients retain their contracts. Compatibility uses first-class generic sender/options APIs plus a minimal site mapping, not cloned AISL endpoints or a permanent duplicate transport.
The window starts at approved rehearsal and ends only after S1 and every remaining consumer's actual parity, authorized development-copy/adoption, queued-intent fencing/drain/rollback and caller-retirement receipts. No guessed date. Record safe aggregate fallback/shim use and policy/reason codes with client-safe sender IDs; no addresses, action links/tokens, bodies/context/secrets. Zero usage alone never authorizes deletion.
Removal ledger binds each donor caller/path, replacement, donor IDs, fresh Tester/PM and adoption receipts, queued accepted/unknown/unsent disposition and rollback owner. Retain shims/SES identity/calendar raw path/operator/privacy/history/UI until their own preservation gates pass. This issue's Done means accepted scoped local capability plus its required repository shipping gates, not #25 real readiness, full #35/#37 parity, source adoption or parent completion; later owner receipts stay explicitly pending.
Environment and authority note
Relay process guidance still uses Datamailer repo/pre-production wording. Actual repository is DataTalksClub/relay and user confirmed relay.datatalks.club production. That confirmation resolves naming, not production permission. No live credential/send/domain/deploy/cloud/import/history deletion or scheduler operation belongs to implementation verification here. Guidance alignment is separate from this issue's narrow source scope.
- Ngôn ngữ chính
- Python
- Star
- 0
- Fork
- 0
- Merge trung bình
- 11 phút
- Pull request đã merge (30 ngày)
- 4
Chuẩn bị môi trường
- Có Dockerfile hoặc tệp Docker Compose
- Không có mẫu pull request
- Không có hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của DataTalksClub/relay
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
DataTalksClub/relay#48 ·
-
enhancement
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 20/100
DataTalksClub/relay#49 · 3 bình luận ·
-
bug
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 20/100
DataTalksClub/relay#42 · 7 bình luận ·
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 15/100
DataTalksClub/relay#41 · 9 bình luận ·
-
community-base enhancement
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 15/100
DataTalksClub/relay#37 · 15 bình luận ·
Tất cả issue của DataTalksClub/relay
Issue tương tự
-
integration: logger
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
home-assistant/core#191147 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
documentation p4
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 88/100
MillenniumDawn/focus-tree-creation-tool#417 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
CharlesP44/Beem_Energy#96 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
rheeloaded/paperpull#153 ·
Maintainer thường phản hồi trong vòng 1 ngày