"""战略基座 — 战略章程(使命 / 愿景 / 价值观) 任务:`project-20261021-cma-strategy-charter-p0-fullstack`(P0 战略基座) 依据:《2026-10-21 CMA 知识库 M0 与系统实现差距报告》§四 P0 —— 知识卡 `CMA-P1-B-009 愿景、使命与价值观`:使命=为何存在;愿景=要成为什么 (**带年份与可验证状态**);价值观=不可交易的底线,是决策冲突时的裁决依据。 单一事实源:每个账套(entity_id)**一条**章程行,唯一键 uq_strategy_charter_entity。 本模块只做「表结构 + 契约常量」;读写端点见 app/api/charter.py。 字段语义(派单表:语义不可减,类型可调整): mission 使命 TEXT NOT NULL vision 愿景 TEXT NOT NULL vision_year 愿景达成年份 VARCHAR(20) NOT NULL(**不可空**;4 位年份) vision_measurable 可验证状态 TEXT NOT NULL(**不可空**;用可核对的规模/业务口径描述) values_text 价值观总述 TEXT NOT NULL value_items 价值观条目 JSON NOT NULL `[{name, meaning}]` —— 每条须能作"决策冲突时的裁决依据" 隔离:`entity_id NOT NULL` + 唯一键以 entity_id 打头(多租户隔离 + 索引可用性)。 禁止示例数据:本模块与迁移脚本**零 INSERT**;GET 无行返回 `filled=false` 空态。 """ from sqlalchemy import Column, Integer, String, Text, JSON, DateTime, UniqueConstraint, func from app.database import Base # 愿景年度格式:4 位年份(不臆造业务上限;允许字符串以兼容前端输入) VISION_YEAR_RE = r"^\d{4}$" # 长文本上限(与列宽一致,避免 MySQL 截断静默丢字) MISSION_MAX_LEN = 1000 VISION_MAX_LEN = 1000 VISION_MEASURABLE_MAX_LEN = 1000 VALUES_TEXT_MAX_LEN = 2000 VALUE_ITEM_NAME_MAX_LEN = 50 VALUE_ITEM_MEANING_MAX_LEN = 300 VALUE_ITEMS_MAX = 20 class StrategyCharter(Base): """战略章程 — 使命/愿景(年度+可验证状态)/价值观(每账套一行)""" __tablename__ = "strategy_charter" id = Column(Integer, primary_key=True) entity_id = Column(Integer, nullable=False, comment="企业ID(账套,多租户隔离;唯一键已建索引)") mission = Column(Text, nullable=False, comment="使命:我们为何存在(做什么、为谁做)") vision = Column(Text, nullable=False, comment="愿景:要成为什么") vision_year = Column(String(20), nullable=False, comment="愿景达成年份 YYYY(不可空)") vision_measurable = Column( Text, nullable=False, comment="可验证状态:用可核对的规模/业务口径描述(不可空)", ) values_text = Column(Text, nullable=False, comment="价值观总述(不可交易的底线)") value_items = Column( JSON, nullable=False, comment="价值观条目数组 [{name, meaning}],每条可作决策冲突时的裁决依据", ) updated_by = Column(Integer, nullable=True, comment="最后修改人 user.id") updated_by_name = Column(String(50), nullable=True, comment="最后修改人姓名(快照)") created_at = Column(DateTime, server_default=func.now()) updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now()) __table_args__ = ( UniqueConstraint("entity_id", name="uq_strategy_charter_entity"), )