Refactor compare-view component to use observables for data loading, enhancing performance and responsiveness. Update compare service interfaces and methods for improved delta computation. Modify audit log component to handle optional event properties gracefully. Optimize Monaco editor worker loading to reduce bundle size. Introduce shared SCSS mixins for consistent styling across components. Add Gitea test instance setup and NuGet package publishing test scripts for CI/CD validation. Update documentation paths and ensure all references are accurate.
This commit is contained in:
@@ -8,7 +8,7 @@ Design and maintain deterministic benchmark suites that measure StellaOps perfor
|
||||
- ImpactIndex/Scheduler/Scanner/Policy Engine workload simulations referenced in tasks.
|
||||
- Benchmark configuration and warm-up scripts used by DevOps for regression tracking.
|
||||
- Documentation of benchmark methodology and expected baseline metrics.
|
||||
- Determinism bench harness lives at `Determinism/` with optional reachability hashing; CI wrapper at `scripts/bench/determinism-run.sh` (threshold via `BENCH_DETERMINISM_THRESHOLD`). Include feeds via `DET_EXTRA_INPUTS`; optional reachability hashes via `DET_REACH_GRAPHS`/`DET_REACH_RUNTIME`.
|
||||
- Determinism bench harness lives at `Determinism/` with optional reachability hashing; CI wrapper at `.gitea/scripts/test/determinism-run.sh` (threshold via `BENCH_DETERMINISM_THRESHOLD`). Include feeds via `DET_EXTRA_INPUTS`; optional reachability hashes via `DET_REACH_GRAPHS`/`DET_REACH_RUNTIME`.
|
||||
|
||||
## Required Reading
|
||||
- `docs/modules/platform/architecture-overview.md`
|
||||
|
||||
@@ -75,7 +75,7 @@ Version comparators must be tested with 50+ cases per distro. See:
|
||||
- Storage: `StellaOps.Concelier.Storage.Postgres.Tests` (use in-memory or Testcontainers; determinism on ordering/hashes).
|
||||
- Observability/analyzers: tests in `__Analyzers` or respective test projects.
|
||||
- Tests must assert determinism (stable ordering/hashes), tenant guards, AOC invariants, and no derived fields in ingestion.
|
||||
- Prefer seeded fixtures under `seed-data/` for repeatability; avoid network in tests.
|
||||
- Prefer seeded fixtures under `src/__Tests/__Datasets/seed-data/` for repeatability; avoid network in tests.
|
||||
|
||||
## Delivery Discipline
|
||||
- Update sprint tracker status (`TODO → DOING → DONE/BLOCKED`) when you start/finish/block work; mirror decisions in Execution Log and Decisions & Risks.
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
- Adapter regression: deterministic fixtures for Trivy DB/Java DB, mirror delta/base comparison, OCI manifest generation; no network.
|
||||
- Risk bundle pipeline: tests in `StellaOps.ExportCenter.RiskBundles.Tests` (or add) covering bundle layout, DSSE signatures, checksum publication.
|
||||
- Determinism checks: stable ordering/hashes in manifests, provenance, and distribution descriptors; retry paths must not duplicate outputs.
|
||||
- Keep tests air-gap friendly; seeded data under `seed-data/` or inline fixtures.
|
||||
- Keep tests air-gap friendly; seeded data under `src/__Tests/__Datasets/seed-data/` or inline fixtures.
|
||||
|
||||
## Delivery Discipline
|
||||
- Update sprint tracker statuses (`TODO → DOING → DONE/BLOCKED`) in `docs/implplan/SPRINT_0164_0001_0001_exportcenter_iii.md` when starting/finishing/blocking work; mirror design decisions in Decisions & Risks and Execution Log.
|
||||
|
||||
@@ -16,7 +16,7 @@ Provide strongly-typed configuration helpers for Scanner/Zastava components, enc
|
||||
- `docs/modules/scanner/design/surface-validation.md`
|
||||
- `docs/modules/scanner/architecture.md`
|
||||
- `docs/modules/zastava/architecture.md`
|
||||
- Deployment guides (`deploy/README.md`, `ops/devops/TASKS.md`) referencing scanner env vars.
|
||||
- Deployment guides (`devops/docs/README.md`) referencing scanner env vars.
|
||||
|
||||
## Working Agreement
|
||||
1. **State sync**: mark tasks `DOING`/`DONE` in both sprint file `/docs/implplan/SPRINT_*.md` and local `TASKS.md` before/after changes.
|
||||
|
||||
@@ -5,12 +5,10 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
# Restore only filtered projects using offline/local feed
|
||||
NUGET_PACKAGES="$REPO_ROOT/offline/packages" \
|
||||
# Restore using standard NuGet cache
|
||||
DOTNET_RESTORE_DISABLE_PARALLEL=true \
|
||||
DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER=0 \
|
||||
dotnet restore src/Scanner/StellaOps.Scanner.Node.slnf \
|
||||
-p:RestorePackagesPath="$REPO_ROOT/offline/packages" \
|
||||
-p:ContinuousIntegrationBuild=true
|
||||
|
||||
# Run node analyzer tests in isolation (minimal logging)
|
||||
@@ -21,7 +19,6 @@ fi
|
||||
|
||||
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 \
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT=1 \
|
||||
NUGET_PACKAGES="$REPO_ROOT/offline/packages" \
|
||||
dotnet test src/Scanner/StellaOps.Scanner.Node.slnf \
|
||||
--no-restore \
|
||||
--settings "$REPO_ROOT/src/Scanner/__Tests/node-isolated.runsettings" \
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.Postgres.Testing", "src\__Tests\__Libraries\StellaOps.Infrastructure.Postgres.Testing\StellaOps.Infrastructure.Postgres.Testing.csproj", "{B7CA7A16-AAFB-5A8F-B598-0284ED7DF744}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Messaging.Testing", "src\__Tests\__Libraries\StellaOps.Messaging.Testing\StellaOps.Messaging.Testing.csproj", "{2E7B8D21-CAD8-5844-B59F-7A487E6594DD}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Router.Testing", "src\__Tests\__Libraries\StellaOps.Router.Testing\StellaOps.Router.Testing.csproj", "{F30EF61D-A7FC-5689-A06F-42A152CF7393}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Testing.AirGap", "src\__Tests\__Libraries\StellaOps.Testing.AirGap\StellaOps.Testing.AirGap.csproj", "{96610609-85C7-5F09-B765-A86463A8DBDE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Testing.Determinism", "src\__Tests\__Libraries\StellaOps.Testing.Determinism\StellaOps.Testing.Determinism.csproj", "{E5A69860-1704-5FB1-BFA3-5872182D4829}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Testing.Determinism.Properties", "src\__Tests\__Libraries\StellaOps.Testing.Determinism.Properties\StellaOps.Testing.Determinism.Properties.csproj", "{1F5FFF7C-AF58-5C3E-9981-EE5E978426E8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Testing.Manifests", "src\__Tests\__Libraries\StellaOps.Testing.Manifests\StellaOps.Testing.Manifests.csproj", "{51652C28-0583-5556-A941-D16D99F97B82}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Architecture.Tests", "src\__Tests\architecture\StellaOps.Architecture.Tests\StellaOps.Architecture.Tests.csproj", "{068138BD-177D-5359-B0DD-A369BB607E95}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Chaos.Router.Tests", "src\__Tests\chaos\StellaOps.Chaos.Router.Tests\StellaOps.Chaos.Router.Tests.csproj", "{91306E2D-A310-50D1-B64F-47A158D42085}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Integration.AirGap", "src\__Tests\Integration\StellaOps.Integration.AirGap\StellaOps.Integration.AirGap.csproj", "{F2126F28-8343-5BEB-BE5D-D0E4F7CA1A93}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Integration.Determinism", "src\__Tests\Integration\StellaOps.Integration.Determinism\StellaOps.Integration.Determinism.csproj", "{59234A8C-D502-5965-AAFC-19739C833885}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Integration.E2E", "src\__Tests\Integration\StellaOps.Integration.E2E\StellaOps.Integration.E2E.csproj", "{2CE72B3D-4D13-500A-A44D-76029069C773}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Integration.Performance", "src\__Tests\Integration\StellaOps.Integration.Performance\StellaOps.Integration.Performance.csproj", "{422C9F81-D3AB-5EFC-A6CD-245C7FA24ADF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Integration.Platform", "src\__Tests\Integration\StellaOps.Integration.Platform\StellaOps.Integration.Platform.csproj", "{8F7505CD-473C-590A-8851-FA762AB5E214}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Integration.ProofChain", "src\__Tests\Integration\StellaOps.Integration.ProofChain\StellaOps.Integration.ProofChain.csproj", "{B2ABA214-83FB-5E9E-8AD4-2D54E579310A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Integration.Reachability", "src\__Tests\Integration\StellaOps.Integration.Reachability\StellaOps.Integration.Reachability.csproj", "{3EC6A343-75E8-511F-A767-8FAB9EC79A62}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Integration.Unknowns", "src\__Tests\Integration\StellaOps.Integration.Unknowns\StellaOps.Integration.Unknowns.csproj", "{37DF1BF6-AD9C-59A2-8F10-512ABE804ED3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Interop.Tests", "src\__Tests\interop\StellaOps.Interop.Tests\StellaOps.Interop.Tests.csproj", "{A93B89A8-E39D-560B-82E8-96EAEA545A28}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Offline.E2E.Tests", "src\__Tests\offline\StellaOps.Offline.E2E.Tests\StellaOps.Offline.E2E.Tests.csproj", "{DF5A6010-D88B-5327-8E1A-74F2A716D340}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Parity.Tests", "src\__Tests\parity\StellaOps.Parity.Tests\StellaOps.Parity.Tests.csproj", "{C7E0CDBA-5E91-546C-AE25-27D0C82F1A23}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provenance.Attestation.Tests", "src\__Tests\Provenance\StellaOps.Provenance.Attestation.Tests\StellaOps.Provenance.Attestation.Tests.csproj", "{B143BD73-A4D7-51F3-804E-03CE8C6CF639}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Reachability.FixtureTests", "src\__Tests\reachability\StellaOps.Reachability.FixtureTests\StellaOps.Reachability.FixtureTests.csproj", "{53EEFE3D-CE01-598F-9EE0-49DF5F6806BF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Security.Tests", "src\__Tests\security\StellaOps.Security.Tests\StellaOps.Security.Tests.csproj", "{96E7DE01-9824-53C8-B4A6-5E8BA4BD42E3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Audit.ReplayToken.Tests", "src\__Tests\StellaOps.Audit.ReplayToken.Tests\StellaOps.Audit.ReplayToken.Tests.csproj", "{FB55B7A8-C0F5-53EE-B9E9-B66F4E4D453B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Evidence.Bundle.Tests", "src\__Tests\StellaOps.Evidence.Bundle.Tests\StellaOps.Evidence.Bundle.Tests.csproj", "{2063D4CC-6C01-5693-B0B9-1376FB928E43}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Microservice.Tests", "src\__Tests\StellaOps.Microservice.Tests\StellaOps.Microservice.Tests.csproj", "{B0A0E3D1-FF2E-5005-B619-4523C2A2C955}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Router.Common.Tests", "src\__Tests\StellaOps.Router.Common.Tests\StellaOps.Router.Common.Tests.csproj", "{004D507B-32A2-5704-8747-412E7B8EFAE4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Router.Config.Tests", "src\__Tests\StellaOps.Router.Config.Tests\StellaOps.Router.Config.Tests.csproj", "{FA6CBA17-E0E7-5C13-ADC3-0FB73949CCE0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Router.Gateway.Tests", "src\__Tests\StellaOps.Router.Gateway.Tests\StellaOps.Router.Gateway.Tests.csproj", "{62186A00-3E04-51EF-9497-258A973D6E24}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Router.Transport.InMemory.Tests", "src\__Tests\StellaOps.Router.Transport.InMemory.Tests\StellaOps.Router.Transport.InMemory.Tests.csproj", "{81DADA98-669F-5B5B-8C31-EA3B5CF77380}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Router.Transport.Udp.Tests", "src\__Tests\StellaOps.Router.Transport.Udp.Tests\StellaOps.Router.Transport.Udp.Tests.csproj", "{768155E4-8D91-5A02-A006-2B357C033E25}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.AuditPack.Tests", "src\__Tests\unit\StellaOps.AuditPack.Tests\StellaOps.AuditPack.Tests.csproj", "{DCA9FEBF-076C-5040-BFE8-1F8A0088DE79}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B7CA7A16-AAFB-5A8F-B598-0284ED7DF744}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B7CA7A16-AAFB-5A8F-B598-0284ED7DF744}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B7CA7A16-AAFB-5A8F-B598-0284ED7DF744}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B7CA7A16-AAFB-5A8F-B598-0284ED7DF744}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2E7B8D21-CAD8-5844-B59F-7A487E6594DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2E7B8D21-CAD8-5844-B59F-7A487E6594DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2E7B8D21-CAD8-5844-B59F-7A487E6594DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2E7B8D21-CAD8-5844-B59F-7A487E6594DD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F30EF61D-A7FC-5689-A06F-42A152CF7393}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F30EF61D-A7FC-5689-A06F-42A152CF7393}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F30EF61D-A7FC-5689-A06F-42A152CF7393}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F30EF61D-A7FC-5689-A06F-42A152CF7393}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{96610609-85C7-5F09-B765-A86463A8DBDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{96610609-85C7-5F09-B765-A86463A8DBDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{96610609-85C7-5F09-B765-A86463A8DBDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{96610609-85C7-5F09-B765-A86463A8DBDE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E5A69860-1704-5FB1-BFA3-5872182D4829}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E5A69860-1704-5FB1-BFA3-5872182D4829}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E5A69860-1704-5FB1-BFA3-5872182D4829}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E5A69860-1704-5FB1-BFA3-5872182D4829}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1F5FFF7C-AF58-5C3E-9981-EE5E978426E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1F5FFF7C-AF58-5C3E-9981-EE5E978426E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1F5FFF7C-AF58-5C3E-9981-EE5E978426E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1F5FFF7C-AF58-5C3E-9981-EE5E978426E8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{51652C28-0583-5556-A941-D16D99F97B82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{51652C28-0583-5556-A941-D16D99F97B82}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{51652C28-0583-5556-A941-D16D99F97B82}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{51652C28-0583-5556-A941-D16D99F97B82}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{068138BD-177D-5359-B0DD-A369BB607E95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{068138BD-177D-5359-B0DD-A369BB607E95}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{068138BD-177D-5359-B0DD-A369BB607E95}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{068138BD-177D-5359-B0DD-A369BB607E95}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{91306E2D-A310-50D1-B64F-47A158D42085}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{91306E2D-A310-50D1-B64F-47A158D42085}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{91306E2D-A310-50D1-B64F-47A158D42085}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{91306E2D-A310-50D1-B64F-47A158D42085}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F2126F28-8343-5BEB-BE5D-D0E4F7CA1A93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F2126F28-8343-5BEB-BE5D-D0E4F7CA1A93}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F2126F28-8343-5BEB-BE5D-D0E4F7CA1A93}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F2126F28-8343-5BEB-BE5D-D0E4F7CA1A93}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{59234A8C-D502-5965-AAFC-19739C833885}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{59234A8C-D502-5965-AAFC-19739C833885}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{59234A8C-D502-5965-AAFC-19739C833885}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{59234A8C-D502-5965-AAFC-19739C833885}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2CE72B3D-4D13-500A-A44D-76029069C773}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2CE72B3D-4D13-500A-A44D-76029069C773}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2CE72B3D-4D13-500A-A44D-76029069C773}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2CE72B3D-4D13-500A-A44D-76029069C773}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{422C9F81-D3AB-5EFC-A6CD-245C7FA24ADF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{422C9F81-D3AB-5EFC-A6CD-245C7FA24ADF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{422C9F81-D3AB-5EFC-A6CD-245C7FA24ADF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{422C9F81-D3AB-5EFC-A6CD-245C7FA24ADF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8F7505CD-473C-590A-8851-FA762AB5E214}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8F7505CD-473C-590A-8851-FA762AB5E214}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8F7505CD-473C-590A-8851-FA762AB5E214}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8F7505CD-473C-590A-8851-FA762AB5E214}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B2ABA214-83FB-5E9E-8AD4-2D54E579310A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B2ABA214-83FB-5E9E-8AD4-2D54E579310A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B2ABA214-83FB-5E9E-8AD4-2D54E579310A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B2ABA214-83FB-5E9E-8AD4-2D54E579310A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3EC6A343-75E8-511F-A767-8FAB9EC79A62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3EC6A343-75E8-511F-A767-8FAB9EC79A62}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3EC6A343-75E8-511F-A767-8FAB9EC79A62}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3EC6A343-75E8-511F-A767-8FAB9EC79A62}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{37DF1BF6-AD9C-59A2-8F10-512ABE804ED3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{37DF1BF6-AD9C-59A2-8F10-512ABE804ED3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{37DF1BF6-AD9C-59A2-8F10-512ABE804ED3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{37DF1BF6-AD9C-59A2-8F10-512ABE804ED3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A93B89A8-E39D-560B-82E8-96EAEA545A28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A93B89A8-E39D-560B-82E8-96EAEA545A28}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A93B89A8-E39D-560B-82E8-96EAEA545A28}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A93B89A8-E39D-560B-82E8-96EAEA545A28}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DF5A6010-D88B-5327-8E1A-74F2A716D340}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DF5A6010-D88B-5327-8E1A-74F2A716D340}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DF5A6010-D88B-5327-8E1A-74F2A716D340}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DF5A6010-D88B-5327-8E1A-74F2A716D340}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C7E0CDBA-5E91-546C-AE25-27D0C82F1A23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C7E0CDBA-5E91-546C-AE25-27D0C82F1A23}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C7E0CDBA-5E91-546C-AE25-27D0C82F1A23}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C7E0CDBA-5E91-546C-AE25-27D0C82F1A23}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B143BD73-A4D7-51F3-804E-03CE8C6CF639}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B143BD73-A4D7-51F3-804E-03CE8C6CF639}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B143BD73-A4D7-51F3-804E-03CE8C6CF639}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B143BD73-A4D7-51F3-804E-03CE8C6CF639}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{53EEFE3D-CE01-598F-9EE0-49DF5F6806BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{53EEFE3D-CE01-598F-9EE0-49DF5F6806BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{53EEFE3D-CE01-598F-9EE0-49DF5F6806BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{53EEFE3D-CE01-598F-9EE0-49DF5F6806BF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{96E7DE01-9824-53C8-B4A6-5E8BA4BD42E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{96E7DE01-9824-53C8-B4A6-5E8BA4BD42E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{96E7DE01-9824-53C8-B4A6-5E8BA4BD42E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{96E7DE01-9824-53C8-B4A6-5E8BA4BD42E3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FB55B7A8-C0F5-53EE-B9E9-B66F4E4D453B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FB55B7A8-C0F5-53EE-B9E9-B66F4E4D453B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FB55B7A8-C0F5-53EE-B9E9-B66F4E4D453B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FB55B7A8-C0F5-53EE-B9E9-B66F4E4D453B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2063D4CC-6C01-5693-B0B9-1376FB928E43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2063D4CC-6C01-5693-B0B9-1376FB928E43}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2063D4CC-6C01-5693-B0B9-1376FB928E43}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2063D4CC-6C01-5693-B0B9-1376FB928E43}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B0A0E3D1-FF2E-5005-B619-4523C2A2C955}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B0A0E3D1-FF2E-5005-B619-4523C2A2C955}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B0A0E3D1-FF2E-5005-B619-4523C2A2C955}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B0A0E3D1-FF2E-5005-B619-4523C2A2C955}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{004D507B-32A2-5704-8747-412E7B8EFAE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{004D507B-32A2-5704-8747-412E7B8EFAE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{004D507B-32A2-5704-8747-412E7B8EFAE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{004D507B-32A2-5704-8747-412E7B8EFAE4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FA6CBA17-E0E7-5C13-ADC3-0FB73949CCE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FA6CBA17-E0E7-5C13-ADC3-0FB73949CCE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FA6CBA17-E0E7-5C13-ADC3-0FB73949CCE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FA6CBA17-E0E7-5C13-ADC3-0FB73949CCE0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{62186A00-3E04-51EF-9497-258A973D6E24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{62186A00-3E04-51EF-9497-258A973D6E24}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{62186A00-3E04-51EF-9497-258A973D6E24}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{62186A00-3E04-51EF-9497-258A973D6E24}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{81DADA98-669F-5B5B-8C31-EA3B5CF77380}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{81DADA98-669F-5B5B-8C31-EA3B5CF77380}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{81DADA98-669F-5B5B-8C31-EA3B5CF77380}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{81DADA98-669F-5B5B-8C31-EA3B5CF77380}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{768155E4-8D91-5A02-A006-2B357C033E25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{768155E4-8D91-5A02-A006-2B357C033E25}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{768155E4-8D91-5A02-A006-2B357C033E25}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{768155E4-8D91-5A02-A006-2B357C033E25}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DCA9FEBF-076C-5040-BFE8-1F8A0088DE79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DCA9FEBF-076C-5040-BFE8-1F8A0088DE79}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DCA9FEBF-076C-5040-BFE8-1F8A0088DE79}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DCA9FEBF-076C-5040-BFE8-1F8A0088DE79}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{B7CA7A16-AAFB-5A8F-B598-0284ED7DF744} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{2E7B8D21-CAD8-5844-B59F-7A487E6594DD} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{F30EF61D-A7FC-5689-A06F-42A152CF7393} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{96610609-85C7-5F09-B765-A86463A8DBDE} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{E5A69860-1704-5FB1-BFA3-5872182D4829} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{1F5FFF7C-AF58-5C3E-9981-EE5E978426E8} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{51652C28-0583-5556-A941-D16D99F97B82} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{068138BD-177D-5359-B0DD-A369BB607E95} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{91306E2D-A310-50D1-B64F-47A158D42085} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{F2126F28-8343-5BEB-BE5D-D0E4F7CA1A93} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{59234A8C-D502-5965-AAFC-19739C833885} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{2CE72B3D-4D13-500A-A44D-76029069C773} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{422C9F81-D3AB-5EFC-A6CD-245C7FA24ADF} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{8F7505CD-473C-590A-8851-FA762AB5E214} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{B2ABA214-83FB-5E9E-8AD4-2D54E579310A} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{3EC6A343-75E8-511F-A767-8FAB9EC79A62} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{37DF1BF6-AD9C-59A2-8F10-512ABE804ED3} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{A93B89A8-E39D-560B-82E8-96EAEA545A28} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{DF5A6010-D88B-5327-8E1A-74F2A716D340} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{C7E0CDBA-5E91-546C-AE25-27D0C82F1A23} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{B143BD73-A4D7-51F3-804E-03CE8C6CF639} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{53EEFE3D-CE01-598F-9EE0-49DF5F6806BF} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{96E7DE01-9824-53C8-B4A6-5E8BA4BD42E3} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{FB55B7A8-C0F5-53EE-B9E9-B66F4E4D453B} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{2063D4CC-6C01-5693-B0B9-1376FB928E43} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{B0A0E3D1-FF2E-5005-B619-4523C2A2C955} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{004D507B-32A2-5704-8747-412E7B8EFAE4} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{FA6CBA17-E0E7-5C13-ADC3-0FB73949CCE0} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{62186A00-3E04-51EF-9497-258A973D6E24} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{81DADA98-669F-5B5B-8C31-EA3B5CF77380} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{768155E4-8D91-5A02-A006-2B357C033E25} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
{DCA9FEBF-076C-5040-BFE8-1F8A0088DE79} = {B487748B-DCC0-5C86-A5D8-C17BCF7CE71E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
2
src/StellaOps.Tests.slnx
Normal file
2
src/StellaOps.Tests.slnx
Normal file
@@ -0,0 +1,2 @@
|
||||
<Solution>
|
||||
</Solution>
|
||||
@@ -383,7 +383,7 @@ def parse_args(argv: Optional[List[str]] = None) -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Capture CERT-Bund search/export snapshots for Offline Kit packaging.",
|
||||
)
|
||||
parser.add_argument("--output", default="seed-data/cert-bund", help="Destination directory for artefacts.")
|
||||
parser.add_argument("--output", default="src/__Tests/__Datasets/seed-data/cert-bund", help="Destination directory for artefacts.")
|
||||
parser.add_argument("--start-year", type=int, default=2014, help="First year (inclusive) for export snapshots.")
|
||||
parser.add_argument(
|
||||
"--end-year",
|
||||
|
||||
@@ -133,4 +133,4 @@ Tests use Testcontainers for PostgreSQL integration testing.
|
||||
|
||||
- `docs/operations/postgresql-patterns-runbook.md` - Operational guide
|
||||
- `docs/implplan/SPRINT_3420_0001_0001_bitemporal_unknowns_schema.md` - Sprint spec
|
||||
- `deploy/postgres-validation/001_validate_rls.sql` - RLS validation
|
||||
- `devops/database/postgres/validation/001_validate_rls.sql` - RLS validation
|
||||
|
||||
@@ -44,16 +44,17 @@
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kb",
|
||||
"maximumError": "1mb"
|
||||
"maximumWarning": "750kb",
|
||||
"maximumError": "1.5mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "6kb",
|
||||
"maximumError": "12kb"
|
||||
"maximumWarning": "12kb",
|
||||
"maximumError": "20kb"
|
||||
}
|
||||
],
|
||||
"outputHashing": "all"
|
||||
"outputHashing": "all",
|
||||
"namedChunks": true
|
||||
},
|
||||
"development": {
|
||||
"optimization": false,
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"build:stats": "ng build --stats-json",
|
||||
"analyze": "ng build --stats-json && npx esbuild-visualizer --metadata dist/stellaops-web/browser/stats.json --open",
|
||||
"analyze:source-map": "ng build --source-map && npx source-map-explorer dist/stellaops-web/browser/*.js",
|
||||
"watch": "ng build --watch --configuration development",
|
||||
"test": "npm run verify:chromium && ng test --watch=false",
|
||||
"test:watch": "ng test --watch",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<span *ngIf="action.targetVersion"> → {{ action.targetVersion }}</span>
|
||||
</div>
|
||||
<div matListItemLine *ngIf="action.cveIds?.length" class="cve-list">
|
||||
CVEs: {{ action.cveIds.join(', ') }}
|
||||
CVEs: {{ action.cveIds?.join(', ') }}
|
||||
</div>
|
||||
<div matListItemLine *ngIf="action.estimatedEffort" class="effort-estimate">
|
||||
Estimated effort: {{ action.estimatedEffort }}
|
||||
|
||||
@@ -89,27 +89,30 @@ export class CompareViewComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
async loadTarget(id: string, type: 'current' | 'baseline'): Promise<void> {
|
||||
const target = await this.compareService.getTarget(id);
|
||||
if (type === 'current') {
|
||||
this.currentTarget.set(target);
|
||||
} else {
|
||||
this.baselineTarget.set(target);
|
||||
// Load baseline rationale
|
||||
const rationale = await this.compareService.getBaselineRationale(id);
|
||||
this.baselineRationale.set(rationale);
|
||||
}
|
||||
this.loadDelta();
|
||||
loadTarget(id: string, type: 'current' | 'baseline'): void {
|
||||
this.compareService.getTarget(id).subscribe(target => {
|
||||
if (type === 'current') {
|
||||
this.currentTarget.set(target);
|
||||
} else {
|
||||
this.baselineTarget.set(target);
|
||||
// Load baseline rationale
|
||||
this.compareService.getBaselineRationale(id).subscribe(rationale => {
|
||||
this.baselineRationale.set(rationale.selectionReason);
|
||||
});
|
||||
}
|
||||
this.loadDelta();
|
||||
});
|
||||
}
|
||||
|
||||
async loadDelta(): Promise<void> {
|
||||
loadDelta(): void {
|
||||
const current = this.currentTarget();
|
||||
const baseline = this.baselineTarget();
|
||||
if (!current || !baseline) return;
|
||||
|
||||
const delta = await this.compareService.computeDelta(current.id, baseline.id);
|
||||
this.categories.set(delta.categories);
|
||||
this.items.set(delta.items);
|
||||
this.compareService.computeDelta(current.id, baseline.id).subscribe(delta => {
|
||||
this.categories.set(delta.categories);
|
||||
this.items.set(delta.items);
|
||||
});
|
||||
}
|
||||
|
||||
selectCategory(categoryId: string): void {
|
||||
@@ -123,17 +126,12 @@ export class CompareViewComponent implements OnInit {
|
||||
this.loadEvidence(item);
|
||||
}
|
||||
|
||||
async loadEvidence(item: DeltaItem): Promise<void> {
|
||||
const current = this.currentTarget();
|
||||
const baseline = this.baselineTarget();
|
||||
if (!current || !baseline) return;
|
||||
|
||||
const evidence = await this.compareService.getItemEvidence(
|
||||
item.id,
|
||||
baseline.id,
|
||||
current.id
|
||||
);
|
||||
this.evidence.set(evidence);
|
||||
loadEvidence(item: DeltaItem): void {
|
||||
this.compareService.getItemEvidence(item.id).subscribe(panes => {
|
||||
// Get the first pane or create a placeholder
|
||||
const evidence = panes.length > 0 ? panes[0] : null;
|
||||
this.evidence.set(evidence);
|
||||
});
|
||||
}
|
||||
|
||||
toggleViewMode(): void {
|
||||
@@ -142,24 +140,25 @@ export class CompareViewComponent implements OnInit {
|
||||
);
|
||||
}
|
||||
|
||||
getChangeIcon(changeType: 'added' | 'removed' | 'changed'): string {
|
||||
getChangeIcon(changeType: 'added' | 'removed' | 'changed' | undefined): string {
|
||||
switch (changeType) {
|
||||
case 'added': return 'add_circle';
|
||||
case 'removed': return 'remove_circle';
|
||||
case 'changed': return 'change_circle';
|
||||
default: return 'help_outline';
|
||||
}
|
||||
}
|
||||
|
||||
getChangeClass(changeType: 'added' | 'removed' | 'changed'): string {
|
||||
return `change-${changeType}`;
|
||||
getChangeClass(changeType: 'added' | 'removed' | 'changed' | undefined): string {
|
||||
return changeType ? `change-${changeType}` : 'change-unknown';
|
||||
}
|
||||
|
||||
async exportReport(): Promise<void> {
|
||||
exportReport(): void {
|
||||
const current = this.currentTarget();
|
||||
const baseline = this.baselineTarget();
|
||||
if (!current || !baseline) return;
|
||||
|
||||
await this.exportService.exportJson(
|
||||
this.exportService.exportJson(
|
||||
current,
|
||||
baseline,
|
||||
this.categories(),
|
||||
|
||||
@@ -52,6 +52,7 @@ export interface CompareSession {
|
||||
* Compare target (current or baseline scan).
|
||||
*/
|
||||
export interface CompareTarget {
|
||||
id: string;
|
||||
digest: string;
|
||||
imageRef: string;
|
||||
scanDate: string;
|
||||
@@ -59,21 +60,37 @@ export interface CompareTarget {
|
||||
}
|
||||
|
||||
/**
|
||||
* Delta category for grouping changes.
|
||||
* Delta category type (string literal).
|
||||
*/
|
||||
export type DeltaCategory = 'added' | 'removed' | 'changed' | 'unchanged';
|
||||
export type DeltaCategoryType = 'added' | 'removed' | 'changed' | 'unchanged';
|
||||
|
||||
/**
|
||||
* Delta category for grouping changes with summary counts.
|
||||
*/
|
||||
export interface DeltaCategory {
|
||||
id: DeltaCategoryType;
|
||||
name: string;
|
||||
icon: string;
|
||||
added: number;
|
||||
removed: number;
|
||||
changed: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delta item representing a difference between scans.
|
||||
*/
|
||||
export interface DeltaItem {
|
||||
id: string;
|
||||
category: DeltaCategory;
|
||||
category: DeltaCategoryType;
|
||||
component: string;
|
||||
cve?: string;
|
||||
currentSeverity?: string;
|
||||
baselineSeverity?: string;
|
||||
description: string;
|
||||
// Export service expected properties
|
||||
changeType?: 'added' | 'removed' | 'changed';
|
||||
title?: string;
|
||||
severity?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,6 +100,18 @@ export interface EvidencePane {
|
||||
digest: string;
|
||||
data: Record<string, unknown>;
|
||||
loading: boolean;
|
||||
// View-specific properties
|
||||
title?: string;
|
||||
beforeEvidence?: Record<string, unknown>;
|
||||
afterEvidence?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of computing delta between scans.
|
||||
*/
|
||||
export interface DeltaResult {
|
||||
categories: DeltaCategory[];
|
||||
items: DeltaItem[];
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
@@ -206,10 +235,10 @@ export class CompareService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes delta between current and baseline.
|
||||
* Result of computing a delta between scans.
|
||||
*/
|
||||
computeDelta(currentDigest: string, baselineDigest: string): Observable<DeltaItem[]> {
|
||||
return this.http.get<DeltaItem[]>(
|
||||
computeDelta(currentDigest: string, baselineDigest: string): Observable<DeltaResult> {
|
||||
return this.http.get<DeltaResult>(
|
||||
`${this.baseUrl}/delta?current=${currentDigest}&baseline=${baselineDigest}`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -122,9 +122,9 @@ import { StellaOpsScopes } from '../../../core/auth/scopes';
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (event of paginatedEvents; track event.id) {
|
||||
@for (event of paginatedEvents; track event.id ?? event.eventType + event.occurredAt) {
|
||||
<tr>
|
||||
<td class="timestamp">{{ formatTimestamp(event.timestamp) }}</td>
|
||||
<td class="timestamp">{{ formatTimestamp(event.timestamp ?? event.occurredAt) }}</td>
|
||||
<td>
|
||||
<span class="event-badge" [class]="getEventClass(event.eventType)">
|
||||
{{ event.eventType }}
|
||||
@@ -182,7 +182,7 @@ import { StellaOpsScopes } from '../../../core/auth/scopes';
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Timestamp:</span>
|
||||
<span>{{ formatTimestamp(selectedEvent.timestamp) }}</span>
|
||||
<span>{{ formatTimestamp(selectedEvent.timestamp ?? selectedEvent.occurredAt) }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Event Type:</span>
|
||||
@@ -208,7 +208,7 @@ import { StellaOpsScopes } from '../../../core/auth/scopes';
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Metadata:</span>
|
||||
<pre class="metadata-json">{{ formatMetadata(selectedEvent.metadata) }}</pre>
|
||||
<pre class="metadata-json">{{ formatMetadata(selectedEvent.metadata ?? {}) }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -46,26 +46,21 @@ export class MonacoLoaderService {
|
||||
/**
|
||||
* Configure Monaco web workers for language services.
|
||||
* Ensures deterministic, offline-friendly loading (no CDN usage).
|
||||
*
|
||||
* OPTIMIZATION: Only load editor core + JSON worker.
|
||||
* Removed CSS/HTML/TypeScript workers to save ~3-4MB.
|
||||
* Stella DSL only needs basic editor + JSON-like validation.
|
||||
*/
|
||||
private async configureWorkers(monaco: MonacoNamespace): Promise<void> {
|
||||
const [editorWorker, cssWorker, htmlWorker, jsonWorker, tsWorker] = await Promise.all([
|
||||
// Only load essential workers - saves ~3-4MB
|
||||
const [editorWorker, jsonWorker] = await Promise.all([
|
||||
import('monaco-editor/esm/vs/editor/editor.worker?worker'),
|
||||
import('monaco-editor/esm/vs/language/css/css.worker?worker'),
|
||||
import('monaco-editor/esm/vs/language/html/html.worker?worker'),
|
||||
import('monaco-editor/esm/vs/language/json/json.worker?worker'),
|
||||
import('monaco-editor/esm/vs/language/typescript/ts.worker?worker'),
|
||||
]);
|
||||
|
||||
// Minimal worker mapping - all non-JSON languages use base editor worker
|
||||
const workerByLabel: Record<string, () => Worker> = {
|
||||
json: () => new (jsonWorker as any).default(),
|
||||
css: () => new (cssWorker as any).default(),
|
||||
scss: () => new (cssWorker as any).default(),
|
||||
less: () => new (cssWorker as any).default(),
|
||||
html: () => new (htmlWorker as any).default(),
|
||||
handlebars: () => new (htmlWorker as any).default(),
|
||||
razor: () => new (htmlWorker as any).default(),
|
||||
javascript: () => new (tsWorker as any).default(),
|
||||
typescript: () => new (tsWorker as any).default(),
|
||||
default: () => new (editorWorker as any).default(),
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
// Design system imports
|
||||
@import './styles/tokens/motion';
|
||||
@import './styles/mixins';
|
||||
|
||||
// Monaco Editor styles (lazy-loaded with editor)
|
||||
@import 'monaco-editor/min/vs/editor/editor.main.css';
|
||||
|
||||
/* Global motion helpers */
|
||||
|
||||
457
src/Web/StellaOps.Web/src/styles/_mixins.scss
Normal file
457
src/Web/StellaOps.Web/src/styles/_mixins.scss
Normal file
@@ -0,0 +1,457 @@
|
||||
// =============================================================================
|
||||
// Shared SCSS Mixins - Bundle Optimization
|
||||
// =============================================================================
|
||||
// These mixins consolidate common patterns to reduce component CSS size.
|
||||
// Import with: @use 'styles/mixins' as m;
|
||||
// =============================================================================
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Design Tokens (CSS Custom Properties fallbacks)
|
||||
// -----------------------------------------------------------------------------
|
||||
$color-surface: #ffffff !default;
|
||||
$color-surface-secondary: #f8fafc !default;
|
||||
$color-border: #e2e8f0 !default;
|
||||
$color-text-primary: #1e293b !default;
|
||||
$color-text-secondary: #64748b !default;
|
||||
$color-text-muted: #94a3b8 !default;
|
||||
$color-brand: #4f46e5 !default;
|
||||
$color-brand-light: rgba(79, 70, 229, 0.1) !default;
|
||||
|
||||
// Severity colors
|
||||
$severity-critical: #dc2626 !default;
|
||||
$severity-high: #ea580c !default;
|
||||
$severity-medium: #f59e0b !default;
|
||||
$severity-low: #22c55e !default;
|
||||
$severity-info: #3b82f6 !default;
|
||||
|
||||
// Spacing
|
||||
$spacing-xs: 0.25rem !default;
|
||||
$spacing-sm: 0.5rem !default;
|
||||
$spacing-md: 1rem !default;
|
||||
$spacing-lg: 1.5rem !default;
|
||||
$spacing-xl: 2rem !default;
|
||||
|
||||
// Border radius
|
||||
$radius-sm: 0.375rem !default;
|
||||
$radius-md: 0.5rem !default;
|
||||
$radius-lg: 0.75rem !default;
|
||||
$radius-xl: 1rem !default;
|
||||
|
||||
// Shadows
|
||||
$shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05) !default;
|
||||
$shadow-md: 0 1px 3px rgba(0, 0, 0, 0.1) !default;
|
||||
$shadow-lg: 0 4px 6px rgba(0, 0, 0, 0.1) !default;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Layout Mixins
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Flex container with common settings
|
||||
@mixin flex-row($gap: $spacing-md, $align: center) {
|
||||
display: flex;
|
||||
align-items: $align;
|
||||
gap: $gap;
|
||||
}
|
||||
|
||||
@mixin flex-col($gap: $spacing-md) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $gap;
|
||||
}
|
||||
|
||||
@mixin flex-between {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/// Grid with auto-fit columns
|
||||
@mixin auto-grid($min-width: 200px, $gap: $spacing-md) {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax($min-width, 1fr));
|
||||
gap: $gap;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Component Base Mixins
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Card/Panel base styling
|
||||
@mixin card-base($padding: $spacing-md) {
|
||||
padding: $padding;
|
||||
background: $color-surface;
|
||||
border-radius: $radius-lg;
|
||||
border: 1px solid $color-border;
|
||||
box-shadow: $shadow-md;
|
||||
}
|
||||
|
||||
/// Panel with header section
|
||||
@mixin panel-base {
|
||||
@include card-base($spacing-lg);
|
||||
}
|
||||
|
||||
/// Stat card styling
|
||||
@mixin stat-card {
|
||||
@include flex-col($spacing-xs);
|
||||
align-items: center;
|
||||
@include card-base;
|
||||
}
|
||||
|
||||
/// Toolbar container
|
||||
@mixin toolbar {
|
||||
@include flex-row;
|
||||
flex-wrap: wrap;
|
||||
@include card-base;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Form Element Mixins
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Base input styling
|
||||
@mixin input-base {
|
||||
padding: $spacing-sm $spacing-md;
|
||||
border: 1px solid $color-border;
|
||||
border-radius: $radius-md;
|
||||
font-size: 0.875rem;
|
||||
background: $color-surface;
|
||||
outline: none;
|
||||
transition: border-color 0.15s, box-shadow 0.15s;
|
||||
|
||||
&:focus {
|
||||
border-color: $color-brand;
|
||||
box-shadow: 0 0 0 3px $color-brand-light;
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
color: $color-text-muted;
|
||||
}
|
||||
}
|
||||
|
||||
/// Select dropdown
|
||||
@mixin select-base {
|
||||
@include input-base;
|
||||
cursor: pointer;
|
||||
min-width: 140px;
|
||||
}
|
||||
|
||||
/// Search box container
|
||||
@mixin search-box($max-width: 400px) {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-width: 250px;
|
||||
max-width: $max-width;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/// Filter group (label + control)
|
||||
@mixin filter-group {
|
||||
@include flex-col($spacing-xs);
|
||||
|
||||
label,
|
||||
&__label {
|
||||
font-size: 0.75rem;
|
||||
color: $color-text-secondary;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Typography Mixins
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@mixin heading-lg {
|
||||
margin: 0;
|
||||
font-size: 1.75rem;
|
||||
font-weight: 600;
|
||||
color: $color-text-primary;
|
||||
}
|
||||
|
||||
@mixin heading-md {
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: $color-text-primary;
|
||||
}
|
||||
|
||||
@mixin text-secondary {
|
||||
color: $color-text-secondary;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
@mixin text-label {
|
||||
font-size: 0.75rem;
|
||||
color: $color-text-secondary;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
@mixin text-mono {
|
||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Badge/Chip Mixins
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Base badge styling
|
||||
@mixin badge-base($bg: $color-surface-secondary, $color: $color-text-primary) {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0.125rem 0.5rem;
|
||||
border-radius: 9999px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
background: $bg;
|
||||
color: $color;
|
||||
}
|
||||
|
||||
/// Severity badge with color variants
|
||||
@mixin severity-badge($severity) {
|
||||
$colors: (
|
||||
'critical': $severity-critical,
|
||||
'high': $severity-high,
|
||||
'medium': $severity-medium,
|
||||
'low': $severity-low,
|
||||
'info': $severity-info,
|
||||
);
|
||||
|
||||
$color: map-get($colors, $severity);
|
||||
@if $color {
|
||||
@include badge-base(rgba($color, 0.1), $color);
|
||||
border: 1px solid rgba($color, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate all severity badge classes
|
||||
@mixin severity-badge-variants {
|
||||
&--critical,
|
||||
&.critical {
|
||||
@include severity-badge('critical');
|
||||
}
|
||||
&--high,
|
||||
&.high {
|
||||
@include severity-badge('high');
|
||||
}
|
||||
&--medium,
|
||||
&.medium {
|
||||
@include severity-badge('medium');
|
||||
}
|
||||
&--low,
|
||||
&.low {
|
||||
@include severity-badge('low');
|
||||
}
|
||||
&--info,
|
||||
&.info {
|
||||
@include severity-badge('info');
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Message/Alert Mixins
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@mixin message-base {
|
||||
padding: $spacing-md;
|
||||
border-radius: $radius-md;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
@mixin message-info {
|
||||
@include message-base;
|
||||
background: #e0f2fe;
|
||||
color: #0369a1;
|
||||
border: 1px solid #7dd3fc;
|
||||
}
|
||||
|
||||
@mixin message-success {
|
||||
@include message-base;
|
||||
background: #dcfce7;
|
||||
color: #166534;
|
||||
border: 1px solid #86efac;
|
||||
}
|
||||
|
||||
@mixin message-warning {
|
||||
@include message-base;
|
||||
background: #fef3c7;
|
||||
color: #92400e;
|
||||
border: 1px solid #fcd34d;
|
||||
}
|
||||
|
||||
@mixin message-error {
|
||||
@include message-base;
|
||||
background: #fef2f2;
|
||||
color: #991b1b;
|
||||
border: 1px solid #fca5a5;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Button Mixins
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@mixin btn-base {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: $spacing-sm;
|
||||
padding: $spacing-sm $spacing-md;
|
||||
border: none;
|
||||
border-radius: $radius-md;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.15s, opacity 0.15s;
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin btn-primary {
|
||||
@include btn-base;
|
||||
background: $color-brand;
|
||||
color: white;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: darken($color-brand, 8%);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin btn-secondary {
|
||||
@include btn-base;
|
||||
background: $color-surface-secondary;
|
||||
color: $color-text-primary;
|
||||
border: 1px solid $color-border;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: darken($color-surface-secondary, 3%);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin btn-ghost {
|
||||
@include btn-base;
|
||||
background: transparent;
|
||||
color: $color-text-secondary;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background: $color-surface-secondary;
|
||||
color: $color-text-primary;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin btn-icon {
|
||||
@include btn-ghost;
|
||||
padding: $spacing-sm;
|
||||
border-radius: $radius-md;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Table Mixins
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@mixin table-base {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
background: $color-surface;
|
||||
border-radius: $radius-lg;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@mixin table-header {
|
||||
background: $color-surface-secondary;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
color: $color-text-secondary;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
@mixin table-cell {
|
||||
padding: $spacing-md;
|
||||
border-bottom: 1px solid $color-border;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
@mixin table-row-hover {
|
||||
&:hover {
|
||||
background: $color-surface-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Scrollbar Mixins
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@mixin custom-scrollbar($width: 8px) {
|
||||
&::-webkit-scrollbar {
|
||||
width: $width;
|
||||
height: $width;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: $color-border;
|
||||
border-radius: $width;
|
||||
|
||||
&:hover {
|
||||
background: $color-text-muted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Utility Mixins
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Truncate text with ellipsis
|
||||
@mixin truncate($max-width: 100%) {
|
||||
max-width: $max-width;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/// Visually hidden but accessible
|
||||
@mixin visually-hidden {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/// Loading skeleton
|
||||
@mixin skeleton {
|
||||
background: linear-gradient(90deg, $color-surface-secondary 25%, $color-border 50%, $color-surface-secondary 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: skeleton-loading 1.5s infinite;
|
||||
border-radius: $radius-sm;
|
||||
}
|
||||
|
||||
@keyframes skeleton-loading {
|
||||
0% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
100% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Empty state container
|
||||
@mixin empty-state {
|
||||
@include flex-col;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: $spacing-xl * 2;
|
||||
color: $color-text-muted;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -3,13 +3,13 @@
|
||||
## Roles
|
||||
- Backend engineer: maintain the shared PostgreSQL infrastructure primitives (DataSourceBase, RepositoryBase, MigrationRunner, options/DI helpers).
|
||||
- QA automation: own Postgres Testcontainers coverage, tenant-context/RLS checks, and migration idempotency tests.
|
||||
- DevOps liaison: keep provisioning values in `ops/devops/postgres` aligned with library defaults (timeouts, schema names, TLS, pooling).
|
||||
- DevOps liaison: keep provisioning values in `devops/database/postgres` aligned with library defaults (timeouts, schema names, TLS, pooling).
|
||||
|
||||
## Required Reading
|
||||
- docs/db/README.md, SPECIFICATION.md, RULES.md, VERIFICATION.md, CONVERSION_PLAN.md
|
||||
- docs/modules/platform/architecture-overview.md
|
||||
- docs/airgap/airgap-mode.md
|
||||
- ops/devops/AGENTS.md (DevOps working agreement)
|
||||
- devops/AGENTS.md (DevOps working agreement)
|
||||
|
||||
## Working Directory & Scope
|
||||
- Primary: `src/__Libraries/StellaOps.Infrastructure.Postgres`
|
||||
@@ -28,5 +28,5 @@
|
||||
- Treat analyzer warnings as errors; ensure nullable enabled and `LangVersion` follows repo default.
|
||||
|
||||
## Handoff Notes
|
||||
- Align configuration defaults with the provisioning values under `ops/devops/postgres` (ports, pool sizes, SSL/TLS).
|
||||
- Align configuration defaults with the provisioning values under `devops/database/postgres` (ports, pool sizes, SSL/TLS).
|
||||
- Update this AGENTS file whenever connection/session rules or provisioning defaults change; record updates in the sprint Execution Log.
|
||||
|
||||
@@ -13,7 +13,7 @@ portal.
|
||||
## Recommended layout
|
||||
|
||||
```
|
||||
seed-data/cert-bund/
|
||||
src/__Tests/__Datasets/seed-data/cert-bund/
|
||||
├── search/ # paginated search JSON files
|
||||
│ ├── certbund-search-page-00.json
|
||||
│ └── …
|
||||
@@ -36,7 +36,7 @@ Run the helper under `src/Tools/` to capture fresh snapshots or regenerate
|
||||
the manifest:
|
||||
|
||||
```
|
||||
python src/Tools/certbund_offline_snapshot.py --output seed-data/cert-bund
|
||||
python src/Tools/certbund_offline_snapshot.py --output src/__Tests/__Datasets/seed-data/cert-bund
|
||||
```
|
||||
|
||||
See the connector operations guide
|
||||
|
||||
@@ -13,10 +13,10 @@ This directory contains HTML snapshots of the KISA/KNVD advisory detail pages (`
|
||||
## Regeneration
|
||||
|
||||
```bash
|
||||
python scripts/kisa_capture_html.py --out seed-data/kisa/html
|
||||
python devops/tools/kisa_capture_html.py --out src/__Tests/__Datasets/seed-data/kisa/html
|
||||
```
|
||||
|
||||
(See `scripts/kisa_capture_html.py` for exact implementation; it parses the RSS feed, walks each `IDX`, and writes `IDX.html` alongside a sha256 manifest.)
|
||||
(See `devops/tools/kisa_capture_html.py` for exact implementation; it parses the RSS feed, walks each `IDX`, and writes `IDX.html` alongside a sha256 manifest.)
|
||||
|
||||
## sha256 manifest
|
||||
|
||||
|
||||
Reference in New Issue
Block a user