From 1acc87a25df73593df3be674185c009253fda511 Mon Sep 17 00:00:00 2001 From: master <> Date: Mon, 16 Mar 2026 17:55:58 +0200 Subject: [PATCH] Fix scan submit: imageRef signal binding + API URL path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: canSubmit computed() used plain string imageRef which computed() can't track. Submit button was permanently disabled. Fix: Changed imageRef to signal(''), updated template to use [ngModel]="imageRef()" (ngModelChange)="imageRef.set($event)", updated all class references to imageRef() for reads and .set() for writes. Bug: Scan submit called /scanner/api/v1/scans/ (console nginx prefix) instead of /api/v1/scans/ (gateway route). Fix: Removed /scanner/ prefix from all API URLs. KNOWN ISSUE: Scanner service needs identity envelope middleware (same as Concelier fix) — ReverseProxy strips JWT, scanner returns 400 "tenant required". The scan submission reaches the scanner but auth fails. Fix requires adding the same pre-auth envelope middleware pattern to the Scanner service. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../features/scanner/scan-submit.component.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Web/StellaOps.Web/src/app/features/scanner/scan-submit.component.ts b/src/Web/StellaOps.Web/src/app/features/scanner/scan-submit.component.ts index a22d3ddb5..fca43f7e8 100644 --- a/src/Web/StellaOps.Web/src/app/features/scanner/scan-submit.component.ts +++ b/src/Web/StellaOps.Web/src/app/features/scanner/scan-submit.component.ts @@ -57,7 +57,8 @@ interface ScanStatusResponse { Image reference * @@ -160,7 +161,7 @@ interface ScanStatusResponse {
Image - {{ imageRef }} + {{ imageRef() }}
Status @@ -471,7 +472,7 @@ export class ScanSubmitComponent implements OnDestroy { private readonly destroyRef = inject(DestroyRef); /** Form state */ - imageRef = ''; + imageRef = signal(''); forceRescan = false; showMetadata = false; metadataEntries: MetadataEntry[] = []; @@ -487,7 +488,7 @@ export class ScanSubmitComponent implements OnDestroy { /** Derive image name (strip tag/digest for triage link) */ readonly imageName = computed(() => { - const ref = this.imageRef.trim(); + const ref = this.imageRef().trim(); const atIdx = ref.indexOf('@'); if (atIdx > 0) return ref.substring(0, atIdx); const colonIdx = ref.lastIndexOf(':'); @@ -496,7 +497,7 @@ export class ScanSubmitComponent implements OnDestroy { }); readonly canSubmit = computed(() => { - return this.imageRef.trim().length > 0 && !this.submitting(); + return this.imageRef().trim().length > 0 && !this.submitting(); }); addMetadataEntry(): void { @@ -523,7 +524,7 @@ export class ScanSubmitComponent implements OnDestroy { } const body: Record = { - image: { reference: this.imageRef.trim() }, + image: { reference: this.imageRef().trim() }, force: this.forceRescan, }; @@ -531,7 +532,7 @@ export class ScanSubmitComponent implements OnDestroy { body['metadata'] = metadata; } - this.http.post('/scanner/api/v1/scans/', body).pipe( + this.http.post('/api/v1/scans/', body).pipe( takeUntilDestroyed(this.destroyRef), ).subscribe({ next: (response) => { @@ -552,7 +553,7 @@ export class ScanSubmitComponent implements OnDestroy { this.scanId.set(null); this.scanStatus.set('queued'); this.submitError.set(null); - this.imageRef = ''; + this.imageRef.set(''); this.forceRescan = false; this.showMetadata = false; this.metadataEntries = []; @@ -567,7 +568,7 @@ export class ScanSubmitComponent implements OnDestroy { this.pollSubscription = timer(0, 3000).pipe( switchMap(() => - this.http.get(`/scanner/api/v1/scans/${encodeURIComponent(scanId)}`) + this.http.get(`/api/v1/scans/${encodeURIComponent(scanId)}`) ), tap((response) => { this.scanStatus.set(response.status);