Platform Evolution
Assessment run-2026-07-27-1 · 213 of 213 repos assessed
Repos / tc-mail-composer

tc-mail-composer

.NET 8 mail-composition service that consumes send-email commands off MassTransit/SQS, renders localised Razor email templates (TC Score, Trustpilot links, per-company profiles) and hands off to the mail sender/tracking services.

78 · greenlowlooseAWSZDD: no excuseservicesecrets in source

Health score

78

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.


Runtime currency / 25
25
Runs on supported modern .NET
Legacy transport / 15
15
No legacy WCF or SOAP surface
Test posture / 15
8
Some tests, coverage is thin
Security hygiene / 15
0
Credentials or keys committed to source
Dangerous coupling / 15
15
No dangerous coupling detected
Activity / 10
10
Actively maintained
Deployment hygiene / 5
5
CI in place
Health over time
2026-07-27 (run-2026-07-27-1): 78
Baseline 78 recorded 2026-07-27. The trend fills in with each monthly assessment run.

Facts

Languagescsharp
FrameworksASP.NET Core 8, MassTransit 8, RazorEngineCore
Runtimes.NET 8
Tests / CIsome / CI in place
Last commit2026-06-01
OwnerOwner unknown (mapping to be curated)
DomainCustomer communications (system generated; curate in repo-owners.json to override)
Product areaShared platform
HostedAWS Deployed to AWS
  • build "tc-mail-composer" (azure-pipeline.yaml): AWS signal "ecsTerraformRepo"
Releases0 release pipeline(s):
Integrationrest, masstransit, sqs
SourceOpen in Azure DevOps

Risk flags

Each flag links to its glossary definition.

Dependencies in context

Laying out the graph…
greenamberreddata store (square, dashed link)Node size follows fan-in. Click any node to open it.

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 excuse

    Nothing 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.

    Dependencies and gotchas
    • 3 system(s) depend on this repo; during a rolling deploy they will talk to old and new versions at once, so responses must stay compatible
    • Serialized state or messages in flight (Redis or queues): new code must deserialize objects written by the previous version
    Steps
    1. Adopt the four-stage discipline from the ZDD engineering standard: pre-deployment compatibility, deployment, feature activation behind a flag, post-release cleanup.
    2. Raise automated test coverage first: ZDD trades the end-of-sprint manual gate for continuous automated confidence, so the tests are the entry ticket.
    3. 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.
    4. Audit serialized data: anything in Redis, queues or shared caches must deserialize cleanly across adjacent versions.
    5. Wrap behaviour changes in feature flags so code deploys dark and release becomes a business decision, not a deployment event.
    6. Use ECS rolling deployments with health checks gating traffic, and take this service off the three-week release train.
    7. 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 applicable

    No SQL Server dependency is recorded for this repo. Nothing to migrate.

    Containerisation

    Already containerised

    Its pipelines already build containers and deploy to AWS. Nothing to do here.

    Recommended actions

    Rotate the credentials committed to tc-mail-composer

    Risk flags indicate credentials or keys in source (secrets-in-source). Rotate now and enable secret scanning in CI; this is independent of all other work.

    Impact: Closes a live security exposure at near-zero cost

    proposed

    Assessment notes

    tc-mail-composer

    Purpose

    The composition stage of the modern TC mail pipeline: SendEmailCommand/SendCustomEmailCommand consumers take structured email data (e.g. TC Score notifications), compose HTML using RazorEngineCore templates with per-language .resx resources and per-company profiles (UK, Ireland, Netherlands, Belgium, South Africa, UAE — each with its own Trustpilot domain and mail-tracked profile), then dispatch onward via TC.Mail.Sender and TC.Mail.Tracked contracts. A small API host fronts the service.

    Tech stack

    C# on .NET 8: layered Abstractions/Contracts/Core/Api projects, MassTransit over Amazon SQS (TC.MassTransit.AmazonSQS) with MassTransit.AmazonS3 claim-check support, FluentValidation, Mapster, Scrutor, AuthenticatedEncryption (for Trustpilot link tokens), Swashbuckle, ConnectionBroker AWS extensions and TC health checks. Publishes the TC.Mail.Composer.Contracts NuGet package.

    Deployment

    Included via build->yaml-deploy with 0 classic releases: build pipeline tc-mail-composer from azure-pipeline.yaml, shared InternalOSS ci.yml (SDK 8.x) packing the Contracts package and building the API app, containerAfterBuild: true into the cx namespace, ECS Terraform from aws-cx-tc-apps (eu-west-1, functional area cx).

    Dependencies

    Internal: TC.Mail.Sender.Contracts (tc-mail-sender), TC.Mail.Tracked.Contracts (tc-mail-tracked), TC.Phenix.CompanyInfo (company-info-api), TC.ConnectionBroker.* (tc-connectionbroker), TC.Diagnostics.HealthChecks (tc-diagnostics-portal). External: Trustpilot (encrypted review-invitation links per company domain).

    Data stores

    None of its own — it is a stateless transformer between queues. MassTransit.AmazonS3 is wired for claim-check payloads, and links point at the TC Score page on travelcounsellors.net.

    Integration points

    Consumes and publishes MassTransit messages over Amazon SQS; small inbound REST API host with Swagger and TC health checks; outbound behaviour is entirely message-based to the sender/tracked services.

    Code health

    Two unit-test projects (~20 test files) with shared test helpers, StyleCop rulesets and Nerdbank-style versioning. README is untouched boilerplate. Active — last commit 2026-06-01. Trustpilot crypt/auth keys and the TC Score checksum GUID are committed in plaintext, including production values in appsettings.production.json.

    Modernisation risks

    Low platform risk (.NET 8, containerised, message-driven), but the committed Trustpilot encryption/auth keys should be rotated and moved to SSM/secrets management. Otherwise its risks are coupling ones: correctness depends on the tc-mail-sender/tc-mail-tracked contract packages and on company profile config staying in step with the company-info data.

    Data store follow-up (2026-07-28)

    A targeted scan of project files confirmed no database. The service does use Amazon S3 through MassTransit.AmazonS3 (large message payloads offloaded to a message-data bucket, resolved at runtime via SSM), which is now recorded as a data store. Messaging is SQS/SNS via MassTransit.