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

tc-mail-tracked

.NET 8 API and MassTransit consumers wrapping the Spotler (WebPower) and Hive email-marketing platforms: sends transactional emails, syncs customer lists over SFTP and refreshes campaign reporting into MongoDB.

85 · greenmediumlooseAWSZDD: no excuseservicesecrets in source

Health score

85

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
15
Good test coverage
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): 85
Baseline 85 recorded 2026-07-27. The trend fills in with each monthly assessment run.

Facts

Languagescsharp, typescript
FrameworksASP.NET Core 8, MassTransit 8, AWS Lambda
Runtimes.NET 8, nodejs 20
Tests / CIgood / CI in place
Last commit2026-03-19
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-tracked" (azure-pipeline.yaml): AWS signal "ecsTerraformRepo"
  • build "tc-mail-tracked-lambdas" (build-node.yaml): AWS signal "useTFVarsDeployment: true"
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
    • 2 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. 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.
    3. Audit serialized data: anything in Redis, queues or shared caches must deserialize cleanly across adjacent versions.
    4. Wrap behaviour changes in feature flags so code deploys dark and release becomes a business decision, not a deployment event.
    5. Use ECS rolling deployments with health checks gating traffic, and take this service off the three-week release train.
    6. 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-tracked

    Risk flags indicate credentials or keys in source (plaintext-credentials). 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-tracked

    Purpose

    Anti-corruption layer over the third-party email-marketing platforms Spotler (travelcounsellors.webpower.eu) and Hive: sends transactional emails (mailing IDs per email programme per company UK/IE/NL/BE/ZA/AE), uploads customer/subscriber lists via SFTP, and refreshes campaign and reporting data into MongoDB. Two EventBridge-triggered TypeScript Lambdas (tc-mail-tracked-spotler-refresh, tc-mail-tracked-hive-refresh) publish Refresh*CampaignsCommand MassTransit envelopes to SNS. It emits transactional-email-activity events consumed upstream by tc-mail-scheduler.

    Tech stack

    C# on .NET 8 across a provider-oriented solution (Api, core, Contracts, Persistence, Provider, per-provider Spotler and Hive Provider/Services projects): MassTransit over TC.MassTransit.AmazonSQS, Mapster, FluentResults/FluentValidation, Polly, CsvHelper, SSH.NET for SFTP, MongoDB.Driver via TC.ConnectionBroker.Mongo, System.ServiceModel packages, Swashbuckle. Lambdas are TypeScript/webpack/Jest on @tc/tc-aws-lambda-core.

    Deployment

    No classic release pipelines (release_count 0); YAML-only. azure-pipeline.yaml uses the shared InternalOSS/azure-pipelines-templates ci.yml (SDK 8.x), packs TC.Mail.Tracked.Contracts, builds the API container (namespace cx) and deploys via Terraform tfvars into aws-cx-tc-apps ECS; build-node.yaml deploys the Node 20 Lambdas; deploy-mongodb.yaml runs Mongo script-runner migrations. Build pipelines: tc-mail-tracked, tc-mail-tracked-lambdas.

    Dependencies

    Internal packages: TC.ConnectionBroker.* (tc-connectionbroker), TC.Mail.Composer.Contracts (tc-mail-composer, send-transactional-email commands), TC.Mail.Scheduler.Contracts (tc-mail-scheduler, scheduled-email-send-failed events), TC.Diagnostics.HealthChecks (tc-diagnostics-portal). External: Spotler/WebPower REST API and SFTP, Hive FTP/API, AWS (SNS/SQS/EventBridge/Lambda/ECS), Cognito.

    Data stores

    Owns the MailTracked MongoDB database (campaigns, reporting, customer list state; Mongo script-runner migrations). No SQL Server.

    Integration points

    Inbound REST (Campaigns, CampaignsReporting, Customers, Hive, Lists, TransactionalEmails controllers, Swagger); MassTransit over Amazon SQS/SNS (send-transactional-email and refresh-campaign command consumers, send-failed event consumers); outbound REST plus SFTP to the two vendor platforms.

    Code health

    Good: 237 xUnit facts/theories across Api, core, Persistence and per-provider test projects, shared fixtures, coverlet, and the standard TC analyzer set via Directory.Build.props. No README at all. Last commit 2026-03-19.

    Modernisation risks

    Medium, driven by hygiene rather than stack: real-looking Spotler API client secrets and SFTP passwords are committed in plaintext in appsettings.json and appsettings.production.json (rotation and a move to a secret store needed). Otherwise a modern .NET 8/ECS service; the same hand-rolled MassTransit envelope construction in the Lambdas as tc-mail-scheduler, and heavy per-environment mailing-ID configuration coupled to vendor campaign setup.