core-framework 2.3.1__tar.gz → 2.3.3__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 (709) hide show
  1. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/api-reference-docs.mdc +9 -0
  2. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/constitution.mdc +1 -1
  3. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/error-boundary.mdc +3 -3
  4. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/no-code-in-docs.mdc +1 -1
  5. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/skills/add-domain/SKILL.md +1 -1
  6. core_framework-2.3.3/.cursor/skills/implement-feature/SKILL.md +93 -0
  7. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/skills/sync-host-rules/SKILL.md +5 -5
  8. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/skills/write-flow-doc/SKILL.md +2 -1
  9. {core_framework-2.3.1 → core_framework-2.3.3}/CHANGELOG.md +55 -5
  10. {core_framework-2.3.1 → core_framework-2.3.3}/PKG-INFO +3 -2
  11. {core_framework-2.3.1 → core_framework-2.3.3}/README.md +2 -0
  12. core_framework-2.3.3/alembic/analytics/alembic/versions/2d61a5e88d76_analytics_utm_events_add_kind.py +36 -0
  13. core_framework-2.3.3/alembic/analytics/alembic/versions/585105e1149e_analytics_add_utm_events.py +38 -0
  14. core_framework-2.3.3/alembic/user/alembic/versions/44df70a45ba6_user_add_signup_events.py +32 -0
  15. {core_framework-2.3.1 → core_framework-2.3.3}/config.toml +1 -0
  16. {core_framework-2.3.1 → core_framework-2.3.3}/config.toml.template +1 -0
  17. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/auth/schemas.py +1 -12
  18. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/dependencies.py +12 -14
  19. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/auth/access_service.py +2 -1
  20. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/bootstrap.py +2 -5
  21. core_framework-2.3.3/core_framework/application/events/README.md +31 -0
  22. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/events/event_service.py +63 -2
  23. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/events/event_token.py +2 -2
  24. core_framework-2.3.3/core_framework/application/events/utm_capture_kinds.py +30 -0
  25. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/shared/enums.py +3 -1
  26. core_framework-2.3.3/core_framework/application/shared/request_context.py +66 -0
  27. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/users/admin_service.py +0 -2
  28. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/users/public_service.py +4 -2
  29. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/cache.py +18 -2
  30. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/analytics/README.md +18 -2
  31. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/analytics/__init__.py +9 -1
  32. core_framework-2.3.3/core_framework/domains/analytics/constants.py +19 -0
  33. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/analytics/repository.py +29 -0
  34. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/analytics/service.py +65 -1
  35. core_framework-2.3.3/core_framework/domains/auth/README.md +68 -0
  36. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/comment/README.md +2 -0
  37. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/README.md +3 -1
  38. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/moderation/README.md +2 -0
  39. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/notification/README.md +3 -3
  40. core_framework-2.3.3/core_framework/domains/outbox/README.md +65 -0
  41. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/post/README.md +2 -0
  42. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/user/README.md +7 -1
  43. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/user/repository.py +25 -0
  44. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/user/service.py +21 -0
  45. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/testing/auth.py +0 -19
  46. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/schedule_expired_account_deletions.py +1 -0
  47. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/schedule_expired_mute_lifts.py +1 -0
  48. core_framework-2.3.3/docs/README.md +46 -0
  49. {core_framework-2.3.1 → core_framework-2.3.3}/docs/deployments/README.md +1 -1
  50. {core_framework-2.3.1 → core_framework-2.3.3}/docs/deployments/deploy-playbook.md +2 -1
  51. {core_framework-2.3.1 → core_framework-2.3.3}/docs/deployments/edge-upload-limits.md +1 -1
  52. core_framework-2.3.3/docs/deployments/guides/app-server-deploy-ssh.md +78 -0
  53. core_framework-2.3.3/docs/deployments/guides/image-server-ssh.md +93 -0
  54. {core_framework-2.3.1 → core_framework-2.3.3}/docs/deployments/guides/ubuntu-server-setup.md +1 -0
  55. core_framework-2.3.3/docs/design/README.md +30 -0
  56. {core_framework-2.3.1/docs/platform → core_framework-2.3.3/docs/design}/analytics-rollup-design.md +40 -45
  57. core_framework-2.3.3/docs/design/cache-invalidation-design.md +141 -0
  58. {core_framework-2.3.1/docs/platform → core_framework-2.3.3/docs/design}/create-idempotency-design.md +19 -18
  59. {core_framework-2.3.1/docs/platform → core_framework-2.3.3/docs/design}/event-outbox-design.md +50 -169
  60. core_framework-2.3.3/docs/design/events-ingest-design.md +226 -0
  61. {core_framework-2.3.1/docs/platform → core_framework-2.3.3/docs/design}/media-storage-topology.md +2 -2
  62. {core_framework-2.3.1/docs/platform → core_framework-2.3.3/docs/design}/outbox-admin-ops-design.md +3 -3
  63. core_framework-2.3.3/docs/design/utm-events-design.md +272 -0
  64. core_framework-2.3.3/docs/domains/README.md +23 -0
  65. core_framework-2.3.3/docs/domains/analytics/admin_analytics_reads.md +135 -0
  66. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/auth/access_control.md +1 -1
  67. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/auth/registration.md +4 -3
  68. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/cache/admin_cache_invalidation.md +11 -50
  69. core_framework-2.3.3/docs/domains/comments/README.md +31 -0
  70. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/comments/admin_comments.md +6 -5
  71. core_framework-2.3.3/docs/domains/comments/comment_like.md +96 -0
  72. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/comments/comment_report.md +4 -3
  73. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/comments/comment_stats_aggregation.md +6 -7
  74. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/comments/create_comment.md +22 -18
  75. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/comments/edit_comment.md +7 -5
  76. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/comments/retrieve_comments.md +13 -9
  77. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/deletion/comments.md +1 -1
  78. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/deletion/overview.md +11 -3
  79. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/deletion/posts.md +1 -1
  80. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/deletion/users.md +65 -63
  81. core_framework-2.3.3/docs/domains/events/events.md +242 -0
  82. core_framework-2.3.3/docs/domains/media/README.md +36 -0
  83. core_framework-2.3.3/docs/domains/media/attachment_upload.md +73 -0
  84. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/media/avatar-upload-design.md +9 -9
  85. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/media/banner-upload-design.md +14 -14
  86. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/media/post-comment-attachments-design.md +9 -9
  87. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/media/upload-pipeline-design.md +51 -46
  88. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/media/upload_pipeline.md +20 -5
  89. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/mentions/mentions_in_content.md +12 -11
  90. core_framework-2.3.3/docs/domains/moderation/README.md +28 -0
  91. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/moderation/appeals.md +18 -8
  92. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/moderation/internal_notes.md +11 -10
  93. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/moderation/moderator_actions.md +6 -5
  94. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/moderation/reports.md +10 -8
  95. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/moderation/restrictions.md +55 -23
  96. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/notifications/notification_inbox.md +19 -17
  97. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/outbox/admin_outbox_ops.md +8 -6
  98. core_framework-2.3.3/docs/domains/posts/README.md +33 -0
  99. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/posts/admin_posts.md +8 -6
  100. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/posts/author_context.md +1 -1
  101. core_framework-2.3.3/docs/domains/posts/create_post.md +112 -0
  102. core_framework-2.3.3/docs/domains/posts/edit_post.md +80 -0
  103. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/posts/hashtag_discovery.md +6 -4
  104. core_framework-2.3.3/docs/domains/posts/post_report.md +105 -0
  105. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/posts/post_stats_aggregation.md +7 -8
  106. core_framework-2.3.3/docs/domains/posts/retrieve_posts.md +190 -0
  107. core_framework-2.3.3/docs/domains/users/account.md +106 -0
  108. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/users/account_deletion.md +6 -7
  109. core_framework-2.3.3/docs/domains/users/admin_users.md +166 -0
  110. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/users/avatar.md +1 -3
  111. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/users/banner.md +7 -8
  112. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/users/blocks.md +10 -9
  113. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/users/change_history.md +5 -4
  114. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/users/check_username_exists.md +3 -3
  115. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/users/follow-system-design.md +26 -32
  116. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/users/follow.md +13 -10
  117. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/users/my_posts_and_comments.md +4 -4
  118. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/users/preferences.md +1 -1
  119. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/users/public_profile.md +5 -5
  120. core_framework-2.3.3/docs/domains/users/user_removal.md +86 -0
  121. core_framework-2.3.3/docs/domains/users/user_stats_aggregation.md +79 -0
  122. core_framework-2.3.3/docs/library/README.md +15 -0
  123. core_framework-2.3.3/docs/library/api.md +212 -0
  124. core_framework-2.3.3/docs/library/capability-wiring.md +123 -0
  125. {core_framework-2.3.1 → core_framework-2.3.3}/docs/library/core-framework-migration.md +21 -65
  126. {core_framework-2.3.1 → core_framework-2.3.3}/docs/library/overview.md +19 -17
  127. {core_framework-2.3.1 → core_framework-2.3.3}/docs/library/package-api.md +37 -7
  128. {core_framework-2.3.1 → core_framework-2.3.3}/docs/library/testing-plugin-design.md +23 -26
  129. core_framework-2.3.3/docs/library/workers.md +81 -0
  130. core_framework-2.3.3/docs/platform/README.md +18 -0
  131. {core_framework-2.3.1 → core_framework-2.3.3}/docs/platform/architecture-decisions.md +11 -13
  132. {core_framework-2.3.1 → core_framework-2.3.3}/docs/platform/client-error-visibility.md +100 -56
  133. {core_framework-2.3.1 → core_framework-2.3.3}/docs/platform/conventions.md +22 -1
  134. core_framework-2.3.3/docs/platform/domain-services-and-adapters.md +60 -0
  135. {core_framework-2.3.1 → core_framework-2.3.3}/docs/platform/patch-update-typed-payload.md +2 -1
  136. {core_framework-2.3.1 → core_framework-2.3.3}/docs/testing.md +14 -13
  137. {core_framework-2.3.1 → core_framework-2.3.3}/docs/todo.md +1 -2
  138. {core_framework-2.3.1 → core_framework-2.3.3}/pyproject.toml +2 -2
  139. core_framework-2.3.3/tests/integration/api/events/router_test.py +759 -0
  140. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/posts/post_stats_dirty_marking_test.py +2 -2
  141. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/application/events/event_service_test.py +47 -1
  142. core_framework-2.3.3/tests/unit/application/shared/request_context_test.py +30 -0
  143. core_framework-2.3.3/tests/unit/docs/_api_reference.py +67 -0
  144. core_framework-2.3.3/tests/unit/docs/api_routes_test.py +54 -0
  145. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/domains/user/service_test.py +46 -0
  146. {core_framework-2.3.1 → core_framework-2.3.3}/uv.lock +101 -12
  147. core_framework-2.3.1/.cursor/skills/implement-feature/SKILL.md +0 -66
  148. core_framework-2.3.1/core_framework/application/events/README.md +0 -35
  149. core_framework-2.3.1/core_framework/application/shared/user_agent.py +0 -25
  150. core_framework-2.3.1/core_framework/domains/analytics/constants.py +0 -3
  151. core_framework-2.3.1/docs/README.md +0 -30
  152. core_framework-2.3.1/docs/deployments/guides/app-server-deploy-ssh.md +0 -55
  153. core_framework-2.3.1/docs/deployments/guides/image-server-ssh.md +0 -62
  154. core_framework-2.3.1/docs/domains/README.md +0 -18
  155. core_framework-2.3.1/docs/domains/events/events.md +0 -126
  156. core_framework-2.3.1/docs/domains/users/account.md +0 -61
  157. core_framework-2.3.1/docs/domains/users/user_removal.md +0 -133
  158. core_framework-2.3.1/docs/library/README.md +0 -12
  159. core_framework-2.3.1/docs/library/api.md +0 -205
  160. core_framework-2.3.1/docs/platform/README.md +0 -19
  161. core_framework-2.3.1/docs/platform/domain-services-and-adapters.md +0 -116
  162. core_framework-2.3.1/docs/platform/events-ingest-design.md +0 -109
  163. core_framework-2.3.1/tests/integration/api/events/router_test.py +0 -180
  164. {core_framework-2.3.1 → core_framework-2.3.3}/.agents/skills/fastapi +0 -0
  165. {core_framework-2.3.1 → core_framework-2.3.3}/.agents/skills/library-skills/.library-skills.json +0 -0
  166. {core_framework-2.3.1 → core_framework-2.3.3}/.agents/skills/library-skills/SKILL.md +0 -0
  167. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/alembic-migrations.mdc +0 -0
  168. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/api-layer.mdc +0 -0
  169. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/api-validation.mdc +0 -0
  170. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/application-layer.mdc +0 -0
  171. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/constants-final.mdc +0 -0
  172. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/database-triggers.mdc +0 -0
  173. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/docstrings.mdc +0 -0
  174. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/domain-caller-context.mdc +0 -0
  175. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/domain-imports.mdc +0 -0
  176. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/domain-input-guards.mdc +0 -0
  177. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/domain-repository-exceptions.mdc +0 -0
  178. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/domain-services-and-adapters.mdc +0 -0
  179. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/flow-documentation.mdc +0 -0
  180. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/inline-raise-messages.mdc +0 -0
  181. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/integration-test-strategy.mdc +0 -0
  182. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/layer-boundaries.mdc +0 -0
  183. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/postgres-config-conventions.mdc +0 -0
  184. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/repository-schema-isolation.mdc +0 -0
  185. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/strong-reads.mdc +0 -0
  186. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/rules/structured-logging.mdc +0 -0
  187. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/skills/add-config/SKILL.md +0 -0
  188. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/skills/code-review/SKILL.md +0 -0
  189. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/skills/fastapi +0 -0
  190. {core_framework-2.3.1 → core_framework-2.3.3}/.cursor/skills/recommend-features/SKILL.md +0 -0
  191. {core_framework-2.3.1 → core_framework-2.3.3}/.dockerignore +0 -0
  192. {core_framework-2.3.1 → core_framework-2.3.3}/.github/workflows/_deploy.yml +0 -0
  193. {core_framework-2.3.1 → core_framework-2.3.3}/.github/workflows/dev-ci-cd.yaml +0 -0
  194. {core_framework-2.3.1 → core_framework-2.3.3}/.github/workflows/manual-deployment.yaml +0 -0
  195. {core_framework-2.3.1 → core_framework-2.3.3}/.github/workflows/publish-pypi.yml +0 -0
  196. {core_framework-2.3.1 → core_framework-2.3.3}/.github/workflows/test.yaml +0 -0
  197. {core_framework-2.3.1 → core_framework-2.3.3}/.gitignore +0 -0
  198. {core_framework-2.3.1 → core_framework-2.3.3}/.pre-commit-config.yaml +0 -0
  199. {core_framework-2.3.1 → core_framework-2.3.3}/.python-version +0 -0
  200. {core_framework-2.3.1 → core_framework-2.3.3}/LICENSE +0 -0
  201. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/analytics/alembic/README +0 -0
  202. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/analytics/alembic/env.py +0 -0
  203. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/analytics/alembic/script.py.mako +0 -0
  204. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/analytics/alembic/versions/5b9ac98bb150_analytics_daily_fact.py +0 -0
  205. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/analytics/alembic/versions/7f2a9c1d4e8b_analytics_daily_fact_day_index.py +0 -0
  206. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/analytics/alembic.ini +0 -0
  207. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/comment/alembic/README +0 -0
  208. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/comment/alembic/env.py +0 -0
  209. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/comment/alembic/script.py.mako +0 -0
  210. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/comment/alembic/versions/comment_add_comment_attachments.py +0 -0
  211. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/comment/alembic/versions/comment_add_comment_create_idempotency.py +0 -0
  212. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/comment/alembic/versions/comment_add_comment_create_idempotency_created_at_index.py +0 -0
  213. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/comment/alembic/versions/comment_add_comment_mentions.py +0 -0
  214. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/comment/alembic/versions/comment_tombstone_status_model.py +0 -0
  215. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/comment/alembic/versions/v1_comment_init_baseline.py +0 -0
  216. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/comment/alembic.ini +0 -0
  217. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/extension/alembic/README +0 -0
  218. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/extension/alembic/env.py +0 -0
  219. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/extension/alembic/script.py.mako +0 -0
  220. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/extension/alembic/versions/v1_ext_init_baseline.py +0 -0
  221. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/extension/alembic.ini +0 -0
  222. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/media/alembic/README +0 -0
  223. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/media/alembic/env.py +0 -0
  224. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/media/alembic/script.py.mako +0 -0
  225. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/media/alembic/versions/media_add_attachment_staging_registry.py +0 -0
  226. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/media/alembic/versions/media_add_banner_staging_and_lease.py +0 -0
  227. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/media/alembic/versions/media_attachment_staging_registry_published_at.py +0 -0
  228. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/media/alembic/versions/v1_media_init_baseline.py +0 -0
  229. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/media/alembic.ini +0 -0
  230. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/moderation/alembic/README +0 -0
  231. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/moderation/alembic/env.py +0 -0
  232. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/moderation/alembic/script.py.mako +0 -0
  233. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/moderation/alembic/versions/moderation_add_event_outbox.py +0 -0
  234. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/moderation/alembic/versions/moderation_add_event_outbox_dead_indexes.py +0 -0
  235. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/moderation/alembic/versions/moderation_add_event_outbox_pending_created_at_index.py +0 -0
  236. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/moderation/alembic/versions/v1_mod_init_baseline.py +0 -0
  237. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/moderation/alembic.ini +0 -0
  238. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/notification/alembic/README +0 -0
  239. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/notification/alembic/env.py +0 -0
  240. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/notification/alembic/script.py.mako +0 -0
  241. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/notification/alembic/versions/v1_notif_init_baseline.py +0 -0
  242. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/notification/alembic.ini +0 -0
  243. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/post/alembic/README +0 -0
  244. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/post/alembic/env.py +0 -0
  245. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/post/alembic/script.py.mako +0 -0
  246. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/post/alembic/versions/post_add_post_attachments.py +0 -0
  247. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/post/alembic/versions/post_add_post_create_idempotency.py +0 -0
  248. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/post/alembic/versions/post_add_post_create_idempotency_created_at_index.py +0 -0
  249. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/post/alembic/versions/post_add_post_mentions.py +0 -0
  250. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/post/alembic/versions/post_post_views_retention_high_water_mark.py +0 -0
  251. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/post/alembic/versions/post_tombstone_status_model.py +0 -0
  252. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/post/alembic/versions/v1_post_init_baseline.py +0 -0
  253. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/post/alembic.ini +0 -0
  254. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/user/alembic/README +0 -0
  255. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/user/alembic/env.py +0 -0
  256. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/user/alembic/script.py.mako +0 -0
  257. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/user/alembic/versions/user_add_avatar_ingest_sequences.py +0 -0
  258. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/user/alembic/versions/user_add_banner_ingest_sequences.py +0 -0
  259. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/user/alembic/versions/user_add_date_of_birth_to_profiles.py +0 -0
  260. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/user/alembic/versions/user_add_event_outbox.py +0 -0
  261. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/user/alembic/versions/user_add_event_outbox_dead_indexes.py +0 -0
  262. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/user/alembic/versions/user_add_event_outbox_pending_created_at_index.py +0 -0
  263. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/user/alembic/versions/user_reserve_sentinel_user_ids.py +0 -0
  264. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/user/alembic/versions/v1_user_init_baseline.py +0 -0
  265. {core_framework-2.3.1 → core_framework-2.3.3}/alembic/user/alembic.ini +0 -0
  266. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/__init__.py +0 -0
  267. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/__init__.py +0 -0
  268. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/__init__.py +0 -0
  269. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/analytics/router.py +0 -0
  270. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/analytics/schemas.py +0 -0
  271. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/cache/router.py +0 -0
  272. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/cache/schemas.py +0 -0
  273. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/comments/router.py +0 -0
  274. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/comments/schemas.py +0 -0
  275. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/moderation/__init__.py +0 -0
  276. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/moderation/router.py +0 -0
  277. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/moderation/schemas.py +0 -0
  278. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/outbox/router.py +0 -0
  279. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/outbox/schemas.py +0 -0
  280. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/posts/router.py +0 -0
  281. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/posts/schemas.py +0 -0
  282. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/router.py +0 -0
  283. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/users/__init__.py +0 -0
  284. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/users/router.py +0 -0
  285. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/admin/users/schemas.py +0 -0
  286. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/attachments/router.py +0 -0
  287. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/attachments/schemas.py +0 -0
  288. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/auth/__init__.py +0 -0
  289. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/auth/router.py +0 -0
  290. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/comments/authenticated/mappers.py +0 -0
  291. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/comments/authenticated/router.py +0 -0
  292. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/comments/authenticated/schemas.py +0 -0
  293. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/comments/public/router.py +0 -0
  294. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/comments/public/schemas.py +0 -0
  295. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/comments/router.py +0 -0
  296. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/comments/schemas.py +0 -0
  297. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/constants.py +0 -0
  298. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/events/router.py +0 -0
  299. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/events/schemas.py +0 -0
  300. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/idempotency/__init__.py +0 -0
  301. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/idempotency/dependencies.py +0 -0
  302. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/notifications/authenticated/router.py +0 -0
  303. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/notifications/authenticated/schemas.py +0 -0
  304. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/notifications/router.py +0 -0
  305. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/posts/authenticated/mappers.py +0 -0
  306. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/posts/authenticated/router.py +0 -0
  307. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/posts/authenticated/schemas.py +0 -0
  308. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/posts/public/router.py +0 -0
  309. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/posts/public/schemas.py +0 -0
  310. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/posts/router.py +0 -0
  311. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/posts/schemas.py +0 -0
  312. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/router.py +0 -0
  313. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/schemas.py +0 -0
  314. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/system/__init__.py +0 -0
  315. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/system/router.py +0 -0
  316. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/users/__init__.py +0 -0
  317. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/users/authenticated/__init__.py +0 -0
  318. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/users/authenticated/mappers.py +0 -0
  319. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/users/authenticated/router.py +0 -0
  320. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/users/authenticated/schemas.py +0 -0
  321. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/users/mappers.py +0 -0
  322. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/users/public/__init__.py +0 -0
  323. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/users/public/router.py +0 -0
  324. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/users/public/schemas.py +0 -0
  325. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/users/router.py +0 -0
  326. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/api/users/shared/schemas.py +0 -0
  327. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/__init__.py +0 -0
  328. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/analytics/bucket_service.py +0 -0
  329. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/analytics/prune_service.py +0 -0
  330. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/analytics/read_service.py +0 -0
  331. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/analytics/refresh_service.py +0 -0
  332. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/analytics/registry.py +0 -0
  333. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/analytics/sources/comment_created.py +0 -0
  334. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/analytics/sources/post_created.py +0 -0
  335. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/analytics/sources/post_viewed.py +0 -0
  336. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/analytics/sources/user_registered.py +0 -0
  337. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/auth/__init__.py +0 -0
  338. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/auth/auth_service.py +0 -0
  339. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/auth/models.py +0 -0
  340. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/cache/invalidate_service.py +0 -0
  341. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/cache/models.py +0 -0
  342. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/comments/admin_service.py +0 -0
  343. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/comments/aggregation_service.py +0 -0
  344. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/comments/authenticated_service.py +0 -0
  345. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/comments/cleanup_service.py +0 -0
  346. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/comments/public_service.py +0 -0
  347. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/events/models.py +0 -0
  348. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/media/README.md +0 -0
  349. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/media/attachment_read.py +0 -0
  350. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/media/attachment_service.py +0 -0
  351. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/media/avatar_service.py +0 -0
  352. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/media/banner_service.py +0 -0
  353. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/media/ingest_guards.py +0 -0
  354. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/media/read_url_config.py +0 -0
  355. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/moderation/__init__.py +0 -0
  356. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/moderation/appeal_service.py +0 -0
  357. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/moderation/moderator_service.py +0 -0
  358. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/moderation/report_service.py +0 -0
  359. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/moderation/scheduled_service.py +0 -0
  360. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/moderation/user_service.py +0 -0
  361. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/notifications/README.md +0 -0
  362. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/notifications/enums.py +0 -0
  363. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/notifications/inbox_service.py +0 -0
  364. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/notifications/mute_service.py +0 -0
  365. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/notifications/notification_service.py +0 -0
  366. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/outbox/block_mirrors.py +0 -0
  367. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/outbox/events.py +0 -0
  368. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/outbox/exceptions.py +0 -0
  369. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/outbox/follow_mirrors.py +0 -0
  370. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/outbox/handlers.py +0 -0
  371. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/outbox/ops_service.py +0 -0
  372. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/outbox/polling_service.py +0 -0
  373. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/outbox/processing_service.py +0 -0
  374. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/outbox/restriction_mirrors.py +0 -0
  375. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/posts/admin_service.py +0 -0
  376. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/posts/aggregation_service.py +0 -0
  377. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/posts/authenticated_service.py +0 -0
  378. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/posts/cleanup_service.py +0 -0
  379. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/posts/public_service.py +0 -0
  380. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/shared/__init__.py +0 -0
  381. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/shared/exceptions.py +0 -0
  382. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/shared/worker_jobs.py +0 -0
  383. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/users/__init__.py +0 -0
  384. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/users/aggregation_service.py +0 -0
  385. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/users/authenticated_service.py +0 -0
  386. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/users/deletion_audit.py +0 -0
  387. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/users/enums.py +0 -0
  388. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/users/scheduled_service.py +0 -0
  389. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/application/users/user_deletion_service.py +0 -0
  390. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/asgi.py +0 -0
  391. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/bundled_alembic.py +0 -0
  392. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/constants.py +0 -0
  393. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/__init__.py +0 -0
  394. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/context.py +0 -0
  395. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/database.py +0 -0
  396. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/exception_handlers/__init__.py +0 -0
  397. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/exception_handlers/application.py +0 -0
  398. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/exception_handlers/common.py +0 -0
  399. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/exception_handlers/setup.py +0 -0
  400. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/exceptions.py +0 -0
  401. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/firebase.py +0 -0
  402. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/http_client.py +0 -0
  403. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/logging.py +0 -0
  404. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/middleware.py +0 -0
  405. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/observability.py +0 -0
  406. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/pagination.py +0 -0
  407. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/redis.py +0 -0
  408. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/runtime.py +0 -0
  409. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/core/settings.py +0 -0
  410. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/__init__.py +0 -0
  411. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/analytics/dependencies.py +0 -0
  412. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/analytics/exceptions.py +0 -0
  413. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/analytics/models.py +0 -0
  414. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/analytics/ports/activity_source.py +0 -0
  415. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/auth/__init__.py +0 -0
  416. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/auth/dependencies.py +0 -0
  417. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/auth/exceptions.py +0 -0
  418. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/auth/models.py +0 -0
  419. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/auth/ports/__init__.py +0 -0
  420. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/auth/ports/auth.py +0 -0
  421. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/auth/service.py +0 -0
  422. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/comment/__init__.py +0 -0
  423. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/comment/constants.py +0 -0
  424. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/comment/dependencies.py +0 -0
  425. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/comment/enums.py +0 -0
  426. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/comment/exceptions.py +0 -0
  427. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/comment/models.py +0 -0
  428. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/comment/outcomes.py +0 -0
  429. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/comment/repository.py +0 -0
  430. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/comment/service.py +0 -0
  431. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/exceptions.py +0 -0
  432. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/__init__.py +0 -0
  433. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/attachment/components/finals_publisher.py +0 -0
  434. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/attachment/components/staging.py +0 -0
  435. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/attachment/components/variant_encoder.py +0 -0
  436. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/attachment/constants.py +0 -0
  437. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/attachment/exceptions.py +0 -0
  438. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/attachment/models.py +0 -0
  439. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/attachment/ports/finals_publisher.py +0 -0
  440. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/attachment/ports/staging.py +0 -0
  441. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/attachment/ports/variant_encoder.py +0 -0
  442. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/attachment/service.py +0 -0
  443. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/avatar/__init__.py +0 -0
  444. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/avatar/components/__init__.py +0 -0
  445. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/avatar/components/finals_publisher.py +0 -0
  446. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/avatar/components/staging.py +0 -0
  447. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/avatar/components/variant_encoder.py +0 -0
  448. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/avatar/constants.py +0 -0
  449. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/avatar/exceptions.py +0 -0
  450. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/avatar/models.py +0 -0
  451. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/avatar/ports/__init__.py +0 -0
  452. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/avatar/ports/finals_publisher.py +0 -0
  453. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/avatar/ports/staging.py +0 -0
  454. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/avatar/ports/variant_encoder.py +0 -0
  455. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/avatar/service.py +0 -0
  456. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/banner/components/finals_publisher.py +0 -0
  457. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/banner/components/staging.py +0 -0
  458. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/banner/components/variant_encoder.py +0 -0
  459. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/banner/constants.py +0 -0
  460. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/banner/exceptions.py +0 -0
  461. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/banner/models.py +0 -0
  462. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/banner/ports/finals_publisher.py +0 -0
  463. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/banner/ports/staging.py +0 -0
  464. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/banner/ports/variant_encoder.py +0 -0
  465. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/banner/service.py +0 -0
  466. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/dependencies.py +0 -0
  467. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/shared/__init__.py +0 -0
  468. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/shared/constants.py +0 -0
  469. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/shared/exceptions.py +0 -0
  470. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/shared/outcomes.py +0 -0
  471. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/shared/repository.py +0 -0
  472. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/shared/service.py +0 -0
  473. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/media/shared/utils.py +0 -0
  474. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/moderation/__init__.py +0 -0
  475. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/moderation/dependencies.py +0 -0
  476. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/moderation/enums.py +0 -0
  477. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/moderation/exceptions.py +0 -0
  478. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/moderation/models.py +0 -0
  479. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/moderation/outbox_repository.py +0 -0
  480. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/moderation/outbox_service.py +0 -0
  481. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/moderation/outcomes.py +0 -0
  482. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/moderation/repository.py +0 -0
  483. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/moderation/service.py +0 -0
  484. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/notification/__init__.py +0 -0
  485. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/notification/dependencies.py +0 -0
  486. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/notification/enums.py +0 -0
  487. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/notification/exceptions.py +0 -0
  488. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/notification/models.py +0 -0
  489. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/notification/repository.py +0 -0
  490. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/notification/service.py +0 -0
  491. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/outbox/__init__.py +0 -0
  492. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/outbox/dependencies.py +0 -0
  493. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/outbox/models.py +0 -0
  494. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/outbox/ports/admin.py +0 -0
  495. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/outbox/ports/consumer.py +0 -0
  496. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/outbox/ports/producer.py +0 -0
  497. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/outbox/service.py +0 -0
  498. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/post/__init__.py +0 -0
  499. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/post/constants.py +0 -0
  500. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/post/dependencies.py +0 -0
  501. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/post/enums.py +0 -0
  502. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/post/exceptions.py +0 -0
  503. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/post/models.py +0 -0
  504. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/post/outcomes.py +0 -0
  505. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/post/repository.py +0 -0
  506. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/post/service.py +0 -0
  507. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/user/__init__.py +0 -0
  508. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/user/constants.py +0 -0
  509. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/user/dependencies.py +0 -0
  510. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/user/enums.py +0 -0
  511. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/user/exceptions.py +0 -0
  512. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/user/models.py +0 -0
  513. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/user/outbox_repository.py +0 -0
  514. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/user/outbox_service.py +0 -0
  515. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/user/outcomes.py +0 -0
  516. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/user/utils.py +0 -0
  517. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/domains/utils.py +0 -0
  518. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/__init__.py +0 -0
  519. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/firebase/__init__.py +0 -0
  520. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/firebase/firebase_auth_adapter.py +0 -0
  521. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/media/__init__.py +0 -0
  522. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/media/attachment_staging_display_geometry.py +0 -0
  523. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/media/local_attachment_staging_adapter.py +0 -0
  524. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/media/local_banner_staging_adapter.py +0 -0
  525. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/media/local_staging_adapter.py +0 -0
  526. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/media/pillow_attachment_variant_encoder_adapter.py +0 -0
  527. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/media/pillow_avatar_variant_encoder_adapter.py +0 -0
  528. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/media/pillow_banner_variant_encoder_adapter.py +0 -0
  529. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/media/pillow_staging_image.py +0 -0
  530. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/media/ssh_attachment_finals_publisher_adapter.py +0 -0
  531. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/media/ssh_banner_finals_publisher_adapter.py +0 -0
  532. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/media/ssh_finals_publisher_adapter.py +0 -0
  533. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/outbox/outbox_consumer_adapter.py +0 -0
  534. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/infrastructure/outbox/outbox_producer_adapter.py +0 -0
  535. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/main.py +0 -0
  536. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/migrate_cli.py +0 -0
  537. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/testing/__init__.py +0 -0
  538. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/testing/arq.py +0 -0
  539. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/testing/config.py +0 -0
  540. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/testing/containers.py +0 -0
  541. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/testing/firebase.py +0 -0
  542. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/testing/firebase_identity_toolkit.py +0 -0
  543. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/testing/hookspecs.py +0 -0
  544. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/testing/httpx_test_client.py +0 -0
  545. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/testing/media.py +0 -0
  546. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/testing/migrations.py +0 -0
  547. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/testing/plugin.py +0 -0
  548. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/__init__.py +0 -0
  549. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/main.py +0 -0
  550. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/__init__.py +0 -0
  551. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/analytics_refresh_cron.py +0 -0
  552. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/schedule_aggregate_comment_stats.py +0 -0
  553. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/schedule_aggregate_post_stats.py +0 -0
  554. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/schedule_aggregate_user_stats.py +0 -0
  555. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/schedule_poll_outbox.py +0 -0
  556. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/schedule_prune_analytics_daily_facts.py +0 -0
  557. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/schedule_prune_post_views.py +0 -0
  558. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/schedule_purge_expired_create_idempotency_keys.py +0 -0
  559. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/schedule_refresh_analytics.py +0 -0
  560. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/schedule_sweep_stale_attachment_staging.py +0 -0
  561. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/schedule_sweep_stale_avatar_staging.py +0 -0
  562. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/schedules/schedule_sweep_stale_banner_staging.py +0 -0
  563. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/__init__.py +0 -0
  564. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/delete_attachment_finals.py +0 -0
  565. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/delete_superseded_avatar_finals.py +0 -0
  566. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/delete_superseded_banner_finals.py +0 -0
  567. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_account_deletion.py +0 -0
  568. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_admin_user_deletion.py +0 -0
  569. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_aggregate_comment_stats.py +0 -0
  570. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_aggregate_post_stats.py +0 -0
  571. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_aggregate_user_stats.py +0 -0
  572. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_attachment_asset_variants.py +0 -0
  573. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_banner_asset_variants.py +0 -0
  574. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_cache_pattern_invalidation.py +0 -0
  575. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_destructive_comment_delete.py +0 -0
  576. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_destructive_post_delete.py +0 -0
  577. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_media_asset_variants.py +0 -0
  578. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_mute_lift.py +0 -0
  579. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_outbox_row.py +0 -0
  580. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_refresh_analytics_bucket.py +0 -0
  581. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/tasks/process_user_content_deletion.py +0 -0
  582. {core_framework-2.3.1 → core_framework-2.3.3}/core_framework/worker/worker_context.py +0 -0
  583. {core_framework-2.3.1 → core_framework-2.3.3}/docker-compose.dev.yaml +0 -0
  584. {core_framework-2.3.1 → core_framework-2.3.3}/docker-compose.yml +0 -0
  585. {core_framework-2.3.1 → core_framework-2.3.3}/dockerfile +0 -0
  586. {core_framework-2.3.1 → core_framework-2.3.3}/docs/deployments/e2e-smoke-tests-design.md +0 -0
  587. {core_framework-2.3.1 → core_framework-2.3.3}/docs/deployments/examples/Caddyfile.example +0 -0
  588. {core_framework-2.3.1 → core_framework-2.3.3}/docs/deployments/examples/image-server-known-hosts.example +0 -0
  589. {core_framework-2.3.1 → core_framework-2.3.3}/docs/deployments/guides/postgres-setup.md +0 -0
  590. {core_framework-2.3.1 → core_framework-2.3.3}/docs/deployments/guides/redis-setup.md +0 -0
  591. {core_framework-2.3.1 → core_framework-2.3.3}/docs/deployments/release-playbook.md +0 -0
  592. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/comments/delete_comment.md +0 -0
  593. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/posts/post_like.md +0 -0
  594. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/posts/post_visibility.md +0 -0
  595. {core_framework-2.3.1 → core_framework-2.3.3}/docs/domains/users/profile.md +0 -0
  596. {core_framework-2.3.1 → core_framework-2.3.3}/docs/platform/database-triggers.md +0 -0
  597. {core_framework-2.3.1 → core_framework-2.3.3}/docs/platform/layers-and-boundaries.md +0 -0
  598. {core_framework-2.3.1 → core_framework-2.3.3}/firebase_config.example.json +0 -0
  599. {core_framework-2.3.1 → core_framework-2.3.3}/makefile +0 -0
  600. {core_framework-2.3.1 → core_framework-2.3.3}/tests/__init__.py +0 -0
  601. {core_framework-2.3.1 → core_framework-2.3.3}/tests/conftest.py +0 -0
  602. {core_framework-2.3.1 → core_framework-2.3.3}/tests/e2e/_auth.py +0 -0
  603. {core_framework-2.3.1 → core_framework-2.3.3}/tests/e2e/_canaries.py +0 -0
  604. {core_framework-2.3.1 → core_framework-2.3.3}/tests/e2e/_media.py +0 -0
  605. {core_framework-2.3.1 → core_framework-2.3.3}/tests/e2e/_settings.py +0 -0
  606. {core_framework-2.3.1 → core_framework-2.3.3}/tests/e2e/_upload_payloads.py +0 -0
  607. {core_framework-2.3.1 → core_framework-2.3.3}/tests/e2e/conftest.py +0 -0
  608. {core_framework-2.3.1 → core_framework-2.3.3}/tests/e2e/media/pipeline_test.py +0 -0
  609. {core_framework-2.3.1 → core_framework-2.3.3}/tests/e2e/smoke/canary_test.py +0 -0
  610. {core_framework-2.3.1 → core_framework-2.3.3}/tests/e2e/smoke/media_test.py +0 -0
  611. {core_framework-2.3.1 → core_framework-2.3.3}/tests/e2e/smoke/system_test.py +0 -0
  612. {core_framework-2.3.1 → core_framework-2.3.3}/tests/e2e/smoke/tls_host_test.py +0 -0
  613. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/__init__.py +0 -0
  614. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/_http_error_details.py +0 -0
  615. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/analytics/_helpers.py +0 -0
  616. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/__init__.py +0 -0
  617. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/_auth_helpers.py +0 -0
  618. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/_destructive_delete_helpers.py +0 -0
  619. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/_http_helpers.py +0 -0
  620. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/_outbox_helpers.py +0 -0
  621. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/_user_deletion_helpers.py +0 -0
  622. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/_user_helpers.py +0 -0
  623. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/__init__.py +0 -0
  624. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/_auth_cases.py +0 -0
  625. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/analytics/__init__.py +0 -0
  626. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/analytics/router_test.py +0 -0
  627. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/cache/__init__.py +0 -0
  628. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/cache/router_test.py +0 -0
  629. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/comments/__init__.py +0 -0
  630. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/comments/router_test.py +0 -0
  631. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/moderation/__init__.py +0 -0
  632. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/moderation/_auth_cases.py +0 -0
  633. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/moderation/router_test.py +0 -0
  634. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/outbox/__init__.py +0 -0
  635. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/outbox/router_test.py +0 -0
  636. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/posts/__init__.py +0 -0
  637. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/posts/router_test.py +0 -0
  638. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/users/__init__.py +0 -0
  639. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/admin/users/router_test.py +0 -0
  640. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/attachments/_helpers.py +0 -0
  641. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/attachments/attachment_upload_test.py +0 -0
  642. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/auth/__init__.py +0 -0
  643. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/auth/router_test.py +0 -0
  644. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/comments/__init__.py +0 -0
  645. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/comments/authenticated/__init__.py +0 -0
  646. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/comments/authenticated/comment_writes_integration_test.py +0 -0
  647. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/comments/comment_attachments_integration_test.py +0 -0
  648. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/comments/public/__init__.py +0 -0
  649. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/comments/public/router_test.py +0 -0
  650. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/create_idempotency_integration_test.py +0 -0
  651. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/media/ingest_contract_test.py +0 -0
  652. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/mentions/mentions_integration_test.py +0 -0
  653. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/notifications/__init__.py +0 -0
  654. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/notifications/router_test.py +0 -0
  655. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/posts/__init__.py +0 -0
  656. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/posts/authenticated/post_writes_integration_test.py +0 -0
  657. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/posts/comment_count_aggregation_test.py +0 -0
  658. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/posts/followers_visibility_test.py +0 -0
  659. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/posts/post_attachments_integration_test.py +0 -0
  660. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/posts/post_deletion_integration_test.py +0 -0
  661. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/posts/public/__init__.py +0 -0
  662. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/posts/public/router_test.py +0 -0
  663. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/public_read_by_id_unavailable_detail_test.py +0 -0
  664. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/system/__init__.py +0 -0
  665. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/system/router_test.py +0 -0
  666. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/users/__init__.py +0 -0
  667. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/users/authenticated/__init__.py +0 -0
  668. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/users/authenticated/avatar_upload_test.py +0 -0
  669. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/users/authenticated/banner_upload_test.py +0 -0
  670. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/users/authenticated/router_test.py +0 -0
  671. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/users/deletion_audit_integration_test.py +0 -0
  672. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/users/public/__init__.py +0 -0
  673. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/users/public/router_test.py +0 -0
  674. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/api/users/user_deletion_integration_test.py +0 -0
  675. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/__init__.py +0 -0
  676. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/_media_upload_helpers.py +0 -0
  677. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/account_deletion_test.py +0 -0
  678. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/aggregate_comment_stats_test.py +0 -0
  679. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/aggregate_post_stats_test.py +0 -0
  680. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/aggregate_user_stats_test.py +0 -0
  681. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/analytics_prune_test.py +0 -0
  682. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/analytics_refresh_test.py +0 -0
  683. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/attachment_upload_test.py +0 -0
  684. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/avatar_upload_test.py +0 -0
  685. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/banner_upload_test.py +0 -0
  686. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/conftest.py +0 -0
  687. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/create_idempotency_retention_test.py +0 -0
  688. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/moderation_outbox_test.py +0 -0
  689. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/mute_lift_test.py +0 -0
  690. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/stale_staging_sweep_test.py +0 -0
  691. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/user_outbox_test.py +0 -0
  692. {core_framework-2.3.1 → core_framework-2.3.3}/tests/integration/worker/utils_test.py +0 -0
  693. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/__init__.py +0 -0
  694. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/api/comments/authenticated/comment_request_schemas_test.py +0 -0
  695. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/api/dedupe_preserving_order_test.py +0 -0
  696. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/api/posts/authenticated/post_update_mapper_test.py +0 -0
  697. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/api/users/profile_update_mapper_test.py +0 -0
  698. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/application/comments/__init__.py +0 -0
  699. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/application/notifications/inbox_service_test.py +0 -0
  700. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/application/users/deletion_audit_test.py +0 -0
  701. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/core/bundled_alembic_test.py +0 -0
  702. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/core/migrate_cli_test.py +0 -0
  703. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/core/pagination_test.py +0 -0
  704. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/domains/__init__.py +0 -0
  705. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/domains/comment/__init__.py +0 -0
  706. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/domains/post/models_test.py +0 -0
  707. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/infrastructure/__init__.py +0 -0
  708. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/infrastructure/media/__init__.py +0 -0
  709. {core_framework-2.3.1 → core_framework-2.3.3}/tests/unit/infrastructure/media/ssh_finals_publisher_adapter_test.py +0 -0
@@ -29,3 +29,12 @@ globs:
29
29
  - Detailed behavior notes
30
30
 
31
31
  For detailed API behavior, create or update flow documentation in `docs/domains/` instead.
32
+
33
+ ## CI contract
34
+
35
+ `tests/unit/docs/api_routes_test.py` parses this file and asserts **bidirectional** parity with the core FastAPI app:
36
+
37
+ - every listed `(METHOD, path)` exists on the app with **matching path-param names**
38
+ - every app `(METHOD, path)` (GET/POST/PUT/PATCH/DELETE) is listed here
39
+
40
+ Flow docs under `docs/domains/` must not list endpoints in their `http` blocks unless those exact routes appear here. Update this index when adding or renaming routes.
@@ -39,4 +39,4 @@ Do not edit consuming host repos in the same task as core-framework work unless
39
39
 
40
40
  ## Feature implementation
41
41
 
42
- Greenfield features (DB → API → repository → service → tests): use the **implement-feature** skill — one layer per response unless the user says otherwise.
42
+ Greenfield features (DB → API → repository → service → **documentation** → tests): use the **implement-feature** skill — one layer per response unless the user says otherwise. A feature is **not done** until documentation is updated.
@@ -16,10 +16,10 @@ Platform contract: **`docs/platform/client-error-visibility.md`**. Domain import
16
16
 
17
17
  | Layer | Outward errors | HTTP |
18
18
  |-------|----------------|------|
19
- | **Application** | **`application.shared.exceptions`**, **`InvalidPageTokenError`** | Handlers map type → status + `detail` |
19
+ | **Application** | **`application.shared.exceptions`**, **`InvalidPageTokenError`** | Handlers map type → status + catalog **`detail`** |
20
+ | **API** | Pydantic; **`HTTPException`** for transport-local guards | **422** field errors; router-chosen status + **`detail`** |
20
21
  | **Domain typed** | Internal — not imported by API/application | No typed handlers |
21
22
  | **Domain `BaseXxxException`** | Handler catch-all only | **500** if leaked |
22
- | **API** | Pydantic | **422** |
23
23
 
24
24
  ## Application and domain
25
25
 
@@ -47,7 +47,7 @@ Platform contract: **`docs/platform/client-error-visibility.md`**. Domain import
47
47
 
48
48
  ## Validation order
49
49
 
50
- User-fixable input shape → API schemas (**422**). Domain backstops → **`DomainValidationError`** → generic **400**.
50
+ User-fixable input shape → API schemas (**422**) or router **`HTTPException`**. Use-case outcomes → application exceptions + handlers. Domain backstops → **`DomainValidationError`** → generic **400** (never domain text in **`detail`**).
51
51
 
52
52
  ## Logging
53
53
 
@@ -28,7 +28,7 @@ Documentation under **`docs/`** must not carry **implementation** snippets that
28
28
  ## Exceptions
29
29
 
30
30
  - **Deployment runbooks** under **`docs/deployments/`** (setup guides, deploy/release playbooks, SSH/image-server guides) may include fenced **`bash`** shell blocks. These are operator instructions for interactive server setup, not implementation that drifts from source; copy-paste commands are the practical content. This exemption does **not** extend to **`docs/deployments/*-design.md`** design docs, which follow the general rules above.
31
- - **Design docs** under **`docs/platform/`** and **`docs/library/`** (and **`docs/deployments/*-design.md`**) follow the general allow/exclude lists — DDL is allowed, DML and Python are not. Flow docs under **`docs/domains/**`** are stricter: see **`flow-documentation.mdc`** (no DDL, no JSON request bodies, fields described as text/tables).
31
+ - **Design docs** under **`docs/design/`**, **`docs/platform/`**, and **`docs/library/`** (and **`docs/deployments/*-design.md`**) follow the general allow/exclude lists — DDL is allowed, DML and Python are not. Flow docs under **`docs/domains/**`** are stricter: see **`flow-documentation.mdc`** (no DDL, no JSON request bodies, fields described as text/tables).
32
32
 
33
33
  ## Rationale
34
34
 
@@ -18,7 +18,7 @@ Follow the **implement-feature** skill: one step per response, wait for review.
18
18
  Not every domain owns persistence. A **capability-only** domain wraps a non-SQL capability (for example `auth`, which wraps Firebase Admin via `domains/auth/ports/`, `domains/auth/service.py`, and `core_framework/infrastructure/firebase/`). For those, **skip** schema config, the Alembic tree, and `ALEMBIC_DOMAINS` entirely — no `schema_<domain>` in `PostgresSchemasConfig` / `[postgres_schemas]`, no `alembic/<domain>/`, no repository. Scaffold only:
19
19
 
20
20
  - `domains/<domain>/{__init__.py, exceptions.py, models.py, ports/, service.py, dependencies.py}`
21
- - A port (`<Name>Port`) describing the capability, a facade `*Service` over it, and an adapter under `core_framework/infrastructure/<domain>/` wired in `dependencies.py` — see `docs/platform/domain-services-and-adapters.md` (Auth section) for the layout.
21
+ - A port (`<Name>Port`) describing the capability, a facade `*Service` over it, and an adapter under `core_framework/infrastructure/<domain>/` wired in `dependencies.py` — see `docs/platform/domain-services-and-adapters.md` (rules) and `docs/library/capability-wiring.md` (Auth example).
22
22
  - Export only `Base<Domain>Exception` + public models from `__init__.py`; keep the facade service in `dependencies.py`.
23
23
  - Wire `configure_<domain>_dependencies()` in `application/bootstrap.py` (no `runtime` needed when there is no Postgres handle).
24
24
 
@@ -0,0 +1,93 @@
1
+ ---
2
+ name: implement-feature
3
+ description: Step-by-step feature implementation — DB → API → repository → service/application → documentation → tests. Use when adding a new feature, endpoint, or domain behavior across layers, or when the user asks to follow the implementation workflow.
4
+ ---
5
+
6
+ # Implement Feature
7
+
8
+ Implement **one step at a time**. Stop after each step and wait for user review. Do **not** skip ahead or implement multiple layers in one response unless the user **explicitly** says "implement everything" or "do it all at once".
9
+
10
+ ## Definition of done
11
+
12
+ A feature is **not complete** until **all** documentation for the shipped behavior is updated. Code merged without matching docs is **unfinished work** — do not treat the feature as done or move on until the documentation step is accepted.
13
+
14
+ ## Before you start
15
+
16
+ - Do **not** implement repository, service, or application code when doing the API layer.
17
+ - Do **not** implement multiple layers in a single response.
18
+ - When in doubt, do **less** and wait for review.
19
+
20
+ ## 1. Database changes (if needed)
21
+
22
+ - **Only** create the Alembic migration file(s).
23
+ - **No** code changes anywhere else.
24
+ - Wait for the user to review and accept the database structure before proceeding.
25
+
26
+ ## 2. API layer (if needed)
27
+
28
+ After the user accepts database changes (or if there were none):
29
+
30
+ - **Only** implement the API layer: schemas and router.
31
+ - Follow the **fastapi** skill (`.agents/skills/fastapi/`) and **`api-layer`** / **`api-validation`** / **`error-boundary`** rules.
32
+ - **No** changes in domain, service, or application layers.
33
+ - Include request/response schemas, error handling, and HTTP-related logic.
34
+ - If the feature is not yet implemented, return 501 Not Implemented from the route.
35
+ - Wait for the user to review and accept before proceeding.
36
+
37
+ ## 3. Repository and domain model
38
+
39
+ After the user accepts the API layer (or if there was no API layer):
40
+
41
+ - Implement the **Repository** for the domain layer (Postgres only).
42
+ - Include the **domain model** if data is retrieved from the database.
43
+ - If the feature needs non-SQL I/O (filesystem, HTTP, SSH), add **ports** in the domain and **adapter implementations** under `core_framework/infrastructure/<domain>/` per `docs/platform/domain-services-and-adapters.md` — not in the repository.
44
+ - Wait for the user to review and accept before proceeding.
45
+
46
+ ## 4. Service and application layer
47
+
48
+ After the user accepts the repository (and any ports/adapters):
49
+
50
+ - Implement **domain service(s)** (persistence and any port-backed collaborators); wire in `dependencies.py`.
51
+ - Implement the **application** layer (orchestration across domains and transports — no permanent home for raw I/O libraries).
52
+ - Wire everything together (replace 501 with real logic).
53
+ - Wait for the user to review and accept before proceeding.
54
+
55
+ ## 5. Documentation (required)
56
+
57
+ After the user accepts the service and application layer:
58
+
59
+ Update **every** doc surface the feature touches. Use the **write-flow-doc** skill for new or changed HTTP behavior. Follow **`no-code-in-docs.mdc`** and **`flow-documentation.mdc`**.
60
+
61
+ | Change | Update |
62
+ | ------------------------------------------- | -------------------------------------------------------------------------------- |
63
+ | New or changed HTTP endpoint | Flow doc under `docs/domains/{domain}/`; add **`Current Implementation Status`** |
64
+ | New or changed route in the index | `docs/library/api.md` (endpoint list only — see **`api-reference-docs.mdc`**) |
65
+ | New flow or design doc file | `docs/domains/README.md` (and `docs/design/README.md` if cross-cutting) |
66
+ | New cross-cutting mechanism | `docs/design/*-design.md` |
67
+ | New or changed worker schedule or ARQ task | `docs/library/workers.md`; link from domain flow or design doc |
68
+ | Domain scope, tables, or invariants changed | `core_framework/domains/{domain}/README.md` |
69
+ | New audit trigger | `docs/platform/database-triggers.md` |
70
+ | Settings / config the host must wire | `docs/library/package-api.md` and/or **add-config** skill targets |
71
+ | Accepted policy or ADR | `docs/platform/architecture-decisions.md` when the feature locks a new decision |
72
+
73
+ **Do not** mark a feature done while any row above still applies and is missing an update.
74
+
75
+ Wait for the user to review and accept documentation before proceeding (or before declaring the feature complete when tests are skipped).
76
+
77
+ ## 6. Tests (when requested)
78
+
79
+ After documentation is accepted:
80
+
81
+ - Add or update integration tests when the user asks for tests in this task.
82
+ - If the user did not ask for tests, the feature is **done** after step 5 is accepted.
83
+
84
+ ## Flexibility
85
+
86
+ If the feature has no database change (e.g., pure logic, workers) or no API layer (e.g., background workers, internal jobs), skip the irrelevant steps and follow the remaining order. **Documentation (step 5) still applies** whenever behavior ships.
87
+
88
+ ## Checklist (verify before every response)
89
+
90
+ - [ ] Did I implement only one step?
91
+ - [ ] Did I stop and wait for review?
92
+ - [ ] Did I skip ahead to other layers? (If yes, roll back and redo.)
93
+ - [ ] If this step finishes the feature: is **all** required documentation updated? (If no, the feature is **not** done.)
@@ -12,7 +12,7 @@ Consuming applications embed **core-framework** as a dependency.
12
12
  When changing **core-framework** code, migrations, tests, or **`docs/`**:
13
13
 
14
14
  - **Do not** edit host repos in the same task.
15
- - **Do not** port **`docs/platform/`**, **`docs/deployments/`**, **`.cursor/rules/`**, or **`.cursor/skills/`** to hosts proactively.
15
+ - **Do not** port **`docs/platform/`**, **`docs/design/`**, **`docs/deployments/`**, **`.cursor/rules/`**, or **`.cursor/skills/`** to hosts proactively.
16
16
  - Mention that host sync is **deferred until the host bumps its core-framework version** (unless the user asked otherwise).
17
17
 
18
18
  ## When host changes are allowed
@@ -35,7 +35,7 @@ Diff by **basename** against the host's **`.cursor/`** and applicable **`docs/`*
35
35
 
36
36
  **Core `docs/` must stay host-agnostic** — no references to specific consuming applications.
37
37
 
38
- | Core path | Host behavior |
39
- | --------------------------------------------- | ------------------------------------------------------------- |
40
- | **`docs/platform/`**, **`docs/deployments/`** | Sync on dependency upgrade or explicit sync request |
41
- | **`docs/domains/`**, **`docs/library/`** | Canonical in core only — do not mirror product trees to hosts |
38
+ | Core path | Host behavior |
39
+ | ----------------------------------------------------------------- | ------------------------------------------------------------- |
40
+ | **`docs/platform/`**, **`docs/design/`**, **`docs/deployments/`** | Sync on dependency upgrade or explicit sync request |
41
+ | **`docs/domains/`**, **`docs/library/`** | Canonical in core only — do not mirror product trees to hosts |
@@ -74,5 +74,6 @@ Concise, active voice, present tense, client perspective. Horizontal rules betwe
74
74
 
75
75
  - [ ] Endpoint list at top; each endpoint has Goal, Preconditions, Flow, Errors
76
76
  - [ ] No implementation identifiers or code snippets
77
- - [ ] Links to **`docs/platform/architecture-decisions.md`** when referencing design choices
77
+ - [ ] Links to **`docs/platform/architecture-decisions.md`** when referencing accepted policy or ADR decisions
78
+ - [ ] Links to **`docs/design/`** when referencing cross-cutting mechanisms (outbox, events ingest, idempotency, analytics rollup, etc.)
78
79
  ```
@@ -4,6 +4,52 @@ Notable changes to **core-framework** (import **`core_framework`**). Format foll
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [2.3.3] - 2026-07-05
8
+
9
+ ### Added
10
+
11
+ - **UTM capture `kind`:** `POST /events` with `type: "utm_data"` requires a `kind`
12
+ item in `events[]` (`subject_type` `kind`, `subject` the capture context). Core
13
+ ships `registration`; hosts register additional kinds via
14
+ `register_utm_capture_kind`. See **`docs/design/utm-events-design.md`** and
15
+ **`docs/domains/events/events.md`**.
16
+
17
+ ### Changed
18
+
19
+ - **`analytics` schema:** **`2d61a5e88d76_analytics_utm_events_add_kind`** — `utm_events.kind`
20
+ column and `idx_utm_events_kind_created_at`. **Deletes all existing `utm_events` rows**
21
+ before adding the column (legacy UTM-only rows are not backfilled). Run **`cf-alembic`**
22
+ when upgrading.
23
+
24
+ ### Breaking
25
+
26
+ - **Breaking (clients — `utm_data`):** Batches without a valid `kind` item and at
27
+ least one allowlisted UTM key no longer persist. UTM-only payloads from 2.3.2
28
+ stop writing rows.
29
+
30
+ - **Breaking (operators — `utm_events` data):** Upgrading through
31
+ **`2d61a5e88d76_analytics_utm_events_add_kind`** clears **`analytics.utm_events`**
32
+ before the **`kind`** column is added.
33
+
34
+ ## [2.3.2] - 2026-07-05
35
+
36
+ ### Added
37
+
38
+ - **UTM attribution ingest:** `POST /events` with `type: "utm_data"` records `analytics.utm_events` (`utm` and `request_context` jsonb; optional `user_id`). UTM keys are sent as `events[]` items (`subject_type` = field name, `subject` = value). See **`docs/domains/events/events.md`** and **`docs/design/utm-events-design.md`**.
39
+ - **Signup telemetry:** `POST /events` with `type: "signup"` records `user_signup_events` (one row per user, `request_context` jsonb) after `POST /auth/register`. See **`docs/domains/events/events.md`**.
40
+ - **Request context parsing:** `application/shared/request_context.py` normalizes `User-Agent`, `client-referrer` (`referrer_url`, `referrer_host`), and `Cf-Ipcountry` for events ingest.
41
+
42
+ ### Breaking
43
+
44
+ - **Breaking (clients — events ingest):** Traffic source for request context uses the **`client-referrer`** header instead of browser **`Referer`**. Clients should send an explicit referrer URL (for example captured from `document.referrer` on first load).
45
+ - **Breaking (clients — events ingest):** Rename event type **`view`** → **`impression`** on `POST /events`. Clients and hosts must send `type: "impression"` for subject-impression batches (post views, calculator opens, etc.). Core enum: **`EventType.IMPRESSION`** (replaces **`EventType.VIEW`**). Host handlers registered on `"view"` must re-register on **`"impression"`** (for example Henry calculator view ingest).
46
+ - **Breaking (hosts — imports):** Rename **`EVENT_TOKEN_MAX_AGE_VIEW_SECONDS`** → **`EVENT_TOKEN_MAX_AGE_SECONDS`** in **`core_framework.application.events.event_token`** (behavior unchanged; token max-age remains 600s for all event types).
47
+
48
+ ### Migration
49
+
50
+ - **`analytics` schema:** **`585105e1149e_analytics_add_utm_events`** — `utm_events` table. Run **`cf-alembic`** when upgrading.
51
+ - **`user` schema:** **`44df70a45ba6_user_add_signup_events`** — `user_signup_events` table (`user_id` unique, `request_context` jsonb). Run **`cf-alembic`** when upgrading.
52
+
7
53
  ## [2.3.1] - 2026-07-03
8
54
 
9
55
  ### Added
@@ -23,7 +69,7 @@ Analytics rollup domain (materialized daily activity counts), admin read API, an
23
69
 
24
70
  ### Added
25
71
 
26
- - **Analytics rollup (Phase 1):** `analytics` domain scaffold, `schema_analytics`, `[analytics].refresh_interval_seconds` (required on **`Settings`**; core **`config.toml`** ships **300**), Alembic tree with `daily_fact` table (PK only), and activity source registry shell. See **`docs/platform/analytics-rollup-design.md`**.
72
+ - **Analytics rollup (Phase 1):** `analytics` domain scaffold, `schema_analytics`, `[analytics].refresh_interval_seconds` (required on **`Settings`**; core **`config.toml`** ships **300**), Alembic tree with `daily_fact` table (PK only), and activity source registry shell. See **`docs/design/analytics-rollup-design.md`**.
27
73
  - **Analytics rollup (Phase 2):** `AnalyticsService.list_refreshable_days` and `is_final_bucket_refresh` (planner inputs), `refresh_daily_fact_bucket` (single-bucket executor), optional `refresh_all_open_buckets` for tests; transactional `replace_daily_fact_bucket`; admin read helpers.
28
74
  - **Analytics rollup (Phase 3):** `post` / `created` activity source, planner (`enqueue_refresh_analytics_buckets`) and executor (`refresh_analytics_bucket`) application entrypoints, `schedule_refresh_analytics` + `process_refresh_analytics_bucket` worker (cron from `refresh_interval_seconds`).
29
75
  - **Analytics rollup (Phase 4):** `comment` / `created`, `user` / `registered`, and `post` / `viewed` activity sources with domain UTC-day count accessors and registry registration.
@@ -43,7 +89,7 @@ Transactional outbox (block, follow, restriction), post views retention, and inc
43
89
  ### Added
44
90
 
45
91
  - **Post views retention:** Incremental **`view_count`** aggregation via **`post_stats.view_count_aggregated_up_to`** (high-water mark on **`post_views.created_at`**); daily worker **`schedule_prune_post_views`** (05:00 UTC) deletes aggregated rows older than **`retention.post_views_retention_days`** (default **90**). See **`docs/domains/posts/post_stats_aggregation.md`**.
46
- - **Transactional outbox (block pilot):** `user.event_outbox`, worker poller/handler for **`user.block.relationship_changed`**, durable post/comment/notification block mirror fanout. See **`docs/platform/event-outbox-design.md`**.
92
+ - **Transactional outbox (block pilot):** `user.event_outbox`, worker poller/handler for **`user.block.relationship_changed`**, durable post/comment/notification block mirror fanout. See **`docs/design/event-outbox-design.md`**.
47
93
  - **Transactional outbox (follow, Phase 2):** **`user.follow.relationship_changed`** enqueued with truth changes; worker reconciles **`post.user_followers_lookup`** (outbox-only mirror path, matching block). Non-retryable handler errors dead-letter immediately (decision **#22**).
48
94
  - **Transactional outbox (restriction, Phase 3):** **`moderation.restriction.relationship_changed`** enqueued on truth changes and no-op healing; worker reconciles post/comment/user/notification restriction lookup mirrors (outbox-only, matching block/follow). Poller E2E in **`tests/integration/worker/moderation_outbox_test.py`**. Run **`cf-alembic`** for **`moderation_add_event_outbox`**.
49
95
 
@@ -88,7 +134,7 @@ First production-ready **2.x** release. Hosts must run **`cf-alembic`**, configu
88
134
 
89
135
  - **Post and comment image attachments (v1):** **`POST /attachments`** compose-time ingest; worker encodes and publishes **`thumb`** / **`display`** WebP finals; **`attachment_ids`** on post/comment create and **`PATCH`** diff edit — attach is **best-effort per added asset** on create **and** edit (failing assets are skipped and burned; the post/comment write still succeeds and mention notifications proceed; malformed sets — duplicates or over-cap — fail request validation with **`422`**, with the same guards re-checked in the post/comment domain services); public and admin read **`attachments`** wrapper on post/comment responses; staging housekeeping sweeps; admin hard delete and account removal enqueue attachment finals cleanup. Tables **`post_image_attachments`**, **`comment_image_attachments`**, **`attachment_staging_registry`**. Config **`[attachment]`** and deploy vars **`ATTACHMENT_*`**. See **`docs/domains/media/post-comment-attachments-design.md`**.
90
136
 
91
- - **HTTP create idempotency (v1):** Optional **`Idempotency-Key`** on **`POST /posts`**, **`POST /comments`**, and **`POST /comments/{comment_id}/replies`**. At most one committed row per **`(author_id, key, operation)`**; replays return **`201`** with empty body and skip mention notifications, attachment attach, and stats-dirty side effects. See **`docs/platform/create-idempotency-design.md`**.
137
+ - **HTTP create idempotency (v1):** Optional **`Idempotency-Key`** on **`POST /posts`**, **`POST /comments`**, and **`POST /comments/{comment_id}/replies`**. At most one committed row per **`(author_id, key, operation)`**; replays return **`201`** with empty body and skip mention notifications, attachment attach, and stats-dirty side effects. See **`docs/design/create-idempotency-design.md`**.
92
138
 
93
139
  - **Request profiling (opt-in):** **`PROFILING_ENABLED`** and **`PROFILING_KEY`** — pyinstrument middleware gated by **`Profiling-Key`** header.
94
140
 
@@ -149,7 +195,7 @@ Run **`uv run cf-alembic`** (or host **`cf-alembic`**) before deploying **2.0.0*
149
195
 
150
196
  ### Documentation
151
197
 
152
- - **`docs/platform/client-error-visibility.md`**, **`docs/platform/create-idempotency-design.md`**, **`docs/deployments/edge-upload-limits.md`**, **`docs/deployments/deploy-playbook.md`**, deletion refactor docs under **`docs/domains/deletion/`**.
198
+ - **`docs/platform/client-error-visibility.md`**, **`docs/design/create-idempotency-design.md`**, **`docs/deployments/edge-upload-limits.md`**, **`docs/deployments/deploy-playbook.md`**, deletion refactor docs under **`docs/domains/deletion/`**.
153
199
 
154
200
  ## [1.8.1] - 2026-06-07
155
201
 
@@ -413,4 +459,8 @@ First **SemVer-stable** release per **`docs/library/package-api.md`**.
413
459
  [2.0.0]: https://github.com/NepNepFFXIV/core-framework/compare/v1.8.1...v2.0.0
414
460
  [2.1.0]: https://github.com/NepNepFFXIV/core-framework/compare/v2.0.0...v2.1.0
415
461
  [2.2.0]: https://github.com/NepNepFFXIV/core-framework/compare/v2.1.0...v2.2.0
416
- [unreleased]: https://github.com/NepNepFFXIV/core-framework/compare/v2.2.0...HEAD
462
+ [2.3.0]: https://github.com/NepNepFFXIV/core-framework/compare/v2.2.0...v2.3.0
463
+ [2.3.1]: https://github.com/NepNepFFXIV/core-framework/compare/v2.3.0...v2.3.1
464
+ [2.3.2]: https://github.com/NepNepFFXIV/core-framework/compare/v2.3.1...v2.3.2
465
+ [2.3.3]: https://github.com/NepNepFFXIV/core-framework/compare/v2.3.2...v2.3.3
466
+ [unreleased]: https://github.com/NepNepFFXIV/core-framework/compare/v2.3.3...HEAD
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: core-framework
3
- Version: 2.3.1
3
+ Version: 2.3.3
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
@@ -10,7 +10,6 @@ Requires-Python: >=3.14
10
10
  Requires-Dist: aiofiles>=25.1.0
11
11
  Requires-Dist: alembic>=1.18.4
12
12
  Requires-Dist: arq>=0.28.0
13
- Requires-Dist: async-lru>=2.1.0
14
13
  Requires-Dist: asyncer>=0.0.14
15
14
  Requires-Dist: asyncpg>=0.31.0
16
15
  Requires-Dist: asyncssh>=2.23.0
@@ -62,6 +61,8 @@ make run
62
61
 
63
62
  For **`make test`**, use the Firebase CLI (Auth emulator). Stop DB/Redis: **`docker compose -f docker-compose.dev.yaml down`**.
64
63
 
64
+ **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
+
65
66
  ## Hosts
66
67
 
67
68
  In your host app, load **`Settings`** or a **`Settings`** subclass from **`core_framework.core.settings`**, pass it to **`init_app`** from **`core_framework.main`**, then wire host-specific dependencies, exception handlers, and routers.
@@ -23,6 +23,8 @@ make run
23
23
 
24
24
  For **`make test`**, use the Firebase CLI (Auth emulator). Stop DB/Redis: **`docker compose -f docker-compose.dev.yaml down`**.
25
25
 
26
+ **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
+
26
28
  ## Hosts
27
29
 
28
30
  In your host app, load **`Settings`** or a **`Settings`** subclass from **`core_framework.core.settings`**, pass it to **`init_app`** from **`core_framework.main`**, then wire host-specific dependencies, exception handlers, and routers.
@@ -0,0 +1,36 @@
1
+ """analytics utm_events add capture kind column
2
+
3
+ Revision ID: 2d61a5e88d76
4
+ Revises: 585105e1149e
5
+ Create Date: 2026-07-05 13:30:00.000000
6
+
7
+ """
8
+
9
+ from collections.abc import Sequence
10
+
11
+ from alembic import op
12
+
13
+ revision: str = "2d61a5e88d76"
14
+ down_revision: str | Sequence[str] | None = "585105e1149e"
15
+ branch_labels: str | Sequence[str] | None = None
16
+ depends_on: str | Sequence[str] | None = None
17
+
18
+
19
+ def upgrade() -> None:
20
+ op.execute("delete from utm_events;")
21
+ op.execute("""
22
+ alter table utm_events
23
+ add column kind varchar(64) not null;
24
+ """)
25
+ op.execute("""
26
+ create index if not exists idx_utm_events_kind_created_at
27
+ on utm_events (kind, created_at);
28
+ """)
29
+
30
+
31
+ def downgrade() -> None:
32
+ op.execute("drop index if exists idx_utm_events_kind_created_at;")
33
+ op.execute("""
34
+ alter table utm_events
35
+ drop column if exists kind;
36
+ """)
@@ -0,0 +1,38 @@
1
+ """analytics utm_events for client UTM attribution ingest
2
+
3
+ Revision ID: 585105e1149e
4
+ Revises: 7f2a9c1d4e8b
5
+ Create Date: 2026-07-05 12:00:00.000000
6
+
7
+ """
8
+
9
+ from collections.abc import Sequence
10
+
11
+ from alembic import op
12
+
13
+ revision: str = "585105e1149e"
14
+ down_revision: str | Sequence[str] | None = "7f2a9c1d4e8b"
15
+ branch_labels: str | Sequence[str] | None = None
16
+ depends_on: str | Sequence[str] | None = None
17
+
18
+
19
+ def upgrade() -> None:
20
+ op.execute("""
21
+ create table utm_events (
22
+ id bigint generated always as identity primary key,
23
+ created_at timestamptz not null default now(),
24
+ token varchar(256) not null,
25
+ user_id varchar(128),
26
+ utm jsonb not null default '{}'::jsonb,
27
+ request_context jsonb not null default '{}'::jsonb
28
+ );
29
+ """)
30
+ op.execute("""
31
+ create index if not exists idx_utm_events_created_at
32
+ on utm_events (created_at);
33
+ """)
34
+
35
+
36
+ def downgrade() -> None:
37
+ op.execute("drop index if exists idx_utm_events_created_at;")
38
+ op.execute("drop table if exists utm_events;")
@@ -0,0 +1,32 @@
1
+ """add user_signup_events for registration telemetry
2
+
3
+ Revision ID: 44df70a45ba6
4
+ Revises: 9d9611e47ce2
5
+ Create Date: 2026-07-04 12:00:00.000000
6
+
7
+ """
8
+
9
+ from collections.abc import Sequence
10
+
11
+ from alembic import op
12
+
13
+ revision: str = "44df70a45ba6"
14
+ down_revision: str | Sequence[str] | None = "9d9611e47ce2"
15
+ branch_labels: str | Sequence[str] | None = None
16
+ depends_on: str | Sequence[str] | None = None
17
+
18
+
19
+ def upgrade() -> None:
20
+ op.execute("""
21
+ create table user_signup_events (
22
+ id bigint generated always as identity primary key,
23
+ user_id varchar(128) not null references users(user_id) on delete cascade,
24
+ created_at timestamptz not null default now(),
25
+ request_context jsonb not null default '{}'::jsonb,
26
+ constraint user_signup_events_user_id_unique unique (user_id)
27
+ );
28
+ """)
29
+
30
+
31
+ def downgrade() -> None:
32
+ op.execute("drop table if exists user_signup_events")
@@ -80,6 +80,7 @@ allowed_headers = [
80
80
  "Content-Type",
81
81
  "Idempotency-Key",
82
82
  "Profiling-Key",
83
+ "Client-Referrer",
83
84
  ]
84
85
 
85
86
  [http_client]
@@ -64,6 +64,7 @@ allowed_headers = [
64
64
  "Content-Type",
65
65
  "Idempotency-Key",
66
66
  "Profiling-Key",
67
+ "Client-Referrer",
67
68
  ]
68
69
 
69
70
  [http_client]
@@ -1,18 +1,7 @@
1
- from typing import Annotated
2
-
3
- from pydantic import BaseModel, EmailStr, Field
1
+ from pydantic import BaseModel, EmailStr
4
2
 
5
3
  from core_framework.api.users.shared.schemas import UserID, Username
6
4
 
7
- CountryCode = Annotated[
8
- str,
9
- Field(
10
- description="ISO 3166-1 alpha-2 country code",
11
- pattern="^[A-Z]{2}$",
12
- examples=["US", "GB"],
13
- ),
14
- ]
15
-
16
5
 
17
6
  class CreatedUserResponse(BaseModel):
18
7
  user_id: UserID
@@ -1,17 +1,20 @@
1
1
  from typing import Annotated
2
2
 
3
- from async_lru import alru_cache
4
3
  from fastapi import Depends, Header, Query, Security
5
4
  from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
6
5
  from pydantic import ValidationError
7
6
 
8
7
  import core_framework.domains.auth.dependencies as auth_deps
9
- from core_framework.api.auth.schemas import CountryCode, FirebaseUser
8
+ from core_framework.api.auth.schemas import FirebaseUser
10
9
  from core_framework.api.users.shared.schemas import UserID, parse_user_id
11
10
  from core_framework.application.auth.access_service import get_user_detail
12
11
  from core_framework.application.auth.models import UserDetail
13
12
  from core_framework.application.shared.exceptions import BadRequestException, ForbiddenException, UnauthorizedException
14
- from core_framework.application.shared.user_agent import parse_user_agent
13
+ from core_framework.application.shared.request_context import (
14
+ parse_cf_ipcountry,
15
+ parse_client_referrer,
16
+ parse_user_agent,
17
+ )
15
18
  from core_framework.application.users.admin_service import retrieve_admin_user_ids
16
19
  from core_framework.core.context import user_id
17
20
  from core_framework.domains.auth import VerifiedTokenClaims
@@ -21,11 +24,6 @@ from core_framework.domains.user import UserIdentity
21
24
  bearer_scheme = HTTPBearer(auto_error=False)
22
25
 
23
26
 
24
- @alru_cache(maxsize=5000, ttl=300) # ~10MB per worker, 5 minutes TTL
25
- async def _verify_id_token(token: str) -> VerifiedTokenClaims | None:
26
- return await auth_deps.auth_service.verify_id_token(token=token)
27
-
28
-
29
27
  def _build_firebase_user_from_claims(claims: VerifiedTokenClaims) -> FirebaseUser | None:
30
28
  try:
31
29
  return FirebaseUser(
@@ -54,7 +52,7 @@ async def _get_firebase_user(token: Annotated[str | None, Depends(_get_bearer_to
54
52
  if not token:
55
53
  return None
56
54
 
57
- claims = await _verify_id_token(token)
55
+ claims = await auth_deps.auth_service.verify_id_token(token=token)
58
56
  if claims is None:
59
57
  return None
60
58
 
@@ -106,18 +104,18 @@ async def check_not_banned(user_detail: Annotated[UserDetail, Depends(_get_user_
106
104
  async def _get_request_context(
107
105
  firebase_user: Annotated[FirebaseUser | None, Depends(_get_firebase_user)],
108
106
  user_agent: Annotated[str | None, Header()] = None,
109
- cf_ipcountry: Annotated[CountryCode | None, Header()] = None,
107
+ cf_ipcountry: Annotated[str | None, Header()] = None,
108
+ client_referrer: Annotated[str | None, Header()] = None,
110
109
  ) -> dict[str, str]:
111
110
  metadata: dict[str, str] = {}
112
111
 
113
112
  if firebase_user:
114
113
  metadata["viewer_id"] = firebase_user.user_id
115
114
  metadata["provider"] = firebase_user.sign_in_provider
116
- if cf_ipcountry:
117
- metadata["country_code"] = cf_ipcountry
118
115
 
119
- client_info = parse_user_agent(user_agent=user_agent)
120
- metadata.update(client_info)
116
+ metadata.update(parse_cf_ipcountry(cf_ipcountry=cf_ipcountry))
117
+ metadata.update(parse_client_referrer(client_referrer=client_referrer))
118
+ metadata.update(parse_user_agent(user_agent=user_agent))
121
119
 
122
120
  return {k: v for k, v in metadata.items() if v is not None}
123
121
 
@@ -9,8 +9,9 @@ from core_framework.core import CacheKey
9
9
  from core_framework.domains.user import UserIdentity
10
10
 
11
11
 
12
- @cache.cache(
12
+ @cache.early(
13
13
  ttl=lambda *_args, **_kwargs: CacheKey.USER_DETAIL.ttl_seconds,
14
+ early_ttl=lambda *_args, **_kwargs: CacheKey.USER_DETAIL.early_ttl_seconds,
14
15
  key=CacheKey.USER_DETAIL.key_template,
15
16
  condition=lambda result, args, kwargs, key=None: result.identity != UserIdentity.DEFAULT,
16
17
  )
@@ -2,6 +2,7 @@ import core_framework.domains.moderation.dependencies as moderation_deps
2
2
  import core_framework.domains.user.dependencies as user_deps
3
3
  from core_framework.application.analytics.registry import configure_activity_sources
4
4
  from core_framework.application.events.event_service import configure_event_handlers
5
+ from core_framework.application.events.utm_capture_kinds import configure_utm_capture_kinds
5
6
  from core_framework.application.shared.worker_jobs import configure_worker_jobs
6
7
  from core_framework.core.cache import configure_cashews_backend
7
8
  from core_framework.core.runtime import CoreRuntime
@@ -19,6 +20,7 @@ from core_framework.domains.user.dependencies import configure_user_dependencies
19
20
  def configure_application_dependencies(*, runtime: CoreRuntime) -> None:
20
21
  """Wire application-level dependencies from the shared runtime."""
21
22
  configure_event_handlers()
23
+ configure_utm_capture_kinds()
22
24
  configure_activity_sources()
23
25
  configure_worker_jobs(runtime=runtime)
24
26
  configure_cashews_backend(redis_cache_url=runtime.settings.redis.redis_cache_url)
@@ -39,8 +41,3 @@ def configure_application_dependencies(*, runtime: CoreRuntime) -> None:
39
41
  runtime.settings.postgres_schemas.schema_moderation: moderation_deps.moderation_outbox_service,
40
42
  }
41
43
  )
42
-
43
- # alru_cache on user id set must not survive a rebound UserService instance
44
- import core_framework.application.users.admin_service as admin_service
45
-
46
- admin_service.retrieve_admin_user_ids.cache_clear()
@@ -0,0 +1,31 @@
1
+ # Events Application Layer
2
+
3
+ Client-initiated, eventually consistent side effects: token verification, handler
4
+ registry, and built-in handlers.
5
+
6
+ ## Role
7
+
8
+ `POST /events` dispatches batched client work to registered handlers. Handlers are
9
+ **loss-tolerant** (errors logged, not raised to the client).
10
+
11
+ **Canonical core event catalog** (shipped and planned `type` values, auth, dedup,
12
+ side effects): `docs/domains/events/events.md` → **Core event catalog**.
13
+
14
+ Platform design and host extension: `docs/design/events-ingest-design.md`.
15
+
16
+ ## Host extension
17
+
18
+ - `register_event_handler(event_type, handler)` — append a handler after `configure_application_dependencies`
19
+ - `register_utm_capture_kind(kind)` — append a `utm_data` capture kind after `configure_application_dependencies`
20
+ - `configure_event_handlers()` — reset handler registry and register core built-ins
21
+ - `configure_utm_capture_kinds()` — reset capture-kind registry and seed core kinds (`registration`)
22
+ - `type` and `subject_type` are plain strings at the schema boundary
23
+ - Each handler receives the full batch and filters its own `subject_type` values
24
+
25
+ ## Flow
26
+
27
+ 1. Client obtains a token via `GET /events/token`
28
+ 1. Client posts via `POST /events` with `type`, `token`, and `events`
29
+ 1. Invalid token → early return (HTTP still 202)
30
+ 1. Registered handlers for `type` are queued on FastAPI `BackgroundTasks` and run **sequentially** after the response
31
+ 1. Unknown `type` → warning log, no handler run