feat(admin): Complete tenant management and module access control system

Major Features:
- Tenant management CRUD (list, create, edit, delete, module configuration)
- Dynamic module management system (modules table with 8 modules)
- Multi-tenant module permission merging (ModuleService)
- Module access control middleware (requireModule)
- User module permission API (GET /api/v1/auth/me/modules)
- Frontend module permission filtering (HomePage + TopNavigation)

Module Integration:
- RVW module integrated with PromptService (editorial + methodology)
- All modules (RVW/PKB/ASL/DC) added authenticate + requireModule middleware
- Fixed ReviewTask foreign key constraint (cross-schema issue)
- Removed all MOCK_USER_ID, unified to request.user?.userId

Prompt Management Enhancements:
- Module names displayed in Chinese (RVW -> 智能审稿)
- Enhanced version history with view content and rollback features
- List page shows both activeVersion and draftVersion columns

Database Changes:
- Added platform_schema.modules table
- Modified tenant_modules table (added index and UUID)
- Removed ReviewTask foreign key to public.users (cross-schema fix)
- Seeded 8 modules: RVW, PKB, ASL, DC, IIT, AIA, SSA, ST

Documentation Updates:
- Updated ADMIN module development status
- Updated TODO checklist (89% progress)
- Updated Prompt management plan (Phase 3.5.5 completed)
- Added module authentication specification

Files Changed: 80+
Status: All features tested and verified locally
Next: User management module development
This commit is contained in:
2026-01-13 07:34:30 +08:00
parent 5523ef36ea
commit d595037316
51 changed files with 3550 additions and 287 deletions

View File

@@ -10,21 +10,22 @@ import {
retryFailed,
getTemplates,
} from '../controllers/batchController.js';
import { authenticate, requireModule } from '../../../common/auth/auth.middleware.js';
export default async function batchRoutes(fastify: FastifyInstance) {
// 执行批处理任务
fastify.post('/batch/execute', executeBatch);
fastify.post('/batch/execute', { preHandler: [authenticate, requireModule('PKB')] }, executeBatch);
// 获取任务状态
fastify.get('/batch/tasks/:taskId', getTask);
fastify.get('/batch/tasks/:taskId', { preHandler: [authenticate, requireModule('PKB')] }, getTask);
// 获取任务结果
fastify.get('/batch/tasks/:taskId/results', getTaskResults);
fastify.get('/batch/tasks/:taskId/results', { preHandler: [authenticate, requireModule('PKB')] }, getTaskResults);
// 重试失败的文档
fastify.post('/batch/tasks/:taskId/retry-failed', retryFailed);
fastify.post('/batch/tasks/:taskId/retry-failed', { preHandler: [authenticate, requireModule('PKB')] }, retryFailed);
// 获取所有预设模板
// 获取所有预设模板公开API不需要认证
fastify.get('/batch/templates', getTemplates);
}

View File

@@ -49,3 +49,5 @@ export default async function healthRoutes(fastify: FastifyInstance) {

View File

@@ -1,53 +1,54 @@
import type { FastifyInstance } from 'fastify';
import * as knowledgeBaseController from '../controllers/knowledgeBaseController.js';
import * as documentController from '../controllers/documentController.js';
import { authenticate, requireModule } from '../../../common/auth/auth.middleware.js';
export default async function knowledgeBaseRoutes(fastify: FastifyInstance) {
// ==================== 知识库管理 API ====================
// 创建知识库
fastify.post('/knowledge-bases', knowledgeBaseController.createKnowledgeBase);
fastify.post('/knowledge-bases', { preHandler: [authenticate, requireModule('PKB')] }, knowledgeBaseController.createKnowledgeBase);
// 获取知识库列表
fastify.get('/knowledge-bases', knowledgeBaseController.getKnowledgeBases);
fastify.get('/knowledge-bases', { preHandler: [authenticate, requireModule('PKB')] }, knowledgeBaseController.getKnowledgeBases);
// 获取知识库详情
fastify.get('/knowledge-bases/:id', knowledgeBaseController.getKnowledgeBaseById);
fastify.get('/knowledge-bases/:id', { preHandler: [authenticate, requireModule('PKB')] }, knowledgeBaseController.getKnowledgeBaseById);
// 更新知识库
fastify.put('/knowledge-bases/:id', knowledgeBaseController.updateKnowledgeBase);
fastify.put('/knowledge-bases/:id', { preHandler: [authenticate, requireModule('PKB')] }, knowledgeBaseController.updateKnowledgeBase);
// 删除知识库
fastify.delete('/knowledge-bases/:id', knowledgeBaseController.deleteKnowledgeBase);
fastify.delete('/knowledge-bases/:id', { preHandler: [authenticate, requireModule('PKB')] }, knowledgeBaseController.deleteKnowledgeBase);
// 检索知识库
fastify.get('/knowledge-bases/:id/search', knowledgeBaseController.searchKnowledgeBase);
fastify.get('/knowledge-bases/:id/search', { preHandler: [authenticate, requireModule('PKB')] }, knowledgeBaseController.searchKnowledgeBase);
// 获取知识库统计信息
fastify.get('/knowledge-bases/:id/stats', knowledgeBaseController.getKnowledgeBaseStats);
fastify.get('/knowledge-bases/:id/stats', { preHandler: [authenticate, requireModule('PKB')] }, knowledgeBaseController.getKnowledgeBaseStats);
// Phase 2: 获取文档选择(全文阅读模式)
fastify.get('/knowledge-bases/:id/document-selection', knowledgeBaseController.getDocumentSelection);
fastify.get('/knowledge-bases/:id/document-selection', { preHandler: [authenticate, requireModule('PKB')] }, knowledgeBaseController.getDocumentSelection);
// ==================== 文档管理 API ====================
// 上传文档
fastify.post('/knowledge-bases/:kbId/documents', documentController.uploadDocument);
fastify.post('/knowledge-bases/:kbId/documents', { preHandler: [authenticate, requireModule('PKB')] }, documentController.uploadDocument);
// 获取文档列表
fastify.get('/knowledge-bases/:kbId/documents', documentController.getDocuments);
fastify.get('/knowledge-bases/:kbId/documents', { preHandler: [authenticate, requireModule('PKB')] }, documentController.getDocuments);
// 获取文档详情
fastify.get('/documents/:id', documentController.getDocumentById);
fastify.get('/documents/:id', { preHandler: [authenticate, requireModule('PKB')] }, documentController.getDocumentById);
// Phase 2: 获取文档全文
fastify.get('/documents/:id/full-text', documentController.getDocumentFullText);
fastify.get('/documents/:id/full-text', { preHandler: [authenticate, requireModule('PKB')] }, documentController.getDocumentFullText);
// 删除文档
fastify.delete('/documents/:id', documentController.deleteDocument);
fastify.delete('/documents/:id', { preHandler: [authenticate, requireModule('PKB')] }, documentController.deleteDocument);
// 重新处理文档
fastify.post('/documents/:id/reprocess', documentController.reprocessDocument);
fastify.post('/documents/:id/reprocess', { preHandler: [authenticate, requireModule('PKB')] }, documentController.reprocessDocument);
}