geek-cafe-saas-sdk 0.7.4__py3-none-any.whl → 0.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (131) hide show
  1. geek_cafe_saas_sdk/__init__.py +1 -1
  2. geek_cafe_saas_sdk/core/anonymous_context.py +321 -0
  3. geek_cafe_saas_sdk/core/request_context.py +184 -0
  4. geek_cafe_saas_sdk/decorators/__init__.py +1 -1
  5. geek_cafe_saas_sdk/decorators/auth.py +6 -6
  6. geek_cafe_saas_sdk/decorators/core.py +44 -44
  7. geek_cafe_saas_sdk/domains/analytics/services/website_analytics_service.py +1 -3
  8. geek_cafe_saas_sdk/domains/analytics/services/website_analytics_summary_service.py +1 -3
  9. geek_cafe_saas_sdk/domains/analytics/services/website_analytics_tally_service.py +15 -3
  10. geek_cafe_saas_sdk/domains/auth/handlers/users/create/app.py +1 -1
  11. geek_cafe_saas_sdk/domains/auth/handlers/users/delete/app.py +1 -1
  12. geek_cafe_saas_sdk/domains/auth/handlers/users/get/app.py +1 -1
  13. geek_cafe_saas_sdk/domains/auth/handlers/users/list/app.py +1 -1
  14. geek_cafe_saas_sdk/domains/auth/handlers/users/update/app.py +1 -1
  15. geek_cafe_saas_sdk/domains/auth/services/resource_permission_service.py +1 -4
  16. geek_cafe_saas_sdk/domains/auth/services/user_service.py +0 -2
  17. geek_cafe_saas_sdk/domains/communities/handlers/communities/create/app.py +1 -1
  18. geek_cafe_saas_sdk/domains/communities/handlers/communities/delete/app.py +1 -1
  19. geek_cafe_saas_sdk/domains/communities/handlers/communities/get/app.py +1 -1
  20. geek_cafe_saas_sdk/domains/communities/handlers/communities/list/app.py +1 -1
  21. geek_cafe_saas_sdk/domains/communities/handlers/communities/update/app.py +1 -1
  22. geek_cafe_saas_sdk/domains/communities/services/community_member_service.py +1 -3
  23. geek_cafe_saas_sdk/domains/communities/services/community_service.py +3 -3
  24. geek_cafe_saas_sdk/domains/events/handlers/attendees/app.py +1 -1
  25. geek_cafe_saas_sdk/domains/events/handlers/cancel/app.py +1 -1
  26. geek_cafe_saas_sdk/domains/events/handlers/check_in/app.py +1 -1
  27. geek_cafe_saas_sdk/domains/events/handlers/create/app.py +1 -1
  28. geek_cafe_saas_sdk/domains/events/handlers/delete/app.py +1 -1
  29. geek_cafe_saas_sdk/domains/events/handlers/get/app.py +1 -1
  30. geek_cafe_saas_sdk/domains/events/handlers/invite/app.py +1 -1
  31. geek_cafe_saas_sdk/domains/events/handlers/list/app.py +1 -1
  32. geek_cafe_saas_sdk/domains/events/handlers/publish/app.py +1 -1
  33. geek_cafe_saas_sdk/domains/events/handlers/rsvp/app.py +1 -1
  34. geek_cafe_saas_sdk/domains/events/handlers/update/app.py +1 -1
  35. geek_cafe_saas_sdk/domains/events/services/event_attendee_service.py +1 -2
  36. geek_cafe_saas_sdk/domains/events/services/event_service.py +6 -4
  37. geek_cafe_saas_sdk/domains/files/handlers/README.md +1 -1
  38. geek_cafe_saas_sdk/domains/files/handlers/files/create/app.py +1 -1
  39. geek_cafe_saas_sdk/domains/files/handlers/files/download/app.py +1 -1
  40. geek_cafe_saas_sdk/domains/files/handlers/files/get/app.py +1 -1
  41. geek_cafe_saas_sdk/domains/files/handlers/files/list/app.py +1 -1
  42. geek_cafe_saas_sdk/domains/files/handlers/lineage/create_derived/app.py +1 -1
  43. geek_cafe_saas_sdk/domains/files/handlers/lineage/create_main/app.py +1 -1
  44. geek_cafe_saas_sdk/domains/files/handlers/lineage/download_bundle/app.py +1 -1
  45. geek_cafe_saas_sdk/domains/files/handlers/lineage/get_lineage/app.py +1 -1
  46. geek_cafe_saas_sdk/domains/files/handlers/lineage/prepare_bundle/app.py +1 -1
  47. geek_cafe_saas_sdk/domains/files/models/file.py +16 -6
  48. geek_cafe_saas_sdk/domains/files/services/directory_service.py +34 -9
  49. geek_cafe_saas_sdk/domains/files/services/file_system_service.py +38 -3
  50. geek_cafe_saas_sdk/domains/files/services/file_version_service.py +33 -36
  51. geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/create/app.py +1 -1
  52. geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/delete/app.py +1 -1
  53. geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/get/app.py +1 -1
  54. geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/list/app.py +1 -1
  55. geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/update/app.py +1 -1
  56. geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/create/app.py +1 -1
  57. geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/delete/app.py +1 -1
  58. geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/get/app.py +1 -1
  59. geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/list/app.py +1 -1
  60. geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/update/app.py +1 -1
  61. geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/create/app.py +1 -1
  62. geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/delete/app.py +1 -1
  63. geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/get/app.py +1 -1
  64. geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/list/app.py +3 -2
  65. geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/update/app.py +1 -1
  66. geek_cafe_saas_sdk/domains/messaging/services/chat_channel_service.py +35 -2
  67. geek_cafe_saas_sdk/domains/messaging/services/chat_message_service.py +20 -3
  68. geek_cafe_saas_sdk/domains/messaging/services/contact_thread_service.py +1 -3
  69. geek_cafe_saas_sdk/domains/notifications/handlers/create_webhook/app.py +1 -1
  70. geek_cafe_saas_sdk/domains/notifications/handlers/get/app.py +1 -1
  71. geek_cafe_saas_sdk/domains/notifications/handlers/get_preferences/app.py +1 -1
  72. geek_cafe_saas_sdk/domains/notifications/handlers/list/app.py +1 -1
  73. geek_cafe_saas_sdk/domains/notifications/handlers/list_webhooks/app.py +1 -1
  74. geek_cafe_saas_sdk/domains/notifications/handlers/mark_read/app.py +1 -1
  75. geek_cafe_saas_sdk/domains/notifications/handlers/send/app.py +1 -1
  76. geek_cafe_saas_sdk/domains/notifications/handlers/update_preferences/app.py +1 -1
  77. geek_cafe_saas_sdk/domains/notifications/services/notification_service.py +1 -2
  78. geek_cafe_saas_sdk/domains/payments/handlers/billing_accounts/create/app.py +1 -1
  79. geek_cafe_saas_sdk/domains/payments/handlers/billing_accounts/get/app.py +1 -1
  80. geek_cafe_saas_sdk/domains/payments/handlers/billing_accounts/update/app.py +1 -1
  81. geek_cafe_saas_sdk/domains/payments/handlers/payment_intents/create/app.py +1 -1
  82. geek_cafe_saas_sdk/domains/payments/handlers/payment_intents/get/app.py +1 -1
  83. geek_cafe_saas_sdk/domains/payments/handlers/payments/get/app.py +1 -1
  84. geek_cafe_saas_sdk/domains/payments/handlers/payments/list/app.py +1 -1
  85. geek_cafe_saas_sdk/domains/payments/handlers/payments/record/app.py +1 -1
  86. geek_cafe_saas_sdk/domains/payments/handlers/refunds/create/app.py +1 -1
  87. geek_cafe_saas_sdk/domains/payments/handlers/refunds/get/app.py +1 -1
  88. geek_cafe_saas_sdk/domains/payments/services/payment_service.py +1 -2
  89. geek_cafe_saas_sdk/domains/subscriptions/handlers/README.md +2 -2
  90. geek_cafe_saas_sdk/domains/subscriptions/handlers/addons/create/app.py +1 -1
  91. geek_cafe_saas_sdk/domains/subscriptions/handlers/addons/get/app.py +1 -1
  92. geek_cafe_saas_sdk/domains/subscriptions/handlers/addons/list/app.py +1 -1
  93. geek_cafe_saas_sdk/domains/subscriptions/handlers/addons/update/app.py +1 -1
  94. geek_cafe_saas_sdk/domains/subscriptions/handlers/discounts/create/app.py +1 -1
  95. geek_cafe_saas_sdk/domains/subscriptions/handlers/discounts/get/app.py +1 -1
  96. geek_cafe_saas_sdk/domains/subscriptions/handlers/discounts/validate/app.py +1 -1
  97. geek_cafe_saas_sdk/domains/subscriptions/handlers/plans/create/app.py +1 -1
  98. geek_cafe_saas_sdk/domains/subscriptions/handlers/plans/get/app.py +1 -1
  99. geek_cafe_saas_sdk/domains/subscriptions/handlers/plans/list/app.py +1 -1
  100. geek_cafe_saas_sdk/domains/subscriptions/handlers/plans/update/app.py +1 -1
  101. geek_cafe_saas_sdk/domains/subscriptions/handlers/usage/aggregate/app.py +1 -1
  102. geek_cafe_saas_sdk/domains/subscriptions/handlers/usage/record/app.py +1 -1
  103. geek_cafe_saas_sdk/domains/subscriptions/services/subscription_manager_service.py +0 -2
  104. geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/activate/app.py +1 -1
  105. geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/active/app.py +1 -1
  106. geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/cancel/app.py +1 -1
  107. geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/get/app.py +1 -1
  108. geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/list/app.py +1 -1
  109. geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/record_payment/app.py +1 -1
  110. geek_cafe_saas_sdk/domains/tenancy/handlers/tenants/get/app.py +1 -1
  111. geek_cafe_saas_sdk/domains/tenancy/handlers/tenants/me/app.py +1 -1
  112. geek_cafe_saas_sdk/domains/tenancy/handlers/tenants/signup/app.py +1 -1
  113. geek_cafe_saas_sdk/domains/tenancy/handlers/tenants/update/app.py +1 -1
  114. geek_cafe_saas_sdk/domains/tenancy/services/subscription_service.py +3 -3
  115. geek_cafe_saas_sdk/domains/tenancy/services/tenant_service.py +3 -3
  116. geek_cafe_saas_sdk/domains/voting/handlers/votes/delete/app.py +1 -1
  117. geek_cafe_saas_sdk/domains/voting/handlers/votes/get/app.py +1 -1
  118. geek_cafe_saas_sdk/domains/voting/handlers/votes/list/app.py +1 -1
  119. geek_cafe_saas_sdk/domains/voting/handlers/votes/update/app.py +1 -1
  120. geek_cafe_saas_sdk/domains/voting/services/vote_service.py +1 -5
  121. geek_cafe_saas_sdk/domains/voting/services/vote_summary_service.py +1 -5
  122. geek_cafe_saas_sdk/domains/voting/services/vote_tally_service.py +10 -3
  123. geek_cafe_saas_sdk/lambda_handlers/_base/base_handler.py +40 -6
  124. geek_cafe_saas_sdk/lambda_handlers/_base/service_pool.py +157 -12
  125. geek_cafe_saas_sdk/middleware/authorization.py +1 -1
  126. geek_cafe_saas_sdk/middleware/cors.py +8 -8
  127. geek_cafe_saas_sdk/services/database_service.py +76 -5
  128. {geek_cafe_saas_sdk-0.7.4.dist-info → geek_cafe_saas_sdk-0.8.0.dist-info}/METADATA +16 -16
  129. {geek_cafe_saas_sdk-0.7.4.dist-info → geek_cafe_saas_sdk-0.8.0.dist-info}/RECORD +131 -129
  130. {geek_cafe_saas_sdk-0.7.4.dist-info → geek_cafe_saas_sdk-0.8.0.dist-info}/WHEEL +0 -0
  131. {geek_cafe_saas_sdk-0.7.4.dist-info → geek_cafe_saas_sdk-0.8.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,5 @@
1
1
  """
2
- Core Lambda handler decorators for common cross-cutting concerns.
2
+ Core Lambda lambda_handler decorators for common cross-cutting concerns.
3
3
 
4
4
  These decorators handle:
5
5
  - Error handling and standardized error responses
@@ -25,7 +25,7 @@ from geek_cafe_saas_sdk.lambda_handlers._base.service_pool import ServicePool
25
25
  logger = Logger()
26
26
 
27
27
 
28
- def handle_errors(handler: Callable) -> Callable:
28
+ def handle_errors(lambda_handler: Callable) -> Callable:
29
29
  """
30
30
  Catch exceptions and return standardized error responses.
31
31
 
@@ -34,17 +34,17 @@ def handle_errors(handler: Callable) -> Callable:
34
34
 
35
35
  Usage:
36
36
  @handle_errors
37
- def handler(event, context):
37
+ def lambda_handler(event, context):
38
38
  # Any exception becomes a 500 response
39
39
  raise ValueError("Something went wrong")
40
40
 
41
41
  Returns:
42
- Decorated handler that catches exceptions
42
+ Decorated lambda_handler that catches exceptions
43
43
  """
44
- @functools.wraps(handler)
44
+ @functools.wraps(lambda_handler)
45
45
  def wrapper(event: Dict[str, Any], context: Any, *args, **kwargs) -> Dict[str, Any]:
46
46
  try:
47
- return handler(event, context, *args, **kwargs)
47
+ return lambda_handler(event, context, *args, **kwargs)
48
48
  except ValueError as e:
49
49
  # Validation errors -> 400
50
50
  logger.warning(f"Validation error: {e}")
@@ -59,7 +59,7 @@ def handle_errors(handler: Callable) -> Callable:
59
59
  return error_response(f"Missing required field: {str(e)}", "MISSING_FIELD", 400)
60
60
  except Exception as e:
61
61
  # Unexpected errors -> 500
62
- logger.exception(f"Unexpected error in handler: {e}")
62
+ logger.exception(f"Unexpected error in lambda_handler: {e}")
63
63
  return error_response(
64
64
  "An unexpected error occurred",
65
65
  "INTERNAL_ERROR",
@@ -83,21 +83,21 @@ def add_cors(
83
83
 
84
84
  Usage:
85
85
  @add_cors()
86
- def handler(event, context):
86
+ def lambda_handler(event, context):
87
87
  return {'statusCode': 200, 'body': '{}'}
88
88
 
89
89
  # Custom CORS
90
90
  @add_cors(allow_origin="https://example.com")
91
- def handler(event, context):
91
+ def lambda_handler(event, context):
92
92
  return {'statusCode': 200, 'body': '{}'}
93
93
 
94
94
  Returns:
95
- Decorated handler with CORS headers
95
+ Decorated lambda_handler with CORS headers
96
96
  """
97
- def decorator(handler: Callable) -> Callable:
98
- @functools.wraps(handler)
97
+ def decorator(lambda_handler: Callable) -> Callable:
98
+ @functools.wraps(lambda_handler)
99
99
  def wrapper(event: Dict[str, Any], context: Any, *args, **kwargs) -> Dict[str, Any]:
100
- response = handler(event, context, *args, **kwargs)
100
+ response = lambda_handler(event, context, *args, **kwargs)
101
101
 
102
102
  # Ensure headers dict exists
103
103
  if 'headers' not in response:
@@ -129,15 +129,15 @@ def parse_request_body(
129
129
 
130
130
  Usage:
131
131
  @parse_request_body(required=True)
132
- def handler(event, context):
132
+ def lambda_handler(event, context):
133
133
  payload = event['parsed_body']
134
134
  return {'statusCode': 200, 'body': json.dumps(payload)}
135
135
 
136
136
  Returns:
137
- Decorated handler with parsed body in event['parsed_body']
137
+ Decorated lambda_handler with parsed body in event['parsed_body']
138
138
  """
139
- def decorator(handler: Callable) -> Callable:
140
- @functools.wraps(handler)
139
+ def decorator(lambda_handler: Callable) -> Callable:
140
+ @functools.wraps(lambda_handler)
141
141
  def wrapper(event: Dict[str, Any], context: Any, *args, **kwargs) -> Dict[str, Any]:
142
142
  # Check if body is required
143
143
  if required and not event.get('body'):
@@ -166,7 +166,7 @@ def parse_request_body(
166
166
  400
167
167
  )
168
168
 
169
- return handler(event, context, *args, **kwargs)
169
+ return lambda_handler(event, context, *args, **kwargs)
170
170
  return wrapper
171
171
  return decorator
172
172
 
@@ -178,10 +178,10 @@ def inject_service(
178
178
  **service_kwargs
179
179
  ) -> Callable:
180
180
  """
181
- Inject service instance into handler.
181
+ Inject service instance into lambda_handler.
182
182
 
183
183
  Creates and injects a service instance, optionally using connection pooling.
184
- The service is passed as a keyword argument to the handler.
184
+ The service is passed as a keyword argument to the lambda_handler.
185
185
 
186
186
  Args:
187
187
  service_class: Service class to instantiate
@@ -191,23 +191,23 @@ def inject_service(
191
191
 
192
192
  Usage:
193
193
  @inject_service(MessageService)
194
- def handler(event, context, service):
194
+ def lambda_handler(event, context, service):
195
195
  return service.get_by_id(message_id)
196
196
 
197
197
  # Custom parameter name
198
198
  @inject_service(MessageService, param_name="msg_service")
199
- def handler(event, context, msg_service):
199
+ def lambda_handler(event, context, msg_service):
200
200
  return msg_service.get_by_id(message_id)
201
201
 
202
202
  Returns:
203
- Decorated handler with service injected
203
+ Decorated lambda_handler with service injected
204
204
  """
205
205
  # Initialize service pool if using pooling
206
206
  if use_pooling:
207
207
  service_pool = ServicePool(service_class, **service_kwargs)
208
208
 
209
- def decorator(handler: Callable) -> Callable:
210
- @functools.wraps(handler)
209
+ def decorator(lambda_handler: Callable) -> Callable:
210
+ @functools.wraps(lambda_handler)
211
211
  def wrapper(event: Dict[str, Any], context: Any, *args, **kwargs) -> Dict[str, Any]:
212
212
  # Get service from pool or create new instance
213
213
  if use_pooling:
@@ -218,7 +218,7 @@ def inject_service(
218
218
  # Inject service as keyword argument
219
219
  kwargs[param_name] = service
220
220
 
221
- return handler(event, context, *args, **kwargs)
221
+ return lambda_handler(event, context, *args, **kwargs)
222
222
  return wrapper
223
223
  return decorator
224
224
 
@@ -229,7 +229,7 @@ def log_execution(
229
229
  log_duration: bool = True
230
230
  ) -> Callable:
231
231
  """
232
- Log handler execution details.
232
+ Log lambda_handler execution details.
233
233
 
234
234
  Logs request/response details and execution duration for monitoring
235
235
  and debugging purposes.
@@ -241,14 +241,14 @@ def log_execution(
241
241
 
242
242
  Usage:
243
243
  @log_execution(log_response=True)
244
- def handler(event, context):
244
+ def lambda_handler(event, context):
245
245
  return {'statusCode': 200, 'body': '{}'}
246
246
 
247
247
  Returns:
248
- Decorated handler with execution logging
248
+ Decorated lambda_handler with execution logging
249
249
  """
250
- def decorator(handler: Callable) -> Callable:
251
- @functools.wraps(handler)
250
+ def decorator(lambda_handler: Callable) -> Callable:
251
+ @functools.wraps(lambda_handler)
252
252
  def wrapper(event: Dict[str, Any], context: Any, *args, **kwargs) -> Dict[str, Any]:
253
253
  start_time = time.time()
254
254
 
@@ -263,8 +263,8 @@ def log_execution(
263
263
  }
264
264
  )
265
265
 
266
- # Execute handler
267
- response = handler(event, context, *args, **kwargs)
266
+ # Execute lambda_handler
267
+ response = lambda_handler(event, context, *args, **kwargs)
268
268
 
269
269
  duration = time.time() - start_time
270
270
 
@@ -300,16 +300,16 @@ def validate_path_params(required_params: List[str]) -> Callable:
300
300
 
301
301
  Usage:
302
302
  @validate_path_params(['tenant_id', 'user_id', 'message_id'])
303
- def handler(event, context):
303
+ def lambda_handler(event, context):
304
304
  # All required params guaranteed to exist
305
305
  message_id = event['pathParameters']['message_id']
306
306
  return {'statusCode': 200}
307
307
 
308
308
  Returns:
309
- Decorated handler with validated path parameters
309
+ Decorated lambda_handler with validated path parameters
310
310
  """
311
- def decorator(handler: Callable) -> Callable:
312
- @functools.wraps(handler)
311
+ def decorator(lambda_handler: Callable) -> Callable:
312
+ @functools.wraps(lambda_handler)
313
313
  def wrapper(event: Dict[str, Any], context: Any, *args, **kwargs) -> Dict[str, Any]:
314
314
  path_params = event.get('pathParameters', {})
315
315
 
@@ -326,33 +326,33 @@ def validate_path_params(required_params: List[str]) -> Callable:
326
326
  400
327
327
  )
328
328
 
329
- return handler(event, context, *args, **kwargs)
329
+ return lambda_handler(event, context, *args, **kwargs)
330
330
  return wrapper
331
331
  return decorator
332
332
 
333
333
 
334
- def extract_user_context_decorator(handler: Callable) -> Callable:
334
+ def extract_user_context_decorator(lambda_handler: Callable) -> Callable:
335
335
  """
336
336
  Extract user context from JWT and add to event.
337
337
 
338
338
  Extracts user context from API Gateway authorizer and adds it to
339
- event['user_context'] for easy access in handler.
339
+ event['user_context'] for easy access in lambda_handler.
340
340
 
341
341
  Usage:
342
342
  @extract_user_context_decorator
343
- def handler(event, context):
343
+ def lambda_handler(event, context):
344
344
  user_id = event['user_context']['user_id']
345
345
  tenant_id = event['user_context']['tenant_id']
346
346
  return {'statusCode': 200}
347
347
 
348
348
  Returns:
349
- Decorated handler with user_context in event
349
+ Decorated lambda_handler with user_context in event
350
350
  """
351
- @functools.wraps(handler)
351
+ @functools.wraps(lambda_handler)
352
352
  def wrapper(event: Dict[str, Any], context: Any, *args, **kwargs) -> Dict[str, Any]:
353
353
  # Extract user context from authorizer
354
354
  user_context = extract_user_context(event)
355
355
  event['user_context'] = user_context
356
356
 
357
- return handler(event, context, *args, **kwargs)
357
+ return lambda_handler(event, context, *args, **kwargs)
358
358
  return wrapper
@@ -11,9 +11,7 @@ from geek_cafe_saas_sdk.domains.analytics.models import WebsiteAnalytics
11
11
  class WebsiteAnalyticsService(DatabaseService[WebsiteAnalytics]):
12
12
  """Service for WebsiteAnalytics database operations."""
13
13
 
14
- def __init__(self, *, dynamodb: DynamoDB = None, table_name: str = None):
15
- super().__init__(dynamodb=dynamodb, table_name=table_name)
16
-
14
+
17
15
  def create(self, tenant_id: str, user_id: str, **kwargs) -> ServiceResult[WebsiteAnalytics]:
18
16
  """Create a new analytics record."""
19
17
  try:
@@ -10,9 +10,7 @@ from geek_cafe_saas_sdk.domains.analytics.models import WebsiteAnalyticsSummary
10
10
 
11
11
  class WebsiteAnalyticsSummaryService(DatabaseService[WebsiteAnalyticsSummary]):
12
12
  """Service for WebsiteAnalyticsSummary database operations."""
13
-
14
- def __init__(self, *, dynamodb: DynamoDB = None, table_name: str = None):
15
- super().__init__(dynamodb=dynamodb, table_name=table_name)
13
+
16
14
 
17
15
  def create(self, tenant_id: str, user_id: str, **kwargs) -> ServiceResult[WebsiteAnalyticsSummary]:
18
16
  """Create or update (upsert) an analytics summary."""
@@ -4,6 +4,7 @@ from typing import Dict, Any, Optional, List
4
4
  from boto3_assist.dynamodb.dynamodb import DynamoDB
5
5
  from geek_cafe_saas_sdk.core.service_result import ServiceResult
6
6
  from geek_cafe_saas_sdk.core.error_codes import ErrorCode
7
+ from geek_cafe_saas_sdk.core.request_context import RequestContext
7
8
  from .website_analytics_service import WebsiteAnalyticsService
8
9
  from .website_analytics_summary_service import WebsiteAnalyticsSummaryService
9
10
  from geek_cafe_saas_sdk.domains.analytics.models import WebsiteAnalytics, WebsiteAnalyticsSummary
@@ -23,9 +24,20 @@ class WebsiteAnalyticsTallyService:
23
24
  Aggregates raw analytics events into summary records for efficient querying.
24
25
  """
25
26
 
26
- def __init__(self, *, dynamodb: DynamoDB = None, table_name: str = None):
27
- self.analytics_service = WebsiteAnalyticsService(dynamodb=dynamodb, table_name=table_name)
28
- self.summary_service = WebsiteAnalyticsSummaryService(dynamodb=dynamodb, table_name=table_name)
27
+ def __init__(self, *, dynamodb: DynamoDB = None, table_name: str = None,
28
+ request_context: RequestContext):
29
+ """
30
+ Initialize tally service with child services.
31
+
32
+ NOTE: This service keeps custom __init__ because it creates child services.
33
+ Simple services inherit DatabaseService.__init__ directly.
34
+ """
35
+ self.analytics_service = WebsiteAnalyticsService(
36
+ dynamodb=dynamodb, table_name=table_name, request_context=request_context
37
+ )
38
+ self.summary_service = WebsiteAnalyticsSummaryService(
39
+ dynamodb=dynamodb, table_name=table_name, request_context=request_context
40
+ )
29
41
  self.page_size = 100 # Configurable page size for pagination
30
42
 
31
43
  # Pagination monitoring configuration from environment variables
@@ -10,7 +10,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
10
10
 
11
11
  user_service_pool = ServicePool(UserService)
12
12
 
13
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
14
14
  """
15
15
  Lambda handler for creating a new user.
16
16
 
@@ -9,7 +9,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
9
9
 
10
10
  user_service_pool = ServicePool(UserService)
11
11
 
12
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
12
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
13
  """
14
14
  Lambda handler for deleting a user by its ID.
15
15
 
@@ -9,7 +9,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
9
9
 
10
10
  user_service_pool = ServicePool(UserService)
11
11
 
12
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
12
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
13
  """
14
14
  Lambda handler for retrieving a single user by its ID.
15
15
 
@@ -9,7 +9,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
9
9
 
10
10
  user_service_pool = ServicePool(UserService)
11
11
 
12
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
12
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
13
  """
14
14
  Lambda handler for listing users with optional filters.
15
15
 
@@ -10,7 +10,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
10
10
 
11
11
  user_service_pool = ServicePool(UserService)
12
12
 
13
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
14
14
  """
15
15
  Lambda handler for updating an existing user.
16
16
 
@@ -15,10 +15,7 @@ class ResourcePermissionService(DatabaseService[ResourcePermission]):
15
15
  Service for ResourcePermission operations (ABAC).
16
16
 
17
17
  Manages resource-level permission grants for fine-grained sharing.
18
- """
19
-
20
- def __init__(self, *, dynamodb: DynamoDB = None, table_name: str = None):
21
- super().__init__(dynamodb=dynamodb, table_name=table_name)
18
+ """
22
19
 
23
20
  # Required abstract methods from DatabaseService
24
21
  def create(self, tenant_id: str, user_id: str, **kwargs) -> ServiceResult[ResourcePermission]:
@@ -12,8 +12,6 @@ import datetime as dt
12
12
 
13
13
  class UserService(DatabaseService[User]):
14
14
 
15
- def __init__(self, *, dynamodb: DynamoDB = None, table_name: str = None):
16
- super().__init__(dynamodb=dynamodb, table_name=table_name)
17
15
 
18
16
  def create(self, tenant_id: str, user_id: str, **kwargs) -> ServiceResult[User]:
19
17
  """Create a new user."""
@@ -10,7 +10,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
10
10
 
11
11
  community_service_pool = ServicePool(CommunityService)
12
12
 
13
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
14
14
  """
15
15
  Lambda handler for creating a new community.
16
16
 
@@ -9,7 +9,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
9
9
 
10
10
  community_service_pool = ServicePool(CommunityService)
11
11
 
12
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
12
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
13
  """
14
14
  Lambda handler for deleting a community.
15
15
 
@@ -9,7 +9,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
9
9
 
10
10
  community_service_pool = ServicePool(CommunityService)
11
11
 
12
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
12
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
13
  """
14
14
  Lambda handler for getting a community by ID.
15
15
 
@@ -9,7 +9,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
9
9
 
10
10
  community_service_pool = ServicePool(CommunityService)
11
11
 
12
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
12
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
13
  """
14
14
  Lambda handler for listing communities.
15
15
 
@@ -10,7 +10,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
10
10
 
11
11
  community_service_pool = ServicePool(CommunityService)
12
12
 
13
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
14
14
  """
15
15
  Lambda handler for updating a community.
16
16
 
@@ -15,9 +15,7 @@ class CommunityMemberService(DatabaseService[CommunityMember]):
15
15
 
16
16
  Manages scalable membership using adjacent record pattern.
17
17
  """
18
-
19
- def __init__(self, *, dynamodb: DynamoDB = None, table_name: str = None):
20
- super().__init__(dynamodb=dynamodb, table_name=table_name)
18
+
21
19
 
22
20
  # Required abstract methods from DatabaseService
23
21
  def create(self, tenant_id: str, user_id: str, **kwargs) -> ServiceResult[CommunityMember]:
@@ -13,10 +13,10 @@ import datetime as dt
13
13
  class CommunityService(DatabaseService[Community]):
14
14
  """Service for Community database operations."""
15
15
 
16
- def __init__(self, *, dynamodb: DynamoDB = None, table_name: str = None):
17
- super().__init__(dynamodb=dynamodb, table_name=table_name)
16
+ def __init__(self, *, dynamodb: DynamoDB = None, table_name: str = None, request_context: Optional[Dict[str, str]] = None):
17
+ super().__init__(dynamodb=dynamodb, table_name=table_name, request_context=request_context)
18
18
  # Initialize member service with same DB connection
19
- self.member_service = CommunityMemberService(dynamodb=dynamodb, table_name=table_name)
19
+ self.member_service = CommunityMemberService(dynamodb=dynamodb, table_name=table_name, request_context=request_context)
20
20
 
21
21
  def create(self, tenant_id: str, user_id: str, **kwargs) -> ServiceResult[Community]:
22
22
  """Create a new community."""
@@ -9,7 +9,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
9
9
 
10
10
  attendee_service_pool = ServicePool(EventAttendeeService)
11
11
 
12
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
12
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
13
  """
14
14
  Lambda handler for listing event attendees.
15
15
 
@@ -10,7 +10,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
10
10
 
11
11
  event_service_pool = ServicePool(EventService)
12
12
 
13
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
14
14
  """
15
15
  Lambda handler for cancelling an event.
16
16
 
@@ -10,7 +10,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
10
10
 
11
11
  attendee_service_pool = ServicePool(EventAttendeeService)
12
12
 
13
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
14
14
  """
15
15
  Lambda handler for checking in attendees.
16
16
 
@@ -11,7 +11,7 @@ from geek_cafe_saas_sdk.domains.events.models.event import Event
11
11
 
12
12
  event_service_pool = ServicePool(EventService)
13
13
 
14
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
14
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
15
15
  """
16
16
  Lambda handler for creating a new event.
17
17
 
@@ -9,7 +9,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
9
9
 
10
10
  event_service_pool = ServicePool(EventService)
11
11
 
12
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
12
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
13
  """
14
14
  Lambda handler for deleting an event by its ID.
15
15
 
@@ -9,7 +9,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
9
9
 
10
10
  event_service_pool = ServicePool(EventService)
11
11
 
12
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
12
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
13
  """
14
14
  Lambda handler for retrieving a single event by its ID.
15
15
 
@@ -10,7 +10,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
10
10
 
11
11
  attendee_service_pool = ServicePool(EventAttendeeService)
12
12
 
13
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
14
14
  """
15
15
  Lambda handler for inviting user(s) to an event.
16
16
 
@@ -9,7 +9,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
9
9
 
10
10
  event_service_pool = ServicePool(EventService)
11
11
 
12
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
12
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
13
  """
14
14
  Lambda handler for listing events with location-based and other filters.
15
15
 
@@ -9,7 +9,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
9
9
 
10
10
  event_service_pool = ServicePool(EventService)
11
11
 
12
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
12
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
13
  """
14
14
  Lambda handler for publishing a draft event.
15
15
 
@@ -10,7 +10,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
10
10
 
11
11
  attendee_service_pool = ServicePool(EventAttendeeService)
12
12
 
13
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
14
14
  """
15
15
  Lambda handler for updating RSVP status.
16
16
 
@@ -10,7 +10,7 @@ from geek_cafe_saas_sdk.utilities.lambda_event_utility import LambdaEventUtility
10
10
 
11
11
  event_service_pool = ServicePool(EventService)
12
12
 
13
- def handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
13
+ def lambda_handler(event: Dict[str, Any], context: object, injected_service=None) -> Dict[str, Any]:
14
14
  """
15
15
  Lambda handler for updating an existing event.
16
16
 
@@ -13,8 +13,7 @@ import datetime as dt
13
13
  class EventAttendeeService(DatabaseService[EventAttendee]):
14
14
  """Service for EventAttendee database operations (RSVP tracking, invitations, check-in)."""
15
15
 
16
- def __init__(self, *, dynamodb: DynamoDB = None, table_name: str = None):
17
- super().__init__(dynamodb=dynamodb, table_name=table_name)
16
+
18
17
 
19
18
  # Required abstract methods from DatabaseService
20
19
  def create(self, tenant_id: str, user_id: str, **kwargs) -> ServiceResult[EventAttendee]:
@@ -22,9 +22,7 @@ class EventService(DatabaseService[Event]):
22
22
  - Capacity management
23
23
  - Multi-host support via EventAttendee
24
24
  """
25
-
26
- def __init__(self, *, dynamodb: DynamoDB = None, table_name: str = None):
27
- super().__init__(dynamodb=dynamodb, table_name=table_name)
25
+
28
26
 
29
27
  def create(self, tenant_id: str, user_id: str, create_organizer_attendee: bool = True,
30
28
  **kwargs) -> ServiceResult[Event]:
@@ -85,7 +83,11 @@ class EventService(DatabaseService[Event]):
85
83
  if save_result.success and create_organizer_attendee:
86
84
  # Create EventAttendee record for organizer
87
85
  from .event_attendee_service import EventAttendeeService
88
- attendee_service = EventAttendeeService(dynamodb=self.dynamodb, table_name=self.table_name)
86
+ attendee_service = EventAttendeeService(
87
+ dynamodb=self.dynamodb,
88
+ table_name=self.table_name,
89
+ request_context=self._request_context
90
+ )
89
91
 
90
92
  attendee_result = attendee_service.invite(
91
93
  event_id=event.id,
@@ -431,7 +431,7 @@ event = {
431
431
  }
432
432
 
433
433
  # Test
434
- result = app.handler(event, None)
434
+ result = app.lambda_handler(event, None)
435
435
  print(result)
436
436
  ```
437
437
 
@@ -18,7 +18,7 @@ handler_wrapper = create_handler(
18
18
  )
19
19
 
20
20
 
21
- def handler(event: Dict[str, Any], context: Any, injected_service=None) -> Dict[str, Any]:
21
+ def lambda_handler(event: Dict[str, Any], context: Any, injected_service=None) -> Dict[str, Any]:
22
22
  """
23
23
  Upload a new file.
24
24
 
@@ -18,7 +18,7 @@ handler_wrapper = create_handler(
18
18
  )
19
19
 
20
20
 
21
- def handler(event: Dict[str, Any], context: Any, injected_service=None) -> Dict[str, Any]:
21
+ def lambda_handler(event: Dict[str, Any], context: Any, injected_service=None) -> Dict[str, Any]:
22
22
  """
23
23
  Download file content.
24
24