deliver: 交付收口(引擎代为提交)
This commit is contained in:
parent
aed40d3491
commit
7f91a13e0d
@ -1,8 +1,39 @@
|
|||||||
#!/usr/bin/env python3
|
#!/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'
|
MODULE = 'world_sync'
|
||||||
PATHS_ANY = [f'/{MODULE}']
|
|
||||||
|
# ── 既有(M11b-2 之前)路径:any 层——无需登录即可访问的静态/公共资源 ──────────
|
||||||
|
PATHS_ANY = [
|
||||||
|
f'/{MODULE}',
|
||||||
|
]
|
||||||
|
|
||||||
|
# ── 既有(M11b-2 之前)路径:logined 层——.ui 页面与 .dspy 接口 ────────────────
|
||||||
|
# M11b-2 未在此列表新增任何条目(见文件头「里程碑 RBAC 声明台账」)。
|
||||||
PATHS_LOGINED = [
|
PATHS_LOGINED = [
|
||||||
f'/{MODULE}', f'/{MODULE}/index.ui', f'/{MODULE}/sync_form.ui',
|
f'/{MODULE}', f'/{MODULE}/index.ui', f'/{MODULE}/sync_form.ui',
|
||||||
f'/{MODULE}/world_sync', f'/{MODULE}/world_sync/index.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',
|
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():
|
def _find_sage_root():
|
||||||
for c in [os.path.expanduser('~/repos/sage'), os.path.expanduser('~/sage'), '/d/ymq/repos/sage']:
|
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')):
|
if os.path.isdir(os.path.join(c, 'wwwroot')) and os.path.isdir(os.path.join(c, 'py3', 'bin')):
|
||||||
return c
|
return c
|
||||||
return None
|
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():
|
def main():
|
||||||
|
if '--check' in sys.argv[1:]:
|
||||||
|
return check()
|
||||||
root = _find_sage_root()
|
root = _find_sage_root()
|
||||||
if not root:
|
if not root:
|
||||||
print('[world_sync] 未找到 Sage 根目录,跳过(请确认中央 load_path.py 已登记)')
|
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)
|
sys.path.insert(0, root)
|
||||||
try:
|
try:
|
||||||
from set_role_perm import set_role_perm
|
from set_role_perm import set_role_perm
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print('[world_sync] set_role_perm 不可用,请改用中央 load_path.py')
|
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:
|
for p in PATHS_ANY:
|
||||||
set_role_perm(p, 'any')
|
set_role_perm(p, 'any')
|
||||||
for p in PATHS_LOGINED:
|
for p in PATHS_LOGINED:
|
||||||
set_role_perm(p, '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__':
|
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