"/admin/kb/query":
    post:
        tags: [Knowledge Base]
        operationId: kbQuery
        summary: Run a natural-language query
        description: Runs a natural-language query against the knowledge base and returns the model's answer plus citations.
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [query]
                        properties:
                            query: { type: string, description: Natural-language question. }
                            options:
                                type: object
                                properties:
                                    limit: { type: integer, default: 10 }
                                    sourceTypes:
                                        type: array
                                        items: { type: string }
                                        description: Restrict retrieval to these source types.
                                    includeContext:
                                        type: boolean
                                        description: When true, sources include a short `excerpt`.
        responses:
            "200":
                description: Query result.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/KBQueryResult.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [KBUser, Admin]
        x-scopes: ["kb:write", "admin:all"]

"/admin/kb/search":
    post:
        tags: [Knowledge Base]
        operationId: kbSearch
        summary: Search the knowledge base
        description: Returns documents matching the supplied search query — vector + keyword search with the LLM step skipped.
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [query]
                        properties:
                            query: { type: string }
                            options:
                                type: object
                                properties:
                                    limit: { type: integer, default: 10 }
                                    sourceTypes:
                                        type: array
                                        items: { type: string }
                                    useReranking:
                                        type: boolean
                                        default: true
                                        description: When false, skip the Cohere re-rank step.
        responses:
            "200":
                description: Search results.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/KBSearchResult.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [KBUser, Admin]
        x-scopes: ["kb:write", "admin:all"]

"/admin/kb/ingest/document":
    post:
        tags: [Knowledge Base]
        operationId: kbIngestDocument
        summary: Ingest a document
        description: Adds a document to the knowledge base.
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [sourceType, sourceId, title, content]
                        properties:
                            sourceType:
                                type: string
                                description: "Source class (e.g. `document`, `discord`, `github`)."
                            sourceId: { type: string, description: Source-specific identifier. }
                            sourceUrl: { type: string }
                            title: { type: string }
                            content: { type: string, description: Full document body to chunk and embed. }
                            contentType: { type: string, example: "text/markdown" }
                            metadata:
                                type: object
                                additionalProperties: true
                            visibility:
                                type: string
                                description: "e.g. `public`, `internal`."
                            allowedGroups:
                                type: array
                                items: { type: string }
        responses:
            "200":
                description: Ingestion result.
                content:
                    application/json:
                        schema:
                            type: object
                            required: [success]
                            properties:
                                success: { type: boolean }
                                documentId: { type: string }
                                chunkCount:
                                    type: integer
                                    description: Number of chunks the document was split into.
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [KBAdmin, Admin]
        x-scopes: ["kb:write", "admin:all"]

"/admin/kb/ingest/discord":
    post:
        tags: [Knowledge Base]
        operationId: kbIngestDiscord
        summary: Ingest Discord messages
        description: |
            Pulls and ingests messages from configured Discord channels. **Note:**
            currently disabled (returns `501 Not Implemented`) pending a discord.js
            compatibility fix.
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            channels:
                                type: array
                                items: { type: string }
                                description: When set, restrict ingestion to these channel ids.
        responses:
            "200":
                description: Ingestion result (when re-enabled).
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                success: { type: boolean }
                                channelsSynced: { type: integer }
                                messagesSynced: { type: integer }
            "501":
                description: Discord integration is temporarily disabled.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [KBAdmin, Admin]
        x-scopes: ["kb:write", "admin:all"]

"/admin/kb/ingest/github":
    post:
        tags: [Knowledge Base]
        operationId: kbIngestGitHub
        summary: Ingest GitHub content
        description: Ingests issues, PRs, commits, README/wiki content from configured GitHub repositories.
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            repos:
                                type: array
                                description: When set, override the env-configured repo list.
                                items:
                                    type: object
                                    properties:
                                        owner: { type: string }
                                        repo: { type: string }
                                        includeIssues: { type: boolean }
                                        includePullRequests: { type: boolean }
                                        includeCommits: { type: boolean }
                                        includeWiki: { type: boolean }
                                    additionalProperties: true
        responses:
            "200":
                description: Ingestion result.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/KBIngestionResult.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [KBAdmin, Admin]
        x-scopes: ["kb:write", "admin:all"]

"/admin/kb/ingest/github/cleanup-commits":
    post:
        tags: [Knowledge Base]
        operationId: kbCleanupGitHubCommits
        summary: Clean up ingested GitHub commits
        description: Deletes previously-ingested GitHub commit documents that no longer match the configured ingestion filters.
        responses:
            "200":
                description: Cleanup result.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/KBIngestionResult.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [KBAdmin, Admin]
        x-scopes: ["kb:write", "admin:all"]

"/admin/kb/sync":
    get:
        tags: [Knowledge Base]
        operationId: kbSync
        summary: Sync the knowledge base
        description: Triggers a sync that reconciles the KB with its upstream sources.
        responses:
            "200":
                description: Sync result.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/KBIngestionResult.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [FabricatorReadOnly, Admin]
        x-scopes: ["kb:read", "admin:all"]

"/admin/kb/document/{sourceType}/{sourceId}":
    parameters:
        - in: path
          name: sourceType
          required: true
          schema: { type: string }
          description: Source type identifier (e.g. `discord`, `github`, `document`).
        - in: path
          name: sourceId
          required: true
          schema: { type: string }
          description: Source-specific identifier for the document.
    delete:
        tags: [Knowledge Base]
        operationId: kbDeleteDocumentBySource
        summary: Delete a document by source
        description: Removes the document identified by the supplied source type + source id from the KB.
        responses:
            "200":
                description: Delete result.
                content:
                    application/json:
                        schema:
                            type: object
                            required: [success]
                            properties:
                                success: { type: boolean }
                                documentsDeleted: { type: integer }
                                chunksDeleted: { type: integer }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: No document for the supplied source.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [KBAdmin, Admin]
        x-scopes: ["kb:write", "admin:all"]

"/admin/kb/documents":
    get:
        tags: [Knowledge Base]
        operationId: kbGetDocuments
        summary: List KB documents
        description: Returns documents currently in the knowledge base, with optional source-type filter and pagination.
        parameters:
            - in: query
              name: sourceType
              schema: { type: string }
              description: Optional filter — restrict to one source type.
            - in: query
              name: limit
              schema: { type: integer, default: 50 }
            - in: query
              name: offset
              schema: { type: integer, default: 0 }
        responses:
            "200":
                description: Documents listing.
                content:
                    application/json:
                        schema:
                            type: object
                            required: [documents, pagination]
                            properties:
                                documents:
                                    type: array
                                    items: { $ref: "../components/schemas/KBDocument.yaml" }
                                pagination:
                                    type: object
                                    properties:
                                        limit: { type: integer }
                                        offset: { type: integer }
                                        total: { type: integer }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [KBAdmin, Admin]
        x-scopes: ["kb:read", "admin:all"]

"/admin/kb/document/{documentId}":
    parameters:
        - in: path
          name: documentId
          required: true
          schema: { type: string }
    get:
        tags: [Knowledge Base]
        operationId: kbGetDocument
        summary: Fetch one KB document
        description: Returns a specific document by id, plus its individual chunk metadata.
        responses:
            "200":
                description: Document record with embedded chunk index.
                content:
                    application/json:
                        schema:
                            type: object
                            required: [document, chunks]
                            properties:
                                document: { $ref: "../components/schemas/KBDocument.yaml" }
                                chunks:
                                    type: array
                                    items:
                                        type: object
                                        properties:
                                            id: { type: string }
                                            chunk_index: { type: integer }
                                            content_tokens: { type: integer }
                                            start_char: { type: integer }
                                            end_char: { type: integer }
                                            created_at: { type: string, format: date-time }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
            "404":
                description: No document with this id.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
        x-access-policies: [KBAdmin, Admin]
        x-scopes: ["kb:read", "admin:all"]

"/admin/kb/clear":
    post:
        tags: [Knowledge Base]
        operationId: kbClear
        summary: Clear all KB documents
        description: |
            Hard-deletes every document in the knowledge base. Optional `sourceType`
            in the body filters the deletion. **Destructive** — `confirm` must be the
            literal string `DELETE_ALL_DOCUMENTS`. Restricted to `Admin`.
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [confirm]
                        properties:
                            confirm:
                                type: string
                                enum: [DELETE_ALL_DOCUMENTS]
                                description: Must be the literal string `DELETE_ALL_DOCUMENTS`.
                            sourceType:
                                type: string
                                description: When set, restrict deletion to one source type.
        responses:
            "200":
                description: KB cleared.
                content:
                    application/json:
                        schema:
                            type: object
                            required: [success, documentsDeleted, chunksDeleted, sourceType]
                            properties:
                                success: { type: boolean }
                                documentsDeleted: { type: integer }
                                chunksDeleted: { type: integer }
                                sourceType:
                                    type: string
                                    description: '`"all"` or the supplied filter.'
            "400":
                description: Confirmation missing or wrong.
                content:
                    application/json:
                        schema: { $ref: "../admin-api.yaml#/components/schemas/Error" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [Admin]
        x-scopes: ["kb:write", "admin:all"]

"/admin/kb/stats":
    get:
        tags: [Knowledge Base]
        operationId: kbStats
        summary: KB statistics
        description: Returns aggregate statistics about the knowledge base (document counts, ingestion timestamps, etc.).
        responses:
            "200":
                description: Stats payload.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/KBStats.yaml" }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [KBAdmin, Admin]
        x-scopes: ["kb:read", "admin:all"]

"/admin/kb/logs":
    get:
        tags: [Knowledge Base]
        operationId: kbLogs
        summary: Query logs
        description: Returns query log entries — what users have asked, when, and how it was answered.
        parameters:
            - in: query
              name: limit
              schema: { type: integer, default: 50 }
            - in: query
              name: offset
              schema: { type: integer, default: 0 }
        responses:
            "200":
                description: Query log entries.
                content:
                    application/json:
                        schema:
                            type: object
                            required: [logs, pagination]
                            properties:
                                logs:
                                    type: array
                                    items: { $ref: "../components/schemas/KBQueryLog.yaml" }
                                pagination:
                                    type: object
                                    properties:
                                        limit: { type: integer }
                                        offset: { type: integer }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [KBAdmin, Admin]
        x-scopes: ["kb:read", "admin:all"]

"/admin/kb/feedback/{queryLogId}":
    parameters:
        - in: path
          name: queryLogId
          required: true
          schema: { type: string }
          description: Query log id to attach feedback to.
    post:
        tags: [Knowledge Base]
        operationId: kbSubmitFeedback
        summary: Submit feedback on a query
        description: Submits user feedback (thumbs-up/down + comments) for a given query log entry.
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            score:
                                type: integer
                                description: "`1` = thumbs-up, `-1` = thumbs-down."
                            text:
                                type: string
                                description: Optional free-text follow-up.
        responses:
            "200":
                description: Feedback recorded.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                success: { type: boolean }
            "401": { $ref: "../admin-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../admin-api.yaml#/components/responses/Forbidden" }
        x-access-policies: [KBUser, Admin]
        x-scopes: ["kb:write", "admin:all"]
