Initial commit of Descrybe v2 without local scratch artifacts.

Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
2026-08-09 22:47:43 +02:00
commit 8580c996c3
1285 changed files with 325780 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
# 03 — KB / FAQ auto-reply (agent 3/10)
## Goal
Platform knowledge base + reply templates with a **sync lexical matcher** that can post a labeled `author_role=system` first response when confidence clears the threshold. No LLM on this path (agent 4 owns `TryAutoReplyLLM`).
## Schema
Migration: `apps/api/sql/schema/032_support_kb_auto_reply.sql`
| Table | Purpose |
|-------|---------|
| `support_kb_articles` | Published FAQ articles (`slug`, `title`, `body_md`, `keywords`, `intent_keys`, `category_slugs`, `priority_weight`) |
| `support_reply_templates` | Canned replies with same match fields; placeholders allowlist: `{{subject}}`, `{{category}}` |
| `support_auto_config` | Singleton: `enabled`, `faq_enabled`, `match_confidence_threshold` (default **0.78**), `retry_on_first_customer_reply` |
Ticket/message auto columns (`auto_reply_*`, `is_auto_reply`, …) come from **`031_support_ticket_detail.sql`** (agent 5). Do not re-ALTER them here.
## Service API
Package: `apps/api/internal/support`
| Symbol | Role |
|--------|------|
| `MatchAutoReply(ctx, ticket) → MatchAutoReplyResult` | Scores corpus; `{matched, confidence, reply_body, article_id, template_id, kind}` — never posts, never LLM |
| `PostMatchedAutoReply` | Posts system message when `confidence >= threshold`; sets status `pending`, `auto_reply_status=matched`; notifies `auto_reply` |
| `MaybeAutoReplyOnCreate` | Stage A after create (respects config) |
| `MaybeAutoReplyOnCustomerReply` | Optional retry when `retry_on_first_customer_reply`; handoff if prior public auto exists |
| KB / template CRUD | `Create/Update/Delete/List/Get` for articles + templates |
| `GetAutoConfig` / `UpdateAutoConfig` | FAQ switchboard |
Matching: keyword overlap (0.70) + intent phrase (0.15) + category boost (0.15) + small priority weight. Secrets redacted before score (`RedactSecretsForMatch`). Corpus cached ~60s; invalidated on admin writes.
## HTTP (platform admin)
Mounted under `RequirePlatformAdmin`:
| Method | Path |
|--------|------|
| GET/POST | `/api/admin/support/kb/articles` |
| GET/PATCH/DELETE | `/api/admin/support/kb/articles/{id}` |
| GET/POST | `/api/admin/support/templates` |
| GET/PATCH/DELETE | `/api/admin/support/templates/{id}` |
| GET/PUT | `/api/admin/support/auto-config` |
Customer create (`POST /api/support/tickets`) calls `MaybeAutoReplyOnCreate` after successful create. Customer reply calls `MaybeAutoReplyOnCustomerReply` (no-op unless retry flag).
## Defaults / ops
- Master `enabled=false` until admin turns FAQ auto on.
- Enable + publish articles/templates + set threshold → create a ticket whose subject/body hits keywords → expect system message with footer “Automated answer from help center”.
- Below threshold → `auto_reply_status=skipped` (agent 4 may enqueue AI).
## Tests
- Unit: `apps/api/internal/support/match_auto_reply_test.go` (scoring, redaction, placeholders, footer).
- Auth probes include KB/template/auto-config paths in `support_auth_test.go`.
## Coordination
- Agent 4: on match miss / low confidence → `TryAutoReplyLLM` async; reuse message auto_* columns.
- Agent 5: ticket detail fields + activity; FAQ posts `ActivityAutoReply` via `insertActivity`.
- Agent 6: admin UI for KB + auto-config.
- Agent 10: migrate `032_*`, end-to-end verify.