feat: 职称评审核验助手首版 v1.0.1(verify-promotion-metric-default)
All checks were successful
技能自动化发布 / release (push) Successful in 7s
All checks were successful
技能自动化发布 / release (push) Successful in 7s
This commit is contained in:
169
scripts/db/connection.py
Normal file
169
scripts/db/connection.py
Normal file
@@ -0,0 +1,169 @@
|
||||
"""SQLite 连接与幂等初始化(职称评审核验助手)。
|
||||
|
||||
业务表 2 张:
|
||||
- threshold_rules(评审门槛库,可编辑)
|
||||
- verify_cases(核验案例,只读,核验自动写入)
|
||||
|
||||
表间禁止 SQLite 外键,仅存业务 id(见 references/SCHEMA.md)。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sqlite3
|
||||
|
||||
from db.display_metadata import (
|
||||
init_display_metadata,
|
||||
seed_column_metadata_batch,
|
||||
upsert_table_metadata,
|
||||
)
|
||||
from db.seed_data import seed_all
|
||||
from db.timestamp_columns import init_updated_at_trigger
|
||||
from util.runtime_paths import get_db_path
|
||||
|
||||
|
||||
def get_conn() -> sqlite3.Connection:
|
||||
return sqlite3.connect(get_db_path())
|
||||
|
||||
|
||||
_THRESHOLD_RULES_DDL = """
|
||||
CREATE TABLE IF NOT EXISTS threshold_rules (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
rank TEXT NOT NULL,
|
||||
metric_key TEXT NOT NULL,
|
||||
metric_name TEXT NOT NULL,
|
||||
min_value REAL NOT NULL,
|
||||
unit TEXT,
|
||||
basis_doc TEXT,
|
||||
clause TEXT,
|
||||
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
||||
updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
||||
UNIQUE (rank, metric_key)
|
||||
)
|
||||
"""
|
||||
|
||||
_VERIFY_CASES_DDL = """
|
||||
CREATE TABLE IF NOT EXISTS verify_cases (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
batch_no TEXT NOT NULL,
|
||||
teacher_name TEXT,
|
||||
department TEXT,
|
||||
apply_rank TEXT,
|
||||
metrics_json TEXT,
|
||||
verdict TEXT NOT NULL,
|
||||
matrix_json TEXT,
|
||||
report_file TEXT,
|
||||
created_at INTEGER NOT NULL DEFAULT (unixepoch())
|
||||
)
|
||||
"""
|
||||
|
||||
_VERIFY_CASES_INDEX = """
|
||||
CREATE INDEX IF NOT EXISTS idx_verify_cases_batch
|
||||
ON verify_cases(batch_no)
|
||||
"""
|
||||
|
||||
_TS_COLUMN_NAMES = {"created_at", "updated_at"}
|
||||
|
||||
|
||||
def _col(column_name: str, display_name: str, description: str, **extra: object) -> dict[str, object]:
|
||||
base: dict[str, object] = {
|
||||
"column_name": column_name,
|
||||
"display_name": display_name,
|
||||
"description": description,
|
||||
"visible": 1,
|
||||
"searchable": 0,
|
||||
"editable": 0,
|
||||
}
|
||||
base.update(extra)
|
||||
if column_name in _TS_COLUMN_NAMES:
|
||||
base["display_type"] = "datetime_unix_seconds"
|
||||
return base
|
||||
|
||||
|
||||
_THRESHOLD_RULES_COLUMNS: tuple[dict[str, object], ...] = (
|
||||
_col("id", "编号", "主键", searchable=1),
|
||||
_col("rank", "申报级别", "副教授 / 教授。", searchable=1),
|
||||
_col("metric_key", "指标键", "指标唯一键(presiding_provincial 等)。", searchable=1),
|
||||
_col("metric_name", "指标名称", "如 主持省部级项目。", searchable=1, editable=1),
|
||||
_col("min_value", "最低要求", "刚性门槛数值。", searchable=1, editable=1, display_type="number"),
|
||||
_col("unit", "单位", "项/篇/课时/年 等。", editable=1),
|
||||
_col("basis_doc", "依据文件", "如《专业技术职务评聘办法》。", searchable=1, editable=1),
|
||||
_col("clause", "条款", "门槛出处条款号。", editable=1),
|
||||
_col("created_at", "创建时间", "记录创建时间(Unix 秒级,自动生成)。"),
|
||||
_col("updated_at", "更新时间", "记录最后更新时间(Unix 秒级,自动维护)。"),
|
||||
)
|
||||
|
||||
_VERIFY_CASES_COLUMNS: tuple[dict[str, object], ...] = (
|
||||
_col("id", "案例编号", "主键,核验记录编号。", searchable=1),
|
||||
_col("batch_no", "核验批次号", "同一次核验请求的批次号。", searchable=1),
|
||||
_col("teacher_name", "教师姓名", "被核验教师。", searchable=1),
|
||||
_col("department", "所属学院", "教师所属学院。", searchable=1),
|
||||
_col("apply_rank", "申报级别", "副教授 / 教授。", searchable=1),
|
||||
_col("metrics_json", "申报指标", "教师实有指标(JSON,默认隐藏)。", visible=0, display_type="textarea"),
|
||||
_col(
|
||||
"verdict",
|
||||
"核验结论",
|
||||
"安全(形式审查通过)/ 边缘(建议补充)/ 硬伤(暂缓提交)。",
|
||||
searchable=1,
|
||||
options_json='[{"value":"安全","label":"🟢 安全"},{"value":"边缘","label":"🟡 边缘"},{"value":"硬伤","label":"🔴 硬伤"}]',
|
||||
),
|
||||
_col("matrix_json", "达标矩阵", "逐项达标矩阵(JSON)。", visible=0, display_type="textarea"),
|
||||
_col("report_file", "报告文件", "《核验报告》HTML 文件路径。", visible=0),
|
||||
_col("created_at", "创建时间", "记录创建时间(Unix 秒级,自动生成)。"),
|
||||
)
|
||||
|
||||
|
||||
def _init_threshold_rules_metadata(cursor) -> None:
|
||||
cursor.execute(_THRESHOLD_RULES_DDL)
|
||||
init_updated_at_trigger(cursor, "threshold_rules")
|
||||
upsert_table_metadata(
|
||||
cursor,
|
||||
table_name="threshold_rules",
|
||||
display_name="评审门槛库",
|
||||
description="各级别职称申报的刚性门槛(数值须以人事处最新文件为准)。",
|
||||
grid_help="按 申报级别+指标键 唯一;行内可编辑最低要求与依据条款。",
|
||||
visible=1,
|
||||
readonly=0,
|
||||
)
|
||||
seed_column_metadata_batch(
|
||||
cursor,
|
||||
table_name="threshold_rules",
|
||||
columns=_THRESHOLD_RULES_COLUMNS,
|
||||
valid_column_names=[str(c["column_name"]) for c in _THRESHOLD_RULES_COLUMNS],
|
||||
)
|
||||
|
||||
|
||||
def _init_verify_cases_metadata(cursor) -> None:
|
||||
cursor.execute(_VERIFY_CASES_DDL)
|
||||
cursor.execute(_VERIFY_CASES_INDEX)
|
||||
upsert_table_metadata(
|
||||
cursor,
|
||||
table_name="verify_cases",
|
||||
display_name="核验案例",
|
||||
description="每次核验的达标矩阵与三色结论;可重建《核验报告》。",
|
||||
grid_help="🔴硬伤=存在不达门槛项;🟡边缘=达标但余量不足10%;🟢安全=全部超标准10%以上。",
|
||||
visible=1,
|
||||
readonly=1,
|
||||
default_sort_json='[{"column":"id","direction":"desc"}]',
|
||||
default_visible_columns_json='["id","teacher_name","department","apply_rank","verdict","created_at"]',
|
||||
)
|
||||
seed_column_metadata_batch(
|
||||
cursor,
|
||||
table_name="verify_cases",
|
||||
columns=_VERIFY_CASES_COLUMNS,
|
||||
valid_column_names=[str(c["column_name"]) for c in _VERIFY_CASES_COLUMNS],
|
||||
)
|
||||
|
||||
|
||||
def init_db() -> dict[str, int]:
|
||||
"""幂等创建/迁移本地 SQLite、数据管理元数据与门槛种子。"""
|
||||
conn = get_conn()
|
||||
try:
|
||||
cur = conn.cursor()
|
||||
init_display_metadata(cur)
|
||||
_init_threshold_rules_metadata(cur)
|
||||
_init_verify_cases_metadata(cur)
|
||||
seeded = seed_all(cur)
|
||||
conn.commit()
|
||||
return seeded
|
||||
finally:
|
||||
conn.close()
|
||||
Reference in New Issue
Block a user