geek-cafe-saas-sdk 0.7.5__tar.gz → 0.8.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.

Potentially problematic release.


This version of geek-cafe-saas-sdk might be problematic. Click here for more details.

Files changed (301) hide show
  1. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/ARCHITECTURE.md +2 -2
  2. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/CHANGELOG_0.4.1.md +6 -6
  3. geek_cafe_saas_sdk-0.8.0/MIGRATION_EXAMPLE.md +392 -0
  4. geek_cafe_saas_sdk-0.8.0/MIGRATION_PLAN.md +267 -0
  5. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/PKG-INFO +16 -16
  6. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/README.md +15 -15
  7. geek_cafe_saas_sdk-0.8.0/README_SECURITY_CONTEXT.md +444 -0
  8. geek_cafe_saas_sdk-0.8.0/SECURITY_CONTEXT_SUMMARY.md +268 -0
  9. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/examples/decorator_pattern_handlers.py +1 -1
  10. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/examples/lambda_event_logging_example.py +2 -2
  11. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/pyproject.toml +1 -1
  12. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/__init__.py +1 -1
  13. geek_cafe_saas_sdk-0.8.0/src/geek_cafe_saas_sdk/core/anonymous_context.py +321 -0
  14. geek_cafe_saas_sdk-0.8.0/src/geek_cafe_saas_sdk/core/request_context.py +184 -0
  15. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/decorators/__init__.py +1 -1
  16. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/decorators/auth.py +6 -6
  17. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/decorators/core.py +44 -44
  18. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/analytics/services/website_analytics_service.py +1 -3
  19. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/analytics/services/website_analytics_summary_service.py +1 -3
  20. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/analytics/services/website_analytics_tally_service.py +15 -3
  21. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/handlers/users/create/app.py +1 -1
  22. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/handlers/users/delete/app.py +1 -1
  23. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/handlers/users/get/app.py +1 -1
  24. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/handlers/users/list/app.py +1 -1
  25. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/handlers/users/update/app.py +1 -1
  26. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/services/resource_permission_service.py +1 -4
  27. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/services/user_service.py +0 -2
  28. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/communities/handlers/communities/create/app.py +1 -1
  29. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/communities/handlers/communities/delete/app.py +1 -1
  30. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/communities/handlers/communities/get/app.py +1 -1
  31. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/communities/handlers/communities/list/app.py +1 -1
  32. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/communities/handlers/communities/update/app.py +1 -1
  33. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/communities/services/community_member_service.py +1 -3
  34. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/communities/services/community_service.py +3 -3
  35. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/handlers/attendees/app.py +1 -1
  36. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/handlers/cancel/app.py +1 -1
  37. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/handlers/check_in/app.py +1 -1
  38. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/handlers/create/app.py +1 -1
  39. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/handlers/delete/app.py +1 -1
  40. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/handlers/get/app.py +1 -1
  41. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/handlers/invite/app.py +1 -1
  42. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/handlers/list/app.py +1 -1
  43. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/handlers/publish/app.py +1 -1
  44. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/handlers/rsvp/app.py +1 -1
  45. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/handlers/update/app.py +1 -1
  46. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/services/event_attendee_service.py +1 -2
  47. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/services/event_service.py +6 -4
  48. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/handlers/README.md +1 -1
  49. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/handlers/files/create/app.py +1 -1
  50. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/handlers/files/download/app.py +1 -1
  51. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/handlers/files/get/app.py +1 -1
  52. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/handlers/files/list/app.py +1 -1
  53. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/handlers/lineage/create_derived/app.py +1 -1
  54. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/handlers/lineage/create_main/app.py +1 -1
  55. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/handlers/lineage/download_bundle/app.py +1 -1
  56. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/handlers/lineage/get_lineage/app.py +1 -1
  57. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/handlers/lineage/prepare_bundle/app.py +1 -1
  58. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/models/file.py +16 -6
  59. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/services/directory_service.py +34 -9
  60. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/services/file_system_service.py +38 -3
  61. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/services/file_version_service.py +33 -36
  62. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/create/app.py +1 -1
  63. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/delete/app.py +1 -1
  64. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/get/app.py +1 -1
  65. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/list/app.py +1 -1
  66. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/update/app.py +1 -1
  67. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/create/app.py +1 -1
  68. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/delete/app.py +1 -1
  69. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/get/app.py +1 -1
  70. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/list/app.py +1 -1
  71. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/update/app.py +1 -1
  72. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/create/app.py +1 -1
  73. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/delete/app.py +1 -1
  74. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/get/app.py +1 -1
  75. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/list/app.py +1 -1
  76. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/update/app.py +1 -1
  77. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/services/chat_channel_service.py +35 -2
  78. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/services/chat_message_service.py +20 -3
  79. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/services/contact_thread_service.py +1 -3
  80. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/handlers/create_webhook/app.py +1 -1
  81. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/handlers/get/app.py +1 -1
  82. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/handlers/get_preferences/app.py +1 -1
  83. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/handlers/list/app.py +1 -1
  84. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/handlers/list_webhooks/app.py +1 -1
  85. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/handlers/mark_read/app.py +1 -1
  86. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/handlers/send/app.py +1 -1
  87. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/handlers/update_preferences/app.py +1 -1
  88. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/services/notification_service.py +1 -2
  89. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/handlers/billing_accounts/create/app.py +1 -1
  90. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/handlers/billing_accounts/get/app.py +1 -1
  91. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/handlers/billing_accounts/update/app.py +1 -1
  92. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/handlers/payment_intents/create/app.py +1 -1
  93. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/handlers/payment_intents/get/app.py +1 -1
  94. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/handlers/payments/get/app.py +1 -1
  95. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/handlers/payments/list/app.py +1 -1
  96. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/handlers/payments/record/app.py +1 -1
  97. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/handlers/refunds/create/app.py +1 -1
  98. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/handlers/refunds/get/app.py +1 -1
  99. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/services/payment_service.py +1 -2
  100. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/README.md +2 -2
  101. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/addons/create/app.py +1 -1
  102. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/addons/get/app.py +1 -1
  103. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/addons/list/app.py +1 -1
  104. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/addons/update/app.py +1 -1
  105. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/discounts/create/app.py +1 -1
  106. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/discounts/get/app.py +1 -1
  107. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/discounts/validate/app.py +1 -1
  108. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/plans/create/app.py +1 -1
  109. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/plans/get/app.py +1 -1
  110. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/plans/list/app.py +1 -1
  111. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/plans/update/app.py +1 -1
  112. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/usage/aggregate/app.py +1 -1
  113. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/usage/record/app.py +1 -1
  114. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/services/subscription_manager_service.py +0 -2
  115. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/activate/app.py +1 -1
  116. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/active/app.py +1 -1
  117. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/cancel/app.py +1 -1
  118. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/get/app.py +1 -1
  119. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/list/app.py +1 -1
  120. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/record_payment/app.py +1 -1
  121. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/tenants/get/app.py +1 -1
  122. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/tenants/me/app.py +1 -1
  123. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/tenants/signup/app.py +1 -1
  124. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/tenants/update/app.py +1 -1
  125. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/services/subscription_service.py +3 -3
  126. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/services/tenant_service.py +3 -3
  127. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/handlers/votes/delete/app.py +1 -1
  128. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/handlers/votes/get/app.py +1 -1
  129. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/handlers/votes/list/app.py +1 -1
  130. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/handlers/votes/update/app.py +1 -1
  131. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/services/vote_service.py +1 -5
  132. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/services/vote_summary_service.py +1 -5
  133. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/services/vote_tally_service.py +10 -3
  134. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/base_handler.py +40 -6
  135. geek_cafe_saas_sdk-0.8.0/src/geek_cafe_saas_sdk/lambda_handlers/_base/service_pool.py +239 -0
  136. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/middleware/authorization.py +1 -1
  137. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/middleware/cors.py +8 -8
  138. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/services/database_service.py +76 -5
  139. geek_cafe_saas_sdk-0.7.5/src/geek_cafe_saas_sdk/lambda_handlers/_base/service_pool.py +0 -94
  140. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/.env.mock +0 -0
  141. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/.gitignore +0 -0
  142. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/.windsurf/rules/cascade.yaml +0 -0
  143. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/CHANGELOG.md +0 -0
  144. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/CURRENT_TASKS.md +0 -0
  145. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/LICENSE +0 -0
  146. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/README_FILE_SYSTEM_SDK_USAGE.md +0 -0
  147. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/coverage.json +0 -0
  148. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/examples/factory_authorization_example.py +0 -0
  149. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/examples/file_lineage_example.py +0 -0
  150. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/examples/hierarchical_routing_handler_example.py +0 -0
  151. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/examples/lambda_handler_examples.py +0 -0
  152. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/examples/lambda_handlers/api_key_example.py +0 -0
  153. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/examples/website_analytics_example.py +0 -0
  154. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/lambda_handlers/auth/confirm_forgot_password/app.py +0 -0
  155. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/lambda_handlers/auth/forgot_password/app.py +0 -0
  156. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/lambda_handlers/users/change_password/app.py +0 -0
  157. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/lambda_handlers/users/reset_password/app.py +0 -0
  158. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/publish_to_pypi.py +0 -0
  159. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/publish_to_pypi.sh +0 -0
  160. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/pysetup.py +0 -0
  161. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/pysetup.sh +0 -0
  162. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/requirements.dev.txt +0 -0
  163. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/requirements.txt +0 -0
  164. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/run_unit_tests.sh +0 -0
  165. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/core/__init__.py +0 -0
  166. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/core/audit_mixin.py +0 -0
  167. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/core/error_codes.py +0 -0
  168. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/core/service_errors.py +0 -0
  169. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/core/service_result.py +0 -0
  170. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/__init__.py +0 -0
  171. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/analytics/__init__.py +0 -0
  172. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/analytics/handlers/__init__.py +0 -0
  173. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/analytics/models/__init__.py +0 -0
  174. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/analytics/models/website_analytics.py +0 -0
  175. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/analytics/models/website_analytics_summary.py +0 -0
  176. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/analytics/services/__init__.py +0 -0
  177. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/__init__.py +0 -0
  178. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/handlers/__init__.py +0 -0
  179. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/models/__init__.py +0 -0
  180. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/models/permission.py +0 -0
  181. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/models/resource_permission.py +0 -0
  182. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/models/role.py +0 -0
  183. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/models/user.py +0 -0
  184. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/services/__init__.py +0 -0
  185. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/services/authorization_service.py +0 -0
  186. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/auth/services/permission_registry.py +0 -0
  187. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/communities/__init__.py +0 -0
  188. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/communities/handlers/__init__.py +0 -0
  189. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/communities/models/__init__.py +0 -0
  190. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/communities/models/community.py +0 -0
  191. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/communities/models/community_member.py +0 -0
  192. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/communities/services/__init__.py +0 -0
  193. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/__init__.py +0 -0
  194. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/handlers/__init__.py +0 -0
  195. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/models/__init__.py +0 -0
  196. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/models/event.py +0 -0
  197. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/models/event_attendee.py +0 -0
  198. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/events/services/__init__.py +0 -0
  199. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/__init__.py +0 -0
  200. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/handlers/__init__.py +0 -0
  201. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/models/__init__.py +0 -0
  202. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/models/directory.py +0 -0
  203. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/models/file_share.py +0 -0
  204. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/models/file_version.py +0 -0
  205. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/services/__init__.py +0 -0
  206. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/services/file_lineage_service.py +0 -0
  207. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/services/file_share_service.py +0 -0
  208. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/files/services/s3_file_service.py +0 -0
  209. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/__init__.py +0 -0
  210. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/__init__.py +0 -0
  211. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/models/__init__.py +0 -0
  212. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/models/chat_channel.py +0 -0
  213. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/models/chat_channel_member.py +0 -0
  214. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/models/chat_message.py +0 -0
  215. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/models/contact_thread.py +0 -0
  216. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/messaging/services/__init__.py +0 -0
  217. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/__init__.py +0 -0
  218. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/handlers/__init__.py +0 -0
  219. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/models/__init__.py +0 -0
  220. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/models/notification.py +0 -0
  221. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/models/notification_preference.py +0 -0
  222. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/models/webhook_subscription.py +0 -0
  223. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/notifications/services/__init__.py +0 -0
  224. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/__init__.py +0 -0
  225. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/handlers/README.md +0 -0
  226. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/handlers/__init__.py +0 -0
  227. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/models/__init__.py +0 -0
  228. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/models/billing_account.py +0 -0
  229. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/models/payment.py +0 -0
  230. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/models/payment_intent_ref.py +0 -0
  231. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/models/refund.py +0 -0
  232. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/payments/services/__init__.py +0 -0
  233. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/__init__.py +0 -0
  234. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/handlers/__init__.py +0 -0
  235. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/models/__init__.py +0 -0
  236. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/models/addon.py +0 -0
  237. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/models/discount.py +0 -0
  238. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/models/plan.py +0 -0
  239. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/models/usage_record.py +0 -0
  240. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/subscriptions/services/__init__.py +0 -0
  241. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/__init__.py +0 -0
  242. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/__init__.py +0 -0
  243. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/models/__init__.py +0 -0
  244. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/models/subscription.py +0 -0
  245. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/models/tenant.py +0 -0
  246. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/tenancy/services/__init__.py +0 -0
  247. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/__init__.py +0 -0
  248. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/handlers/__init__.py +0 -0
  249. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/handlers/votes/create/app.py +0 -0
  250. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/handlers/votes/summerize/README.md +0 -0
  251. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/models/__init__.py +0 -0
  252. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/models/vote.py +0 -0
  253. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/models/vote_summary.py +0 -0
  254. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/domains/voting/services/__init__.py +0 -0
  255. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/README.md +0 -0
  256. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/__init__.py +0 -0
  257. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/__init__.py +0 -0
  258. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/api_key_handler.py +0 -0
  259. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/authorized_secure_handler.py +0 -0
  260. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/handler_factory.py +0 -0
  261. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/public_handler.py +0 -0
  262. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/secure_handler.py +0 -0
  263. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/directories/create/app.py +0 -0
  264. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/directories/delete/app.py +0 -0
  265. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/directories/get/app.py +0 -0
  266. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/directories/list/app.py +0 -0
  267. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/directories/move/app.py +0 -0
  268. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/delete/app.py +0 -0
  269. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/download/app.py +0 -0
  270. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/get/app.py +0 -0
  271. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/list/app.py +0 -0
  272. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/share/app.py +0 -0
  273. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/shares/list/app.py +0 -0
  274. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/shares/revoke/app.py +0 -0
  275. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/update/app.py +0 -0
  276. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/upload/app.py +0 -0
  277. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/middleware/__init__.py +0 -0
  278. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/middleware/auth.py +0 -0
  279. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/middleware/error_handling.py +0 -0
  280. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/middleware/validation.py +0 -0
  281. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/models/__init__.py +0 -0
  282. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/models/base_model.py +0 -0
  283. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/services/__init__.py +0 -0
  284. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/__init__.py +0 -0
  285. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/cognito_utility.py +0 -0
  286. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/custom_exceptions.py +0 -0
  287. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/datetime_utility.py +0 -0
  288. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/dictionary_utility.py +0 -0
  289. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/dynamodb_utils.py +0 -0
  290. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/environment_loader.py +0 -0
  291. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/environment_variables.py +0 -0
  292. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/http_body_parameters.py +0 -0
  293. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/http_path_parameters.py +0 -0
  294. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/http_status_code.py +0 -0
  295. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/jwt_utility.py +0 -0
  296. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/lambda_event_utility.py +0 -0
  297. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/logging_utility.py +0 -0
  298. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/message_query_helper.py +0 -0
  299. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/response.py +0 -0
  300. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/src/geek_cafe_saas_sdk/utilities/string_functions.py +0 -0
  301. {geek_cafe_saas_sdk-0.7.5 → geek_cafe_saas_sdk-0.8.0}/update_readme_badges.py +0 -0
@@ -146,7 +146,7 @@ def test_create_event(integration_setup, helper):
146
146
  db, event_service = integration_setup
147
147
 
148
148
  event = helper.build_proxy_event(body={"title": "Test"})
149
- response = handler(event, None, injected_service=event_service)
149
+ response = lambda_handler(event, None, injected_service=event_service)
150
150
 
151
151
  assert response['statusCode'] == 201
152
152
  ```
@@ -160,7 +160,7 @@ Reduces Lambda cold starts by 80-90% through connection reuse:
160
160
  # Module level - initialized once
161
161
  service_pool = ServicePool(EventService)
162
162
 
163
- def handler(event, context):
163
+ def lambda_handler(event, context):
164
164
  # Reuses service on warm invocations
165
165
  service = service_pool.get()
166
166
  ```
@@ -49,23 +49,23 @@ This standardizes the parameter name across the entire codebase for testing with
49
49
  #### Before (0.4.0)
50
50
  ```python
51
51
  # Old parameter name (WRONG)
52
- def handler(event, context, injected_services=None):
52
+ def lambda_handler(event, context, injected_services=None):
53
53
  service = injected_services or service_pool.get()
54
54
  # ...
55
55
 
56
56
  # In tests
57
- response = handler(event, None, injected_services=mock_service)
57
+ response = lambda_handler(event, None, injected_services=mock_service)
58
58
  ```
59
59
 
60
60
  #### After (0.4.1)
61
61
  ```python
62
62
  # New parameter name (CORRECT)
63
- def handler(event, context, injected_service=None):
63
+ def lambda_handler(event, context, injected_service=None):
64
64
  service = injected_service or service_pool.get()
65
65
  # ...
66
66
 
67
67
  # In tests
68
- response = handler(event, None, injected_service=mock_service)
68
+ response = lambda_handler(event, None, injected_service=mock_service)
69
69
  ```
70
70
 
71
71
  ### Testing Impact
@@ -79,7 +79,7 @@ from moto import mock_dynamodb
79
79
  @mock_dynamodb
80
80
  def test_handler():
81
81
  service = MessageService()
82
- response = handler(event, None, injected_services=service) # ❌ Wrong param name
82
+ response = lambda_handler(event, None, injected_services=service) # ❌ Wrong param name
83
83
 
84
84
  # NEW WAY (0.4.1) - Correct
85
85
  from moto import mock_dynamodb
@@ -87,7 +87,7 @@ from moto import mock_dynamodb
87
87
  @mock_dynamodb
88
88
  def test_handler():
89
89
  service = MessageService()
90
- response = handler(event, None, injected_service=service) # ✅ Correct param name
90
+ response = lambda_handler(event, None, injected_service=service) # ✅ Correct param name
91
91
  ```
92
92
 
93
93
  ### Why This Change?
@@ -0,0 +1,392 @@
1
+ # Complete Migration Example: VoteService
2
+
3
+ This document shows a complete before/after migration of the VoteService as a template for all other services.
4
+
5
+ ## 📁 Files to Update
6
+
7
+ 1. Service implementation
8
+ 2. Lambda handler
9
+ 3. Test file
10
+ 4. Test fixtures
11
+
12
+ ---
13
+
14
+ ## 1️⃣ Service Implementation
15
+
16
+ ### File: `src/geek_cafe_saas_sdk/domains/voting/services/vote_service.py`
17
+
18
+ #### BEFORE:
19
+ ```python
20
+ from geek_cafe_saas_sdk.services.database_service import DatabaseService
21
+ from typing import Dict, Any
22
+
23
+ class VoteService(DatabaseService):
24
+ def __init__(self, dynamodb=None, table_name=None):
25
+ super().__init__(dynamodb=dynamodb, table_name=table_name)
26
+
27
+ def create(self, tenant_id: str, user_id: str, user_context: Dict[str, Any], **kwargs) -> ServiceResult[Vote]:
28
+ """Create a vote."""
29
+ # Manual security validation (or none at all!)
30
+ if not user_context:
31
+ return ServiceResult.error_result("UNAUTHORIZED", "No user context")
32
+
33
+ vote = Vote()
34
+ vote.tenant_id = tenant_id
35
+ vote.user_id = user_id
36
+ vote.target_id = kwargs.get('target_id')
37
+ vote.up_vote = kwargs.get('up_vote', 0)
38
+ vote.down_vote = kwargs.get('down_vote', 0)
39
+
40
+ # Manual audit trail
41
+ vote.created_by = user_id
42
+ vote.updated_by = user_id
43
+
44
+ vote.prep_for_save()
45
+ return self._save_model(vote)
46
+
47
+ def get_by_id(self, resource_id: str, tenant_id: str, user_id: str, user_context: Dict[str, Any]) -> ServiceResult[Vote]:
48
+ """Get vote by ID."""
49
+ vote = self._get_model_by_id_with_tenant_check(resource_id, Vote, tenant_id)
50
+
51
+ if not vote:
52
+ return ServiceResult.error_result("NOT_FOUND", "Vote not found")
53
+
54
+ return ServiceResult.success_result(vote)
55
+ ```
56
+
57
+ #### AFTER:
58
+ ```python
59
+ from geek_cafe_saas_sdk.services.database_service import DatabaseService
60
+ from geek_cafe_saas_sdk.core.request_context import RequestContext
61
+
62
+ class VoteService(DatabaseService):
63
+ def __init__(self, dynamodb=None, table_name=None, request_context=None):
64
+ super().__init__(
65
+ dynamodb=dynamodb,
66
+ table_name=table_name,
67
+ request_context=request_context # ✅ Pass context to parent
68
+ )
69
+
70
+ def create(self, tenant_id: str, user_id: str, **kwargs) -> ServiceResult[Vote]:
71
+ """Create a vote."""
72
+ # ✅ Set targets for security validation
73
+ self.request_context.set_targets(tenant_id=tenant_id, user_id=user_id)
74
+
75
+ vote = Vote()
76
+ vote.tenant_id = tenant_id
77
+ vote.user_id = user_id
78
+ vote.target_id = kwargs.get('target_id')
79
+ vote.up_vote = kwargs.get('up_vote', 0)
80
+ vote.down_vote = kwargs.get('down_vote', 0)
81
+
82
+ vote.prep_for_save()
83
+
84
+ # ✅ Automatic security validation + audit trail
85
+ return self._save_model(vote)
86
+
87
+ def get_by_id(self, resource_id: str, tenant_id: str, user_id: str) -> ServiceResult[Vote]:
88
+ """Get vote by ID."""
89
+ # ✅ Automatic tenant validation (uses request_context internally)
90
+ vote = self._get_model_by_id_with_tenant_check(resource_id, Vote, tenant_id)
91
+
92
+ if not vote:
93
+ return ServiceResult.error_result("NOT_FOUND", "Vote not found")
94
+
95
+ return ServiceResult.success_result(vote)
96
+ ```
97
+
98
+ ### Key Changes:
99
+ 1. ✅ Added `request_context` to `__init__` parameters
100
+ 2. ✅ Passed `request_context` to `super().__init__()`
101
+ 3. ❌ Removed `user_context: Dict` from all method signatures
102
+ 4. ✅ Added `self.request_context.set_targets()` in methods
103
+ 5. ❌ Removed manual audit trail (`created_by`, `updated_by`) - now automatic
104
+ 6. ❌ Removed manual security validation - now automatic in `_save_model()`
105
+
106
+ ---
107
+
108
+ ## 2️⃣ Lambda Handler
109
+
110
+ ### File: `src/geek_cafe_saas_sdk/domains/voting/handlers/votes/create/app.py`
111
+
112
+ #### BEFORE:
113
+ ```python
114
+ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
115
+ from geek_cafe_saas_sdk.domains.voting.services.vote_service import VoteService
116
+ from boto3_assist.dynamodb.dynamodb import DynamoDB
117
+ import os
118
+
119
+ def lambda_handler(event, context):
120
+ # Extract user context from JWT
121
+ user_context = LambdaEventUtility.get_user_context(event)
122
+ tenant_id = LambdaEventUtility.get_authenticated_user_tenant_id(event)
123
+ user_id = LambdaEventUtility.get_authenticated_user_id(event)
124
+
125
+ # Get request body
126
+ body = LambdaEventUtility.get_body_from_event(event)
127
+
128
+ # Create service
129
+ vote_service = VoteService(
130
+ dynamodb=DynamoDB(),
131
+ table_name=os.getenv("DYNAMODB_TABLE_NAME")
132
+ )
133
+
134
+ # Call service (pass user_context)
135
+ result = vote_service.create(
136
+ tenant_id=tenant_id,
137
+ user_id=user_id,
138
+ user_context=user_context, # ❌ Passed explicitly
139
+ target_id=body.get('target_id'),
140
+ up_vote=body.get('up_vote', 0),
141
+ down_vote=body.get('down_vote', 0)
142
+ )
143
+
144
+ return service_result_to_response(result)
145
+ ```
146
+
147
+ #### AFTER:
148
+ ```python
149
+ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
150
+ from geek_cafe_saas_sdk.domains.voting.services.vote_service import VoteService
151
+ from geek_cafe_saas_sdk.core.request_context import RequestContext # ✅ Import
152
+ from boto3_assist.dynamodb.dynamodb import DynamoDB
153
+ import os
154
+
155
+ def lambda_handler(event, context):
156
+ # Extract user context from JWT
157
+ user_context_dict = LambdaEventUtility.get_user_context(event)
158
+
159
+ # ✅ Create security context
160
+ request_context = RequestContext(user_context_dict)
161
+
162
+ tenant_id = LambdaEventUtility.get_authenticated_user_tenant_id(event)
163
+ user_id = LambdaEventUtility.get_authenticated_user_id(event)
164
+
165
+ # Get request body
166
+ body = LambdaEventUtility.get_body_from_event(event)
167
+
168
+ # ✅ Create service with security context
169
+ vote_service = VoteService(
170
+ dynamodb=DynamoDB(),
171
+ table_name=os.getenv("DYNAMODB_TABLE_NAME"),
172
+ request_context=request_context # ✅ Set once
173
+ )
174
+
175
+ # ✅ Clean API call (no user_context)
176
+ result = vote_service.create(
177
+ tenant_id=tenant_id,
178
+ user_id=user_id,
179
+ target_id=body.get('target_id'),
180
+ up_vote=body.get('up_vote', 0),
181
+ down_vote=body.get('down_vote', 0)
182
+ )
183
+
184
+ return service_result_to_response(result)
185
+ ```
186
+
187
+ ### Key Changes:
188
+ 1. ✅ Import `RequestContext`
189
+ 2. ✅ Create `request_context = RequestContext(user_context_dict)`
190
+ 3. ✅ Pass `request_context` to service initialization
191
+ 4. ❌ Remove `user_context` from service method calls
192
+
193
+ ---
194
+
195
+ ## 3️⃣ Test Fixtures
196
+
197
+ ### File: `tests/conftest.py`
198
+
199
+ #### BEFORE:
200
+ ```python
201
+ import pytest
202
+ from boto3_assist.dynamodb.dynamodb import DynamoDB
203
+
204
+ @pytest.fixture
205
+ def user_context():
206
+ """Mock user context for tests."""
207
+ return {
208
+ 'user_id': 'user-123',
209
+ 'tenant_id': 'tenant-123',
210
+ 'roles': [],
211
+ 'permissions': [],
212
+ 'email': 'test@example.com',
213
+ 'inboxes': []
214
+ }
215
+
216
+ @pytest.fixture
217
+ def vote_service(mock_dynamodb):
218
+ """Vote service for testing."""
219
+ from geek_cafe_saas_sdk.domains.voting.services.vote_service import VoteService
220
+ return VoteService(dynamodb=mock_dynamodb, table_name="test_table")
221
+ ```
222
+
223
+ #### AFTER:
224
+ ```python
225
+ import pytest
226
+ from boto3_assist.dynamodb.dynamodb import DynamoDB
227
+ from geek_cafe_saas_sdk.core.request_context import RequestContext # ✅ Import
228
+
229
+ @pytest.fixture
230
+ def request_context():
231
+ """Security context for tests."""
232
+ user_context = {
233
+ 'user_id': 'user-123',
234
+ 'tenant_id': 'tenant-123',
235
+ 'roles': [],
236
+ 'permissions': [],
237
+ 'email': 'test@example.com',
238
+ 'inboxes': []
239
+ }
240
+ return RequestContext(user_context) # ✅ Return RequestContext
241
+
242
+ @pytest.fixture
243
+ def vote_service(mock_dynamodb, request_context):
244
+ """Vote service for testing."""
245
+ from geek_cafe_saas_sdk.domains.voting.services.vote_service import VoteService
246
+ return VoteService(
247
+ dynamodb=mock_dynamodb,
248
+ table_name="test_table",
249
+ request_context=request_context # ✅ Pass context
250
+ )
251
+ ```
252
+
253
+ ### Key Changes:
254
+ 1. ✅ Import `RequestContext`
255
+ 2. ✅ Rename `user_context` fixture to `request_context`
256
+ 3. ✅ Return `RequestContext(user_context)` instead of dict
257
+ 4. ✅ Add `request_context` parameter to service fixtures
258
+ 5. ✅ Pass `request_context` to service initialization
259
+
260
+ ---
261
+
262
+ ## 4️⃣ Test Files
263
+
264
+ ### File: `tests/test_vote_service.py`
265
+
266
+ #### BEFORE:
267
+ ```python
268
+ def test_create_vote(vote_service, user_context):
269
+ """Test creating a vote."""
270
+ result = vote_service.create(
271
+ tenant_id="tenant-123",
272
+ user_id="user-456",
273
+ user_context=user_context, # ❌ Passed to every test
274
+ target_id="target-1",
275
+ up_vote=1,
276
+ down_vote=0
277
+ )
278
+
279
+ assert result.success is True
280
+ assert result.data.target_id == "target-1"
281
+ assert result.data.created_by == "user-456" # Manual audit trail
282
+
283
+ def test_get_vote_by_id(vote_service, user_context):
284
+ """Test getting a vote by ID."""
285
+ # Create vote first
286
+ create_result = vote_service.create(
287
+ tenant_id="tenant-123",
288
+ user_id="user-456",
289
+ user_context=user_context, # ❌ Repeated
290
+ target_id="target-1",
291
+ up_vote=1
292
+ )
293
+
294
+ # Get vote
295
+ get_result = vote_service.get_by_id(
296
+ resource_id=create_result.data.id,
297
+ tenant_id="tenant-123",
298
+ user_id="user-456",
299
+ user_context=user_context # ❌ Repeated
300
+ )
301
+
302
+ assert get_result.success is True
303
+ ```
304
+
305
+ #### AFTER:
306
+ ```python
307
+ def test_create_vote(vote_service): # ✅ No user_context parameter
308
+ """Test creating a vote."""
309
+ result = vote_service.create(
310
+ tenant_id="tenant-123",
311
+ user_id="user-456",
312
+ # ✅ No user_context - already set in fixture
313
+ target_id="target-1",
314
+ up_vote=1,
315
+ down_vote=0
316
+ )
317
+
318
+ assert result.success is True
319
+ assert result.data.target_id == "target-1"
320
+ assert result.data.created_by == "user-123" # ✅ Automatic from request_context
321
+
322
+ def test_get_vote_by_id(vote_service): # ✅ No user_context parameter
323
+ """Test getting a vote by ID."""
324
+ # Create vote first
325
+ create_result = vote_service.create(
326
+ tenant_id="tenant-123",
327
+ user_id="user-456",
328
+ # ✅ No user_context
329
+ target_id="target-1",
330
+ up_vote=1
331
+ )
332
+
333
+ # Get vote
334
+ get_result = vote_service.get_by_id(
335
+ resource_id=create_result.data.id,
336
+ tenant_id="tenant-123",
337
+ user_id="user-456"
338
+ # ✅ No user_context
339
+ )
340
+
341
+ assert get_result.success is True
342
+ ```
343
+
344
+ ### Key Changes:
345
+ 1. ❌ Remove `user_context` parameter from test functions
346
+ 2. ❌ Remove `user_context=user_context` from all service calls
347
+ 3. ✅ Tests are cleaner and shorter
348
+ 4. ✅ Audit trail (`created_by`) is automatic from `request_context.authenticated_user_id`
349
+
350
+ ---
351
+
352
+ ## 📊 Summary of Changes
353
+
354
+ ### Removed:
355
+ - ❌ `user_context: Dict[str, Any]` parameter from **all** service methods
356
+ - ❌ `user_context` parameter from **all** test functions
357
+ - ❌ Manual `created_by` / `updated_by` assignment
358
+ - ❌ Manual tenant security validation
359
+
360
+ ### Added:
361
+ - ✅ `request_context: RequestContext` to service `__init__()`
362
+ - ✅ `request_context` fixture in tests
363
+ - ✅ `RequestContext` import in handlers
364
+ - ✅ `self.request_context.set_targets()` in service methods
365
+
366
+ ### Automatic:
367
+ - ✅ Tenant access validation in `_save_model()`
368
+ - ✅ Audit trail (`created_by`, `updated_by`)
369
+ - ✅ Security validation in `_get_model_by_id_with_tenant_check()`
370
+
371
+ ---
372
+
373
+ ## ✅ Testing the Migration
374
+
375
+ Run tests after migration:
376
+ ```bash
377
+ pytest tests/test_vote_service.py -v
378
+ ```
379
+
380
+ All tests should pass with the new pattern!
381
+
382
+ ## 🎯 Next Domain to Migrate
383
+
384
+ Use this same pattern for:
385
+ 1. Auth services
386
+ 2. Community services
387
+ 3. Event services
388
+ 4. File services
389
+ 5. Messaging services
390
+ 6. Analytics services
391
+ 7. Tenant services
392
+ 8. Subscription services