pz-cli 5.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pz_cli-5.0.0.dist-info/METADATA +51 -0
- pz_cli-5.0.0.dist-info/RECORD +399 -0
- pz_cli-5.0.0.dist-info/WHEEL +4 -0
- pz_cli-5.0.0.dist-info/entry_points.txt +5 -0
- pz_core/__init__.py +64 -0
- pz_core/__main__.py +7 -0
- pz_core/app.py +45 -0
- pz_core/assembly/__init__.py +17 -0
- pz_core/assembly/app_discovery.py +1240 -0
- pz_core/assembly/apps/__init__.py +25 -0
- pz_core/assembly/apps/compiler.py +824 -0
- pz_core/assembly/apps/providers.py +188 -0
- pz_core/assembly/cli/__init__.py +9 -0
- pz_core/assembly/cli/compiler.py +166 -0
- pz_core/assembly/diagnostics/__init__.py +21 -0
- pz_core/assembly/diagnostics/checks.py +257 -0
- pz_core/assembly/diagnostics/dev_sources.py +569 -0
- pz_core/assembly/events/__init__.py +5 -0
- pz_core/assembly/events/compiler.py +219 -0
- pz_core/assembly/extensions/__init__.py +5 -0
- pz_core/assembly/extensions/compiler.py +696 -0
- pz_core/assembly/infra/__init__.py +6 -0
- pz_core/assembly/infra/compiler.py +272 -0
- pz_core/assembly/lifecycle/__init__.py +5 -0
- pz_core/assembly/lifecycle/compiler.py +95 -0
- pz_core/assembly/middlewares/__init__.py +19 -0
- pz_core/assembly/middlewares/compiler.py +508 -0
- pz_core/assembly/project/__init__.py +7 -0
- pz_core/assembly/project/compiler.py +9 -0
- pz_core/assembly/project/context.py +17 -0
- pz_core/assembly/project/discovery.py +227 -0
- pz_core/assembly/resources/__init__.py +19 -0
- pz_core/assembly/resources/compiler.py +310 -0
- pz_core/assembly/resources/settings.py +129 -0
- pz_core/assembly/routes/__init__.py +7 -0
- pz_core/assembly/routes/compiler.py +400 -0
- pz_core/assembly/runtime_manifests/__init__.py +13 -0
- pz_core/assembly/runtime_manifests/compiler.py +159 -0
- pz_core/assembly/settings/__init__.py +17 -0
- pz_core/assembly/settings/compiler.py +786 -0
- pz_core/assembly/settings/host_project_overrides.py +82 -0
- pz_core/assembly/settings/host_runtime_endpoint.py +207 -0
- pz_core/authoring/__init__.py +79 -0
- pz_core/authoring/app_init_service.py +946 -0
- pz_core/authoring/app_versions.py +814 -0
- pz_core/authoring/cli.py +192 -0
- pz_core/authoring/commands.py +1810 -0
- pz_core/authoring/conflicts.py +180 -0
- pz_core/authoring/dev_bindings.py +916 -0
- pz_core/authoring/dev_git.py +1087 -0
- pz_core/authoring/dev_import.py +1061 -0
- pz_core/authoring/dev_manifest.py +522 -0
- pz_core/authoring/dev_sources.py +1638 -0
- pz_core/authoring/env_cli.py +454 -0
- pz_core/authoring/files.py +109 -0
- pz_core/authoring/ide_projection.py +1129 -0
- pz_core/authoring/naming.py +58 -0
- pz_core/authoring/official_dev_sources.py +432 -0
- pz_core/authoring/official_sources.json +156 -0
- pz_core/authoring/orchestration_service.py +558 -0
- pz_core/authoring/project_default.jsonc +53 -0
- pz_core/authoring/project_defaults.py +88 -0
- pz_core/authoring/project_metadata_service.py +199 -0
- pz_core/authoring/project_settings_checks.py +51 -0
- pz_core/authoring/project_settings_cli.py +299 -0
- pz_core/authoring/project_settings_service.py +1700 -0
- pz_core/authoring/project_state.py +399 -0
- pz_core/authoring/publish_git.py +423 -0
- pz_core/authoring/publish_lock.py +188 -0
- pz_core/authoring/publish_source.py +195 -0
- pz_core/authoring/release.py +1382 -0
- pz_core/authoring/repo_keys.py +29 -0
- pz_core/authoring/root_cli.py +28 -0
- pz_core/authoring/scaffold_service.py +325 -0
- pz_core/authoring/sync_service.py +787 -0
- pz_core/authoring/templates/app/__init__.py +1 -0
- pz_core/authoring/templates/app/api.py +25 -0
- pz_core/authoring/templates/app/apps.py +31 -0
- pz_core/authoring/templates/app/auth_package_init.py +14 -0
- pz_core/authoring/templates/app/auth_readme.py +29 -0
- pz_core/authoring/templates/app/configs_package_init.py +14 -0
- pz_core/authoring/templates/app/default_env.py +18 -0
- pz_core/authoring/templates/app/default_jsonc.py +25 -0
- pz_core/authoring/templates/app/locales_readme.py +25 -0
- pz_core/authoring/templates/app/migrations_readme.py +19 -0
- pz_core/authoring/templates/app/models.py +14 -0
- pz_core/authoring/templates/app/package_init.py +8 -0
- pz_core/authoring/templates/app/pages_base.py +161 -0
- pz_core/authoring/templates/app/pages_readme.py +25 -0
- pz_core/authoring/templates/app/public.py +31 -0
- pz_core/authoring/templates/app/pyproject.py +77 -0
- pz_core/authoring/templates/app/readme.py +74 -0
- pz_core/authoring/templates/app/settings.py +46 -0
- pz_core/authoring/templates/app/static_app_js.py +24 -0
- pz_core/authoring/templates/app/static_readme.py +31 -0
- pz_core/authoring/templates/app/template_config_page.py +23 -0
- pz_core/authoring/templates/app/template_index_html.py +28 -0
- pz_core/authoring/templates/app/templates_readme.py +32 -0
- pz_core/authoring/templates/app/urls.py +36 -0
- pz_core/authoring/templates/app/views.py +36 -0
- pz_core/authoring/templates/project/__init__.py +1 -0
- pz_core/authoring/templates/project/agents.py +51 -0
- pz_core/authoring/templates/project/apps_container_readme.py +37 -0
- pz_core/authoring/templates/project/main_py.py +59 -0
- pz_core/authoring/templates/project/project_env.py +19 -0
- pz_core/authoring/templates/project/pyproject.py +26 -0
- pz_core/authoring/templates/project/pz_env_env.py +65 -0
- pz_core/authoring/templates/project/pz_env_jsonc.py +69 -0
- pz_core/authoring/templates/project/pz_jsonc.py +12 -0
- pz_core/authoring/templates/project/readme.py +94 -0
- pz_core/authoring/templates/project/root_gitkeep.py +8 -0
- pz_core/authoring/templates/shared/__init__.py +5 -0
- pz_core/authoring/templates/shared/text.py +10 -0
- pz_core/authoring/venv_service.py +87 -0
- pz_core/authoring/workspace.py +167 -0
- pz_core/cli.py +291 -0
- pz_core/cli_options.py +74 -0
- pz_core/core/__init__.py +3 -0
- pz_core/core/errors/__init__.py +5 -0
- pz_core/core/errors/models.py +117 -0
- pz_core/core/events/__init__.py +5 -0
- pz_core/core/events/registry.py +54 -0
- pz_core/core/extensions/__init__.py +51 -0
- pz_core/core/extensions/registry.py +790 -0
- pz_core/core/health/__init__.py +6 -0
- pz_core/core/health/contracts.py +10 -0
- pz_core/core/middlewares/__init__.py +6 -0
- pz_core/core/middlewares/models.py +24 -0
- pz_core/core/routing/__init__.py +5 -0
- pz_core/core/routing/models.py +21 -0
- pz_core/core/settings_contracts.py +25 -0
- pz_core/docs/README.md +20 -0
- pz_core/docs/distribution-README.md +438 -0
- pz_core/docs/pz/345/221/275/344/273/244/346/200/273/350/247/210.md +1011 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/00-pz/346/236/266/346/236/204/346/200/273/347/272/262.md +240 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/01-/347/233/256/345/275/225/344/270/216/345/210/206/345/261/202/350/247/204/350/214/203.md +216 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/02-/345/214/205/344/270/216/345/210/206/345/217/221/350/247/204/350/214/203.md +403 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/03-App/346/234/200/345/260/217/345/255/220/345/214/205/350/247/204/350/214/203.md +571 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/04-Settings/344/270/216/351/205/215/347/275/256/350/247/204/350/214/203.md +1177 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/05-/350/265/204/346/272/220/344/270/216/350/277/220/350/241/214/347/233/256/345/275/225/350/247/204/350/214/203.md +575 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/06-/346/225/260/346/215/256/345/272/223/344/270/216/345/217/257/351/200/211/345/237/272/347/241/200/350/256/276/346/226/275/350/247/204/350/214/203.md +499 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/07-App/346/233/277/346/215/242/350/247/204/350/214/203.md +206 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/08-/345/271/263/345/217/260/347/272/247App/344/270/216/350/277/220/350/241/214/346/227/266/345/215/225/344/276/213/350/247/204/350/214/203.md +445 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/09-CLI/344/270/216Worker/345/205/245/345/217/243/350/247/204/350/214/203.md +950 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/10-/346/265/213/350/257/225/344/270/216/345/245/221/347/272/246/350/247/204/350/214/203.md +1001 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/11-/344/273/223/345/272/223/347/234/237/347/233/270/346/272/220/345/234/260/345/233/276.md +102 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/12-/346/236/204/345/273/272/344/270/216/345/217/221/345/270/203/346/243/200/346/237/245/346/270/205/345/215/225.md +171 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/13-/346/255/243/345/274/217Facade/346/200/273/350/241/250.md +402 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/14-/345/210/206/345/261/202/344/270/216/346/211/251/345/261/225/350/247/204/350/214/203.md +550 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/15-/345/255/220/345/214/205/345/274/200/345/217/221/344/275/277/347/224/250/346/211/213/345/206/214.md +1004 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/16-/346/211/251/345/261/225/347/202/271/346/255/243/345/274/217/345/215/217/350/256/256/346/270/205/345/215/225.md +352 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/17-pz.protocols.v1/346/255/243/345/274/217/345/215/217/350/256/256.md +266 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/18-/346/211/251/345/261/225/347/202/271/345/206/262/347/252/201/350/243/201/345/206/263/346/200/273/350/241/250.md +131 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/19-/351/224/231/350/257/257/347/240/201/344/270/216/350/257/212/346/226/255/345/215/217/350/256/256.md +176 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/20-/347/247/201/346/234/211/345/214/205/344/273/223/344/270/216/347/273/237/344/270/200/350/256/244/350/257/201/351/203/250/347/275/262/350/247/204/350/214/203.md +243 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/21-contrib/347/272/246/345/256/232/344/270/216Provider/346/216/245/345/205/245/350/247/204/350/214/203.md +365 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/22-/345/244/232/345/233/275/350/257/255/350/250/200/350/265/204/346/272/220/346/262/273/347/220/206/344/270/216/346/214/211/351/234/200/345/212/240/350/275/275/350/247/204/350/214/203.md +912 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/23-/351/246/226/345/261/217/345/261/225/347/244/272/344/270/216/351/246/226/345/270/247/347/250/263/345/256/232/350/247/204/350/214/203.md +269 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/24-pz/345/220/257/345/212/250/344/270/216/350/277/220/350/241/214/346/227/266/347/274/226/350/257/221/346/265/201/347/250/213.md +245 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/25-/351/235/242/345/220/221/345/257/271/350/261/241/345/274/200/345/217/221/350/247/204/350/214/203.md +300 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/README.md +98 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/00-legacy_core/346/240/207/345/207/206pip/345/214/205/345/214/226/351/207/215/346/236/204/346/200/273/347/272/262.md +1073 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/01-/347/233/256/345/275/225/344/270/216/345/210/206/345/261/202/351/207/215/346/236/204/346/211/247/350/241/214/346/226/271/346/241/210.md +224 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/02-/345/214/205/344/270/216/345/210/206/345/217/221/350/247/204/350/214/203-/345/220/253/345/216/206/345/217/262/345/217/243/345/276/204.md +671 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/13-/344/270/200/346/254/241/346/200/247/345/256/236/346/226/275/346/270/205/345/215/225.md +387 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/14-/345/255/220/345/214/205/351/200/202/351/205/215/346/224/271/351/200/240/346/270/205/345/215/225.md +592 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/15-infra/350/243/201/345/211/252/344/270/216/350/220/275/344/275/215/346/270/205/345/215/225.md +81 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/19-core/345/215/225/344/270/200/346/255/243/345/274/217/346/226/271/346/241/210/346/224/266/346/225/233/346/211/247/350/241/214/346/270/205/345/215/225.md +161 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/25-/345/215/217/350/256/256/345/210/260/346/272/220/347/240/201/345/267/256/350/267/235/346/270/205/345/215/225.md +377 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/26-cutover/345/256/214/345/267/245/346/243/200/346/237/245/346/270/205/345/215/225.md +117 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/29-/345/244/232/345/233/275/350/257/255/350/250/200/350/265/204/346/272/220/346/262/273/347/220/206/344/270/216/346/214/211/351/234/200/345/212/240/350/275/275/350/247/204/350/214/203-/345/220/253/350/277/201/347/247/273/347/255/226/347/225/245.md +956 -0
- pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/archive//344/270/255/351/227/264/346/200/201/99-/350/265/204/346/272/220/346/224/266/345/217/243/345/220/216/347/273/255TODO.md +84 -0
- pz_core/docs//345/217/221/347/211/210/345/211/215/346/270/205/345/215/225-4.0.11.md +84 -0
- pz_core/docs//346/226/260/346/211/213/346/214/207/345/215/227.md +422 -0
- pz_core/infra/__init__.py +17 -0
- pz_core/infra/db/__init__.py +23 -0
- pz_core/infra/db/contracts.py +73 -0
- pz_core/infra/health/__init__.py +5 -0
- pz_core/infra/health/contracts.py +8 -0
- pz_core/infra/kv/__init__.py +5 -0
- pz_core/infra/kv/contracts.py +17 -0
- pz_core/infra/observability/__init__.py +23 -0
- pz_core/infra/observability/contracts.py +142 -0
- pz_core/infra/resilience/__init__.py +5 -0
- pz_core/infra/resilience/contracts.py +17 -0
- pz_core/infra/resources/__init__.py +5 -0
- pz_core/infra/resources/contracts.py +16 -0
- pz_core/infra/settings/__init__.py +17 -0
- pz_core/infra/settings/models.py +81 -0
- pz_core/infra/storage/__init__.py +5 -0
- pz_core/infra/storage/ports.py +27 -0
- pz_core/project_root_commands.py +282 -0
- pz_core/project_runtime_cli.py +344 -0
- pz_core/project_sources.py +253 -0
- pz_core/pz_launcher.py +209 -0
- pz_core/root_cli.py +70 -0
- pz_core/runtime/__init__.py +229 -0
- pz_core/runtime/access.py +86 -0
- pz_core/runtime/adapters/__init__.py +5 -0
- pz_core/runtime/adapters/base.py +18 -0
- pz_core/runtime/asyncio_bridge.py +18 -0
- pz_core/runtime/bindings/__init__.py +5 -0
- pz_core/runtime/bindings/container.py +50 -0
- pz_core/runtime/cli/__init__.py +5 -0
- pz_core/runtime/cli/_args.py +67 -0
- pz_core/runtime/cli/app_commands.py +417 -0
- pz_core/runtime/cli/check.py +214 -0
- pz_core/runtime/cli/db.py +297 -0
- pz_core/runtime/cli/main.py +89 -0
- pz_core/runtime/cli/resources.py +280 -0
- pz_core/runtime/discovery.py +23 -0
- pz_core/runtime/environment_integrity.py +157 -0
- pz_core/runtime/errors.py +5 -0
- pz_core/runtime/events.py +87 -0
- pz_core/runtime/facades/__init__.py +38 -0
- pz_core/runtime/facades/_capabilities.py +46 -0
- pz_core/runtime/facades/cache.py +103 -0
- pz_core/runtime/facades/database.py +71 -0
- pz_core/runtime/facades/events.py +380 -0
- pz_core/runtime/facades/health.py +101 -0
- pz_core/runtime/facades/mail.py +121 -0
- pz_core/runtime/facades/observability.py +102 -0
- pz_core/runtime/facades/providers.py +75 -0
- pz_core/runtime/facades/resources.py +52 -0
- pz_core/runtime/facades/storage.py +296 -0
- pz_core/runtime/health/__init__.py +5 -0
- pz_core/runtime/health/service.py +102 -0
- pz_core/runtime/host.py +188 -0
- pz_core/runtime/host_runner.py +282 -0
- pz_core/runtime/http/__init__.py +20 -0
- pz_core/runtime/http/app.py +576 -0
- pz_core/runtime/http_timing.py +173 -0
- pz_core/runtime/invocation.py +29 -0
- pz_core/runtime/json_safe.py +47 -0
- pz_core/runtime/lifecycle/__init__.py +25 -0
- pz_core/runtime/lifecycle/manager.py +533 -0
- pz_core/runtime/plan.py +214 -0
- pz_core/runtime/plan_context.py +33 -0
- pz_core/runtime/plan_snapshot.py +177 -0
- pz_core/runtime/registries/__init__.py +27 -0
- pz_core/runtime/registries/capabilities.py +101 -0
- pz_core/runtime/registries/providers.py +396 -0
- pz_core/runtime/resource_assets.py +344 -0
- pz_core/runtime/run_cli.py +211 -0
- pz_core/runtime/settings.py +888 -0
- pz_core/runtime/worker/__init__.py +21 -0
- pz_core/runtime/worker/engine.py +921 -0
- pz_core/runtime/worker/runtime.py +25 -0
- pz_core/testing/__init__.py +15 -0
- pz_core/testing/doc_route_contracts.py +305 -0
- pz_core/utils/__init__.py +44 -0
- pz_core/utils/env.py +65 -0
- pz_core/utils/project_jsonc/__init__.py +29 -0
- pz_core/utils/project_jsonc/document.py +420 -0
- pz_core/utils/project_settings.py +99 -0
- pz_foundation/__init__.py +50 -0
- pz_foundation/_contracts.py +81 -0
- pz_foundation/_errors.py +34 -0
- pz_foundation/api.py +14 -0
- pz_foundation/apps.py +127 -0
- pz_foundation/auth/__init__.py +1 -0
- pz_foundation/cache_control.py +233 -0
- pz_foundation/cli/__init__.py +2 -0
- pz_foundation/cli/workers.py +565 -0
- pz_foundation/configs/__init__.py +0 -0
- pz_foundation/configs/default.env +15 -0
- pz_foundation/configs/default.jsonc +452 -0
- pz_foundation/db/__init__.py +94 -0
- pz_foundation/db/aerich_executor.py +664 -0
- pz_foundation/db/config.py +358 -0
- pz_foundation/db/connection_manager.py +689 -0
- pz_foundation/db/connection_probe.py +204 -0
- pz_foundation/db/database.py +1291 -0
- pz_foundation/db/deps.py +47 -0
- pz_foundation/db/lifecycle_status.py +85 -0
- pz_foundation/db/migrations.py +477 -0
- pz_foundation/db/mysql.py +57 -0
- pz_foundation/db/postgresql.py +409 -0
- pz_foundation/db/production_pool_fallback.py +143 -0
- pz_foundation/db/public.py +45 -0
- pz_foundation/db/session.py +369 -0
- pz_foundation/db/sqlite.py +15 -0
- pz_foundation/db/tortoise_manager.py +724 -0
- pz_foundation/db/tortoise_psycopg.py +148 -0
- pz_foundation/docs/README.md +18 -0
- pz_foundation/docs/distribution-README.md +319 -0
- pz_foundation/docs/infra/350/243/201/345/211/252/344/270/216/350/220/275/344/275/215/350/257/264/346/230/216.md +39 -0
- pz_foundation/docs//345/205/254/345/274/200/345/205/215/350/264/271/346/216/245/345/217/243/351/230/262/346/273/245/347/224/250/344/270/216/344/272/272/346/234/272/346/240/241/351/252/214.md +680 -0
- pz_foundation/docs//350/256/276/350/256/241/346/226/207/346/241/243.md +288 -0
- pz_foundation/docs//350/267/257/347/224/261/344/270/216URL/345/244/204/347/220/206/350/247/204/350/214/203.md +119 -0
- pz_foundation/health.py +105 -0
- pz_foundation/host/__init__.py +11 -0
- pz_foundation/host/builder.py +34 -0
- pz_foundation/host/cache_runtime.py +44 -0
- pz_foundation/host/db/__init__.py +17 -0
- pz_foundation/host/db/aerich_config.py +36 -0
- pz_foundation/host/db/config.py +106 -0
- pz_foundation/host/db/connection_manager.py +48 -0
- pz_foundation/host/db/deps.py +5 -0
- pz_foundation/host/db/orm_retry_patch.py +566 -0
- pz_foundation/host/db/request_adapter.py +325 -0
- pz_foundation/host/db/router.py +28 -0
- pz_foundation/host/db/session.py +284 -0
- pz_foundation/host/db/tortoise_manager.py +10 -0
- pz_foundation/host/idempotency.py +132 -0
- pz_foundation/host/lifespan.py +247 -0
- pz_foundation/host/redis_runtime.py +100 -0
- pz_foundation/host/web.py +790 -0
- pz_foundation/infra_provider.py +236 -0
- pz_foundation/kv/__init__.py +25 -0
- pz_foundation/kv/cache.py +1166 -0
- pz_foundation/kv/deps.py +84 -0
- pz_foundation/kv/public.py +25 -0
- pz_foundation/kv/redis_manager.py +1531 -0
- pz_foundation/lazy_exports.py +43 -0
- pz_foundation/lazy_imports.py +124 -0
- pz_foundation/lifecycle.py +392 -0
- pz_foundation/managed_workers.py +1117 -0
- pz_foundation/middlewares/__init__.py +26 -0
- pz_foundation/middlewares/_settings.py +250 -0
- pz_foundation/middlewares/analytics.py +124 -0
- pz_foundation/middlewares/cache_control.py +156 -0
- pz_foundation/middlewares/compression.py +202 -0
- pz_foundation/middlewares/cors.py +62 -0
- pz_foundation/middlewares/geo_country.py +44 -0
- pz_foundation/middlewares/inner_router.py +50 -0
- pz_foundation/middlewares/rate_limited/__init__.py +3 -0
- pz_foundation/middlewares/rate_limited/key_limiter.py +115 -0
- pz_foundation/middlewares/request_logging.py +104 -0
- pz_foundation/middlewares/route_owner.py +309 -0
- pz_foundation/middlewares/security_csrf.py +44 -0
- pz_foundation/middlewares/security_headers/__init__.py +4 -0
- pz_foundation/middlewares/security_headers/conflicts.py +44 -0
- pz_foundation/middlewares/security_headers/csp_nonce.py +200 -0
- pz_foundation/middlewares/security_headers/security_headers.py +44 -0
- pz_foundation/migrations/__init__.py +1 -0
- pz_foundation/migrations/pz_foundation/__init__.py +1 -0
- pz_foundation/models.py +22 -0
- pz_foundation/notifications/__init__.py +23 -0
- pz_foundation/notifications/email.py +542 -0
- pz_foundation/notifications/public.py +31 -0
- pz_foundation/observability/__init__.py +71 -0
- pz_foundation/observability/http.py +34 -0
- pz_foundation/observability/logger/__init__.py +49 -0
- pz_foundation/observability/logger/_bot_settings.py +126 -0
- pz_foundation/observability/logger/bot_message.py +592 -0
- pz_foundation/observability/logger/core.py +385 -0
- pz_foundation/observability/logger/delivery_audit.py +84 -0
- pz_foundation/observability/logger/feishu_bot.py +199 -0
- pz_foundation/observability/logger/telegram_bot.py +194 -0
- pz_foundation/observability/metrics.py +365 -0
- pz_foundation/observability/runtime.py +68 -0
- pz_foundation/public.py +405 -0
- pz_foundation/resources/__init__.py +12 -0
- pz_foundation/resources/builder.py +900 -0
- pz_foundation/resources/images.py +363 -0
- pz_foundation/root_cli.py +20 -0
- pz_foundation/routing/__init__.py +203 -0
- pz_foundation/routing/canonical.py +486 -0
- pz_foundation/routing/convertors.py +82 -0
- pz_foundation/routing/declarations.py +843 -0
- pz_foundation/routing/exports.py +148 -0
- pz_foundation/routing/loaders.py +138 -0
- pz_foundation/routing/manifest.py +215 -0
- pz_foundation/routing/manifest_provider.py +47 -0
- pz_foundation/routing/mounts.py +101 -0
- pz_foundation/routing/ordering.py +172 -0
- pz_foundation/routing/registry.py +133 -0
- pz_foundation/routing/utils.py +28 -0
- pz_foundation/runtime.py +234 -0
- pz_foundation/settings.py +253 -0
- pz_foundation/settings_normalization.py +130 -0
- pz_foundation/storage/__init__.py +25 -0
- pz_foundation/storage/local.py +209 -0
- pz_foundation/storage/public.py +106 -0
- pz_foundation/storage/s3.py +116 -0
- pz_foundation/storage/service.py +234 -0
- pz_foundation/urls.py +19 -0
- pz_foundation/utils/__init__.py +6 -0
- pz_foundation/utils/merge.py +160 -0
- pz_foundation/worker_replicas.py +55 -0
- pz_settings_center/__init__.py +5 -0
- pz_settings_center/api/__init__.py +5 -0
- pz_settings_center/api/runtime_overrides.py +360 -0
- pz_settings_center/apps.py +28 -0
- pz_settings_center/configs/__init__.py +0 -0
- pz_settings_center/configs/default.env +2 -0
- pz_settings_center/configs/default.jsonc +1 -0
- pz_settings_center/docs/01-settings_center/350/203/275/345/212/233/350/276/271/347/225/214.md +124 -0
- pz_settings_center/docs/README.md +12 -0
- pz_settings_center/docs/distribution-README.md +150 -0
- pz_settings_center/docs//350/256/276/350/256/241/346/226/207/346/241/243.md +48 -0
- pz_settings_center/integration_payload.py +18 -0
- pz_settings_center/project_helpers.py +405 -0
- pz_settings_center/public.py +139 -0
- pz_settings_center/routing_helpers.py +73 -0
- pz_settings_center/runtime_override_provider.py +61 -0
- pz_settings_center/typed_settings.py +324 -0
- pz_settings_center/urls.py +9 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# 仓库真相源地图
|
|
2
|
+
|
|
3
|
+
本文只描述 pz v5 的最终仓库与源码真相源,不保留旧三仓结构的运行时兼容。
|
|
4
|
+
|
|
5
|
+
## 1. 只有两个 Git 仓库
|
|
6
|
+
|
|
7
|
+
| 逻辑仓名 | 物理远端 | 默认分支 | 职责 |
|
|
8
|
+
| --- | --- | --- | --- |
|
|
9
|
+
| `pz` | `git@github.com:JiXiangTools/pyzza.git` | `develop` | 单一 `pz-cli` distribution 及 wheel 内的 `pz_core`、`pz_foundation`、`pz_settings_center` Python 包 |
|
|
10
|
+
| `pz_apps` | `git@github.com:JiXiangTools/pyzza_platform.git` | `develop` | 除最小基础能力外的全部正式最小子包 |
|
|
11
|
+
|
|
12
|
+
原站点运行时仓的代码与历史已经并入逻辑仓 `pz_apps`。它不再是独立 checkout、独立依赖根或独立运行时分组。
|
|
13
|
+
|
|
14
|
+
## 2. `pz` 仓职责
|
|
15
|
+
|
|
16
|
+
`pz` 仓根固定包含:
|
|
17
|
+
|
|
18
|
+
- 根 `pyproject.toml` / `uv.lock`:`pz-cli==5.0.0` 的唯一构建、版本与依赖真相源;console script 入口为 `pz_core.pz_launcher:main`
|
|
19
|
+
- `pz_core/`:稳定合同、发现协议、编译、authoring 与统一启动协议
|
|
20
|
+
- `pz_contrib/`:同一个 `pz-cli` wheel 内的官方最小完整基础能力源码容器;容器本身不提供运行时 namespace 或独立 wheel
|
|
21
|
+
- `pz_contrib/pz_foundation/`:通用基础设施最小子包
|
|
22
|
+
- `pz_contrib/pz_settings_center/`:settings 最小子包
|
|
23
|
+
|
|
24
|
+
`pz run` 是最小完整能力。`pz` 是唯一可独立启动的基础仓,不再创建第二套 core、CLI 或宿主壳。
|
|
25
|
+
|
|
26
|
+
## 3. `pz_apps` 仓职责
|
|
27
|
+
|
|
28
|
+
`pz_apps/<app_id>/` 是其他正式最小子包的唯一源码位置。每个叶子项目统一满足:
|
|
29
|
+
|
|
30
|
+
- 目录名与 import 包名:`pz_<name>`
|
|
31
|
+
- distribution:`pz-<name>`
|
|
32
|
+
- `app_id`:`pz_<name>`
|
|
33
|
+
- 一个叶子目录对应一个可独立声明、安装和绑定的最小子包
|
|
34
|
+
|
|
35
|
+
单仓不等于统一 release:
|
|
36
|
+
|
|
37
|
+
- 每个叶子 `pyproject.toml [project].version` 独立决定该 distribution 的发布版本
|
|
38
|
+
- `pz pub <app_id>` 只提交目标叶子路径,并创建 `<distribution-name>@<version>` package tag
|
|
39
|
+
- `pz pub` 优先把精确匹配目标 distribution 的当前 Git 仓库根作为发布源,否则从宿主 `apps/.sources` 枚举 Git source-root 并复用正式 workspace 子包发现程序;只有精确根匹配或唯一叶子命中可以进入发布链
|
|
40
|
+
- 同一个 Git 仓库允许在不同 commit 上形成不同子包 release,也允许同一 commit 被多个精确 package tag 引用
|
|
41
|
+
- 其他子包的未提交修改不得进入目标 release commit;未归属任何叶子的 shared-root 未提交修改必须先人工收敛
|
|
42
|
+
- `pz pub` 不执行 `git push`,远端 commit/tag 同步属于显式 Git 或 CI 工作流
|
|
43
|
+
|
|
44
|
+
平台能力、站点能力和业务能力不再按旧仓名分组;它们都使用同一最小子包装配模型。
|
|
45
|
+
|
|
46
|
+
## 4. 宿主项目源码所有权与 checkout
|
|
47
|
+
|
|
48
|
+
宿主项目只使用以下正式布局:
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
<project>/
|
|
52
|
+
├── apps/
|
|
53
|
+
│ ├── <business-owned-app>/ # 业务仓拥有的真实最小子包
|
|
54
|
+
│ ├── .sources/
|
|
55
|
+
│ │ ├── manifest.json
|
|
56
|
+
│ │ ├── pz/ # pz Git checkout
|
|
57
|
+
│ │ └── pz_apps/ # pz_apps Git checkout
|
|
58
|
+
│ └── <binding> -> .sources/<repo>/<subpath>
|
|
59
|
+
├── .idea/ # 已存在时由 PyCharm 拥有
|
|
60
|
+
│ └── pz.generated.sources.iml # PZ 可重建 IDE 影子投影
|
|
61
|
+
├── .vscode/ # 已存在时由 VS Code/用户拥有
|
|
62
|
+
│ ├── settings.json # PZ 只拥有其插入的 analysis extraPaths
|
|
63
|
+
│ └── pz.generated.sources.json # PZ-owned entry 状态账本
|
|
64
|
+
└── pz.jsonc
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- `pz dev add <子包>` 把一个正式最小子包导入 `apps/<app_id>`,不保留嵌套 `.git`;导入后的源码由业务仓统一管理
|
|
68
|
+
- Git 输入默认读取 `develop` 分支;`pz dev source cache` 在当前用户隔离的 `<system-temp>/pz/users/<user-key>/git/` 维护可丢弃 checkout,cache root、lock、checkout 与 owner marker 必须验证 owner、权限和非符号链接。cache 命中时先 fetch,未命中时 staged clone,再以 canonical `repo_key`、full commit 与不可变 resolution ref 交给 `dev source import`;import 不得读取可移动 branch 或 `HEAD`
|
|
69
|
+
- 系统临时 Git cache 只用于减少网络与 clone 成本,不是项目源码、版本或运行时真相源;导入完成后 `apps/<app_id>` 才是业务代码的唯一真相源
|
|
70
|
+
- 默认 `pz dev init` 通过系统临时 Git cache 导入官方 `pz_apps` 的全部正式最小叶子,由业务仓管理;只有 `pz dev init --link --clone-sources` 或 `--link --source-dir <path>` 保留原 bootstrap linked scope
|
|
71
|
+
- `pz dev link <目录>` 在 `apps/` 创建目录 binding
|
|
72
|
+
- `pz dev link <子包>` 在 `apps/` 创建该子包 binding
|
|
73
|
+
- linked Git checkout 的项目入口永远位于 `apps/.sources/`;该入口可以是真实目录,也可以是指向项目外共享 Git checkout 的符号链接;`apps/` 只暴露宿主需要扫描的 binding
|
|
74
|
+
- `manifest.json` 是 linked repo checkout 与 binding 的唯一 authoring 真相源;它不登记业务仓拥有的真实本地 app
|
|
75
|
+
- 共享 checkout 的目标由外部所有;PZ 运行、同步和构建可以读取,authoring 命令不得修改其分支、refs 或工作区内容
|
|
76
|
+
- 发布发现可以读取共享 checkout;`pub commit` / `pub tag` 仍受上述只读所有权约束,必须在任何 Git mutation 前失败
|
|
77
|
+
- 同一个 `app_id` 不得同时存在业务仓真实目录与 linked binding;本地源码与已安装 distribution 同名时仍由本地源码优先
|
|
78
|
+
- `apps/.sources/repos/`、额外 wrapper、旧三仓 alias 都不是正式结构
|
|
79
|
+
- `.idea/pz.generated.sources.iml` 只把当前可见最小子包投影成 PyCharm source roots;它不复制源码、不参与运行时发现,也不是 repo、binding 或版本真相源
|
|
80
|
+
- `.vscode/settings.json` 中的 PZ entries 只把项目可见叶子路径加入 `python.analysis.extraPaths`;`pz.generated.sources.json` 只记录 PZ-owned entries,不是源码或装配真相源
|
|
81
|
+
- `pz dev ide sync` 是全部 IDE 投影的唯一原子 owner;它复用同一可见 app 投影并委托 PyCharm/VS Code provider,`dev add/link/unlink/branch/update` 作为编排命令在源码、settings 与环境原子阶段之后调用它
|
|
82
|
+
|
|
83
|
+
## 5. 分支安全合同
|
|
84
|
+
|
|
85
|
+
`pz dev link` 在写入 binding 前必须原子地确保受管 checkout 位于当前业务分支:
|
|
86
|
+
|
|
87
|
+
- 业务分支名默认取宿主项目目录名,也可显式指定
|
|
88
|
+
- 基线分支默认是 `develop`
|
|
89
|
+
- 调用方可显式指定从 `main` 创建业务分支
|
|
90
|
+
- 不允许在 `develop` 或 `main` 上直接承载当前业务修改
|
|
91
|
+
- checkout、切分支、manifest 更新与 `apps/` 快捷方式更新必须作为一个可回滚事务完成
|
|
92
|
+
|
|
93
|
+
`pz dev add` 的业务接管流程不保留上游 checkout:Git 来源默认从 `develop` 分支解析;`dev source cache` 先更新或创建系统临时 cache 并固定 full commit,`dev source import` 再从该 commit 导出源码。导出的源码先在 `apps/` 同文件系统隐藏目录完成校验,再原子落位到 `apps/<app_id>`。cache 更新失败不得静默使用陈旧 revision,导入失败不得留下半成品目录或项目装配残留。
|
|
94
|
+
|
|
95
|
+
## 6. 运行时边界
|
|
96
|
+
|
|
97
|
+
- 运行时只识别最小子包,不识别 Git 仓名或旧 platform/site-runtime namespace
|
|
98
|
+
- `installed_apps` 是装配顺序的唯一真相源
|
|
99
|
+
- 项目源码优先于环境 distribution,同一个 `app_id` 在项目源码范围内只能有一个正式来源
|
|
100
|
+
- 业务仓拥有的真实本地 app 与 linked binding 在运行时平权;差别只在作者面所有权和更新协议
|
|
101
|
+
- `.runtime/`、cache、merged resources、构建目录都是派生产物,不是源码修改入口
|
|
102
|
+
- 新实现只能落在对应最小子包、`pz_core` 稳定合同边界或明确的 `pz_contrib` 基础能力中
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# 构建与发布检查清单
|
|
2
|
+
|
|
3
|
+
本文档用于固定当前 `pz` 基础包构建、测试与发布前检查流程,避免后续误用环境导致“本地可跑但分发失败”。
|
|
4
|
+
|
|
5
|
+
适用范围:
|
|
6
|
+
|
|
7
|
+
- 根包构建与 wheel 分发
|
|
8
|
+
- 最小子包 `<app_id>` 的发布前 smoke 验证原则
|
|
9
|
+
|
|
10
|
+
补充边界:
|
|
11
|
+
|
|
12
|
+
- 本文只定义 `pz` 基础包发布门禁与最小子包 smoke 原则
|
|
13
|
+
- 官方最小子包 `<app_id>` 不属于 `pz` 基础包本体
|
|
14
|
+
- 若采用并列源码组织根布局,官方维护最小子包真相源位于 `pz/pz_contrib/<app_id>/`
|
|
15
|
+
- 因此 `pz` 基础包 wheel 的发布门禁,与各最小子包自己的发布门禁必须分开执行,不能误把官方 `pz_*` 子包当成基础包内建内容
|
|
16
|
+
|
|
17
|
+
## 1. 标准执行顺序
|
|
18
|
+
|
|
19
|
+
发布前固定按下面顺序执行,不要跳步:
|
|
20
|
+
|
|
21
|
+
1. 版本与 scope 检查:目标子包 `project.version` 明确,Git index clean,release scope 只包含目标最小子包
|
|
22
|
+
2. 依赖锁检查:`uv lock --check`
|
|
23
|
+
3. 测试回归:运行当前关键 pytest 集合
|
|
24
|
+
4. release commit:`pz pub commit <app_id>`
|
|
25
|
+
5. package tag:`pz pub tag <app_id>`
|
|
26
|
+
6. 从 tag commit 构建、校验 wheel metadata、执行干净 venv 安装/导入 smoke,最后上传:`pz pub upload <app_id>`
|
|
27
|
+
7. 从目标 index 安装已发布版本并完成远端闭环 smoke
|
|
28
|
+
|
|
29
|
+
日常正式入口仍是 `pz pub <app_id>`,由它按固定顺序编排第 4 至第 6 步。原子命令用于单步验证、失败续跑和自动化测试。
|
|
30
|
+
|
|
31
|
+
## 2. 标准命令
|
|
32
|
+
|
|
33
|
+
在仓库根执行:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
uv lock --check
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
关键测试集:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
python -m pytest tests
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
构建 wheel:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
uv build
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
当前正式口径不再依赖外部 `verify_install_chain.sh`;完成 `uv build` 后,继续执行下文的干净 venv 安装与导入 smoke。
|
|
52
|
+
|
|
53
|
+
### 2.1 `pz` core wheel smoke
|
|
54
|
+
|
|
55
|
+
`pz` 核心仓只验证 core wheel 自身:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
repo_root="$(pwd)"
|
|
59
|
+
wheel_path="$(ls dist/pz-*.whl | tail -n 1)"
|
|
60
|
+
rm -rf /tmp/pz-wheel-smoke-verify
|
|
61
|
+
python3 -m venv /tmp/pz-wheel-smoke-verify
|
|
62
|
+
/tmp/pz-wheel-smoke-verify/bin/python -m pip install --upgrade pip
|
|
63
|
+
/tmp/pz-wheel-smoke-verify/bin/pip install "$repo_root/$wheel_path"
|
|
64
|
+
|
|
65
|
+
cd /tmp
|
|
66
|
+
/tmp/pz-wheel-smoke-verify/bin/python - <<'PY'
|
|
67
|
+
import importlib
|
|
68
|
+
modules = [
|
|
69
|
+
"pz",
|
|
70
|
+
"pz.app",
|
|
71
|
+
"pz.runtime",
|
|
72
|
+
"pz.runtime.http",
|
|
73
|
+
"pz.runtime.facades",
|
|
74
|
+
"pz.runtime.cli.main",
|
|
75
|
+
]
|
|
76
|
+
failed = []
|
|
77
|
+
for m in modules:
|
|
78
|
+
try:
|
|
79
|
+
importlib.import_module(m)
|
|
80
|
+
print("OK", m)
|
|
81
|
+
except Exception as e:
|
|
82
|
+
failed.append((m, repr(e)))
|
|
83
|
+
print("FAIL", m, repr(e))
|
|
84
|
+
print(f"TOTAL_OK={len(modules)-len(failed)} TOTAL_FAIL={len(failed)}")
|
|
85
|
+
if failed:
|
|
86
|
+
raise SystemExit(1)
|
|
87
|
+
PY
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 2.2 最小子包 smoke
|
|
91
|
+
|
|
92
|
+
最小子包的导入 smoke 不属于 core wheel 本体,而属于对应子包发布链。若当前工作区采用分仓布局,则应在对应子包 wheel 安装后,按当前发布 manifest / `installed_apps` 枚举验证:
|
|
93
|
+
|
|
94
|
+
- `<apps_workspace>/apps`
|
|
95
|
+
|
|
96
|
+
对应 app 构建产物安装后验证:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# 该检查在最小子包 wheel 安装后执行,而不是要求 pz core wheel 内建这些模块。
|
|
100
|
+
cd /tmp
|
|
101
|
+
/tmp/pz-wheel-smoke-verify/bin/python - <<'PY'
|
|
102
|
+
import importlib
|
|
103
|
+
modules = [line.strip() for line in open("/tmp/pz-app-imports.txt") if line.strip()]
|
|
104
|
+
failed = []
|
|
105
|
+
for m in modules:
|
|
106
|
+
try:
|
|
107
|
+
importlib.import_module(m)
|
|
108
|
+
print("OK", m)
|
|
109
|
+
except Exception as e:
|
|
110
|
+
failed.append((m, repr(e)))
|
|
111
|
+
print("FAIL", m, repr(e))
|
|
112
|
+
print(f"TOTAL_OK={len(modules)-len(failed)} TOTAL_FAIL={len(failed)}")
|
|
113
|
+
if failed:
|
|
114
|
+
raise SystemExit(1)
|
|
115
|
+
PY
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## 3. 发布前必须检查项
|
|
119
|
+
|
|
120
|
+
- 当前目录可作为发布源的前提是它本身为 Git root 且根 distribution 精确匹配目标;否则 `apps/.sources` 必须存在可用 Git source-root 并唯一找到目标子包;业务复制目录不能替代发布源
|
|
121
|
+
- Git HEAD 必须附着在分支上,Git author identity 必须已配置
|
|
122
|
+
- Git index 必须 clean;目标子包之外的 staged 内容直接阻止发布
|
|
123
|
+
- 根 distribution 的 release commit 使用显式 `.` 整仓 scope;嵌套子包只能包含目标路径,其他最小子包 unstaged 修改必须保持不变
|
|
124
|
+
- 未归属任何正式最小子包的 shared-root 未提交文件属于歧义 scope,必须先人工收敛
|
|
125
|
+
- tag、tagged tree 的 `project.version`、wheel distribution/version metadata 必须完全一致
|
|
126
|
+
- build/upload 必须要求当前 checkout clean 且 HEAD 精确等于 package tag commit,并从当前 package root 直接执行;不得创建临时 worktree
|
|
127
|
+
- package wheel 的干净 venv 安装/import smoke 必须在远端 upload 前通过
|
|
128
|
+
- `uv lock --check` 必须通过
|
|
129
|
+
- 关键测试集必须全绿(允许已知非阻塞 warning)
|
|
130
|
+
- `uv build` 必须成功
|
|
131
|
+
- `pz` core wheel 的干净 venv smoke 必须 `TOTAL_FAIL=0`
|
|
132
|
+
- 最小子包若声明额外稳定 import surface,必须在该子包自己的发布文档与测试中验证;core 发布门禁不得硬编码具体子包模块清单
|
|
133
|
+
- `pz pub` 不执行 `git push`;release commit 与 tag 的远端推送属于显式 Git/CI 步骤
|
|
134
|
+
- upload 失败后保留 release commit 与 tag;重跑通过精确匹配续跑,不 reset、amend 或删除 tag
|
|
135
|
+
|
|
136
|
+
## 4. 常见误区与规避
|
|
137
|
+
|
|
138
|
+
### 4.1 repo root `cwd/PYTHONPATH` 遮蔽
|
|
139
|
+
|
|
140
|
+
问题现象:
|
|
141
|
+
|
|
142
|
+
- 在 `cwd=<repo_root>` 或 `PYTHONPATH=<repo_root>` 下,可能命中源码树中的旧目录,导致导入行为与 wheel 安装后不一致。
|
|
143
|
+
|
|
144
|
+
规避方式:
|
|
145
|
+
|
|
146
|
+
- wheel smoke 一律在干净 venv + `/tmp` 下执行
|
|
147
|
+
- 导入 smoke 时不要把 repo root 放进 `PYTHONPATH`
|
|
148
|
+
|
|
149
|
+
### 4.2 误把非正式目录当真相源
|
|
150
|
+
|
|
151
|
+
问题现象:
|
|
152
|
+
|
|
153
|
+
- 直接在基础包内部薄绑定层或其它非正式目录增加业务逻辑,会重新引入双真相源。
|
|
154
|
+
|
|
155
|
+
规避方式:
|
|
156
|
+
|
|
157
|
+
- 真相源优先写到对应 `<app_id>/` 最小子包或 `pz/` 基础包主链必要边界
|
|
158
|
+
- `pz/infra/*` 与其它非正式目录不作为业务实现真相源
|
|
159
|
+
|
|
160
|
+
### 4.3 修改 `pyproject.toml` 后漏更新锁文件
|
|
161
|
+
|
|
162
|
+
规避方式:
|
|
163
|
+
|
|
164
|
+
- 任何依赖变更后都执行并提交 `uv lock` 结果
|
|
165
|
+
- 发布前必须再次运行 `uv lock --check`
|
|
166
|
+
|
|
167
|
+
## 5. 失败定位建议
|
|
168
|
+
|
|
169
|
+
- `wheel 构建失败`:先看 `pyproject.toml` 打包规则与 `force-include` 映射
|
|
170
|
+
- `venv 导入失败但本地源码可导入`:优先怀疑 `cwd/PYTHONPATH` 遮蔽,不要先改业务代码
|
|
171
|
+
- `最小子包稳定 import surface 导入失败`:先检查 wheel zip 中对应路径是否存在,再检查安装后 `site-packages` 布局
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
# 正式 Facade 总表
|
|
2
|
+
|
|
3
|
+
## 1. 目的
|
|
4
|
+
|
|
5
|
+
本文件用于把新架构中的正式 `Facade` 名称、职责和边界统一收口。
|
|
6
|
+
|
|
7
|
+
原则:
|
|
8
|
+
|
|
9
|
+
- 同一类公共运行能力,只允许一个正式 `Facade`
|
|
10
|
+
- `Facade` 是外部调用面,不是内部实现目录名
|
|
11
|
+
- app 的正式运行时依赖面是 facade 或其它 app 的 `public.py`,不是 runtime registry 本身
|
|
12
|
+
|
|
13
|
+
## 2. 正式 Facade 命名规则
|
|
14
|
+
|
|
15
|
+
统一规则:
|
|
16
|
+
|
|
17
|
+
- 对外公共能力统一命名为 `XxxFacade`
|
|
18
|
+
|
|
19
|
+
禁止作为正式公共边界的名称:
|
|
20
|
+
|
|
21
|
+
- `manager`
|
|
22
|
+
- `service`
|
|
23
|
+
- `helper`
|
|
24
|
+
- `sdk`
|
|
25
|
+
|
|
26
|
+
## 3. 正式 Facade 总表
|
|
27
|
+
|
|
28
|
+
### 3.1 `ObservabilityFacade`
|
|
29
|
+
|
|
30
|
+
职责:
|
|
31
|
+
|
|
32
|
+
- 暴露 logger / metrics / tracing 的统一访问面
|
|
33
|
+
|
|
34
|
+
最小稳定方法面:
|
|
35
|
+
|
|
36
|
+
- `status()`
|
|
37
|
+
- `logger(name: str)`
|
|
38
|
+
- `counter(name: str, *, unit: str | None = None, description: str | None = None)`
|
|
39
|
+
- `histogram(name: str, *, unit: str | None = None, description: str | None = None)`
|
|
40
|
+
- `span(name: str, *, attributes: dict[str, object] | None = None)`
|
|
41
|
+
|
|
42
|
+
不负责:
|
|
43
|
+
|
|
44
|
+
- Prometheus server 部署
|
|
45
|
+
- Bot handler 部署
|
|
46
|
+
- 监控平台拓扑
|
|
47
|
+
|
|
48
|
+
返回语义约束:
|
|
49
|
+
|
|
50
|
+
- `logger(name)` 只返回当前 runtime 作用域内的 logger 句柄,不得隐式重配 root logger、monkey patch `logging.Logger` 或创建文件输出目录
|
|
51
|
+
- `counter()` / `histogram()` 在 metrics disabled 场景下返回可审计的 noop handle,而不是偷偷绑定默认全局 registry
|
|
52
|
+
- observability facade 若暴露 bot/告警能力,其发送失败、丢弃与降级语义必须可区分
|
|
53
|
+
|
|
54
|
+
### 3.2 `DatabaseFacade`
|
|
55
|
+
|
|
56
|
+
职责:
|
|
57
|
+
|
|
58
|
+
- 暴露 DB capability 的统一访问面
|
|
59
|
+
|
|
60
|
+
最小稳定方法面:
|
|
61
|
+
|
|
62
|
+
- `status()`
|
|
63
|
+
- `connection()`
|
|
64
|
+
- `session()`
|
|
65
|
+
- `transaction()`
|
|
66
|
+
|
|
67
|
+
不负责:
|
|
68
|
+
|
|
69
|
+
- 迁移归属裁决
|
|
70
|
+
- Web startup 隐式建表
|
|
71
|
+
|
|
72
|
+
### 3.3 `CacheFacade`
|
|
73
|
+
|
|
74
|
+
职责:
|
|
75
|
+
|
|
76
|
+
- 暴露 Redis/cache/L2 相关 capability 的统一访问面
|
|
77
|
+
|
|
78
|
+
最小稳定方法面:
|
|
79
|
+
|
|
80
|
+
- `status()`
|
|
81
|
+
- `get(key: str)`
|
|
82
|
+
- `set(key: str, value: object, *, ttl: int | None = None)`
|
|
83
|
+
- `delete(key: str)`
|
|
84
|
+
- `lock(key: str, *, ttl: int | None = None)`
|
|
85
|
+
|
|
86
|
+
不负责:
|
|
87
|
+
|
|
88
|
+
- 默认回落本机 Redis
|
|
89
|
+
- 把测试替身混入正式运行模型
|
|
90
|
+
|
|
91
|
+
### 3.4 `StorageFacade`
|
|
92
|
+
|
|
93
|
+
职责:
|
|
94
|
+
|
|
95
|
+
- 暴露对象存储/本地存储的统一访问面
|
|
96
|
+
|
|
97
|
+
最小稳定方法面:
|
|
98
|
+
|
|
99
|
+
- `status()`
|
|
100
|
+
- `open(key: str, *, mode: str = "rb")`
|
|
101
|
+
- `save(key: str, payload: object, *, content_type: str | None = None, metadata: dict[str, str] | None = None)`
|
|
102
|
+
- `delete(key: str)`
|
|
103
|
+
- `url(key: str, *, expires_in: int | None = None, download_name: str | None = None)`
|
|
104
|
+
- `presign(key: str, *, method: str = "GET", expires_in: int | None = None)`
|
|
105
|
+
|
|
106
|
+
不负责:
|
|
107
|
+
|
|
108
|
+
- 具体云厂商实现内建
|
|
109
|
+
- 业务 object key 命名规则
|
|
110
|
+
|
|
111
|
+
返回语义约束:
|
|
112
|
+
|
|
113
|
+
- `url()` 只有在当前 backend 具备正式公共访问语义时才返回可公开消费的 URL
|
|
114
|
+
- 无公共访问入口时,`url()` 必须返回 `None` 或显式能力错误
|
|
115
|
+
- 不得把宿主机绝对路径、相对路径或 `file://` 暴露成正式公共 URL 契约
|
|
116
|
+
- `presign()` 只表达上传/下载授权,不隐含“对象可被公开访问”的语义
|
|
117
|
+
|
|
118
|
+
### 3.5 `MailFacade`
|
|
119
|
+
|
|
120
|
+
职责:
|
|
121
|
+
|
|
122
|
+
- 暴露 mail/notification 的统一访问面
|
|
123
|
+
|
|
124
|
+
最小稳定方法面:
|
|
125
|
+
|
|
126
|
+
- `status()`
|
|
127
|
+
- `render(template: str, context: dict[str, object], *, locale: str | None = None)`
|
|
128
|
+
- `send(message: object)`
|
|
129
|
+
- `enqueue(message: object)`
|
|
130
|
+
|
|
131
|
+
不负责:
|
|
132
|
+
|
|
133
|
+
- 具体 SMTP/custom provider 的内建实现
|
|
134
|
+
- 把邮件能力伪装成 core 必选项
|
|
135
|
+
|
|
136
|
+
返回语义约束:
|
|
137
|
+
|
|
138
|
+
- `send()` / `enqueue()` 的结果必须能区分:
|
|
139
|
+
- 已提交给正式 provider
|
|
140
|
+
- provider 不可用
|
|
141
|
+
- 仅做本地日志降级
|
|
142
|
+
- 若允许备用 provider,备用链必须是显式配置,而不是隐式多级尝试
|
|
143
|
+
- 不得把“仅记录日志”伪装成正式投递成功
|
|
144
|
+
|
|
145
|
+
### 3.6 `I18nFacade`
|
|
146
|
+
|
|
147
|
+
职责:
|
|
148
|
+
|
|
149
|
+
- 暴露展示层翻译、语言元数据、语言解析能力
|
|
150
|
+
|
|
151
|
+
不负责:
|
|
152
|
+
|
|
153
|
+
- 作为基础设施 capability 常驻在 `infra`
|
|
154
|
+
|
|
155
|
+
### 3.7 `ResourceFacade`
|
|
156
|
+
|
|
157
|
+
职责:
|
|
158
|
+
|
|
159
|
+
- 暴露资源读取的统一访问面
|
|
160
|
+
|
|
161
|
+
不负责:
|
|
162
|
+
|
|
163
|
+
- 运行期再次 merge 资源
|
|
164
|
+
- repo-root/path 猜测
|
|
165
|
+
|
|
166
|
+
### 3.8 `HealthFacade`
|
|
167
|
+
|
|
168
|
+
职责:
|
|
169
|
+
|
|
170
|
+
- 暴露 liveness / readiness 的统一聚合面
|
|
171
|
+
|
|
172
|
+
最小稳定方法面:
|
|
173
|
+
|
|
174
|
+
- `liveness()`
|
|
175
|
+
- `readiness()`
|
|
176
|
+
- `capabilities()`
|
|
177
|
+
|
|
178
|
+
不负责:
|
|
179
|
+
|
|
180
|
+
- 隐式初始化 DB/Redis
|
|
181
|
+
- 混入 debug/dev surface
|
|
182
|
+
|
|
183
|
+
### 3.9 平台 app Facade
|
|
184
|
+
|
|
185
|
+
以下能力不属于 core/infra 默认 facade,但必须由对应平台 app 提供正式 facade:
|
|
186
|
+
|
|
187
|
+
- `SiteUiFacade`
|
|
188
|
+
- `ConfigFacade`
|
|
189
|
+
- `TaskFacade`
|
|
190
|
+
- `AuthFacade`
|
|
191
|
+
- `RedirectsFacade`
|
|
192
|
+
|
|
193
|
+
原则:
|
|
194
|
+
|
|
195
|
+
- 这些 facade 统一放在对应 app 的 `public.py`
|
|
196
|
+
- 外部 app 只能通过 `public.py` 依赖
|
|
197
|
+
|
|
198
|
+
### 3.10 Official infra owner public surface
|
|
199
|
+
|
|
200
|
+
official infra owner 的 `public.py` 只允许导出以下 facade:
|
|
201
|
+
|
|
202
|
+
- `DatabaseFacade`
|
|
203
|
+
- `CacheFacade`
|
|
204
|
+
- `StorageFacade`
|
|
205
|
+
- `MailFacade`
|
|
206
|
+
- `ObservabilityFacade`
|
|
207
|
+
- `HealthFacade`
|
|
208
|
+
|
|
209
|
+
补充约束:
|
|
210
|
+
|
|
211
|
+
- `I18nFacade` 不放在 infra owner `public.py`,仍归 shared site UI owner 或展示层平台 app
|
|
212
|
+
- infra owner `public.py` 只暴露稳定 facade,不暴露内部 `db/kv/storage/...` 目录
|
|
213
|
+
- 若未来某项基础能力从 infra owner 拆出独立子包,应先保持 facade 名称不变,再调整实现归属
|
|
214
|
+
|
|
215
|
+
## 4. Facade 与其它构件的关系
|
|
216
|
+
|
|
217
|
+
- `Compiler` 负责裁决与产出计划;`Facade` 不负责裁决
|
|
218
|
+
- `Registry` 负责索引与查找;`Facade` 负责对外暴露稳定调用面
|
|
219
|
+
- `Provider` 负责具体绑定实现;`Facade` 屏蔽 provider 差异
|
|
220
|
+
- `Adapter` 负责翻译第三方库细节;`Facade` 不直接暴露底层第三方库对象
|
|
221
|
+
|
|
222
|
+
## 5. 正式 Capability 总表
|
|
223
|
+
|
|
224
|
+
### 5.1 capability 的正式定义
|
|
225
|
+
|
|
226
|
+
capability 表示:
|
|
227
|
+
|
|
228
|
+
- 当前运行图中某类能力是否存在
|
|
229
|
+
- 是否启用
|
|
230
|
+
- 是否已经 ready
|
|
231
|
+
- 若不可用,为什么不可用
|
|
232
|
+
|
|
233
|
+
capability 不是:
|
|
234
|
+
|
|
235
|
+
- 某个具体模块路径
|
|
236
|
+
- 某个默认单例对象
|
|
237
|
+
- 某个具体官方 app / 独立子包名称
|
|
238
|
+
|
|
239
|
+
补充裁决:
|
|
240
|
+
|
|
241
|
+
- `CapabilityRegistry` 是 capability 的内部承载容器,不是 app 稳定公共 API
|
|
242
|
+
- app 消费 capability 时,应通过 facade 暴露的状态语义或稳定 capability contract,而不是直接依赖 registry 内部结构
|
|
243
|
+
|
|
244
|
+
### 5.2 capability 的统一状态语义
|
|
245
|
+
|
|
246
|
+
所有正式 capability 统一使用以下状态:
|
|
247
|
+
|
|
248
|
+
- `disabled`
|
|
249
|
+
- `enabled`
|
|
250
|
+
- `ready`
|
|
251
|
+
- `unavailable`
|
|
252
|
+
|
|
253
|
+
语义固定为:
|
|
254
|
+
|
|
255
|
+
- `disabled`
|
|
256
|
+
- 配置明确关闭,或当前运行图未声明该能力
|
|
257
|
+
- `enabled`
|
|
258
|
+
- 能力已被声明启用,但底层 provider/client 尚未进入 ready
|
|
259
|
+
- `ready`
|
|
260
|
+
- 能力可被正式消费
|
|
261
|
+
- `unavailable`
|
|
262
|
+
- 能力按配置需要存在,但由于缺驱动、缺 provider、连接失败、初始化失败而当前不可用
|
|
263
|
+
|
|
264
|
+
禁止:
|
|
265
|
+
|
|
266
|
+
- 用空对象、默认 localhost、静默 no-op 伪装成 `ready`
|
|
267
|
+
- 把不同失败原因都吞成同一个“best effort 成功”
|
|
268
|
+
|
|
269
|
+
补充约束:
|
|
270
|
+
|
|
271
|
+
- 除 `HealthFacade` 外,基础能力 facade 的最小稳定方法面都必须包含 `status()`
|
|
272
|
+
- `status()` 只能返回上述正式状态语义,不能返回 provider 私有枚举或底层 client 对象
|
|
273
|
+
|
|
274
|
+
### 5.3 capability 生命周期
|
|
275
|
+
|
|
276
|
+
统一固定为:
|
|
277
|
+
|
|
278
|
+
1. `SettingsSnapshot` 编译 capability 配置
|
|
279
|
+
2. `InfraSettings` / app 声明编译 capability 状态
|
|
280
|
+
3. `CapabilityRegistry` 挂入运行图
|
|
281
|
+
4. 执行阶段创建 provider/client
|
|
282
|
+
5. 状态推进到 `ready` 或 `unavailable`
|
|
283
|
+
6. shutdown 阶段对称清理
|
|
284
|
+
|
|
285
|
+
### 5.4 capability 总表
|
|
286
|
+
|
|
287
|
+
边界:
|
|
288
|
+
|
|
289
|
+
- `observability` 是 facade 组,不是单独 capability 名称;底层正式 capability 仍是 `metrics` / `tracing` 及对应 logging provider 绑定
|
|
290
|
+
- `i18n` 不单列为 core/infra capability;展示层语言与翻译能力归属 shared site UI owner 或正式 site/runtime bundle
|
|
291
|
+
|
|
292
|
+
`database`
|
|
293
|
+
|
|
294
|
+
- 来源:`InfraContext`
|
|
295
|
+
- 编译输入:owner app 的 `infra.provider` 输出;例如 `settings_center.settings.<infra_owner>.database`
|
|
296
|
+
- 消费方:`DatabaseFacade`、readiness、DB CLI、ORM adapter
|
|
297
|
+
- 正式要求:支持 SQLite / MySQL / PostgreSQL;未启用时状态必须是 `disabled`;缺驱动或连通失败时是 `unavailable`
|
|
298
|
+
|
|
299
|
+
`cache`
|
|
300
|
+
|
|
301
|
+
- 来源:`InfraContext`
|
|
302
|
+
- 编译输入:owner app 的 `infra.provider` 输出;例如 `settings_center.settings.<infra_owner>.cache`
|
|
303
|
+
- 消费方:`CacheFacade`、锁/版本/L2 逻辑、readiness
|
|
304
|
+
- 正式要求:不再默认回落本机 Redis;local-only 与 unavailable 语义必须可区分
|
|
305
|
+
|
|
306
|
+
`mail`
|
|
307
|
+
|
|
308
|
+
- 来源:`InfraContext`
|
|
309
|
+
- 编译输入:owner app 的 `infra.provider` 输出;例如 `settings_center.settings.<infra_owner>.mail`
|
|
310
|
+
- 消费方:`MailFacade`、auth/task 等需要邮件能力的 app
|
|
311
|
+
- 正式要求:mail 是可选 capability;SMTP/custom mail provider 只是 provider 实现,不是 capability 本身
|
|
312
|
+
|
|
313
|
+
`metrics`
|
|
314
|
+
|
|
315
|
+
- 来源:`InfraContext`
|
|
316
|
+
- 编译输入:owner app 的 `infra.provider` 输出;例如 `settings_center.settings.<infra_owner>.observability.metrics`
|
|
317
|
+
- 消费方:`ObservabilityFacade`、exporter route、readiness 诊断
|
|
318
|
+
- 正式要求:当前唯一正式 exporter 是 Prometheus;exporter 关闭时 capability 可 `disabled`;exporter 不可用时不应拖垮主请求路径
|
|
319
|
+
|
|
320
|
+
`tracing`
|
|
321
|
+
|
|
322
|
+
- 来源:`InfraContext`
|
|
323
|
+
- 编译输入:owner app 的 `infra.provider` 输出;例如 `settings_center.settings.<infra_owner>.observability.tracing`
|
|
324
|
+
- 消费方:`ObservabilityFacade`
|
|
325
|
+
- 正式要求:tracing 必须低侵入;exporter 不可用时应落到 `unavailable` 或 graceful no-op
|
|
326
|
+
|
|
327
|
+
`storage`
|
|
328
|
+
|
|
329
|
+
- 来源:provider binding + app/project 声明
|
|
330
|
+
- 编译输入:owner app 的 `infra.provider` 输出;例如 `settings_center.settings.<infra_owner>.storage`
|
|
331
|
+
- 消费方:`StorageFacade`、file/asset/media 相关 app
|
|
332
|
+
- 正式要求:`StoragePort` 是稳定抽象;local/s3/gcs 只是 provider 差异
|
|
333
|
+
|
|
334
|
+
`resources`
|
|
335
|
+
|
|
336
|
+
- 来源:`ResourceManifest`
|
|
337
|
+
- 编译输入:installed apps、`resources.items`、`ProjectContext`
|
|
338
|
+
- 消费方:`ResourceFacade`、template/static/locales/migrations 读取方
|
|
339
|
+
- 正式要求:编译结果唯一真相源是 manifest;运行期不再二次 merge
|
|
340
|
+
- 正式结果:`ResourceManifest.items` 统一承载每个资源项的 `name / source_dirs / output_dir`
|
|
341
|
+
|
|
342
|
+
`health`
|
|
343
|
+
|
|
344
|
+
- 来源:`RuntimePlan`、`CapabilityRegistry`
|
|
345
|
+
- 消费方:`HealthFacade`、liveness/readiness route
|
|
346
|
+
- 正式要求:health 是 capability 聚合视图;不再自己维护第二套 infra 判定逻辑
|
|
347
|
+
|
|
348
|
+
`shared_site_ui`
|
|
349
|
+
|
|
350
|
+
- 来源:shared site UI owner 声明
|
|
351
|
+
- 消费方:模板渲染、i18n 展示能力、站点上下文能力
|
|
352
|
+
- 正式要求:这是平台 capability,不是 core 内建事实;若缺失,应明确报 capability 缺失;i18n 展示能力、语言元数据、模板语言解析都归属该平台 capability 或对应 site/runtime bundle
|
|
353
|
+
|
|
354
|
+
`config`
|
|
355
|
+
|
|
356
|
+
- 来源:settings runtime owner 或替代平台 app
|
|
357
|
+
- 消费方:模块配置读取、settings overrides/L2
|
|
358
|
+
- 正式要求:provider/loader 必须有 owner/scope/reset;不能继续通过全局 setter 写进 `infra.ports`
|
|
359
|
+
|
|
360
|
+
`task`
|
|
361
|
+
|
|
362
|
+
- 来源:task dispatch / worker owner 或替代平台 app
|
|
363
|
+
- 消费方:worker SDK、scheduler/reclaimer、task dispatch
|
|
364
|
+
- 正式要求:任务能力不是 core 必选项;若依赖 Redis,应显式体现在 capability 状态里
|
|
365
|
+
|
|
366
|
+
`auth`
|
|
367
|
+
|
|
368
|
+
- 来源:auth owner 或替代平台 app
|
|
369
|
+
- 消费方:当前用户解析、admin checker、auth middleware/pages
|
|
370
|
+
- 正式要求:user resolver / admin checker 通过正式 facade 暴露;不能继续通过 `infra.ports` 全局 setter 暴露
|
|
371
|
+
|
|
372
|
+
### 5.5 capability 的唯一编译与消费路径
|
|
373
|
+
|
|
374
|
+
正式路径固定为:
|
|
375
|
+
|
|
376
|
+
1. 配置编译出 typed snapshot
|
|
377
|
+
2. 运行图编译出 capability 状态
|
|
378
|
+
3. `CapabilityRegistry` 统一暴露 capability
|
|
379
|
+
4. facade 统一消费 capability
|
|
380
|
+
5. Web / CLI / worker / checks 复用同一份 capability 状态
|
|
381
|
+
|
|
382
|
+
不允许:
|
|
383
|
+
|
|
384
|
+
- readiness 再自己判断一次
|
|
385
|
+
|
|
386
|
+
## 6. 正式要求
|
|
387
|
+
|
|
388
|
+
- app 不得直接 import `pz.infra.*` 私有实现获取能力
|
|
389
|
+
- app 统一通过 facade、request/runtime helper、或其它 app 的 `public.py` 获取能力
|
|
390
|
+
- 同一类能力不能同时出现 `manager`、`service`、`facade` 三套公共入口
|
|
391
|
+
|
|
392
|
+
补充约束:
|
|
393
|
+
|
|
394
|
+
- `CapabilityRegistry` 是 `RuntimePlan` 的内部运行图对象,不是 app 稳定公共依赖面
|
|
395
|
+
- app 判断某能力是否存在时,应通过 facade 暴露的状态语义或稳定 capability contract,而不是直接抓取 registry 内部结构
|
|
396
|
+
- 只有 runtime / entrypoint / facade 组装层可以直接持有并遍历 `CapabilityRegistry`
|
|
397
|
+
|
|
398
|
+
## 7. 公开入口原则
|
|
399
|
+
|
|
400
|
+
`Facade` 是新架构的唯一公共运行能力入口。
|
|
401
|
+
|
|
402
|
+
如果某个能力还需要调用方直接 import 内部 `manager`、默认单例、或直接依赖 `CapabilityRegistry` 的内部结构,说明该能力的 facade 还没有真正建立完成。
|