feat(scheduler): plugin architecture + Doctor health check plugin

- Create ISchedulerJobPlugin abstraction with JobKind routing
- Add SchedulerPluginRegistry for plugin discovery and resolution
- Wrap existing scan logic as ScanJobPlugin (zero behavioral change)
- Extend Schedule model with JobKind (default "scan") and PluginConfig (jsonb)
- Add SQL migrations 007 (job_kind/plugin_config) and 008 (doctor_trends table)
- Implement DoctorJobPlugin replacing standalone doctor-scheduler service
- Add PostgresDoctorTrendRepository for persistent trend storage
- Register Doctor trend endpoints at /api/v1/scheduler/doctor/trends/*
- Seed 3 default Doctor schedules (daily full, hourly quick, weekly compliance)
- Comment out doctor-scheduler container in compose and services-matrix
- Update Doctor architecture docs and AGENTS.md with scheduling migration info

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-04-08 16:24:46 +03:00
parent 53f294400f
commit 908619e739
32 changed files with 1619 additions and 55 deletions

View File

@@ -1606,29 +1606,32 @@ services:
<<: *healthcheck-tcp
labels: *release-labels
doctor-scheduler:
<<: *resources-light
image: stellaops/doctor-scheduler:dev
container_name: stellaops-doctor-scheduler
restart: unless-stopped
depends_on: *depends-infra
environment:
ASPNETCORE_URLS: "http://+:80"
<<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
ConnectionStrings__Default: *postgres-connection
ConnectionStrings__Redis: "cache.stella-ops.local:6379"
Router__Enabled: "${DOCTOR_SCHEDULER_ROUTER_ENABLED:-true}"
Router__Messaging__ConsumerGroup: "doctor-scheduler"
volumes:
- *cert-volume
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
<<: *healthcheck-tcp
networks:
stellaops:
aliases:
- doctor-scheduler.stella-ops.local
labels: *release-labels
# DEPRECATED: doctor-scheduler is replaced by the DoctorJobPlugin in the Scheduler service.
# Scheduling and trend storage are now handled by the Scheduler with jobKind="doctor".
# See: SPRINT_20260408_003_JobEngine_scheduler_plugin_architecture.md
# doctor-scheduler:
# <<: *resources-light
# image: stellaops/doctor-scheduler:dev
# container_name: stellaops-doctor-scheduler
# restart: unless-stopped
# depends_on: *depends-infra
# environment:
# ASPNETCORE_URLS: "http://+:80"
# <<: [*kestrel-cert, *router-microservice-defaults, *gc-light]
# ConnectionStrings__Default: *postgres-connection
# ConnectionStrings__Redis: "cache.stella-ops.local:6379"
# Router__Enabled: "${DOCTOR_SCHEDULER_ROUTER_ENABLED:-true}"
# Router__Messaging__ConsumerGroup: "doctor-scheduler"
# volumes:
# - *cert-volume
# healthcheck:
# test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/$(hostname)/80'"]
# <<: *healthcheck-tcp
# networks:
# stellaops:
# aliases:
# - doctor-scheduler.stella-ops.local
# labels: *release-labels
# --- Slot 27: OpsMemory (src/AdvisoryAI/StellaOps.OpsMemory.WebService) ---
opsmemory-web:

View File

@@ -61,7 +61,8 @@ timeline-web|devops/docker/Dockerfile.hardened.template|src/Timeline/StellaOps.T
findings-ledger-web|devops/docker/Dockerfile.hardened.template|src/Findings/StellaOps.Findings.Ledger.WebService/StellaOps.Findings.Ledger.WebService.csproj|StellaOps.Findings.Ledger.WebService|8080
# ── Slot 26: Doctor ─────────────────────────────────────────────────────────────
doctor-web|devops/docker/Dockerfile.hardened.template|src/Doctor/StellaOps.Doctor.WebService/StellaOps.Doctor.WebService.csproj|StellaOps.Doctor.WebService|8080
doctor-scheduler|devops/docker/Dockerfile.hardened.template|src/Doctor/StellaOps.Doctor.Scheduler/StellaOps.Doctor.Scheduler.csproj|StellaOps.Doctor.Scheduler|8080
# DEPRECATED: doctor-scheduler replaced by DoctorJobPlugin in Scheduler service
# doctor-scheduler|devops/docker/Dockerfile.hardened.template|src/Doctor/StellaOps.Doctor.Scheduler/StellaOps.Doctor.Scheduler.csproj|StellaOps.Doctor.Scheduler|8080
# ── Slot 27: OpsMemory ──────────────────────────────────────────────────────────
opsmemory-web|devops/docker/Dockerfile.hardened.template|src/AdvisoryAI/StellaOps.OpsMemory.WebService/StellaOps.OpsMemory.WebService.csproj|StellaOps.OpsMemory.WebService|8080
# ── Slot 28: Notifier ───────────────────────────────────────────────────────────