tc-mail-orchestrator
.NET 8 orchestration service for automated customer emails: consumes booking/TC Score/passport events over MassTransit and schedules the right email (thank-you, pre-departure, welcome-home, reminders) via the mail scheduler and composer.
Health score
0 to 100 across seven weighted factors; nothing is hidden. Green is 75 and above, amber 50 to 74, red below 50. How scoring works.
Facts
| Languages | csharp |
| Frameworks | ASP.NET Core 8, MassTransit 8 |
| Runtimes | .NET 8 |
| Tests / CI | some / CI in place |
| Last commit | 2026-06-08 |
| Owner | Owner unknown (mapping to be curated) |
| Domain | Customer communications (system generated; curate in repo-owners.json to override) |
| Product area | Shared platform |
| Hosted | AWS Deployed to AWS
|
| Releases | 0 release pipeline(s): |
| Integration | rest, masstransit, sqs |
| Source | Open in Azure DevOps |
Dependencies in context
Entanglement
loose No binding mechanisms apply: this system needs no untangling work.
Migration playbooks
Generated from this repo's assessment data: what is feasible, what blocks it, and the steps in order. Ratings: green means actionable now, amber means sequence other work first, red means blocked, grey means not applicable.
ZDD adoption
No excuseNothing technical is holding this repo on the three-week release. It either already deploys without downtime (AWS) or is a modern, well-tested service the automated stealth path can carry today. Already deploys as a container to AWS, which releases without downtime today. Separating it from the three-week release is a process decision, not a technical one.
- Serialized state or messages in flight (Redis or queues): new code must deserialize objects written by the previous version
- Adopt the four-stage discipline from the ZDD engineering standard: pre-deployment compatibility, deployment, feature activation behind a flag, post-release cleanup.
- Raise automated test coverage first: ZDD trades the end-of-sprint manual gate for continuous automated confidence, so the tests are the entry ticket.
- Make every change dual-version safe: backwards-compatible APIs (new major version for breaking wire changes), expand and contract for any schema change, and consumers tolerant of unknown fields.
- Audit serialized data: anything in Redis, queues or shared caches must deserialize cleanly across adjacent versions.
- Wrap behaviour changes in feature flags so code deploys dark and release becomes a business decision, not a deployment event.
- Use ECS rolling deployments with health checks gating traffic, and take this service off the three-week release train.
- Verify with area-scoped regression rather than the whole-platform cycle, and watch error rates after rollout with automated rollback on alert.
SQL Server exit
Not applicableNo SQL Server dependency is recorded for this repo. Nothing to migrate.
Containerisation
Already containerisedIts pipelines already build containers and deploy to AWS. Nothing to do here.
Recommended actions
No specific actions for this repo. It either needs only normal maintenance, or its work is covered by an estate-level action. See the full programme.
Assessment notes
tc-mail-orchestrator
Purpose
The decision layer of the modern TC mail pipeline. Event-adapter consumers handle BookingChanged (arriving from Redis streams via the streams-MassTransit adapter), PassportExpiringSoon, TC Score saved/updated/deleted, and ScheduleCustomEmailCommand; per-email-type rules in config (ThankYouForBooking +2 days from booking, HaveANiceTime -4 days before departure, WelcomeHome +2 days after return, PassportReminder -270 days before expiry, TcScore/TcScoreReminder) compute send times, and scheduling/composition commands are issued to tc-mail-scheduler and tc-mail-composer.
Tech stack
C# on .NET 8: MassTransit 8.5 over Amazon SQS/SNS with S3 claim-check support, FluentValidation, Polly, Swashbuckle/OpenAPI on the host, TC.Cognito.Auth.Client for outbound authenticated calls, ConnectionBroker, TC health checks. Sub-projects wrap the mail-scheduler API client and a PublicTravelCounsellors API client; tools/CustomEmailSender.Net10 is a documented console test client for injecting custom email commands.
Deployment
Included via build->yaml-deploy with 0 classic releases: build pipeline tc-mail-orchestrator from azure-pipeline.yaml, shared InternalOSS ci.yml (SDK 8.x), containerAfterBuild: true into the cx namespace, ECS Terraform from aws-cx-tc-apps (eu-west-1, functional area cx).
Dependencies
Internal: TC.Mail.Composer.Contracts (tc-mail-composer), TC.Mail.Scheduler.Contracts (tc-mail-scheduler), TC.StreamsMassTransitAdapter.Events (tc-streams-masstransit-adapter), TC.PassportExpiration.Service.Events (tc-passport-expiration-service), Phenix.Contact.Contracts (phenix-contact-api), TC.Phenix.CompanyInfo (company-info-api), the public Travel Counsellors profile API (tc-public-travelcounsellors) and TC.ConnectionBroker.*/TC.Diagnostics platform packages. External: AWS Cognito for service-to-service auth.
Data stores
None of its own — state lives with the scheduler; the orchestrator is stateless event-in/command-out logic with config-driven timing calculators and email-rewrite processors.
Integration points
MassTransit over Amazon SQS/SNS for all event consumption and command publication; outbound REST (via ConnectionBroker with Cognito auth) to the mail-scheduler and public-TC APIs; a small inbound HTTP host with Swagger and health checks.
Code health
One unit-test project (~14 test files) covering calculators and consumers — adequate but not deep. The README is mostly boilerplate except for a genuinely useful test-client section. Actively maintained — last commit 2026-06-08.
Modernisation risks
Low — modern .NET 8, containerised, message-driven. Risks are of the coupling kind: it sits at the centre of the mail pipeline fan-out (five upstream event/contract packages and two downstream mail services), so contract version drift is the likeliest breakage, and email-timing business rules live in per-environment config that has no owning UI or validation.
Data store follow-up (2026-07-28)
A targeted scan of project files confirmed no database. The service uses Amazon S3 through MassTransit.AmazonS3 (large message payloads offloaded to a message-data bucket, resolved at runtime via SSM), now recorded as a data store, alongside SQS/SNS messaging via MassTransit.