phenix-p2p
.NET 8 monorepo for the Phenix point-to-point transfers component: a gateway API, selling and metrics APIs, provider anti-corruption-layer services (Mozio, HolidayTaxis, BedsOnline, DirectStock, mock) and a Redis message clean-up task.
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, MediatR, Dapper, AutoMapper, OpenTelemetry |
| Runtimes | .NET 8 |
| Tests / CI | good / CI in place |
| Last commit | 2026-07-22 |
| 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 | 9 release pipeline(s): \commercial\p2p\p2p-acl-bedsonline; \commercial\p2p\p2p-acl-directstock; \commercial\p2p\p2p-acl-holidaytaxis; \commercial\p2p\p2p-acl-mock; \commercial\p2p\p2p-acl-mozio; \commercial\p2p\p2p-gateway-api; \commercial\p2p\p2p-metrics-api; \commercial\p2p\p2p-scheduledtasks-redismessagecleanup; \commercial\p2p\p2p-selling-api |
| Integration | rest, graphql, redis, redis-streams, jwt |
| Source | Open in Azure DevOps |
Dependencies in context
Entanglement
kernel Bound into the core by 2 mechanism(s).
- Pinning dependency: mail-service
- Shares core database sqlserver:Phenix
Detaches when its pinning dependencies are cut or multi-targeted (mail-service); 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
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:Phenix: expand and contract is mandatory for any schema change.
- 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
- 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:Transfers 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:Transfers is shared with 1 other system(s)
- Inventory the schema and query surface of sqlserver:Phenix, sqlserver:Transfers: 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).
- 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
phenix-p2p
Purpose
Monorepo (explicitly trunk-based, no develop branch) for the point-to-point transfers component. Deployables: P2P.Gateway.Api (search/book/amend/cancel orchestration plus booking pre-population from accommodation, flight and cruise data), P2P.Selling.Api (markups), P2P.Metrics.Api, provider ACL services for Mozio, HolidayTaxis, BedsOnline, DirectStock and a mock provider, and P2P.ScheduledTasks.RedisMessageCleanup. Shared libraries cover ACL plumbing, triage/FreshDesk escalation, email and company configuration.
Tech stack
All 33 projects target .NET 8 with central package management, StyleCop/Sonar/SecurityCodeScan analysers and Nerdbank GitVersioning. ASP.NET Core APIs use MediatR, FluentValidation, AutoMapper, Polly, OpenTelemetry (OTLP exporter), PhenixAuthLib plus API-key claims, Dapper for SQL, StackExchange.Redis, MongoDB.Driver, and GraphQL.Client.
Deployment
One repo drives 12 build pipelines and 9 release pipelines under \commercial\p2p\ (release_count 9) — each deployable has its own azure-pipelines.yml with path-filtered triggers so components ship independently. Docker-compose exists for local development.
Dependencies
Internal: tc-connectionbroker (Sql/Redis/Api brokers), phenix-cart-api (Phenix.CartApi.Client), phenix-quote (TC.Quote.Api.Client), phenix-provider (Phenix.Provider.Domain/ProxyTools), tax-service (TC.Phenix.Tax.ServiceContract), mail-service (TC.Mail.ServiceClient), backoffice-useraccount-service (TC.UserAccount.ServiceClient), and backoffice via the DirectStock ACL's BackOfficeGraphQLClient. External: Mozio, HolidayTaxis and BedsOnline transfer-provider APIs, FreshDesk ticketing for triage.
Data stores
MongoDB p2pGateway_logs for request/response logging (toggleable). SQL Server: shared Phenix database (selling-API markups repository) and a Transfers database (DirectStock ACL Dapper DAL). Redis heavily: streams as the gateway↔ACL message bus, TC.RemoteSession session storage, and TC.Cache caching; the scheduled task purges expired stream messages.
Integration points
Inbound REST (JWT + API-key auth) on each API. Gateway and ACLs communicate asynchronously over Redis streams (consumer groups via StreamReadGroupAsync). Outbound REST to provider APIs and internal cart/quote services; GraphQL to backoffice for booking lookups.
Code health
Strong: 17 test projects (unit plus Reqnroll/NUnit integration suites per component), analyser rulesets enforced, YAML CI per deployable, active development (last commit 2026-07-22), and a genuinely informative README documenting the trunk-based/monorepo strategy.
Modernisation risks
Low priority — modern .NET 8, well-tested, independently deployable components. Residual concerns: the selling API reads the shared Phenix SQL database (markups) so it inherits shared-db coupling; Redis streams as a bus is bespoke infrastructure (with its own clean-up task) compared with the MassTransit/SQS pattern used elsewhere in the estate; and the monorepo's 12 pipelines need path filters kept in sync as components are added.