core-framework 3.0.0__tar.gz → 3.1.0__tar.gz

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 (787) hide show
  1. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/constitution.mdc +6 -1
  2. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/skills/code-review/SKILL.md +1 -0
  3. {core_framework-3.0.0 → core_framework-3.1.0}/.github/workflows/_deploy.yml +5 -3
  4. {core_framework-3.0.0 → core_framework-3.1.0}/.github/workflows/dev-ci-cd.yaml +2 -3
  5. {core_framework-3.0.0 → core_framework-3.1.0}/.github/workflows/manual-deployment.yaml +0 -1
  6. core_framework-3.1.0/.github/workflows/manual-observability-deployment.yaml +225 -0
  7. {core_framework-3.0.0 → core_framework-3.1.0}/.github/workflows/test.yaml +23 -6
  8. {core_framework-3.0.0 → core_framework-3.1.0}/.gitignore +3 -0
  9. {core_framework-3.0.0 → core_framework-3.1.0}/.pre-commit-config.yaml +3 -12
  10. {core_framework-3.0.0 → core_framework-3.1.0}/CHANGELOG.md +58 -1
  11. {core_framework-3.0.0 → core_framework-3.1.0}/PKG-INFO +27 -4
  12. {core_framework-3.0.0 → core_framework-3.1.0}/README.md +18 -2
  13. core_framework-3.1.0/alembic/notification/alembic/versions/2fdd68777706_notification_read_at_retention_index.py +28 -0
  14. {core_framework-3.0.0 → core_framework-3.1.0}/config.toml +3 -1
  15. {core_framework-3.0.0 → core_framework-3.1.0}/config.toml.template +3 -1
  16. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/cache/schemas.py +1 -1
  17. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/comments/authenticated/router.py +8 -5
  18. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/comments/authenticated/schemas.py +5 -0
  19. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/posts/authenticated/router.py +11 -5
  20. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/posts/authenticated/schemas.py +5 -0
  21. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/analytics/refresh_service.py +6 -4
  22. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/media/README.md +1 -1
  23. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/notifications/notification_service.py +34 -44
  24. core_framework-3.1.0/core_framework/application/notifications/prune_service.py +8 -0
  25. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/outbox/events.py +4 -0
  26. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/outbox/polling_service.py +8 -4
  27. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/outbox/processing_service.py +24 -2
  28. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/posts/aggregation_service.py +1 -4
  29. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/posts/authenticated_service.py +2 -1
  30. core_framework-3.1.0/core_framework/application/shared/worker_jobs.py +62 -0
  31. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/users/admin_service.py +2 -2
  32. core_framework-3.1.0/core_framework/core/context.py +40 -0
  33. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/database.py +6 -8
  34. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/exception_handlers/common.py +19 -16
  35. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/http_client.py +1 -1
  36. core_framework-3.1.0/core_framework/core/http_probes.py +4 -0
  37. core_framework-3.1.0/core_framework/core/logging.py +120 -0
  38. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/middleware.py +60 -11
  39. core_framework-3.1.0/core_framework/core/observability.py +648 -0
  40. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/pagination.py +4 -7
  41. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/redis.py +1 -1
  42. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/settings.py +37 -1
  43. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/analytics/service.py +4 -4
  44. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/comment/repository.py +1 -4
  45. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/moderation/service.py +4 -4
  46. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/notification/README.md +4 -4
  47. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/notification/repository.py +26 -0
  48. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/notification/service.py +20 -0
  49. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/outbox/models.py +1 -0
  50. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/user/repository.py +2 -2
  51. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/user/service.py +2 -2
  52. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/utils.py +2 -2
  53. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/media/pillow_staging_image.py +3 -6
  54. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/media/ssh_attachment_finals_publisher_adapter.py +32 -28
  55. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/media/ssh_banner_finals_publisher_adapter.py +28 -24
  56. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/media/ssh_finals_publisher_adapter.py +39 -35
  57. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/outbox/outbox_consumer_adapter.py +3 -1
  58. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/main.py +15 -3
  59. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/testing/arq.py +3 -4
  60. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/testing/auth.py +9 -6
  61. core_framework-3.1.0/core_framework/testing/firebase.py +132 -0
  62. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/testing/httpx_test_client.py +2 -2
  63. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/testing/plugin.py +11 -9
  64. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/main.py +24 -13
  65. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/__init__.py +8 -0
  66. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/schedule_aggregate_comment_stats.py +4 -2
  67. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/schedule_aggregate_post_stats.py +4 -2
  68. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/schedule_aggregate_user_stats.py +4 -2
  69. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/schedule_expired_account_deletions.py +4 -2
  70. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/schedule_expired_mute_lifts.py +4 -2
  71. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/schedule_prune_analytics_daily_facts.py +1 -2
  72. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/schedule_prune_post_views.py +1 -2
  73. core_framework-3.1.0/core_framework/worker/schedules/schedule_prune_read_notifications.py +16 -0
  74. core_framework-3.1.0/core_framework/worker/schedules/schedule_purge_expired_create_idempotency_keys.py +17 -0
  75. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/__init__.py +2 -0
  76. core_framework-3.1.0/deploy/README.md +27 -0
  77. core_framework-3.1.0/deploy/observability/.env.example +7 -0
  78. core_framework-3.1.0/deploy/observability/README.md +11 -0
  79. core_framework-3.1.0/deploy/observability/docker-compose.yml +153 -0
  80. core_framework-3.1.0/deploy/observability/grafana/dashboards/application/api-http.json +297 -0
  81. core_framework-3.1.0/deploy/observability/grafana/dashboards/application/worker-jobs.json +250 -0
  82. core_framework-3.1.0/deploy/observability/grafana/dashboards/infrastructure/node-exporter.json +23900 -0
  83. core_framework-3.1.0/deploy/observability/grafana/dashboards/infrastructure/postgres-exporter.json +1453 -0
  84. core_framework-3.1.0/deploy/observability/grafana/dashboards/infrastructure/redis-exporter.json +1620 -0
  85. core_framework-3.1.0/deploy/observability/grafana/provisioning/dashboards/dashboards.yml +26 -0
  86. core_framework-3.1.0/deploy/observability/grafana/provisioning/datasources/datasources.yml +49 -0
  87. core_framework-3.1.0/deploy/observability/loki.yaml +61 -0
  88. core_framework-3.1.0/deploy/observability/otel-collector-config.yaml +54 -0
  89. core_framework-3.1.0/deploy/observability/prometheus.yml +39 -0
  90. core_framework-3.1.0/deploy/observability/targets.example/README.md +19 -0
  91. core_framework-3.1.0/deploy/observability/targets.example/node.yml.example +9 -0
  92. core_framework-3.1.0/deploy/observability/targets.example/postgres.yml.example +5 -0
  93. core_framework-3.1.0/deploy/observability/targets.example/redis.yml.example +6 -0
  94. core_framework-3.1.0/deploy/observability/tempo.yaml +30 -0
  95. {core_framework-3.0.0 → core_framework-3.1.0}/docs/README.md +1 -1
  96. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/README.md +15 -11
  97. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/deploy-playbook.md +39 -10
  98. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/examples/Caddyfile.example +3 -0
  99. core_framework-3.1.0/docs/deployments/examples/Caddyfile.observability.example +13 -0
  100. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/guides/playbook/postgres-backup-playbook.md +1 -1
  101. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/guides/setup/caddy-setup.md +1 -0
  102. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/guides/setup/cloudflare-setup.md +37 -11
  103. core_framework-3.1.0/docs/deployments/guides/setup/observability-lgtm-setup.md +204 -0
  104. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/guides/setup/postgres-setup.md +9 -1
  105. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/guides/setup/redis-setup.md +9 -1
  106. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/guides/setup/ubuntu-server-setup.md +10 -4
  107. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/release-playbook.md +1 -1
  108. {core_framework-3.0.0 → core_framework-3.1.0}/docs/design/README.md +11 -10
  109. {core_framework-3.0.0 → core_framework-3.1.0}/docs/design/create-idempotency-design.md +18 -20
  110. {core_framework-3.0.0 → core_framework-3.1.0}/docs/design/event-outbox-design.md +1 -1
  111. core_framework-3.1.0/docs/design/observability-lgtm-design.md +591 -0
  112. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/comments/create_comment.md +20 -6
  113. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/media/post-comment-attachments-design.md +2 -2
  114. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/notifications/notification_inbox.md +6 -8
  115. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/posts/create_post.md +14 -9
  116. {core_framework-3.0.0 → core_framework-3.1.0}/docs/library/core-framework-migration.md +3 -2
  117. {core_framework-3.0.0 → core_framework-3.1.0}/docs/library/overview.md +3 -2
  118. {core_framework-3.0.0 → core_framework-3.1.0}/docs/library/package-api.md +104 -23
  119. {core_framework-3.0.0 → core_framework-3.1.0}/docs/library/testing-plugin-design.md +9 -9
  120. {core_framework-3.0.0 → core_framework-3.1.0}/docs/library/workers.md +22 -16
  121. {core_framework-3.0.0 → core_framework-3.1.0}/docs/platform/architecture-decisions.md +4 -4
  122. {core_framework-3.0.0 → core_framework-3.1.0}/docs/platform/conventions.md +4 -3
  123. {core_framework-3.0.0 → core_framework-3.1.0}/docs/reviews/review-playbook.md +1 -0
  124. {core_framework-3.0.0 → core_framework-3.1.0}/docs/reviews/slices.md +21 -10
  125. {core_framework-3.0.0 → core_framework-3.1.0}/docs/testing.md +2 -2
  126. core_framework-3.1.0/docs/todo.md +4 -0
  127. {core_framework-3.0.0 → core_framework-3.1.0}/makefile +1 -4
  128. {core_framework-3.0.0 → core_framework-3.1.0}/pyproject.toml +41 -26
  129. core_framework-3.1.0/tach.toml +176 -0
  130. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/analytics/_helpers.py +15 -14
  131. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/_destructive_delete_helpers.py +1 -1
  132. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/_http_helpers.py +18 -29
  133. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/_user_deletion_helpers.py +2 -2
  134. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/_user_helpers.py +3 -1
  135. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/admin/analytics/router_test.py +0 -2
  136. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/admin/cache/router_test.py +1 -1
  137. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/admin/comments/router_test.py +0 -14
  138. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/admin/moderation/router_test.py +0 -9
  139. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/admin/outbox/router_test.py +12 -13
  140. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/admin/posts/router_test.py +8 -17
  141. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/attachments/_helpers.py +43 -33
  142. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/comments/authenticated/comment_writes_integration_test.py +18 -22
  143. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/comments/comment_attachments_integration_test.py +0 -12
  144. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/comments/public/router_test.py +0 -14
  145. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/create_idempotency_integration_test.py +12 -8
  146. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/events/router_test.py +0 -1
  147. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/mentions/mentions_integration_test.py +0 -13
  148. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/notifications/router_test.py +0 -7
  149. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/posts/authenticated/post_writes_integration_test.py +10 -19
  150. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/posts/comment_count_aggregation_test.py +0 -4
  151. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/posts/followers_visibility_test.py +2 -8
  152. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/posts/post_attachments_integration_test.py +11 -28
  153. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/posts/post_deletion_integration_test.py +0 -18
  154. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/posts/post_stats_dirty_marking_test.py +0 -7
  155. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/posts/public/router_test.py +0 -41
  156. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/users/authenticated/router_test.py +10 -5
  157. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/users/deletion_audit_integration_test.py +5 -3
  158. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/users/user_deletion_integration_test.py +0 -8
  159. core_framework-3.1.0/tests/integration/worker/_media_upload_helpers.py +84 -0
  160. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/account_deletion_test.py +7 -8
  161. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/aggregate_comment_stats_test.py +4 -10
  162. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/aggregate_post_stats_test.py +2 -9
  163. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/aggregate_user_stats_test.py +1 -1
  164. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/analytics_refresh_test.py +0 -1
  165. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/avatar_upload_test.py +8 -8
  166. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/banner_upload_test.py +8 -8
  167. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/create_idempotency_retention_test.py +0 -5
  168. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/moderation_outbox_test.py +5 -6
  169. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/mute_lift_test.py +7 -7
  170. core_framework-3.1.0/tests/integration/worker/read_notifications_retention_test.py +169 -0
  171. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/user_outbox_test.py +0 -4
  172. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/utils_test.py +37 -40
  173. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/core/bundled_alembic_test.py +3 -5
  174. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/core/pagination_test.py +14 -13
  175. core_framework-3.1.0/tests/unit/domains/__init__.py +0 -0
  176. core_framework-3.1.0/tests/unit/domains/comment/__init__.py +0 -0
  177. core_framework-3.1.0/tests/unit/infrastructure/__init__.py +0 -0
  178. core_framework-3.1.0/tests/unit/infrastructure/media/__init__.py +0 -0
  179. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/infrastructure/media/ssh_finals_publisher_adapter_test.py +18 -14
  180. {core_framework-3.0.0 → core_framework-3.1.0}/uv.lock +213 -102
  181. core_framework-3.0.0/core_framework/application/shared/worker_jobs.py +0 -19
  182. core_framework-3.0.0/core_framework/core/context.py +0 -14
  183. core_framework-3.0.0/core_framework/core/logging.py +0 -79
  184. core_framework-3.0.0/core_framework/core/observability.py +0 -31
  185. core_framework-3.0.0/core_framework/testing/firebase.py +0 -95
  186. core_framework-3.0.0/core_framework/worker/schedules/schedule_purge_expired_create_idempotency_keys.py +0 -23
  187. core_framework-3.0.0/docs/todo.md +0 -71
  188. core_framework-3.0.0/tests/integration/worker/_media_upload_helpers.py +0 -77
  189. {core_framework-3.0.0 → core_framework-3.1.0}/.agents/skills/fastapi +0 -0
  190. {core_framework-3.0.0 → core_framework-3.1.0}/.agents/skills/library-skills/.library-skills.json +0 -0
  191. {core_framework-3.0.0 → core_framework-3.1.0}/.agents/skills/library-skills/SKILL.md +0 -0
  192. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/alembic-migrations.mdc +0 -0
  193. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/api-layer.mdc +0 -0
  194. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/api-reference-docs.mdc +0 -0
  195. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/api-validation.mdc +0 -0
  196. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/application-layer.mdc +0 -0
  197. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/constants-final.mdc +0 -0
  198. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/database-triggers.mdc +0 -0
  199. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/docstrings.mdc +0 -0
  200. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/domain-caller-context.mdc +0 -0
  201. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/domain-imports.mdc +0 -0
  202. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/domain-input-guards.mdc +0 -0
  203. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/domain-repository-exceptions.mdc +0 -0
  204. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/domain-services-and-adapters.mdc +0 -0
  205. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/error-boundary.mdc +0 -0
  206. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/flow-documentation.mdc +0 -0
  207. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/inline-raise-messages.mdc +0 -0
  208. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/integration-test-strategy.mdc +0 -0
  209. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/layer-boundaries.mdc +0 -0
  210. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/no-code-in-docs.mdc +0 -0
  211. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/postgres-config-conventions.mdc +0 -0
  212. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/repository-schema-isolation.mdc +0 -0
  213. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/strong-reads.mdc +0 -0
  214. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/rules/structured-logging.mdc +0 -0
  215. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/skills/add-config/SKILL.md +0 -0
  216. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/skills/add-domain/SKILL.md +0 -0
  217. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/skills/fastapi +0 -0
  218. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/skills/implement-feature/SKILL.md +0 -0
  219. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/skills/recommend-features/SKILL.md +0 -0
  220. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/skills/sync-host-rules/SKILL.md +0 -0
  221. {core_framework-3.0.0 → core_framework-3.1.0}/.cursor/skills/write-flow-doc/SKILL.md +0 -0
  222. {core_framework-3.0.0 → core_framework-3.1.0}/.dockerignore +0 -0
  223. {core_framework-3.0.0 → core_framework-3.1.0}/.github/ci/package-lock.json +0 -0
  224. {core_framework-3.0.0 → core_framework-3.1.0}/.github/ci/package.json +0 -0
  225. {core_framework-3.0.0 → core_framework-3.1.0}/.github/workflows/publish-pypi.yml +0 -0
  226. {core_framework-3.0.0 → core_framework-3.1.0}/.python-version +0 -0
  227. {core_framework-3.0.0 → core_framework-3.1.0}/LICENSE +0 -0
  228. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/analytics/alembic/README +0 -0
  229. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/analytics/alembic/env.py +0 -0
  230. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/analytics/alembic/script.py.mako +0 -0
  231. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/analytics/alembic/versions/2d61a5e88d76_analytics_utm_events_add_kind.py +0 -0
  232. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/analytics/alembic/versions/585105e1149e_analytics_add_utm_events.py +0 -0
  233. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/analytics/alembic/versions/5b9ac98bb150_analytics_daily_fact.py +0 -0
  234. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/analytics/alembic/versions/7f2a9c1d4e8b_analytics_daily_fact_day_index.py +0 -0
  235. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/analytics/alembic.ini +0 -0
  236. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/comment/alembic/README +0 -0
  237. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/comment/alembic/env.py +0 -0
  238. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/comment/alembic/script.py.mako +0 -0
  239. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/comment/alembic/versions/comment_add_comment_attachments.py +0 -0
  240. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/comment/alembic/versions/comment_add_comment_create_idempotency.py +0 -0
  241. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/comment/alembic/versions/comment_add_comment_create_idempotency_created_at_index.py +0 -0
  242. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/comment/alembic/versions/comment_add_comment_mentions.py +0 -0
  243. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/comment/alembic/versions/comment_tombstone_status_model.py +0 -0
  244. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/comment/alembic/versions/v1_comment_init_baseline.py +0 -0
  245. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/comment/alembic.ini +0 -0
  246. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/extension/alembic/README +0 -0
  247. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/extension/alembic/env.py +0 -0
  248. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/extension/alembic/script.py.mako +0 -0
  249. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/extension/alembic/versions/v1_ext_init_baseline.py +0 -0
  250. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/extension/alembic.ini +0 -0
  251. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/media/alembic/README +0 -0
  252. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/media/alembic/env.py +0 -0
  253. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/media/alembic/script.py.mako +0 -0
  254. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/media/alembic/versions/media_add_attachment_staging_registry.py +0 -0
  255. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/media/alembic/versions/media_add_banner_staging_and_lease.py +0 -0
  256. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/media/alembic/versions/media_attachment_staging_registry_published_at.py +0 -0
  257. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/media/alembic/versions/v1_media_init_baseline.py +0 -0
  258. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/media/alembic.ini +0 -0
  259. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/moderation/alembic/README +0 -0
  260. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/moderation/alembic/env.py +0 -0
  261. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/moderation/alembic/script.py.mako +0 -0
  262. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/moderation/alembic/versions/moderation_add_event_outbox.py +0 -0
  263. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/moderation/alembic/versions/moderation_add_event_outbox_dead_indexes.py +0 -0
  264. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/moderation/alembic/versions/moderation_add_event_outbox_pending_created_at_index.py +0 -0
  265. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/moderation/alembic/versions/v1_mod_init_baseline.py +0 -0
  266. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/moderation/alembic.ini +0 -0
  267. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/notification/alembic/README +0 -0
  268. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/notification/alembic/env.py +0 -0
  269. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/notification/alembic/script.py.mako +0 -0
  270. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/notification/alembic/versions/v1_notif_init_baseline.py +0 -0
  271. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/notification/alembic.ini +0 -0
  272. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/post/alembic/README +0 -0
  273. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/post/alembic/env.py +0 -0
  274. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/post/alembic/script.py.mako +0 -0
  275. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/post/alembic/versions/post_add_post_attachments.py +0 -0
  276. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/post/alembic/versions/post_add_post_create_idempotency.py +0 -0
  277. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/post/alembic/versions/post_add_post_create_idempotency_created_at_index.py +0 -0
  278. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/post/alembic/versions/post_add_post_mentions.py +0 -0
  279. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/post/alembic/versions/post_post_views_retention_high_water_mark.py +0 -0
  280. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/post/alembic/versions/post_tombstone_status_model.py +0 -0
  281. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/post/alembic/versions/v1_post_init_baseline.py +0 -0
  282. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/post/alembic.ini +0 -0
  283. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/user/alembic/README +0 -0
  284. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/user/alembic/env.py +0 -0
  285. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/user/alembic/script.py.mako +0 -0
  286. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/user/alembic/versions/44df70a45ba6_user_add_signup_events.py +0 -0
  287. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/user/alembic/versions/user_add_avatar_ingest_sequences.py +0 -0
  288. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/user/alembic/versions/user_add_banner_ingest_sequences.py +0 -0
  289. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/user/alembic/versions/user_add_date_of_birth_to_profiles.py +0 -0
  290. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/user/alembic/versions/user_add_event_outbox.py +0 -0
  291. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/user/alembic/versions/user_add_event_outbox_dead_indexes.py +0 -0
  292. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/user/alembic/versions/user_add_event_outbox_pending_created_at_index.py +0 -0
  293. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/user/alembic/versions/user_reserve_sentinel_user_ids.py +0 -0
  294. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/user/alembic/versions/v1_user_init_baseline.py +0 -0
  295. {core_framework-3.0.0 → core_framework-3.1.0}/alembic/user/alembic.ini +0 -0
  296. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/__init__.py +0 -0
  297. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/__init__.py +0 -0
  298. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/__init__.py +0 -0
  299. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/analytics/__init__.py +0 -0
  300. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/analytics/router.py +0 -0
  301. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/analytics/schemas.py +0 -0
  302. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/cache/__init__.py +0 -0
  303. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/cache/router.py +0 -0
  304. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/comments/__init__.py +0 -0
  305. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/comments/router.py +0 -0
  306. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/comments/schemas.py +0 -0
  307. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/moderation/__init__.py +0 -0
  308. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/moderation/router.py +0 -0
  309. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/moderation/schemas.py +0 -0
  310. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/outbox/__init__.py +0 -0
  311. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/outbox/router.py +0 -0
  312. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/outbox/schemas.py +0 -0
  313. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/posts/__init__.py +0 -0
  314. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/posts/router.py +0 -0
  315. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/posts/schemas.py +0 -0
  316. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/router.py +0 -0
  317. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/users/__init__.py +0 -0
  318. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/users/router.py +0 -0
  319. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/admin/users/schemas.py +0 -0
  320. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/attachments/__init__.py +0 -0
  321. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/attachments/router.py +0 -0
  322. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/attachments/schemas.py +0 -0
  323. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/auth/__init__.py +0 -0
  324. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/auth/router.py +0 -0
  325. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/auth/schemas.py +0 -0
  326. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/comments/__init__.py +0 -0
  327. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/comments/authenticated/__init__.py +0 -0
  328. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/comments/authenticated/mappers.py +0 -0
  329. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/comments/public/__init__.py +0 -0
  330. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/comments/public/router.py +0 -0
  331. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/comments/public/schemas.py +0 -0
  332. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/comments/router.py +0 -0
  333. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/comments/schemas.py +0 -0
  334. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/constants.py +0 -0
  335. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/dependencies.py +1 -1
  336. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/events/__init__.py +0 -0
  337. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/events/router.py +0 -0
  338. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/events/schemas.py +0 -0
  339. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/idempotency/__init__.py +0 -0
  340. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/idempotency/dependencies.py +0 -0
  341. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/notifications/__init__.py +0 -0
  342. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/notifications/authenticated/__init__.py +0 -0
  343. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/notifications/authenticated/router.py +0 -0
  344. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/notifications/authenticated/schemas.py +0 -0
  345. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/notifications/router.py +0 -0
  346. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/posts/__init__.py +0 -0
  347. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/posts/authenticated/__init__.py +0 -0
  348. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/posts/authenticated/mappers.py +0 -0
  349. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/posts/public/__init__.py +0 -0
  350. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/posts/public/router.py +0 -0
  351. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/posts/public/schemas.py +0 -0
  352. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/posts/router.py +0 -0
  353. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/posts/schemas.py +0 -0
  354. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/router.py +0 -0
  355. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/schemas.py +0 -0
  356. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/system/__init__.py +0 -0
  357. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/system/router.py +0 -0
  358. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/upload.py +0 -0
  359. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/users/__init__.py +0 -0
  360. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/users/authenticated/__init__.py +0 -0
  361. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/users/authenticated/mappers.py +0 -0
  362. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/users/authenticated/router.py +0 -0
  363. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/users/authenticated/schemas.py +0 -0
  364. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/users/mappers.py +0 -0
  365. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/users/public/__init__.py +0 -0
  366. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/users/public/router.py +0 -0
  367. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/users/public/schemas.py +0 -0
  368. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/users/router.py +0 -0
  369. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/users/shared/__init__.py +0 -0
  370. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/api/users/shared/schemas.py +0 -0
  371. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/__init__.py +0 -0
  372. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/analytics/__init__.py +0 -0
  373. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/analytics/bucket_service.py +0 -0
  374. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/analytics/prune_service.py +0 -0
  375. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/analytics/read_service.py +0 -0
  376. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/analytics/registry.py +0 -0
  377. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/analytics/sources/__init__.py +0 -0
  378. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/analytics/sources/comment_created.py +0 -0
  379. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/analytics/sources/post_created.py +0 -0
  380. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/analytics/sources/post_viewed.py +0 -0
  381. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/analytics/sources/user_registered.py +0 -0
  382. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/auth/__init__.py +0 -0
  383. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/auth/access_service.py +0 -0
  384. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/auth/auth_service.py +0 -0
  385. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/auth/models.py +0 -0
  386. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/auth/token_verification.py +0 -0
  387. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/bootstrap.py +0 -0
  388. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/cache/__init__.py +0 -0
  389. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/cache/invalidate_service.py +0 -0
  390. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/cache/models.py +0 -0
  391. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/comments/__init__.py +0 -0
  392. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/comments/admin_service.py +0 -0
  393. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/comments/aggregation_service.py +0 -0
  394. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/comments/authenticated_service.py +0 -0
  395. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/comments/cleanup_service.py +0 -0
  396. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/comments/public_service.py +0 -0
  397. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/events/README.md +0 -0
  398. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/events/__init__.py +0 -0
  399. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/events/event_service.py +0 -0
  400. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/events/event_token.py +0 -0
  401. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/events/models.py +0 -0
  402. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/events/utm_capture_kinds.py +0 -0
  403. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/media/__init__.py +0 -0
  404. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/media/attachment_read.py +0 -0
  405. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/media/attachment_service.py +0 -0
  406. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/media/avatar_service.py +0 -0
  407. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/media/banner_service.py +0 -0
  408. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/media/ingest_guards.py +0 -0
  409. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/media/read_url_config.py +0 -0
  410. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/moderation/__init__.py +0 -0
  411. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/moderation/appeal_service.py +0 -0
  412. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/moderation/moderator_service.py +0 -0
  413. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/moderation/report_service.py +0 -0
  414. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/moderation/scheduled_service.py +0 -0
  415. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/moderation/user_service.py +0 -0
  416. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/notifications/README.md +0 -0
  417. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/notifications/__init__.py +0 -0
  418. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/notifications/enums.py +0 -0
  419. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/notifications/inbox_service.py +0 -0
  420. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/notifications/mute_service.py +0 -0
  421. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/outbox/__init__.py +0 -0
  422. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/outbox/block_mirrors.py +0 -0
  423. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/outbox/exceptions.py +0 -0
  424. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/outbox/follow_mirrors.py +0 -0
  425. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/outbox/handlers.py +0 -0
  426. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/outbox/ops_service.py +0 -0
  427. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/outbox/restriction_mirrors.py +0 -0
  428. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/posts/__init__.py +0 -0
  429. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/posts/admin_service.py +0 -0
  430. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/posts/cleanup_service.py +0 -0
  431. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/posts/public_service.py +0 -0
  432. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/shared/__init__.py +0 -0
  433. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/shared/enums.py +0 -0
  434. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/shared/exceptions.py +0 -0
  435. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/shared/request_context.py +0 -0
  436. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/users/__init__.py +0 -0
  437. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/users/aggregation_service.py +0 -0
  438. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/users/authenticated_service.py +0 -0
  439. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/users/deletion_audit.py +0 -0
  440. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/users/enums.py +0 -0
  441. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/users/public_service.py +0 -0
  442. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/users/scheduled_service.py +0 -0
  443. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/application/users/user_deletion_service.py +0 -0
  444. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/asgi.py +0 -0
  445. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/bundled_alembic.py +0 -0
  446. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/constants.py +0 -0
  447. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/__init__.py +4 -4
  448. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/cache.py +0 -0
  449. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/exception_handlers/__init__.py +0 -0
  450. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/exception_handlers/application.py +0 -0
  451. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/exception_handlers/setup.py +0 -0
  452. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/exceptions.py +0 -0
  453. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/firebase.py +0 -0
  454. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/core/runtime.py +0 -0
  455. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/__init__.py +0 -0
  456. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/analytics/README.md +0 -0
  457. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/analytics/__init__.py +4 -4
  458. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/analytics/constants.py +0 -0
  459. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/analytics/dependencies.py +2 -2
  460. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/analytics/exceptions.py +0 -0
  461. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/analytics/models.py +0 -0
  462. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/analytics/ports/__init__.py +0 -0
  463. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/analytics/ports/activity_source.py +0 -0
  464. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/analytics/repository.py +0 -0
  465. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/auth/README.md +0 -0
  466. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/auth/__init__.py +0 -0
  467. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/auth/dependencies.py +0 -0
  468. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/auth/exceptions.py +0 -0
  469. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/auth/models.py +0 -0
  470. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/auth/ports/__init__.py +0 -0
  471. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/auth/ports/auth.py +0 -0
  472. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/auth/service.py +0 -0
  473. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/comment/README.md +0 -0
  474. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/comment/__init__.py +12 -12
  475. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/comment/constants.py +0 -0
  476. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/comment/dependencies.py +1 -1
  477. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/comment/enums.py +0 -0
  478. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/comment/exceptions.py +0 -0
  479. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/comment/models.py +0 -0
  480. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/comment/outcomes.py +0 -0
  481. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/comment/service.py +0 -0
  482. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/exceptions.py +0 -0
  483. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/README.md +0 -0
  484. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/__init__.py +4 -4
  485. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/attachment/__init__.py +0 -0
  486. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/attachment/components/__init__.py +0 -0
  487. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/attachment/components/finals_publisher.py +0 -0
  488. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/attachment/components/staging.py +0 -0
  489. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/attachment/components/variant_encoder.py +0 -0
  490. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/attachment/constants.py +0 -0
  491. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/attachment/exceptions.py +0 -0
  492. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/attachment/models.py +0 -0
  493. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/attachment/ports/__init__.py +0 -0
  494. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/attachment/ports/finals_publisher.py +0 -0
  495. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/attachment/ports/staging.py +0 -0
  496. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/attachment/ports/variant_encoder.py +0 -0
  497. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/attachment/service.py +0 -0
  498. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/avatar/__init__.py +0 -0
  499. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/avatar/components/__init__.py +0 -0
  500. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/avatar/components/finals_publisher.py +0 -0
  501. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/avatar/components/staging.py +0 -0
  502. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/avatar/components/variant_encoder.py +0 -0
  503. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/avatar/constants.py +0 -0
  504. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/avatar/exceptions.py +0 -0
  505. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/avatar/models.py +0 -0
  506. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/avatar/ports/__init__.py +0 -0
  507. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/avatar/ports/finals_publisher.py +0 -0
  508. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/avatar/ports/staging.py +0 -0
  509. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/avatar/ports/variant_encoder.py +0 -0
  510. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/avatar/service.py +0 -0
  511. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/banner/__init__.py +0 -0
  512. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/banner/components/__init__.py +0 -0
  513. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/banner/components/finals_publisher.py +0 -0
  514. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/banner/components/staging.py +0 -0
  515. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/banner/components/variant_encoder.py +0 -0
  516. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/banner/constants.py +0 -0
  517. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/banner/exceptions.py +0 -0
  518. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/banner/models.py +0 -0
  519. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/banner/ports/__init__.py +0 -0
  520. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/banner/ports/finals_publisher.py +0 -0
  521. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/banner/ports/staging.py +0 -0
  522. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/banner/ports/variant_encoder.py +0 -0
  523. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/banner/service.py +0 -0
  524. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/dependencies.py +0 -0
  525. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/shared/__init__.py +0 -0
  526. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/shared/constants.py +0 -0
  527. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/shared/exceptions.py +0 -0
  528. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/shared/outcomes.py +0 -0
  529. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/shared/repository.py +0 -0
  530. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/shared/service.py +0 -0
  531. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/media/shared/utils.py +0 -0
  532. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/moderation/README.md +0 -0
  533. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/moderation/__init__.py +12 -12
  534. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/moderation/dependencies.py +0 -0
  535. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/moderation/enums.py +0 -0
  536. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/moderation/exceptions.py +0 -0
  537. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/moderation/models.py +0 -0
  538. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/moderation/outbox_repository.py +0 -0
  539. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/moderation/outbox_service.py +0 -0
  540. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/moderation/outcomes.py +0 -0
  541. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/moderation/repository.py +0 -0
  542. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/notification/__init__.py +1 -1
  543. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/notification/dependencies.py +0 -0
  544. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/notification/enums.py +0 -0
  545. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/notification/exceptions.py +0 -0
  546. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/notification/models.py +0 -0
  547. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/outbox/README.md +0 -0
  548. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/outbox/__init__.py +0 -0
  549. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/outbox/dependencies.py +0 -0
  550. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/outbox/exceptions.py +0 -0
  551. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/outbox/ports/__init__.py +0 -0
  552. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/outbox/ports/admin.py +0 -0
  553. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/outbox/ports/consumer.py +0 -0
  554. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/outbox/ports/producer.py +0 -0
  555. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/outbox/service.py +0 -0
  556. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/post/README.md +0 -0
  557. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/post/__init__.py +9 -9
  558. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/post/constants.py +0 -0
  559. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/post/dependencies.py +0 -0
  560. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/post/enums.py +0 -0
  561. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/post/exceptions.py +0 -0
  562. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/post/models.py +0 -0
  563. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/post/outcomes.py +0 -0
  564. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/post/repository.py +0 -0
  565. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/post/service.py +0 -0
  566. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/repository_sql.py +0 -0
  567. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/user/README.md +0 -0
  568. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/user/__init__.py +11 -11
  569. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/user/constants.py +0 -0
  570. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/user/dependencies.py +0 -0
  571. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/user/enums.py +0 -0
  572. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/user/exceptions.py +0 -0
  573. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/user/models.py +0 -0
  574. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/user/outbox_repository.py +0 -0
  575. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/user/outbox_service.py +0 -0
  576. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/user/outcomes.py +0 -0
  577. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/domains/user/utils.py +0 -0
  578. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/__init__.py +0 -0
  579. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/firebase/__init__.py +0 -0
  580. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/firebase/firebase_auth_adapter.py +0 -0
  581. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/media/__init__.py +0 -0
  582. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/media/attachment_staging_display_geometry.py +0 -0
  583. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/media/local_attachment_staging_adapter.py +0 -0
  584. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/media/local_avatar_staging_adapter.py +0 -0
  585. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/media/local_banner_staging_adapter.py +0 -0
  586. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/media/pillow_attachment_variant_encoder_adapter.py +0 -0
  587. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/media/pillow_avatar_variant_encoder_adapter.py +0 -0
  588. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/media/pillow_banner_variant_encoder_adapter.py +0 -0
  589. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/media/staging_paths.py +0 -0
  590. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/outbox/__init__.py +0 -0
  591. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/infrastructure/outbox/outbox_producer_adapter.py +0 -0
  592. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/migrate_cli.py +0 -0
  593. /core_framework-3.0.0/core_framework/worker/__init__.py → /core_framework-3.1.0/core_framework/py.typed +0 -0
  594. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/testing/__init__.py +0 -0
  595. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/testing/config.py +0 -0
  596. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/testing/containers.py +0 -0
  597. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/testing/firebase_identity_toolkit.py +0 -0
  598. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/testing/hookspecs.py +0 -0
  599. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/testing/media.py +0 -0
  600. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/testing/migrations.py +0 -0
  601. {core_framework-3.0.0/tests → core_framework-3.1.0/core_framework/worker}/__init__.py +0 -0
  602. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/analytics_refresh_cron.py +0 -0
  603. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/schedule_poll_outbox.py +0 -0
  604. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/schedule_refresh_analytics.py +0 -0
  605. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/schedule_sweep_stale_attachment_staging.py +0 -0
  606. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/schedule_sweep_stale_avatar_staging.py +0 -0
  607. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/schedules/schedule_sweep_stale_banner_staging.py +0 -0
  608. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/delete_attachment_finals.py +0 -0
  609. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/delete_superseded_avatar_finals.py +0 -0
  610. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/delete_superseded_banner_finals.py +0 -0
  611. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_account_deletion.py +0 -0
  612. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_admin_user_deletion.py +0 -0
  613. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_aggregate_comment_stats.py +0 -0
  614. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_aggregate_post_stats.py +0 -0
  615. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_aggregate_user_stats.py +0 -0
  616. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_attachment_asset_variants.py +0 -0
  617. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_banner_asset_variants.py +0 -0
  618. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_cache_pattern_invalidation.py +0 -0
  619. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_destructive_comment_delete.py +0 -0
  620. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_destructive_post_delete.py +0 -0
  621. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_media_asset_variants.py +0 -0
  622. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_mute_lift.py +0 -0
  623. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_outbox_row.py +0 -0
  624. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_refresh_analytics_bucket.py +0 -0
  625. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/tasks/process_user_content_deletion.py +0 -0
  626. {core_framework-3.0.0 → core_framework-3.1.0}/core_framework/worker/worker_context.py +0 -0
  627. {core_framework-3.0.0 → core_framework-3.1.0/deploy/app}/docker-compose.dev.yaml +0 -0
  628. {core_framework-3.0.0 → core_framework-3.1.0/deploy/app}/docker-compose.yml +0 -0
  629. {core_framework-3.0.0 → core_framework-3.1.0/deploy/app}/dockerfile +0 -0
  630. /core_framework-3.0.0/tests/integration/__init__.py → /core_framework-3.1.0/deploy/observability/targets/node/.gitkeep +0 -0
  631. /core_framework-3.0.0/tests/integration/api/__init__.py → /core_framework-3.1.0/deploy/observability/targets/postgres/.gitkeep +0 -0
  632. /core_framework-3.0.0/tests/integration/api/admin/__init__.py → /core_framework-3.1.0/deploy/observability/targets/redis/.gitkeep +0 -0
  633. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/e2e-smoke-tests-design.md +0 -0
  634. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/edge-rate-limits.md +0 -0
  635. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/edge-upload-limits.md +0 -0
  636. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/examples/image-server-known-hosts.example +0 -0
  637. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/guides/playbook/py-spy-playbook.md +0 -0
  638. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/guides/setup/app-server-deploy-ssh.md +0 -0
  639. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/guides/setup/image-server-ssh.md +0 -0
  640. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/guides/setup/postgres-backup-setup.md +0 -0
  641. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/guides/setup/py-spy-setup.md +0 -0
  642. {core_framework-3.0.0 → core_framework-3.1.0}/docs/deployments/postgres-backup-design.md +0 -0
  643. {core_framework-3.0.0 → core_framework-3.1.0}/docs/design/analytics-rollup-design.md +0 -0
  644. {core_framework-3.0.0 → core_framework-3.1.0}/docs/design/cache-invalidation-design.md +0 -0
  645. {core_framework-3.0.0 → core_framework-3.1.0}/docs/design/events-ingest-design.md +0 -0
  646. {core_framework-3.0.0 → core_framework-3.1.0}/docs/design/media-storage-topology.md +0 -0
  647. {core_framework-3.0.0 → core_framework-3.1.0}/docs/design/outbox-admin-ops-design.md +0 -0
  648. {core_framework-3.0.0 → core_framework-3.1.0}/docs/design/utm-events-design.md +0 -0
  649. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/README.md +0 -0
  650. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/analytics/admin_analytics_reads.md +0 -0
  651. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/auth/access_control.md +0 -0
  652. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/auth/registration.md +0 -0
  653. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/cache/admin_cache_invalidation.md +0 -0
  654. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/comments/README.md +0 -0
  655. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/comments/admin_comments.md +0 -0
  656. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/comments/comment_like.md +0 -0
  657. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/comments/comment_report.md +0 -0
  658. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/comments/comment_stats_aggregation.md +0 -0
  659. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/comments/delete_comment.md +0 -0
  660. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/comments/edit_comment.md +0 -0
  661. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/comments/retrieve_comments.md +0 -0
  662. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/deletion/comments.md +0 -0
  663. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/deletion/overview.md +0 -0
  664. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/deletion/posts.md +0 -0
  665. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/deletion/users.md +0 -0
  666. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/events/events.md +0 -0
  667. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/media/README.md +0 -0
  668. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/media/attachment_upload.md +0 -0
  669. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/media/avatar-upload-design.md +0 -0
  670. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/media/banner-upload-design.md +0 -0
  671. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/media/upload-pipeline-design.md +0 -0
  672. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/media/upload_pipeline.md +0 -0
  673. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/mentions/mentions_in_content.md +0 -0
  674. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/moderation/README.md +0 -0
  675. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/moderation/appeals.md +0 -0
  676. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/moderation/internal_notes.md +0 -0
  677. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/moderation/moderator_actions.md +0 -0
  678. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/moderation/reports.md +0 -0
  679. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/moderation/restrictions.md +0 -0
  680. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/outbox/admin_outbox_ops.md +0 -0
  681. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/posts/README.md +0 -0
  682. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/posts/admin_posts.md +0 -0
  683. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/posts/author_context.md +0 -0
  684. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/posts/delete_post.md +0 -0
  685. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/posts/edit_post.md +0 -0
  686. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/posts/hashtag_discovery.md +0 -0
  687. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/posts/post_like.md +0 -0
  688. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/posts/post_report.md +0 -0
  689. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/posts/post_stats_aggregation.md +0 -0
  690. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/posts/post_visibility.md +0 -0
  691. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/posts/retrieve_posts.md +0 -0
  692. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/account.md +0 -0
  693. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/account_deletion.md +0 -0
  694. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/admin_users.md +0 -0
  695. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/avatar.md +0 -0
  696. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/banner.md +0 -0
  697. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/blocks.md +0 -0
  698. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/change_history.md +0 -0
  699. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/check_username_exists.md +0 -0
  700. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/follow-system-design.md +0 -0
  701. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/follow.md +0 -0
  702. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/my_posts_and_comments.md +0 -0
  703. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/preferences.md +0 -0
  704. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/profile.md +0 -0
  705. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/public_profile.md +0 -0
  706. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/user_removal.md +0 -0
  707. {core_framework-3.0.0 → core_framework-3.1.0}/docs/domains/users/user_stats_aggregation.md +0 -0
  708. {core_framework-3.0.0 → core_framework-3.1.0}/docs/library/README.md +0 -0
  709. {core_framework-3.0.0 → core_framework-3.1.0}/docs/library/api.md +0 -0
  710. {core_framework-3.0.0 → core_framework-3.1.0}/docs/library/capability-wiring.md +0 -0
  711. {core_framework-3.0.0 → core_framework-3.1.0}/docs/platform/README.md +0 -0
  712. {core_framework-3.0.0 → core_framework-3.1.0}/docs/platform/client-error-visibility.md +0 -0
  713. {core_framework-3.0.0 → core_framework-3.1.0}/docs/platform/database-triggers.md +0 -0
  714. {core_framework-3.0.0 → core_framework-3.1.0}/docs/platform/domain-services-and-adapters.md +0 -0
  715. {core_framework-3.0.0 → core_framework-3.1.0}/docs/platform/layers-and-boundaries.md +0 -0
  716. {core_framework-3.0.0 → core_framework-3.1.0}/docs/platform/patch-update-typed-payload.md +0 -0
  717. {core_framework-3.0.0 → core_framework-3.1.0}/docs/reviews/README.md +0 -0
  718. {core_framework-3.0.0 → core_framework-3.1.0}/docs/reviews/log.md +0 -0
  719. {core_framework-3.0.0 → core_framework-3.1.0}/firebase_config.example.json +0 -0
  720. {core_framework-3.0.0/tests/integration/api/admin/analytics → core_framework-3.1.0/tests}/__init__.py +0 -0
  721. {core_framework-3.0.0 → core_framework-3.1.0}/tests/conftest.py +0 -0
  722. {core_framework-3.0.0 → core_framework-3.1.0}/tests/e2e/_auth.py +0 -0
  723. {core_framework-3.0.0 → core_framework-3.1.0}/tests/e2e/_canaries.py +0 -0
  724. {core_framework-3.0.0 → core_framework-3.1.0}/tests/e2e/_media.py +0 -0
  725. {core_framework-3.0.0 → core_framework-3.1.0}/tests/e2e/_settings.py +0 -0
  726. {core_framework-3.0.0 → core_framework-3.1.0}/tests/e2e/_upload_payloads.py +0 -0
  727. {core_framework-3.0.0 → core_framework-3.1.0}/tests/e2e/conftest.py +0 -0
  728. {core_framework-3.0.0 → core_framework-3.1.0}/tests/e2e/media/pipeline_test.py +0 -0
  729. {core_framework-3.0.0 → core_framework-3.1.0}/tests/e2e/smoke/canary_test.py +0 -0
  730. {core_framework-3.0.0 → core_framework-3.1.0}/tests/e2e/smoke/media_test.py +0 -0
  731. {core_framework-3.0.0 → core_framework-3.1.0}/tests/e2e/smoke/system_test.py +0 -0
  732. {core_framework-3.0.0 → core_framework-3.1.0}/tests/e2e/smoke/tls_host_test.py +0 -0
  733. {core_framework-3.0.0/tests/integration/api/admin/cache → core_framework-3.1.0/tests/integration}/__init__.py +0 -0
  734. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/_http_error_details.py +0 -0
  735. {core_framework-3.0.0/tests/integration/api/admin/comments → core_framework-3.1.0/tests/integration/api}/__init__.py +0 -0
  736. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/_auth_helpers.py +0 -0
  737. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/_outbox_helpers.py +0 -0
  738. {core_framework-3.0.0/tests/integration/api/admin/moderation → core_framework-3.1.0/tests/integration/api/admin}/__init__.py +0 -0
  739. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/admin/_auth_cases.py +0 -0
  740. {core_framework-3.0.0/tests/integration/api/admin/outbox → core_framework-3.1.0/tests/integration/api/admin/analytics}/__init__.py +0 -0
  741. {core_framework-3.0.0/tests/integration/api/admin/posts → core_framework-3.1.0/tests/integration/api/admin/cache}/__init__.py +0 -0
  742. {core_framework-3.0.0/tests/integration/api/admin/users → core_framework-3.1.0/tests/integration/api/admin/comments}/__init__.py +0 -0
  743. {core_framework-3.0.0/tests/integration/api/auth → core_framework-3.1.0/tests/integration/api/admin/moderation}/__init__.py +0 -0
  744. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/admin/moderation/_auth_cases.py +0 -0
  745. {core_framework-3.0.0/tests/integration/api/comments → core_framework-3.1.0/tests/integration/api/admin/outbox}/__init__.py +0 -0
  746. {core_framework-3.0.0/tests/integration/api/comments/authenticated → core_framework-3.1.0/tests/integration/api/admin/posts}/__init__.py +0 -0
  747. {core_framework-3.0.0/tests/integration/api/comments/public → core_framework-3.1.0/tests/integration/api/admin/users}/__init__.py +0 -0
  748. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/admin/users/router_test.py +0 -0
  749. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/attachments/attachment_upload_test.py +0 -0
  750. {core_framework-3.0.0/tests/integration/api/notifications → core_framework-3.1.0/tests/integration/api/auth}/__init__.py +0 -0
  751. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/auth/router_test.py +0 -0
  752. {core_framework-3.0.0/tests/integration/api/posts → core_framework-3.1.0/tests/integration/api/comments}/__init__.py +0 -0
  753. {core_framework-3.0.0/tests/integration/api/posts/public → core_framework-3.1.0/tests/integration/api/comments/authenticated}/__init__.py +0 -0
  754. {core_framework-3.0.0/tests/integration/api/system → core_framework-3.1.0/tests/integration/api/comments/public}/__init__.py +0 -0
  755. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/media/ingest_contract_test.py +0 -0
  756. {core_framework-3.0.0/tests/integration/api/users → core_framework-3.1.0/tests/integration/api/notifications}/__init__.py +0 -0
  757. {core_framework-3.0.0/tests/integration/api/users/authenticated → core_framework-3.1.0/tests/integration/api/posts}/__init__.py +0 -0
  758. {core_framework-3.0.0/tests/integration/api/users → core_framework-3.1.0/tests/integration/api/posts}/public/__init__.py +0 -0
  759. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/public_read_by_id_unavailable_detail_test.py +0 -0
  760. {core_framework-3.0.0/tests/integration/worker → core_framework-3.1.0/tests/integration/api/system}/__init__.py +0 -0
  761. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/system/router_test.py +0 -0
  762. {core_framework-3.0.0/tests/unit → core_framework-3.1.0/tests/integration/api/users}/__init__.py +0 -0
  763. {core_framework-3.0.0/tests/unit/application/comments → core_framework-3.1.0/tests/integration/api/users/authenticated}/__init__.py +0 -0
  764. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/users/authenticated/avatar_upload_test.py +0 -0
  765. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/users/authenticated/banner_upload_test.py +0 -0
  766. {core_framework-3.0.0/tests/unit/domains → core_framework-3.1.0/tests/integration/api/users/public}/__init__.py +0 -0
  767. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/api/users/public/router_test.py +0 -0
  768. {core_framework-3.0.0/tests/unit/domains/comment → core_framework-3.1.0/tests/integration/worker}/__init__.py +0 -0
  769. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/analytics_prune_test.py +0 -0
  770. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/attachment_upload_test.py +0 -0
  771. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/conftest.py +0 -0
  772. {core_framework-3.0.0 → core_framework-3.1.0}/tests/integration/worker/stale_staging_sweep_test.py +0 -0
  773. {core_framework-3.0.0/tests/unit/infrastructure → core_framework-3.1.0/tests/unit}/__init__.py +0 -0
  774. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/api/comments/authenticated/comment_request_schemas_test.py +0 -0
  775. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/api/dedupe_preserving_order_test.py +0 -0
  776. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/api/posts/authenticated/post_update_mapper_test.py +0 -0
  777. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/api/users/profile_update_mapper_test.py +0 -0
  778. {core_framework-3.0.0/tests/unit/infrastructure/media → core_framework-3.1.0/tests/unit/application/comments}/__init__.py +0 -0
  779. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/application/events/event_service_test.py +0 -0
  780. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/application/notifications/inbox_service_test.py +0 -0
  781. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/application/shared/request_context_test.py +0 -0
  782. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/application/users/deletion_audit_test.py +0 -0
  783. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/core/migrate_cli_test.py +0 -0
  784. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/docs/_api_reference.py +0 -0
  785. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/docs/api_routes_test.py +0 -0
  786. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/domains/post/models_test.py +0 -0
  787. {core_framework-3.0.0 → core_framework-3.1.0}/tests/unit/domains/user/service_test.py +0 -0
@@ -16,7 +16,12 @@ alwaysApply: true
16
16
 
17
17
  - Python 3.14, Pydantic v2, PostgreSQL 18, orjson (not stdlib json).
18
18
  - Absolute imports only (`from core_framework....`). Comma-style `except A, B:` is intentional.
19
- - Prefer newer APIs (`asyncio.TaskGroup` over `gather`).
19
+ - Prefer newer APIs and **current Python syntax** over older equivalents still legal on 3.14, for example:
20
+ - `asyncio.TaskGroup` over `asyncio.gather`
21
+ - PEP 695 type parameters (`def f[T](...)`, `def f[**P, R](...)`) over module-level `TypeVar` / `ParamSpec`
22
+ - Built-in generics (`list[str]`, `dict[str, int]`) over `typing.List` / `typing.Dict`
23
+ - `X | Y` over `Optional[X]` / `Union[X, Y]` unless a library API requires the old form
24
+ - Do **not** add `from __future__ import annotations` — 3.14 deferred annotations are the default (PEP 649)
20
25
 
21
26
  ## Layers
22
27
 
@@ -28,6 +28,7 @@ Do **not** flag documented accepted trade-offs in **`docs/platform/architecture-
28
28
  - API: thin routers, validation in schemas, orchestration in application — **fastapi** skill (`.agents/skills/fastapi/`) + **`api-layer`** / **`api-validation`** / **`error-boundary`** rules.
29
29
  - Domain: imports only via **`__init__.py`** / **`dependencies`** from outer layers; no caller-context names (**`domain-caller-context`**).
30
30
  - Read-after-write refetches use **`*_strong`** where applicable.
31
+ - **Python modernity (constitution):** prefer current 3.14 syntax in reviewed code — PEP 695 type params over module-level `TypeVar`/`ParamSpec`; no unnecessary `from __future__ import annotations`; builtins / `X | Y` over legacy `typing` aliases; `asyncio.TaskGroup` over `gather`.
31
32
 
32
33
  ## Parallel drift
33
34
 
@@ -20,8 +20,6 @@ on:
20
20
  required: true
21
21
  READ_POSTGRES_PASSWORD:
22
22
  required: true
23
- LOGFIRE_TOKEN:
24
- required: true
25
23
  FIREBASE_CONFIG:
26
24
  required: true
27
25
  IMAGE_SERVER_SSH_PRIVATE_KEY:
@@ -79,13 +77,14 @@ jobs:
79
77
  IMAGE_SERVER_HOST: ${{ vars.IMAGE_SERVER_HOST }}
80
78
  IMAGE_SERVER_PORT: ${{ vars.IMAGE_SERVER_PORT }}
81
79
  IMAGE_SERVER_USER: ${{ vars.IMAGE_SERVER_USER }}
82
- LOGFIRE_TOKEN: ${{ secrets.LOGFIRE_TOKEN }}
83
80
  OBSERVABILITY_ENABLED: ${{ vars.OBSERVABILITY_ENABLED }}
81
+ OBSERVABILITY_OTLP_ENDPOINT: ${{ vars.OBSERVABILITY_OTLP_ENDPOINT }}
84
82
  PROFILING_KEY: ${{ vars.PROFILING_KEY }}
85
83
  PROFILING_ENABLED: ${{ vars.PROFILING_ENABLED }}
86
84
  LOG_LEVEL: ${{ vars.LOG_LEVEL }}
87
85
  CORS_ALLOWED_ORIGINS: ${{ vars.CORS_ALLOWED_ORIGINS }}
88
86
  RETENTION_POST_VIEWS_DAYS: ${{ vars.RETENTION_POST_VIEWS_DAYS }}
87
+ RETENTION_READ_NOTIFICATIONS_DAYS: ${{ vars.RETENTION_READ_NOTIFICATIONS_DAYS }}
89
88
  ANALYTICS_REFRESH_INTERVAL_SECONDS: ${{ vars.ANALYTICS_REFRESH_INTERVAL_SECONDS }}
90
89
  run: |
91
90
  set -euo pipefail
@@ -150,6 +149,9 @@ jobs:
150
149
  test -s image_server_known_hosts
151
150
  chmod 644 image_server_known_hosts
152
151
 
152
+ - name: Stage docker-compose.yml for upload
153
+ run: cp deploy/app/docker-compose.yml ./docker-compose.yml
154
+
153
155
  - name: Upload rendered config.toml, firebase_config.json and docker-compose.yml
154
156
  uses: appleboy/scp-action@ff85246acaad7bdce478db94a363cd2bf7c90345 # v1.0.0
155
157
  with:
@@ -133,7 +133,7 @@ jobs:
133
133
  uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
134
134
  with:
135
135
  context: .
136
- file: ./dockerfile
136
+ file: ./deploy/app/dockerfile
137
137
  target: api
138
138
  push: true
139
139
  tags: ${{ steps.meta.outputs.tags }}
@@ -170,7 +170,7 @@ jobs:
170
170
  uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
171
171
  with:
172
172
  context: .
173
- file: ./dockerfile
173
+ file: ./deploy/app/dockerfile
174
174
  target: worker
175
175
  push: true
176
176
  tags: ${{ steps.meta.outputs.tags }}
@@ -187,7 +187,6 @@ jobs:
187
187
  SECRET_KEY: ${{ secrets.SECRET_KEY }}
188
188
  WRITE_POSTGRES_PASSWORD: ${{ secrets.WRITE_POSTGRES_PASSWORD }}
189
189
  READ_POSTGRES_PASSWORD: ${{ secrets.READ_POSTGRES_PASSWORD }}
190
- LOGFIRE_TOKEN: ${{ secrets.LOGFIRE_TOKEN }}
191
190
  FIREBASE_CONFIG: ${{ secrets.FIREBASE_CONFIG }}
192
191
  IMAGE_SERVER_SSH_PRIVATE_KEY: ${{ secrets.IMAGE_SERVER_SSH_PRIVATE_KEY }}
193
192
  IMAGE_SERVER_KNOWN_HOSTS: ${{ secrets.IMAGE_SERVER_KNOWN_HOSTS }}
@@ -45,7 +45,6 @@ jobs:
45
45
  SECRET_KEY: ${{ secrets.SECRET_KEY }}
46
46
  WRITE_POSTGRES_PASSWORD: ${{ secrets.WRITE_POSTGRES_PASSWORD }}
47
47
  READ_POSTGRES_PASSWORD: ${{ secrets.READ_POSTGRES_PASSWORD }}
48
- LOGFIRE_TOKEN: ${{ secrets.LOGFIRE_TOKEN }}
49
48
  FIREBASE_CONFIG: ${{ secrets.FIREBASE_CONFIG }}
50
49
  IMAGE_SERVER_SSH_PRIVATE_KEY: ${{ secrets.IMAGE_SERVER_SSH_PRIVATE_KEY }}
51
50
  IMAGE_SERVER_KNOWN_HOSTS: ${{ secrets.IMAGE_SERVER_KNOWN_HOSTS }}
@@ -0,0 +1,225 @@
1
+ name: Manual Observability Deployment
2
+
3
+ # Syncs deploy/observability/ to the LGTM host and runs docker compose up -d
4
+ # --force-recreate --remove-orphans (so bind-mounted config changes reload).
5
+ # Uses OBSERVABILITY_DEPLOY_* (not DEPLOY_SERVER_*) so the stack can move hosts later.
6
+ # Optional PROMETHEUS_TARGETS_{NODE,POSTGRES,REDIS} (GitHub Environment vars) are
7
+ # written to targets/*/hosts.yml at stage time — host inventory stays out of the repo.
8
+
9
+ on:
10
+ workflow_dispatch:
11
+ inputs:
12
+ environment:
13
+ description: "Target environment (development or production)"
14
+ required: true
15
+ type: choice
16
+ options:
17
+ - development
18
+ - production
19
+ confirm:
20
+ description: "Type the environment name to confirm (development or production)"
21
+ required: true
22
+
23
+ permissions: {}
24
+
25
+ jobs:
26
+ validate:
27
+ runs-on: ubuntu-latest
28
+ permissions: {}
29
+ steps:
30
+ - name: Validate confirmation
31
+ env:
32
+ CONFIRM: ${{ inputs.confirm }}
33
+ ENVIRONMENT: ${{ inputs.environment }}
34
+ run: |
35
+ if [ "$CONFIRM" != "$ENVIRONMENT" ]; then
36
+ echo "Deployment cancelled: confirmation mismatch."
37
+ echo "Expected: '$ENVIRONMENT', got: '$CONFIRM'"
38
+ exit 1
39
+ fi
40
+
41
+ deploy:
42
+ needs: validate
43
+ runs-on: ubuntu-latest
44
+ environment: ${{ inputs.environment }}
45
+ permissions:
46
+ contents: read
47
+ steps:
48
+ - name: Checkout code
49
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
50
+ with:
51
+ persist-credentials: false
52
+
53
+ # Stage as staging/observability (not deploy/observability). Upload uses
54
+ # strip_components: 1 so remote is .../app_configs/observability.
55
+ # Host scrape inventory comes from GitHub Environment vars (not the repo).
56
+ - name: Stage observability stack for upload
57
+ env:
58
+ PROMETHEUS_TARGETS_NODE: ${{ vars.PROMETHEUS_TARGETS_NODE }}
59
+ PROMETHEUS_TARGETS_POSTGRES: ${{ vars.PROMETHEUS_TARGETS_POSTGRES }}
60
+ PROMETHEUS_TARGETS_REDIS: ${{ vars.PROMETHEUS_TARGETS_REDIS }}
61
+ run: |
62
+ set -euo pipefail
63
+ mkdir -p staging/observability
64
+ cp -a deploy/observability/. staging/observability/
65
+ rm -f staging/observability/.env
66
+ rm -rf staging/observability/targets.example
67
+ mkdir -p \
68
+ staging/observability/targets/node \
69
+ staging/observability/targets/postgres \
70
+ staging/observability/targets/redis
71
+ rm -f staging/observability/targets/*/.gitkeep
72
+ python3 -m pip install --user -q pyyaml
73
+ python3 <<'PY'
74
+ import os
75
+ import sys
76
+ from pathlib import Path
77
+
78
+ import yaml
79
+
80
+ def write_targets(dest, body, var_name):
81
+ text = body or ""
82
+ stripped = text.strip()
83
+ path = Path(dest)
84
+ if not stripped:
85
+ path.write_text("[]\n", encoding="utf-8")
86
+ print(f"{var_name}: empty → []")
87
+ return
88
+ try:
89
+ data = yaml.safe_load(text)
90
+ except yaml.YAMLError as exc:
91
+ print(f"ERROR: {var_name} is not valid YAML: {exc}", file=sys.stderr)
92
+ sys.exit(1)
93
+ if data is None:
94
+ # Comment-only or empty document
95
+ path.write_text("[]\n", encoding="utf-8")
96
+ print(f"{var_name}: comment-only/null → []")
97
+ return
98
+ if not isinstance(data, list):
99
+ print(
100
+ f"ERROR: {var_name} must be a YAML list of file_sd target groups, "
101
+ f"got {type(data).__name__}",
102
+ file=sys.stderr,
103
+ )
104
+ sys.exit(1)
105
+ out = text if text.endswith("\n") else text + "\n"
106
+ path.write_text(out, encoding="utf-8")
107
+ print(f"{var_name}: wrote {len(data)} target group(s) → {dest}")
108
+
109
+ write_targets(
110
+ "staging/observability/targets/node/hosts.yml",
111
+ os.environ.get("PROMETHEUS_TARGETS_NODE", ""),
112
+ "PROMETHEUS_TARGETS_NODE",
113
+ )
114
+ write_targets(
115
+ "staging/observability/targets/postgres/hosts.yml",
116
+ os.environ.get("PROMETHEUS_TARGETS_POSTGRES", ""),
117
+ "PROMETHEUS_TARGETS_POSTGRES",
118
+ )
119
+ write_targets(
120
+ "staging/observability/targets/redis/hosts.yml",
121
+ os.environ.get("PROMETHEUS_TARGETS_REDIS", ""),
122
+ "PROMETHEUS_TARGETS_REDIS",
123
+ )
124
+ PY
125
+
126
+ - name: Ensure remote app_configs directory
127
+ uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1.2.5
128
+ env:
129
+ OBSERVABILITY_DEPLOY_USER: ${{ vars.OBSERVABILITY_DEPLOY_USER }}
130
+ with:
131
+ host: ${{ vars.OBSERVABILITY_DEPLOY_HOST }}
132
+ username: ${{ vars.OBSERVABILITY_DEPLOY_USER }}
133
+ key: ${{ secrets.OBSERVABILITY_DEPLOY_SSH_KEY }}
134
+ port: ${{ vars.OBSERVABILITY_DEPLOY_PORT }}
135
+ envs: OBSERVABILITY_DEPLOY_USER
136
+ script: |
137
+ set -euo pipefail
138
+ mkdir -p "/home/$OBSERVABILITY_DEPLOY_USER/app_configs"
139
+
140
+ # Drop any leftover file_sd YAML under targets/ before upload (SCP overwrite
141
+ # does not delete extras; Prometheus scrapes targets/*/*.yml).
142
+ - name: Reset remote Prometheus targets directory
143
+ uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1.2.5
144
+ env:
145
+ OBSERVABILITY_DEPLOY_USER: ${{ vars.OBSERVABILITY_DEPLOY_USER }}
146
+ with:
147
+ host: ${{ vars.OBSERVABILITY_DEPLOY_HOST }}
148
+ username: ${{ vars.OBSERVABILITY_DEPLOY_USER }}
149
+ key: ${{ secrets.OBSERVABILITY_DEPLOY_SSH_KEY }}
150
+ port: ${{ vars.OBSERVABILITY_DEPLOY_PORT }}
151
+ envs: OBSERVABILITY_DEPLOY_USER
152
+ script: |
153
+ set -euo pipefail
154
+ STACK_DIR="/home/$OBSERVABILITY_DEPLOY_USER/app_configs/observability"
155
+ mkdir -p "$STACK_DIR"
156
+ rm -rf "$STACK_DIR/targets"
157
+ mkdir -p \
158
+ "$STACK_DIR/targets/node" \
159
+ "$STACK_DIR/targets/postgres" \
160
+ "$STACK_DIR/targets/redis"
161
+
162
+ - name: Upload observability stack
163
+ uses: appleboy/scp-action@ff85246acaad7bdce478db94a363cd2bf7c90345 # v1.0.0
164
+ with:
165
+ host: ${{ vars.OBSERVABILITY_DEPLOY_HOST }}
166
+ username: ${{ vars.OBSERVABILITY_DEPLOY_USER }}
167
+ key: ${{ secrets.OBSERVABILITY_DEPLOY_SSH_KEY }}
168
+ port: ${{ vars.OBSERVABILITY_DEPLOY_PORT }}
169
+ # Stage path is staging/observability; strip "staging/" so remote is
170
+ # .../app_configs/observability (not .../app_configs/staging/observability).
171
+ source: "staging/observability"
172
+ target: "/home/${{ vars.OBSERVABILITY_DEPLOY_USER }}/app_configs"
173
+ strip_components: 1
174
+ overwrite: true
175
+
176
+ - name: Compose up on observability host
177
+ uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1.2.5
178
+ env:
179
+ OBSERVABILITY_DEPLOY_USER: ${{ vars.OBSERVABILITY_DEPLOY_USER }}
180
+ GRAFANA_ADMIN_USER: ${{ vars.GRAFANA_ADMIN_USER }}
181
+ GRAFANA_ADMIN_PASSWORD: ${{ secrets.GRAFANA_ADMIN_PASSWORD }}
182
+ GRAFANA_ROOT_URL: ${{ vars.GRAFANA_ROOT_URL }}
183
+ with:
184
+ host: ${{ vars.OBSERVABILITY_DEPLOY_HOST }}
185
+ username: ${{ vars.OBSERVABILITY_DEPLOY_USER }}
186
+ key: ${{ secrets.OBSERVABILITY_DEPLOY_SSH_KEY }}
187
+ port: ${{ vars.OBSERVABILITY_DEPLOY_PORT }}
188
+ envs: OBSERVABILITY_DEPLOY_USER,GRAFANA_ADMIN_USER,GRAFANA_ADMIN_PASSWORD,GRAFANA_ROOT_URL
189
+ script: |
190
+ set -euo pipefail
191
+
192
+ STACK_DIR="/home/$OBSERVABILITY_DEPLOY_USER/app_configs/observability"
193
+ test -d "$STACK_DIR"
194
+ cd "$STACK_DIR"
195
+
196
+ # Never overwrite an existing host .env (password / local tweaks).
197
+ if [ ! -f .env ]; then
198
+ if [ -z "${GRAFANA_ADMIN_PASSWORD:-}" ]; then
199
+ echo "ERROR: $STACK_DIR/.env is missing and GRAFANA_ADMIN_PASSWORD is not set."
200
+ echo "Add the secret in the GitHub environment, then re-run this workflow."
201
+ exit 1
202
+ fi
203
+ ADMIN_USER="${GRAFANA_ADMIN_USER:-admin}"
204
+ # GRAFANA_ROOT_URL optional: set for observability.{ZONE} (Caddy);
205
+ # leave empty for SSH-tunnel-only access.
206
+ umask 077
207
+ printf '%s\n' \
208
+ "GRAFANA_ADMIN_USER=${ADMIN_USER}" \
209
+ "GRAFANA_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}" \
210
+ "GRAFANA_ROOT_URL=${GRAFANA_ROOT_URL:-}" \
211
+ > .env
212
+ if [ -z "${GRAFANA_ROOT_URL:-}" ]; then
213
+ echo "Created .env (first install); GRAFANA_ROOT_URL empty (SSH-tunnel fallback)"
214
+ else
215
+ echo "Created .env (first install); GRAFANA_ROOT_URL=${GRAFANA_ROOT_URL}"
216
+ fi
217
+ else
218
+ echo "Keeping existing .env"
219
+ fi
220
+
221
+ docker compose pull
222
+ docker compose up -d --force-recreate --remove-orphans
223
+ docker compose ps
224
+
225
+ echo "Observability stack deployment complete"
@@ -35,7 +35,12 @@ jobs:
35
35
  run: uv sync --locked --all-extras --dev
36
36
 
37
37
  - name: ruff
38
- run: uv run ruff check
38
+ run: |
39
+ uv run ruff check
40
+ uv run ruff format --check
41
+
42
+ - name: ty
43
+ run: uv run ty check
39
44
 
40
45
  - name: Install Firebase CLI
41
46
  working-directory: .github/ci
@@ -43,11 +48,23 @@ jobs:
43
48
 
44
49
  - name: pytest
45
50
  run: |
51
+ set -euo pipefail
46
52
  export PATH="$PWD/.github/ci/node_modules/.bin:$PATH"
47
53
  firebase --version
48
- uv run pytest tests/unit tests/integration -n 2
49
- env:
50
- FIREBASE_AUTH_EMULATOR_HOST: 127.0.0.1:9099
54
+ echo "Starting Firebase Auth emulator..."
55
+ firebase emulators:start --only auth --project=test > /dev/null 2>&1 &
56
+ EMULATOR_PID=$!
57
+ # Mirror makefile warm-up; the testing plugin also waits for Identity Toolkit HTTP readiness.
58
+ sleep 3
59
+ echo "Running unit and integration tests with emulator..."
60
+ set +e
61
+ FIREBASE_AUTH_EMULATOR_HOST=127.0.0.1:9099 uv run pytest tests/unit tests/integration -n 2
62
+ TEST_EXIT=$?
63
+ set -e
64
+ echo "Stopping emulator..."
65
+ kill "$EMULATOR_PID" 2>/dev/null || true
66
+ wait "$EMULATOR_PID" 2>/dev/null || true
67
+ exit "$TEST_EXIT"
51
68
 
52
69
  package-smoke:
53
70
  runs-on: ubuntu-latest
@@ -155,7 +172,7 @@ jobs:
155
172
  uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
156
173
  with:
157
174
  context: .
158
- file: ./dockerfile
175
+ file: ./deploy/app/dockerfile
159
176
  target: api
160
177
  push: false
161
178
  tags: core-framework:ci
@@ -164,7 +181,7 @@ jobs:
164
181
  uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
165
182
  with:
166
183
  context: .
167
- file: ./dockerfile
184
+ file: ./deploy/app/dockerfile
168
185
  target: worker
169
186
  push: false
170
187
  tags: core-framework-worker:ci
@@ -33,3 +33,6 @@ image_server_ssh_key
33
33
  # Cursor debug
34
34
  firebase-debug.log
35
35
  ui-debug.log
36
+
37
+ # Tach
38
+ tach_module_graph.dot
@@ -19,18 +19,6 @@ repos:
19
19
  args: ['--maxkb=750']
20
20
  exclude: ^uv.lock$
21
21
 
22
- - repo: https://github.com/asottile/pyupgrade
23
- rev: v3.21.2
24
- hooks:
25
- - id: pyupgrade
26
- args: [--py314-plus]
27
- name: Upgrade code to Python 3.14+
28
-
29
- - repo: https://github.com/asottile/yesqa
30
- rev: v1.5.0
31
- hooks:
32
- - id: yesqa
33
-
34
22
  - repo: https://github.com/astral-sh/uv-pre-commit
35
23
  rev: 0.11.24
36
24
  hooks:
@@ -43,17 +31,20 @@ repos:
43
31
  entry: uv run --frozen ruff check --fix
44
32
  language: system
45
33
  types_or: [python, pyi]
34
+
46
35
  - id: ruff-format
47
36
  name: ruff format
48
37
  entry: uv run --frozen ruff format
49
38
  language: system
50
39
  types_or: [python, pyi]
40
+
51
41
  - id: ty
52
42
  name: ty check
53
43
  entry: uv run --frozen ty check
54
44
  language: system
55
45
  types_or: [python, pyi]
56
46
  pass_filenames: false
47
+
57
48
  - id: zizmor
58
49
  name: zizmor
59
50
  entry: uv run --frozen zizmor .github/workflows
@@ -4,6 +4,62 @@ Notable changes to **core-framework** (import **`core_framework`**). Format foll
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [3.1.0] - 2026-07-16
8
+
9
+ ### Fixed
10
+
11
+ - **HTTP request correlation on failures/aborts:** `ContextMiddleware` always emits **`HTTP request completed`** (with **`aborted=true`** / null **`status_code`** when no response starts), always attaches **`X-Request-ID`** (including missing-client 400s), stores **`request_id`** on ASGI scope state for 500 handlers, and stays outermost over profiling so profile HTML keeps the header.
12
+ - **Structlog logger caching:** `setup_logging` keeps `cache_logger_on_first_use=False` so the OTel reconfigure can attach; `configure_observability_providers` (OTLP or kill-switch-off) finalizes with `True`.
13
+ - **Observability polish:** Direct ARQ enqueue propagates **`request_id`** (worker ContextVar + span attribute) so Loki filters match media/variant jobs, not only outbox handlers. ARQ job timeouts/`CancelledError` mark the consumer span ERROR (metrics already set `error.type`). **`shutdown_observability`** uninstruments FastAPI/httpx/asyncpg/Redis before shutting providers. Shared **`PROBE_PATHS`** for health/readiness. **`otlp_endpoint`** requires an **`http(s)://`** base URL (stored stripped) and rejects signal paths (`.../v1/traces` etc.). FastAPI probe **`excluded_urls`** match host + exact path (`://[^/]+/health$`). Collector Compose healthcheck removed (distroless image; Grafana depends on start-order). Tempo→Loki **`tracesToLogsV2`** maps **`service.name`** / **`deployment.environment.name`**. Provisioned dashboards set **`allowUiUpdates: false`** and **`editable: false`**.
14
+ - **Observability review pass:** Structlog OTLP processor skips export when instrumentation is disabled (exporter failure feedback loop guard); trims duplicate **`level`**/**`timestamp`** and native **`trace_id`**/**`span_id`** attributes; truncates large **`exception`** strings. FastAPI instrumentation uses **`exclude_spans=["receive","send"]`**. Sampler uses **`get_value`** for suppress-instrumentation keys. OTLP headers parsed via **`parse_env_headers`**. Worker metrics include **`messaging.system=arq`** and **`error.type`** on generic exceptions. **`shutdown_observability`** isolates per-provider failures and clears the job duration histogram; API and worker shut it down via **`asyncio.to_thread`**. ARQ job metrics skip recording after the kill switch flips. Outbox origin metadata reuses **`capture_request_id_for_job`**. Compose **`mem_limit`** / **`GOMEMLIMIT`** on Tempo, Loki, Prometheus, and Grafana.
15
+
16
+ ### Added
17
+
18
+ - **Manual Observability Deployment:** GitHub Actions **`manual-observability-deployment.yaml`** syncs **`deploy/observability/`** and runs Compose on the LGTM host. Uses separate **`OBSERVABILITY_DEPLOY_*`** / **`GRAFANA_ADMIN_PASSWORD`** / optional **`GRAFANA_ROOT_URL`** (not app **`DEPLOY_SERVER_*`**). First run seeds host **`.env`**; later runs keep it.
19
+
20
+ - **Grafana hostname:** Preferred UI access is **`observability.{ZONE}`** via Caddy ([`Caddyfile.observability.example`](docs/deployments/examples/Caddyfile.observability.example)) + Cloudflare DNS + WAF IP allowlist. OTLP stays private. Compose sets **`GF_SERVER_ROOT_URL`** from **`GRAFANA_ROOT_URL`**.
21
+
22
+ - **LGTM image bumps:** Collector **0.156.0**, Tempo **3.0.2** (monolithic config: drop `ingester`/`compactor`; retention via `backend_worker.compaction.block_retention`), Loki **3.7.3**, Prometheus **v3.13.0**, Grafana **13.1.0**.
23
+
24
+ - **API request correlation:** Non-probe responses include **`X-Request-ID`** (also exposed for CORS). **`ContextMiddleware`** sets `request_id` on the current HTTP SERVER span after generating the ULID; emits a structured **`HTTP request completed`** log so quiet successes remain searchable in Loki → Tempo. Uvicorn **`--no-access-log`** is unchanged.
25
+
26
+ - **HTTP metrics semconv:** When OTLP is enabled, core sets **`OTEL_SEMCONV_STABILITY_OPT_IN=http`** (unless already set) before FastAPI/ASGI instrumentation so Prometheus series match **`api-http`** (`http_server_request_duration_seconds_*`).
27
+
28
+ - **Loki storage paths:** **`deploy/observability/loki.yaml`** uses **`path_prefix: /loki`** with explicit TSDB index/cache and WAL dirs under **`/loki`**, matching the Compose **`loki-data:/loki`** volume (avoids writing outside the mount).
29
+
30
+ - **Dashboard env filter:** API/worker dashboards include a **`deployment.environment.name`** variable (Prometheus label **`deployment_environment_name`**).
31
+
32
+ - **Worker telemetry coverage:** **`instrument_arq_jobs`** wraps core **`functions`** and **`cron_jobs`** at registration; timeouts/cancellations set **`error.type=CancelledError`**; hosts must wrap custom jobs the same way.
33
+
34
+ - **LGTM ops hardening:** Collector **`memory_limiter`** + Compose **`mem_limit`/`GOMEMLIMIT`**; Prometheus **8GB** size retention; Loki ingestion caps; Loki **`3.6.12`** native **`-health`** (distroless-safe); Tempo and Collector start-order only (distroless — no in-container wget healthcheck); Grafana waits on Loki/Prometheus healthy + Collector/Tempo started; optional exporter scrape jobs commented by default; Grafana password required; Grafana UI via **`observability.{ZONE}`** (Caddy + WAF allowlist) or SSH tunnel; Tempo datasource omits **`nodeGraph`** (metrics_generator off); docs clarify Loki/Tempo are time-retention only (no size quota).
35
+
36
+ - **Observability lifecycle / naming:** **`shutdown_observability`** is process-end only (OTLP globals cannot be unset); clears kill-switch flags; structlog OTel processor no-ops when the kill switch is off; ARQ job span/metric names use ARQ **`Function.name`/`CronJob.name`**; HTTP **`request_id`** via **`ContextMiddleware`** on the SERVER span; **`HTTP request completed`** covers full response duration (structlog OTel processor injects **`trace_id`** for Loki → Tempo); shared-runtime worker docs note API **`service.name`**.
37
+
38
+ - **Same-host exporter scrapes:** Setup guides allow Docker bridge (**`172.16.0.0/12`**) to node/Postgres/Redis exporter ports so Compose Prometheus (`host.docker.internal`) is not blocked by UFW rules that only permit **`{ADMIN_IP}`**.
39
+
40
+ ### Changed
41
+
42
+ - **Dashboard uid prefix:** Renamed Grafana dashboards **`cf-api-http`** → **`api-http`** and **`cf-worker-jobs`** → **`worker-jobs`** (files and uids). Existing Grafana bookmarks / `/d/cf-*` links need updating after re-provision.
43
+
44
+ ### Removed
45
+
46
+ - **Exporter Grafana dashboards:** Dropped **`cf-host.json`**, **`cf-postgres.json`**, and **`cf-redis.json`**. v1 provisioned dashboards are app/worker OTLP only (API HTTP, Worker jobs). Optional Prometheus scrape jobs for node/Postgres/Redis exporters remain commented in **`prometheus.yml`**.
47
+ - **Runtime dashboard shells:** Dropped deferred **`cf-api-runtime.json`** and **`cf-worker-runtime.json`** (no in-app process metrics in v1).
48
+
49
+ ### Breaking
50
+
51
+ - **Breaking (hosts — observability):** Replace Logfire with OpenTelemetry OTLP on the API and worker. Remove **`logfire`** / **`LOGFIRE_TOKEN`** / **`observability.logfire_token`**. Add **`observability.otlp_endpoint`** (required when enabled outside **`local`**) and **`observability.otlp_headers`** (TOML; deploy template hardcodes empty). Deploy variables **`OBSERVABILITY_OTLP_ENDPOINT`** (and existing **`OBSERVABILITY_ENABLED`**). Pins: **`opentelemetry-api`/`sdk`/`exporter-otlp-proto-http` ≥1.43.0,\<1.44**, instrumentation + **`opentelemetry-semantic-conventions` ≥0.64b0,\<0.65** (FastAPI OPTIONS / `_IncludedRouter` fix). Resource attribute **`deployment.environment.name`** (not deprecated **`deployment.environment`**). ARQ spans use **`messaging.operation.type=process`**, **`messaging.destination.name=<queue>`**, **`messaging.operation.name=<job>`**. Direct ARQ enqueue propagates W3C context; outbox jobs keep a separate consumer span linked to the originating request via persisted **`event_outbox.metadata`** (**`request_id`**, W3C carrier) plus outbox span attributes (`outbox_id`, `idempotency_key`, …). No in-process **`SystemMetricsInstrumentor`**; v1 ships no host/Postgres/Redis or process-runtime Grafana dashboards (optional exporter scrapes stay commented in **`prometheus.yml`**).
52
+
53
+ - **Breaking (API):** **`POST /posts`**, **`POST /comments`**, and **`POST /comments/{comment_id}/replies`** return **`201`** with **`{ "id": "<ulid>" }`** (first success and idempotency replay return the same id). Previously these returned an empty body. See **`docs/domains/posts/create_post.md`**, **`docs/domains/comments/create_comment.md`**, and **`docs/design/create-idempotency-design.md`**.
54
+
55
+ - **Breaking (hosts — config):** Add **`retention.read_notifications_retention_days`** under **`[retention]`** (default **90**). Deploy variable **`RETENTION_READ_NOTIFICATIONS_DAYS`**. The worker runs **`schedule_prune_read_notifications`** (daily **05:05 UTC**) to delete read notifications past that window; unread rows are never pruned. See **`docs/library/workers.md`** and **`docs/domains/notifications/notification_inbox.md`**.
56
+
57
+ ### Migration
58
+
59
+ - **Observability (Logfire → OTLP):** Drop **`LOGFIRE_TOKEN`** / **`observability.logfire_token`**. Add **`observability.otlp_endpoint`** (and optional **`otlp_headers`**) under **`[observability]`**; set **`OBSERVABILITY_OTLP_ENDPOINT`** when **`OBSERVABILITY_ENABLED=true`** outside **`local`**. See **`docs/library/package-api.md`** (Host upgrade — observability OTLP) and **`docs/deployments/guides/setup/observability-lgtm-setup.md`**.
60
+
61
+ - **`notification` schema:** Run **`cf-alembic`** so the stream applies **`2fdd68777706`** (`idx_notifications_read_at_retention` on **`read_at`** where not null) before relying on age-based read-notification pruning at scale.
62
+
7
63
  ## [3.0.0] - 2026-07-11
8
64
 
9
65
  ### Breaking
@@ -515,4 +571,5 @@ First **SemVer-stable** release per **`docs/library/package-api.md`**.
515
571
  [2.3.2]: https://github.com/NepNepFFXIV/core-framework/compare/v2.3.1...v2.3.2
516
572
  [2.3.3]: https://github.com/NepNepFFXIV/core-framework/compare/v2.3.2...v2.3.3
517
573
  [3.0.0]: https://github.com/NepNepFFXIV/core-framework/compare/v2.3.3...v3.0.0
518
- [unreleased]: https://github.com/NepNepFFXIV/core-framework/compare/v3.0.0...HEAD
574
+ [3.1.0]: https://github.com/NepNepFFXIV/core-framework/compare/v3.0.0...v3.1.0
575
+ [unreleased]: https://github.com/NepNepFFXIV/core-framework/compare/v3.1.0...HEAD
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: core-framework
3
- Version: 3.0.0
3
+ Version: 3.1.0
4
4
  Summary: Core framework package (import as core_framework)
5
5
  Project-URL: Homepage, https://github.com/NepNepFFXIV/core-framework
6
6
  Project-URL: Repository, https://github.com/NepNepFFXIV/core-framework
@@ -20,8 +20,15 @@ Requires-Dist: fastapi[standard]>=0.139.0
20
20
  Requires-Dist: firebase-admin>=7.5.0
21
21
  Requires-Dist: httpx[http2]>=0.28.1
22
22
  Requires-Dist: itsdangerous>=2.2.0
23
- Requires-Dist: logfire[asyncpg,fastapi,httpx,redis]>=4.37.0
24
23
  Requires-Dist: mashumaro[orjson]>=3.22
24
+ Requires-Dist: opentelemetry-api<1.44,>=1.43.0
25
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http<1.44,>=1.43.0
26
+ Requires-Dist: opentelemetry-instrumentation-asyncpg<0.65,>=0.64b0
27
+ Requires-Dist: opentelemetry-instrumentation-fastapi<0.65,>=0.64b0
28
+ Requires-Dist: opentelemetry-instrumentation-httpx<0.65,>=0.64b0
29
+ Requires-Dist: opentelemetry-instrumentation-redis<0.65,>=0.64b0
30
+ Requires-Dist: opentelemetry-sdk<1.44,>=1.43.0
31
+ Requires-Dist: opentelemetry-semantic-conventions<0.65,>=0.64b0
25
32
  Requires-Dist: orjson>=3.11.9
26
33
  Requires-Dist: pillow-heif>=1.4.0
27
34
  Requires-Dist: pillow>=12.3.0
@@ -40,18 +47,30 @@ Description-Content-Type: text/markdown
40
47
 
41
48
  Install from PyPI as **`core-framework`**, import **`core_framework`**. MIT — [LICENSE](LICENSE). [Repository](https://github.com/NepNepFFXIV/core-framework), [PyPI](https://pypi.org/project/core-framework/).
42
49
 
50
+ ## Documentation
51
+
52
+ | Doc | Purpose |
53
+ | ---------------------------------------------------------- | --------------------------------------------------------- |
54
+ | [docs/README.md](docs/README.md) | Doc map (platform, design, library, domains, deployments) |
55
+ | [docs/library/package-api.md](docs/library/package-api.md) | Host import surface and upgrade tables |
56
+ | [CHANGELOG.md](CHANGELOG.md) | Release notes (SemVer) |
57
+
43
58
  ## Install
44
59
 
45
60
  ```bash
46
61
  uv add core-framework
47
62
  ```
48
63
 
64
+ Pin hosts to a locked version. On each bump, read **[CHANGELOG.md](CHANGELOG.md)** and the host-upgrade tables in **[package-api.md](docs/library/package-api.md)**.
65
+
49
66
  ## Local development
50
67
 
51
68
  Use **Python 3.14**. Install **uv** and **Docker**.
52
69
 
70
+ Tracked **`config.toml`** at the repo root is the local-dev settings file (dummy values; no production secrets). Production renders from **`config.toml.template`** via deploy **`envsubst`** — see [architecture decisions](docs/platform/architecture-decisions.md).
71
+
53
72
  ```bash
54
- docker compose -f docker-compose.dev.yaml up -d
73
+ docker compose -f deploy/app/docker-compose.dev.yaml up -d
55
74
  uv sync --locked --all-extras --dev
56
75
  uv run cf-alembic
57
76
  make run
@@ -59,7 +78,7 @@ make run
59
78
 
60
79
  **Firebase:** copy **`firebase_config.example.json`** to **`firebase_config.json`** at the repo root and replace with your Firebase project’s **service account** JSON from the console.
61
80
 
62
- For **`make test`**, use the Firebase CLI (Auth emulator). Stop DB/Redis: **`docker compose -f docker-compose.dev.yaml down`**.
81
+ For **`make test`**, use the Firebase CLI (Auth emulator). Stop DB/Redis: **`docker compose -f deploy/app/docker-compose.dev.yaml down`**.
63
82
 
64
83
  **Pre-commit:** `uv sync --dev` installs **pre-commit**. Enable hooks with **`uv run pre-commit install`** (ruff, mdformat, uv-lock, and other checks in **`.pre-commit-config.yaml`**).
65
84
 
@@ -92,6 +111,10 @@ def build_app(settings: HostSettings | None = None) -> FastAPI:
92
111
 
93
112
  From the host repository root, run **`uv run cf-alembic`**. See [core-framework-migration](docs/library/core-framework-migration.md).
94
113
 
114
+ **Worker:** production also runs the ARQ worker (`arq core_framework.worker.main.WorkerSettings`, or a host composition that calls the same startup path). Schedules and tasks: [workers.md](docs/library/workers.md). Composition details: [package-api.md](docs/library/package-api.md) (Default deployment entrypoints).
115
+
116
+ **Observability:** OpenTelemetry OTLP (not Logfire). Under **`[observability]`**, set **`enabled`** and **`otlp_endpoint`** (required when enabled outside **`local`**); drop **`logfire_token`** / **`LOGFIRE_TOKEN`**. Same-host Grafana LGTM stack: **`deploy/observability/`** and [observability-lgtm-setup.md](docs/deployments/guides/setup/observability-lgtm-setup.md). Host upgrade table: [package-api.md — observability OTLP](docs/library/package-api.md).
117
+
95
118
  ## Host pytest
96
119
 
97
120
  In your host repository, add the **`core-framework[testing]`** extra to dev or test dependencies. In **`tests/conftest.py`**, register **`pytest_core_framework_config`** (returns **`TestConfig`**) and a session-scoped **`anyio_backend`** fixture that returns **`"asyncio"`**.
@@ -2,18 +2,30 @@
2
2
 
3
3
  Install from PyPI as **`core-framework`**, import **`core_framework`**. MIT — [LICENSE](LICENSE). [Repository](https://github.com/NepNepFFXIV/core-framework), [PyPI](https://pypi.org/project/core-framework/).
4
4
 
5
+ ## Documentation
6
+
7
+ | Doc | Purpose |
8
+ | ---------------------------------------------------------- | --------------------------------------------------------- |
9
+ | [docs/README.md](docs/README.md) | Doc map (platform, design, library, domains, deployments) |
10
+ | [docs/library/package-api.md](docs/library/package-api.md) | Host import surface and upgrade tables |
11
+ | [CHANGELOG.md](CHANGELOG.md) | Release notes (SemVer) |
12
+
5
13
  ## Install
6
14
 
7
15
  ```bash
8
16
  uv add core-framework
9
17
  ```
10
18
 
19
+ Pin hosts to a locked version. On each bump, read **[CHANGELOG.md](CHANGELOG.md)** and the host-upgrade tables in **[package-api.md](docs/library/package-api.md)**.
20
+
11
21
  ## Local development
12
22
 
13
23
  Use **Python 3.14**. Install **uv** and **Docker**.
14
24
 
25
+ Tracked **`config.toml`** at the repo root is the local-dev settings file (dummy values; no production secrets). Production renders from **`config.toml.template`** via deploy **`envsubst`** — see [architecture decisions](docs/platform/architecture-decisions.md).
26
+
15
27
  ```bash
16
- docker compose -f docker-compose.dev.yaml up -d
28
+ docker compose -f deploy/app/docker-compose.dev.yaml up -d
17
29
  uv sync --locked --all-extras --dev
18
30
  uv run cf-alembic
19
31
  make run
@@ -21,7 +33,7 @@ make run
21
33
 
22
34
  **Firebase:** copy **`firebase_config.example.json`** to **`firebase_config.json`** at the repo root and replace with your Firebase project’s **service account** JSON from the console.
23
35
 
24
- For **`make test`**, use the Firebase CLI (Auth emulator). Stop DB/Redis: **`docker compose -f docker-compose.dev.yaml down`**.
36
+ For **`make test`**, use the Firebase CLI (Auth emulator). Stop DB/Redis: **`docker compose -f deploy/app/docker-compose.dev.yaml down`**.
25
37
 
26
38
  **Pre-commit:** `uv sync --dev` installs **pre-commit**. Enable hooks with **`uv run pre-commit install`** (ruff, mdformat, uv-lock, and other checks in **`.pre-commit-config.yaml`**).
27
39
 
@@ -54,6 +66,10 @@ def build_app(settings: HostSettings | None = None) -> FastAPI:
54
66
 
55
67
  From the host repository root, run **`uv run cf-alembic`**. See [core-framework-migration](docs/library/core-framework-migration.md).
56
68
 
69
+ **Worker:** production also runs the ARQ worker (`arq core_framework.worker.main.WorkerSettings`, or a host composition that calls the same startup path). Schedules and tasks: [workers.md](docs/library/workers.md). Composition details: [package-api.md](docs/library/package-api.md) (Default deployment entrypoints).
70
+
71
+ **Observability:** OpenTelemetry OTLP (not Logfire). Under **`[observability]`**, set **`enabled`** and **`otlp_endpoint`** (required when enabled outside **`local`**); drop **`logfire_token`** / **`LOGFIRE_TOKEN`**. Same-host Grafana LGTM stack: **`deploy/observability/`** and [observability-lgtm-setup.md](docs/deployments/guides/setup/observability-lgtm-setup.md). Host upgrade table: [package-api.md — observability OTLP](docs/library/package-api.md).
72
+
57
73
  ## Host pytest
58
74
 
59
75
  In your host repository, add the **`core-framework[testing]`** extra to dev or test dependencies. In **`tests/conftest.py`**, register **`pytest_core_framework_config`** (returns **`TestConfig`**) and a session-scoped **`anyio_backend`** fixture that returns **`"asyncio"`**.