refactor(deploy): sd_audit_logs 建表 + owner.audit 角色从启动期迁到部署期(create_tables.py + import_init.py)

This commit is contained in:
yumoqing 2026-08-18 16:23:25 +08:00
parent 4f8aff467f
commit f59e6f3c45
2 changed files with 39 additions and 2 deletions

View File

@ -124,6 +124,25 @@ _V2_COLUMNS = {
"pipeline_tasks": {"retry_count": "int NOT NULL DEFAULT 0", "last_error": "text"},
}
# app_audit 审计日志表(原 app_audit/init.py::_init_audit 启动时建,现迁到部署期)
_AUDIT_LOGS_DDL = """
CREATE TABLE IF NOT EXISTS sd_audit_logs (
`id` varchar(32) NOT NULL,
`user_id` varchar(32),
`username` varchar(100),
`action` varchar(50) NOT NULL,
`target` varchar(200),
`detail` text,
`result` varchar(10),
`client_ip` varchar(64),
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_user` (`user_id`),
KEY `idx_action` (`action`),
KEY `idx_created` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
"""
def split_ddl(ddl):
"""按分号分割 DDL跳过注释行和空语句。"""
@ -257,6 +276,13 @@ async def main():
except Exception as e:
print(f' WARN: v2 engine column migrate failed: {e}')
# app_audit 审计日志表(原启动时建,现迁到部署期幂等建表)
try:
await sor.execute(_AUDIT_LOGS_DDL, {})
print(' tables: sd_audit_logs ensured (idempotent)')
except Exception as e:
print(f' WARN: sd_audit_logs ensure failed: {e}')
if __name__ == '__main__':
asyncio.run(main())

View File

@ -27,6 +27,7 @@ INIT_MODULES = [
('discount', 'pkgs/discount/init/data.json'),
('pipeline_core', 'pkgs/pipeline_core/init/data.json'),
('pipeline-sdlc', 'pkgs/pipeline-sdlc/init/data.json'),
('app_audit', 'pkgs/app_audit/init/data.json'),
]
@ -65,7 +66,7 @@ async def main():
env = ServerEnv()
env.get_module_dbname = lambda m: 'pipeline' if 'pipeline' in m else 'sage'
total = {'appcodes': 0, 'appcodes_kv': 0, 'organization': 0}
total = {'appcodes': 0, 'appcodes_kv': 0, 'organization': 0, 'roles': 0}
async with DBPools().sqlorContext('pipeline') as sor:
for mod, rel in INIT_MODULES:
f = os.path.join(ROOT_DIR, rel)
@ -105,7 +106,17 @@ async def main():
'orgname': org.get('orgname', ''),
})
total['organization'] += 1
print(f'import_init: appcodes {total["appcodes"]}, appcodes_kv {total["appcodes_kv"]}, organization {total["organization"]}')
# RBAC 角色(如 app_audit 的 owner.audit 审计独立角色),幂等按主键 id 检查
for r in data.get('roles', []):
recs = await sor.R('role', {'id': r['id']})
if not recs:
await sor.C('role', {
'id': r['id'],
'orgtypeid': r.get('orgtypeid', '0'),
'name': r.get('name', ''),
})
total['roles'] += 1
print(f'import_init: appcodes {total["appcodes"]}, appcodes_kv {total["appcodes_kv"]}, organization {total["organization"]}, roles {total["roles"]}')
if __name__ == '__main__':