{
  "openapi": "3.1.0",
  "info": {
    "title": "RSX Webhooks",
    "version": "v1",
    "description": "GitHub App event receiver that relays repository activity (push, PRs, CI, releases) to Discord."
  },
  "servers": [
    {
      "url": "https://api.rsx.group"
    }
  ],
  "components": {
    "schemas": {
      "WebhookInstallation": {
        "type": "object",
        "properties": {
          "installationId": {
            "type": "string",
            "example": "48291733"
          },
          "accountLogin": {
            "type": "string",
            "example": "whitehill-group"
          },
          "accountType": {
            "type": "string",
            "example": "Organization"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "suspendedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "repoCount": {
            "type": "integer",
            "example": 3
          }
        },
        "required": [
          "installationId",
          "accountLogin",
          "accountType",
          "createdAt",
          "suspendedAt",
          "repoCount"
        ]
      },
      "WebhookEvents": {
        "type": "object",
        "additionalProperties": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "description": "Enabled events keyed by family → enabled action keys. Atomic families use [] (present = on)."
      },
      "WebhookRepo": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "installationId": {
            "type": "string",
            "example": "48291733"
          },
          "fullName": {
            "type": "string",
            "example": "whitehill-group/rsx-infra"
          },
          "private": {
            "type": "boolean"
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether events for this repo are relayed to Discord."
          },
          "events": {
            "$ref": "#/components/schemas/WebhookEvents"
          },
          "hideBots": {
            "type": "boolean",
            "description": "Skip activity from bot actors (dependabot, github-actions, …)."
          },
          "pingRules": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "event": {
                  "type": "string",
                  "example": "workflow_run"
                },
                "condition": {
                  "type": "string",
                  "description": "CI conclusion, or the catalog action.",
                  "example": "failure"
                },
                "targets": {
                  "type": "array",
                  "items": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "kind": {
                            "type": "string",
                            "enum": [
                              "user"
                            ]
                          },
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "kind",
                          "id"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "kind": {
                            "type": "string",
                            "enum": [
                              "role"
                            ]
                          },
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "kind",
                          "id"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "kind": {
                            "type": "string",
                            "enum": [
                              "everyone"
                            ]
                          }
                        },
                        "required": [
                          "kind"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "kind": {
                            "type": "string",
                            "enum": [
                              "here"
                            ]
                          }
                        },
                        "required": [
                          "kind"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "kind": {
                            "type": "string",
                            "enum": [
                              "linked"
                            ]
                          },
                          "who": {
                            "type": "string",
                            "enum": [
                              "assignee",
                              "reviewer",
                              "author",
                              "actor"
                            ]
                          }
                        },
                        "required": [
                          "kind",
                          "who"
                        ]
                      }
                    ]
                  }
                }
              },
              "required": [
                "id",
                "event",
                "targets"
              ]
            },
            "description": "Ping targets keyed by event + condition."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Repo description, shown in the channel topic."
          },
          "discordChannelId": {
            "type": [
              "string",
              "null"
            ],
            "example": "1180000000000000000"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ],
            "description": "Current relay/permission problem, or null when healthy."
          },
          "lastErrorAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "lastOkAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Last successful enable/relay."
          }
        },
        "required": [
          "id",
          "installationId",
          "fullName",
          "private",
          "enabled",
          "events",
          "hideBots",
          "pingRules",
          "description",
          "discordChannelId",
          "createdAt",
          "updatedAt",
          "lastError",
          "lastErrorAt",
          "lastOkAt"
        ]
      },
      "ConfigureRepo": {
        "type": "object",
        "properties": {
          "repoId": {
            "type": "string",
            "format": "uuid"
          },
          "enabled": {
            "type": "boolean"
          },
          "events": {
            "$ref": "#/components/schemas/WebhookEvents"
          },
          "hideBots": {
            "type": "boolean"
          },
          "pingRules": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "event": {
                  "type": "string",
                  "example": "workflow_run"
                },
                "condition": {
                  "type": "string",
                  "description": "CI conclusion, or the catalog action.",
                  "example": "failure"
                },
                "targets": {
                  "type": "array",
                  "items": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "kind": {
                            "type": "string",
                            "enum": [
                              "user"
                            ]
                          },
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "kind",
                          "id"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "kind": {
                            "type": "string",
                            "enum": [
                              "role"
                            ]
                          },
                          "id": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "kind",
                          "id"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "kind": {
                            "type": "string",
                            "enum": [
                              "everyone"
                            ]
                          }
                        },
                        "required": [
                          "kind"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "kind": {
                            "type": "string",
                            "enum": [
                              "here"
                            ]
                          }
                        },
                        "required": [
                          "kind"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "kind": {
                            "type": "string",
                            "enum": [
                              "linked"
                            ]
                          },
                          "who": {
                            "type": "string",
                            "enum": [
                              "assignee",
                              "reviewer",
                              "author",
                              "actor"
                            ]
                          }
                        },
                        "required": [
                          "kind",
                          "who"
                        ]
                      }
                    ]
                  }
                }
              },
              "required": [
                "id",
                "event",
                "targets"
              ]
            }
          }
        },
        "required": [
          "repoId"
        ]
      },
      "DisconnectRepo": {
        "type": "object",
        "properties": {
          "repoId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "repoId"
        ]
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "deliveryId": {
            "type": "string",
            "description": "GitHub X-GitHub-Delivery id.",
            "example": "8f9a…"
          },
          "event": {
            "type": "string",
            "example": "push"
          },
          "action": {
            "type": [
              "string",
              "null"
            ],
            "example": "opened"
          },
          "repoFullName": {
            "type": [
              "string",
              "null"
            ],
            "example": "whitehill-group/rsx-infra"
          },
          "status": {
            "type": "string",
            "enum": [
              "posted",
              "skipped",
              "ignored",
              "error"
            ],
            "description": "posted → relayed; skipped → repo/event off; ignored → unsupported/dup; error → relay failed."
          },
          "detail": {
            "type": [
              "string",
              "null"
            ]
          },
          "at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "deliveryId",
          "event",
          "action",
          "repoFullName",
          "status",
          "detail",
          "at"
        ]
      },
      "RepoAuditRecord": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "actor": {
            "type": "string",
            "example": "ada@rsx.group"
          },
          "action": {
            "type": "string",
            "enum": [
              "enabled",
              "disabled",
              "events_changed",
              "filters_changed",
              "pings_changed",
              "disconnected"
            ]
          },
          "repoId": {
            "type": "string",
            "format": "uuid"
          },
          "repoFullName": {
            "type": "string",
            "example": "whitehill-group/rsx-infra"
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "detail": {
            "type": [
              "string",
              "null"
            ],
            "example": "events: 3 → 5 families"
          }
        },
        "required": [
          "id",
          "actor",
          "action",
          "repoId",
          "repoFullName",
          "at",
          "detail"
        ]
      }
    },
    "parameters": {}
  },
  "paths": {
    "/webhooks/v1/admin/status": {
      "get": {
        "operationId": "webhooksStatus",
        "summary": "Report whether the GitHub + Discord integration is configured",
        "tags": [
          "admin"
        ],
        "responses": {
          "200": {
            "description": "Configuration status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "githubConfigured": {
                          "type": "boolean"
                        },
                        "discordConfigured": {
                          "type": "boolean"
                        },
                        "appSlug": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "GitHub App slug, for the install deep link."
                        }
                      },
                      "required": [
                        "githubConfigured",
                        "discordConfigured",
                        "appSlug"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/v1/admin/installations": {
      "get": {
        "operationId": "listInstallations",
        "summary": "List GitHub App installations",
        "tags": [
          "admin"
        ],
        "responses": {
          "200": {
            "description": "Installations",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookInstallation"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/v1/admin/repos": {
      "get": {
        "operationId": "listWebhookRepos",
        "summary": "List repositories and their relay config",
        "tags": [
          "admin"
        ],
        "responses": {
          "200": {
            "description": "Repositories",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookRepo"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/v1/admin/repos/configure": {
      "post": {
        "operationId": "configureWebhookRepo",
        "summary": "Enable/disable a repo and set its relayed events",
        "tags": [
          "admin"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConfigureRepo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookRepo"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/v1/admin/repos/disconnect": {
      "post": {
        "operationId": "disconnectWebhookRepo",
        "summary": "Delete a repo's Discord channel and disable its relay",
        "tags": [
          "admin"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DisconnectRepo"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Disconnected",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookRepo"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/v1/admin/deliveries": {
      "get": {
        "operationId": "listDeliveries",
        "summary": "List recent webhook deliveries",
        "tags": [
          "admin"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Deliveries, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "cursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "cursor"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "meta"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/v1/admin/audit": {
      "get": {
        "operationId": "listRepoAudit",
        "summary": "List operator changes to repo relay config",
        "tags": [
          "admin"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "required": false,
            "name": "limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Audit records, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RepoAuditRecord"
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "cursor": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "cursor"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "meta"
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {}
}
