Getting Started

Migrating from SpocR to Xtraq

High-level guide for replacing legacy SpocR-generated artefacts with Xtraq pipelines in an existing solution. Written for teams that want a clean cut-over path without project-specific assumptions.

Use this playbook once you have audited your applications and confirmed that the remaining gaps in Xtraq have been addressed. It focuses on the final migration activity rather than discovery or optimisation.

Overview

StepOutcome
PrepareTeam agrees on migration scope, timelines, and rollback plan.
Cut-overSpocR artefacts are replaced with Xtraq equivalents, and cross-cutting behaviours are reattached.
ValidateRegression tests, performance checks, and observability confirm parity.
DecommissionLegacy assets are retired, documentation updated, and lessons captured.

Prerequisites

  • Audit of SpocR usage is complete and tracked in an internal backlog.
  • Xtraq generator settings (snapshots, configuration) are verified against the target environment.
  • Generated folders Xtraq/ and .xtraq/ remain disposable and can be cleared; keep custom code outside of them (see Generated output is disposable).
  • Required features or optimisations (for example table-type trimming, execution policies, DI-scoped transaction orchestrator with ambient EF support) have landed in your branch or are covered by feature flags.
  • Legacy result envelopes that must stay compatible (for example ResponseResult) have a documented adapter plan using pipeline policies or interceptors.
  • Stakeholders sign off on the migration schedule and rollback triggers.

💡 Prompt idea: "Review our SpocR → Xtraq readiness checklist and report any missing prerequisites."

Typical gaps when replacing SpocR services

  • Services often build a shared context TVP per call (user/app/language + record metadata). Manual With(...) plumbing is brittle.
  • Write paths wrap outputs into legacy envelopes (for example ResponseResult/CrudResult) and log history/audit content beside the main procedure result.
  • Cross-entity workflows open explicit transactions and chain several procedures plus side effects before committing.
  • Change notifications are dispatched after successful writes (for example SignalR hubs) based on attributes or request model metadata.
  • Many endpoints expose raw JSON (*AsJson), while other paths consume typed records; both shapes must remain usable during migration.
  • Context binding: Use ParameterBindings.BindTableFrom<TInput,...> or BindTableWithInput to hydrate a context TVP from DI/claims (user/app/language) and merge record-level fields (RecordId, RowVersion, Overwrite) from the request before execution.
  • Result/history adaptation: Use ResultCallbackExecutionPolicy<TInput, TResult> to wrap pipeline outputs into legacy envelopes and trigger history/audit calls (for example invoking a HistoryCreate procedure) without changing executor signatures.
  • Dispatch hooks: Use DispatchExecutionPolicy<TInput, TResult> to fire notifications (SignalR, metrics, logging) on success and optionally on failure. Plug your dispatcher into the callback.
  • Transactions: Use .WithTransaction(...) or custom policies plus the ambient accessors (ProcedureExecutionContext.AmbientConnection/AmbientTransaction) when auxiliary ADO.NET work must share the scope with generated procedures.
  • API config: Add an Api section when you need request DTOs, table-type request rows, and the associated Api.Requests.* auto-bind allow-lists; omit the section when a project only requires raw input structs.
  • JSON null emission: Controlled via ResultSet.Json.IncludeNullValues.

Context-TVP Binding: Use ParameterBindingOptions.BindTableWithInput to merge ambient data (for example IHttpContextAccessor for user/app/language) with per-request record metadata at call time:

services.AddXtraqDbContext(options =>
{
  options.ParameterBindings
    .BindTableWithInput<ContextTableType>("@Context", (input, sp, ct) =>
    {
      var accessor = sp?.GetService<IHttpContextAccessor>();
      var userId = accessor?.HttpContext?.User?.FindFirstValue("sub");
      var record = input as IRecordContext;
      return new[]
      {
        new ContextTableType
        {
          UserId = int.TryParse(userId, out var uid) ? uid : 0,
          RecordId = record?.RecordId,
          RowVersion = record?.RowVersion,
          Overwrite = record?.Overwrite
        }
      };
    });
});

Migration Steps

  1. Generate fresh Xtraq artefacts
  • Run the agreed snapshot/build workflow.
  • Commit or stage the generated code on a dedicated migration branch.
  1. Replace application wiring
    • Update dependency injection and project references to point at the Xtraq assemblies.
    • Introduce the DI-scoped transaction orchestrator so procedure calls share the intended connection/transaction scope.
    • When Entity Framework Core remains in the request pipeline, adapt your generated IXtraqDbContext to implement IXtraqAmbientTransactionAccessor so the orchestrator can join EF-managed transactions (see Entity Framework Integration).
    • Swap SpocR invocation sites with ConfigureProcedure(...), pipeline execution methods, and policies.
    • Ensure table types, DTOs, and streaming helpers map to the new structures.
  2. Reconnect cross-cutting concerns
    • Attach IProcedureExecutionPolicy implementations for retries, caching, history logging, or timeouts.
    • Register consumer-side interceptors/transformers that wrap pipeline results into legacy contracts (for example ResponseResult) when required.
    • Add WithLabel(...) annotations for telemetry and logging scopes.
    • Verify diagnostics pipelines or tracing remain functional.
  3. Feature toggles & deployment
    • Wrap the migration behind feature flags, environment toggles, or staged rollouts.
    • Document rollback instructions referencing the flag/branch.

💡 Prompt idea: "Refactor this service to call the Xtraq pipeline and include a labelled retry policy." 💡 Prompt idea: "Create a pipeline policy that maps InvoiceCreateResult into our existing ResponseResult shell."

Validation

  • Execute automated tests covering critical stored procedures and integration paths.
  • Exercise transaction rollbacks and nested transaction paths to ensure the orchestrator behaves like the legacy managers.
  • Perform targeted performance benchmarks comparing latency and throughput to the SpocR baseline.
  • Confirm observability signals (logs, metrics, traces) include the new pipeline labels and policies.
  • Conduct manual exploratory testing for edge cases identified during the audit.

💡 Prompt idea: "Generate a validation checklist for the Xtraq migration including performance and observability steps."

Decommissioning and Follow-Up

  1. Toggle production traffic to Xtraq paths and monitor for the agreed soak period.
  2. Remove SpocR references from solution files, CI pipelines, and deployment scripts.
  3. Archive or delete legacy artefacts once rollback is no longer required.
  4. Update internal and external documentation to reference the Xtraq workflow.
  5. Capture lessons learned and store reusable AI prompt templates in the team knowledge base.

💡 Prompt idea: "Draft a release note summarising the migration from SpocR to Xtraq and its operational impact."

Quick Checklist

  • Migration prerequisites satisfied and approved.
  • Xtraq artefacts generated and integrated.
  • Transaction orchestrator or interim wrapper wired into the DI scope.
  • Result adapter/interceptor strategy implemented where legacy envelopes remain.
  • Regression, performance, and observability checks passed.
  • Legacy SpocR assets removed or archived.
  • Documentation and knowledge base updated.