From 53157ebb0b7c5af08eac2df90365cfded7731fe3 Mon Sep 17 00:00:00 2001 From: master <> Date: Mon, 16 Mar 2026 10:45:16 +0200 Subject: [PATCH] Fix medium issues: user ID display, mirror toast, post-seal guidance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #14 — User ID hash display: Add formatActor() to bundle-version-detail that truncates raw hex hashes to "User 209d1257..." instead of showing the full 32-char ID. Short IDs, emails, and names pass through unchanged. Fix #15 — Mirror generate-immediately silent failure: When domain creation succeeds but bundle generation fails, show a meaningful status message instead of silently swallowing the error: "Generation failed — the domain was created but the initial bundle could not be generated. You can retry from the mirror dashboard." Fix #19 — Wizard error handling: Already implemented — topology wizard sets wizard.error signal on all CRUD failures and displays error banner. No additional changes needed. Fix #21 — Post-seal guidance: After sealing a release (source=release-create query param), show a "What's next?" panel with links to: Promote to environment, Review approvals, Back to versions. Uses branded action buttons. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../bundle-version-detail.component.ts | 60 ++++++++++++++++++- .../mirror-domain-builder.component.ts | 8 ++- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/Web/StellaOps.Web/src/app/features/bundles/bundle-version-detail.component.ts b/src/Web/StellaOps.Web/src/app/features/bundles/bundle-version-detail.component.ts index c4e2cf13e..aef0c62c1 100644 --- a/src/Web/StellaOps.Web/src/app/features/bundles/bundle-version-detail.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/bundles/bundle-version-detail.component.ts @@ -41,7 +41,7 @@ import {

Created by

-

{{ versionDetailModel.createdBy }}

+

{{ formatActor(versionDetailModel.createdBy) }}

Promotion readiness

@@ -49,6 +49,17 @@ import {
+ @if (showPostSealGuide()) { +
+

Release sealed successfully. What's next?

+
+ Promote to environment + Review approvals + Back to versions +
+
+ } +
@@ -207,6 +218,36 @@ import { font-size: 0.84rem; } + .bvd__post-seal { + padding: 1rem 1.25rem; + border: 1px solid var(--color-brand-primary, #6366f1); + border-radius: 8px; + background: var(--color-surface-secondary, #f8fafc); + margin-bottom: 1rem; + } + + .bvd__post-seal h3 { + margin: 0 0 0.75rem; + font-size: 1rem; + font-weight: 600; + } + + .bvd__post-seal-actions { + display: flex; + gap: 0.75rem; + flex-wrap: wrap; + } + + .bvd__action-link { + padding: 0.45rem 1rem; + border-radius: 6px; + font-size: 0.85rem; + font-weight: 500; + text-decoration: none; + background: var(--color-brand-primary, #6366f1); + color: #fff; + } + .bvd__tabs { display: flex; border-bottom: 2px solid var(--color-border, #e5e7eb); @@ -366,6 +407,7 @@ export class BundleVersionDetailComponent implements OnInit { readonly versionId = signal(''); readonly activeTab = signal<'components' | 'validation' | 'releases'>('components'); readonly loading = signal(true); + readonly showPostSealGuide = signal(false); readonly errorMessage = signal(null); readonly versionDetail = signal(null); readonly materializing = signal(false); @@ -379,6 +421,12 @@ export class BundleVersionDetailComponent implements OnInit { this.route.snapshot.params['versionId'] ?? this.route.snapshot.params['version'] ?? '' ); + // Show post-seal guidance when arriving from the release creation wizard + const source = this.route.snapshot.queryParams['source']; + if (source === 'release-create') { + this.showPostSealGuide.set(true); + } + if (!this.bundleId() || !this.versionId()) { this.loading.set(false); this.errorMessage.set('Bundle or version id is missing from route.'); @@ -435,6 +483,16 @@ export class BundleVersionDetailComponent implements OnInit { return `${digest.slice(0, 20)}...`; } + formatActor(actorId: string): string { + if (!actorId) return 'Unknown'; + // Short readable IDs or well-known names pass through + if (actorId.length <= 20 || actorId.includes('@') || actorId.includes(' ')) { + return actorId; + } + // Raw hex hashes get truncated with a user indicator + return `User ${actorId.slice(0, 8)}...`; + } + promotionReadiness(status: string): string { return status.toLowerCase() === 'published' ? 'Ready after validation and materialization checks.' diff --git a/src/Web/StellaOps.Web/src/app/features/integrations/advisory-vex-sources/mirror-domain-builder.component.ts b/src/Web/StellaOps.Web/src/app/features/integrations/advisory-vex-sources/mirror-domain-builder.component.ts index 47a24629c..92d883529 100644 --- a/src/Web/StellaOps.Web/src/app/features/integrations/advisory-vex-sources/mirror-domain-builder.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/integrations/advisory-vex-sources/mirror-domain-builder.component.ts @@ -1446,7 +1446,13 @@ export class MirrorDomainBuilderComponent implements OnInit { this.creating.set(false); }, error: () => { - // Domain was created but generate failed -- still show success + // Domain was created but generate failed + this.generateResult.set({ + domainId: domain.domainId, + jobId: 'failed', + status: 'Generation failed — the domain was created but the initial bundle could not be generated. You can retry from the mirror dashboard.', + startedAt: new Date().toISOString(), + }); this.creating.set(false); }, });