Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
820 lines
19 KiB
JSON
820 lines
19 KiB
JSON
[
|
|
{
|
|
"id": "F001",
|
|
"description": "Migration: Add entity_id and entity_type columns to document_folders table (includes inline distributeIfCitus)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.1"
|
|
]
|
|
},
|
|
{
|
|
"id": "F002",
|
|
"description": "Migration: Replace unique constraint on document_folders to include entity scope (COALESCE-based)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.2"
|
|
]
|
|
},
|
|
{
|
|
"id": "F003",
|
|
"description": "Migration: Add is_client_visible boolean column to documents table (default false)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.3"
|
|
]
|
|
},
|
|
{
|
|
"id": "F004",
|
|
"description": "Migration: Add is_client_visible boolean column to document_folders table (default false)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.3"
|
|
]
|
|
},
|
|
{
|
|
"id": "F005",
|
|
"description": "Migration: Add RLS tenant isolation policies to document_folders (SELECT and INSERT)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.11"
|
|
]
|
|
},
|
|
{
|
|
"id": "F006",
|
|
"description": "Migration: Add partial index on documents (tenant, is_client_visible) WHERE is_client_visible = true",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.3"
|
|
]
|
|
},
|
|
{
|
|
"id": "F007",
|
|
"description": "Type: Add is_client_visible to IDocument interface",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.3"
|
|
]
|
|
},
|
|
{
|
|
"id": "F008",
|
|
"description": "Type: Add entity_id, entity_type, is_client_visible to IDocumentFolder and IFolderNode interfaces",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.1"
|
|
]
|
|
},
|
|
{
|
|
"id": "F009",
|
|
"description": "Action: getFolderTree() accepts optional entityId/entityType params and filters accordingly",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.4"
|
|
]
|
|
},
|
|
{
|
|
"id": "F010",
|
|
"description": "Action: getFolderTree() returns only global folders (entity_id IS NULL) when no entity params provided",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.4"
|
|
]
|
|
},
|
|
{
|
|
"id": "F011",
|
|
"description": "Action: getDocumentsByFolder() respects entity scope parameters",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.5"
|
|
]
|
|
},
|
|
{
|
|
"id": "F012",
|
|
"description": "Action: createFolder() accepts entityId, entityType, isClientVisible parameters",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.6"
|
|
]
|
|
},
|
|
{
|
|
"id": "F013",
|
|
"description": "Action: toggleDocumentVisibility(documentIds, isClientVisible) bulk-toggles visibility",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.7"
|
|
]
|
|
},
|
|
{
|
|
"id": "F014",
|
|
"description": "Action: toggleFolderVisibility(folderId, isClientVisible, cascade?) toggles folder and optionally cascades to documents",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.8"
|
|
]
|
|
},
|
|
{
|
|
"id": "F015",
|
|
"description": "Action: ensureEntityFolders(entityId, entityType) stub that returns empty tree",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.12"
|
|
]
|
|
},
|
|
{
|
|
"id": "F016",
|
|
"description": "UI: Documents component in entity mode shows FolderTreeView sidebar",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.9"
|
|
]
|
|
},
|
|
{
|
|
"id": "F017",
|
|
"description": "UI: FolderTreeView accepts optional entityId/entityType props",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.9"
|
|
]
|
|
},
|
|
{
|
|
"id": "F018",
|
|
"description": "UI: VisibilityToggle component with eye/eye-off icon",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.10"
|
|
]
|
|
},
|
|
{
|
|
"id": "F019",
|
|
"description": "UI: Visibility badge and toggle shown on DocumentListView rows (MSP context only)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.10"
|
|
]
|
|
},
|
|
{
|
|
"id": "F020",
|
|
"description": "UI: Visibility badge and toggle shown on DocumentCard (MSP context only)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.10"
|
|
]
|
|
},
|
|
{
|
|
"id": "F021",
|
|
"description": "UI: Visibility indicator shown on FolderTreeView folders",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-1.10"
|
|
]
|
|
},
|
|
{
|
|
"id": "F023",
|
|
"description": "Migration: Create document_folder_templates table with tenant, name, entity_type, is_default (includes inline distributeIfCitus)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.1"
|
|
]
|
|
},
|
|
{
|
|
"id": "F024",
|
|
"description": "Migration: Create document_folder_template_items table with folder tree structure (includes inline distributeIfCitus)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.2"
|
|
]
|
|
},
|
|
{
|
|
"id": "F025",
|
|
"description": "Migration: Create document_entity_folder_init tracker table (includes inline distributeIfCitus)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.3"
|
|
]
|
|
},
|
|
{
|
|
"id": "F026",
|
|
"description": "Migration: Partial unique index (tenant, entity_type) WHERE is_default = true on templates",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.4"
|
|
]
|
|
},
|
|
{
|
|
"id": "F027",
|
|
"description": "Migration: RLS policies on all Phase 2 tables",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"NFR-1"
|
|
]
|
|
},
|
|
{
|
|
"id": "F028",
|
|
"description": "Action: getFolderTemplates(entityType?) returns filtered template list",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.5"
|
|
]
|
|
},
|
|
{
|
|
"id": "F029",
|
|
"description": "Action: getFolderTemplate(templateId) returns template with items",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.5"
|
|
]
|
|
},
|
|
{
|
|
"id": "F030",
|
|
"description": "Action: createFolderTemplate(data) creates template and items",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.5"
|
|
]
|
|
},
|
|
{
|
|
"id": "F031",
|
|
"description": "Action: updateFolderTemplate(templateId, data) updates template and items",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.5"
|
|
]
|
|
},
|
|
{
|
|
"id": "F032",
|
|
"description": "Action: deleteFolderTemplate(templateId) deletes template (cascades to items)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.5"
|
|
]
|
|
},
|
|
{
|
|
"id": "F033",
|
|
"description": "Action: setDefaultTemplate(templateId) marks as default, unsets previous default for same entity type",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.4"
|
|
]
|
|
},
|
|
{
|
|
"id": "F034",
|
|
"description": "Action: applyTemplateToEntity(templateId, entityId, entityType) creates entity-scoped folders from template",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.6"
|
|
]
|
|
},
|
|
{
|
|
"id": "F035",
|
|
"description": "Action: ensureEntityFolders() checks init tracker and applies default template if uninitialized",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.6"
|
|
]
|
|
},
|
|
{
|
|
"id": "F036",
|
|
"description": "Action: ensureEntityFolders() is idempotent — skips existing folders on re-run",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.7"
|
|
]
|
|
},
|
|
{
|
|
"id": "F037",
|
|
"description": "Action: uploadDocument() auto-files into matching entity folder (best-effort, never fails upload)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.8"
|
|
]
|
|
},
|
|
{
|
|
"id": "F038",
|
|
"description": "UI: FolderTemplateList component showing templates by entity type with default badge",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.5"
|
|
]
|
|
},
|
|
{
|
|
"id": "F039",
|
|
"description": "UI: FolderTemplateEditor component with drag-and-drop reorder, add/remove, visibility toggles",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.9"
|
|
]
|
|
},
|
|
{
|
|
"id": "F040",
|
|
"description": "UI: Admin settings page/section for Document Templates",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.5"
|
|
]
|
|
},
|
|
{
|
|
"id": "F041",
|
|
"description": "UI: Documents entity mode calls ensureEntityFolders() on mount",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-2.10"
|
|
]
|
|
},
|
|
{
|
|
"id": "F043",
|
|
"description": "Action: getClientDocuments(page, limit, filters) returns paginated client-visible docs for authenticated client",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-3.3",
|
|
"FR-3.4"
|
|
]
|
|
},
|
|
{
|
|
"id": "F044",
|
|
"description": "Action: getClientDocumentFolders() returns folder tree of client-visible folders",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-3.5"
|
|
]
|
|
},
|
|
{
|
|
"id": "F045",
|
|
"description": "Action: downloadClientDocument(documentId) verifies visibility and client ownership",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-3.8"
|
|
]
|
|
},
|
|
{
|
|
"id": "F046",
|
|
"description": "Action: All client-documents actions wrapped in withAuth() enforcing user_type === 'client'",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-3.7"
|
|
]
|
|
},
|
|
{
|
|
"id": "F047",
|
|
"description": "API: File view route extended to check is_client_visible for client users",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-3.9"
|
|
]
|
|
},
|
|
{
|
|
"id": "F048",
|
|
"description": "API: File view route extended to support contract-associated document access",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-3.9"
|
|
]
|
|
},
|
|
{
|
|
"id": "F049",
|
|
"description": "UI: New client portal documents page at /client-portal/documents",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-3.1"
|
|
]
|
|
},
|
|
{
|
|
"id": "F050",
|
|
"description": "UI: 'Documents' nav link added to ClientPortalLayout between Projects and Appointments",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-3.2"
|
|
]
|
|
},
|
|
{
|
|
"id": "F051",
|
|
"description": "UI: ClientDocumentsPage component with folder tree sidebar and document grid/list",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-3.6"
|
|
]
|
|
},
|
|
{
|
|
"id": "F052",
|
|
"description": "UI: ClientFolderTree component (read-only folder tree for portal)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-3.6"
|
|
]
|
|
},
|
|
{
|
|
"id": "F053",
|
|
"description": "UI: ClientDocumentCard component (view/download only, no edit/delete)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-3.6"
|
|
]
|
|
},
|
|
{
|
|
"id": "F054",
|
|
"description": "UI: ClientDocumentFilters component (search, source type, date range)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-3.6"
|
|
]
|
|
},
|
|
{
|
|
"id": "F055",
|
|
"description": "Regression: Existing inline ticket document display continues unchanged",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-3.10"
|
|
]
|
|
},
|
|
{
|
|
"id": "F056",
|
|
"description": "Migration: Create document_share_links table with token, type, password_hash, expiry, limits, revocation (includes inline distributeIfCitus)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.1"
|
|
]
|
|
},
|
|
{
|
|
"id": "F057",
|
|
"description": "Migration: Create document_share_access_log table (includes inline distributeIfCitus)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.2"
|
|
]
|
|
},
|
|
{
|
|
"id": "F058",
|
|
"description": "Migration: RLS policies on Phase 4 tables",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"NFR-1"
|
|
]
|
|
},
|
|
{
|
|
"id": "F059",
|
|
"description": "Action: createShareLink(input) generates 256-bit token, hashes password if provided, inserts record",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.3",
|
|
"FR-4.4"
|
|
]
|
|
},
|
|
{
|
|
"id": "F060",
|
|
"description": "Action: getShareLinksForDocument(documentId) returns active (non-revoked) links",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.11"
|
|
]
|
|
},
|
|
{
|
|
"id": "F061",
|
|
"description": "Action: revokeShareLink(shareId) soft-revokes link",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.13"
|
|
]
|
|
},
|
|
{
|
|
"id": "F062",
|
|
"description": "Action: validateShareToken(token) uses admin connection, validates expiry/revocation/download limits",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.6",
|
|
"NFR-4"
|
|
]
|
|
},
|
|
{
|
|
"id": "F063",
|
|
"description": "API: GET /api/share/[token] serves file for valid public shares without session",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.6"
|
|
]
|
|
},
|
|
{
|
|
"id": "F064",
|
|
"description": "API: GET /api/share/[token] verifies password for password-protected shares",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.7"
|
|
]
|
|
},
|
|
{
|
|
"id": "F065",
|
|
"description": "API: GET /api/share/[token] verifies portal session for portal-authenticated shares",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.8"
|
|
]
|
|
},
|
|
{
|
|
"id": "F066",
|
|
"description": "API: GET /api/share/[token] logs access and increments download_count",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.12"
|
|
]
|
|
},
|
|
{
|
|
"id": "F067",
|
|
"description": "API: GET /api/share/[token]/info returns document metadata without download",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.9"
|
|
]
|
|
},
|
|
{
|
|
"id": "F068",
|
|
"description": "API: Share routes enforce expiry and max_downloads limits",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.5"
|
|
]
|
|
},
|
|
{
|
|
"id": "F069",
|
|
"description": "UI: Public share landing page at /share/[token] with download button and minimal layout",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.10"
|
|
]
|
|
},
|
|
{
|
|
"id": "F070",
|
|
"description": "UI: Share landing page shows password input for password-protected links",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.10"
|
|
]
|
|
},
|
|
{
|
|
"id": "F071",
|
|
"description": "UI: ShareLinkDialog component with share type selector, password input, expiry picker, max downloads",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.11"
|
|
]
|
|
},
|
|
{
|
|
"id": "F072",
|
|
"description": "UI: ShareLinkDialog lists existing share links with copy URL and revoke actions",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.11"
|
|
]
|
|
},
|
|
{
|
|
"id": "F073",
|
|
"description": "UI: 'Share' option added to document context menu in DocumentListView and DocumentCard",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.11"
|
|
]
|
|
},
|
|
{
|
|
"id": "F074",
|
|
"description": "UI: Share indicator icon shown on documents that have active share links",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-4.11"
|
|
]
|
|
},
|
|
{
|
|
"id": "F076",
|
|
"description": "Migration: Create kb_articles table extending documents with article_type, audience, status, review fields, slug (includes inline distributeIfCitus)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.1",
|
|
"FR-5.2",
|
|
"FR-5.3",
|
|
"FR-5.4"
|
|
]
|
|
},
|
|
{
|
|
"id": "F077",
|
|
"description": "Migration: Create kb_article_relations table (related/prerequisite/supersedes) (includes inline distributeIfCitus)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.9"
|
|
]
|
|
},
|
|
{
|
|
"id": "F078",
|
|
"description": "Migration: Create kb_article_templates table with BlockNote JSON template data (includes inline distributeIfCitus)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.10"
|
|
]
|
|
},
|
|
{
|
|
"id": "F079",
|
|
"description": "Migration: Create kb_article_reviewers table with review status tracking (includes inline distributeIfCitus)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.8"
|
|
]
|
|
},
|
|
{
|
|
"id": "F080",
|
|
"description": "Migration: RLS policies on all Phase 5 tables",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"NFR-1"
|
|
]
|
|
},
|
|
{
|
|
"id": "F081",
|
|
"description": "Action: createArticle(data) creates both document and kb_articles record in transaction",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.1"
|
|
]
|
|
},
|
|
{
|
|
"id": "F082",
|
|
"description": "Action: updateArticle(articleId, data) updates KB metadata",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.1"
|
|
]
|
|
},
|
|
{
|
|
"id": "F083",
|
|
"description": "Action: publishArticle(articleId) sets status=published and auto-sets is_client_visible for client/public audience",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.4",
|
|
"FR-5.5"
|
|
]
|
|
},
|
|
{
|
|
"id": "F084",
|
|
"description": "Action: archiveArticle(articleId) sets status=archived and clears is_client_visible",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.4",
|
|
"FR-5.6"
|
|
]
|
|
},
|
|
{
|
|
"id": "F085",
|
|
"description": "Action: submitForReview(articleId, reviewerUserIds) creates reviewer assignments",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.8"
|
|
]
|
|
},
|
|
{
|
|
"id": "F086",
|
|
"description": "Action: completeReview(articleId, status, notes) records reviewer decision",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.8"
|
|
]
|
|
},
|
|
{
|
|
"id": "F087",
|
|
"description": "Action: getArticles(filters) returns paginated articles with audience/status/type/category filters",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.11"
|
|
]
|
|
},
|
|
{
|
|
"id": "F088",
|
|
"description": "Action: getArticle(articleId) returns full article with document content",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.11"
|
|
]
|
|
},
|
|
{
|
|
"id": "F089",
|
|
"description": "Action: getStaleArticles() returns articles past next_review_due",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.7"
|
|
]
|
|
},
|
|
{
|
|
"id": "F090",
|
|
"description": "Action: recordArticleView(articleId) increments view_count",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.15"
|
|
]
|
|
},
|
|
{
|
|
"id": "F091",
|
|
"description": "Action: recordArticleFeedback(articleId, helpful) increments helpful_count or not_helpful_count",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.15"
|
|
]
|
|
},
|
|
{
|
|
"id": "F092",
|
|
"description": "Action: getArticleTemplates() returns KB article templates",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.10"
|
|
]
|
|
},
|
|
{
|
|
"id": "F093",
|
|
"description": "Action: createArticleFromTicket(ticketId) pre-populates article from ticket resolution data",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.14"
|
|
]
|
|
},
|
|
{
|
|
"id": "F094",
|
|
"description": "UI: KBArticleList component with filterable article list (status, audience, type, category)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.11"
|
|
]
|
|
},
|
|
{
|
|
"id": "F095",
|
|
"description": "UI: KBArticleEditor component wrapping DocumentEditor with KB metadata sidebar",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.11"
|
|
]
|
|
},
|
|
{
|
|
"id": "F096",
|
|
"description": "UI: KBPublishingControls component for status transitions (Draft/Review/Published/Archived)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.4"
|
|
]
|
|
},
|
|
{
|
|
"id": "F097",
|
|
"description": "UI: KBReviewDashboard component showing articles awaiting review and overdue reviews",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.7",
|
|
"FR-5.8"
|
|
]
|
|
},
|
|
{
|
|
"id": "F098",
|
|
"description": "UI: KBCategoryTree component for category navigation (reuses standard_categories)",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.11"
|
|
]
|
|
},
|
|
{
|
|
"id": "F099",
|
|
"description": "UI: Staleness badge shown on articles past review due date",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.7"
|
|
]
|
|
},
|
|
{
|
|
"id": "F100",
|
|
"description": "UI: ClientKBPage component for client portal KB browsing with search and categories",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.12"
|
|
]
|
|
},
|
|
{
|
|
"id": "F101",
|
|
"description": "UI: ClientKBArticleView component with read-only rendering and 'Was this helpful?' feedback",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.12"
|
|
]
|
|
},
|
|
{
|
|
"id": "F102",
|
|
"description": "UI: KB section added to MSP navigation",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.11"
|
|
]
|
|
},
|
|
{
|
|
"id": "F103",
|
|
"description": "UI: Knowledge Base tab/section added to client portal Documents hub",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.12"
|
|
]
|
|
},
|
|
{
|
|
"id": "F104",
|
|
"description": "Integration: Articles can be tagged via existing tag system with tagged_type = 'knowledge_base_article'",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"FR-5.13"
|
|
]
|
|
}
|
|
]
|