{
  "admin_dsn_required": true,
  "available": true,
  "checks": [
    {
      "id": "security_feed_observations_table",
      "label": "Feed-Observations-Tabelle",
      "operator_action": "infra/postgres/migrations/security-feed-storage.sql mit DB-Owner/Admin aus sicherer Shell anwenden.",
      "purpose": "Private Malware-/Blacklist-/DAST-Observations mit Hash, Verdict, Review- und Publish-Status.",
      "ready": false,
      "required_for_storage": true,
      "status": "missing"
    },
    {
      "id": "security_feed_alert_links_table",
      "label": "Alert-Link-Tabelle",
      "operator_action": "infra/postgres/migrations/security-feed-storage.sql mit DB-Owner/Admin aus sicherer Shell anwenden.",
      "purpose": "Verknuepft private Feed-Observations mit Alerts/Tickets ohne Rohpayload-Export.",
      "ready": false,
      "required_for_storage": true,
      "status": "missing"
    },
    {
      "id": "security_feed_audit_log_table",
      "label": "Feed-Auditlog",
      "operator_action": "infra/postgres/migrations/security-feed-storage.sql mit DB-Owner/Admin aus sicherer Shell anwenden.",
      "purpose": "Append-only Review-, Publish-, Suppress- und Delete-Entscheidungen.",
      "ready": false,
      "required_for_storage": true,
      "status": "missing"
    },
    {
      "id": "security_feed_observations_domain_checked_idx",
      "label": "Domain/Checked-Index",
      "operator_action": "infra/postgres/migrations/security-feed-storage.sql mit DB-Owner/Admin aus sicherer Shell anwenden.",
      "purpose": "Schneller Zugriff auf letzte Feed-Checks pro Domain.",
      "ready": false,
      "required_for_storage": true,
      "status": "missing"
    },
    {
      "id": "security_feed_observations_source_verdict_idx",
      "label": "Source/Verdict-Index",
      "operator_action": "infra/postgres/migrations/security-feed-storage.sql mit DB-Owner/Admin aus sicherer Shell anwenden.",
      "purpose": "Auswertung nach Feed-Quelle und Verdict.",
      "ready": false,
      "required_for_storage": true,
      "status": "missing"
    },
    {
      "id": "security_feed_observations_expires_idx",
      "label": "Retention-Index",
      "operator_action": "infra/postgres/migrations/security-feed-storage.sql mit DB-Owner/Admin aus sicherer Shell anwenden.",
      "purpose": "Loesch- und Ablaufjobs finden faellige Observations.",
      "ready": false,
      "required_for_storage": true,
      "status": "missing"
    },
    {
      "id": "security_feed_observations_result_meta_gin_idx",
      "label": "Result-Meta-GIN-Index",
      "operator_action": "infra/postgres/migrations/security-feed-storage.sql mit DB-Owner/Admin aus sicherer Shell anwenden.",
      "purpose": "Sanitisierte Metadaten bleiben filterbar.",
      "ready": false,
      "required_for_storage": true,
      "status": "missing"
    },
    {
      "id": "security_feed_alert_links_dedupe_idx",
      "label": "Alert-Dedupe-Index",
      "operator_action": "infra/postgres/migrations/security-feed-storage.sql mit DB-Owner/Admin aus sicherer Shell anwenden.",
      "purpose": "Verhindert doppelte Alert-Verknuepfungen.",
      "ready": false,
      "required_for_storage": true,
      "status": "missing"
    },
    {
      "id": "security_feed_audit_log_dedupe_idx",
      "label": "Audit-Dedupe-Index",
      "operator_action": "infra/postgres/migrations/security-feed-storage.sql mit DB-Owner/Admin aus sicherer Shell anwenden.",
      "purpose": "Audit-Events koennen pro Dedupe-Key nachvollzogen werden.",
      "ready": false,
      "required_for_storage": true,
      "status": "missing"
    },
    {
      "id": "security_feed_observations_set_updated_at_trigger",
      "label": "Observations-updated_at-Trigger",
      "operator_action": "infra/postgres/migrations/security-feed-storage.sql mit DB-Owner/Admin aus sicherer Shell anwenden.",
      "purpose": "Aenderungen setzen updated_at automatisch.",
      "ready": false,
      "required_for_storage": true,
      "status": "missing"
    },
    {
      "id": "security_feed_alert_links_set_updated_at_trigger",
      "label": "Alert-Link-updated_at-Trigger",
      "operator_action": "infra/postgres/migrations/security-feed-storage.sql mit DB-Owner/Admin aus sicherer Shell anwenden.",
      "purpose": "Aenderungen setzen updated_at automatisch.",
      "ready": false,
      "required_for_storage": true,
      "status": "missing"
    }
  ],
  "database_name": "saferpage",
  "database_reachable": true,
  "db_user_redacted": "63a9f0ea7bb98050796b649e85481845",
  "generated_at": "2026-06-09T21:05:24.958878Z",
  "migration_path": "infra/postgres/migrations/security-feed-storage.sql",
  "migration_required": true,
  "migration_sha256": "306a569bdf0d59054861ddc8ddfcf0d09a825f097f3d1dbe88993e481f048314",
  "missing_artifact_count": 11,
  "missing_required_artifacts": [
    "security_feed_observations_table",
    "security_feed_alert_links_table",
    "security_feed_audit_log_table",
    "security_feed_observations_domain_checked_idx",
    "security_feed_observations_source_verdict_idx",
    "security_feed_observations_expires_idx",
    "security_feed_observations_result_meta_gin_idx",
    "security_feed_alert_links_dedupe_idx",
    "security_feed_audit_log_dedupe_idx",
    "security_feed_observations_set_updated_at_trigger",
    "security_feed_alert_links_set_updated_at_trigger"
  ],
  "operator_runbook": [
    "Kurzlebigen Admin-DSN nur in einer sicheren Shell setzen; nicht in History, Projektdateien, systemd-Units oder Public-State speichern.",
    "scripts/run-security-feed-storage-preflight.sh ausfuehren und missing_required_artifacts pruefen.",
    "infra/postgres/migrations/security-feed-storage.sql mit DB-Owner/Admin anwenden oder scripts/run-storage-migrations.sh nutzen.",
    "Preflight erneut ausfuehren, danach Retention/Review freigeben und erst dann SAFERPAGE_SECURITY_FEED_STORAGE_APPROVED setzen.",
    "Storage-Canary ausfuehren, bevor echte externe Feed-Treffer gespeichert werden."
  ],
  "public_schema_create_privilege": false,
  "ready_artifact_count": 0,
  "required_artifact_count": 11,
  "safe_apply_command": "psql -d saferpage -v ON_ERROR_STOP=1 -f infra/postgres/migrations/security-feed-storage.sql",
  "safe_combined_apply_command": "SAFERPAGE_MIGRATION_DATABASE_URL='postgresql://admin@localhost/saferpage' scripts/run-storage-migrations.sh",
  "safe_next_action": "Apply the storage migration from a secure shell with a DB owner/admin role; keep credentials out of project files, public state and logs.",
  "safe_preflight_command": "scripts/run-security-feed-storage-preflight.sh",
  "schema": "https://saferpage.de/schemas/security-feed-storage-preflight.v1",
  "secret_policy": "No DSN, password, raw database user, host, port, feed credential, webhook URL or raw feed payload is exported.",
  "security_feed_alert_links_dedupe_idx": false,
  "security_feed_alert_links_set_updated_at_trigger": false,
  "security_feed_alert_links_table": false,
  "security_feed_audit_log_dedupe_idx": false,
  "security_feed_audit_log_table": false,
  "security_feed_observations_domain_checked_idx": false,
  "security_feed_observations_expires_idx": false,
  "security_feed_observations_result_meta_gin_idx": false,
  "security_feed_observations_set_updated_at_trigger": false,
  "security_feed_observations_source_verdict_idx": false,
  "security_feed_observations_table": false,
  "storage_artifact_ready": false
}
