- knowledge_events/knowledge_summaries: entity_id NOT NULL DEFAULT 1 + 索引(企业记忆抽屉) - knowledge_articles: entity_id 可空——NULL=全局共享(CMA教学知识), 有值=企业专属 - knowledge_service 全链路 entity_id: extract_events(KPIAlert直过滤+OperationLog经user_entities归属)/_kpi_snapshot(修跨企业KPI泄漏)/generate_summary/get_last_summary/run_*/sync - api/knowledge.py 8端点 Depends(get_entity_id) 强制过滤;详情越权404 - api/knowledge_articles.py 全局∪本企业查询;企业专属越权404 - 生产DB三表ALTER+索引已完成; 存量38篇教学文章保持NULL全局共享 - 测试 test_security_knowledge_partition.py 8条(双实体互查越权/生成自动带entity/全局文章双可见) - 方案文档 docs/knowledge-entity-partition-plan-20260903.md(附评审决策点)
25 lines
1.4 KiB
Python
25 lines
1.4 KiB
Python
"""管理会计OS — 知识库文章(P1-3 嵌入功能模块用)
|
||
|
||
与 KnowledgeSummary/KnowledgeEvent(AI摘要系统)不同,此表存储静态的CMA知识文章,
|
||
用于在功能模块右侧/底部嵌入展示。
|
||
"""
|
||
from sqlalchemy import Column, Integer, String, Text, DateTime, func
|
||
from app.database import Base
|
||
|
||
|
||
class KnowledgeArticle(Base):
|
||
"""知识库文章"""
|
||
__tablename__ = "knowledge_articles"
|
||
|
||
id = Column(Integer, primary_key=True, index=True)
|
||
entity_id = Column(Integer, nullable=True, index=True, comment="企业ID: NULL=全局共享(系统教学), 有值=企业专属 (多租户隔离 2026-09-03)")
|
||
title = Column(String(200), nullable=False, comment="文章标题")
|
||
summary = Column(String(500), nullable=True, comment="一句话摘要")
|
||
content = Column(Text, nullable=False, comment="文章正文(支持Markdown)")
|
||
category = Column(String(50), nullable=True, comment="分类: term/formula/practice/faq")
|
||
icon = Column(String(10), default="📖", comment="图标")
|
||
related_page = Column(String(200), nullable=True, comment="关联页面路由,如 /maps/canvas/:id, /kpis, /budget, /deviations, /predict, /maps-review")
|
||
sort_order = Column(Integer, default=0, comment="排序")
|
||
created_at = Column(DateTime, server_default=func.now())
|
||
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now())
|