using ItWorx.KnowledgeHub.Application.Knowledge.UseCases; using ItWorx.KnowledgeHub.Domain.Decisions; namespace ItWorx.KnowledgeHub.Application.Decisions.UseCases; public sealed record DecisionDetailResult( DecisionRecord Decision, PageDetailResult Page, string ETag, DecisionRecord? Supersedes, DecisionRecord? SupersededBy); /// Assembles one ADR's full lineage view: its own lifecycle metadata, the /// linked page's rendered content, and — resolved by one extra lookup each, never a /// duplicated copy — the decision it supersedes and/or is superseded by /// (docs/16-runbooks-and-adrs.md: "Links are bidirectional"). public sealed class GetDecisionUseCase(IDecisionRepository decisions, GetPageUseCase getPage) { public async Task ExecuteAsync(Guid decisionId, CancellationToken cancellationToken) { var decision = await decisions.FindAsync(decisionId, cancellationToken); if (decision is null) { return null; } var page = await getPage.ExecuteAsync(decision.PageId, cancellationToken); if (page is null) { return null; } var etag = await decisions.GetETagAsync(decisionId, cancellationToken) ?? string.Empty; var supersedes = decision.SupersedesDecisionId is { } supersedesId ? await decisions.FindAsync(supersedesId, cancellationToken) : null; var supersededBy = decision.SupersededByDecisionId is { } supersededById ? await decisions.FindAsync(supersededById, cancellationToken) : null; return new DecisionDetailResult(decision, page, etag, supersedes, supersededBy); } }