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,1073 @@
|
|
|
1
|
+
# legacy_core 标准 pip 包化重构总纲
|
|
2
|
+
|
|
3
|
+
> 历史说明:本文保留 `legacy_core` 字样,仅用于记录 `legacy_core -> pz` 的迁移背景、旧方案与治理禁区;当前正式基础包统一为 `pz`。
|
|
4
|
+
|
|
5
|
+
> settings 统一口径:Python 运行时代码只允许 `import pz_settings_center.public as settings_center`,并通过 `settings_center.settings.<app_id>.<field>` 读取;`settings.py` / `settings/` 只负责声明。
|
|
6
|
+
> namespace 统一口径:每个正式最小子包都必须有稳定唯一的 `app.id`;新建子包默认让目录名、import 包名与 `app.id` 对齐,distribution 使用对应的 Python 分发名;不强制特定技术前缀;没有叶子 app 身份的内部模块不得自定义 namespace。
|
|
7
|
+
|
|
8
|
+
## 0. 资源覆盖正式结论
|
|
9
|
+
|
|
10
|
+
- PZ 资源层是 Django 式同名覆盖:资源覆盖是文件级覆盖,顺序只看 `installed_apps`,后出现 app 覆盖前者同相对路径。
|
|
11
|
+
|
|
12
|
+
## 0. 架构公约
|
|
13
|
+
|
|
14
|
+
本次及后续所有 `pz` 架构设计,统一服从下面这条最高优先级公约:
|
|
15
|
+
|
|
16
|
+
- 系统里真正存在的正式单位,只有最小子包。
|
|
17
|
+
- `pz` 是职责特殊的基础包:它只负责稳定合同、发现、编译、组装与启动其他最小子包。
|
|
18
|
+
- settings surface owner 是职责专门的最小子包:它只负责应用层 settings surface、project/app settings 读取面与相关正式注册入口;其物理源码落位由 owning 子包文档和仓库真相源地图维护。
|
|
19
|
+
- `pz_framework`、`pz_apps`、`pz_apps`、`customerhub` 这类顶层源码组织根只用于 Git 与源码组织,不再是正式架构层,不再进入运行时 namespace。
|
|
20
|
+
- 正式运行时身份必须收敛到最小子包本身,不允许再通过集合层目录表达正式依赖关系。
|
|
21
|
+
- `installed_apps` 的唯一正式语法固定为“写目录名”,不写文件系统路径、不写 distribution 名、不写 `<pkg>.apps:app`。
|
|
22
|
+
- 每个最小子包统一采用一套命名规则:
|
|
23
|
+
- `app_id = <app_id>`
|
|
24
|
+
- 目录名 = `<app_id>`
|
|
25
|
+
- import 包名 = `<app_id>`
|
|
26
|
+
- distribution = `<app_id with _ replaced by ->`
|
|
27
|
+
- 新建子包默认让目录名、import 包名与 `app_id` 对齐;历史稳定 `app_id` 以已声明值为准,不因文档命名口径变化迁移。
|
|
28
|
+
- 正式命名不强制 `pz`、`pz` 或其它特定技术前缀;不得再保留“什么时候加前缀、什么时候不加”的第二套规则。
|
|
29
|
+
- 集合层 import 路径例如 `platform.*`、`site_runtime.*`、`contrib.*` 都不是长期正式方案;长期正式导入面只能是最小子包自己的包名。
|
|
30
|
+
|
|
31
|
+
## 1. 背景
|
|
32
|
+
|
|
33
|
+
当前 `legacy_core` 已具备独立框架包雏形,但实现上仍大量保留“仓库内 vendored 子系统”的运行假设,例如:
|
|
34
|
+
- CLI 入口优先照顾 `python legacy_core` 与 wrapper 模式
|
|
35
|
+
- settings 默认强依赖仓库根 `.env`
|
|
36
|
+
- 资源与迁移合并输出写回 `legacy_core/merged/*`
|
|
37
|
+
- 默认安装清单中直接内置大量官方 app 与业务 `app`
|
|
38
|
+
- 运行期路径推断较多依赖 `Path.cwd()`、仓库根和包目录可写
|
|
39
|
+
|
|
40
|
+
这些假设会阻碍 `legacy_core` 成为标准的 `pip` 安装包,也会模糊“框架内核”和“具体业务项目”的边界。
|
|
41
|
+
|
|
42
|
+
## 2. 本次重构目标
|
|
43
|
+
|
|
44
|
+
本次重构的直接目标不是“仅补齐一个 `pyproject.toml`”,而是将 `legacy_core` 收敛为一套标准、清晰、可替换的 Python app 框架约定:
|
|
45
|
+
|
|
46
|
+
- `legacy_core` 作为一个标准 Python 包建设,开发、依赖锁定、命令执行、构建与测试统一使用 `uv` 管理
|
|
47
|
+
- 让 `legacy_core` 可以作为标准框架包安装与运行
|
|
48
|
+
- 让官方 app 与独立 app 在装配模型上完全一致
|
|
49
|
+
- 让资源合并、迁移合并、运行时锁与临时文件都落到外部 `cache/runtime dir`
|
|
50
|
+
- 让数据库、Redis 变成按需启用的可选能力
|
|
51
|
+
- 让 Prometheus/metrics 以显式集成边界存在,而不是变成 import-time 全局副作用
|
|
52
|
+
- 为后续将独立子包与部分官方 app 独立维护提供稳定契约
|
|
53
|
+
- 让“最小子包是唯一正式单位,外层目录只是 Git 管理容器”成为文档、代码与发布层面的单一事实
|
|
54
|
+
|
|
55
|
+
补充约束:
|
|
56
|
+
|
|
57
|
+
- 本次按全新架构设计推进,运行时只保留新主链
|
|
58
|
+
- 对历史子包的改造,主要通过明确的适配改造文档完成,而不是在 core 中长期保留两套主链
|
|
59
|
+
- 旧 `legacy_core` 代码是外部可观察行为的回归基线,不是目录结构、全局状态与历史脏实现的复制模板
|
|
60
|
+
- 重构允许重写结构、分层、生命周期与全局状态模型,但不得无文档声明地改变外部 API、路由、配置、资源覆盖、worker 协议与关键错误语义
|
|
61
|
+
|
|
62
|
+
## 3. 设计原则
|
|
63
|
+
|
|
64
|
+
- Django 风格:一切功能以 app 为最小装配单元
|
|
65
|
+
- 最小子包唯一化:系统只承认最小子包,不承认集合层 namespace
|
|
66
|
+
- 自顶向下设计:先定义边界、契约、真相源,再落实现细节
|
|
67
|
+
- 自底向上开发:先落稳定 schema/manifest/registry,再接 facade/capability,最后接入口与 app 集成
|
|
68
|
+
- 单一职责:每个核心构件只解决一个问题,不混入第二条主职责
|
|
69
|
+
- 依赖倒置:上层只依赖契约、facade、capability,不依赖具体实现模块
|
|
70
|
+
- 单一路径原则:一个问题只保留一种正式解决方案
|
|
71
|
+
- 不重复造轮子:不得在不同层各自重写同类扫描、聚合、推导、注册逻辑
|
|
72
|
+
- 单一顺序源:`installed_apps` 是唯一 app 装载顺序来源
|
|
73
|
+
- 文件夹声明装配:`installed_apps` 可以声明最小子包,也可以声明文件夹/容器目录;框架负责自动递归发现其中嵌套的最小子包,并以展开结果作为正式装配单位
|
|
74
|
+
- 目录名语法固定:`installed_apps` 中每个条目只能是正式最小子包目录名或正式容器目录名
|
|
75
|
+
- 发现算法固定:命中最小子包后立即停止继续向下递归;容器目录按目录名字典序做深度优先展开;重复 `app_id` 直接报错,不做静默跳过
|
|
76
|
+
- 命名统一:每个最小子包必须有稳定唯一的 `app_id`;新建子包默认让目录名、import 包名与 `app_id` 对齐,distribution 使用对应的 Python 分发名,不强制特定技术前缀
|
|
77
|
+
- 无特权 app:官方维护最小子包与其它最小子包统一为普通 app;装配层面平权,公开交互面分层
|
|
78
|
+
- 显式优于隐式:替换、覆盖、装配、资源输出路径必须显式声明
|
|
79
|
+
- 可安装优先:所有路径与入口设计默认面向 `pip install` 场景
|
|
80
|
+
- 工具链统一:新版包的开发、依赖锁定、构建与命令执行统一采用 `uv`
|
|
81
|
+
- 行为优先:优先保持旧实现的外部可观察行为;若需改变行为,必须在设计文档、迁移说明与测试门禁中显式声明
|
|
82
|
+
- 可选基础设施:数据库、Redis、观测能力按需启用,不成为 base 运行前提
|
|
83
|
+
- 能力边界清晰:监控集成属于框架边界,监控平台部署属于项目/运维边界
|
|
84
|
+
|
|
85
|
+
约束:
|
|
86
|
+
|
|
87
|
+
- `uv` 只用于开发、锁定依赖、构建与测试
|
|
88
|
+
- 对外分发与运行仍保持标准 `pip` / wheel 交付模型
|
|
89
|
+
- 不允许把 `uv workspace` 心智扩散成用户运行前提
|
|
90
|
+
|
|
91
|
+
### 3.1 Django 风格的具体落点
|
|
92
|
+
|
|
93
|
+
这里说“借鉴 Django”,指的是借鉴其设计哲学,而不是复制其实现:
|
|
94
|
+
|
|
95
|
+
- 用 app registry / `installed_apps` 管理装配顺序
|
|
96
|
+
- 用命名空间 settings 管理 app 配置,而不是平铺全局字段
|
|
97
|
+
- 用统一 CLI / management command 风格暴露运维入口
|
|
98
|
+
- 用 preflight / system checks 风格在启动前发现阻断项
|
|
99
|
+
- 用显式生命周期与公共门面代替隐式 import side effect
|
|
100
|
+
|
|
101
|
+
补充约束:
|
|
102
|
+
|
|
103
|
+
- system checks 的正式入口统一为 `pz check`
|
|
104
|
+
- 检查逻辑统一消费已编译完成的 `RuntimePlan`
|
|
105
|
+
- 不允许 Web startup、debug 页面、worker SDK、子包脚本各自实现第二套检查主链
|
|
106
|
+
|
|
107
|
+
不借鉴 Django 的部分:
|
|
108
|
+
|
|
109
|
+
- 不引入过度依赖约定路径的项目骨架魔法
|
|
110
|
+
- 不允许框架偷偷依赖仓库根目录或 vendored 目录结构
|
|
111
|
+
- 不把进程级全局单例当成长期稳定契约
|
|
112
|
+
|
|
113
|
+
### 3.2 分层与依赖方向
|
|
114
|
+
|
|
115
|
+
正式架构统一分为五层:
|
|
116
|
+
|
|
117
|
+
1. 契约层
|
|
118
|
+
- schema
|
|
119
|
+
- settings model
|
|
120
|
+
- manifest
|
|
121
|
+
- capability interface
|
|
122
|
+
- provider contract
|
|
123
|
+
2. 编译/聚合层
|
|
124
|
+
- app registry compiler
|
|
125
|
+
- route manifest compiler
|
|
126
|
+
- middleware manifest compiler
|
|
127
|
+
- resource manifest compiler
|
|
128
|
+
- infra snapshot compiler
|
|
129
|
+
3. facade/capability 层
|
|
130
|
+
- context-bound facade
|
|
131
|
+
- capability registry
|
|
132
|
+
- provider registry
|
|
133
|
+
4. 适配器层
|
|
134
|
+
- FastAPI/ASGI
|
|
135
|
+
- Aerich/Tortoise
|
|
136
|
+
- Redis client
|
|
137
|
+
- Prometheus exporter
|
|
138
|
+
5. 入口层
|
|
139
|
+
- CLI
|
|
140
|
+
- Web app
|
|
141
|
+
- worker
|
|
142
|
+
|
|
143
|
+
依赖方向固定为:
|
|
144
|
+
|
|
145
|
+
- 入口层 -> facade/capability 层 -> 编译/聚合层 -> 契约层
|
|
146
|
+
- 适配器层 -> 契约层 或 facade/capability 层
|
|
147
|
+
- app 代码 -> public facade / capability contract
|
|
148
|
+
|
|
149
|
+
禁止:
|
|
150
|
+
|
|
151
|
+
- 入口层直接操作底层模块级单例
|
|
152
|
+
- app 直接 import core/infra 内部实现细节
|
|
153
|
+
- facade 反向依赖某个具体入口
|
|
154
|
+
- 同一能力在多层各自维护一份规则与状态
|
|
155
|
+
|
|
156
|
+
### 3.2.1 官方维护最小子包与其它最小子包的正式关系
|
|
157
|
+
|
|
158
|
+
- 官方维护最小子包与其它最小子包在装配层面完全一致
|
|
159
|
+
- 两者都只是 app
|
|
160
|
+
- 两者都只能通过 `installed_apps` 进入系统
|
|
161
|
+
- 两者都没有装配优先级特权
|
|
162
|
+
|
|
163
|
+
但在公开交互面上,两者明确分层:
|
|
164
|
+
|
|
165
|
+
- 官方维护最小子包
|
|
166
|
+
- 定义为官方 `library app`
|
|
167
|
+
- 允许其它 app 通过稳定 `public.py` 依赖
|
|
168
|
+
- 统一由 official infra owner 承载 `infra` 背后的具体实现
|
|
169
|
+
- 独立子包
|
|
170
|
+
- 定义为独立 `integration app`
|
|
171
|
+
- 不允许其它 app 直接 import 其内部 Python 模块
|
|
172
|
+
- 只允许通过稳定交互边界协作:
|
|
173
|
+
- capability
|
|
174
|
+
- facade
|
|
175
|
+
- events
|
|
176
|
+
- provider contract / internal binding
|
|
177
|
+
- CLI/task 协议
|
|
178
|
+
- 必要时的 HTTP API
|
|
179
|
+
|
|
180
|
+
禁止:
|
|
181
|
+
|
|
182
|
+
- 让独立子包重新变成“可直接 import 的内部实现仓库”
|
|
183
|
+
- 让任何容器目录在装配上拥有高于其它 app 的优先级
|
|
184
|
+
|
|
185
|
+
### 3.3 唯一真相源清单
|
|
186
|
+
|
|
187
|
+
以下对象必须各自成为唯一真相源:
|
|
188
|
+
|
|
189
|
+
- `project_dir`:项目边界唯一真相源
|
|
190
|
+
- `pz.jsonc`:项目正式配置唯一真相源
|
|
191
|
+
- `<project_dir>/.env` 与 `<project_dir>/.env.{PZ_ENV}`:环境覆盖文件唯一入口集合
|
|
192
|
+
- `installed_apps`:app 装载顺序唯一真相源
|
|
193
|
+
- `[app_replacements]`:app 替换关系唯一真相源
|
|
194
|
+
- route manifest:路由裁决唯一真相源
|
|
195
|
+
- middleware manifest:中间件裁决唯一真相源
|
|
196
|
+
- `<cache_dir>/resources/manifest.json`:资源合并结果唯一真相源
|
|
197
|
+
- `InfraSettings` / `InfraContext`:基础设施状态唯一真相源
|
|
198
|
+
|
|
199
|
+
任何历史 helper、回退路径或旧门面都不得再生成第二套并行真相源。
|
|
200
|
+
|
|
201
|
+
补充说明:
|
|
202
|
+
|
|
203
|
+
- `installed_apps` 的每一项可以是正式最小子包目录名,也可以是正式容器目录名
|
|
204
|
+
- 分组目录只用于 Git 与源码组织,不参与运行时 namespace
|
|
205
|
+
- app registry、settings、resources、routes 都以 `installed_apps` 展开后的最小子包集合为单位工作
|
|
206
|
+
- 正式发现只认目录结构,不做模块名猜测、历史别名补全或 package-level `app` 猜测
|
|
207
|
+
|
|
208
|
+
### 3.4 唯一组合根与运行计划
|
|
209
|
+
|
|
210
|
+
正式架构中,必须存在且只存在一个组合根:
|
|
211
|
+
|
|
212
|
+
- `RuntimePlan` 编译入口
|
|
213
|
+
|
|
214
|
+
它负责把所有下层正式产物一次性编译为当前进程的运行计划。
|
|
215
|
+
|
|
216
|
+
`RuntimePlan` 至少固定包含:
|
|
217
|
+
|
|
218
|
+
- `ProjectContext`
|
|
219
|
+
- `SettingsSnapshot`
|
|
220
|
+
- `AppRegistry`
|
|
221
|
+
- `ResourceManifest`
|
|
222
|
+
- `InfraContext`
|
|
223
|
+
- `RouteManifest`
|
|
224
|
+
- `MiddlewareManifest`
|
|
225
|
+
- `CapabilityRegistry`
|
|
226
|
+
|
|
227
|
+
其中资源域的正式心智固定为:
|
|
228
|
+
|
|
229
|
+
- 作者配置入口是 `resources.items`
|
|
230
|
+
- 单个 app 的资源发现结果落在 `ResourceSource.items`
|
|
231
|
+
- 当前项目的统一资源编译结果落在 `ResourceManifest.items`
|
|
232
|
+
- 每个资源项直接持有 `name / source_dirs / output_dir`
|
|
233
|
+
|
|
234
|
+
正式要求:
|
|
235
|
+
|
|
236
|
+
- Web、CLI、worker 都只能先构建 `RuntimePlan`,再消费它
|
|
237
|
+
- 不允许某个入口跳过 `RuntimePlan`,直接单独拼 settings、app registry、resource manifest 或 infra context
|
|
238
|
+
- `RuntimePlan` 一旦生成,就作为当前进程唯一运行图输入
|
|
239
|
+
- `RuntimePlan` 产物必须视为不可变快照;后续阶段只能消费,不得原地改写
|
|
240
|
+
- `lifespan/startup/shutdown` 只允许激活或关闭 `RuntimePlan` 中已经编译好的 capability,不再反向改写运行图
|
|
241
|
+
- `CapabilityRegistry` 只作为运行图内部对象存在,不提升为 app 稳定公共依赖面
|
|
242
|
+
|
|
243
|
+
禁止:
|
|
244
|
+
|
|
245
|
+
- Web 入口自己再扫一遍 apps
|
|
246
|
+
- worker 入口自己再推一遍 infra config
|
|
247
|
+
- CLI 命令自己再定位一遍 resources/migrations
|
|
248
|
+
- bootstrap/lifespan 再临时补 route、middleware、settings 稳定字段
|
|
249
|
+
|
|
250
|
+
### 3.5 编译阶段与执行阶段分离
|
|
251
|
+
|
|
252
|
+
正式架构统一分为两个阶段:
|
|
253
|
+
|
|
254
|
+
1. 编译阶段
|
|
255
|
+
- 读取配置
|
|
256
|
+
- 解析 app
|
|
257
|
+
- 编译 manifest
|
|
258
|
+
- 编译 typed snapshot
|
|
259
|
+
- 生成 `RuntimePlan`
|
|
260
|
+
2. 执行阶段
|
|
261
|
+
- 挂载 route
|
|
262
|
+
- 初始化 provider/client
|
|
263
|
+
- 创建 facade/capability 实例
|
|
264
|
+
- 启动 Web/CLI/worker
|
|
265
|
+
- 执行 shutdown/cleanup
|
|
266
|
+
|
|
267
|
+
正式要求:
|
|
268
|
+
|
|
269
|
+
- 编译阶段负责裁决与产出,不负责启动任何运行时副作用
|
|
270
|
+
- 执行阶段只消费编译结果,不再重新裁决规则
|
|
271
|
+
- 冲突检测、替换关系、顺序决定、路径决定、enabled/disabled 判定,全部必须在编译阶段完成
|
|
272
|
+
- DB/Redis client 初始化、logger handler 注册、worker loop 启动、route mutation,只允许发生在执行阶段
|
|
273
|
+
|
|
274
|
+
禁止:
|
|
275
|
+
|
|
276
|
+
- 在编译阶段偷偷初始化 DB/Redis/metrics/exporter
|
|
277
|
+
- 在执行阶段重新扫描 installed apps、重新推导 settings、重新生成 manifest
|
|
278
|
+
- 在 `startup()`、`lifespan`、middleware 构造期重新做冲突裁决
|
|
279
|
+
- 在 adapter 层重新实现一套编译规则
|
|
280
|
+
|
|
281
|
+
## 4. 核心决策
|
|
282
|
+
|
|
283
|
+
### 4.1 包边界
|
|
284
|
+
|
|
285
|
+
- `legacy_core` 主包只承载框架内核与通用装配能力
|
|
286
|
+
- `pz_contrib` 是官方通用实现最小子包,不具备特殊装配权限
|
|
287
|
+
- 官方能力与业务能力一样,统一以 `<app_id>` 最小子包形式存在
|
|
288
|
+
- 最小子包的正式源码统一收口到某个顶层源码组织根下的 `<app_id>/`,例如 `pz_framework/pz_contrib/<app_id>/`、`pz_apps/<app_id>/`、`pz_apps/<app_id>/`
|
|
289
|
+
- 外部业务 app、第三方 app、官方维护最小子包在装配层面没有优先级差异
|
|
290
|
+
|
|
291
|
+
补充约束:
|
|
292
|
+
|
|
293
|
+
- 官方能力不得再通过任何集合层 namespace 暴露长期 import path
|
|
294
|
+
- 任何最小子包都不得再借 `platform.*`、`site_runtime.*`、`contrib.*` 这类集合层路径伪装成正式运行单元
|
|
295
|
+
- `infra` 的具体实现统一收口到官方最小子包;`legacy_core/infra` 只保留薄绑定层
|
|
296
|
+
|
|
297
|
+
official infra owner 的完整目录结构以 `01-目录与分层重构执行方案.md` 为准。
|
|
298
|
+
|
|
299
|
+
约束:
|
|
300
|
+
|
|
301
|
+
- official infra owner 只承接“原本误落在 `legacy_core/infra` 的具体实现”
|
|
302
|
+
- official infra owner 的 `public.py` 负责向其它官方 app 暴露稳定 facade
|
|
303
|
+
- official infra owner `public.py` 的正式导出面以 `16-正式Facade总表.md` 为准
|
|
304
|
+
- middleware 不属于 `core`;`assembly` 只编译 `MiddlewareManifest`,具体 middleware 类统一进入官方基础能力最小子包或对应 app
|
|
305
|
+
- `i18n` / `jinja` 属于展示层 runtime,不进入 infra owner,而进入 shared site UI owner 或对应展示层 app
|
|
306
|
+
- `HealthFacade` 是公开能力面,但 health 聚合实现仍归 `runtime` / capability 层,不单独要求 `foundation/health/`
|
|
307
|
+
- official infra owner 不重新变成第二个 `infra`;它只是集中落位,不改变依赖方向
|
|
308
|
+
|
|
309
|
+
补充冻结:
|
|
310
|
+
|
|
311
|
+
- `legacy_core.host` 已删除;正式 installable 通用入口只允许落在 `legacy_core.runtime/*`,workspace 开发辅助脚本只允许位于仓根 `devtools/*`
|
|
312
|
+
- `legacy_core` 不允许 import 或点名任何具体 owner app
|
|
313
|
+
- owner-specific host/runtime 入口必须回到 owner 自己的 app 包下
|
|
314
|
+
- `legacy_core` 只按正式协议、manifest、installed apps 与 capability/host registration 进行发现和编排
|
|
315
|
+
|
|
316
|
+
禁止:
|
|
317
|
+
|
|
318
|
+
- 在 `legacy_core` 下恢复 `host/` 或保留 DB / Redis / task runtime 的 owner facade
|
|
319
|
+
- 在宿主项目中再次创建 `project_runtime` 一类第二装配层
|
|
320
|
+
- 让 core 通过硬编码 import path 支持某个特定 app
|
|
321
|
+
|
|
322
|
+
### 4.2 装配边界
|
|
323
|
+
|
|
324
|
+
- 所有 app 统一通过 `installed_apps` 装配
|
|
325
|
+
- 默认不再把业务根包 `app` 视为内建特殊层
|
|
326
|
+
- `installed_apps` 可以直接写最小子包,也可以写文件夹/容器目录;真正进入 app registry、settings、resources、routes 的是递归展开后的最小子包
|
|
327
|
+
- `installed_apps` 不接受文件系统路径、distribution 名或 `<pkg>.apps:app` 语法
|
|
328
|
+
- 最小子包判定固定为:
|
|
329
|
+
- 目录名对应稳定 `<app_id>`
|
|
330
|
+
- 目录内存在同名 Python 包目录 `<app_id>/`
|
|
331
|
+
- 同名 Python 包目录内存在正式 `apps.py`
|
|
332
|
+
- 命中最小子包后,不再继续向下扫描其子目录
|
|
333
|
+
- 容器目录展开顺序固定为:先保持 `installed_apps` 条目顺序,再在每个容器内部按目录名字典序深度优先展开
|
|
334
|
+
- 模板、静态、语言、页面声明、模板配置、模型、迁移等资源覆盖规则统一跟随 `installed_apps` 顺序
|
|
335
|
+
- `pages/`、`template_config/` 与 `templates/`、`locales/` 一样,都是正式资源目录;启动时必须走同一套覆盖逻辑,不允许各自再发明第二套扫描或优先级规则
|
|
336
|
+
- 同 `app_id` 冲突默认报错,只有显式替换才允许覆盖
|
|
337
|
+
|
|
338
|
+
### 4.3 运行边界
|
|
339
|
+
|
|
340
|
+
- 包目录必须视为只读
|
|
341
|
+
- 合并产物统一写入外部 `cache_dir` / `runtime_dir`
|
|
342
|
+
- 运行期不得假设当前工作目录就是项目根目录
|
|
343
|
+
- 标准用户入口统一为 `legacy_core`
|
|
344
|
+
- `python -m legacy_core` 只保留为技术入口,不作为正式文档主路径
|
|
345
|
+
|
|
346
|
+
### 4.4 配置边界
|
|
347
|
+
|
|
348
|
+
- 主配置文件统一为 `pz.jsonc`
|
|
349
|
+
- 环境变量与 `.env` 主要负责敏感值与覆盖
|
|
350
|
+
- app 私有配置统一走 `settings_center.settings.<app_id>`
|
|
351
|
+
- app 代码不得直接读取 `os.environ`
|
|
352
|
+
|
|
353
|
+
## 5. 目标目录心智
|
|
354
|
+
|
|
355
|
+
完整目录结构以 `01-目录与分层重构执行方案.md` 为唯一真相源。
|
|
356
|
+
|
|
357
|
+
这套目录设计先裁掉几个歧义:
|
|
358
|
+
|
|
359
|
+
- `legacy_core/` 只保留框架入口与内核主链
|
|
360
|
+
- `runtime/assembly/core/infra` 共同组成框架主链,但各自职责单独收口
|
|
361
|
+
- 官方与业务最小子包的正式源码真相源统一收口到各自顶层源码组织根下的 `<app_id>/`
|
|
362
|
+
|
|
363
|
+
## 5.1 四层目录的硬边界表
|
|
364
|
+
|
|
365
|
+
为了避免后续又把“暂时方便的实现”塞回错误目录,`runtime / assembly / core / infra` 的文件类型边界固定如下。
|
|
366
|
+
|
|
367
|
+
### 5.1.1 `runtime/`
|
|
368
|
+
|
|
369
|
+
允许放入:
|
|
370
|
+
|
|
371
|
+
- `ProjectContext`、`RuntimePlan` 的运行时持有与访问入口
|
|
372
|
+
- context-bound `Registry` / `Facade` / provider binding 激活逻辑
|
|
373
|
+
- request/app-state/runtime helper
|
|
374
|
+
- Web / CLI / worker 的执行期入口胶水
|
|
375
|
+
- `startup()` / `shutdown()` 的执行器
|
|
376
|
+
- health / metrics / debug surface 的执行期暴露
|
|
377
|
+
- 把已编译 `RouteManifest` / `MiddlewareManifest` / `ResourceManifest` 应用到宿主框架的 adapter glue
|
|
378
|
+
|
|
379
|
+
补充约束:
|
|
380
|
+
|
|
381
|
+
- runtime 消费资源编译结果时,只读取 `ResourceManifest.items` 与 `manifest_path/output_root/staging_root/lock_path`
|
|
382
|
+
- runtime 不得自行恢复目录名映射表、固定资源输出字段或第二套资源 facade
|
|
383
|
+
|
|
384
|
+
禁止放入:
|
|
385
|
+
|
|
386
|
+
- settings 读取器、`.env` 发现器、project root 推断器
|
|
387
|
+
- app 扫描、资源扫描、迁移扫描、middleware 扫描
|
|
388
|
+
- route / middleware / resource / infra 的编译规则
|
|
389
|
+
- 具体 middleware 类
|
|
390
|
+
- 具体 provider/client/SDK 实现
|
|
391
|
+
- 任何 import-time 单例、全局 setter、全局 manager
|
|
392
|
+
|
|
393
|
+
### 5.1.2 `assembly/`
|
|
394
|
+
|
|
395
|
+
允许放入:
|
|
396
|
+
|
|
397
|
+
- settings compiler
|
|
398
|
+
- app registry compiler
|
|
399
|
+
- route / middleware / resource / infra manifest compiler
|
|
400
|
+
- project/app/resource 路径归一化逻辑
|
|
401
|
+
- 冲突检测、替换裁决、顺序裁决
|
|
402
|
+
- 资源 merge 计划、迁移归属计划、诊断产物编译
|
|
403
|
+
|
|
404
|
+
禁止放入:
|
|
405
|
+
|
|
406
|
+
- FastAPI/ASGI 对象创建与 mutation
|
|
407
|
+
- DB/Redis/mail/storage client 初始化
|
|
408
|
+
- logger/exporter/worker loop 启动
|
|
409
|
+
- 具体 middleware 类与具体 provider 实现
|
|
410
|
+
- request helper、app.state helper、thread-local/runtime-local 状态
|
|
411
|
+
- 在编译阶段触发文件写入、网络 I/O、依赖探测
|
|
412
|
+
|
|
413
|
+
### 5.1.3 `core/`
|
|
414
|
+
|
|
415
|
+
允许放入:
|
|
416
|
+
|
|
417
|
+
- app protocol、declaration model、dependency rule
|
|
418
|
+
- route / middleware / resource 的声明模型与纯校验规则
|
|
419
|
+
- error code、error envelope、health result model
|
|
420
|
+
- request correlation id / trace correlation model 的纯协议定义
|
|
421
|
+
- capability contract、provider contract 的纯接口定义
|
|
422
|
+
- 不依赖具体 app / 具体 provider / 具体目录真相源的纯规则
|
|
423
|
+
|
|
424
|
+
禁止放入:
|
|
425
|
+
|
|
426
|
+
- 具体 app 清单、具体官方 app import path 特判
|
|
427
|
+
- FastAPI/Request/app.state/CLI 运行时 helper
|
|
428
|
+
- `startup()` / `shutdown()` / lifespan 副作用
|
|
429
|
+
- 具体 middleware 类、模板运行时、i18n 运行时、静态资源服务
|
|
430
|
+
- 具体 DB/Redis/storage/mail/observability provider 实现
|
|
431
|
+
- 任何“因为历史原因先放进 core”的临时实现
|
|
432
|
+
|
|
433
|
+
### 5.1.4 `infra/`
|
|
434
|
+
|
|
435
|
+
允许放入:
|
|
436
|
+
|
|
437
|
+
- typed infra settings / typed context / capability state model
|
|
438
|
+
- provider contract / adapter protocol / binder interface
|
|
439
|
+
- capability 装配所需的最小 runtime binder
|
|
440
|
+
- 最小 noop / null / disabled 语义实现
|
|
441
|
+
- 不带业务语义的 resilience 工具
|
|
442
|
+
|
|
443
|
+
禁止放入:
|
|
444
|
+
|
|
445
|
+
- 共享 middleware 实现目录
|
|
446
|
+
- i18n / jinja / site runtime / template helper
|
|
447
|
+
- 平台 app 专属 registry、provider 注册表、模块配置逻辑
|
|
448
|
+
- 具体第三方 SDK / 云服务 / exporter / bot handler 实现
|
|
449
|
+
- import-time 默认 client、默认 registry、默认 logger
|
|
450
|
+
- 任何官方 app 或独立子包的业务逻辑
|
|
451
|
+
|
|
452
|
+
### 5.1.5 一票否决规则
|
|
453
|
+
|
|
454
|
+
某个文件只要满足以下任一条件,就不得进入 `core` 或 `infra`:
|
|
455
|
+
|
|
456
|
+
- 需要知道某个具体官方 app / 独立子包的名字
|
|
457
|
+
- 需要直接 import 具体 provider / 具体 middleware 类
|
|
458
|
+
- 需要在导入期或编译期产生运行时副作用
|
|
459
|
+
- 需要依赖 repo-root、`cwd`、历史目录布局才能工作
|
|
460
|
+
- 需要通过“临时回退”补正式主链缺口
|
|
461
|
+
|
|
462
|
+
### 5.1.6 二级目录固定说明
|
|
463
|
+
|
|
464
|
+
完整二级目录结构以 `01-目录与分层重构执行方案.md` 为唯一真相源。
|
|
465
|
+
|
|
466
|
+
补充约束:
|
|
467
|
+
|
|
468
|
+
- `runtime/cli/` 只放执行期 CLI context/helper,不承担 console-script 入口发现
|
|
469
|
+
- `assembly/*` 不得夹带执行期状态与宿主框架 mutation
|
|
470
|
+
- `core/*` 不再保留 `app_factory/`、`ops/`、`resources/`、`cli/` 目录
|
|
471
|
+
- `core/` 不设 `apps/` 子目录
|
|
472
|
+
- `infra/*` 若保留 `observability/` 与 `resources/`,也只能保留 contract/noop/path-model 边界
|
|
473
|
+
|
|
474
|
+
## 6. 关键约定
|
|
475
|
+
|
|
476
|
+
- `installed_apps` 是唯一 app 顺序真相源
|
|
477
|
+
- `middleware` 是唯一中间件顺序真相源
|
|
478
|
+
- 模板/静态/语言/页面声明/模板配置覆盖按 `installed_apps` 后者覆盖前者
|
|
479
|
+
- 迁移必须落在 `migrations/<app_id>/`
|
|
480
|
+
- app 间禁止直接 import 对方内部实现
|
|
481
|
+
- 跨 app 协作统一走 public facade、capability contract、events,以及必要的 provider contract / internal binding 协议
|
|
482
|
+
|
|
483
|
+
## 6.1 稳定边界与内部边界
|
|
484
|
+
|
|
485
|
+
从工程治理角度,`legacy_core` 必须明确区分“稳定公共契约”和“可自由重构的内部实现”。
|
|
486
|
+
|
|
487
|
+
稳定公共契约包括:
|
|
488
|
+
|
|
489
|
+
- `pz` CLI 入口语义
|
|
490
|
+
- `pz.app:create_app`
|
|
491
|
+
- `pz.app:create_host_app`
|
|
492
|
+
- `pz.app:run_host_main`
|
|
493
|
+
- `pz.jsonc` 配置结构
|
|
494
|
+
- app 最小协议
|
|
495
|
+
- `installed_apps` / app registry / migrations / resources 的正式约定
|
|
496
|
+
- 官方声明为 `public.py`、capability contract、provider contract 的稳定边界
|
|
497
|
+
|
|
498
|
+
默认不属于稳定公共契约的内容:
|
|
499
|
+
|
|
500
|
+
- `legacy_core.settings`
|
|
501
|
+
- `core/*`、`infra/*` 内部 helper 的具体文件布局
|
|
502
|
+
- 官方维护最小子包/独立子包的内部 service / runtime / module 目录
|
|
503
|
+
- 历史 adapter、旧入口和回退路径
|
|
504
|
+
- 任何未在文档中声明为 stable 的私有模块 import path
|
|
505
|
+
|
|
506
|
+
要求:
|
|
507
|
+
|
|
508
|
+
- 文档必须明确哪些入口是 stable,哪些不属于稳定公共边界
|
|
509
|
+
- 重构中允许调整内部目录,但不得破坏已声明的 stable 契约
|
|
510
|
+
|
|
511
|
+
## 6.2 旧路径清理策略
|
|
512
|
+
|
|
513
|
+
本次重构要求旧路径、旧入口与旧导入魔法全部退出正式设计。
|
|
514
|
+
|
|
515
|
+
要求:
|
|
516
|
+
|
|
517
|
+
- 每个旧入口都要列入删除清单:
|
|
518
|
+
- 当前状态
|
|
519
|
+
- 正式替代方案
|
|
520
|
+
- 本次重构中直接移除
|
|
521
|
+
- 正式发布目标中不保留两套主链并存
|
|
522
|
+
- 任何历史导入魔法、自动补全、隐式回退都不得继续扩展能力
|
|
523
|
+
- 开发过程中若仍看到旧路径命中,必须视为未完成项并立即修正
|
|
524
|
+
|
|
525
|
+
交付边界:
|
|
526
|
+
|
|
527
|
+
- 对“标准 pip 包化重构”而言,最终交付物只保留新正式路径
|
|
528
|
+
- 真正需要保留的是迁移说明、子包适配改造清单、发布说明
|
|
529
|
+
|
|
530
|
+
## 6.3 默认失败语义
|
|
531
|
+
|
|
532
|
+
从最佳工程实践看,框架重构期间最容易失控的点,是把“warning + 继续运行”当成常态。
|
|
533
|
+
|
|
534
|
+
新规范应默认采用:
|
|
535
|
+
|
|
536
|
+
- 配置错误默认失败
|
|
537
|
+
- app registry 冲突默认失败
|
|
538
|
+
- route / extension / middleware 冲突默认失败
|
|
539
|
+
- 必需 provider 缺失默认失败
|
|
540
|
+
- 只有显式声明为 optional 的能力,才允许降级为 disabled / unavailable
|
|
541
|
+
|
|
542
|
+
不采用:
|
|
543
|
+
|
|
544
|
+
- 先吞异常
|
|
545
|
+
- 留 warning
|
|
546
|
+
- 继续把半初始化结果带入后续装配链
|
|
547
|
+
|
|
548
|
+
要求:
|
|
549
|
+
|
|
550
|
+
- 每个装配阶段都应明确哪些错误 fail-fast、哪些错误可降级,以及降级后的正式语义
|
|
551
|
+
|
|
552
|
+
## 6.4 单一职责与禁止重复实现
|
|
553
|
+
|
|
554
|
+
核心构件职责固定如下:
|
|
555
|
+
|
|
556
|
+
- settings compiler 只负责读取与归一化配置,不负责 app 装配
|
|
557
|
+
- app settings 聚合器只负责聚合 app 配置,不负责 runtime override 执行
|
|
558
|
+
- app registry 只负责 app 解析、依赖校验、顺序裁决
|
|
559
|
+
- route registry 只负责 route manifest 编译与冲突裁决
|
|
560
|
+
- middleware registry 只负责 middleware manifest 编译与冲突裁决
|
|
561
|
+
- resource manifest compiler 只负责资源发现、合并、manifest 生成
|
|
562
|
+
- infra snapshot compiler 只负责把配置编译为 typed snapshot
|
|
563
|
+
- readiness aggregator 只负责聚合已启用探针结果,不负责初始化依赖
|
|
564
|
+
- facade/capability 只负责当前上下文的能力暴露,不负责重新解析配置
|
|
565
|
+
- entrypoint 只负责选择进程类型并组装上下文,不负责重写核心规则
|
|
566
|
+
|
|
567
|
+
禁止:
|
|
568
|
+
|
|
569
|
+
- 同时在 settings compiler、bootstrap、lifespan 三处重复做字段归一化
|
|
570
|
+
- 同时在 app registry compiler、DB config compiler、resource manifest compiler 三处重复扫描 installed apps
|
|
571
|
+
- 同时在 route registry 与 FastAPI mutation 阶段各做一遍冲突裁决
|
|
572
|
+
- 同时在 facade 与 adapter 中重复维护缓存、订阅、版本游标
|
|
573
|
+
- 每个 app 各自重写一套 env 读取、resource 定位、provider 注册协议
|
|
574
|
+
|
|
575
|
+
正式要求:
|
|
576
|
+
|
|
577
|
+
- 相同问题只允许有一个正式编译器/聚合器
|
|
578
|
+
- 其它层只允许消费结果,不允许再派生第二份规则
|
|
579
|
+
|
|
580
|
+
## 6.5 核心构件唯一命名约束
|
|
581
|
+
|
|
582
|
+
为了避免同一职责在实现中被 `builder`、`manager`、`service`、`helper`、`loader` 混名复写,正式架构对核心构件名称作如下约束:
|
|
583
|
+
|
|
584
|
+
- `Compiler`
|
|
585
|
+
- 只表示编译阶段构件
|
|
586
|
+
- 负责把声明、配置、元数据编译为不可变 snapshot / manifest / plan
|
|
587
|
+
- 可以失败、可以输出诊断,但不得持有长期运行态状态
|
|
588
|
+
- `Registry`
|
|
589
|
+
- 只表示当前 `RuntimePlan` 派生出来的 context-bound 索引与查找容器
|
|
590
|
+
- 其输入必须来自编译结果,不得再次扫描目录、推导配置、重做冲突裁决
|
|
591
|
+
- `Facade`
|
|
592
|
+
- 只表示对 app/handler/worker 暴露的稳定公共能力入口
|
|
593
|
+
- 只消费当前上下文已经编译好的 plan/snapshot/registry/provider
|
|
594
|
+
- `Provider`
|
|
595
|
+
- 只表示 capability 背后的具体实现、工厂或外部系统绑定点
|
|
596
|
+
- 必须受当前 context 生命周期约束
|
|
597
|
+
- `Adapter`
|
|
598
|
+
- 只表示与 FastAPI、Tortoise、Aerich、Redis、Prometheus 之类外部框架或协议的对接层
|
|
599
|
+
- 只负责协议适配,不负责框架内部裁决
|
|
600
|
+
|
|
601
|
+
禁止把以下命名作为稳定架构角色继续扩散:
|
|
602
|
+
|
|
603
|
+
- `manager`
|
|
604
|
+
- `service`
|
|
605
|
+
- `helper`
|
|
606
|
+
- `loader`
|
|
607
|
+
|
|
608
|
+
这些名称若仍保留,只能作为局部内部实现文件名,且不得承担稳定公共契约职责,不得成为跨 app 依赖入口。
|
|
609
|
+
|
|
610
|
+
补充要求:
|
|
611
|
+
|
|
612
|
+
- 同一类问题只能有一个正式 `Compiler`
|
|
613
|
+
- 同一类运行态公共能力只能有一个正式 `Facade`
|
|
614
|
+
- 同一类上下文索引只能有一个正式 `Registry`
|
|
615
|
+
- 文档名、代码名、测试名必须对齐,不再同时并存语义等价的:
|
|
616
|
+
- `RuntimePlan`
|
|
617
|
+
- `BootstrapState`
|
|
618
|
+
- `ExecutionGraph`
|
|
619
|
+
- `AppAssemblyContext`
|
|
620
|
+
这类多套同义核心名词
|
|
621
|
+
|
|
622
|
+
## 6.6 Adapter 层职责与禁止清单
|
|
623
|
+
|
|
624
|
+
Adapter 层是正式架构里最容易失控的地方,必须明确收口。
|
|
625
|
+
|
|
626
|
+
Adapter 只允许做:
|
|
627
|
+
|
|
628
|
+
- 把 `RouteManifest` 挂载到 FastAPI/ASGI
|
|
629
|
+
- 把 `MiddlewareManifest` 转成宿主框架中间件实例
|
|
630
|
+
- 把 `InfraContext` 中的 DB/Redis/metrics 配置接到具体客户端
|
|
631
|
+
- 把 `Facade` / `Provider` 暴露给外部框架需要的调用点
|
|
632
|
+
|
|
633
|
+
Adapter 不允许做:
|
|
634
|
+
|
|
635
|
+
- 重新解析 `project_dir`
|
|
636
|
+
- 重新读取 settings 或环境变量
|
|
637
|
+
- 重新扫描 app、资源、迁移目录
|
|
638
|
+
- 重新决定 app 顺序、替换关系、冲突裁决结果
|
|
639
|
+
- 重新生成 route/middleware/resource/infra 规则
|
|
640
|
+
- 在内部偷偷维护第二套 registry/cache/snapshot
|
|
641
|
+
- 夹带业务规则、默认兜底、来源优先级或 heuristic
|
|
642
|
+
- 通过吞异常把 `unavailable` 伪装成 `ready`
|
|
643
|
+
- 直接改写 `RuntimePlan`、`SettingsSnapshot`、`InfraContext`
|
|
644
|
+
|
|
645
|
+
正式要求:
|
|
646
|
+
|
|
647
|
+
- 启用/禁用判定只能来自编译阶段产物
|
|
648
|
+
- adapter 读取到的所有输入都必须是已编译完成的 typed snapshot 或 manifest
|
|
649
|
+
- adapter 若发现输入不足,只能 fail-fast 报错,不得在本层补推导逻辑
|
|
650
|
+
|
|
651
|
+
## 6.7 公共 registry / facade / provider 的统一编译与生命周期
|
|
652
|
+
|
|
653
|
+
所有平台能力都必须遵守同一套装配模式:
|
|
654
|
+
|
|
655
|
+
1. 编译阶段由正式 `Compiler` 产出声明和计划
|
|
656
|
+
2. 执行阶段基于计划创建 context-bound `Registry`
|
|
657
|
+
3. 再由 `Registry` 和 `Provider` 组装稳定 `Facade`
|
|
658
|
+
4. 生命周期结束时统一 `shutdown/reset`
|
|
659
|
+
|
|
660
|
+
正式要求:
|
|
661
|
+
|
|
662
|
+
- extension、route、middleware、provider、capability、metrics 等同类能力,不得各自发明局部 registry 体系
|
|
663
|
+
- app `startup()` 只允许激活或绑定已编译好的 provider/capability,不得在运行时再创建新的正式 registry 主链
|
|
664
|
+
- 任一公共能力的消费侧只允许依赖对应 facade,不得同时旁路读取 registry、provider 私有状态和模块级缓存
|
|
665
|
+
- 公共 registry 的 owner、scope、reset、diagnostics 语义必须统一,不再让不同平台 app 各自定义
|
|
666
|
+
- facade 不得兼任 compiler;provider 不得兼任 facade;adapter 不得兼任 registry
|
|
667
|
+
|
|
668
|
+
## 6.8 诊断与系统检查的单一路径原则
|
|
669
|
+
|
|
670
|
+
诊断能力也必须只有一种正式解决方案。
|
|
671
|
+
|
|
672
|
+
正式要求:
|
|
673
|
+
|
|
674
|
+
- system checks 统一由 `RuntimePlan` 驱动
|
|
675
|
+
- 检查结果统一产出结构化 `CheckReport`
|
|
676
|
+
- CLI、debug surface、发布前校验、preflight 都只允许消费同一份 `CheckReport` 或其同源数据
|
|
677
|
+
|
|
678
|
+
`CheckReport` 至少固定包含:
|
|
679
|
+
|
|
680
|
+
- check id
|
|
681
|
+
- severity
|
|
682
|
+
- owner
|
|
683
|
+
- scope
|
|
684
|
+
- message
|
|
685
|
+
- remediation
|
|
686
|
+
- related manifest / settings / app_id
|
|
687
|
+
|
|
688
|
+
禁止:
|
|
689
|
+
|
|
690
|
+
- 某个入口自己扫描目录再拼一份检查结果
|
|
691
|
+
- 某个平台 app 自己定义一套不同 check 输出格式
|
|
692
|
+
- 用 warning 文本流代替正式检查报告
|
|
693
|
+
|
|
694
|
+
## 6.9 生命周期状态机的单一路径原则
|
|
695
|
+
|
|
696
|
+
生命周期也必须有唯一正式语义,不允许不同 app、不同入口各自解释 `init/startup/shutdown`。
|
|
697
|
+
|
|
698
|
+
正式状态机固定为:
|
|
699
|
+
|
|
700
|
+
1. declared
|
|
701
|
+
2. compiled
|
|
702
|
+
3. bound
|
|
703
|
+
4. started
|
|
704
|
+
5. stopped
|
|
705
|
+
|
|
706
|
+
状态含义固定如下:
|
|
707
|
+
|
|
708
|
+
- declared
|
|
709
|
+
- app 声明已被读取
|
|
710
|
+
- 尚未进入运行期绑定
|
|
711
|
+
- compiled
|
|
712
|
+
- app 已进入 `RuntimePlan`
|
|
713
|
+
- 所有声明裁决已完成
|
|
714
|
+
- bound
|
|
715
|
+
- provider / facade / registry 已按当前上下文创建
|
|
716
|
+
- 尚未启动长期运行副作用
|
|
717
|
+
- started
|
|
718
|
+
- 必要运行期能力已激活
|
|
719
|
+
- stopped
|
|
720
|
+
- 已完成对称清理
|
|
721
|
+
|
|
722
|
+
正式要求:
|
|
723
|
+
|
|
724
|
+
- `init()` 只允许发生在 declared -> compiled 之间
|
|
725
|
+
- `startup()` 只允许发生在 bound -> started
|
|
726
|
+
- `shutdown()` 只允许发生在 started -> stopped
|
|
727
|
+
- 不允许 `startup()` 补声明
|
|
728
|
+
- 不允许 `shutdown()` 承担新的裁决逻辑
|
|
729
|
+
- Web / CLI / worker / tests 共用同一套生命周期状态机
|
|
730
|
+
|
|
731
|
+
禁止:
|
|
732
|
+
|
|
733
|
+
- 某个 app 自己扩展第二套正式生命周期阶段名
|
|
734
|
+
- 入口层与 app 层对同一钩子有不同语义解释
|
|
735
|
+
- 通过重复调用 `startup()` / `shutdown()` 制造隐式重编译或隐式重绑定
|
|
736
|
+
|
|
737
|
+
## 6.10 错误与诊断编码的单一路径原则
|
|
738
|
+
|
|
739
|
+
错误语义也必须可编排、可测试、可自动化消费。
|
|
740
|
+
|
|
741
|
+
正式要求:
|
|
742
|
+
|
|
743
|
+
- 配置错误、装配错误、能力错误、执行错误使用统一错误编码体系
|
|
744
|
+
- `CheckReport`、CLI `--json` 输出、日志诊断、测试断言都使用同一编码集合
|
|
745
|
+
- 错误编码必须稳定、可枚举、可文档化
|
|
746
|
+
|
|
747
|
+
最少固定四类前缀:
|
|
748
|
+
|
|
749
|
+
- `CFG`
|
|
750
|
+
- 配置与 project context 错误
|
|
751
|
+
- `ASM`
|
|
752
|
+
- app/route/middleware/resource 装配错误
|
|
753
|
+
- `CAP`
|
|
754
|
+
- capability/provider/infra 错误
|
|
755
|
+
- `RUN`
|
|
756
|
+
- 运行期执行与生命周期错误
|
|
757
|
+
|
|
758
|
+
禁止:
|
|
759
|
+
|
|
760
|
+
- 只返回自由文本而没有稳定 code
|
|
761
|
+
- CLI、debug、tests 各自定义不同错误标签
|
|
762
|
+
- 用异常类名或第三方库原始报错直接充当正式对外错误编码
|
|
763
|
+
|
|
764
|
+
## 7. 一次性落地
|
|
765
|
+
|
|
766
|
+
本次不采用分阶段交付策略,目标是一次性完成标准 `pip` 包化重构。
|
|
767
|
+
|
|
768
|
+
但工程上仍固定按以下内部顺序实施:
|
|
769
|
+
|
|
770
|
+
1. 先收口包边界、入口边界、配置边界、运行目录边界
|
|
771
|
+
2. 再收口资源输出、运行目录、可选基础设施
|
|
772
|
+
3. 再完成平台 app、worker、capability、子包适配
|
|
773
|
+
4. 最后补齐测试矩阵、发布说明、迁移说明、子包改造验收
|
|
774
|
+
|
|
775
|
+
要求:
|
|
776
|
+
|
|
777
|
+
- 不允许以“先上半套架构,后续再补”为正式交付方式
|
|
778
|
+
- 一次性实现并不等于无顺序开发,而是最终交付目标必须一次达到新架构要求
|
|
779
|
+
- 子包适配应纳入本次整体交付,而不是延后为未来阶段性工作
|
|
780
|
+
|
|
781
|
+
## 8. DoD
|
|
782
|
+
|
|
783
|
+
达到以下条件时,可认为“标准 pip 包化”基本成立:
|
|
784
|
+
|
|
785
|
+
- `pip install legacy_core` 后可直接通过 `legacy_core` 运行
|
|
786
|
+
- 不依赖仓库根路径、默认 `app` 包或包目录可写
|
|
787
|
+
- 资源、迁移、运行态文件全部落在外部 `cache/runtime dir`
|
|
788
|
+
- 官方维护最小子包与其它最小子包可统一装配与替换
|
|
789
|
+
- SQLite、MySQL、PostgreSQL 均可按需启用
|
|
790
|
+
- 无 DB / 无 Redis 场景可正常运行最小应用
|
|
791
|
+
|
|
792
|
+
交付补全项:
|
|
793
|
+
|
|
794
|
+
- `public.py` / facade / capability contract 与 internal/private 边界已经文档化
|
|
795
|
+
- 旧路径清理清单、一次性替换说明、迁移说明完整
|
|
796
|
+
- 整体交付具备可回滚发布面,不依赖未来追加 phase 才闭环
|
|
797
|
+
|
|
798
|
+
## 9. 生产化补充约束
|
|
799
|
+
|
|
800
|
+
从生产最佳实践看,框架设计除了边界清晰,还必须具备可发布、可回滚、可支持、可诊断。
|
|
801
|
+
|
|
802
|
+
### 9.1 支持策略
|
|
803
|
+
|
|
804
|
+
正式要求:
|
|
805
|
+
|
|
806
|
+
- `legacy_core` core 必须声明明确的 Python 版本支持范围
|
|
807
|
+
- `legacy_core` core 必须声明明确的数据库支持范围:
|
|
808
|
+
- SQLite
|
|
809
|
+
- MySQL
|
|
810
|
+
- PostgreSQL
|
|
811
|
+
- 每个官方维护最小子包 / 独立 app 都必须声明与 core 的版本范围
|
|
812
|
+
- 不允许把“理论上可用”当作正式支持
|
|
813
|
+
|
|
814
|
+
### 9.2 发布与回滚策略
|
|
815
|
+
|
|
816
|
+
正式要求:
|
|
817
|
+
|
|
818
|
+
- 每次 core 发布都必须具备:
|
|
819
|
+
- 升级说明
|
|
820
|
+
- 破坏性变更说明
|
|
821
|
+
- 回滚说明
|
|
822
|
+
- 目录边界、迁移归属、settings 字段、错误编码一旦变更,必须进入发布说明
|
|
823
|
+
- 不允许通过隐藏开关或未文档化回退逻辑充当回滚机制
|
|
824
|
+
|
|
825
|
+
### 9.3 运行成本边界
|
|
826
|
+
|
|
827
|
+
正式要求:
|
|
828
|
+
|
|
829
|
+
- base 安装启动最小应用时,不应默认初始化 DB、Redis、metrics exporter、asset build、worker loop
|
|
830
|
+
- `pz check`、`pz list`、`pz --help` 这类基础命令必须保持轻量,不触发重依赖初始化
|
|
831
|
+
- 资源编译、preflight、迁移工具必须显式进入,不得混入常规启动热路径
|
|
832
|
+
|
|
833
|
+
### 9.4 core freeze / extension-first
|
|
834
|
+
|
|
835
|
+
本次 `legacy_core` 重构完成后,`legacy_core` 内核进入冻结治理。
|
|
836
|
+
|
|
837
|
+
正式要求:
|
|
838
|
+
|
|
839
|
+
- 重构完成后的 `legacy_core` 不再作为持续承载新功能的默认落位
|
|
840
|
+
- 后续所有 `pz` 相关增量需求,默认进入官方扩展包,而不是继续修改 `legacy_core`
|
|
841
|
+
- 官方扩展包的正式落位为官方最小子包源码根,或单独发布的官方最小子包
|
|
842
|
+
- 只有框架级公共契约、编译边界、运行边界、诊断边界、安全修复与缺陷修复,才允许继续修改 `legacy_core`
|
|
843
|
+
- 任何业务能力、平台能力、provider 实现、共享 middleware、站点能力、任务能力、运维能力,均不得再回灌到 `legacy_core`
|
|
844
|
+
|
|
845
|
+
判断标准:
|
|
846
|
+
|
|
847
|
+
- 若一个改动离开某个具体官方扩展包或具体业务 app 后仍然成立,才有资格评估是否进入 `legacy_core`
|
|
848
|
+
- 若一个改动主要服务于某类 app、某类 provider、某类站点/平台场景,则必须进入官方扩展包
|
|
849
|
+
- 不能证明“这是框架级公共边界”的改动,一律不得进入 `legacy_core`
|
|
850
|
+
|
|
851
|
+
### 9.5 生产红线
|
|
852
|
+
|
|
853
|
+
正式红线如下:
|
|
854
|
+
|
|
855
|
+
- 不把 `warning + continue` 当作生产可接受语义
|
|
856
|
+
- 不把 import-time 单例当作生产稳定边界
|
|
857
|
+
- 不把 repo-root/cwd 猜测当作生产项目发现机制
|
|
858
|
+
- 不把 debug/dev surface 当作默认公开能力
|
|
859
|
+
- 不把“后续再补测试/文档/回滚”当作可接受交付
|
|
860
|
+
|
|
861
|
+
## 10. 进入代码重构前的最终红线清单
|
|
862
|
+
|
|
863
|
+
以下红线在进入代码重构前必须视为不可退让约束:
|
|
864
|
+
|
|
865
|
+
1. 不允许再新增第二套真相源。
|
|
866
|
+
2. 不允许 `startup()`、`lifespan`、adapter 层补编译逻辑。
|
|
867
|
+
3. 不允许新增 import-time 全局单例或全局 setter 主链。
|
|
868
|
+
4. 不允许继续依赖 repo-root、`cwd`、`ROOT_DIR`、包目录可写。
|
|
869
|
+
5. 不允许 core 直接依赖具体官方维护最小子包 / 独立子包内部实现。
|
|
870
|
+
6. 不允许独立子包被其它 app 直接 import 其内部模块。
|
|
871
|
+
7. 不允许 middleware 继续走类路径去重、反射补参、后写覆盖。
|
|
872
|
+
8. 不允许 system checks 出现第二套入口或第二套输出格式。
|
|
873
|
+
9. 不允许 CLI / Web / worker 拥有不同生命周期语义和错误编码。
|
|
874
|
+
10. 不允许 base 安装命令路径依赖可选基础设施或重型 extras。
|
|
875
|
+
11. 不允许 warning-only 半初始化结果进入正式运行态。
|
|
876
|
+
12. 不允许发布时缺失升级说明、回滚说明、版本范围说明。
|
|
877
|
+
|
|
878
|
+
执行要求:
|
|
879
|
+
|
|
880
|
+
- 任一红线被打破,都不应视为“局部可接受实现”
|
|
881
|
+
- 必须先修架构问题,再继续上层功能开发
|
|
882
|
+
|
|
883
|
+
## 附录 A. `legacy_core core` 边界总表
|
|
884
|
+
|
|
885
|
+
### A.1 `legacy_core core` 的正式定位
|
|
886
|
+
|
|
887
|
+
`legacy_core core` 的正式定位只有一个:
|
|
888
|
+
|
|
889
|
+
- 标准框架内核与装配层
|
|
890
|
+
|
|
891
|
+
它负责:
|
|
892
|
+
|
|
893
|
+
- 定义正式契约
|
|
894
|
+
- 编译运行计划
|
|
895
|
+
- 组装正式运行边界
|
|
896
|
+
- 提供标准入口
|
|
897
|
+
|
|
898
|
+
它不负责:
|
|
899
|
+
|
|
900
|
+
- 业务能力实现
|
|
901
|
+
- 平台 app 具体实现
|
|
902
|
+
- 具体第三方服务集成
|
|
903
|
+
- 监控平台、任务平台、邮件平台本身
|
|
904
|
+
|
|
905
|
+
进入 `core` 的唯一门槛:
|
|
906
|
+
|
|
907
|
+
- 该内容在没有任何官方 app、独立子包、具体 provider、具体 middleware 实现时仍然成立
|
|
908
|
+
- 该内容必须以契约、声明模型、纯规则或纯校验逻辑存在
|
|
909
|
+
- 该内容不得依赖具体运行时副作用、具体目录真相源、具体 app/provider 名称
|
|
910
|
+
|
|
911
|
+
### A.2 `legacy_core core` 正式提供什么
|
|
912
|
+
|
|
913
|
+
- `ProjectContext`
|
|
914
|
+
- `SettingsSnapshot`
|
|
915
|
+
- `AppRegistry`
|
|
916
|
+
- `RouteManifest`
|
|
917
|
+
- `MiddlewareManifest`
|
|
918
|
+
- `ResourceManifest`
|
|
919
|
+
- `InfraSettings`
|
|
920
|
+
- `InfraContext`
|
|
921
|
+
- `CapabilityRegistry`
|
|
922
|
+
- project context compiler
|
|
923
|
+
- settings compiler
|
|
924
|
+
- app registry compiler
|
|
925
|
+
- route / middleware / resource compiler
|
|
926
|
+
- infra snapshot compiler
|
|
927
|
+
- `RuntimePlan` compiler
|
|
928
|
+
- Web / CLI / worker 标准入口流水线
|
|
929
|
+
- capability 激活与 shutdown 边界
|
|
930
|
+
- facade / provider / adapter 的组装边界
|
|
931
|
+
- `pz`
|
|
932
|
+
- `pz.app`
|
|
933
|
+
- system checks 正式入口
|
|
934
|
+
|
|
935
|
+
补充约束:
|
|
936
|
+
|
|
937
|
+
- 这里的“装配”只表示正式边界、声明模型和统一入口链,不表示具体 app mutation、startup 副作用、client 初始化
|
|
938
|
+
- `core` 可以定义 route / middleware / resource / capability 的声明模型与校验规则,但不承载其具体实现
|
|
939
|
+
- `ResourceManifest` 的正式公开结构应收敛到 `items + sources + manifest_path + output_root + staging_root + lock_path`
|
|
940
|
+
|
|
941
|
+
### A.3 `legacy_core core` 明确不提供什么
|
|
942
|
+
|
|
943
|
+
- 不提供业务 app
|
|
944
|
+
- 不提供任何 app 具体实现
|
|
945
|
+
- 不提供 shared site UI owner / settings runtime owner / task dispatch owner 这类平台 app 的具体实现
|
|
946
|
+
- 不提供 PostgreSQL / MySQL / Redis / SMTP / S3 / GCS / exporter / bot handler 这类具体后端与共享实现
|
|
947
|
+
- 不提供共享 middleware 的具体类
|
|
948
|
+
- 不提供模板渲染、i18n、Jinja、静态资源服务的具体运行时实现
|
|
949
|
+
- 不提供 `startup()` / `shutdown()` 的具体副作用
|
|
950
|
+
- 不直接初始化 DB / Redis / mail / storage client
|
|
951
|
+
- 不直接 mount static / uploads
|
|
952
|
+
- 不直接注册 FastAPI 错误处理器、HTTP middleware 类、ASGI app mutation 流程
|
|
953
|
+
- 不直接做资源 merge、迁移 merge、文件系统写入
|
|
954
|
+
- 不提供 repo-root / `cwd` 驱动心智
|
|
955
|
+
- 不提供 import-time 全局单例主链
|
|
956
|
+
- 不提供第二套 settings / app / resource / infra 真相源
|
|
957
|
+
- 不承载脚手架、debug/dev/ops surface、临时旧入口的长期正式落位
|
|
958
|
+
|
|
959
|
+
### A.4 `legacy_core core` 与其它层的关系
|
|
960
|
+
|
|
961
|
+
对 `infra`:
|
|
962
|
+
|
|
963
|
+
- `core` 只消费 `InfraContext`、typed contract、capability 结果
|
|
964
|
+
- `core` 不直接依赖 `infra` 的旧 manager / 默认 client / setter 主链
|
|
965
|
+
|
|
966
|
+
对官方维护最小子包:
|
|
967
|
+
|
|
968
|
+
- 官方维护最小子包是普通 app
|
|
969
|
+
- `core` 不直接依赖某个具体官方 app 内部实现
|
|
970
|
+
- `core` 只依赖 capability / facade / contract
|
|
971
|
+
|
|
972
|
+
对独立子包:
|
|
973
|
+
|
|
974
|
+
- `<app_id>` 是普通独立子包
|
|
975
|
+
- `core` 不把独立子包当内部模块
|
|
976
|
+
- 独立子包只通过正式边界接入运行图
|
|
977
|
+
|
|
978
|
+
对 provider package / extras:
|
|
979
|
+
|
|
980
|
+
- `core` 只定义 provider contract 与 binding 边界
|
|
981
|
+
- 具体 provider 通过 extras 或独立 package 接入
|
|
982
|
+
|
|
983
|
+
### A.5 `core` 内部统一原则
|
|
984
|
+
|
|
985
|
+
`core` 必须保持为“纯规则和纯契约层”,不能再混成“框架剩余物收容站”。
|
|
986
|
+
|
|
987
|
+
统一要求:
|
|
988
|
+
|
|
989
|
+
- 同一文件若依赖具体 app、具体 provider、具体 middleware 类、具体目录真相源,就不应留在 `core`
|
|
990
|
+
- 同一能力若既在 `core` 定义契约、又在 `core` 承载具体实现,必须拆分
|
|
991
|
+
- `core` 中允许存在 FastAPI / CLI 相关的最小声明类型,但不允许存在具体装配副作用
|
|
992
|
+
- `core` 中不允许再出现官方 app 内部模块路径、独立子包内部模块路径、具体 `legacy_core.infra.*` 实现路径作为正式依赖真相
|
|
993
|
+
|
|
994
|
+
判断一个目录是否算“统一的 core”,只看三条:
|
|
995
|
+
|
|
996
|
+
1. 是否不依赖具体 app 真相。
|
|
997
|
+
2. 是否不依赖具体 infra/provider 真相。
|
|
998
|
+
3. 是否不携带执行期副作用。
|
|
999
|
+
|
|
1000
|
+
三条任意一条不满足,就说明它不该留在 `core`。
|
|
1001
|
+
|
|
1002
|
+
### A.6 `core/*` 的目标边界划分
|
|
1003
|
+
|
|
1004
|
+
可以保留在 `core`:
|
|
1005
|
+
|
|
1006
|
+
- `events`
|
|
1007
|
+
- 只保留事件 contract、topic/handler 协议、纯内存/纯声明模型
|
|
1008
|
+
- `extensions`
|
|
1009
|
+
- 只保留 extension declaration、registry contract
|
|
1010
|
+
- `routing`
|
|
1011
|
+
- 只保留 route declaration、顺序规则、冲突校验、纯 registry model
|
|
1012
|
+
- `health`
|
|
1013
|
+
- 只保留 health contract、result model、capability 聚合规则
|
|
1014
|
+
- `errors`
|
|
1015
|
+
- 只保留错误 envelope、错误码、异常 contract
|
|
1016
|
+
|
|
1017
|
+
应迁入 `assembly`:
|
|
1018
|
+
|
|
1019
|
+
- `apps`
|
|
1020
|
+
- app declaration、registry contract、替换规则、依赖校验规则与 compiler 归 `assembly/apps`
|
|
1021
|
+
- `settings`
|
|
1022
|
+
- settings schema、settings compiler、app settings 编译、middleware/resource/app registry 编译
|
|
1023
|
+
- `middlewares`
|
|
1024
|
+
- `MiddlewareDecl`、`MiddlewareManifest`、middleware compiler 与纯校验归 `assembly/middlewares`
|
|
1025
|
+
- `ops`
|
|
1026
|
+
- 只要本质是预处理、编译、归并、校验、扫描,都归 `assembly`
|
|
1027
|
+
- `resources`
|
|
1028
|
+
- 资源目录发现、merge 计划、manifest 编译归 `assembly`
|
|
1029
|
+
|
|
1030
|
+
应迁入 `runtime`:
|
|
1031
|
+
|
|
1032
|
+
- `app_factory`
|
|
1033
|
+
- FastAPI app 创建、route/middleware/resource 装配、lifespan、startup/shutdown 流程
|
|
1034
|
+
- `deps`
|
|
1035
|
+
- request/app.state/runtime helper
|
|
1036
|
+
- `health/router.py`
|
|
1037
|
+
- readiness/liveness 的 HTTP 暴露
|
|
1038
|
+
- `errors/handlers.py`
|
|
1039
|
+
- FastAPI/ASGI 错误处理器注册
|
|
1040
|
+
- `routing` 中直接操作 `FastAPI` 的部分
|
|
1041
|
+
|
|
1042
|
+
应迁出到 app 层:
|
|
1043
|
+
|
|
1044
|
+
- `middlewares`
|
|
1045
|
+
- 具体 middleware 类全部迁出;共享实现进官方基础能力最小子包,app 专属实现进对应 app
|
|
1046
|
+
- `resources` 中依赖展示层、模板、静态服务的实现
|
|
1047
|
+
- 迁到官方基础能力最小子包或对应 app
|
|
1048
|
+
|
|
1049
|
+
应迁出到 `infra` 或 provider/app 层:
|
|
1050
|
+
|
|
1051
|
+
- `storage`
|
|
1052
|
+
- `core` 只保留 `StoragePort` 级 contract;具体 driver、provider 选择、S3/local 绑定迁出
|
|
1053
|
+
- 任何直接 import `legacy_core.infra.*` 具体实现的逻辑
|
|
1054
|
+
- 一律改成 contract / facade / runtime helper
|
|
1055
|
+
|
|
1056
|
+
`core` 最终保留的二级目录以 `01-目录与分层重构执行方案.md` 为准。
|
|
1057
|
+
|
|
1058
|
+
补充约束:
|
|
1059
|
+
|
|
1060
|
+
- `core/` 不设 `apps/` 子目录
|
|
1061
|
+
- `core/` 不再保留 `app_factory/`、`ops/`、`resources/`、`cli/`、`deps.py`、运行时 helper
|
|
1062
|
+
|
|
1063
|
+
### A.7 `legacy_core core` 的最小完成定义
|
|
1064
|
+
|
|
1065
|
+
当以下条件同时满足,才算 `legacy_core core` 边界成立:
|
|
1066
|
+
|
|
1067
|
+
- base 安装可运行最小 app
|
|
1068
|
+
- `RuntimePlan` 成为唯一组合根
|
|
1069
|
+
- Web / CLI / worker 共用同一入口流水线
|
|
1070
|
+
- 官方 app / 独立子包都不再被当作 core 特权内容
|
|
1071
|
+
- DB / Redis / metrics / mail / storage 都作为可选 capability 表达
|
|
1072
|
+
- `core` 内不再直接依赖具体官方 app / 独立子包 / infra 实现路径
|
|
1073
|
+
- `core` 内不再保留具体 middleware、resource runtime、static mount、startup side effect
|