Knowledge Base
Article fields, states, versioning, access control, semantic search, and portal surfacing for the Knowledge Base module.
Overview
The FlowOS Knowledge Base stores how-to guides, troubleshooting articles, known error workarounds, and process documentation. Articles appear in the self-service portal, are surfaced by the virtual agent, and are linked from ITSM records. Full-text and semantic vector search power the search experience.
Article Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| number | string | optional | — | Human-readable identifier, e.g. "KB-0042". Auto-generated. |
| title | string | required | — | Article title. |
| slug | string | required | — | URL slug, unique per tenant. Looked up via GET /api/knowledge/slug/:slug. |
| category | string | required | — | Category label. The values "Known Error", "KEDB" and "known-error" are also matched by the KEDB endpoint (see isKEDB below). |
| knowledgeBaseId | ObjectId | optional | — | Optional grouping into a specific knowledge base. |
| knowledgeBaseTitle | string | optional | "General Knowledge" | Denormalized display name of the knowledge base. |
| excerpt | string | optional | "" | Short summary shown in listings. |
| body | string | optional | "" | Full article content. |
| tags | string[] | optional | [] | Free-form tags. |
| isPublished | boolean | optional | false | The default (unfiltered) list request only returns isPublished: true articles — pass allStates=true, manage=true, or an explicit isPublished/state filter to see the rest. |
| state | enum | optional | "draft" | "draft" · "review" · "in_review" · "approved" · "published" · "retired" · "rejected". The broad lifecycle field — see Article Lifecycle below. |
| reviewStatus | enum | optional | "draft" | A second, narrower field tracking the approval workflow specifically — see Approval Workflow below. |
| confidentialityLevel | enum | optional | "internal" | "public" · "internal" · "restricted" |
| isKEDB | boolean | optional | false | Marks this as a Known Error DB article, surfaced by GET /api/knowledge/kedb. |
| workaroundSteps | string | optional | — | Workaround text for a known-error article. |
| authorId / authorName | ObjectId / string | optional | — | Set from the creating user. authorName defaults to "System". |
| ownerId / ownerName | ObjectId / string | optional | — | Defaults to ownerName "IT Knowledge Team". |
| contributors | string[] | optional | [] | Additional contributor identifiers. |
| version | integer | optional | 1 | Current version number — see Version History below. |
| relatedIncidentIds | ObjectId[] | optional | [] | Incidents this article is linked to. |
| linkedProblemId | ObjectId | optional | — | Problem this article documents a workaround for. |
| incidentsResolvedUsing | number | optional | 0 | Counter for incidents resolved with this article’s help. |
| views / viewCount | number | optional | 0 | Two separate view counters, both present on the schema. |
| deflectionCount | number | optional | 0 | Incremented by POST /:id/deflect (viewed the article instead of filing a ticket). |
| helpful / notHelpful | number | optional | 0 | Feedback tallies from POST /:id/feedback and /:id/rate. |
| publishedAt | Date | optional | — | Set by POST /:id/publish. |
| expiresAt | Date | optional | — | Indexed; read by the background knowledge-expiry worker. |
| attachments | object[] | optional | [] | { filename, url, size, mimeType, uploadedAt }[] |
| feedback | object[] | optional | [] | { userId?, userName?, helpful, comment?, createdAt }[] — one entry per feedback/rate submission. |
Article Lifecycle
Articles carry two lifecycle-shaped fields on the same document: the broad state field (draft · review · in_review · approved · published · retired · rejected) and the narrower reviewStatus field used by the Approval Workflow actions below. The two lifecycle actions on this page set both together:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| POST /:id/publish | action | optional | — | Sets state: "published", reviewStatus: "approved", isPublished: true, publishedAt: now. |
| POST /:id/retire | action | optional | — | Sets state: "retired", reviewStatus: "retired", isPublished: false. |
| POST /:id/archive | action | optional | — | Same effect as retire — sets state and reviewStatus to "retired". |
expiresAt passes — the field is indexed and read by the knowledge-expiry worker, which is a notification/flagging pass rather than an automatic state change.Search & Listing
There is no dedicated semantic or full-text search endpoint. Search is a query parameter on the regular list endpoint: GET /api/knowledge?q=... (aliases: search, $search) runs a case-insensitive regex match across number, title, excerpt, body, tags and category — not a ranked BM25 or vector-similarity search. Combine it with any of the filters below.
GET /api/knowledge?q=vpn+password&category=Networking&isKEDB=false&tag=remote-access&knowledgeBaseId=665f...
// Response
{
"articles": [
{
"_id": "665f1a2b3c4d5e6f7a8b9c0d",
"number": "KB-0042",
"title": "Reset VPN Credentials (GlobalProtect & OpenVPN)",
"excerpt": "Steps to reset your VPN password and re-authenticate...",
"category": "Networking",
"tags": ["vpn", "remote-access"],
"isPublished": true,
"state": "published"
}
],
"records": [ /* same array */ ],
"total": 1
}GET /api/knowledge list (no explicit state, allStates, manage or isPublished query param) implicitly filters to isPublished: true — pass manage=true from an authenticated admin view to see drafts and unpublished articles too.Version History
Every article stores its own revision history inline, as a versions[] array on the article document — there is no separate versions collection. A new entry is appended (and the article's version counter incremented) whenever content is saved through updateArticleWithVersion, such as when restoring a prior revision.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| version | integer | required | Sequential version number for this snapshot. | |
| content | text | optional | "" | Snapshot of the article's body at the time this version was recorded. |
| title | string | optional | "" | Snapshot of the article title at the time this version was recorded. |
| editedBy | string (usr_...) | optional | null | User who made this edit. |
| editedAt | timestamp | optional | now | When this version was recorded. |
| changeNote | string | optional | null | Optional note describing the change, e.g. "Restored from version 3". |
/api/knowledge/:id/versionsList version history, newest first
/api/knowledge/:id/versions/:versionIdGet a specific version's content
/api/knowledge/:id/versions/:versionId/restoreRestore the article's title/body from a prior version, recording a new version entry with the note 'Restored from version :versionId'
Approval Workflow
Articles carry a dedicated reviewStatus field, separate from the broader lifecycle state field, to track approval specifically: draft → in_review → approved | rejected → published / retired.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| reviewStatus | enum | required | draft | draft · in_review · approved · rejected · published · retired. Tracks the approval workflow independently of the lifecycle state. |
| reviewedBy | string (usr_...) | optional | null | User who approved or rejected the article. |
| reviewNote | string | optional | null | Reviewer note, typically populated on rejection. |
| submittedForReviewAt | timestamp | optional | null | Set when the article is submitted for review. |
| approvedAt | timestamp | optional | null | Set when the article is approved. |
/api/knowledge/:id/submit-for-reviewMove the article to reviewStatus=in_review and notify KB approvers/managers
/api/knowledge/:id/approveApprove the article (reviewStatus=approved), publish it, and notify the author
/api/knowledge/:id/rejectReject the article (reviewStatus=rejected) with an optional reviewNote, and notify the author
kb_approver, knowledge_manager, kb_manager, knowledge_admin, itil_admin, or admin. Approving or rejecting likewise notifies the article's author.Comments
Articles support a lightweight discussion thread, stored as a separate KbComment collection (root_kb_comments) keyed by articleId.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| articleId | string (kb_...) | required | The article this comment belongs to. | |
| authorId | string (usr_...) | required | User who posted the comment. | |
| body | string | required | Comment text. | |
| createdAt | timestamp | optional | auto | Creation timestamp. |
/api/knowledge/:id/commentsList comments on an article, oldest first
/api/knowledge/:id/commentsAdd a comment (body is required)
/api/knowledge/:id/comments/:commentIdDelete a comment — only the comment's own author may delete it (403 otherwise)
API Quick Reference
/api/knowledgeList articles
/api/knowledgeCreate an article
/api/knowledge/:idGet article with full content
/api/knowledge/:idUpdate article
/api/knowledge/:idDelete article
/api/knowledge/:id/publishPublish article
/api/knowledge/:id/retireRetire article
/api/knowledge/:id/archiveArchive article (sets state and reviewStatus to retired)
/api/knowledge/:id/feedbackSubmit helpful/not helpful feedback with an optional comment
/api/knowledge/:id/ratePublic: rate an article helpful/not helpful
/api/knowledge/:id/viewPublic: track an article view
/api/knowledge/:id/deflectPublic: track a deflection (viewed article, did not file a ticket)
/api/knowledge/:id/versionsList version history
/api/knowledge/:id/submit-for-reviewSubmit for approval review
/api/knowledge/:id/approveApprove and publish
/api/knowledge/:id/rejectReject with a review note
/api/knowledge/:id/commentsList comments
/api/knowledge/:id/commentsAdd a comment
/api/knowledge/analyticsKnowledge deflection analytics
/api/knowledge/kedbList Known Error DB articles (isKEDB or KEDB/known-error category)
/api/knowledge/gap-analysisResolved incidents with no matching published KB article, grouped by category
/api/knowledge/from-incidentCreate a draft article from an incident