Install and enable
Activating FAQ & Knowledge Base — the extension is named knowledge_base, the four tables it creates, twelve permission keys, the single KYC gate, the optional DeepSeek key, and where the menus actually appear.
Activation is a single screen and there is nothing to configure afterwards. The work is in knowing what to look for once it is on, because the label on the menu and the identifier in every error message are different words.
Before you activate
- Bicrypto core installed and running — see Installing Bicrypto
- Your CodeCanyon username and the purchase code for item
39166202 - Outbound HTTPS from the server, for licence validation
- Optional: a DeepSeek API key, if you want the AI authoring helpers
That is the whole list. This addon has no other addon as a prerequisite, needs no ScyllaDB, adds no cron job and opens no WebSocket.
Activation
-
Open Admin → System → Extensions — the screen is at
/admin/system/extension. -
Find "Knowledge Base & FAQs" — that is the row title. It is not listed as "FAQ".
-
Activate — enter your CodeCanyon username and purchase code. The platform verifies with CodeCanyon before enabling anything.
-
Confirm both surfaces — Knowledge Base appears under Extensions → Business Tools in the admin navigation and points at
/admin/faq. The reader area answers at/faq.
The licence gate is keyed to route prefixes, and for knowledge_base those are
/api/faq and /api/admin/faq. Both the admin screens and the reader-facing
help centre run through it — including the endpoints that need no login at all.
If the licence lapses, /faq stops returning articles for anonymous visitors, not
just for you. The failure is a 403 whose body names the extension as
knowledge_base and the product as 39166202. Neither of those strings appears
anywhere in the admin menu, which is why this looks like an unrelated fault the
first time it happens.
What activation creates
Four tables:
| Table | Holds |
|---|---|
faqs |
The articles. Soft-deleted (paranoid), so filter deletedAt if you query directly |
faq_feedbacks |
One helpful/unhelpful vote per reader per article, with an optional comment |
faq_questions |
Reader-submitted questions — PENDING, ANSWERED or REJECTED |
faq_searches |
One row per recorded search, with the result count it returned |
faqs carries indexes on category, pagePath, order and status — the four
columns every list in the product filters or sorts on.
Two columns are DataTypes.JSON: tags and relatedFaqIds. That is a native
JSON column on MySQL and LONGTEXT on MariaDB, so the driver hands back an array
on one and a raw string on the other. The model normalises both to an array before
anything reads them. If you query the tables directly, you must handle either
shape yourself — this is the single most common cause of a working integration
that breaks when moved between MySQL and MariaDB.
If you deploy with DB_SYNC=none, run the backend once with sync enabled so the
tables and indexes land. If you build from source, run pnpm types:generate.
Permissions
Twelve keys ship with the platform seeder. Assign them at /admin/crm/role.
| Key | Grants |
|---|---|
access.faq |
The Knowledge Base dashboard, the Manage screen and the AI screen |
view.faq |
Reading the admin article list, one article, the page list and per-page counts |
create.faq |
Creating an article — and every AI helper |
edit.faq |
Editing, bulk updates, reordering, and per-page enable/disable |
delete.faq |
Deleting an article, a selection, or every article on a page |
view.faq.category |
The category list — and the tag list |
access.faq.question |
The Questions screen |
view.faq.question |
Reading the submitted-question queue |
edit.faq.question |
Answering a question and changing its status |
access.faq.feedback |
The Feedback screen |
view.faq.feedback |
Reading feedback, both the global list and one article's |
create.faq.feedback |
Writing a feedback row through the admin API |
Two of those pairings are not what the names suggest, and both bite.
All six AI endpoints gate on create.faq, not on a permission of their own. Every
one of them forwards text to a metered third-party model that you are billed for.
Granting an author create.faq so they can add articles also grants them the
ability to spend your DeepSeek balance, in a loop, from the batch-improve screen.
If that matters, keep create.faq on a small set of roles.
The tag list is served under view.faq.category, not a tag key. A role that can
filter by category can filter by tag; there is no way to separate them.
The screens themselves gate on access.*: the dashboard, Manage and AI screens on
access.faq, Questions on access.faq.question, Feedback on
access.faq.feedback. A role with view.faq but no access.faq can call the API
and cannot open the page.
The one KYC gate
It appears in the KYC level builder as Knowledge Base Inquiries, in the Support category, with a recommended level of 1.
It gates exactly one thing: POST /api/faq/question. Reading articles, searching,
browsing categories and viewing statistics are all open to anonymous visitors and
have no gate at all. Voting on an article requires a signed-in account but no KYC
feature.
So the practical effect of leaving ask_faq off is that the Ask a Question form
is present, the reader fills it in, and submission is refused. If you do not want
questions, that is the switch — but consider that the submitted-question queue is
where the dashboard's most actionable figure comes from.
Rate limits
Two limiters, both enforced in Redis, both fixed in code:
| Action | Limit |
|---|---|
| Feedback vote | 20 per hour |
| Question submission | 5 per 24 hours |
Neither is configurable. If Redis is unavailable, so are these two endpoints.
The optional DeepSeek key
The AI helpers are the only part of this addon that needs anything in .env:
DEEPSEEK_API_KEY="sk-…"Leave it unset and the addon works completely — you simply write your own
articles. The AI buttons remain visible; pressing one returns 500 with
DeepSeek API key is not set, and a line is written to the backend log at boot.
There is no screen anywhere that tells you the key is missing before you press a
button.
The key is shared platform-wide, not scoped to this addon. Read AI-assisted authoring before you hand it out — that page covers what each helper sends, including the one that puts your entire published library into a single prompt.
Where everything is
The admin area is four screens plus one that is not in the menu.
| Screen | Path | Gate |
|---|---|---|
| Knowledge Base (dashboard) | /admin/faq |
access.faq |
| Manage | /admin/faq/manage |
access.faq |
| Questions | /admin/faq/question |
access.faq.question |
| Feedback | /admin/faq/feedback |
access.faq.feedback |
| AI batch improve | /admin/faq/ai |
access.faq |
/admin/faq/ai is reachable only from the AI Improve button in the header of
the Manage screen. It is a real, permission-gated page; it is simply absent from
the menu, so it cannot be found by browsing.
The reader area is three screens: the help centre at /faq, an article at
/faq/{id}, and a guided Troubleshooter at /faq/troubleshooter.
Submitted questions also surface in the platform-wide operations queue as User
Questions, counting PENDING rows, under the access.faq.question permission.
That is often the first place anyone notices a backlog.
Smoke test
-
Create an article —
/admin/faq/manage, Add FAQ. A question of at least 10 characters, an answer of at least 20, a category, and a page path. Save. -
Read it as a visitor — sign out and open
/faq. The article should appear. Open it; the view counter should move. -
Unpublish it — turn its status off in the admin list, then reload the article URL while signed out. It must return not found, not the article. Turn it back on.
-
Search for a word that is not in it — from
/faq. Then check/admin/faq— the query should appear under the search figures with no results. That proves search recording is working, which is the single most valuable thing this addon produces. -
Submit a question — as a signed-in reader who passes
ask_faq. It should appear on/admin/faq/questionas pending. -
Answer it — the asker receives an email, and an in-app notification if their address belongs to an account.
If step 4 shows nothing, see Troubleshooting; if step 6 sends no email, the fault is in your mail configuration, not here — the answer is saved either way and the failure is written to the backend log.