(null);
diff --git a/src/Web/StellaOps.Web/src/app/features/evidence/evidence-page.component.ts b/src/Web/StellaOps.Web/src/app/features/evidence/evidence-page.component.ts
index 55f50a601..eb79763e8 100644
--- a/src/Web/StellaOps.Web/src/app/features/evidence/evidence-page.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/evidence/evidence-page.component.ts
@@ -10,16 +10,13 @@ import {
import { ActivatedRoute, Router } from '@angular/router';
import { EvidenceData } from '../../core/api/evidence.models';
-import { EVIDENCE_API, MockEvidenceApiService } from '../../core/api/evidence.client';
+import { EVIDENCE_API } from '../../core/api/evidence.client';
import { EvidencePanelComponent } from './evidence-panel.component';
@Component({
selector: 'app-evidence-page',
standalone: true,
imports: [EvidencePanelComponent],
- providers: [
- { provide: EVIDENCE_API, useClass: MockEvidenceApiService },
- ],
template: `
@if (loading()) {
diff --git a/src/Web/StellaOps.Web/src/app/features/findings/findings-list.component.ts b/src/Web/StellaOps.Web/src/app/features/findings/findings-list.component.ts
index 448acd9bd..2255fe9b3 100644
--- a/src/Web/StellaOps.Web/src/app/features/findings/findings-list.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/findings/findings-list.component.ts
@@ -17,7 +17,7 @@ import {
BUCKET_DISPLAY,
getBucketForScore,
} from '../../core/api/scoring.models';
-import { ScoringService, SCORING_API, MockScoringApi } from '../../core/services/scoring.service';
+import { ScoringService } from '../../core/services/scoring.service';
import {
ScorePillComponent,
ScoreBadgeComponent,
@@ -111,10 +111,6 @@ export interface FindingsFilter {
VexTrustPopoverComponent,
ReasonCapsuleComponent
],
- providers: [
- { provide: SCORING_API, useClass: MockScoringApi },
- ScoringService,
- ],
templateUrl: './findings-list.component.html',
styleUrls: ['./findings-list.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-governance/governance-audit.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-governance/governance-audit.component.ts
index 70aee36eb..6907cd59a 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-governance/governance-audit.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-governance/governance-audit.component.ts
@@ -630,8 +630,9 @@ export class GovernanceAuditComponent implements OnInit {
.pipe(finalize(() => this.loading.set(false)))
.subscribe({
next: (res) => {
- this.response.set(res);
- this.events.set(res.events);
+ const normalized = this.buildSafeResponse(res, page);
+ this.response.set(normalized);
+ this.events.set(normalized.events);
},
error: (err) => console.error('Failed to load audit events:', err),
});
@@ -688,4 +689,156 @@ export class GovernanceAuditComponent implements OnInit {
}
return String(value);
}
+
+ private buildSafeResponse(payload: unknown, fallbackPage: number): AuditResponse {
+ const container = this.asRecord(payload);
+ const eventSource =
+ Array.isArray(payload)
+ ? payload
+ : Array.isArray(container?.['events'])
+ ? container['events']
+ : Array.isArray(container?.['items'])
+ ? container['items']
+ : [];
+
+ const events = eventSource.map((event, index) => this.buildSafeEvent(event, index));
+ const page = this.toPositiveNumber(container?.['page'], fallbackPage);
+ const pageSize = this.toPositiveNumber(container?.['pageSize'], Math.max(events.length, 20));
+ const total = this.toPositiveNumber(container?.['total'] ?? container?.['totalCount'], events.length);
+ const hasMore =
+ typeof container?.['hasMore'] === 'boolean' ? container['hasMore'] : page * pageSize < total;
+
+ return {
+ events,
+ total,
+ page,
+ pageSize,
+ hasMore,
+ };
+ }
+
+ private buildSafeEvent(payload: unknown, index: number): GovernanceAuditEvent {
+ const record = this.asRecord(payload);
+ const rawType = this.toString(record?.['type']);
+ const type = this.toAuditEventType(rawType);
+ const summary = this.toString(record?.['summary']) || this.formatEventType(type);
+ const timestamp = this.toString(record?.['timestamp']) || new Date().toISOString();
+ const actorType = this.toActorType(record?.['actorType']);
+
+ const event: GovernanceAuditEvent = {
+ id: this.toString(record?.['id']) || `audit-event-${index + 1}`,
+ type,
+ timestamp,
+ actor: this.toString(record?.['actor']) || 'system',
+ actorType,
+ targetResource: this.toString(record?.['targetResource']) || 'unknown',
+ targetResourceType: this.toString(record?.['targetResourceType']) || 'unknown',
+ summary,
+ traceId: this.toString(record?.['traceId']) || undefined,
+ tenantId: this.toString(record?.['tenantId']) || 'acme-tenant',
+ projectId: this.toString(record?.['projectId']) || undefined,
+ };
+
+ if (record && 'previousState' in record) {
+ event.previousState = record['previousState'];
+ }
+ if (record && 'newState' in record) {
+ event.newState = record['newState'];
+ }
+
+ const diff = this.buildSafeDiff(record?.['diff']);
+ if (diff) {
+ event.diff = diff;
+ }
+
+ return event;
+ }
+
+ private buildSafeDiff(payload: unknown): GovernanceAuditDiff | undefined {
+ const record = this.asRecord(payload);
+ if (!record) {
+ return undefined;
+ }
+
+ const added = this.asRecord(record['added']) ?? {};
+ const removed = this.asRecord(record['removed']) ?? {};
+ const modifiedSource = this.asRecord(record['modified']) ?? {};
+ const modified: Record = {};
+
+ for (const [key, value] of Object.entries(modifiedSource)) {
+ const entry = this.asRecord(value);
+ if (entry && ('before' in entry || 'after' in entry)) {
+ modified[key] = {
+ before: entry['before'],
+ after: entry['after'],
+ };
+ continue;
+ }
+
+ modified[key] = {
+ before: undefined,
+ after: value,
+ };
+ }
+
+ if (
+ Object.keys(added).length === 0 &&
+ Object.keys(removed).length === 0 &&
+ Object.keys(modified).length === 0
+ ) {
+ return undefined;
+ }
+
+ return {
+ added,
+ removed,
+ modified,
+ };
+ }
+
+ private toAuditEventType(value: string): AuditEventType {
+ const type = this.eventTypes.find((candidate) => candidate === value);
+ return type ?? 'policy_validated';
+ }
+
+ private toActorType(value: unknown): GovernanceAuditEvent['actorType'] {
+ if (value === 'user' || value === 'system' || value === 'automation') {
+ return value;
+ }
+
+ return 'system';
+ }
+
+ private toPositiveNumber(value: unknown, fallback: number): number {
+ if (typeof value === 'number' && Number.isFinite(value) && value > 0) {
+ return Math.floor(value);
+ }
+
+ if (typeof value === 'string') {
+ const parsed = Number(value);
+ if (Number.isFinite(parsed) && parsed > 0) {
+ return Math.floor(parsed);
+ }
+ }
+
+ return fallback;
+ }
+
+ private toString(value: unknown): string {
+ if (typeof value === 'string') {
+ return value;
+ }
+
+ if (typeof value === 'number' || typeof value === 'boolean') {
+ return String(value);
+ }
+
+ return '';
+ }
+
+ private asRecord(value: unknown): Record | null {
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
+ ? (value as Record)
+ : null;
+ }
}
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-governance/risk-budget-dashboard.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-governance/risk-budget-dashboard.component.ts
index e12f4e094..17ff484f6 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-governance/risk-budget-dashboard.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-governance/risk-budget-dashboard.component.ts
@@ -643,7 +643,7 @@ export class RiskBudgetDashboardComponent implements OnInit {
.pipe(finalize(() => this.loading.set(false)))
.subscribe({
next: (dashboard) => {
- this.data.set(dashboard);
+ this.data.set(this.buildSafeDashboard(dashboard));
this.loadError.set(null);
},
error: (err) => {
@@ -654,6 +654,88 @@ export class RiskBudgetDashboardComponent implements OnInit {
});
}
+ private buildSafeDashboard(dashboard: RiskBudgetDashboard): RiskBudgetDashboard {
+ const now = new Date().toISOString();
+ const rawConfig = dashboard?.config;
+ const totalBudget = this.toPositiveNumber(rawConfig?.totalBudget, 1000);
+ const warningThreshold = this.toNumber(rawConfig?.warningThreshold, 70);
+ const criticalThreshold = this.toNumber(rawConfig?.criticalThreshold, 90);
+
+ const config = {
+ id: rawConfig?.id ?? 'risk-budget-default',
+ tenantId: rawConfig?.tenantId ?? 'acme-tenant',
+ projectId: rawConfig?.projectId,
+ name: rawConfig?.name ?? 'Default Risk Budget',
+ totalBudget,
+ warningThreshold,
+ criticalThreshold,
+ period: rawConfig?.period ?? 'monthly',
+ periodStart: rawConfig?.periodStart ?? now,
+ periodEnd: rawConfig?.periodEnd ?? now,
+ createdAt: rawConfig?.createdAt ?? now,
+ updatedAt: rawConfig?.updatedAt ?? now,
+ };
+
+ const currentRiskPoints = this.toNumber(dashboard?.currentRiskPoints, 0);
+ const headroom = this.toNumber(dashboard?.headroom, totalBudget - currentRiskPoints);
+ const utilizationPercent = this.toNumber(
+ dashboard?.utilizationPercent,
+ (currentRiskPoints / totalBudget) * 100,
+ );
+
+ const kpis = {
+ headroom: this.toNumber(dashboard?.kpis?.headroom, headroom),
+ headroomDelta24h: this.toNumber(dashboard?.kpis?.headroomDelta24h, 0),
+ unknownsDelta24h: this.toNumber(dashboard?.kpis?.unknownsDelta24h, 0),
+ riskRetired7d: this.toNumber(dashboard?.kpis?.riskRetired7d, 0),
+ exceptionsExpiring: this.toNumber(dashboard?.kpis?.exceptionsExpiring, 0),
+ burnRate: this.toNumber(dashboard?.kpis?.burnRate, 0),
+ projectedDaysToExceeded: dashboard?.kpis?.projectedDaysToExceeded ?? null,
+ traceId: dashboard?.kpis?.traceId ?? dashboard?.traceId ?? 'risk-budget-fallback',
+ };
+
+ const governance = dashboard?.governance
+ ? {
+ ...dashboard.governance,
+ thresholds: Array.isArray(dashboard.governance.thresholds)
+ ? dashboard.governance.thresholds
+ : [],
+ }
+ : {
+ ...config,
+ thresholds: [],
+ enforceHardLimits: false,
+ gracePeriodHours: 24,
+ autoReset: true,
+ carryoverPercent: 0,
+ };
+
+ return {
+ ...dashboard,
+ config,
+ currentRiskPoints,
+ headroom,
+ utilizationPercent,
+ status: dashboard?.status ?? 'healthy',
+ timeSeries: Array.isArray(dashboard?.timeSeries) ? dashboard.timeSeries : [],
+ updatedAt: dashboard?.updatedAt ?? now,
+ traceId: dashboard?.traceId ?? 'risk-budget-fallback',
+ topContributors: Array.isArray(dashboard?.topContributors) ? dashboard.topContributors : [],
+ activeAlerts: Array.isArray(dashboard?.activeAlerts) ? dashboard.activeAlerts : [],
+ governance,
+ kpis,
+ };
+ }
+
+ private toNumber(value: number | null | undefined, fallback: number): number {
+ return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
+ }
+
+ private toPositiveNumber(value: number | null | undefined, fallback: number): number {
+ const numericValue = this.toNumber(value, fallback);
+ return numericValue > 0 ? numericValue : fallback;
+ }
+
protected formatDate(timestamp: string): string {
const date = new Date(timestamp);
return `${date.getMonth() + 1}/${date.getDate()}`;
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-governance/sealed-mode-control.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-governance/sealed-mode-control.component.ts
index b9d9b54d3..5401ef891 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-governance/sealed-mode-control.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-governance/sealed-mode-control.component.ts
@@ -791,7 +791,7 @@ export class SealedModeControlComponent implements OnInit {
.getSealedModeStatus({ tenantId: 'acme-tenant' })
.pipe(finalize(() => this.loading.set(false)))
.subscribe({
- next: (status) => this.status.set(status),
+ next: (status) => this.status.set(this.buildSafeStatus(status)),
error: (err) => console.error('Failed to load sealed mode status:', err),
});
}
@@ -907,4 +907,31 @@ export class SealedModeControlComponent implements OnInit {
error: (err) => console.error('Failed to revoke override:', err),
});
}
+
+ private buildSafeStatus(status: SealedModeStatus): SealedModeStatus {
+ const now = new Date().toISOString();
+ const overrides = Array.isArray(status?.overrides)
+ ? status.overrides.map((override) => ({
+ ...override,
+ approvedBy: Array.isArray(override.approvedBy) ? override.approvedBy : [],
+ expiresAt: override.expiresAt ?? now,
+ createdAt: override.createdAt ?? now,
+ active: override.active ?? false,
+ }))
+ : [];
+
+ return {
+ ...status,
+ isSealed: Boolean(status?.isSealed),
+ trustRoots: Array.isArray(status?.trustRoots) ? status.trustRoots : [],
+ allowedSources: Array.isArray(status?.allowedSources) ? status.allowedSources : [],
+ overrides,
+ verificationStatus: status?.verificationStatus ?? 'pending',
+ sealedAt: status?.sealedAt,
+ sealedBy: status?.sealedBy,
+ reason: status?.reason,
+ lastUnsealedAt: status?.lastUnsealedAt,
+ lastVerifiedAt: status?.lastVerifiedAt,
+ };
+ }
}
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-governance/staleness-config.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-governance/staleness-config.component.ts
index d43aca6ba..e8986862d 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-governance/staleness-config.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-governance/staleness-config.component.ts
@@ -628,14 +628,22 @@ export class StalenessConfigComponent implements OnInit {
.getStalenessConfig({ tenantId: 'acme-tenant' })
.pipe(finalize(() => this.loading.set(false)))
.subscribe({
- next: (container) => this.configContainer.set(container),
+ next: (container) => {
+ const safeContainer = this.buildSafeContainer(container);
+ this.configContainer.set(safeContainer);
+
+ // Keep active tab bound to a config that actually exists.
+ if (!safeContainer.configs.some((c) => c.dataType === this.activeDataType())) {
+ this.activeDataType.set(safeContainer.configs[0]?.dataType ?? 'sbom');
+ }
+ },
error: (err) => console.error('Failed to load staleness config:', err),
});
}
private loadStatus(): void {
this.api.getStalenessStatus({ tenantId: 'acme-tenant' }).subscribe({
- next: (statuses) => this.statusList.set(statuses),
+ next: (statuses) => this.statusList.set(Array.isArray(statuses) ? statuses : []),
error: (err) => console.error('Failed to load staleness status:', err),
});
}
@@ -657,7 +665,7 @@ export class StalenessConfigComponent implements OnInit {
}
protected getConfigForType(dataType: StalenessDataType): StalenessConfig | undefined {
- return this.configContainer()?.configs.find((c) => c.dataType === dataType);
+ return this.configContainer()?.configs?.find((c) => c.dataType === dataType);
}
protected toggleEnabled(config: StalenessConfig): void {
@@ -709,4 +717,69 @@ export class StalenessConfigComponent implements OnInit {
error: (err) => console.error('Failed to save config:', err),
});
}
+
+ private buildSafeContainer(container: StalenessConfigContainer): StalenessConfigContainer {
+ const now = new Date().toISOString();
+ const incomingConfigs = Array.isArray(container?.configs) ? container.configs : [];
+ const configByType = new Map();
+
+ for (const config of incomingConfigs) {
+ if (!config?.dataType) {
+ continue;
+ }
+ configByType.set(config.dataType, this.buildSafeConfig(config.dataType, config));
+ }
+
+ const configs = this.dataTypes.map((dataType) =>
+ this.buildSafeConfig(dataType, configByType.get(dataType)),
+ );
+
+ return {
+ tenantId: container?.tenantId ?? 'acme-tenant',
+ projectId: container?.projectId,
+ configs,
+ modifiedAt: container?.modifiedAt ?? now,
+ etag: container?.etag,
+ };
+ }
+
+ private buildSafeConfig(dataType: StalenessDataType, config?: StalenessConfig): StalenessConfig {
+ const fallbackThresholds = this.defaultThresholds();
+ const thresholds = Array.isArray(config?.thresholds) && config.thresholds.length > 0
+ ? config.thresholds.map((threshold) => ({
+ ...threshold,
+ actions: Array.isArray(threshold.actions) ? threshold.actions : [],
+ }))
+ : fallbackThresholds;
+
+ return {
+ dataType,
+ thresholds,
+ enabled: config?.enabled ?? true,
+ gracePeriodHours: this.toNumber(config?.gracePeriodHours, 24),
+ };
+ }
+
+ private defaultThresholds() {
+ return [
+ { level: 'fresh' as const, ageDays: 0, severity: 'none' as const, actions: [] },
+ { level: 'aging' as const, ageDays: 7, severity: 'low' as const, actions: [{ type: 'warn' as const }] },
+ {
+ level: 'stale' as const,
+ ageDays: 14,
+ severity: 'medium' as const,
+ actions: [{ type: 'warn' as const }, { type: 'notify' as const }],
+ },
+ {
+ level: 'expired' as const,
+ ageDays: 30,
+ severity: 'high' as const,
+ actions: [{ type: 'block' as const }, { type: 'notify' as const }],
+ },
+ ];
+ }
+
+ private toNumber(value: number | null | undefined, fallback: number): number {
+ return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
+ }
}
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/batch-evaluation.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/batch-evaluation.component.ts
index 9600d4300..2402f1bc8 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/batch-evaluation.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/batch-evaluation.component.ts
@@ -1,10 +1,9 @@
-import { CommonModule } from '@angular/common';
+import { CommonModule } from '@angular/common';
import { Component, ChangeDetectionStrategy, inject, signal, OnInit, OnDestroy } from '@angular/core';
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
import {
POLICY_SIMULATION_API,
- MockPolicySimulationService,
} from '../../core/api/policy-simulation.client';
import {
BatchEvaluationInput,
@@ -22,9 +21,6 @@ import {
@Component({
selector: 'app-batch-evaluation',
imports: [CommonModule, ReactiveFormsModule],
- providers: [
- { provide: POLICY_SIMULATION_API, useClass: MockPolicySimulationService },
- ],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@@ -1525,3 +1521,4 @@ export class BatchEvaluationComponent implements OnInit, OnDestroy {
});
}
}
+
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/conflict-detection.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/conflict-detection.component.ts
index bfdba435a..8f500e0b5 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/conflict-detection.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/conflict-detection.component.ts
@@ -1,10 +1,9 @@
-import { CommonModule } from '@angular/common';
+import { CommonModule } from '@angular/common';
import { Component, ChangeDetectionStrategy, inject, signal, OnInit } from '@angular/core';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import {
POLICY_SIMULATION_API,
- MockPolicySimulationService,
} from '../../core/api/policy-simulation.client';
import {
PolicyConflict,
@@ -21,9 +20,6 @@ import {
@Component({
selector: 'app-conflict-detection',
imports: [CommonModule, ReactiveFormsModule],
- providers: [
- { provide: POLICY_SIMULATION_API, useClass: MockPolicySimulationService },
- ],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@@ -1389,3 +1385,4 @@ export class ConflictDetectionComponent implements OnInit {
this.applyFilters();
}
}
+
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/coverage-fixture.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/coverage-fixture.component.ts
index 769786f62..05b3f8104 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/coverage-fixture.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/coverage-fixture.component.ts
@@ -1,4 +1,4 @@
-import { CommonModule } from '@angular/common';
+import { CommonModule } from '@angular/common';
import { Component, ChangeDetectionStrategy, inject, signal, computed, Input, OnChanges, SimpleChanges } from '@angular/core';
import { finalize } from 'rxjs/operators';
@@ -6,7 +6,6 @@ import { finalize } from 'rxjs/operators';
import {
POLICY_SIMULATION_API,
PolicySimulationApi,
- MockPolicySimulationService,
} from '../../core/api/policy-simulation.client';
import {
CoverageResult,
@@ -22,9 +21,6 @@ import {
@Component({
selector: 'app-coverage-fixture',
imports: [CommonModule],
- providers: [
- { provide: POLICY_SIMULATION_API, useClass: MockPolicySimulationService },
- ],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@@ -802,3 +798,4 @@ export class CoverageFixtureComponent implements OnChanges {
this.activeStatusFilter.set(status);
}
}
+
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/effective-policy-viewer.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/effective-policy-viewer.component.ts
index 563f0310b..d9dec2828 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/effective-policy-viewer.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/effective-policy-viewer.component.ts
@@ -1,4 +1,4 @@
-import { CommonModule } from '@angular/common';
+import { CommonModule } from '@angular/common';
import { Component, ChangeDetectionStrategy, inject, signal, computed, OnInit } from '@angular/core';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
@@ -7,7 +7,6 @@ import { finalize } from 'rxjs/operators';
import {
POLICY_SIMULATION_API,
PolicySimulationApi,
- MockPolicySimulationService,
} from '../../core/api/policy-simulation.client';
import {
EffectivePolicyResult,
@@ -23,9 +22,6 @@ import {
@Component({
selector: 'app-effective-policy-viewer',
imports: [CommonModule, ReactiveFormsModule],
- providers: [
- { provide: POLICY_SIMULATION_API, useClass: MockPolicySimulationService },
- ],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@@ -537,3 +533,4 @@ export class EffectivePolicyViewerComponent implements OnInit {
});
}
}
+
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-audit-log.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-audit-log.component.ts
index 05698cb52..b3d69410b 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-audit-log.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-audit-log.component.ts
@@ -1,4 +1,4 @@
-import { CommonModule } from '@angular/common';
+import { CommonModule } from '@angular/common';
import { Component, ChangeDetectionStrategy, inject, signal, computed, OnInit, Input } from '@angular/core';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { Router } from '@angular/router';
@@ -8,7 +8,6 @@ import { finalize } from 'rxjs/operators';
import {
POLICY_SIMULATION_API,
PolicySimulationApi,
- MockPolicySimulationService,
} from '../../core/api/policy-simulation.client';
import {
PolicyAuditLogResult,
@@ -23,9 +22,6 @@ import {
@Component({
selector: 'app-policy-audit-log',
imports: [CommonModule, ReactiveFormsModule],
- providers: [
- { provide: POLICY_SIMULATION_API, useClass: MockPolicySimulationService },
- ],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@@ -637,3 +633,4 @@ export class PolicyAuditLogComponent implements OnInit {
}
}
}
+
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-diff-viewer.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-diff-viewer.component.ts
index 502c6ecf7..1fbcfa034 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-diff-viewer.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-diff-viewer.component.ts
@@ -1,4 +1,4 @@
-import { CommonModule } from '@angular/common';
+import { CommonModule } from '@angular/common';
import { Component, ChangeDetectionStrategy, inject, signal, Input, OnChanges, SimpleChanges } from '@angular/core';
import { finalize } from 'rxjs/operators';
@@ -6,7 +6,6 @@ import { finalize } from 'rxjs/operators';
import {
POLICY_SIMULATION_API,
PolicySimulationApi,
- MockPolicySimulationService,
} from '../../core/api/policy-simulation.client';
import {
PolicyDiffResult,
@@ -22,9 +21,6 @@ import {
@Component({
selector: 'app-policy-diff-viewer',
imports: [CommonModule],
- providers: [
- { provide: POLICY_SIMULATION_API, useClass: MockPolicySimulationService },
- ],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@@ -528,3 +524,4 @@ export class PolicyDiffViewerComponent implements OnChanges {
return this.expandedFiles.has(path);
}
}
+
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-exception.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-exception.component.ts
index 9e0f34556..7b40e26e1 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-exception.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-exception.component.ts
@@ -1,4 +1,4 @@
-import { CommonModule } from '@angular/common';
+import { CommonModule } from '@angular/common';
import { Component, ChangeDetectionStrategy, inject, signal, computed, OnInit } from '@angular/core';
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
@@ -7,7 +7,6 @@ import { finalize } from 'rxjs/operators';
import {
POLICY_SIMULATION_API,
PolicySimulationApi,
- MockPolicySimulationService,
} from '../../core/api/policy-simulation.client';
import {
PolicyException,
@@ -22,9 +21,6 @@ import {
@Component({
selector: 'app-policy-exception',
imports: [CommonModule, ReactiveFormsModule],
- providers: [
- { provide: POLICY_SIMULATION_API, useClass: MockPolicySimulationService },
- ],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@@ -813,3 +809,4 @@ export class PolicyExceptionComponent implements OnInit {
.filter(Boolean);
}
}
+
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-lint.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-lint.component.ts
index 18cf93c60..a52aad99a 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-lint.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-lint.component.ts
@@ -1,4 +1,4 @@
-import { CommonModule } from '@angular/common';
+import { CommonModule } from '@angular/common';
import { Component, ChangeDetectionStrategy, inject, signal, computed, Input, OnChanges, SimpleChanges } from '@angular/core';
import { finalize } from 'rxjs/operators';
@@ -6,7 +6,6 @@ import { finalize } from 'rxjs/operators';
import {
POLICY_SIMULATION_API,
PolicySimulationApi,
- MockPolicySimulationService,
} from '../../core/api/policy-simulation.client';
import {
PolicyLintResult,
@@ -22,9 +21,6 @@ import {
@Component({
selector: 'app-policy-lint',
imports: [CommonModule],
- providers: [
- { provide: POLICY_SIMULATION_API, useClass: MockPolicySimulationService },
- ],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@@ -664,3 +660,4 @@ export class PolicyLintComponent implements OnChanges {
this.activeCategoryFilter.set(category);
}
}
+
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-merge-preview.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-merge-preview.component.ts
index ddcf7e305..511a5f158 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-merge-preview.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/policy-merge-preview.component.ts
@@ -1,4 +1,4 @@
-import { CommonModule } from '@angular/common';
+import { CommonModule } from '@angular/common';
import { Component, ChangeDetectionStrategy, inject, signal, Input, OnChanges, SimpleChanges } from '@angular/core';
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
@@ -7,7 +7,6 @@ import { finalize } from 'rxjs/operators';
import {
POLICY_SIMULATION_API,
PolicySimulationApi,
- MockPolicySimulationService,
} from '../../core/api/policy-simulation.client';
import {
PolicyMergePreview,
@@ -22,9 +21,6 @@ import {
@Component({
selector: 'app-policy-merge-preview',
imports: [CommonModule, ReactiveFormsModule],
- providers: [
- { provide: POLICY_SIMULATION_API, useClass: MockPolicySimulationService },
- ],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@@ -685,3 +681,4 @@ export class PolicyMergePreviewComponent {
return resolution.replace(/_/g, ' ');
}
}
+
diff --git a/src/Web/StellaOps.Web/src/app/features/policy-simulation/promotion-gate.component.ts b/src/Web/StellaOps.Web/src/app/features/policy-simulation/promotion-gate.component.ts
index ff66922a6..2e5f00268 100644
--- a/src/Web/StellaOps.Web/src/app/features/policy-simulation/promotion-gate.component.ts
+++ b/src/Web/StellaOps.Web/src/app/features/policy-simulation/promotion-gate.component.ts
@@ -1,4 +1,4 @@
-import { CommonModule } from '@angular/common';
+import { CommonModule } from '@angular/common';
import { Component, ChangeDetectionStrategy, inject, signal, Input, OnChanges, SimpleChanges } from '@angular/core';
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
import { Router } from '@angular/router';
@@ -8,7 +8,6 @@ import { finalize } from 'rxjs/operators';
import {
POLICY_SIMULATION_API,
PolicySimulationApi,
- MockPolicySimulationService,
} from '../../core/api/policy-simulation.client';
import {
PromotionGateResult,
@@ -23,9 +22,6 @@ import {
@Component({
selector: 'app-promotion-gate',
imports: [CommonModule, ReactiveFormsModule],
- providers: [
- { provide: POLICY_SIMULATION_API, useClass: MockPolicySimulationService },
- ],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `