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.
Files changed (399) hide show
  1. pz_cli-5.0.0.dist-info/METADATA +51 -0
  2. pz_cli-5.0.0.dist-info/RECORD +399 -0
  3. pz_cli-5.0.0.dist-info/WHEEL +4 -0
  4. pz_cli-5.0.0.dist-info/entry_points.txt +5 -0
  5. pz_core/__init__.py +64 -0
  6. pz_core/__main__.py +7 -0
  7. pz_core/app.py +45 -0
  8. pz_core/assembly/__init__.py +17 -0
  9. pz_core/assembly/app_discovery.py +1240 -0
  10. pz_core/assembly/apps/__init__.py +25 -0
  11. pz_core/assembly/apps/compiler.py +824 -0
  12. pz_core/assembly/apps/providers.py +188 -0
  13. pz_core/assembly/cli/__init__.py +9 -0
  14. pz_core/assembly/cli/compiler.py +166 -0
  15. pz_core/assembly/diagnostics/__init__.py +21 -0
  16. pz_core/assembly/diagnostics/checks.py +257 -0
  17. pz_core/assembly/diagnostics/dev_sources.py +569 -0
  18. pz_core/assembly/events/__init__.py +5 -0
  19. pz_core/assembly/events/compiler.py +219 -0
  20. pz_core/assembly/extensions/__init__.py +5 -0
  21. pz_core/assembly/extensions/compiler.py +696 -0
  22. pz_core/assembly/infra/__init__.py +6 -0
  23. pz_core/assembly/infra/compiler.py +272 -0
  24. pz_core/assembly/lifecycle/__init__.py +5 -0
  25. pz_core/assembly/lifecycle/compiler.py +95 -0
  26. pz_core/assembly/middlewares/__init__.py +19 -0
  27. pz_core/assembly/middlewares/compiler.py +508 -0
  28. pz_core/assembly/project/__init__.py +7 -0
  29. pz_core/assembly/project/compiler.py +9 -0
  30. pz_core/assembly/project/context.py +17 -0
  31. pz_core/assembly/project/discovery.py +227 -0
  32. pz_core/assembly/resources/__init__.py +19 -0
  33. pz_core/assembly/resources/compiler.py +310 -0
  34. pz_core/assembly/resources/settings.py +129 -0
  35. pz_core/assembly/routes/__init__.py +7 -0
  36. pz_core/assembly/routes/compiler.py +400 -0
  37. pz_core/assembly/runtime_manifests/__init__.py +13 -0
  38. pz_core/assembly/runtime_manifests/compiler.py +159 -0
  39. pz_core/assembly/settings/__init__.py +17 -0
  40. pz_core/assembly/settings/compiler.py +786 -0
  41. pz_core/assembly/settings/host_project_overrides.py +82 -0
  42. pz_core/assembly/settings/host_runtime_endpoint.py +207 -0
  43. pz_core/authoring/__init__.py +79 -0
  44. pz_core/authoring/app_init_service.py +946 -0
  45. pz_core/authoring/app_versions.py +814 -0
  46. pz_core/authoring/cli.py +192 -0
  47. pz_core/authoring/commands.py +1810 -0
  48. pz_core/authoring/conflicts.py +180 -0
  49. pz_core/authoring/dev_bindings.py +916 -0
  50. pz_core/authoring/dev_git.py +1087 -0
  51. pz_core/authoring/dev_import.py +1061 -0
  52. pz_core/authoring/dev_manifest.py +522 -0
  53. pz_core/authoring/dev_sources.py +1638 -0
  54. pz_core/authoring/env_cli.py +454 -0
  55. pz_core/authoring/files.py +109 -0
  56. pz_core/authoring/ide_projection.py +1129 -0
  57. pz_core/authoring/naming.py +58 -0
  58. pz_core/authoring/official_dev_sources.py +432 -0
  59. pz_core/authoring/official_sources.json +156 -0
  60. pz_core/authoring/orchestration_service.py +558 -0
  61. pz_core/authoring/project_default.jsonc +53 -0
  62. pz_core/authoring/project_defaults.py +88 -0
  63. pz_core/authoring/project_metadata_service.py +199 -0
  64. pz_core/authoring/project_settings_checks.py +51 -0
  65. pz_core/authoring/project_settings_cli.py +299 -0
  66. pz_core/authoring/project_settings_service.py +1700 -0
  67. pz_core/authoring/project_state.py +399 -0
  68. pz_core/authoring/publish_git.py +423 -0
  69. pz_core/authoring/publish_lock.py +188 -0
  70. pz_core/authoring/publish_source.py +195 -0
  71. pz_core/authoring/release.py +1382 -0
  72. pz_core/authoring/repo_keys.py +29 -0
  73. pz_core/authoring/root_cli.py +28 -0
  74. pz_core/authoring/scaffold_service.py +325 -0
  75. pz_core/authoring/sync_service.py +787 -0
  76. pz_core/authoring/templates/app/__init__.py +1 -0
  77. pz_core/authoring/templates/app/api.py +25 -0
  78. pz_core/authoring/templates/app/apps.py +31 -0
  79. pz_core/authoring/templates/app/auth_package_init.py +14 -0
  80. pz_core/authoring/templates/app/auth_readme.py +29 -0
  81. pz_core/authoring/templates/app/configs_package_init.py +14 -0
  82. pz_core/authoring/templates/app/default_env.py +18 -0
  83. pz_core/authoring/templates/app/default_jsonc.py +25 -0
  84. pz_core/authoring/templates/app/locales_readme.py +25 -0
  85. pz_core/authoring/templates/app/migrations_readme.py +19 -0
  86. pz_core/authoring/templates/app/models.py +14 -0
  87. pz_core/authoring/templates/app/package_init.py +8 -0
  88. pz_core/authoring/templates/app/pages_base.py +161 -0
  89. pz_core/authoring/templates/app/pages_readme.py +25 -0
  90. pz_core/authoring/templates/app/public.py +31 -0
  91. pz_core/authoring/templates/app/pyproject.py +77 -0
  92. pz_core/authoring/templates/app/readme.py +74 -0
  93. pz_core/authoring/templates/app/settings.py +46 -0
  94. pz_core/authoring/templates/app/static_app_js.py +24 -0
  95. pz_core/authoring/templates/app/static_readme.py +31 -0
  96. pz_core/authoring/templates/app/template_config_page.py +23 -0
  97. pz_core/authoring/templates/app/template_index_html.py +28 -0
  98. pz_core/authoring/templates/app/templates_readme.py +32 -0
  99. pz_core/authoring/templates/app/urls.py +36 -0
  100. pz_core/authoring/templates/app/views.py +36 -0
  101. pz_core/authoring/templates/project/__init__.py +1 -0
  102. pz_core/authoring/templates/project/agents.py +51 -0
  103. pz_core/authoring/templates/project/apps_container_readme.py +37 -0
  104. pz_core/authoring/templates/project/main_py.py +59 -0
  105. pz_core/authoring/templates/project/project_env.py +19 -0
  106. pz_core/authoring/templates/project/pyproject.py +26 -0
  107. pz_core/authoring/templates/project/pz_env_env.py +65 -0
  108. pz_core/authoring/templates/project/pz_env_jsonc.py +69 -0
  109. pz_core/authoring/templates/project/pz_jsonc.py +12 -0
  110. pz_core/authoring/templates/project/readme.py +94 -0
  111. pz_core/authoring/templates/project/root_gitkeep.py +8 -0
  112. pz_core/authoring/templates/shared/__init__.py +5 -0
  113. pz_core/authoring/templates/shared/text.py +10 -0
  114. pz_core/authoring/venv_service.py +87 -0
  115. pz_core/authoring/workspace.py +167 -0
  116. pz_core/cli.py +291 -0
  117. pz_core/cli_options.py +74 -0
  118. pz_core/core/__init__.py +3 -0
  119. pz_core/core/errors/__init__.py +5 -0
  120. pz_core/core/errors/models.py +117 -0
  121. pz_core/core/events/__init__.py +5 -0
  122. pz_core/core/events/registry.py +54 -0
  123. pz_core/core/extensions/__init__.py +51 -0
  124. pz_core/core/extensions/registry.py +790 -0
  125. pz_core/core/health/__init__.py +6 -0
  126. pz_core/core/health/contracts.py +10 -0
  127. pz_core/core/middlewares/__init__.py +6 -0
  128. pz_core/core/middlewares/models.py +24 -0
  129. pz_core/core/routing/__init__.py +5 -0
  130. pz_core/core/routing/models.py +21 -0
  131. pz_core/core/settings_contracts.py +25 -0
  132. pz_core/docs/README.md +20 -0
  133. pz_core/docs/distribution-README.md +438 -0
  134. pz_core/docs/pz/345/221/275/344/273/244/346/200/273/350/247/210.md +1011 -0
  135. 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
  136. 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
  137. 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
  138. 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
  139. 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
  140. 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
  141. 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
  142. 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
  143. 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
  144. 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
  145. 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
  146. 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
  147. 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
  148. 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
  149. 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
  150. 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
  151. 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
  152. 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
  153. 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
  154. 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
  155. 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
  156. 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
  157. 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
  158. 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
  159. 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
  160. 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
  161. pz_core/docs/pz/350/247/204/350/214/203/344/270/216/344/275/277/347/224/250/README.md +98 -0
  162. 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
  163. 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
  164. 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
  165. 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
  166. 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
  167. 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
  168. 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
  169. 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
  170. 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
  171. 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
  172. 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
  173. pz_core/docs//345/217/221/347/211/210/345/211/215/346/270/205/345/215/225-4.0.11.md +84 -0
  174. pz_core/docs//346/226/260/346/211/213/346/214/207/345/215/227.md +422 -0
  175. pz_core/infra/__init__.py +17 -0
  176. pz_core/infra/db/__init__.py +23 -0
  177. pz_core/infra/db/contracts.py +73 -0
  178. pz_core/infra/health/__init__.py +5 -0
  179. pz_core/infra/health/contracts.py +8 -0
  180. pz_core/infra/kv/__init__.py +5 -0
  181. pz_core/infra/kv/contracts.py +17 -0
  182. pz_core/infra/observability/__init__.py +23 -0
  183. pz_core/infra/observability/contracts.py +142 -0
  184. pz_core/infra/resilience/__init__.py +5 -0
  185. pz_core/infra/resilience/contracts.py +17 -0
  186. pz_core/infra/resources/__init__.py +5 -0
  187. pz_core/infra/resources/contracts.py +16 -0
  188. pz_core/infra/settings/__init__.py +17 -0
  189. pz_core/infra/settings/models.py +81 -0
  190. pz_core/infra/storage/__init__.py +5 -0
  191. pz_core/infra/storage/ports.py +27 -0
  192. pz_core/project_root_commands.py +282 -0
  193. pz_core/project_runtime_cli.py +344 -0
  194. pz_core/project_sources.py +253 -0
  195. pz_core/pz_launcher.py +209 -0
  196. pz_core/root_cli.py +70 -0
  197. pz_core/runtime/__init__.py +229 -0
  198. pz_core/runtime/access.py +86 -0
  199. pz_core/runtime/adapters/__init__.py +5 -0
  200. pz_core/runtime/adapters/base.py +18 -0
  201. pz_core/runtime/asyncio_bridge.py +18 -0
  202. pz_core/runtime/bindings/__init__.py +5 -0
  203. pz_core/runtime/bindings/container.py +50 -0
  204. pz_core/runtime/cli/__init__.py +5 -0
  205. pz_core/runtime/cli/_args.py +67 -0
  206. pz_core/runtime/cli/app_commands.py +417 -0
  207. pz_core/runtime/cli/check.py +214 -0
  208. pz_core/runtime/cli/db.py +297 -0
  209. pz_core/runtime/cli/main.py +89 -0
  210. pz_core/runtime/cli/resources.py +280 -0
  211. pz_core/runtime/discovery.py +23 -0
  212. pz_core/runtime/environment_integrity.py +157 -0
  213. pz_core/runtime/errors.py +5 -0
  214. pz_core/runtime/events.py +87 -0
  215. pz_core/runtime/facades/__init__.py +38 -0
  216. pz_core/runtime/facades/_capabilities.py +46 -0
  217. pz_core/runtime/facades/cache.py +103 -0
  218. pz_core/runtime/facades/database.py +71 -0
  219. pz_core/runtime/facades/events.py +380 -0
  220. pz_core/runtime/facades/health.py +101 -0
  221. pz_core/runtime/facades/mail.py +121 -0
  222. pz_core/runtime/facades/observability.py +102 -0
  223. pz_core/runtime/facades/providers.py +75 -0
  224. pz_core/runtime/facades/resources.py +52 -0
  225. pz_core/runtime/facades/storage.py +296 -0
  226. pz_core/runtime/health/__init__.py +5 -0
  227. pz_core/runtime/health/service.py +102 -0
  228. pz_core/runtime/host.py +188 -0
  229. pz_core/runtime/host_runner.py +282 -0
  230. pz_core/runtime/http/__init__.py +20 -0
  231. pz_core/runtime/http/app.py +576 -0
  232. pz_core/runtime/http_timing.py +173 -0
  233. pz_core/runtime/invocation.py +29 -0
  234. pz_core/runtime/json_safe.py +47 -0
  235. pz_core/runtime/lifecycle/__init__.py +25 -0
  236. pz_core/runtime/lifecycle/manager.py +533 -0
  237. pz_core/runtime/plan.py +214 -0
  238. pz_core/runtime/plan_context.py +33 -0
  239. pz_core/runtime/plan_snapshot.py +177 -0
  240. pz_core/runtime/registries/__init__.py +27 -0
  241. pz_core/runtime/registries/capabilities.py +101 -0
  242. pz_core/runtime/registries/providers.py +396 -0
  243. pz_core/runtime/resource_assets.py +344 -0
  244. pz_core/runtime/run_cli.py +211 -0
  245. pz_core/runtime/settings.py +888 -0
  246. pz_core/runtime/worker/__init__.py +21 -0
  247. pz_core/runtime/worker/engine.py +921 -0
  248. pz_core/runtime/worker/runtime.py +25 -0
  249. pz_core/testing/__init__.py +15 -0
  250. pz_core/testing/doc_route_contracts.py +305 -0
  251. pz_core/utils/__init__.py +44 -0
  252. pz_core/utils/env.py +65 -0
  253. pz_core/utils/project_jsonc/__init__.py +29 -0
  254. pz_core/utils/project_jsonc/document.py +420 -0
  255. pz_core/utils/project_settings.py +99 -0
  256. pz_foundation/__init__.py +50 -0
  257. pz_foundation/_contracts.py +81 -0
  258. pz_foundation/_errors.py +34 -0
  259. pz_foundation/api.py +14 -0
  260. pz_foundation/apps.py +127 -0
  261. pz_foundation/auth/__init__.py +1 -0
  262. pz_foundation/cache_control.py +233 -0
  263. pz_foundation/cli/__init__.py +2 -0
  264. pz_foundation/cli/workers.py +565 -0
  265. pz_foundation/configs/__init__.py +0 -0
  266. pz_foundation/configs/default.env +15 -0
  267. pz_foundation/configs/default.jsonc +452 -0
  268. pz_foundation/db/__init__.py +94 -0
  269. pz_foundation/db/aerich_executor.py +664 -0
  270. pz_foundation/db/config.py +358 -0
  271. pz_foundation/db/connection_manager.py +689 -0
  272. pz_foundation/db/connection_probe.py +204 -0
  273. pz_foundation/db/database.py +1291 -0
  274. pz_foundation/db/deps.py +47 -0
  275. pz_foundation/db/lifecycle_status.py +85 -0
  276. pz_foundation/db/migrations.py +477 -0
  277. pz_foundation/db/mysql.py +57 -0
  278. pz_foundation/db/postgresql.py +409 -0
  279. pz_foundation/db/production_pool_fallback.py +143 -0
  280. pz_foundation/db/public.py +45 -0
  281. pz_foundation/db/session.py +369 -0
  282. pz_foundation/db/sqlite.py +15 -0
  283. pz_foundation/db/tortoise_manager.py +724 -0
  284. pz_foundation/db/tortoise_psycopg.py +148 -0
  285. pz_foundation/docs/README.md +18 -0
  286. pz_foundation/docs/distribution-README.md +319 -0
  287. 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
  288. 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
  289. pz_foundation/docs//350/256/276/350/256/241/346/226/207/346/241/243.md +288 -0
  290. 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
  291. pz_foundation/health.py +105 -0
  292. pz_foundation/host/__init__.py +11 -0
  293. pz_foundation/host/builder.py +34 -0
  294. pz_foundation/host/cache_runtime.py +44 -0
  295. pz_foundation/host/db/__init__.py +17 -0
  296. pz_foundation/host/db/aerich_config.py +36 -0
  297. pz_foundation/host/db/config.py +106 -0
  298. pz_foundation/host/db/connection_manager.py +48 -0
  299. pz_foundation/host/db/deps.py +5 -0
  300. pz_foundation/host/db/orm_retry_patch.py +566 -0
  301. pz_foundation/host/db/request_adapter.py +325 -0
  302. pz_foundation/host/db/router.py +28 -0
  303. pz_foundation/host/db/session.py +284 -0
  304. pz_foundation/host/db/tortoise_manager.py +10 -0
  305. pz_foundation/host/idempotency.py +132 -0
  306. pz_foundation/host/lifespan.py +247 -0
  307. pz_foundation/host/redis_runtime.py +100 -0
  308. pz_foundation/host/web.py +790 -0
  309. pz_foundation/infra_provider.py +236 -0
  310. pz_foundation/kv/__init__.py +25 -0
  311. pz_foundation/kv/cache.py +1166 -0
  312. pz_foundation/kv/deps.py +84 -0
  313. pz_foundation/kv/public.py +25 -0
  314. pz_foundation/kv/redis_manager.py +1531 -0
  315. pz_foundation/lazy_exports.py +43 -0
  316. pz_foundation/lazy_imports.py +124 -0
  317. pz_foundation/lifecycle.py +392 -0
  318. pz_foundation/managed_workers.py +1117 -0
  319. pz_foundation/middlewares/__init__.py +26 -0
  320. pz_foundation/middlewares/_settings.py +250 -0
  321. pz_foundation/middlewares/analytics.py +124 -0
  322. pz_foundation/middlewares/cache_control.py +156 -0
  323. pz_foundation/middlewares/compression.py +202 -0
  324. pz_foundation/middlewares/cors.py +62 -0
  325. pz_foundation/middlewares/geo_country.py +44 -0
  326. pz_foundation/middlewares/inner_router.py +50 -0
  327. pz_foundation/middlewares/rate_limited/__init__.py +3 -0
  328. pz_foundation/middlewares/rate_limited/key_limiter.py +115 -0
  329. pz_foundation/middlewares/request_logging.py +104 -0
  330. pz_foundation/middlewares/route_owner.py +309 -0
  331. pz_foundation/middlewares/security_csrf.py +44 -0
  332. pz_foundation/middlewares/security_headers/__init__.py +4 -0
  333. pz_foundation/middlewares/security_headers/conflicts.py +44 -0
  334. pz_foundation/middlewares/security_headers/csp_nonce.py +200 -0
  335. pz_foundation/middlewares/security_headers/security_headers.py +44 -0
  336. pz_foundation/migrations/__init__.py +1 -0
  337. pz_foundation/migrations/pz_foundation/__init__.py +1 -0
  338. pz_foundation/models.py +22 -0
  339. pz_foundation/notifications/__init__.py +23 -0
  340. pz_foundation/notifications/email.py +542 -0
  341. pz_foundation/notifications/public.py +31 -0
  342. pz_foundation/observability/__init__.py +71 -0
  343. pz_foundation/observability/http.py +34 -0
  344. pz_foundation/observability/logger/__init__.py +49 -0
  345. pz_foundation/observability/logger/_bot_settings.py +126 -0
  346. pz_foundation/observability/logger/bot_message.py +592 -0
  347. pz_foundation/observability/logger/core.py +385 -0
  348. pz_foundation/observability/logger/delivery_audit.py +84 -0
  349. pz_foundation/observability/logger/feishu_bot.py +199 -0
  350. pz_foundation/observability/logger/telegram_bot.py +194 -0
  351. pz_foundation/observability/metrics.py +365 -0
  352. pz_foundation/observability/runtime.py +68 -0
  353. pz_foundation/public.py +405 -0
  354. pz_foundation/resources/__init__.py +12 -0
  355. pz_foundation/resources/builder.py +900 -0
  356. pz_foundation/resources/images.py +363 -0
  357. pz_foundation/root_cli.py +20 -0
  358. pz_foundation/routing/__init__.py +203 -0
  359. pz_foundation/routing/canonical.py +486 -0
  360. pz_foundation/routing/convertors.py +82 -0
  361. pz_foundation/routing/declarations.py +843 -0
  362. pz_foundation/routing/exports.py +148 -0
  363. pz_foundation/routing/loaders.py +138 -0
  364. pz_foundation/routing/manifest.py +215 -0
  365. pz_foundation/routing/manifest_provider.py +47 -0
  366. pz_foundation/routing/mounts.py +101 -0
  367. pz_foundation/routing/ordering.py +172 -0
  368. pz_foundation/routing/registry.py +133 -0
  369. pz_foundation/routing/utils.py +28 -0
  370. pz_foundation/runtime.py +234 -0
  371. pz_foundation/settings.py +253 -0
  372. pz_foundation/settings_normalization.py +130 -0
  373. pz_foundation/storage/__init__.py +25 -0
  374. pz_foundation/storage/local.py +209 -0
  375. pz_foundation/storage/public.py +106 -0
  376. pz_foundation/storage/s3.py +116 -0
  377. pz_foundation/storage/service.py +234 -0
  378. pz_foundation/urls.py +19 -0
  379. pz_foundation/utils/__init__.py +6 -0
  380. pz_foundation/utils/merge.py +160 -0
  381. pz_foundation/worker_replicas.py +55 -0
  382. pz_settings_center/__init__.py +5 -0
  383. pz_settings_center/api/__init__.py +5 -0
  384. pz_settings_center/api/runtime_overrides.py +360 -0
  385. pz_settings_center/apps.py +28 -0
  386. pz_settings_center/configs/__init__.py +0 -0
  387. pz_settings_center/configs/default.env +2 -0
  388. pz_settings_center/configs/default.jsonc +1 -0
  389. pz_settings_center/docs/01-settings_center/350/203/275/345/212/233/350/276/271/347/225/214.md +124 -0
  390. pz_settings_center/docs/README.md +12 -0
  391. pz_settings_center/docs/distribution-README.md +150 -0
  392. pz_settings_center/docs//350/256/276/350/256/241/346/226/207/346/241/243.md +48 -0
  393. pz_settings_center/integration_payload.py +18 -0
  394. pz_settings_center/project_helpers.py +405 -0
  395. pz_settings_center/public.py +139 -0
  396. pz_settings_center/routing_helpers.py +73 -0
  397. pz_settings_center/runtime_override_provider.py +61 -0
  398. pz_settings_center/typed_settings.py +324 -0
  399. pz_settings_center/urls.py +9 -0
@@ -0,0 +1,365 @@
1
+ # contrib 约定与 Provider 接入规范
2
+
3
+ > 本文说明一条固定主线:`pz` 只定义稳定合同与编译装配协议,`pz_contrib` 负责官方通用能力的正式实现与约定消费,其他最小子包只通过既定扩展点提供 provider / middleware / panel / menu / settings patch,不再在宿主或基础层写第二套装配。
4
+
5
+ ## 1. 为什么单独写这篇
6
+
7
+ 只看 `14-分层与扩展规范`,容易知道“基础层不能吞高层实现”,但还不够回答下面这些高频问题:
8
+
9
+ - 为什么 `contrib` 不是第二基础层,却又要承接很多正式约定。
10
+ - 为什么 `auth`、`seo`、`admin`、`settings operator` 这些能力应该由 `contrib` 集中消费扩展,而不是每个业务包自己拼。
11
+ - 业务包、平台包、站点包到底应该怎么接入,才算遵守约定而不是绕过约定。
12
+
13
+ 本文把这条主线直接固定下来。
14
+
15
+ ## 2. 设计哲学
16
+
17
+ ### 2.1 `pz` 只承载稳定合同
18
+
19
+ `pz` 的职责是:
20
+
21
+ - 定义最小子包发现协议。
22
+ - 编译 `RuntimePlan`、`SettingsSnapshot`、`ExtensionRegistry`。
23
+ - 定义 `host.builder`、`settings.provider`、lifecycle、middleware、resource、CLI 等稳定合同。
24
+ - 定义 `infra.provider`,用于把 concrete infra owner app 的 settings 编译进 typed `InfraContext`。
25
+
26
+ `pz` 不做这些事:
27
+
28
+ - 不直接承载官方业务实现。
29
+ - 不直接承载 `admin` / `seo` / `auth` / 站点壳 / 宿主页面装配。
30
+ - 不为单个业务场景加临时入口。
31
+
32
+ 也就是说,`pz` 只回答“系统支持什么正式扩展点”,不回答“这些扩展点由谁来具体消费和装配”。
33
+
34
+ ### 2.2 `pz_contrib` 是官方约定层
35
+
36
+ `pz_contrib` 不是第二基础层,也不是运行时 namespace;它是官方最小子包源码容器。但它承担一件非常关键的事:
37
+
38
+ - 在 `pz` 已有稳定合同之上,给出官方通用能力的正式实现。
39
+ - 把一些跨业务、跨仓都会用到的约定收敛成统一消费点。
40
+ - 让其他子包只需“声明并接入”,而不是重复发明装配方式。
41
+
42
+ 因此,正式主线是:
43
+
44
+ 1. `pz` 定义扩展点与编译协议。
45
+ 2. `pz_contrib` 按这些扩展点提供官方实现和集中消费逻辑。
46
+ 3. 其他最小子包遵守这些约定,通过 `apps.py` 声明 provider / panel / menu / settings provider / lifecycle。
47
+ 4. 运行时统一从 registry 与 `RuntimePlan` 消费,而不是宿主手工挂载。
48
+
49
+ 这里还要补一条边界,避免把“官方高频能力”误解成“都应进入 `contrib`”:
50
+
51
+ - `pz_contrib` 负责的是官方通用能力的正式实现与集中消费。
52
+ - 某个最小子包如果本质上是公开页面 owner runtime、站点 owner runtime 或其它高内聚 owner runtime,不因“重要”或“高频”自动进入 `contrib`。
53
+ - 这类子包的长期做法应是:协议进入 `pz` 的正式编译主链,runtime 继续留在自己的 owner 包内。
54
+ - 页面中心是当前明确样例:页面装配与 SEO provider 协议通过 core 的“子包正式协议注册机制”进入 `pz`,但公开页面 owner runtime 继续整体留在 `pz_page_center`,不因为协议进入 core 就拆散到 `contrib`。
55
+
56
+ ### 2.3 其他子包只做“按约定提供”
57
+
58
+ 业务包、平台包、站点包的默认职责不是改 host,也不是改 core,而是:
59
+
60
+ - 在自己的 `apps.py` 中声明结构化扩展对象。
61
+ - 在自己的模块中提供实际 provider / router / middleware / settings patch 实现。
62
+ - 把实现注册到既定 kind,对应的消费方再统一装配。
63
+
64
+ 这意味着:
65
+
66
+ - `auth` 相关路由策略不该在宿主里手工判断,而应声明 `auth.route_policy_provider`。
67
+ - 页面 SEO 不该在每个 app 里自己拼 middleware,而应声明 `seo.provider` / `seo.sitemap_provider`。
68
+ - 后台页面不该在宿主里 `include_router()`,而应声明 `admin.panel` / `admin.menu`。
69
+ - 动态 settings 补丁不该再开第二套 loader,而应声明 `settings.provider`。
70
+
71
+ ### 2.4 Provider 的对象纪律
72
+
73
+ provider 是实现正式合同的对象,不是随处调用的函数集合。
74
+
75
+ 固定规则:
76
+
77
+ - provider 必须有稳定输入 context 和结构化返回值。
78
+ - provider 必须幂等、可重复调用,不直接改写全局状态。
79
+ - provider 不直接启动长期运行资源;需要资源时通过 owner runtime 暴露的 facade/capability 获取。
80
+ - provider 实现模块可以私有,但声明必须通过 `apps.py` / `extensions()` / 正式 spec 进入编译主链。
81
+ - consumer / assembler 负责 provider 排序、冲突裁决、合并结果、诊断输出与运行期 facade 暴露。
82
+ - 不允许让每个 provider 自己决定全局装配结果。
83
+
84
+ 更完整的对象边界见 [`25-面向对象开发规范`](./25-面向对象开发规范.md)。
85
+
86
+ ## 3. 正式责任分工
87
+
88
+ ### 3.1 `pz` 基础层负责什么
89
+
90
+ 正式来源:
91
+
92
+ - [`14-分层与扩展规范`](./14-分层与扩展规范.md)
93
+ - [`16-扩展点正式协议清单`](./16-扩展点正式协议清单.md)
94
+ - [`pz_core/runtime/plan.py`](../../runtime/plan.py)
95
+ - [`pz_core/runtime/settings.py`](../../runtime/settings.py)
96
+
97
+ 基础层的正式职责是:
98
+
99
+ - 编译 app registry、extension registry、event registry。
100
+ - 将 `settings.provider` 编译成 `plan.settings_providers`。
101
+ - 在 settings 装配阶段统一调用 `provider.provide(ctx)`,并做优先级与冲突校验。
102
+
103
+ 所以基础层只持有“协议”和“编译”,不持有高层能力的具体消费实现。
104
+
105
+ ### 3.2 `pz_contrib` 负责什么
106
+
107
+ `pz_contrib` 中的各最小子包负责把高频正式能力收成统一消费面:
108
+
109
+ - host / infra owner 持有官方 `host.builder`、infra provider、通用 infra middlewares、resources、migrations 等能力。
110
+ - admin owner 集中消费 `admin.panel` / `admin.menu`,统一做后台 panel 校验、菜单树装配、扩展健康检查。
111
+ - auth owner 集中消费 `auth.control_plane_provider` / `auth.route_policy_provider`,统一形成认证控制面与路由策略。
112
+ - SEO owner 集中消费 `seo.provider` / `seo.sitemap_provider`,统一形成 SEO provider chain 与 sitemap provider chain。
113
+ - settings runtime owner 通过正式 `settings.provider` 主链提供运行时治理实现。
114
+ - shared site UI owner 提供共享站点 UI 壳与正式首帧稳定约定。
115
+
116
+ 这些都属于“官方约定层”,不是宿主的职责,也不应该反向塞回 `pz`。
117
+
118
+ 但这里的“高频正式能力”有一个明确边界:
119
+
120
+ - 如果某个能力的本质是“集中消费别人的 provider / panel / menu / patch”,那么它适合由 `contrib` owner 收口。
121
+ - 如果某个能力的本质是“自己就是公开运行时 owner,并且拥有页面身份、路由身份、治理身份或站点主链真相”,那么它不应仅因为高频就迁入 `contrib`。
122
+
123
+ 公开页面中心 owner runtime 属于后一类:
124
+
125
+ - 它不是单纯的 provider consumer。
126
+ - 它拥有公开页面身份真相、canonical / hreflang / sitemap / route alias / HubResolver 等治理输出。
127
+ - 因此当前正式分层应是:协议进 core,runtime 留 `pz_page_center`。
128
+
129
+ ### 3.2.1 共享首帧稳定责任
130
+
131
+ 首屏展示与首帧稳定的统一 core 规范固定为 `23-首屏展示与首帧稳定规范.md`。
132
+
133
+ 本文只保留分层结论:
134
+
135
+ - core 定义首帧稳定合同与反模式。
136
+ - 官方共享 UI owner 负责落地共享组件、共享 bundle 与共享 runtime 主链。
137
+ - 页面 owner 负责声明页面级状态、资源、heartbeat、轮询与首屏关键资产。
138
+
139
+ 具体共享 UI 实现细节、bundle 拆分、用户态启动链、cookie banner、语言推荐、help widget 与 preload 规则,归属官方共享 UI owner 文档,不在 core contrib 规范里并列维护。
140
+
141
+ ### 3.3 其他最小子包负责什么
142
+
143
+ 其他最小子包只负责:
144
+
145
+ - 在自己的边界内实现 provider / router / middleware / settings patch。
146
+ - 通过 `apps.py` 把这些实现声明成正式扩展。
147
+ - 让 `contrib` 或 `pz` 的正式消费主链接住。
148
+
149
+ 它们不负责:
150
+
151
+ - 在宿主里写手工挂载代码。
152
+ - 给 `pz` 增加项目专用快捷路径。
153
+ - 绕开 `ExtensionRegistry` / `RuntimePlan` 走第二套注册表。
154
+
155
+ ## 4. `contrib` 里已经固定下来的正式约定
156
+
157
+ ### 4.0 扩展点责任矩阵
158
+
159
+ | 扩展点 kind | 合同 owner | 正式 consumer / assembler | 其他子包该提供什么 |
160
+ | --- | --- | --- | --- |
161
+ | `host.builder` | `pz` | official host owner | host builder 实现本身通常只由官方层提供 |
162
+ | `infra.provider` | `pz` | `pz` 编译到 `RuntimePlan.infra` | concrete infra settings -> `InfraPatch` |
163
+ | `admin.panel` | `pz` | official admin owner + official host owner | `/admin` 下的 router 或 router factory |
164
+ | `admin.menu` | `pz` | official admin owner | 菜单节点、children、section、parent 关系 |
165
+ | `seo.provider` | `pz` | official SEO owner | 页面 SEO provider |
166
+ | `seo.sitemap_provider` | `pz` | official SEO owner | sitemap provider |
167
+ | `auth.control_plane_provider` | `pz` | official auth owner | 某个控制面的认证 provider |
168
+ | `auth.route_policy_provider` | `pz` | official auth owner | 路由认证裁决 provider |
169
+ | `settings.provider` | `pz` | `pz.runtime.settings` | `provide(ctx) -> SettingsPatch` |
170
+ | `lifecycle.contribution` | `pz` | `pz` lifecycle 主链 | startup / shutdown handler |
171
+
172
+ 这张表要表达的不是“谁声明 kind”,而是三层关系:
173
+
174
+ - `pz` 持有稳定合同。
175
+ - `contrib` 持有高频正式 consumer / assembler。
176
+ - 其他子包只往这些约定好的 kind 里提供能力。
177
+
178
+ ### 4.1 Host / Infra 约定
179
+
180
+ 固定约定:
181
+
182
+ - Web host 实现必须通过 `HostBuilderSpec(kind="host.builder")` 提供。
183
+ - concrete infra owner 必须通过 `InfraProviderSpec(kind="infra.provider")` 把能力编译进 `RuntimePlan.infra`。
184
+ - host 不从宿主硬编码 admin、SEO、auth 或业务模块;只消费 `RuntimePlan` 中已经编译好的 routers、middlewares、extensions。
185
+ - 其他包不应自己发明第二个 host,也不应在宿主入口中手工拼总路由。
186
+
187
+ 具体官方 host / infra owner 的代码路径、settings 字段、启动降级语义与 middleware 归属,写在该 owner 子包文档里。
188
+
189
+ ### 4.2 Admin 约定
190
+
191
+ 固定约定:
192
+
193
+ - 其它 app 要接入后台,正式方式只有声明 `admin.panel` / `admin.menu`。
194
+ - admin owner 负责统一校验 panel namespace、菜单树结构、group 关系和扩展健康状态。
195
+ - admin 全局侧边栏直接按子包 root 或工作台入口组织,不再要求先按“内容 / 增长 / 商业 / 平台 / 系统”这类业务域分组;`admin.menu.payload.children` 支持递归结构,底层 schema 不限制嵌套层数,但正式信息架构约定为 3 级:子包 root -> 功能分组 -> 页面入口。CMS、配置中心、任务中心等子包应在自己的 root 下声明功能分组,并在功能分组下声明页面入口;如果某个子包只有一个功能分组,admin shell 可以在 presentation 层视觉压平该分组,直接展示 root -> 页面入口,但不得改变 `admin.menu` 真相源和 sidebar 逻辑结构;更深层级属于子包页面内导航或工作流,不提升为全局侧边栏层级。
196
+ - 为兼容历史声明,admin owner 可以把 root 下面直挂的页面入口归入“入口”功能分组以维持 3 级展示;这是迁移兼容,不是新增子包的正式声明方式。
197
+ - host 只负责挂载已编译的 admin panel router,不负责理解每个业务 app 的后台页面细节。
198
+
199
+ 后台集成的真相源是扩展声明,不是宿主里的 `include_router()`;具体 admin shell、菜单、模板、健康页与 facade 写在 admin owner 文档里。
200
+
201
+ ### 4.3 Auth 约定
202
+
203
+ 固定约定:
204
+
205
+ - 认证链自己的中间件由 auth owner 正式声明。
206
+ - 控制面认证通过 `auth.control_plane_provider` 接入。
207
+ - 路由认证默认通过 app settings 中的 `route_policy` 声明;只有超出配置表达力时才声明 `auth.route_policy_provider`。
208
+ - auth owner 从 extension registry 加载 provider,并注册到自己的 runtime。
209
+
210
+ 未登录拦截、登录页跳转、`next` 回跳、默认保护策略、owner 覆盖、runtime override 暴露等具体行为,归属 auth owner 文档,不在 core contrib 规范里并列维护。
211
+
212
+ ### 4.4 SEO 约定
213
+
214
+ 固定约定:
215
+
216
+ - 页面 SEO 内容由各 app 提供 `seo.provider`。
217
+ - sitemap 内容由各 app 提供 `seo.sitemap_provider`。
218
+ - SEO owner 统一把这些 provider 组装成 provider chain。
219
+ - SEO middleware 只消费 provider chain,不拥有各业务页面的 SEO 真相。
220
+
221
+ 页面 app 只需要提供 provider,不需要自己再发明一套 SEO middleware 或中心注册逻辑;具体 metadata、robots、sitemap、LLM 文本与 admin/API surface 写在 SEO owner 文档里。
222
+
223
+ 补充边界:
224
+
225
+ - `SEO owner` 与页面中心 owner 不是同一层职责。
226
+ - `SEO owner` 负责 SEO provider chain、middleware、sitemap provider chain 等“SEO 输出消费面”。
227
+ - 页面中心 owner 负责关键词页注册、公开页面身份、canonical route graph、HubResolver 等“公开页面 owner runtime”。
228
+ - 因此即使公开页面中心与 SEO 都高度相关,也不应简单把公开页面 owner runtime 视为 `contrib` SEO consumer 的一个子实现。
229
+
230
+ ### 4.5 Settings patch 约定
231
+
232
+ 固定约定:
233
+
234
+ - `settings.provider` 是正式 settings patch 接口。
235
+ - provider 必须实现 `provide(ctx)`,返回 `SettingsPatch`。
236
+ - `pz` 在 settings 装配时统一调用所有 provider,按 priority 合并,并对同优先级写同一路径做冲突报错。
237
+ - settings runtime owner 只能通过这条正式主链提供 runtime override patch,不是第二套 settings loader。
238
+
239
+ 任何动态 settings 覆盖都应该进入 `settings.provider`,而不是重新做一个“运行时特供读取入口”;具体 runtime override 存储、治理、UI/API 与审计归属 settings runtime owner 文档。
240
+
241
+ ## 5. 其他最小子包应该如何接入
242
+
243
+ ### 5.1 统一入口:在 `apps.py` 里声明结构化扩展
244
+
245
+ 其他包的接入步骤固定为:
246
+
247
+ 1. 在自己的模块里实现 provider / router / middleware / settings provider。
248
+ 2. 在 `apps.py` 的 `extensions()` 或 `middlewares()` 中返回正式对象。
249
+ 3. 让 `pz` 编译进入 `RuntimePlan`,再由 `contrib` 统一消费。
250
+
251
+ 跨可选 runtime owner 的 provider 贡献应使用 `ProtocolExtensionSpec(optional=True)`,不得为了让协议注册存在而把 runtime owner 写进每个 provider 子包的 `requires_apps` 或 distribution 依赖。owner 未安装时贡献不生效;owner 安装后,required fields、import target 与 validator 仍按正式协议完整校验。
252
+
253
+ 正式对象通常包括:
254
+
255
+ - `ExtensionSpec`
256
+ - `SettingsProviderSpec`
257
+ - `LifecycleContributionSpec`
258
+ - `MiddlewareDecl`
259
+
260
+ ### 5.1.1 前端首帧稳定的业务接入规则
261
+
262
+ 业务接入摘要统一回到 `23-首屏展示与首帧稳定规范.md` 与官方共享 UI owner 文档;本文不再复制首屏关键图、临时 UI、测量后 reveal、SSR widget、页面心跳、cookie consent 等实现细则。
263
+
264
+ 本节只保留接入原则:
265
+
266
+ - 页面事实由页面 owner 声明。
267
+ - 共享组件由共享 UI owner 沉淀。
268
+ - 页面 owner 发现跨 app 重复问题时,应上提到共享 UI owner,而不是复制到宿主或 core。
269
+
270
+ ### 5.2 典型接入模式
271
+
272
+ 平台包、站点包、业务包如果需要同时接入 settings patch、admin、auth、SEO 或 sitemap,仍然只按既定 kind 声明 provider / panel / menu / route policy。
273
+
274
+ 具体包级例子、代码路径和运行边界,必须写在对应子包自己的 README 或设计文档里;core 文档只保留扩展点合同,不维护平台包、站点包或业务包的实现清单。
275
+
276
+ ## 6. 开发时应该遵守的固定写法
277
+
278
+ ### 6.1 路由
279
+
280
+ - app 自己的 URL 真相源固定在 `<pkg>.urls`
281
+ - 简单 app 使用 `urls.py`
282
+ - 复杂 app 使用 `urls/` 目录,但正式入口固定为 `urls/__init__.py`
283
+ - 不在宿主主服务中手工拼业务路由
284
+ - prefix 由上层统一挂载
285
+ - 业务包只声明,不装配
286
+ - admin 页面通过 `admin.panel` 接入,不绕过后台装配主链
287
+
288
+ ### 6.2 Settings
289
+
290
+ - 运行时代码只允许 `import pz_settings_center.public as settings_center`
291
+ - app 私有配置只读 `settings_center.settings.<app_id>.<field>`
292
+ - 动态补丁只通过 `settings.provider`
293
+
294
+ ### 6.3 Public surface
295
+
296
+ - 跨包依赖优先走对方 `public.py`
297
+ - provider 的实现模块可以是私有模块,但注册动作必须通过 `apps.py`
298
+ - `public.py` 优先暴露窄 facade、Protocol、命令对象、结果对象或 factory,不暴露内部 service、repository、adapter、SDK client、session、pool
299
+
300
+ ### 6.4 Middleware
301
+
302
+ - 通用 middleware 用 `middlewares()` 返回 `MiddlewareDecl`
303
+ - 不在宿主或 startup 里临时插入全局中间件
304
+ - 某个 middleware 如果是为了消费特定 provider chain,应由对应 owner app 统一拥有
305
+
306
+ ### 6.5 对象边界
307
+
308
+ - 有身份、生命周期、状态、不变量或可替换实现的能力,必须落成对象。
309
+ - 纯转换、小范围校验、无状态格式化可以保持函数。
310
+ - 运行时资源归明确 owner object;其它对象只能通过 facade/capability 使用。
311
+ - 依赖通过构造参数、factory、context、`RuntimePlan` 或正式 registry 注入。
312
+ - 不在 provider、middleware、route handler 内部临时 import 对方内部实现来绕过合同。
313
+
314
+ ## 7. 明确禁止的反模式
315
+
316
+ - 在宿主里手工 `include_router()` 去补某个 app 的后台页面。
317
+ - 在宿主或基础层里硬编码 import 某个业务包,再手工注册 provider。
318
+ - 为了热更新或特定业务,再开第二套 settings loader / registry。
319
+ - 在业务 app 里自己发明一套 SEO / auth / admin 装配中心。
320
+ - 把 `apps.py`、`urls.py`、`urls/`、`settings.py` 当成跨包公开面直接依赖。
321
+ - 遇到接入问题就把实现塞回 `pz` 基础层,而不是先看现有扩展点是否足够表达。
322
+ - 把第三方 SDK client、浏览器 session、DB pool、queue connection 等外部资源对象直接暴露给跨包调用方。
323
+
324
+ ## 8. 判断一项新需求应该改哪里
325
+
326
+ 优先按下面顺序判断:
327
+
328
+ 1. 现有 app 内是否已经有对应扩展点可以接入。
329
+ 2. 如果是跨多个 app 都会复用的官方通用装配,是否应进入 `pz_contrib`。
330
+ 3. 只有在现有正式合同确实表达不了时,才回到 `pz` 基础层补稳定协议。
331
+
332
+ 补充判断:
333
+
334
+ 4. 如果新需求本质上要求某个子包拥有独立公开页面身份、路由真相、canonical/hreflang/sitemap 主链或其它 owner runtime 事实,先判断它是不是一个独立 owner runtime,而不是先默认迁入 `contrib`。
335
+
336
+ 简单判断:
337
+
338
+ - “我要提供一个页面/菜单/后台入口”
339
+ - 先看 `admin.panel` / `admin.menu`
340
+ - “我要给页面提供 SEO 数据”
341
+ - 先看 `seo.provider` / `seo.sitemap_provider`
342
+ - “我要让某个关键词页/公开承接页 runtime 成为页面 owner”
343
+ - 先判断是否属于独立 owner runtime;像公开页面中心这类场景应走“协议进入 core,runtime 留在 owner 包”的模式
344
+ - “我要给某个控制面提供认证”
345
+ - 先看 `auth.control_plane_provider`
346
+ - “我要声明某组路由应该怎么认证”
347
+ - 先看 `auth.route_policy_provider`
348
+ - “我要在运行时补 settings”
349
+ - 先看 `settings.provider`
350
+ - “我要接入统一 host、资源、静态、middleware 装配”
351
+ - 先看官方 host / infra owner 的正式 host builder 与 lifecycle
352
+
353
+ ## 9. 先读哪些文档
354
+
355
+ - [`14-分层与扩展规范`](./14-分层与扩展规范.md)
356
+ - [`15-子包开发使用手册`](./15-子包开发使用手册.md)
357
+ - [`16-扩展点正式协议清单`](./16-扩展点正式协议清单.md)
358
+ - [`18-扩展点冲突裁决总表`](./18-扩展点冲突裁决总表.md)
359
+ - [`25-面向对象开发规范`](./25-面向对象开发规范.md)
360
+
361
+ 如果要真正开发一个新子包,再继续读:
362
+
363
+ - [`03-App最小子包规范`](./03-App最小子包规范.md)
364
+ - [`04-Settings与配置规范`](./04-Settings与配置规范.md)
365
+ - [`10-测试与契约规范`](./10-测试与契约规范.md)