ITSM

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

FieldTypeRequiredDefaultDescription
numberstringoptionalHuman-readable identifier, e.g. "KB-0042". Auto-generated.
titlestringrequiredArticle title.
slugstringrequiredURL slug, unique per tenant. Looked up via GET /api/knowledge/slug/:slug.
categorystringrequiredCategory label. The values "Known Error", "KEDB" and "known-error" are also matched by the KEDB endpoint (see isKEDB below).
knowledgeBaseIdObjectIdoptionalOptional grouping into a specific knowledge base.
knowledgeBaseTitlestringoptional"General Knowledge"Denormalized display name of the knowledge base.
excerptstringoptional""Short summary shown in listings.
bodystringoptional""Full article content.
tagsstring[]optional[]Free-form tags.
isPublishedbooleanoptionalfalseThe default (unfiltered) list request only returns isPublished: true articles — pass allStates=true, manage=true, or an explicit isPublished/state filter to see the rest.
stateenumoptional"draft""draft" · "review" · "in_review" · "approved" · "published" · "retired" · "rejected". The broad lifecycle field — see Article Lifecycle below.
reviewStatusenumoptional"draft"A second, narrower field tracking the approval workflow specifically — see Approval Workflow below.
confidentialityLevelenumoptional"internal""public" · "internal" · "restricted"
isKEDBbooleanoptionalfalseMarks this as a Known Error DB article, surfaced by GET /api/knowledge/kedb.
workaroundStepsstringoptionalWorkaround text for a known-error article.
authorId / authorNameObjectId / stringoptionalSet from the creating user. authorName defaults to "System".
ownerId / ownerNameObjectId / stringoptionalDefaults to ownerName "IT Knowledge Team".
contributorsstring[]optional[]Additional contributor identifiers.
versionintegeroptional1Current version number — see Version History below.
relatedIncidentIdsObjectId[]optional[]Incidents this article is linked to.
linkedProblemIdObjectIdoptionalProblem this article documents a workaround for.
incidentsResolvedUsingnumberoptional0Counter for incidents resolved with this article’s help.
views / viewCountnumberoptional0Two separate view counters, both present on the schema.
deflectionCountnumberoptional0Incremented by POST /:id/deflect (viewed the article instead of filing a ticket).
helpful / notHelpfulnumberoptional0Feedback tallies from POST /:id/feedback and /:id/rate.
publishedAtDateoptionalSet by POST /:id/publish.
expiresAtDateoptionalIndexed; read by the background knowledge-expiry worker.
attachmentsobject[]optional[]{ filename, url, size, mimeType, uploadedAt }[]
feedbackobject[]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:

FieldTypeRequiredDefaultDescription
POST /:id/publishactionoptionalSets state: "published", reviewStatus: "approved", isPublished: true, publishedAt: now.
POST /:id/retireactionoptionalSets state: "retired", reviewStatus: "retired", isPublished: false.
POST /:id/archiveactionoptionalSame effect as retire — sets state and reviewStatus to "retired".
There is no scheduled job that auto-transitions an article when 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.

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.

bash
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
}
The plain 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.

FieldTypeRequiredDefaultDescription
versionintegerrequiredSequential version number for this snapshot.
contenttextoptional""Snapshot of the article's body at the time this version was recorded.
titlestringoptional""Snapshot of the article title at the time this version was recorded.
editedBystring (usr_...)optionalnullUser who made this edit.
editedAttimestampoptionalnowWhen this version was recorded.
changeNotestringoptionalnullOptional note describing the change, e.g. "Restored from version 3".
GET
/api/knowledge/:id/versions

List version history, newest first

GET
/api/knowledge/:id/versions/:versionId

Get a specific version's content

POST
/api/knowledge/:id/versions/:versionId/restore

Restore 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: draftin_reviewapproved | rejectedpublished / retired.

FieldTypeRequiredDefaultDescription
reviewStatusenumrequireddraftdraft · in_review · approved · rejected · published · retired. Tracks the approval workflow independently of the lifecycle state.
reviewedBystring (usr_...)optionalnullUser who approved or rejected the article.
reviewNotestringoptionalnullReviewer note, typically populated on rejection.
submittedForReviewAttimestampoptionalnullSet when the article is submitted for review.
approvedAttimestampoptionalnullSet when the article is approved.
POST
/api/knowledge/:id/submit-for-review

Move the article to reviewStatus=in_review and notify KB approvers/managers

POST
/api/knowledge/:id/approve

Approve the article (reviewStatus=approved), publish it, and notify the author

POST
/api/knowledge/:id/reject

Reject the article (reviewStatus=rejected) with an optional reviewNote, and notify the author

Reviewer notification
Submitting an article for review creates an in-app notification (linking back to the article) for every user holding a KB manager/approver role — 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.

FieldTypeRequiredDefaultDescription
articleIdstring (kb_...)requiredThe article this comment belongs to.
authorIdstring (usr_...)requiredUser who posted the comment.
bodystringrequiredComment text.
createdAttimestampoptionalautoCreation timestamp.
GET
/api/knowledge/:id/comments

List comments on an article, oldest first

POST
/api/knowledge/:id/comments

Add a comment (body is required)

DELETE
/api/knowledge/:id/comments/:commentId

Delete a comment — only the comment's own author may delete it (403 otherwise)

API Quick Reference

GET
/api/knowledge

List articles

POST
/api/knowledge

Create an article

GET
/api/knowledge/:id

Get article with full content

PATCH
/api/knowledge/:id

Update article

DELETE
/api/knowledge/:id

Delete article

POST
/api/knowledge/:id/publish

Publish article

POST
/api/knowledge/:id/retire

Retire article

POST
/api/knowledge/:id/archive

Archive article (sets state and reviewStatus to retired)

POST
/api/knowledge/:id/feedback

Submit helpful/not helpful feedback with an optional comment

POST
/api/knowledge/:id/rate

Public: rate an article helpful/not helpful

POST
/api/knowledge/:id/view

Public: track an article view

POST
/api/knowledge/:id/deflect

Public: track a deflection (viewed article, did not file a ticket)

GET
/api/knowledge/:id/versions

List version history

POST
/api/knowledge/:id/submit-for-review

Submit for approval review

POST
/api/knowledge/:id/approve

Approve and publish

POST
/api/knowledge/:id/reject

Reject with a review note

GET
/api/knowledge/:id/comments

List comments

POST
/api/knowledge/:id/comments

Add a comment

GET
/api/knowledge/analytics

Knowledge deflection analytics

GET
/api/knowledge/kedb

List Known Error DB articles (isKEDB or KEDB/known-error category)

GET
/api/knowledge/gap-analysis

Resolved incidents with no matching published KB article, grouped by category

POST
/api/knowledge/from-incident

Create a draft article from an incident