API-referentie

Risico's exporteren

Risico's worden geëxporteerd met de risks_paged-query. Elk risico bevat beoordelingsscores (kans, impact, restscores), de behandelbeslissing, gekoppelde controls en gekoppelde assets.

Basisquery

query ExportRisks($first: Int, $after: String, $filter: RiskFilter) {
  risks_paged(first: $first, after: $after, filter: $filter) {
    edges {
      node {
        id
        sequenceId
        customId
        name
        description
        notBefore
        expires
        archived
        likelihood
        impact
        residualLikelihood
        residualImpact
        treatment
        treatmentNotes
        appetite
        controls {
          id
          sequenceId
          name
        }
        assets {
          id
          name
        }
        assignments {
          assignmentType
          user {
            name
            email
          }
        }
        attributes {
          key
          value
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

Variabelen voor de eerste pagina:

{ "first": 50, "after": null, "filter": {} }

Belangrijke velden

  • sequenceId — het leesbare nummer zoals getoond in de UI (bijv. R-42)
  • customId — optionele aangepaste identifier ingesteld door je team
  • likelihood / impact — inherente risicobeoordelingscores (schaal 1–5)
  • residualLikelihood / residualImpact — resterende risicobeoordelingscores na controls
  • treatment — één van ACCEPT, AVOID, TRANSFER, REDUCE
  • appetite — de risicobereidheid van de organisatie voor dit risico

Volledig exportscript (Python)

import requests
import json
import csv

GRAPHQL_URL = "https://portal.tidalcontrol.com/graphql"

QUERY = """
query ExportRisks($first: Int, $after: String, $filter: RiskFilter) {
  risks_paged(first: $first, after: $after, filter: $filter) {
    edges {
      node {
        id
        sequenceId
        customId
        name
        description
        notBefore
        expires
        archived
        likelihood
        impact
        residualLikelihood
        residualImpact
        treatment
        treatmentNotes
        appetite
        controls { id name }
        assets { id name }
        assignments { assignmentType user { name email } }
      }
    }
    pageInfo { hasNextPage endCursor }
  }
}
"""


def graphql(query, variables, access_token):
    r = requests.post(
        GRAPHQL_URL,
        json={"query": query, "variables": variables},
        headers={"Authorization": f"Bearer {access_token}"},
    )
    r.raise_for_status()
    result = r.json()
    if "errors" in result:
        raise RuntimeError(result["errors"])
    return result["data"]


def export_risks(access_token, include_archived=False):
    risks = []
    cursor = None
    risk_filter = {"archived": include_archived} if include_archived else {}

    while True:
        data = graphql(
            QUERY,
            {"first": 50, "after": cursor, "filter": risk_filter},
            access_token,
        )
        page = data["risks_paged"]
        risks.extend(edge["node"] for edge in page["edges"])

        if not page["pageInfo"]["hasNextPage"]:
            break
        cursor = page["pageInfo"]["endCursor"]

    return risks


def to_csv(risks, output_path):
    if not risks:
        print("Geen risico's gevonden.")
        return

    with open(output_path, "w", newline="", encoding="utf-8") as f:
        writer = csv.writer(f)
        writer.writerow([
            "ID", "Volgnummer", "Aangepast ID", "Naam", "Omschrijving",
            "Startdatum", "Vervaldatum", "Gearchiveerd",
            "Kans", "Impact", "Restkans", "Restimpact",
            "Behandeling", "Behandelingstoelichting", "Risicobereidheid",
            "Controls", "Assets", "Eigenaren",
        ])
        for r in risks:
            owners = [
                a["user"]["email"]
                for a in r["assignments"]
                if a["assignmentType"] == "OWNER"
            ]
            writer.writerow([
                r["id"],
                r["sequenceId"],
                r.get("customId", ""),
                r["name"],
                r.get("description", ""),
                r.get("notBefore", ""),
                r.get("expires", ""),
                r["archived"],
                r.get("likelihood", ""),
                r.get("impact", ""),
                r.get("residualLikelihood", ""),
                r.get("residualImpact", ""),
                r.get("treatment", ""),
                r.get("treatmentNotes", ""),
                r.get("appetite", ""),
                ", ".join(c["name"] for c in r["controls"]),
                ", ".join(a["name"] for a in r["assets"]),
                ", ".join(owners),
            ])

    print(f"{len(risks)} risico's geëxporteerd naar {output_path}")


if __name__ == "__main__":
    # Plak hier je toegangstoken of laad het via het authenticatiescript
    ACCESS_TOKEN = "eyJhbGci..."

    risks = export_risks(ACCESS_TOKEN)
    to_csv(risks, "risicos_export.csv")

Filtervoorbeelden

Alleen actieve (niet-gearchiveerde) risico's:

{ "filter": { "archived": false } }

Risico's met behandeling REDUCE:

# RiskFilter filtert niet rechtstreeks op behandeling.
# Haal alle risico's op en filter in Python:
risks_reduce = [r for r in risks if r.get("treatment") == "REDUCE"]

Risico's toegewezen aan een specifieke gebruiker:

{ "filter": { "assignees": ["gebruiker-uuid-hier"] } }

Risico's gekoppeld aan een specifiek framework:

{ "filter": { "frameworks": ["framework-uuid-hier"] } }
Info

Gebruik de users_paged- of frameworks_paged-query's om gebruikers-UUID's of framework-UUID's op te zoeken.

Alleen tellen

Controleer hoeveel risico's er bestaan voordat je exporteert:

query {
  risks_count(filter: { archived: false })
}