tc-score
.NET 8 Windows-service worker that emails TC Score feedback-request cards (and reminders) to customers after a booking, using localised HTML templates per country and travel type.
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 | .NET Worker Service |
| Runtimes | .NET 8 |
| Tests / CI | some / CI in place |
| Last commit | 2026-02-10 |
| Owner | Owner unknown (mapping to be curated) |
| Domain | Agent tools and community (system generated; curate in repo-owners.json to override) |
| Product area | Shared platform |
| Hosted | On-prem Deployed to our own machines
|
| Releases | 1 release pipeline(s): tc-score |
| Integration | sqlserver, smtp |
| Source | Open in Azure DevOps |
Dependencies in context
Entanglement
loosely attached Bound into the core by 1 mechanism(s).
- Shares core database sqlserver:ContactCentre
Detaches when the shared database group it belongs to gains an owned API or completes schema separation (sqlserver:ContactCentre).
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
Ready with guardrailsClose: the deployment path exists, but specific checks are needed first, typically raising tests, auditing serialized data, or respecting a shared schema with expand and contract. Shares sqlserver:ContactCentre: expand and contract is mandatory for any schema change. Test coverage is thin; ZDD shifts the safety net onto automation.
- 1 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
- Shares sqlserver:ContactCentre with 8 system(s): destructive schema change is prohibited in a single release; expand and contract only
- Runs as a Windows service or scheduled task: deploy between runs or use overlapping instances; the load-balancer drain pattern does not apply directly
- 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.
- Route deployments through the Workflow Engine's automated drain, deploy, health-check, return cycle (the path proven by the first automated production run in mid-2026).
- 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
Blocked by a shared core databasesqlserver:ContactCentre is shared, so this system cannot change engine on its own: every sharer moves in convoy. The stage 4 work (named owner, declarative schema, owned API) has to land first; after that, the steps below apply to whatever slice this system ends up owning.
- Inventory the schema and query surface of sqlserver:ContactCentre: tables, stored procedures, triggers, cross-database joins and anything else engine-specific.
- Confirm the target: PostgreSQL (relational model; keep transactions and joins, swap the engine).
- Data access is not through an ORM, so port the SQL by hand: translate T-SQL constructs, replace stored procedures with application code or target-native equivalents, and add integration tests around the queries that matter first.
- Stand up the target alongside SQL Server, backfill with an ETL pass (pgloader or an export/import job), then dual-write or replicate until parity is proven.
- Move reads to the target, watch correctness and latency, then cut writes over and keep SQL Server read-only until confidence is earned.
- Decommission the SQL Server database and remove the connection strings and firewall paths that pointed at it.
Containerisation
Ready to containeriseModern runtime, no hosted legacy transport: this service can follow the estate's proven container path (Dockerfile, shared pipeline template, ECS via Terraform).
- Convert the Windows service or scheduled task into a .NET worker service (or an ECS scheduled task) so it has a container-shaped lifecycle.
- Add a Dockerfile and make the app read all configuration from environment variables and the secrets manager, never from machine-local files.
- Log to stdout and expose a health check endpoint so ECS can supervise it.
- Adopt the shared ci.yml pipeline template with the container parameters (awsRegion, containerAfterBuild, ecsTerraformRepo), which is exactly how the estate's existing AWS services deploy.
- Define the service in the Terraform repo, deploy to a non-production environment, then shift traffic and disarm the deployment-group release pipeline.
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-score
Purpose
TC Score is the customer-feedback survey mailer: it periodically reads score cards due for sending from the ContactCentre database, renders per-company/per-country HTML email templates (Leisure and BusinessTravel variants under Email/, with a parallel Email - legacy/ tree still shipped), builds links into the legacy travelcounsellors.net/TCScore ASP.NET survey page with a checksum, and sends via SMTP. The phenix-contact-api front matter lists tc-score as a dependency, so it sits inside the contact-centre feedback flow.
Tech stack
C# on .NET 8 using the Worker SDK, hosted as a Windows service (Microsoft.Extensions.Hosting.WindowsServices, EventLog logging, win-x64 single-file publish) with Systemd support also referenced. Data access via TC.ConnectionBroker 1.20 + System.Data.SqlClient; TC.Exceptions client for error reporting, TravelCounsellors.ApiTools, TC.Phenix.CompanyInfo for company metadata, plain SmtpClient/MailMessage for mail.
Deployment
prod_application with 1 release: release pipeline tc-score from builds tc-score and tc-score CI; azure-pipelines.yml uses the shared azure-pipelines-templates CI job (dotnet SDK 8.x) with the test project wired in. Per-environment appsettings for qa/preproduction/production; runs on-premise as a Windows service.
Dependencies
Internal packages: TC.ConnectionBroker.* (tc-connectionbroker), TC.Exceptions.* (tc-exceptions), TC.Phenix.CompanyInfo (company-info-api client), TravelCounsellors.ApiTools (tc-api-tools). External: none beyond the SMTP relay.
Data stores
SQL Server — connection-broker target ContactCentre, the shared contact-centre database also used by the phenix contact-centre services, intranet and email server.
Integration points
SQL Server reads/writes for score cards; SMTP outbound for the emails; generated links point customers at the legacy travelcounsellors.net TCScore/Unsubscribe ASPX pages.
Code health
One small MSTest project (folder-map path logic and similar helpers) — thin coverage for the mailing logic. YAML CI with tests in the build. Actively maintained (last commit 2026-02-10); README is brief but real. The csproj carries ClickOnce-era cruft ("Copyright © 2010") from its .NET Framework past, and a duplicated legacy email-template tree bloats the deploy.
Modernisation risks
Low priority overall: modern .NET 8 with CI. Residual risks are the Windows-service on-prem hosting model, coupling to the shared ContactCentre database, dependence on legacy ASPX survey pages for the customer-facing side, and direct SmtpClient mailing rather than the estate mail-service.