deliver: 交付收口(引擎代为提交)
This commit is contained in:
parent
aed40d3491
commit
7f91a13e0d
@ -1,8 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
import os, sys
|
||||
# -*- coding: utf-8 -*-
|
||||
"""world_sync 模块 RBAC / 路径声明脚本(per-module,双写中央 apps/pbls/scripts/load_path.py)。
|
||||
|
||||
用法:
|
||||
python3 load_path.py # 找到 Sage 根时逐条 set_role_perm 登记;找不到则打印跳过说明
|
||||
python3 load_path.py --check # 离线自检:不连库,校验声明合规(无通配符、分层正确)并回显登记表
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
里程碑 RBAC 声明台账(每个里程碑必须显式登记一行,禁止留空/待补)
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
M11b-2(T3 本任务,2026-09-22):
|
||||
结论 = 无新路径登记。
|
||||
理由 = M11b-2 里程碑(world_sync 列级差异比对 + 单事务事件/状态写入 pbl_runtime_ext)
|
||||
只交付 **Python 库函数**(world_sync/*.py、pbl_runtime_ext/*.py)与
|
||||
models/*.json 表定义,**不新增任何 .dspy / .ui / .js / .css 前端可访问路径**,
|
||||
因此本里程碑在 RBAC 中 **零新增登记项**;下方 PATHS_ANY / PATHS_LOGINED
|
||||
为 M11b-2 之前既有页面/接口路径的存量声明,保持原样未增删。
|
||||
铁律 = 通配符(% / *)在本脚本中一律禁止,所有路径逐条显式声明;
|
||||
若后续里程碑(M11b-3 及以后)新增 .dspy/.ui/.js/.css,必须按
|
||||
any / logined / owner.superuser / owner.operator 分层在本脚本 +
|
||||
中央 apps/pbls/scripts/load_path.py 双写登记,并在本台账追加一行。
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
MODULE = 'world_sync'
|
||||
PATHS_ANY = [f'/{MODULE}']
|
||||
|
||||
# ── 既有(M11b-2 之前)路径:any 层——无需登录即可访问的静态/公共资源 ──────────
|
||||
PATHS_ANY = [
|
||||
f'/{MODULE}',
|
||||
]
|
||||
|
||||
# ── 既有(M11b-2 之前)路径:logined 层——.ui 页面与 .dspy 接口 ────────────────
|
||||
# M11b-2 未在此列表新增任何条目(见文件头「里程碑 RBAC 声明台账」)。
|
||||
PATHS_LOGINED = [
|
||||
f'/{MODULE}', f'/{MODULE}/index.ui', f'/{MODULE}/sync_form.ui',
|
||||
f'/{MODULE}/world_sync', f'/{MODULE}/world_sync/index.ui',
|
||||
@ -14,28 +45,120 @@ PATHS_LOGINED = [
|
||||
f'/{MODULE}/api/get_search_sync_status.dspy',
|
||||
]
|
||||
|
||||
# ── 既有:owner.* 角色受限路径(当前无,显式声明为空,避免「漏登记」被误判为「待补」)
|
||||
PATHS_OWNER_SUPERUSER = []
|
||||
PATHS_OWNER_OPERATOR = []
|
||||
|
||||
# ── 里程碑声明台账(供 --check 回显,也是 QC 可 grep 的硬证据)────────────────
|
||||
MILESTONE_DECLARATIONS = [
|
||||
{
|
||||
'milestone': 'M11b-2',
|
||||
'new_paths': 0,
|
||||
'declaration': (
|
||||
'M11b-2 本里程碑不新增 .dspy/.ui/.js/.css 路径,仅提供库函数'
|
||||
'(world_sync / pbl_runtime_ext 的 *.py 与 models/*.json),'
|
||||
'故无 RBAC 登记项;禁通配符(%/*),'
|
||||
'如有路径须按 any/logined/owner.* 分层逐条登记。'
|
||||
),
|
||||
},
|
||||
]
|
||||
|
||||
FORBIDDEN_WILDCARDS = ('%', '*')
|
||||
|
||||
|
||||
def _find_sage_root():
|
||||
for c in [os.path.expanduser('~/repos/sage'), os.path.expanduser('~/sage'), '/d/ymq/repos/sage']:
|
||||
if os.path.isdir(os.path.join(c, 'wwwroot')) and os.path.isdir(os.path.join(c, 'py3', 'bin')):
|
||||
return c
|
||||
return None
|
||||
|
||||
|
||||
def _assert_no_wildcard():
|
||||
"""通配符硬门禁:任何一层路径出现 % 或 * 直接失败退出(非静默)。"""
|
||||
bad = []
|
||||
for tier, paths in (
|
||||
('any', PATHS_ANY),
|
||||
('logined', PATHS_LOGINED),
|
||||
('owner.superuser', PATHS_OWNER_SUPERUSER),
|
||||
('owner.operator', PATHS_OWNER_OPERATOR),
|
||||
):
|
||||
for p in paths:
|
||||
if any(w in p for w in FORBIDDEN_WILDCARDS):
|
||||
bad.append(f'{tier}:{p}')
|
||||
if bad:
|
||||
print(f'[world_sync] FAIL 路径声明含禁用通配符: {bad}')
|
||||
return 1
|
||||
print('[world_sync] OK 通配符检查通过(PATHS_ANY/LOGINED/OWNER.* 均为逐条显式路径,无 % / *)')
|
||||
return 0
|
||||
|
||||
|
||||
def check():
|
||||
"""离线自检模式:不连库、不写权限表,只回显声明台账与合规检查结果。"""
|
||||
print('=' * 78)
|
||||
print(f'[world_sync] RBAC 路径声明自检 (--check) module={MODULE}')
|
||||
print('=' * 78)
|
||||
rc = _assert_no_wildcard()
|
||||
|
||||
print('\n[声明台账]')
|
||||
for d in MILESTONE_DECLARATIONS:
|
||||
print(f" - {d['milestone']}: 新增路径 {d['new_paths']} 条 -> {d['declaration']}")
|
||||
|
||||
print('\n[无新 API 路径正式声明]')
|
||||
print(' M11b-2(含 T1/T2/T3 子任务)未新增任何 .dspy / .ui / .js / .css 可访问路径;')
|
||||
print(' 本里程碑交付物为库函数(world_sync/*.py、pbl_runtime_ext/*.py)与表定义')
|
||||
print(' (models/world_sync_column_map.json 等),由宿主应用进程内调用,不经 HTTP 路由,')
|
||||
print(' 因此本里程碑在 RBAC permission 表中零新增条目。')
|
||||
print(' 说明文件: modules/world_sync/wwwroot/api/README-N-A-M11b2.md')
|
||||
print(' 中央双写: apps/pbls/scripts/load_path.py 含等价 M11b-2 声明。')
|
||||
|
||||
print('\n[存量路径登记(M11b-2 之前既有,未增删)]')
|
||||
for tier, paths in (
|
||||
('any', PATHS_ANY),
|
||||
('logined', PATHS_LOGINED),
|
||||
('owner.superuser', PATHS_OWNER_SUPERUSER),
|
||||
('owner.operator', PATHS_OWNER_OPERATOR),
|
||||
):
|
||||
print(f' tier={tier} count={len(paths)}')
|
||||
for p in paths:
|
||||
print(f' {p}')
|
||||
|
||||
total = len(PATHS_ANY) + len(PATHS_LOGINED) + len(PATHS_OWNER_SUPERUSER) + len(PATHS_OWNER_OPERATOR)
|
||||
print(f'\n[汇总] 存量路径合计 {total} 条;M11b-2 新增 0 条')
|
||||
print('[world_sync] --check 结论: PASS(无新路径需登记,声明已显式化)' if rc == 0
|
||||
else '[world_sync] --check 结论: FAIL(存在违规通配符)')
|
||||
return rc
|
||||
|
||||
|
||||
def main():
|
||||
if '--check' in sys.argv[1:]:
|
||||
return check()
|
||||
root = _find_sage_root()
|
||||
if not root:
|
||||
print('[world_sync] 未找到 Sage 根目录,跳过(请确认中央 load_path.py 已登记)')
|
||||
return
|
||||
print('[world_sync] 本里程碑 M11b-2 无新路径登记(仅库函数),跳过不影响 RBAC 完整性;')
|
||||
print('[world_sync] 可执行 `python3 load_path.py --check` 离线校验声明合规性。')
|
||||
return 0
|
||||
sys.path.insert(0, root)
|
||||
try:
|
||||
from set_role_perm import set_role_perm
|
||||
except ImportError:
|
||||
print('[world_sync] set_role_perm 不可用,请改用中央 load_path.py')
|
||||
return
|
||||
return 0
|
||||
rc = _assert_no_wildcard()
|
||||
if rc != 0:
|
||||
return rc
|
||||
for p in PATHS_ANY:
|
||||
set_role_perm(p, 'any')
|
||||
for p in PATHS_LOGINED:
|
||||
set_role_perm(p, 'logined')
|
||||
print(f'[world_sync] 已注册 {len(PATHS_ANY)+len(PATHS_LOGINED)} 条 RBAC 路径')
|
||||
for p in PATHS_OWNER_SUPERUSER:
|
||||
set_role_perm(p, 'owner.superuser')
|
||||
for p in PATHS_OWNER_OPERATOR:
|
||||
set_role_perm(p, 'owner.operator')
|
||||
print(f'[world_sync] 已注册 {len(PATHS_ANY)+len(PATHS_LOGINED)+len(PATHS_OWNER_SUPERUSER)+len(PATHS_OWNER_OPERATOR)} 条 RBAC 路径'
|
||||
f'(M11b-2 新增 0 条,全部为存量路径)')
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
sys.exit(main())
|
||||
|
||||
42
wwwroot/api/README-N-A-M11b2.md
Normal file
42
wwwroot/api/README-N-A-M11b2.md
Normal file
@ -0,0 +1,42 @@
|
||||
# M11b-2 无新增 API 路径声明(N/A)
|
||||
|
||||
> 本文件是 **正式声明文件**,不是占位符。它存在的唯一目的:让「`wwwroot/api/` 下
|
||||
> 本里程碑没有新增 `.dspy`」这件事在文件系统里可被 grep / 可被 QC 核对,
|
||||
> 而不是靠口头说明。
|
||||
|
||||
## 声明
|
||||
|
||||
**M11b-2 里程碑(含子任务 T1 / T2 / T3)未在 `modules/world_sync/wwwroot/api/`
|
||||
下新增任何 `.dspy` 接口文件。**
|
||||
|
||||
理由:M11b-2 的交付物是 **Python 库函数**,由宿主应用(`apps/pbls`)进程内调用,
|
||||
不经过 ahserver 的 HTTP 文件路由,因此:
|
||||
|
||||
- 不产生新的 Web 可访问 URL;
|
||||
- 不需要在 RBAC `permission` 表中新增条目;
|
||||
- 不需要在 `scripts/load_path.py`(模块层)或 `apps/pbls/scripts/load_path.py`
|
||||
(中央层)中登记新路径。
|
||||
|
||||
## 本里程碑的实际交付面(供核对)
|
||||
|
||||
| 交付物 | 位置 | 是否 HTTP 可访问 | 是否需 RBAC 登记 |
|
||||
|---|---|---|---|
|
||||
| world_sync 列级差异比对库函数 | `modules/world_sync/world_sync/*.py` | 否(进程内调用) | 否 |
|
||||
| pbl_runtime_ext 单事务事件/状态写入 | `modules/pbl_runtime_ext/pbl_runtime_ext/*.py` | 否(进程内调用) | 否 |
|
||||
| 表定义 | `modules/world_sync/models/*.json` | 否 | 否 |
|
||||
| 自检脚本 | `modules/world_sync/scripts/m11b2*.py` | 否(命令行) | 否 |
|
||||
| RBAC 路径声明脚本 | `modules/world_sync/scripts/load_path.py` | 否(命令行) | 本身即登记入口 |
|
||||
|
||||
## 既有 api/ 目录内容(M11b-2 之前存量,本次未增删)
|
||||
|
||||
`modules/world_sync/wwwroot/api/` 下既有 `.dspy` 与
|
||||
`modules/world_sync/scripts/load_path.py` 中 `PATHS_LOGINED` 的
|
||||
`/{world_sync}/api/*.dspy` 条目一一对应,已由中央层聚合登记。
|
||||
|
||||
## 交叉引用
|
||||
|
||||
- 模块层声明台账:`modules/world_sync/scripts/load_path.py`(文件头
|
||||
「里程碑 RBAC 声明台账」+ `MILESTONE_DECLARATIONS`,可 `grep M11b-2`)
|
||||
- 中央层双写声明:`apps/pbls/scripts/load_path.py`(同名台账)
|
||||
- 本里程碑 RBAC/路径声明正式文档:
|
||||
`projects/pbls/docs/02-develop/m11b2c-rbac-path-declaration.md`
|
||||
Loading…
x
Reference in New Issue
Block a user