GraphQL Inactive User Cleanup

API
5 nodes · 5 edgesapi
ex-graphql-mutation.osop.yaml
# GraphQL Mutation Workflow
# Query users, filter inactive accounts, delete via mutation, audit, and notify.
osop_version: "2.0"
id: graphql-mutation
name: GraphQL Inactive User Cleanup

nodes:
  - id: query_users
    type: api
    subtype: graphql
    purpose: Fetch all users with their last active timestamps
    runtime:
      endpoint: /graphql
      method: POST
      url: https://api.platform.com
    security:
      auth: bearer_token
      secret_ref: PLATFORM_API_TOKEN
    outputs:
      - users_list
    explain: "Executes query { users { id email lastActiveAt status } }"

  - id: filter_inactive
    type: cli
    purpose: Filter users inactive for more than 365 days
    runtime:
      command: "python filter_users.py --inactive-days 365 --input ${users_list}"
    inputs:
      - users_list
    outputs:
      - inactive_users
      - inactive_count

  - id: delete_users
    type: api
    subtype: graphql
    purpose: Execute bulk mutation to soft-delete inactive user accounts
    runtime:
      endpoint: /graphql
      method: POST
      url: https://api.platform.com
    inputs:
      - inactive_users
    outputs:
      - deletion_result
    security:
      auth: bearer_token
      secret_ref: PLATFORM_API_TOKEN
    retry_policy:
      max_retries: 2
      backoff_sec: 5
    explain: "Runs mutation { deleteUsers(ids: [...]) { count errors } }"

  - id: log_audit
    type: db
    purpose: Record deletion event in the compliance audit log
    runtime:
      engine: postgres
      connection: postgresql://compliance:5432/audit
    inputs:
      - deletion_result
      - inactive_users
    outputs:
      - audit_record_id

  - id: notify_admin
    type: api
    purpose: Send cleanup summary to admin Slack channel
    runtime:
      endpoint: /api/v1/messages
      method: POST
      url: https://hooks.slack.com
    inputs:
      - inactive_count
      - deletion_result
      - audit_record_id
    outputs:
      - notification_status

edges:
  - from: query_users
    to: filter_inactive
    mode: sequential

  - from: filter_inactive
    to: delete_users
    mode: conditional
    condition: "inactive_count > 0"
    explain: "Skip deletion if no inactive users found."

  - from: delete_users
    to: log_audit
    mode: sequential

  - from: log_audit
    to: notify_admin
    mode: sequential

  - from: delete_users
    to: notify_admin
    mode: error
    condition: "deletion_result.errors.length > 0"
    explain: "Notify admin immediately on deletion errors."