core-framework 2.0.0__tar.gz → 2.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- core_framework-2.1.0/.agents/skills/fastapi +1 -0
- core_framework-2.1.0/.agents/skills/library-skills/.library-skills.json +4 -0
- core_framework-2.1.0/.agents/skills/library-skills/SKILL.md +37 -0
- core_framework-2.1.0/.cursor/rules/api-layer.mdc +36 -0
- core_framework-2.1.0/.cursor/rules/api-validation.mdc +22 -0
- core_framework-2.1.0/.cursor/rules/application-layer.mdc +29 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/rules/constants-final.mdc +1 -1
- core_framework-2.1.0/.cursor/rules/constitution.mdc +36 -0
- core_framework-2.1.0/.cursor/rules/database-triggers.mdc +23 -0
- core_framework-2.1.0/.cursor/rules/docstrings.mdc +29 -0
- core_framework-2.1.0/.cursor/rules/domain-imports.mdc +44 -0
- core_framework-2.1.0/.cursor/rules/domain-input-guards.mdc +32 -0
- core_framework-2.1.0/.cursor/rules/error-boundary.mdc +55 -0
- core_framework-2.1.0/.cursor/rules/flow-documentation.mdc +15 -0
- core_framework-2.1.0/.cursor/rules/layer-boundaries.mdc +24 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/rules/no-code-in-docs.mdc +7 -2
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/rules/postgres-config-conventions.mdc +7 -1
- core_framework-2.1.0/.cursor/rules/strong-reads.mdc +37 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/rules/structured-logging.mdc +3 -1
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/skills/add-domain/SKILL.md +15 -4
- core_framework-2.1.0/.cursor/skills/code-review/SKILL.md +34 -0
- core_framework-2.1.0/.cursor/skills/fastapi +1 -0
- core_framework-2.0.0/.cursor/rules/implementation-workflow.mdc → core_framework-2.1.0/.cursor/skills/implement-feature/SKILL.md +15 -17
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/skills/recommend-features/SKILL.md +5 -5
- core_framework-2.1.0/.cursor/skills/sync-host-rules/SKILL.md +41 -0
- core_framework-2.1.0/.cursor/skills/write-flow-doc/SKILL.md +78 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.github/workflows/dev-ci-cd.yaml +37 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.github/workflows/test.yaml +1 -1
- {core_framework-2.0.0 → core_framework-2.1.0}/.pre-commit-config.yaml +2 -2
- {core_framework-2.0.0 → core_framework-2.1.0}/CHANGELOG.md +15 -1
- {core_framework-2.0.0 → core_framework-2.1.0}/PKG-INFO +5 -5
- core_framework-2.1.0/alembic/comment/alembic/versions/comment_add_comment_create_idempotency_created_at_index.py +27 -0
- core_framework-2.1.0/alembic/post/alembic/versions/post_add_post_create_idempotency_created_at_index.py +27 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/config.toml +6 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/cache/router.py +2 -2
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/cache/schemas.py +3 -3
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/comments/router.py +2 -2
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/moderation/router.py +19 -19
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/moderation/schemas.py +33 -40
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/posts/router.py +2 -2
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/users/router.py +17 -17
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/users/schemas.py +44 -53
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/attachments/router.py +1 -1
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/attachments/schemas.py +12 -15
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/auth/router.py +1 -1
- core_framework-2.1.0/core_framework/api/auth/schemas.py +26 -0
- core_framework-2.1.0/core_framework/api/comments/authenticated/mappers.py +17 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/comments/authenticated/router.py +15 -13
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/comments/authenticated/schemas.py +4 -4
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/comments/public/router.py +5 -5
- core_framework-2.1.0/core_framework/api/comments/schemas.py +19 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/dependencies.py +21 -46
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/notifications/authenticated/router.py +4 -4
- core_framework-2.1.0/core_framework/api/posts/authenticated/mappers.py +19 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/posts/authenticated/router.py +13 -12
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/posts/authenticated/schemas.py +5 -5
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/posts/public/router.py +6 -6
- core_framework-2.1.0/core_framework/api/posts/schemas.py +35 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/schemas.py +2 -4
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/users/authenticated/mappers.py +1 -3
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/users/authenticated/router.py +42 -41
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/users/authenticated/schemas.py +1 -1
- core_framework-2.1.0/core_framework/api/users/mappers.py +16 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/users/public/router.py +5 -12
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/users/shared/schemas.py +99 -88
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/auth/access_service.py +1 -6
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/bootstrap.py +2 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/cache/invalidate_service.py +1 -6
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/comments/admin_service.py +8 -15
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/comments/aggregation_service.py +1 -5
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/comments/authenticated_service.py +23 -7
- core_framework-2.1.0/core_framework/application/comments/cleanup_service.py +109 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/comments/public_service.py +5 -33
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/events/event_service.py +2 -13
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/media/attachment_service.py +11 -10
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/media/avatar_service.py +4 -31
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/moderation/moderator_service.py +1 -6
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/moderation/report_service.py +1 -7
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/moderation/scheduled_service.py +1 -5
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/moderation/user_service.py +6 -34
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/notifications/inbox_service.py +1 -7
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/notifications/notification_service.py +1 -9
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/posts/admin_service.py +12 -19
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/posts/aggregation_service.py +1 -5
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/posts/authenticated_service.py +7 -9
- core_framework-2.0.0/core_framework/application/posts/destructive_delete_cleanup.py → core_framework-2.1.0/core_framework/application/posts/cleanup_service.py +60 -15
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/posts/public_service.py +5 -33
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/users/admin_service.py +12 -34
- core_framework-2.1.0/core_framework/application/users/deletion_audit.py +12 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/users/public_service.py +1 -6
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/users/scheduled_service.py +2 -2
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/users/user_deletion_service.py +10 -16
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/cache.py +2 -2
- core_framework-2.1.0/core_framework/domains/auth/__init__.py +8 -0
- core_framework-2.1.0/core_framework/domains/auth/dependencies.py +28 -0
- core_framework-2.1.0/core_framework/domains/auth/exceptions.py +10 -0
- core_framework-2.1.0/core_framework/domains/auth/models.py +31 -0
- core_framework-2.1.0/core_framework/domains/auth/ports/auth.py +51 -0
- core_framework-2.1.0/core_framework/domains/auth/service.py +57 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/comment/README.md +4 -4
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/comment/constants.py +2 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/comment/repository.py +39 -9
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/comment/service.py +50 -29
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/moderation/repository.py +34 -123
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/moderation/service.py +12 -8
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/notification/repository.py +1 -16
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/notification/service.py +7 -3
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/post/constants.py +2 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/post/repository.py +37 -5
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/post/service.py +41 -27
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/user/repository.py +7 -4
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/user/service.py +9 -7
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/utils.py +30 -0
- core_framework-2.1.0/core_framework/infrastructure/firebase/firebase_auth_adapter.py +110 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/testing/plugin.py +4 -3
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/schedules/__init__.py +9 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/schedules/schedule_aggregate_comment_stats.py +1 -16
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/schedules/schedule_aggregate_post_stats.py +1 -16
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/schedules/schedule_aggregate_user_stats.py +1 -16
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/schedules/schedule_expired_account_deletions.py +5 -21
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/schedules/schedule_expired_mute_lifts.py +1 -15
- core_framework-2.1.0/core_framework/worker/schedules/schedule_purge_expired_create_idempotency_keys.py +23 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/schedules/schedule_sweep_stale_attachment_staging.py +1 -11
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/schedules/schedule_sweep_stale_avatar_staging.py +1 -12
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/delete_attachment_finals.py +1 -12
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/delete_superseded_avatar_finals.py +1 -12
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/process_aggregate_comment_stats.py +1 -15
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/process_aggregate_post_stats.py +1 -15
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/process_aggregate_user_stats.py +1 -15
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/process_cache_pattern_invalidation.py +14 -9
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/process_media_asset_variants.py +1 -15
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/process_mute_lift.py +1 -13
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/deployments/README.md +6 -5
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/deployments/deploy-playbook.md +20 -1
- core_framework-2.1.0/docs/deployments/e2e-smoke-tests-design.md +353 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/auth/access_control.md +1 -1
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/auth/registration.md +1 -1
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/comments/create_comment.md +10 -26
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/deletion/users.md +7 -7
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/media/banner-upload-design.md +1 -1
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/moderation/reports.md +3 -2
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/follow.md +2 -2
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/library/api.md +0 -2
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/library/core-framework-migration.md +1 -12
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/library/package-api.md +2 -23
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/library/testing-plugin-design.md +29 -100
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/platform/architecture-decisions.md +16 -38
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/platform/client-error-visibility.md +3 -4
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/platform/create-idempotency-design.md +24 -14
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/platform/domain-services-and-adapters.md +22 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/platform/event-outbox-design.md +36 -35
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/platform/layers-and-boundaries.md +3 -3
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/platform/patch-update-typed-payload.md +12 -10
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/todo.md +0 -2
- {core_framework-2.0.0 → core_framework-2.1.0}/makefile +8 -4
- {core_framework-2.0.0 → core_framework-2.1.0}/pyproject.toml +13 -7
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/conftest.py +17 -1
- core_framework-2.1.0/tests/e2e/_auth.py +54 -0
- core_framework-2.1.0/tests/e2e/_canaries.py +140 -0
- core_framework-2.1.0/tests/e2e/_media.py +84 -0
- core_framework-2.1.0/tests/e2e/_settings.py +40 -0
- core_framework-2.1.0/tests/e2e/_upload_payloads.py +18 -0
- core_framework-2.1.0/tests/e2e/conftest.py +76 -0
- core_framework-2.1.0/tests/e2e/media/pipeline_test.py +154 -0
- core_framework-2.1.0/tests/e2e/smoke/canary_test.py +36 -0
- core_framework-2.1.0/tests/e2e/smoke/media_test.py +179 -0
- core_framework-2.1.0/tests/e2e/smoke/system_test.py +32 -0
- core_framework-2.1.0/tests/e2e/smoke/tls_host_test.py +66 -0
- core_framework-2.1.0/tests/integration/api/_auth_helpers.py +12 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/_http_helpers.py +4 -4
- core_framework-2.1.0/tests/integration/api/_user_helpers.py +24 -0
- core_framework-2.1.0/tests/integration/api/admin/_auth_cases.py +42 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/admin/cache/router_test.py +24 -55
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/admin/comments/router_test.py +15 -57
- core_framework-2.1.0/tests/integration/api/admin/moderation/_auth_cases.py +30 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/admin/moderation/router_test.py +23 -61
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/admin/posts/router_test.py +16 -49
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/admin/users/router_test.py +2 -2
- core_framework-2.1.0/tests/integration/api/attachments/attachment_upload_test.py +33 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/comments/authenticated/comment_writes_integration_test.py +40 -53
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/comments/comment_attachments_integration_test.py +72 -0
- core_framework-2.1.0/tests/integration/api/media/ingest_contract_test.py +179 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/mentions/mentions_integration_test.py +46 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/notifications/router_test.py +1 -1
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/posts/authenticated/post_writes_integration_test.py +24 -41
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/posts/followers_visibility_test.py +1 -1
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/posts/public/router_test.py +0 -15
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/users/authenticated/avatar_upload_test.py +4 -92
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/users/authenticated/banner_upload_test.py +4 -92
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/users/authenticated/router_test.py +3 -3
- core_framework-2.1.0/tests/integration/api/users/deletion_audit_integration_test.py +180 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/users/public/router_test.py +1 -1
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/users/user_deletion_integration_test.py +1 -1
- core_framework-2.1.0/tests/integration/worker/_media_upload_helpers.py +77 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/worker/account_deletion_test.py +1 -21
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/worker/aggregate_user_stats_test.py +1 -1
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/worker/avatar_upload_test.py +181 -43
- core_framework-2.1.0/tests/integration/worker/banner_upload_test.py +367 -0
- core_framework-2.1.0/tests/integration/worker/create_idempotency_retention_test.py +289 -0
- core_framework-2.1.0/tests/integration/worker/stale_staging_sweep_test.py +169 -0
- core_framework-2.1.0/tests/unit/api/comments/authenticated/comment_request_schemas_test.py +60 -0
- core_framework-2.1.0/tests/unit/api/dedupe_preserving_order_test.py +12 -0
- core_framework-2.1.0/tests/unit/api/posts/authenticated/post_update_mapper_test.py +29 -0
- core_framework-2.1.0/tests/unit/api/users/profile_update_mapper_test.py +22 -0
- core_framework-2.1.0/tests/unit/application/users/deletion_audit_test.py +56 -0
- core_framework-2.1.0/tests/unit/domains/post/models_test.py +28 -0
- core_framework-2.1.0/tests/unit/infrastructure/__init__.py +0 -0
- core_framework-2.1.0/tests/unit/infrastructure/media/__init__.py +0 -0
- core_framework-2.1.0/uv.lock +2327 -0
- core_framework-2.0.0/.cursor/rules/api-layer.mdc +0 -37
- core_framework-2.0.0/.cursor/rules/api-security.mdc +0 -46
- core_framework-2.0.0/.cursor/rules/api-validation.mdc +0 -112
- core_framework-2.0.0/.cursor/rules/application-layer.mdc +0 -96
- core_framework-2.0.0/.cursor/rules/client-error-visibility.mdc +0 -75
- core_framework-2.0.0/.cursor/rules/code-review-output.mdc +0 -32
- core_framework-2.0.0/.cursor/rules/database-triggers.md +0 -184
- core_framework-2.0.0/.cursor/rules/docstrings.mdc +0 -81
- core_framework-2.0.0/.cursor/rules/domain-imports.mdc +0 -124
- core_framework-2.0.0/.cursor/rules/domain-input-guards.mdc +0 -72
- core_framework-2.0.0/.cursor/rules/exception-handlers.mdc +0 -59
- core_framework-2.0.0/.cursor/rules/flow-documentation.mdc +0 -326
- core_framework-2.0.0/.cursor/rules/henry-cursor-rules-sync.mdc +0 -51
- core_framework-2.0.0/.cursor/rules/karpathy-guidelines.mdc +0 -70
- core_framework-2.0.0/.cursor/rules/layer-boundaries.mdc +0 -39
- core_framework-2.0.0/.cursor/rules/repository-read-consistency.mdc +0 -55
- core_framework-2.0.0/.cursor/rules/strong-read-opt-in.mdc +0 -22
- core_framework-2.0.0/.cursor/rules/tech-stack.mdc +0 -14
- core_framework-2.0.0/.cursor/skills/code-review/SKILL.md +0 -122
- core_framework-2.0.0/core_framework/api/auth/schemas.py +0 -29
- core_framework-2.0.0/core_framework/api/comments/authenticated/mappers.py +0 -28
- core_framework-2.0.0/core_framework/api/comments/schemas.py +0 -18
- core_framework-2.0.0/core_framework/api/posts/authenticated/mappers.py +0 -36
- core_framework-2.0.0/core_framework/api/posts/schemas.py +0 -40
- core_framework-2.0.0/core_framework/api/users/mappers.py +0 -52
- core_framework-2.0.0/core_framework/application/comments/destructive_delete_cleanup.py +0 -66
- core_framework-2.0.0/core_framework/application/comments/tombstone_cleanup.py +0 -62
- core_framework-2.0.0/core_framework/application/posts/tombstone_cleanup.py +0 -64
- core_framework-2.0.0/tests/integration/api/attachments/attachment_upload_test.py +0 -122
- core_framework-2.0.0/tests/integration/worker/banner_upload_test.py +0 -229
- core_framework-2.0.0/uv.lock +0 -2293
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/rules/alembic-revision-ids.mdc +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/rules/api-reference-docs.mdc +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/rules/domain-caller-context.mdc +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/rules/domain-repository-exceptions.mdc +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/rules/domain-services-and-adapters.mdc +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/rules/inline-raise-messages.mdc +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/rules/integration-test-strategy.mdc +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/rules/repository-schema-isolation.mdc +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.cursor/skills/add-config/SKILL.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.dockerignore +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.github/workflows/_deploy.yml +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.github/workflows/manual-deployment.yaml +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.github/workflows/publish-pypi.yml +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.gitignore +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/.python-version +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/LICENSE +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/README.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/comment/alembic/README +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/comment/alembic/env.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/comment/alembic/script.py.mako +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/comment/alembic/versions/comment_add_comment_attachments.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/comment/alembic/versions/comment_add_comment_create_idempotency.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/comment/alembic/versions/comment_add_comment_mentions.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/comment/alembic/versions/comment_tombstone_status_model.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/comment/alembic/versions/v1_comment_init_baseline.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/comment/alembic.ini +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/extension/alembic/README +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/extension/alembic/env.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/extension/alembic/script.py.mako +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/extension/alembic/versions/v1_ext_init_baseline.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/extension/alembic.ini +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/media/alembic/README +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/media/alembic/env.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/media/alembic/script.py.mako +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/media/alembic/versions/media_add_attachment_staging_registry.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/media/alembic/versions/media_add_banner_staging_and_lease.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/media/alembic/versions/media_attachment_staging_registry_published_at.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/media/alembic/versions/v1_media_init_baseline.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/media/alembic.ini +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/moderation/alembic/README +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/moderation/alembic/env.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/moderation/alembic/script.py.mako +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/moderation/alembic/versions/v1_mod_init_baseline.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/moderation/alembic.ini +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/notification/alembic/README +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/notification/alembic/env.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/notification/alembic/script.py.mako +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/notification/alembic/versions/v1_notif_init_baseline.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/notification/alembic.ini +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/post/alembic/README +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/post/alembic/env.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/post/alembic/script.py.mako +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/post/alembic/versions/post_add_post_attachments.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/post/alembic/versions/post_add_post_create_idempotency.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/post/alembic/versions/post_add_post_mentions.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/post/alembic/versions/post_tombstone_status_model.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/post/alembic/versions/v1_post_init_baseline.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/post/alembic.ini +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/user/alembic/README +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/user/alembic/env.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/user/alembic/script.py.mako +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/user/alembic/versions/user_add_avatar_ingest_sequences.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/user/alembic/versions/user_add_banner_ingest_sequences.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/user/alembic/versions/user_add_date_of_birth_to_profiles.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/user/alembic/versions/user_reserve_sentinel_user_ids.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/user/alembic/versions/v1_user_init_baseline.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/alembic/user/alembic.ini +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/config.toml.template +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/comments/schemas.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/moderation/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/posts/schemas.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/router.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/admin/users/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/auth/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/comments/public/schemas.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/comments/router.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/constants.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/events/router.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/events/schemas.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/idempotency/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/idempotency/dependencies.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/notifications/authenticated/schemas.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/notifications/router.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/posts/public/schemas.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/posts/router.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/router.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/system/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/system/router.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/users/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/users/authenticated/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/users/public/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/users/public/schemas.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/api/users/router.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/auth/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/auth/auth_service.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/auth/models.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/cache/models.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/events/README.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/events/event_token.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/events/models.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/media/README.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/media/attachment_read.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/media/banner_service.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/media/ingest_guards.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/media/read_url_config.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/moderation/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/moderation/appeal_service.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/notifications/README.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/notifications/enums.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/notifications/mute_service.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/shared/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/shared/enums.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/shared/exceptions.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/shared/user_agent.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/shared/worker_jobs.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/users/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/users/aggregation_service.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/users/authenticated_service.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/application/users/enums.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/asgi.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/bundled_alembic.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/constants.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/context.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/database.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/exception_handlers/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/exception_handlers/application.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/exception_handlers/common.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/exception_handlers/setup.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/firebase.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/http_client.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/logging.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/middleware.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/observability.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/pagination.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/redis.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/runtime.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/core/settings.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/__init__.py +0 -0
- {core_framework-2.0.0/core_framework/domains/media/avatar → core_framework-2.1.0/core_framework/domains/auth/ports}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/comment/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/comment/dependencies.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/comment/enums.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/comment/exceptions.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/comment/models.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/comment/outcomes.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/exceptions.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/README.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/attachment/components/finals_publisher.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/attachment/components/staging.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/attachment/components/variant_encoder.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/attachment/constants.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/attachment/exceptions.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/attachment/models.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/attachment/ports/finals_publisher.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/attachment/ports/staging.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/attachment/ports/variant_encoder.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/attachment/service.py +0 -0
- {core_framework-2.0.0/core_framework/domains/media/avatar/components → core_framework-2.1.0/core_framework/domains/media/avatar}/__init__.py +0 -0
- {core_framework-2.0.0/core_framework/domains/media/avatar/ports → core_framework-2.1.0/core_framework/domains/media/avatar/components}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/avatar/components/finals_publisher.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/avatar/components/staging.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/avatar/components/variant_encoder.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/avatar/constants.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/avatar/exceptions.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/avatar/models.py +0 -0
- {core_framework-2.0.0/core_framework/domains/media/shared → core_framework-2.1.0/core_framework/domains/media/avatar/ports}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/avatar/ports/finals_publisher.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/avatar/ports/staging.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/avatar/ports/variant_encoder.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/avatar/service.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/banner/components/finals_publisher.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/banner/components/staging.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/banner/components/variant_encoder.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/banner/constants.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/banner/exceptions.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/banner/models.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/banner/ports/finals_publisher.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/banner/ports/staging.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/banner/ports/variant_encoder.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/banner/service.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/dependencies.py +0 -0
- {core_framework-2.0.0/core_framework/infrastructure → core_framework-2.1.0/core_framework/domains/media/shared}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/shared/constants.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/shared/exceptions.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/shared/outcomes.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/shared/repository.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/shared/service.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/media/shared/utils.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/moderation/README.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/moderation/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/moderation/dependencies.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/moderation/enums.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/moderation/exceptions.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/moderation/models.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/moderation/outcomes.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/notification/README.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/notification/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/notification/dependencies.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/notification/enums.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/notification/exceptions.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/notification/models.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/post/README.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/post/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/post/dependencies.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/post/enums.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/post/exceptions.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/post/models.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/post/outcomes.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/user/README.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/user/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/user/constants.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/user/dependencies.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/user/enums.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/user/exceptions.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/user/models.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/user/outcomes.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/domains/user/utils.py +0 -0
- {core_framework-2.0.0/core_framework/infrastructure/media → core_framework-2.1.0/core_framework/infrastructure}/__init__.py +0 -0
- {core_framework-2.0.0/core_framework/worker → core_framework-2.1.0/core_framework/infrastructure/firebase}/__init__.py +0 -0
- {core_framework-2.0.0/tests → core_framework-2.1.0/core_framework/infrastructure/media}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/infrastructure/media/attachment_staging_display_geometry.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/infrastructure/media/local_attachment_staging_adapter.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/infrastructure/media/local_banner_staging_adapter.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/infrastructure/media/local_staging_adapter.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/infrastructure/media/pillow_attachment_variant_encoder_adapter.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/infrastructure/media/pillow_avatar_variant_encoder_adapter.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/infrastructure/media/pillow_banner_variant_encoder_adapter.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/infrastructure/media/pillow_staging_image.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/infrastructure/media/ssh_attachment_finals_publisher_adapter.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/infrastructure/media/ssh_banner_finals_publisher_adapter.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/infrastructure/media/ssh_finals_publisher_adapter.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/main.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/migrate_cli.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/testing/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/testing/arq.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/testing/auth.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/testing/config.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/testing/containers.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/testing/firebase.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/testing/hookspecs.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/testing/httpx_test_client.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/testing/media.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/testing/migrations.py +0 -0
- {core_framework-2.0.0/tests/integration → core_framework-2.1.0/core_framework/worker}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/main.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/schedules/schedule_sweep_stale_banner_staging.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/delete_superseded_banner_finals.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/process_account_deletion.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/process_admin_user_deletion.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/process_attachment_asset_variants.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/process_banner_asset_variants.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/process_destructive_comment_delete.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/process_destructive_post_delete.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/tasks/process_user_content_deletion.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/core_framework/worker/worker_context.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docker-compose.dev.yaml +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docker-compose.yml +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/dockerfile +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/README.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/deployments/edge-upload-limits.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/deployments/examples/Caddyfile.example +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/deployments/examples/image-server-known-hosts.example +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/deployments/guides/app-server-deploy-ssh.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/deployments/guides/image-server-ssh.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/deployments/guides/postgres-setup.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/deployments/guides/redis-setup.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/deployments/guides/ubuntu-server-setup.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/deployments/release-playbook.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/README.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/cache/admin_cache_invalidation.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/comments/admin_comments.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/comments/comment_report.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/comments/comment_stats_aggregation.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/comments/delete_comment.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/comments/edit_comment.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/comments/retrieve_comments.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/deletion/comments.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/deletion/overview.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/deletion/posts.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/events/events.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/media/avatar-upload-design.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/media/post-comment-attachments-design.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/media/upload-pipeline-design.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/media/upload_pipeline.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/mentions/mentions_in_content.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/moderation/appeals.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/moderation/internal_notes.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/moderation/moderator_actions.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/moderation/restrictions.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/notifications/notification_inbox.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/posts/admin_posts.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/posts/author_context.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/posts/hashtag_discovery.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/posts/post_like.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/posts/post_stats_aggregation.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/posts/post_visibility.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/account.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/account_deletion.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/avatar.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/banner.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/blocks.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/change_history.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/check_username_exists.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/follow-system-design.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/my_posts_and_comments.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/preferences.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/profile.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/public_profile.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/domains/users/user_removal.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/library/README.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/library/overview.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/platform/README.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/platform/conventions.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/platform/database-triggers.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/docs/platform/media-storage-topology.md +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/firebase_config.example.json +0 -0
- {core_framework-2.0.0/tests/integration/api → core_framework-2.1.0/tests}/__init__.py +0 -0
- {core_framework-2.0.0/tests/integration/api/admin → core_framework-2.1.0/tests/integration}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/_http_error_details.py +0 -0
- {core_framework-2.0.0/tests/integration/api/admin/cache → core_framework-2.1.0/tests/integration/api}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/_destructive_delete_helpers.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/_user_deletion_helpers.py +0 -0
- {core_framework-2.0.0/tests/integration/api/admin/comments → core_framework-2.1.0/tests/integration/api/admin}/__init__.py +0 -0
- {core_framework-2.0.0/tests/integration/api/admin/moderation → core_framework-2.1.0/tests/integration/api/admin/cache}/__init__.py +0 -0
- {core_framework-2.0.0/tests/integration/api/admin/posts → core_framework-2.1.0/tests/integration/api/admin/comments}/__init__.py +0 -0
- {core_framework-2.0.0/tests/integration/api/admin/users → core_framework-2.1.0/tests/integration/api/admin/moderation}/__init__.py +0 -0
- {core_framework-2.0.0/tests/integration/api/auth → core_framework-2.1.0/tests/integration/api/admin/posts}/__init__.py +0 -0
- {core_framework-2.0.0/tests/integration/api/comments → core_framework-2.1.0/tests/integration/api/admin/users}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/attachments/_helpers.py +0 -0
- {core_framework-2.0.0/tests/integration/api/comments/authenticated → core_framework-2.1.0/tests/integration/api/auth}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/auth/router_test.py +0 -0
- {core_framework-2.0.0/tests/integration/api/comments/public → core_framework-2.1.0/tests/integration/api/comments}/__init__.py +0 -0
- {core_framework-2.0.0/tests/integration/api/notifications → core_framework-2.1.0/tests/integration/api/comments/authenticated}/__init__.py +0 -0
- {core_framework-2.0.0/tests/integration/api/posts → core_framework-2.1.0/tests/integration/api/comments/public}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/comments/public/router_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/create_idempotency_integration_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/events/router_test.py +0 -0
- {core_framework-2.0.0/tests/integration/api/posts/public → core_framework-2.1.0/tests/integration/api/notifications}/__init__.py +0 -0
- {core_framework-2.0.0/tests/integration/api/system → core_framework-2.1.0/tests/integration/api/posts}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/posts/comment_count_aggregation_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/posts/post_attachments_integration_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/posts/post_deletion_integration_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/posts/post_stats_dirty_marking_test.py +0 -0
- {core_framework-2.0.0/tests/integration/api/users → core_framework-2.1.0/tests/integration/api/posts/public}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/public_read_by_id_unavailable_detail_test.py +0 -0
- {core_framework-2.0.0/tests/integration/api/users/authenticated → core_framework-2.1.0/tests/integration/api/system}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/api/system/router_test.py +0 -0
- {core_framework-2.0.0/tests/integration/api/users/public → core_framework-2.1.0/tests/integration/api/users}/__init__.py +0 -0
- {core_framework-2.0.0/tests/integration/worker → core_framework-2.1.0/tests/integration/api/users/authenticated}/__init__.py +0 -0
- {core_framework-2.0.0/tests/unit → core_framework-2.1.0/tests/integration/api/users/public}/__init__.py +0 -0
- {core_framework-2.0.0/tests/unit/application/comments → core_framework-2.1.0/tests/integration/worker}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/worker/aggregate_comment_stats_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/worker/aggregate_post_stats_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/worker/attachment_upload_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/worker/conftest.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/worker/mute_lift_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/integration/worker/utils_test.py +0 -0
- {core_framework-2.0.0/tests/unit/domains → core_framework-2.1.0/tests/unit}/__init__.py +0 -0
- {core_framework-2.0.0/tests/unit/domains/comment → core_framework-2.1.0/tests/unit/application/comments}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/unit/application/events/event_service_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/unit/application/notifications/inbox_service_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/unit/core/bundled_alembic_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/unit/core/migrate_cli_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/unit/core/pagination_test.py +0 -0
- {core_framework-2.0.0/tests/unit/infrastructure → core_framework-2.1.0/tests/unit/domains}/__init__.py +0 -0
- {core_framework-2.0.0/tests/unit/infrastructure/media → core_framework-2.1.0/tests/unit/domains/comment}/__init__.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/unit/domains/user/service_test.py +0 -0
- {core_framework-2.0.0 → core_framework-2.1.0}/tests/unit/infrastructure/media/ssh_finals_publisher_adapter_test.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../../.venv/lib/python3.14/site-packages/fastapi/.agents/skills/fastapi
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: library-skills
|
|
3
|
+
description: Use Library Skills to discover, install, refresh, repair, check, and manage agent skills from installed packages.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Library Skills
|
|
7
|
+
|
|
8
|
+
Use this skill when a project might benefit from agent skills bundled by its installed packages, or when existing Library Skills-managed symlinks are stale, broken, orphaned, or need to be checked.
|
|
9
|
+
|
|
10
|
+
Run commands from the project root.
|
|
11
|
+
|
|
12
|
+
Agents bundle their own skills by including an `.agents/skills` directory. More details in [Library Skills](https://library-skills.io).
|
|
13
|
+
|
|
14
|
+
## First-Time Setup
|
|
15
|
+
|
|
16
|
+
- Make sure project dependencies are installed first, for example with `uv sync` for Python projects or `npm install` / `bun install` for Node.js projects.
|
|
17
|
+
- Run `uvx library-skills` or `npx library-skills` to discover skills bundled by the installed packages and install selected skills interactively.
|
|
18
|
+
- Use `uvx library-skills --all` or `npx library-skills --all` only when all newly discovered skills should be installed without selecting individual skills.
|
|
19
|
+
- Use `uvx library-skills --tool-skill` or `npx library-skills --tool-skill` to copy this Library Skills tool skill into the project so future agents know how to discover, install, update, repair, and check skills.
|
|
20
|
+
|
|
21
|
+
## Commands
|
|
22
|
+
|
|
23
|
+
- Run `uvx library-skills` or `npx library-skills` to discover package-provided skills, install selected new skills, and reconcile existing managed symlinks.
|
|
24
|
+
- Run `uvx library-skills list` or `npx library-skills list` to inspect discovered and installed skills.
|
|
25
|
+
- Run `uvx library-skills list --json` or `npx library-skills list --json` for machine-readable installed status.
|
|
26
|
+
- Run `uvx library-skills scan --json` or `npx library-skills scan --json` for discovery-only automation.
|
|
27
|
+
- Run `uvx library-skills --check` or `npx library-skills --check` to validate managed skill symlink state without changing files.
|
|
28
|
+
- Run `uvx library-skills --yes` or `npx library-skills --yes` to repair stale managed symlinks and remove orphaned managed symlinks non-interactively.
|
|
29
|
+
- Add `--claude` when `.claude/skills` should also be managed.
|
|
30
|
+
- Add `--skill NAME` to install a specific discovered skill by name.
|
|
31
|
+
|
|
32
|
+
## Safety
|
|
33
|
+
|
|
34
|
+
- Prefer rerunning `library-skills` over editing managed symlinks manually.
|
|
35
|
+
- If installed skill symlinks are broken, dependencies may not be installed yet. Try the project's normal install command first, such as `uv sync`, `npm install`, or `bun install`, then rerun `library-skills`.
|
|
36
|
+
- Do not delete or overwrite hand-authored skill directories.
|
|
37
|
+
- Library Skills only removes managed symlinks. It should not remove copied or hand-authored skill directories.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Core-framework API architecture — HTTP adapters only. FastAPI/Pydantic patterns in the fastapi skill.
|
|
3
|
+
globs:
|
|
4
|
+
- core_framework/api/**/*.py
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# API layer (core-framework)
|
|
8
|
+
|
|
9
|
+
**Framework patterns:** use the **fastapi** skill (`.cursor/skills/fastapi/`) — `Annotated`, dependencies, routers, Pydantic v2, CLI.
|
|
10
|
+
|
|
11
|
+
**Validation:** **`api-validation.mdc`**. **Errors:** **`error-boundary.mdc`**. **Domain imports:** **`domain-imports.mdc`**.
|
|
12
|
+
|
|
13
|
+
## Architecture
|
|
14
|
+
|
|
15
|
+
The API layer is an HTTP adapter, not a business-logic layer.
|
|
16
|
+
|
|
17
|
+
- Routers, schemas, and HTTP dependencies only.
|
|
18
|
+
- Call **application** services in `core_framework/application/...` — not domain repositories.
|
|
19
|
+
- No orchestration shared with workers; no worker-only logic here.
|
|
20
|
+
|
|
21
|
+
## Routers
|
|
22
|
+
|
|
23
|
+
- Own HTTP concerns: status codes, `HTTPException`, `response_model`, request parsing.
|
|
24
|
+
- When a route sets **`response_model`**, annotate the handler return type as **`typing.Any`** (OpenAPI documents the shape; services may return dicts or domain types). Body-less routes (**`204`**, no **`response_model`**) use **`None`**.
|
|
25
|
+
- Call `validate_*` schema helpers before invoking application services.
|
|
26
|
+
- Do **not** set **`summary=`** or **`description=`** on route decorators or use route docstrings for OpenAPI prose — paths, handler names, **`response_model`**, and schemas suffice.
|
|
27
|
+
|
|
28
|
+
## Response models
|
|
29
|
+
|
|
30
|
+
- Do **not** use bare collection types (e.g. `list[Item]`) as `response_model`. Wrap in a named `BaseModel` with an **`items`** field for extensibility.
|
|
31
|
+
|
|
32
|
+
## Avoid
|
|
33
|
+
|
|
34
|
+
- Reusable business workflows in API modules.
|
|
35
|
+
- Direct imports from domain internals (only `__init__.py` and `dependencies.py`).
|
|
36
|
+
- `ORJSONResponse` / `UJSONResponse` — use return types / `response_model` per the fastapi skill.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: API layer must validate all fields that have database constraints
|
|
3
|
+
globs: ["core_framework/api/**/*.py"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# API validation
|
|
7
|
+
|
|
8
|
+
Any field with a database constraint (CHECK, NOT NULL, UNIQUE, FK, length) **must** be validated at the API layer before Postgres — return **422**, not **500** from constraint violations.
|
|
9
|
+
|
|
10
|
+
## How
|
|
11
|
+
|
|
12
|
+
1. Review migrations when adding endpoints; mirror constraints in Pydantic (`Field`, `field_validator`, enums).
|
|
13
|
+
2. Map common patterns: `varchar(n)` → `max_length`, CHECK patterns → `pattern`/`EmailStr`, enums → Python `Enum`, required → no bare `| None`.
|
|
14
|
+
3. Skip validation only for unconstrained free text, system-generated fields, and internal-only values.
|
|
15
|
+
|
|
16
|
+
## Layer split
|
|
17
|
+
|
|
18
|
+
- **API** — client contract, **422**, OpenAPI accuracy.
|
|
19
|
+
- **Domain service** — business preconditions for all callers (workers too); see **`domain-input-guards.mdc`**.
|
|
20
|
+
- Domain backstops must not become a second client channel: **`DomainValidationError`** → **`GENERIC_BAD_REQUEST_DETAIL`** per **`error-boundary.mdc`**.
|
|
21
|
+
|
|
22
|
+
Canonical doc: **`docs/platform/client-error-visibility.md`**.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Application services must be transport-agnostic and return plain Python types
|
|
3
|
+
globs:
|
|
4
|
+
- core_framework/application/**/*_service.py
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Application layer
|
|
8
|
+
|
|
9
|
+
Application services orchestrate use cases shared by API and workers. They stay transport-agnostic.
|
|
10
|
+
|
|
11
|
+
## No HTTP concerns
|
|
12
|
+
|
|
13
|
+
- Do not import FastAPI/Starlette types, `HTTPException`, `RequestValidationError`, status codes, request/response classes, or background task types.
|
|
14
|
+
- Do not assume the caller is HTTP.
|
|
15
|
+
- Input shape validation belongs in API schemas/routers; services handle use-case orchestration.
|
|
16
|
+
|
|
17
|
+
## Outcomes
|
|
18
|
+
|
|
19
|
+
- Return plain Python/domain values: `dict`, `list[dict]`, dataclasses, primitives, `None`, or empty collections.
|
|
20
|
+
- Do not return API/Pydantic `BaseModel` instances.
|
|
21
|
+
- Signal HTTP-meaningful failures with **`application.shared.exceptions`** or plain outcomes (`None`, empty), never typed domain exceptions. See **`error-boundary.mdc`**.
|
|
22
|
+
|
|
23
|
+
Use a domain dataclass when one domain row matches the response shape; use a `dict` when the payload is composed from several sources.
|
|
24
|
+
|
|
25
|
+
## Function shape
|
|
26
|
+
|
|
27
|
+
- Use keyword-only arguments after `*` for application service functions and private helpers.
|
|
28
|
+
- Zero-argument functions are exempt.
|
|
29
|
+
- Use one-line docstrings only; see **`docstrings.mdc`**.
|
|
@@ -8,7 +8,7 @@ alwaysApply: false
|
|
|
8
8
|
|
|
9
9
|
When introducing or editing **module-level constants** (values that are fixed for the lifetime of the module and not meant to be reassigned):
|
|
10
10
|
|
|
11
|
-
- Annotate them with **`typing.Final`** and an explicit type, e.g. **`NAME: Final[int] = 42`** or **`_INTERNAL: Final[str] = "
|
|
11
|
+
- Annotate them with **`typing.Final`** and an explicit type, e.g. **`NAME: Final[int] = 42`** or **`_INTERNAL: Final[str] = "example"`**.
|
|
12
12
|
- Prefer **`FrozenSet`**, **`frozenset` literals**, **`MappingProxyType`**, or immutable collections for grouped constants when mutation must be prevented — e.g. **`ProfileUpdate.UPDATE_COLUMNS`** on domain update types.
|
|
13
13
|
- **`Final`** is for **assignment** semantics (no rebinding): it does not freeze mutable object contents unless the type/container is immutable.
|
|
14
14
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Core non-negotiables — behavior, tech stack, layer direction, host scope
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Constitution
|
|
7
|
+
|
|
8
|
+
## Behavior
|
|
9
|
+
|
|
10
|
+
- State assumptions; ask when unclear. Prefer the simplest correct solution.
|
|
11
|
+
- Touch only what the task requires. Match existing style. Remove orphans your edits create.
|
|
12
|
+
- Define verifiable success criteria for non-trivial work.
|
|
13
|
+
|
|
14
|
+
## Tech stack
|
|
15
|
+
|
|
16
|
+
- Python 3.14, Pydantic v2, PostgreSQL 18, orjson (not stdlib json).
|
|
17
|
+
- Absolute imports only (`from core_framework....`). Comma-style `except A, B:` is intentional.
|
|
18
|
+
- Prefer newer APIs (`asyncio.TaskGroup` over `gather`).
|
|
19
|
+
|
|
20
|
+
## Layers
|
|
21
|
+
|
|
22
|
+
Dependencies point inward: API/worker → application → domain. Never reverse.
|
|
23
|
+
|
|
24
|
+
- **API/worker** — transport adapters; call application services.
|
|
25
|
+
- **Application** — orchestration shared by API + worker; no FastAPI types.
|
|
26
|
+
- **Domain** — models, repositories (Postgres only), services. No API/worker/application imports except wiring in `dependencies.py`.
|
|
27
|
+
|
|
28
|
+
Path-scoped rules under `.cursor/rules/` add detail (API, domains, docs, etc.). For FastAPI/Pydantic work in `core_framework/api/`, use the **fastapi** skill (`.cursor/skills/fastapi/`).
|
|
29
|
+
|
|
30
|
+
## Host applications
|
|
31
|
+
|
|
32
|
+
Do not edit consuming host repos in the same task as core-framework work unless the user scopes work to a host or asks to sync/upgrade. See the **sync-host-rules** skill.
|
|
33
|
+
|
|
34
|
+
## Feature implementation
|
|
35
|
+
|
|
36
|
+
Greenfield features (DB → API → repository → service → tests): use the **implement-feature** skill — one layer per response unless the user says otherwise.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Triggers are for audit/history only — never business logic
|
|
3
|
+
globs:
|
|
4
|
+
- alembic/**/alembic/versions/*.py
|
|
5
|
+
- docs/domains/**/*.md
|
|
6
|
+
alwaysApply: false
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Database triggers
|
|
10
|
+
|
|
11
|
+
**Triggers are for audit/history tracking only.** Never implement business logic, validation policy, side effects, or state transitions in triggers.
|
|
12
|
+
|
|
13
|
+
## Acceptable
|
|
14
|
+
|
|
15
|
+
- Immutable change history, actor/timestamp capture, read-only audit rows that do not block the original operation.
|
|
16
|
+
|
|
17
|
+
## Not acceptable
|
|
18
|
+
|
|
19
|
+
- Validation that prevents writes, conditional workflows, notifications, cross-table business updates, derived calculations.
|
|
20
|
+
|
|
21
|
+
Enforce policy in domain services and application orchestration instead. When adding an audit trigger, update **`docs/platform/database-triggers.md`**.
|
|
22
|
+
|
|
23
|
+
Full rationale: **`docs/platform/conventions.md`** and **`docs/platform/architecture-decisions.md`**.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Docstring depth by layer — one-line in application, full Args/Returns/Raises in domain and infrastructure
|
|
3
|
+
globs:
|
|
4
|
+
- core_framework/application/**/*.py
|
|
5
|
+
- core_framework/domains/**/*.py
|
|
6
|
+
- core_framework/infrastructure/**/*.py
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Docstrings by layer
|
|
10
|
+
|
|
11
|
+
Docstring depth follows the layer boundary.
|
|
12
|
+
|
|
13
|
+
- **Application** (`core_framework/application/`): one short sentence. No `Args`, `Returns`, or `Raises` sections.
|
|
14
|
+
- **Domain** (`core_framework/domains/`): full docstrings on public service, repository, component, and port methods that implement or define behavior.
|
|
15
|
+
- **Infrastructure** (`core_framework/infrastructure/`): same as domain; document I/O side effects and failure modes.
|
|
16
|
+
|
|
17
|
+
## Domain/infrastructure contract
|
|
18
|
+
|
|
19
|
+
Use `Args`, `Returns`, and `Raises` when they clarify the boundary. Repositories should document non-obvious query semantics (filters, empty results, strong vs normal reads).
|
|
20
|
+
|
|
21
|
+
## When editing
|
|
22
|
+
|
|
23
|
+
- New functions follow the style for their layer.
|
|
24
|
+
- When changing an existing function, update only that function's docstring if it is out of style.
|
|
25
|
+
- Do not repo-wide migrate unrelated docstrings unless the task asks for it.
|
|
26
|
+
|
|
27
|
+
## Out of scope
|
|
28
|
+
|
|
29
|
+
API routers/schemas rely on OpenAPI and Pydantic. Worker wrappers follow application style.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Enforce importing from domain __init__.py in API/application layers
|
|
3
|
+
globs:
|
|
4
|
+
- core_framework/api/**/*.py
|
|
5
|
+
- core_framework/application/**/*.py
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Domain imports
|
|
9
|
+
|
|
10
|
+
When importing from **`core_framework/domains/*`** in API or application code:
|
|
11
|
+
|
|
12
|
+
## Allowed
|
|
13
|
+
|
|
14
|
+
- Public symbols from domain **`__init__.py`** (models, enums, constants, outcomes).
|
|
15
|
+
- Services from **`dependencies.py`** (e.g. **`user_service`**).
|
|
16
|
+
|
|
17
|
+
## Prohibited
|
|
18
|
+
|
|
19
|
+
- Typed or base **domain exceptions** in API/application — use **`application.shared.exceptions`**.
|
|
20
|
+
- Direct imports from internal modules (`models`, `enums`, `repository`, `service`, `exceptions`).
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
# ✅
|
|
24
|
+
from core_framework.domains.user import Profile, UserRole
|
|
25
|
+
from core_framework.domains.user.dependencies import user_service
|
|
26
|
+
|
|
27
|
+
# ❌
|
|
28
|
+
from core_framework.domains.post import PostNotFoundException
|
|
29
|
+
from core_framework.domains.user.models import Profile
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Export policy
|
|
33
|
+
|
|
34
|
+
Export from **`__init__.py`** only what outer layers need. Typed exceptions stay internal; export **only** **`BaseXxxException`** per domain for inheritance typing — not for per-domain HTTP handlers. **`DomainValidationError`** lives in **`domains/exceptions.py`** (core handler wiring only).
|
|
35
|
+
|
|
36
|
+
To see what a domain exports, check its **`__init__.py`** **`__all__`**.
|
|
37
|
+
|
|
38
|
+
## After a domain call
|
|
39
|
+
|
|
40
|
+
1. Return **`None`** or empty when the use case allows.
|
|
41
|
+
2. Raise an **application** exception when HTTP must signal failure.
|
|
42
|
+
3. Extend the domain service API to absorb typed exceptions internally.
|
|
43
|
+
|
|
44
|
+
Application code never imports repositories. Exception boundary details: **`error-boundary.mdc`**.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Where to place input guards—API validation vs domain service vs repository vs database
|
|
3
|
+
globs:
|
|
4
|
+
- core_framework/domains/**/service.py
|
|
5
|
+
- core_framework/domains/**/repository.py
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Domain input guards
|
|
9
|
+
|
|
10
|
+
Use layered checks:
|
|
11
|
+
|
|
12
|
+
- **API/Pydantic**: client contract, **422**, OpenAPI accuracy. See **`api-validation.mdc`**.
|
|
13
|
+
- **Domain service**: primary business preconditions for all callers (HTTP, workers, scripts).
|
|
14
|
+
- **Repository**: thin SQL/data access; only rare SQL-specific safety checks.
|
|
15
|
+
- **Database**: mandatory integrity failsafe, not the normal invalid-input UX path.
|
|
16
|
+
|
|
17
|
+
## Service policy
|
|
18
|
+
|
|
19
|
+
- Enforce cheap, clear domain preconditions before persistence: empty batches, pagination bounds, non-negative counts, non-blank required strings, meaningless argument combinations.
|
|
20
|
+
- Prefer early return when safe behavior is obvious.
|
|
21
|
+
- Use **`DomainValidationError`** for caller mistakes that must not become 500; HTTP maps it to generic 400 per **`error-boundary.mdc`**.
|
|
22
|
+
- Typed domain exceptions remain internal control flow; application translates before HTTP.
|
|
23
|
+
|
|
24
|
+
Use shared helpers in **`core_framework.domains.utils`** (`require_non_blank*`, `validate_pagination_*`, `require_positive_int`) rather than repeating validation logic.
|
|
25
|
+
|
|
26
|
+
## Repository policy
|
|
27
|
+
|
|
28
|
+
- Do not duplicate service guards in repositories.
|
|
29
|
+
- Do not use repositories as the main home for product rules.
|
|
30
|
+
- Keep CHECK/NOT NULL/FK/UNIQUE constraints where they express truth in the data model; service checks do not replace them.
|
|
31
|
+
|
|
32
|
+
When refactoring, move guards toward the service instead of growing repository-only validation.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: HTTP error boundaries — application vs domain exceptions, handlers, anti-enumeration
|
|
3
|
+
globs:
|
|
4
|
+
- core_framework/core/exception_handlers/**/*.py
|
|
5
|
+
- core_framework/application/**/*_service.py
|
|
6
|
+
- core_framework/api/**/router.py
|
|
7
|
+
- core_framework/domains/**/exceptions.py
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Error boundary
|
|
11
|
+
|
|
12
|
+
Platform contract: **`docs/platform/client-error-visibility.md`**. Domain imports: **`domain-imports.mdc`**.
|
|
13
|
+
|
|
14
|
+
## Layers
|
|
15
|
+
|
|
16
|
+
| Layer | Outward errors | HTTP |
|
|
17
|
+
|-------|----------------|------|
|
|
18
|
+
| **Application** | **`application.shared.exceptions`** | Handlers map type → status + `detail` |
|
|
19
|
+
| **Domain typed** | Internal — not imported by API/application | No typed handlers |
|
|
20
|
+
| **Domain `BaseXxxException`** | Handler catch-all only | **500** if leaked |
|
|
21
|
+
| **API** | Pydantic | **422** |
|
|
22
|
+
|
|
23
|
+
## Application and domain
|
|
24
|
+
|
|
25
|
+
- Application **must not** import or raise typed domain exceptions. Signal via **`None`**, empty collections, or **`application.shared.exceptions`**.
|
|
26
|
+
- Typed domain exceptions inherit domain **`BaseXxxException`** → **`BaseDomainException`**. Export **only** **`BaseXxxException`** from domain **`__init__.py`**, not typed subclasses.
|
|
27
|
+
- **`DomainValidationError`** → dedicated **400** handler + **`GENERIC_BAD_REQUEST_DETAIL`**; do not put internal reason in HTTP **`detail`**.
|
|
28
|
+
- Leaked typed domain exception → **`BaseDomainException`** handler → **500** + **`GENERIC_INTERNAL_SERVER_ERROR_DETAIL`**.
|
|
29
|
+
|
|
30
|
+
## Handler registration
|
|
31
|
+
|
|
32
|
+
- Use **`register_exception_handler`** from **`core_framework.core.exception_handlers.common`** — not raw **`app.add_exception_handler`** elsewhere.
|
|
33
|
+
- **`setup.py`**: application types (specific before any base), **`DomainValidationError`**, one **`BaseDomainException`** leak handler, then **`Exception`** unmapped.
|
|
34
|
+
- No per-domain handler modules for typed exceptions. Handlers translate only — no business logic or repository calls.
|
|
35
|
+
- Do not log **error** for expected application 4xx; **`DomainValidationError`** at **warning**/**info**.
|
|
36
|
+
|
|
37
|
+
## Catalog constants
|
|
38
|
+
|
|
39
|
+
**`GENERIC_BAD_REQUEST_DETAIL`** (400), **`GENERIC_NOT_FOUND_DETAIL`** (404), **`GENERIC_FORBIDDEN_DETAIL`** (403), **`GENERIC_CONFLICT_DETAIL`** (409), ingest 413/415, **`GENERIC_INTERNAL_SERVER_ERROR_DETAIL`** (500).
|
|
40
|
+
|
|
41
|
+
## Anti-enumeration (public routes)
|
|
42
|
+
|
|
43
|
+
- Read-by-id: missing / hidden / withheld → same status + **`GENERIC_NOT_FOUND_DETAIL`** where flow docs align.
|
|
44
|
+
- Idempotent writes on unknown ids → **204** without leaking existence. Empty list pages are OK.
|
|
45
|
+
- Admin/internal routes may differ when documented. Intentional existence-check endpoints are separate product surface.
|
|
46
|
+
|
|
47
|
+
## Validation order
|
|
48
|
+
|
|
49
|
+
User-fixable input shape → API schemas (**422**). Domain backstops → **`DomainValidationError`** → generic **400**.
|
|
50
|
+
|
|
51
|
+
## Logging
|
|
52
|
+
|
|
53
|
+
Do not **`logger.error`** at every domain **`raise`**.
|
|
54
|
+
|
|
55
|
+
Apply to new handlers and touched raise sites unless the task scopes repo-wide migration.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Flow docs describe user-facing API behavior only — no implementation code
|
|
3
|
+
globs:
|
|
4
|
+
- docs/domains/**/*.md
|
|
5
|
+
alwaysApply: false
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Flow documentation
|
|
9
|
+
|
|
10
|
+
Flow docs under **`docs/domains/{domain}/`** describe **client-visible API behavior**, not implementation.
|
|
11
|
+
|
|
12
|
+
- **Include**: endpoints, auth, request/response fields (text, not JSON examples), errors, idempotency, side effects.
|
|
13
|
+
- **Exclude**: Python/SQL snippets, function names, layer internals, schema DDL — see **`no-code-in-docs.mdc`**.
|
|
14
|
+
|
|
15
|
+
When creating or rewriting flow docs, use the **write-flow-doc** skill and match existing docs (e.g. **`profile.md`**, **`restrictions.md`**).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Enforce API, worker, application, and domain layer responsibilities
|
|
3
|
+
globs:
|
|
4
|
+
- core_framework/api/**/*.py
|
|
5
|
+
- core_framework/worker/**/*.py
|
|
6
|
+
- core_framework/application/**/*.py
|
|
7
|
+
- core_framework/domains/**/*.py
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Layer boundaries
|
|
11
|
+
|
|
12
|
+
Dependencies point inward: **API/worker → application → domain**. Never reverse.
|
|
13
|
+
|
|
14
|
+
- **API**: HTTP adapter only; shared orchestration belongs in application.
|
|
15
|
+
- **Worker**: schedules/tasks/job handlers; call application services.
|
|
16
|
+
- **Application**: transport-agnostic orchestration; no FastAPI/Starlette types.
|
|
17
|
+
- **Domain**: business rules, models, repositories, services; no API/worker/application imports.
|
|
18
|
+
|
|
19
|
+
## Cross-layer rules
|
|
20
|
+
|
|
21
|
+
- Worker code must not import `core_framework.domains` directly, except documented housekeeping cron handlers that call a configured domain facade.
|
|
22
|
+
- Domain code imports global infrastructure only in `dependencies.py`.
|
|
23
|
+
- Repositories are Postgres-only and must not query other domains' schemas. See **`repository-schema-isolation`**.
|
|
24
|
+
- Non-SQL I/O uses domain ports/components plus infrastructure adapters. See **`domain-services-and-adapters`**.
|
|
@@ -12,7 +12,7 @@ Documentation under **`docs/`** must not carry **implementation** snippets that
|
|
|
12
12
|
|
|
13
13
|
- Python class/function definitions or examples
|
|
14
14
|
- **SQL for data access or mutation** — `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `MERGE`, CTE-heavy reports, cleanup queries, etc. (describe behavior in prose or name the operation; do not paste DML/query text)
|
|
15
|
-
- Shell commands
|
|
15
|
+
- Shell commands — **except** in deployment runbooks under **`docs/deployments/`** (see *Exceptions* below)
|
|
16
16
|
- Pseudocode that mimics real code syntax
|
|
17
17
|
- Inline backticked references to internal function/method/class names when prose suffices (prefer describing behavior)
|
|
18
18
|
|
|
@@ -25,6 +25,11 @@ Documentation under **`docs/`** must not carry **implementation** snippets that
|
|
|
25
25
|
- Plain-text lifecycle diagrams (arrows, boxes)
|
|
26
26
|
- File/directory tree layouts (plain text or a neutral fence such as `text` if helpful)
|
|
27
27
|
|
|
28
|
+
## Exceptions
|
|
29
|
+
|
|
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).
|
|
32
|
+
|
|
28
33
|
## Rationale
|
|
29
34
|
|
|
30
|
-
Implementation snippets in docs drift from source. **HTTP listings** stay stable as the public contract. **DDL** documents intended physical shape. **DML** and **application code** belong in migrations and modules.
|
|
35
|
+
Implementation snippets in docs drift from source. **HTTP listings** stay stable as the public contract. **DDL** documents intended physical shape. **DML** and **application code** belong in migrations and modules. Deployment runbooks are operator-facing setup instructions where shell commands are the deliverable, not source-bound implementation.
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Postgres write/read config and wiring conventions
|
|
3
|
-
|
|
3
|
+
globs:
|
|
4
|
+
- core_framework/core/settings.py
|
|
5
|
+
- core_framework/core/runtime.py
|
|
6
|
+
- config.toml
|
|
7
|
+
- config.toml.template
|
|
8
|
+
- docs/deployments/**/*.md
|
|
9
|
+
alwaysApply: false
|
|
4
10
|
---
|
|
5
11
|
|
|
6
12
|
# Postgres Config Conventions
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Strong read policy and repository naming for read-after-write consistency
|
|
3
|
+
globs:
|
|
4
|
+
- core_framework/domains/**/repository.py
|
|
5
|
+
- core_framework/domains/**/service.py
|
|
6
|
+
- core_framework/domains/**/dependencies.py
|
|
7
|
+
- core_framework/application/**/*_service.py
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Strong reads
|
|
11
|
+
|
|
12
|
+
## Policy
|
|
13
|
+
|
|
14
|
+
- **Read-after-write** in the same HTTP request or worker job → **strong** read (required). Refetch with `strong_read_database`, `*_strong` repository methods, or service accessors that call them.
|
|
15
|
+
- **Decision-critical guards** where stale data can cause incorrect branching → **strong** read (required). These are reads performed to decide a branch (for example pre-write existence, role, or state checks that determine whether a write runs or which outcome is returned), even when there is no immediate prior write in the flow. See the "Read Consistency (Strong vs Normal Reads)" ADR.
|
|
16
|
+
- **All other strong-read usage** (e.g., list/browse freshness) → opt-in unless the user explicitly requested it in the task.
|
|
17
|
+
- If a flow writes then reads and only a normal-read API exists, add or extend the `*_strong` path and call it from that flow.
|
|
18
|
+
- Repositories accept `strong_read_database: Postgres` on `__init__` for wiring symmetry even when unused.
|
|
19
|
+
|
|
20
|
+
## Repository pattern
|
|
21
|
+
|
|
22
|
+
- Normal reads: explicit methods (e.g. `select_appeal`) using `read_database`.
|
|
23
|
+
- Strong reads: separate methods only where needed (e.g. `select_appeal_strong`) using `strong_read_database`.
|
|
24
|
+
- Share one private helper that accepts a database handle — do not duplicate SQL or mapping.
|
|
25
|
+
- If only strong-read behavior is needed today, use a single method with `_strong` in the name.
|
|
26
|
+
- Service accessors that call strong repository methods should also include `_strong`.
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
# Preferred
|
|
30
|
+
async def select_appeal(self, *, appeal_id: int) -> Appeal:
|
|
31
|
+
return await self._select_appeal_with_database(appeal_id=appeal_id, database=self.read_database)
|
|
32
|
+
|
|
33
|
+
async def select_appeal_strong(self, *, appeal_id: int) -> Appeal:
|
|
34
|
+
return await self._select_appeal_with_database(appeal_id=appeal_id, database=self.strong_read_database)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Keep consistency decisions in services/use-case orchestration, not hidden in unrelated call paths.
|
|
@@ -11,7 +11,18 @@ This skill covers **scaffolding only**: settings, a full **Alembic directory lay
|
|
|
11
11
|
|
|
12
12
|
It does **not** cover the API layer or tests — handle those separately following the existing rules.
|
|
13
13
|
|
|
14
|
-
Follow
|
|
14
|
+
Follow the **implement-feature** skill: one step per response, wait for review.
|
|
15
|
+
|
|
16
|
+
## Capability-only domain (no Postgres schema)
|
|
17
|
+
|
|
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
|
+
|
|
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.
|
|
22
|
+
- Export only `Base<Domain>Exception` + public models from `__init__.py`; keep the facade service in `dependencies.py`.
|
|
23
|
+
- Wire `configure_<domain>_dependencies()` in `application/bootstrap.py` (no `runtime` needed when there is no Postgres handle).
|
|
24
|
+
|
|
25
|
+
Use this branch when the user says the domain is "capability-only", "no database", or names an external SDK/service. Otherwise proceed with the persistence-domain steps below.
|
|
15
26
|
|
|
16
27
|
## Inputs
|
|
17
28
|
|
|
@@ -109,7 +120,7 @@ A single `class <Domain>Repository:` whose **`__init__`** takes `(write_postgres
|
|
|
109
120
|
|
|
110
121
|
A single `class <Domain>Service:` whose **`__init__`** takes `<Domain>Repository` and stores it on a **private** attribute (e.g. `_repository`). **No other methods.** No FastAPI/Starlette imports. No caller-context names per `domain-caller-context`.
|
|
111
122
|
|
|
112
|
-
When real behavior is added later, apply
|
|
123
|
+
When real behavior is added later, apply **strong-reads** (`.cursor/rules/strong-reads.mdc`) for reads and `_strong` naming.
|
|
113
124
|
|
|
114
125
|
If the bounded context needs filesystem, HTTP, or SSH, add **ports/adapters** or extra domain collaborators per `docs/platform/domain-services-and-adapters.md` — do not put that I/O in `repository.py`.
|
|
115
126
|
|
|
@@ -199,7 +210,7 @@ Do this in a **separate step/PR** when you have DDL to apply.
|
|
|
199
210
|
|
|
200
211
|
## Reminders
|
|
201
212
|
|
|
202
|
-
- One step per response, wait for review (
|
|
213
|
+
- One step per response, wait for review (**implement-feature** skill).
|
|
203
214
|
- Domain imports follow `domain-imports`; do not import API/application from domain.
|
|
204
215
|
- Never name domain symbols by caller (`Admin*`, `Api*`, `Worker*`) per `domain-caller-context`.
|
|
205
|
-
- When adding real repository methods later, follow
|
|
216
|
+
- When adding real repository methods later, follow **strong-reads** (`_strong` naming where applicable).
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-review
|
|
3
|
+
description: Review code for quality, architecture compliance, and best practices. Use when the user asks for a code review, audit, or review.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Code Review
|
|
7
|
+
|
|
8
|
+
## Output format (required)
|
|
9
|
+
|
|
10
|
+
**Actionable findings only:**
|
|
11
|
+
|
|
12
|
+
- Bugs, wrong behavior, improvements, optimizations, doc/code contradictions, parallel implementation drift (sibling flows that diverge without documented reason).
|
|
13
|
+
- Prioritize by severity with file context and fix direction.
|
|
14
|
+
- **Do not** praise, summarize strengths, or pad with checklist pass narratives.
|
|
15
|
+
- One-line scope is fine. If nothing is wrong, say so in one sentence.
|
|
16
|
+
|
|
17
|
+
Do **not** flag documented accepted trade-offs in **`docs/platform/architecture-decisions.md`** unless the implementation violates them.
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
|
|
21
|
+
1. Read **`docs/platform/layers-and-boundaries.md`**, **`conventions.md`**, and **`architecture-decisions.md`** for the reviewed scope.
|
|
22
|
+
1. Apply **scoped rules** (`.cursor/rules/*.mdc`) matching files under review — especially **`error-boundary`**, **`domain-imports`**, **`api-layer`**, **`application-layer`**, **`strong-reads`**.
|
|
23
|
+
1. Report findings only — no filler.
|
|
24
|
+
|
|
25
|
+
## Quick checks
|
|
26
|
+
|
|
27
|
+
- Application services: no HTTP types, no domain exceptions, no Pydantic return types, one-line docstrings.
|
|
28
|
+
- API: thin routers, validation in schemas, orchestration in application — **fastapi** skill + **`api-layer`** / **`api-validation`** / **`error-boundary`** rules.
|
|
29
|
+
- Domain: imports only via **`__init__.py`** / **`dependencies`** from outer layers; no caller-context names (**`domain-caller-context`**).
|
|
30
|
+
- Read-after-write refetches use **`*_strong`** where applicable.
|
|
31
|
+
|
|
32
|
+
## Parallel drift
|
|
33
|
+
|
|
34
|
+
Flag sibling modules with the same job but different structure (async layout, cleanup order, error/idempotency contracts) when docs do not explain the difference.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../../.agents/skills/fastapi
|