phenix-attractions
Phenix attractions product: API for searching, quoting and booking attraction tickets/excursions, plus a legacy WCF configuration service and back-office integration.
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, sql |
| Frameworks | ASP.NET Core 8, WCF, FluentResults |
| Runtimes | .NET 8, .NET Framework 4.6.2 |
| Tests / CI | good / CI in place |
| Last commit | 2026-07-23 |
| Owner | Owner unknown (mapping to be curated) |
| Domain | Selling and quoting (system generated; curate in repo-owners.json to override) |
| Product area | Phenix |
| Hosted | On-prem Deployed to our own machines
|
| Releases | 2 release pipeline(s): \commercial\attractions\attractions-api; \commercial\attractions\attractions-configuration-service |
| Integration | rest, wcf, redis |
| Source | Open in Azure DevOps |
Dependencies in context
Entanglement
kernel Bound into the core by 2 mechanism(s).
- Speaks WCF (host)
- Shares core database sqlserver:Phenix
Detaches when its WCF surface gains a modern interface or its WCF calls move to one; and when the shared database group it belongs to gains an owned API or completes schema separation (sqlserver:Phenix).
Depends on / used by
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
A long roadTechnically eligible one day, but the blockers are structural: hosted WCF or SOAP contracts that cannot run two versions at once, or heavy legacy coupling. Sequence the modernisation work first. Hosts WCF or SOAP endpoints: strict serialization contracts cannot safely run two versions at once (the shared-enum trap). End-of-life runtime compounds the work. Shares sqlserver:Phenix: schema changes move in convoy.
- 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:Phenix with 21 system(s): destructive schema change is prohibited in a single release; expand and contract only
- Serialized state or messages in flight (Redis or queues): new code must deserialize objects written by the previous version
- Session is externalised to Redis: keep it that way, and check session object compatibility between versions
- Adopt the four-stage discipline from the ZDD engineering standard: pre-deployment compatibility, deployment, feature activation behind a flag, post-release cleanup.
- 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:Phenix, sqlserver:AttractionsRepository are 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.
- sqlserver:Phenix is shared with 21 other system(s) and is a core database
- sqlserver:AttractionsRepository is shared with 1 other system(s)
- Inventory the schema and query surface of sqlserver:Phenix, sqlserver:AttractionsRepository, sqlserver:ProviderArabianAdventures: 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).
- Replatform to modern .NET first (see the recommended actions): current PostgreSQL and MongoDB drivers and EF Core providers target modern .NET, and doing one risky change at a time is cheaper than doing two.
- 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
Feasible after replatformingAppropriate eventually, but not from here: the legacy runtime and the hosted WCF surface both have to go first, and that work is already in this repo's recommended actions.
- .NET Framework only runs on Windows; practical (Linux) containers need modern .NET
- Hosts WCF or SOAP endpoints, which have no home on modern .NET; consumers need a modern interface first
- Replatform to modern .NET first (see the recommended actions), replacing the hosted WCF/SOAP surface with REST, gRPC or messaging so consumers can follow. Containerising then becomes routine.
- 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
Replatform phenix-attractions to modern .NET
Runs on .NET 8, .NET Framework 4.6.2, out of mainstream support. No pinning dependency blocks it; sequence by fan-in (providers before consumers). Shares sqlserver:Phenix, so batch it with its database group (stage 4).
Impact: Unblocks 1 dependent system(s)
proposedAssessment notes
phenix-attractions
Purpose
Owns the attractions component of the Phenix selling platform: the Attractions.Api handles search, quote-basket integration, pricing/markup and booking of attractions (with Arabian Adventures as a supplier-backed provider database), while a legacy configuration WCF service host manages attraction configuration. Back-office integration projects push bookings downstream.
Tech stack
Mostly C# on .NET 8 (API, service, configuration API and tests) with central package management, StyleCop and rulesets; the API ships a Dockerfile and docker-compose. Legacy remnants on .NET Framework 4.6.2: the configuration WCF service host and service contract. Redis-backed remote session (TC.RemoteSession.Redis).
Deployment
Two build pipelines matching in-repo YAML (build-api.yml for phenix-attractions-api, build-configuration.yml for phenix-attractions-configuration-service-host), released via \commercial\attractions\attractions-api and attractions-configuration-service; release_count 2. Builds use shared InternalOSS/azure-pipelines-templates with .NET 8 SDK.
Dependencies
Internal (via TC NuGet packages and service clients): tc-connectionbroker, tc-exceptions, phenix-place-repository, phenix-quote (quote service contract/API client), tax-service, service-fee-api and tc-phenix-cancellation; back-office facade/integration and quote-system, booking-document and user-account clients call the wider Phenix/back-office estate. Reads the shared Phenix database owned by phenix-database. External: Arabian Adventures attraction supplier data.
Data stores
Shared Phenix SQL Server database plus AttractionsRepository and ProviderArabianAdventures SQL databases (resolved via ConnectionBroker); Redis for remote session state.
Integration points
Inbound REST API consumed by the Phenix quote/selling UI; legacy WCF configuration endpoint; outbound WCF/REST to quote, tax, service-fee, cancellation and back-office services; Redis session sharing with the Phenix web estate.
Code health
Good: unit tests across API, service, configuration and back-office integration, plus a dedicated integration-test project and shared testing library. CI in place. Last commit 2026-07-23, actively developed.
Modernisation risks
Configuration service host remains WCF on .NET Framework 4.6.2 (EOL) and needs replacing with the newer configuration API. Coupling to the shared Phenix database and binary-serialised Redis session ties it to legacy platform patterns. Core API itself is modern .NET 8.