Knowledge Base

This page is a complete solution guide. Using the open-source doc-knowledge plugin (com.auraboot.doc-knowledge, namespace dk) as the example, it goes from the user scenario all the way through how it becomes a knowledge source for Aura Bot, the implementation, and the common mistakes. It is a config plugin — its 5 models, 18 commands, 15 pages, and 1 dashboard are all declared in DSL JSON, with no backend Java. Every identifier below can be grepped in plugins/doc-knowledge/config/ and called against a running instance.

This plugin depends on com.auraboot.template.project-management (the project management template) — documents can be linked to projects, so import the project management plugin first.


1. User Scenario

A manufacturer wants to consolidate drawings, specifications, reports, meeting minutes, and contracts scattered across shared drives and email, and to build up a searchable set of knowledge articles. Day to day:

  • An engineer creates a document (draft) → fills in title, type, owning project, access level, body → publishes it so everyone can see it;
  • When a document needs changes it is revised back to draft, edited, then republished; obsolete documents are archived, removed from the active list but still queryable;
  • Each significant change leaves a version record with a change summary and content snapshot, so history can be compared later;
  • Documents are organised under a category tree (product docs / policies / training material / troubleshooting);
  • Documents are scoped by access level (public / internal / confidential / restricted);
  • Documents can be linked to projects, so a project view can trace its specifications, design docs, and compliance certificates;
  • A separate set of knowledge articles — shorter and more topic-focused than documents — follows the same draft → published → archived editorial lifecycle.

A document manager, a document editor, and a document viewer each see and can do different things.

2. Pain Points

  • No lifecycle: files on a shared drive have no "draft / published / archived" state, so nobody knows which copy is final and which is still in progress.
  • Broken version chains: overwrite uploads clobber the old version, so you cannot trace "what changed in the previous revision, and who changed it".
  • No authorization or audit: who published, who archived, and when — none of it is recorded; publishing relies on word of mouth.
  • Access control by vigilance: confidential drawings sit in public folders, guarded only by naming conventions, which is unreliable.
  • Disconnected from projects: project-relevant documents are scattered, so a project cannot show all of its specs and compliance material in one click.

None of this is solved by "make another folder" — it is a problem of controlled state changes plus structured relationships.

3. The Product Approach

In AuraBoot every document action is a command that runs through the unified command pipeline:

  • The "Publish" button calls dk:publish_document, not a raw PUT /api/dk_document; the command runs authorization → state-machine validation → execution → audit → event publication in one pipeline.
  • The document lifecycle is guarded by the state field dk_doc_status plus three state_transition commands (dk:publish_document / dk:archive_document / dk:revise_document); illegal transitions (for example, archiving a draft directly) are rejected by the state machine.
  • Version history is a real model, dk_doc_version, attached to the document via parentModel: dk_document and shown as an inline sub-table on the document detail page — it inherits list, detail, search, export, and audit, sharing the same machinery as every other business entity, with no separate "version management console".
  • The same command is both the target of a UI button and callable from automation rules or BPM review flows — for example "auto-archive documents untouched for 18 months" sends dk:archive_document directly, with no manual second step.

4. Functional Design

4.1 Data Models (5)

ModelTypePurposeKey states
dk_documententityThe primary document entity; carries body, abstract, tags, type, version label, owning category/project, and access leveldk_doc_status: draft / published / archived
dk_doc_categorymasterDocument category tree (self-referencing parent dk_cat_parent_id) for logical groupingno state machine
dk_doc_versionentityDocument version record; parentModel: dk_document, parentField: dk_ver_document_id; carries change summary and content snapshotfollows parent document
dk_knowledge_articleentityKnowledge article; editorial content shorter and more topic-focused than a documentdk_article_status: draft / published / archived
dk_project_documentreferenceMany-to-many bridge linking documents and projectsno state machine

Key document fields (config/fields.json): dk_doc_title (title), dk_doc_type (type, enum), dk_doc_project_id / dk_doc_category_id (reference), dk_doc_abstract / dk_doc_content (text body), dk_doc_access_level (access level, enum), dk_doc_author / dk_doc_owner_id (auto-filled from current_username on create).

4.2 Commands and State Machine

18 commands, named dk:<verb>_<noun> (colon separator, not dots). By type:

TypeCommands
create (5)dk:create_document · dk:create_category · dk:create_version · dk:create_article · dk:link_document
update (3)dk:update_document · dk:update_category · dk:update_article
delete (5)dk:delete_document · dk:delete_category · dk:delete_version · dk:delete_article · dk:unlink_document
state_transition (5)dk:publish_document · dk:archive_document · dk:revise_document · dk:publish_article · dk:archive_article

The document state machine: dk:publish_document (draft → published) → dk:revise_document (published → draft, to re-edit) → dk:archive_document (published → archived). Knowledge articles work the same way.

Each command is a declaration. For example, the real definition of dk:publish_document (config/commands.json):

{
  "code": "dk:publish_document",
  "displayName:zh-CN": "发布文档",
  "displayName:en": "Publish Document",
  "description": "Publish a draft document",
  "type": "state_transition",
  "modelCode": "dk_document",
  "stateField": "dk_doc_status",
  "fromStates": ["draft"],
  "toState": "published",
  "permissions": ["dk.document.publish"],
  "extension": {
    "confirmMessage:zh-CN": "确认发布此文档?",
    "confirmMessage:en": "Confirm publish this document?"
  }
}

What the definition tells you: this is a state_transition that can only go from draft to published (fromStates contains nothing else, so publishing an already-published or archived document is rejected); it requires the dk.document.publish permission (note this is separate from dk.document.manage — being able to edit does not mean being able to publish); and it shows a confirmation dialog on click. create commands (for example dk:create_document) carry inputFields listing the fillable fields and autoSetFields declaring that dk_doc_no is auto-generated as DOC-{yyyyMMdd}-{seq}, dk_doc_status is fixed to draft, and the author is taken from current_username.

4.3 Permissions and Roles

9 permission codes, named dk.<resource>.<action> (dot separator — note that permission codes use dots while command codes use colons; they are different):

dk.document.manage     dk.document.read     dk.document.publish
dk.category.manage     dk.version.manage
dk.article.manage      dk.article.read      dk.article.publish
dk.link.manage

manage covers create/update/delete/archive; publish is split out separately (publishing is a higher privilege); read is a data-type permission (resourceType: data) used for data visibility on list and detail pages.

3 roles (config/roles.json):

  • dk_manager (Document Manager) — all 9 permissions, including publish;
  • dk_editor (Document Editor) — can create/update, manage versions and links, but does not have dk.document.publish / dk.article.publish;
  • dk_viewer (Document Viewer) — only dk.document.read + dk.article.read.

4.4 Pages

15 DSL pages (config/pages.json): list / form / detail for each of the 5 models. Plus 1 dashboard (config/dashboards/dk_dashboard.json) fed by 6 named queries (dk_dashboard_kpi / dk_docs_by_type / dk_docs_by_status / dk_articles_by_status / dk_recent_documents / dk_recent_articles). The menu (config/menus.json) is mounted under /doc-knowledge: dashboard, documents, categories, versions, articles, project documents.

4.5 As a Knowledge Source for Aura Bot

This plugin is plain document/knowledge-base CRUD; it has no built-in vector retrieval or RAG pipeline — it declares no embedding model, no answer-trace model, and no retrieval-scoring logic of its own. Its place in the AI layer is this: published documents and knowledge articles are a knowledge source that Aura Bot can answer over.

The connection is a capability the platform Agent System provides by default — not extra code in this plugin:

  • Read tools are generated automatically: the DSL Tool Provider attaches list:<modelCode> and get:<modelCode> read tools to every model, and named queries become nq:<queryCode>. Put list:dk_knowledge_article / get:dk_document / nq:dk_recent_documents in an agent's tools allowlist and it can query the knowledge base during a turn to answer a user's question.
  • Permissions are the retrieval boundary: the agent runs as the calling user (see Aura Bot § Permissions). A document the user lacks dk.document.read on is invisible to the agent too; dk_doc_access_level (public / internal / confidential / restricted) combined with ABAC policy narrows visibility further. In other words, the bot never reads content the caller cannot read.
  • Write commands are exposed to agents on demand: these commands carry no agent_hint / cmd_risk_level by default, which means they are not offered to an agent for automatic execution. To let an agent draft an article or initiate an archive, add agent_hint (when to use it) and cmd_risk_level (use L2+ for publish/archive so they route through the Approval Gate) to the relevant command so a human confirms first — see Agent Builder for the contract.

So: documents and knowledge live here, while retrieval, permissions, audit, and exposure policy all reuse the platform's single mechanism. It is not a second "AI knowledge console" — it lets AI speak through the existing models, commands, and permissions.

5. Implementation

Get the basics first. This plugin has no backend Java; it relies entirely on a few core platform contracts. Before you start, read: Models and Fields · Commands · Command Pipeline · Permissions · Plugin Manifest · Config-only Plugins · Page Designer.

To land a config plugin like doc-knowledge, the steps are:

  1. Write the manifestplugin.json declares pluginId / namespace (dk) / pluginType: config / dependencies (this plugin depends on the project management template), and registers every config file in resourceDirs (models / commands / permissions / modelFieldBindings …). See Plugin Manifest.
  2. Define models and fieldsconfig/models.json (5 models; the version model declares its parent-child link with parentModel + parentField) plus config/fields.json, with platform dataType values (string / enum / reference / text …). See Models and Fields.
  3. Declare commandsconfig/commands.json; state transitions use type: state_transition + fromStates / toState, CRUD uses create / update / delete, and each binds permission codes in permissions. See Commands.
  4. Configure model-field bindingsconfig/bindings.json, registered under resourceDirs.modelFieldBindings (see "Common Mistakes").
  5. Permissions, roles, dicts, menus, pagesconfig/permissions.json / roles.json / dicts.json / menus.json / pages.json / dashboards/.
  6. Package and import — use the aura CLI's import-directory-sync (the parameter is a directory path) or the platform import API; a success:true response means the import succeeded. Make sure the project-management dependency is imported first.

6. Common Configuration

  • Document lifecycle: the state field dk_doc_status (dict dk_doc_status: draft / published / archived) is guarded by three state_transition commands; to support "unpublish and re-edit", wire dk:revise_document (published → draft).
  • Access level: the field dk_doc_access_level picks from dict dk_access_level (public / internal / confidential / restricted), combined with ABAC policy to control document visibility.
  • Category tree: dk_doc_category uses dk_cat_parent_id self-reference to form a multi-level tree; documents attach to a category via dk_doc_category_id (reference).
  • Version snapshots: on each significant change call dk:create_version to write a dk_doc_version row carrying dk_ver_change_summary (change summary) and dk_ver_content_snapshot (content snapshot); versions appear as a sub-table on the document detail page.
  • Project links: dk:link_document writes a dk_project_document bridge row to attach a document to a project; dk:unlink_document detaches it.
  • Auto-archive: configure an automation rule that sends dk:archive_document for long-untouched published documents, with no manual step.

7. Common Mistakes

  • Dot-notation command codes: dk.document.publish will not run — command codes are colon plus verb_noun: dk:publish_document. Permission codes are the ones that use dots: dk.document.publish. Same name, different separator — don't mix them up.
  • Mutating the document table directly instead of going through a command: a direct UPDATE of dk_document state skips state-machine validation, handlers, and audit/event publication. Every document change goes through a command.
  • Publishing an already-archived document: dk:publish_document's fromStates only contains draft, so calling it on a published/archived document is rejected by the state machine — that is by design, not a bug.
  • Treating edit permission as publish permission: dk.document.manage does not include dk.document.publish (the dk_editor role has no publish right); to let a role publish, grant dk.document.publish separately.
  • Missing dependency on import: this plugin's dependencies declares com.auraboot.template.project-management — import it before this plugin, otherwise the project references in dk_doc_project_id / dk_project_document cannot resolve.
  • Inline bindingRules inside commands.json: they are not imported; use a separate bindings.json registered under resourceDirs.modelFieldBindings, otherwise you get [S-EXT-HANDLER] references unregistered handler. See Config-only Plugins.
  • Command execution payload shape: fields go in { "payload": { ... }, "operationType": ... }, and the target record uses targetRecordId (not recordId) — misplacing them produces the confusing "executed successfully but fields are empty" error.

Next steps

  • System overview — how plugins, commands, and the runtime fit together
  • Command pipeline — the execution contract every command above runs through
  • Permissions — the layered model behind the three roles above
  • Plugin manifest — how a plugin declares dependencies and resource directories