geek-cafe-saas-sdk 0.6.0__tar.gz → 0.7.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 (236) hide show
  1. geek_cafe_saas_sdk-0.7.0/LINEAGE_IMPLEMENTATION_SUMMARY.md +335 -0
  2. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/PKG-INFO +11 -11
  3. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/README.md +10 -10
  4. geek_cafe_saas_sdk-0.7.0/examples/file_lineage_example.py +240 -0
  5. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/pyproject.toml +1 -1
  6. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/__init__.py +2 -2
  7. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/handlers/README.md +446 -0
  8. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/handlers/__init__.py +6 -0
  9. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/handlers/files/create/app.py +121 -0
  10. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/handlers/files/download/app.py +80 -0
  11. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/handlers/files/get/app.py +62 -0
  12. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/handlers/files/list/app.py +72 -0
  13. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/handlers/lineage/create_derived/app.py +99 -0
  14. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/handlers/lineage/create_main/app.py +104 -0
  15. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/handlers/lineage/download_bundle/app.py +99 -0
  16. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/handlers/lineage/get_lineage/app.py +68 -0
  17. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/handlers/lineage/prepare_bundle/app.py +76 -0
  18. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/models/__init__.py +17 -0
  19. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/files/models/file.py +118 -12
  20. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/services/__init__.py +21 -0
  21. geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/files/services/file_lineage_service.py +487 -0
  22. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/files/services/file_system_service.py +27 -1
  23. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/cognito_utility.py +16 -26
  24. geek_cafe_saas_sdk-0.6.0/src/geek_cafe_saas_sdk/domains/voting/__init__.py +0 -0
  25. geek_cafe_saas_sdk-0.6.0/src/geek_cafe_saas_sdk/domains/voting/handlers/__init__.py +0 -0
  26. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/.env.mock +0 -0
  27. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/.gitignore +0 -0
  28. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/.windsurf/rules/cascade.yaml +0 -0
  29. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/ARCHITECTURE.md +0 -0
  30. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/CHANGELOG.md +0 -0
  31. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/CHANGELOG_0.4.1.md +0 -0
  32. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/LICENSE +0 -0
  33. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/README_FILE_SYSTEM_SDK_USAGE.md +0 -0
  34. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/coverage.json +0 -0
  35. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/examples/decorator_pattern_handlers.py +0 -0
  36. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/examples/factory_authorization_example.py +0 -0
  37. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/examples/hierarchical_routing_handler_example.py +0 -0
  38. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/examples/lambda_handler_examples.py +0 -0
  39. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/examples/lambda_handlers/api_key_example.py +0 -0
  40. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/examples/website_analytics_example.py +0 -0
  41. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/lambda_handlers/auth/confirm_forgot_password/app.py +0 -0
  42. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/lambda_handlers/auth/forgot_password/app.py +0 -0
  43. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/lambda_handlers/users/change_password/app.py +0 -0
  44. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/lambda_handlers/users/reset_password/app.py +0 -0
  45. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/publish_to_pypi.py +0 -0
  46. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/publish_to_pypi.sh +0 -0
  47. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/pysetup.py +0 -0
  48. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/pysetup.sh +0 -0
  49. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/requirements.dev.txt +0 -0
  50. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/requirements.txt +0 -0
  51. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/run_unit_tests.sh +0 -0
  52. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/core/__init__.py +0 -0
  53. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/core/audit_mixin.py +0 -0
  54. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/core/error_codes.py +0 -0
  55. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/core/service_errors.py +0 -0
  56. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/core/service_result.py +0 -0
  57. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/decorators/__init__.py +0 -0
  58. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/decorators/auth.py +0 -0
  59. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/decorators/core.py +0 -0
  60. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/__init__.py +0 -0
  61. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/analytics/__init__.py +0 -0
  62. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/analytics/handlers/__init__.py +0 -0
  63. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/analytics/models/__init__.py +0 -0
  64. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/analytics/models/website_analytics.py +0 -0
  65. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/analytics/models/website_analytics_summary.py +0 -0
  66. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/analytics/services/__init__.py +0 -0
  67. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/analytics/services/website_analytics_service.py +0 -0
  68. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/analytics/services/website_analytics_summary_service.py +0 -0
  69. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/analytics/services/website_analytics_tally_service.py +0 -0
  70. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/__init__.py +0 -0
  71. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/handlers/__init__.py +0 -0
  72. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/handlers/users/create/app.py +0 -0
  73. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/handlers/users/delete/app.py +0 -0
  74. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/handlers/users/get/app.py +0 -0
  75. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/handlers/users/list/app.py +0 -0
  76. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/handlers/users/update/app.py +0 -0
  77. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/models/__init__.py +0 -0
  78. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/models/permission.py +0 -0
  79. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/models/resource_permission.py +0 -0
  80. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/models/role.py +0 -0
  81. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/models/user.py +0 -0
  82. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/services/__init__.py +0 -0
  83. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/services/authorization_service.py +0 -0
  84. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/services/permission_registry.py +0 -0
  85. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/services/resource_permission_service.py +0 -0
  86. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/auth/services/user_service.py +0 -0
  87. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/communities/__init__.py +0 -0
  88. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/communities/handlers/__init__.py +0 -0
  89. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/communities/handlers/communities/create/app.py +0 -0
  90. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/communities/handlers/communities/delete/app.py +0 -0
  91. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/communities/handlers/communities/get/app.py +0 -0
  92. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/communities/handlers/communities/list/app.py +0 -0
  93. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/communities/handlers/communities/update/app.py +0 -0
  94. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/communities/models/__init__.py +0 -0
  95. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/communities/models/community.py +0 -0
  96. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/communities/models/community_member.py +0 -0
  97. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/communities/services/__init__.py +0 -0
  98. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/communities/services/community_member_service.py +0 -0
  99. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/communities/services/community_service.py +0 -0
  100. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/__init__.py +0 -0
  101. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/handlers/__init__.py +0 -0
  102. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/handlers/attendees/app.py +0 -0
  103. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/handlers/cancel/app.py +0 -0
  104. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/handlers/check_in/app.py +0 -0
  105. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/handlers/create/app.py +0 -0
  106. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/handlers/delete/app.py +0 -0
  107. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/handlers/get/app.py +0 -0
  108. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/handlers/invite/app.py +0 -0
  109. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/handlers/list/app.py +0 -0
  110. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/handlers/publish/app.py +0 -0
  111. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/handlers/rsvp/app.py +0 -0
  112. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/handlers/update/app.py +0 -0
  113. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/models/__init__.py +0 -0
  114. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/models/event.py +0 -0
  115. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/models/event_attendee.py +0 -0
  116. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/services/__init__.py +0 -0
  117. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/services/event_attendee_service.py +0 -0
  118. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/events/services/event_service.py +0 -0
  119. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/files/__init__.py +0 -0
  120. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/files/models/directory.py +0 -0
  121. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/files/models/file_share.py +0 -0
  122. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/files/models/file_version.py +0 -0
  123. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/files/services/directory_service.py +0 -0
  124. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/files/services/file_share_service.py +0 -0
  125. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/files/services/file_version_service.py +0 -0
  126. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/files/services/s3_file_service.py +0 -0
  127. {geek_cafe_saas_sdk-0.6.0/src/geek_cafe_saas_sdk/domains/files/models → geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/messaging}/__init__.py +0 -0
  128. {geek_cafe_saas_sdk-0.6.0/src/geek_cafe_saas_sdk/domains/files/services → geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/messaging/handlers}/__init__.py +0 -0
  129. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/create/app.py +0 -0
  130. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/delete/app.py +0 -0
  131. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/get/app.py +0 -0
  132. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/list/app.py +0 -0
  133. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_channels/update/app.py +0 -0
  134. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/create/app.py +0 -0
  135. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/delete/app.py +0 -0
  136. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/get/app.py +0 -0
  137. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/list/app.py +0 -0
  138. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/chat_messages/update/app.py +0 -0
  139. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/create/app.py +0 -0
  140. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/delete/app.py +0 -0
  141. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/get/app.py +0 -0
  142. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/list/app.py +0 -0
  143. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/handlers/contact_threads/update/app.py +0 -0
  144. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/models/__init__.py +0 -0
  145. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/models/chat_channel.py +0 -0
  146. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/models/chat_channel_member.py +0 -0
  147. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/models/chat_message.py +0 -0
  148. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/models/contact_thread.py +0 -0
  149. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/services/__init__.py +0 -0
  150. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/services/chat_channel_service.py +0 -0
  151. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/services/chat_message_service.py +0 -0
  152. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/messaging/services/contact_thread_service.py +0 -0
  153. {geek_cafe_saas_sdk-0.6.0/src/geek_cafe_saas_sdk/domains/messaging → geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/tenancy}/__init__.py +0 -0
  154. {geek_cafe_saas_sdk-0.6.0/src/geek_cafe_saas_sdk/domains/messaging → geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/tenancy}/handlers/__init__.py +0 -0
  155. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/activate/app.py +0 -0
  156. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/active/app.py +0 -0
  157. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/cancel/app.py +0 -0
  158. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/get/app.py +0 -0
  159. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/list/app.py +0 -0
  160. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/subscriptions/record_payment/app.py +0 -0
  161. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/tenants/get/app.py +0 -0
  162. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/tenants/me/app.py +0 -0
  163. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/tenants/signup/app.py +0 -0
  164. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/handlers/tenants/update/app.py +0 -0
  165. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/models/__init__.py +0 -0
  166. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/models/subscription.py +0 -0
  167. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/models/tenant.py +0 -0
  168. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/services/__init__.py +0 -0
  169. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/services/subscription_service.py +0 -0
  170. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/tenancy/services/tenant_service.py +0 -0
  171. {geek_cafe_saas_sdk-0.6.0/src/geek_cafe_saas_sdk/domains/tenancy → geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/voting}/__init__.py +0 -0
  172. {geek_cafe_saas_sdk-0.6.0/src/geek_cafe_saas_sdk/domains/tenancy → geek_cafe_saas_sdk-0.7.0/src/geek_cafe_saas_sdk/domains/voting}/handlers/__init__.py +0 -0
  173. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/voting/handlers/votes/create/app.py +0 -0
  174. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/voting/handlers/votes/delete/app.py +0 -0
  175. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/voting/handlers/votes/get/app.py +0 -0
  176. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/voting/handlers/votes/list/app.py +0 -0
  177. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/voting/handlers/votes/summerize/README.md +0 -0
  178. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/voting/handlers/votes/update/app.py +0 -0
  179. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/voting/models/__init__.py +0 -0
  180. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/voting/models/vote.py +0 -0
  181. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/voting/models/vote_summary.py +0 -0
  182. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/voting/services/__init__.py +0 -0
  183. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/voting/services/vote_service.py +0 -0
  184. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/voting/services/vote_summary_service.py +0 -0
  185. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/domains/voting/services/vote_tally_service.py +0 -0
  186. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/README.md +0 -0
  187. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/__init__.py +0 -0
  188. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/__init__.py +0 -0
  189. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/api_key_handler.py +0 -0
  190. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/authorized_secure_handler.py +0 -0
  191. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/base_handler.py +0 -0
  192. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/handler_factory.py +0 -0
  193. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/public_handler.py +0 -0
  194. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/secure_handler.py +0 -0
  195. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/_base/service_pool.py +0 -0
  196. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/directories/create/app.py +0 -0
  197. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/directories/delete/app.py +0 -0
  198. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/directories/get/app.py +0 -0
  199. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/directories/list/app.py +0 -0
  200. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/directories/move/app.py +0 -0
  201. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/delete/app.py +0 -0
  202. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/download/app.py +0 -0
  203. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/get/app.py +0 -0
  204. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/list/app.py +0 -0
  205. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/share/app.py +0 -0
  206. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/shares/list/app.py +0 -0
  207. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/shares/revoke/app.py +0 -0
  208. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/update/app.py +0 -0
  209. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/lambda_handlers/files/upload/app.py +0 -0
  210. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/middleware/__init__.py +0 -0
  211. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/middleware/auth.py +0 -0
  212. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/middleware/authorization.py +0 -0
  213. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/middleware/cors.py +0 -0
  214. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/middleware/error_handling.py +0 -0
  215. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/middleware/validation.py +0 -0
  216. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/models/__init__.py +0 -0
  217. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/models/base_model.py +0 -0
  218. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/services/__init__.py +0 -0
  219. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/services/database_service.py +0 -0
  220. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/__init__.py +0 -0
  221. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/custom_exceptions.py +0 -0
  222. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/datetime_utility.py +0 -0
  223. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/dictionary_utility.py +0 -0
  224. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/dynamodb_utils.py +0 -0
  225. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/environment_loader.py +0 -0
  226. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/environment_variables.py +0 -0
  227. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/http_body_parameters.py +0 -0
  228. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/http_path_parameters.py +0 -0
  229. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/http_status_code.py +0 -0
  230. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/jwt_utility.py +0 -0
  231. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/lambda_event_utility.py +0 -0
  232. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/logging_utility.py +0 -0
  233. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/message_query_helper.py +0 -0
  234. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/response.py +0 -0
  235. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/src/geek_cafe_saas_sdk/utilities/string_functions.py +0 -0
  236. {geek_cafe_saas_sdk-0.6.0 → geek_cafe_saas_sdk-0.7.0}/update_readme_badges.py +0 -0
@@ -0,0 +1,335 @@
1
+ # File Lineage Implementation Summary
2
+
3
+ ## Overview
4
+
5
+ File lineage tracking has been successfully implemented in the Geek Cafe SaaS SDK. This feature allows tracking of file transformations through data processing pipelines.
6
+
7
+ **Implementation Date:** October 2025
8
+
9
+ ---
10
+
11
+ ## What Was Added
12
+
13
+ ### 1. File Model Extensions
14
+
15
+ **File:** `src/geek_cafe_saas_sdk/domains/files/models/file.py`
16
+
17
+ **New Fields:**
18
+ - `file_role`: str - Role in lineage chain ("standalone", "original", "main", "derived")
19
+ - `original_file_id`: str | None - Root file in lineage chain
20
+ - `parent_file_id`: str | None - Immediate parent file
21
+ - `transformation_type`: str | None - Type of transformation ("convert", "clean", "process")
22
+ - `transformation_operation`: str | None - Specific operation name
23
+ - `transformation_metadata`: dict | None - Additional operation details
24
+ - `derived_file_count`: int - Number of files derived from this one
25
+
26
+ **New Properties:**
27
+ - All fields have getter/setter properties with validation
28
+
29
+ **New Helper Methods:**
30
+ - `has_lineage()` - Check if file participates in lineage
31
+ - `is_original()` - Check if this is an original file
32
+ - `is_main()` - Check if this is a main file
33
+ - `is_derived()` - Check if this is a derived file
34
+ - `is_standalone()` - Check if this is a standalone file (no lineage)
35
+ - `increment_derived_count()` - Increment derived file counter
36
+
37
+ ---
38
+
39
+ ### 2. FileLineageService
40
+
41
+ **File:** `src/geek_cafe_saas_sdk/domains/files/services/file_lineage_service.py`
42
+
43
+ **Purpose:** Helper service for managing file lineage and transformations.
44
+
45
+ **Methods:**
46
+
47
+ #### `create_main_file()`
48
+ Create a main file from an original file (e.g., XLS → CSV conversion).
49
+
50
+ **Parameters:**
51
+ - `tenant_id`, `user_id`, `original_file_id`
52
+ - `file_name`, `file_data`, `mime_type`
53
+ - `transformation_operation`, `transformation_metadata`
54
+ - `directory_id` (optional)
55
+
56
+ **Returns:** ServiceResult with main File
57
+
58
+ #### `create_derived_file()`
59
+ Create a derived file from a main file (e.g., data cleaning).
60
+
61
+ **Parameters:**
62
+ - `tenant_id`, `user_id`, `main_file_id`
63
+ - `file_name`, `file_data`
64
+ - `transformation_operation`, `transformation_metadata`
65
+ - `directory_id` (optional)
66
+
67
+ **Returns:** ServiceResult with derived File
68
+
69
+ **Note:** Derived files are ALWAYS created from main files (non-chained).
70
+
71
+ #### `get_lineage()`
72
+ Get complete lineage for a file.
73
+
74
+ **Returns:** Dictionary with:
75
+ - `selected`: The selected file
76
+ - `main`: Main file (if exists)
77
+ - `original`: Original file (if exists)
78
+ - `all_derived`: List of all derived files (if viewing main)
79
+
80
+ #### `list_derived_files()`
81
+ List all files derived from a main file.
82
+
83
+ **Returns:** ServiceResult with list of derived Files
84
+
85
+ #### `prepare_lineage_bundle()`
86
+ Prepare bundle of files for lineage (selected, main, original).
87
+
88
+ **Returns:** Dictionary with files and transformation chain metadata
89
+
90
+ #### `download_lineage_bundle()`
91
+ Download all files in lineage chain with their data.
92
+
93
+ **Returns:** Dictionary with file objects and binary data
94
+
95
+ ---
96
+
97
+ ### 3. FileSystemService Updates
98
+
99
+ **File:** `src/geek_cafe_saas_sdk/domains/files/services/file_system_service.py`
100
+
101
+ **Changes to `create()` method:**
102
+
103
+ Added optional lineage parameters:
104
+ - `file_role`
105
+ - `parent_file_id`
106
+ - `original_file_id`
107
+ - `transformation_type`
108
+ - `transformation_operation`
109
+ - `transformation_metadata`
110
+
111
+ These parameters are set on the File model when provided.
112
+
113
+ ---
114
+
115
+ ### 4. Service Exports
116
+
117
+ **File:** `src/geek_cafe_saas_sdk/domains/files/services/__init__.py`
118
+
119
+ Added export for `FileLineageService` along with existing services:
120
+ - FileSystemService
121
+ - DirectoryService
122
+ - FileVersionService
123
+ - FileShareService
124
+ - S3FileService
125
+ - **FileLineageService** (NEW)
126
+
127
+ ---
128
+
129
+ ### 5. Model Exports
130
+
131
+ **File:** `src/geek_cafe_saas_sdk/domains/files/models/__init__.py`
132
+
133
+ Added exports for all file models:
134
+ - File
135
+ - Directory
136
+ - FileVersion
137
+ - FileShare
138
+
139
+ ---
140
+
141
+ ### 6. Example Code
142
+
143
+ **File:** `examples/file_lineage_example.py`
144
+
145
+ Complete working example demonstrating:
146
+ 1. Upload original file
147
+ 2. Convert to main file
148
+ 3. Create derived files (data cleaning)
149
+ 4. Query lineage
150
+ 5. Prepare lineage bundle
151
+ 6. Download complete bundle
152
+
153
+ ---
154
+
155
+ ## Usage Example
156
+
157
+ ```python
158
+ from geek_cafe_saas_sdk.domains.files.services import (
159
+ FileSystemService,
160
+ S3FileService,
161
+ FileLineageService
162
+ )
163
+
164
+ # Initialize services
165
+ file_service = FileSystemService(...)
166
+ lineage_service = FileLineageService(
167
+ file_service=file_service,
168
+ s3_service=s3_service
169
+ )
170
+
171
+ # 1. Upload original file
172
+ original = file_service.create(
173
+ tenant_id="tenant-123",
174
+ user_id="user-456",
175
+ file_name="data.xls",
176
+ file_data=xls_bytes,
177
+ mime_type="application/vnd.ms-excel",
178
+ file_role="original" # Mark as original
179
+ )
180
+
181
+ # 2. Convert to main file
182
+ main = lineage_service.create_main_file(
183
+ tenant_id="tenant-123",
184
+ user_id="user-456",
185
+ original_file_id=original.data.file_id,
186
+ file_name="data.csv",
187
+ file_data=csv_bytes,
188
+ mime_type="text/csv",
189
+ transformation_operation="xls_to_csv"
190
+ )
191
+
192
+ # 3. Create derived files (cleaning)
193
+ for version in range(1, 55):
194
+ cleaned = lineage_service.create_derived_file(
195
+ tenant_id="tenant-123",
196
+ user_id="user-456",
197
+ main_file_id=main.data.file_id,
198
+ file_name=f"data_clean_v{version}.csv",
199
+ file_data=cleaned_bytes,
200
+ transformation_operation=f"data_cleaning_v{version}"
201
+ )
202
+
203
+ # 4. Get lineage for lineage
204
+ lineage = lineage_service.get_lineage(
205
+ file_id="cleaned_v54_id",
206
+ tenant_id="tenant-123",
207
+ user_id="user-456"
208
+ )
209
+
210
+ # 5. Prepare bundle (selected, main, original)
211
+ bundle = lineage_service.prepare_lineage_bundle(
212
+ selected_file_id="cleaned_v54_id",
213
+ tenant_id="tenant-123",
214
+ user_id="user-456"
215
+ )
216
+
217
+ # Use bundle.data['selected_file'], bundle.data['main_file'], etc.
218
+ ```
219
+
220
+ ---
221
+
222
+ ## Key Features
223
+
224
+ ### ✅ Non-Chained Transformations
225
+ Derived files are ALWAYS created from the main file, never from other derived files. This matches your exact use case.
226
+
227
+ ### ✅ Seamless Integration
228
+ Files with and without lineage work together. Lineage is optional.
229
+
230
+ ### ✅ Backward Compatible
231
+ Existing files automatically have `file_role="standalone"`. No migration needed.
232
+
233
+ ### ✅ Included in Queries
234
+ When listing files, lineage information is automatically present on each file object.
235
+
236
+ ### ✅ Complete Audit Trail
237
+ Track every transformation with operation names and metadata.
238
+
239
+ ---
240
+
241
+ ## Architecture
242
+
243
+ ```
244
+ Original File (data.xls)
245
+ ↓ convert
246
+ Main File (data.csv)
247
+ ↓ clean (not chained)
248
+ ├── Derived v1
249
+ ├── Derived v2
250
+ ├── Derived v3
251
+ └── Derived v54
252
+
253
+ User selects v54 → System bundles: v54 + main + original
254
+ ```
255
+
256
+ ---
257
+
258
+ ## Files Modified/Created
259
+
260
+ ### Modified:
261
+ 1. `src/geek_cafe_saas_sdk/domains/files/models/file.py` - Added lineage fields
262
+ 2. `src/geek_cafe_saas_sdk/domains/files/services/file_system_service.py` - Added lineage parameters
263
+ 3. `src/geek_cafe_saas_sdk/domains/files/services/__init__.py` - Added exports
264
+ 4. `src/geek_cafe_saas_sdk/domains/files/models/__init__.py` - Added exports
265
+
266
+ ### Created:
267
+ 1. `src/geek_cafe_saas_sdk/domains/files/services/file_lineage_service.py` - New service
268
+ 2. `examples/file_lineage_example.py` - Usage example
269
+ 3. `docs/help/file-system/07-file-lineage.md` - User guide
270
+ 4. `docs/help/file-system/08-lineage-implementation.md` - Implementation guide
271
+ 5. `LINEAGE_IMPLEMENTATION_SUMMARY.md` - This file
272
+
273
+ ---
274
+
275
+ ## Documentation
276
+
277
+ Complete documentation added to `docs/help/file-system/`:
278
+
279
+ 1. **07-file-lineage.md** - User guide for file lineage
280
+ - Concepts and use cases
281
+ - Creating lineage chains
282
+ - Querying lineage
283
+ - Bundling for lineage
284
+ - UI integration examples
285
+
286
+ 2. **08-lineage-implementation.md** - Implementation guide
287
+ - Architecture decision
288
+ - Complete code for File model extensions
289
+ - Complete FileLineageService implementation
290
+ - Usage examples
291
+ - Migration guide
292
+
293
+ ---
294
+
295
+ ## Testing Recommendations
296
+
297
+ 1. **Unit Tests** - Test FileLineageService methods
298
+ - `create_main_file()` with valid/invalid original files
299
+ - `create_derived_file()` with valid/invalid main files
300
+ - `get_lineage()` with various file roles
301
+ - `list_derived_files()` with multiple versions
302
+
303
+ 2. **Integration Tests** - Test full pipeline
304
+ - Upload → Convert → Clean → Bundle
305
+ - Verify lineage relationships
306
+ - Verify bundle contents
307
+
308
+ 3. **Edge Cases**
309
+ - Creating main from non-original file (should fail)
310
+ - Creating derived from non-main file (should fail)
311
+ - Getting lineage for standalone file
312
+ - Getting lineage for file with missing parent/original
313
+
314
+ ---
315
+
316
+ ## Next Steps
317
+
318
+ 1. **Run Tests** - Ensure all tests pass with new fields
319
+ 2. **Update Database** - No migration needed (fields have defaults)
320
+ 3. **Deploy** - Deploy updated code to your environment
321
+ 4. **Monitor** - Monitor file creation with lineage fields
322
+ 5. **Document Internal** - Add to your internal docs/wikis
323
+
324
+ ---
325
+
326
+ ## Support
327
+
328
+ For questions or issues:
329
+ - Review `docs/help/file-system/07-file-lineage.md`
330
+ - Check `examples/file_lineage_example.py`
331
+ - See `docs/help/file-system/08-lineage-implementation.md`
332
+
333
+ ---
334
+
335
+ **Implementation Status:** ✅ Complete and Ready for Testing
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geek_cafe_saas_sdk
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: Base Reusable Services for SaaS
5
5
  Project-URL: Homepage, https://github.com/geekcafe/geek-cafe-services
6
6
  Project-URL: Documentation, https://github.com/geekcafe/geek-cafe-services/blob/main/README.md
@@ -87,20 +87,20 @@ Description-Content-Type: text/markdown
87
87
  <!-- COVERAGE-BADGE:START -->
88
88
  ## Test Coverage
89
89
 
90
- ![Tests](https://img.shields.io/badge/tests-1127%20passed-brightgreen)
91
- ![Coverage](https://img.shields.io/badge/coverage-82.9%25-green)
90
+ ![Tests](https://img.shields.io/badge/tests-1145%20passed-brightgreen)
91
+ ![Coverage](https://img.shields.io/badge/coverage-83.1%25-green)
92
92
 
93
- **Overall Coverage:** 82.9% (9325/11242 statements)
93
+ **Overall Coverage:** 83.1% (9646/11611 statements)
94
94
 
95
95
  ### Coverage Summary
96
96
 
97
97
  | Metric | Value |
98
98
  |--------|-------|
99
- | Total Statements | 11,242 |
100
- | Covered Statements | 9,325 |
101
- | Missing Statements | 1,917 |
102
- | Coverage Percentage | 82.9% |
103
- | Total Tests | 1127 |
99
+ | Total Statements | 11,611 |
100
+ | Covered Statements | 9,646 |
101
+ | Missing Statements | 1,965 |
102
+ | Coverage Percentage | 83.1% |
103
+ | Total Tests | 1145 |
104
104
  | Test Status | ✅ All Passing |
105
105
 
106
106
  ### Files Needing Attention (< 80% coverage)
@@ -118,7 +118,7 @@ Description-Content-Type: text/markdown
118
118
  | 63.4% | 86 | `domains/communities/services/community_service.py` |
119
119
  | 64.0% | 41 | `domains/files/services/s3_file_service.py` |
120
120
 
121
- *... and 20 more files with < 80% coverage*
121
+ *... and 22 more files with < 80% coverage*
122
122
 
123
123
  ### Running Tests
124
124
 
@@ -130,7 +130,7 @@ Description-Content-Type: text/markdown
130
130
  open reports/coverage/index.html
131
131
  ```
132
132
 
133
- *Last updated: 2025-10-15 22:38:06*
133
+ *Last updated: 2025-10-16 13:22:11*
134
134
 
135
135
  ---
136
136
 
@@ -12,20 +12,20 @@
12
12
  <!-- COVERAGE-BADGE:START -->
13
13
  ## Test Coverage
14
14
 
15
- ![Tests](https://img.shields.io/badge/tests-1127%20passed-brightgreen)
16
- ![Coverage](https://img.shields.io/badge/coverage-82.9%25-green)
15
+ ![Tests](https://img.shields.io/badge/tests-1145%20passed-brightgreen)
16
+ ![Coverage](https://img.shields.io/badge/coverage-83.1%25-green)
17
17
 
18
- **Overall Coverage:** 82.9% (9325/11242 statements)
18
+ **Overall Coverage:** 83.1% (9646/11611 statements)
19
19
 
20
20
  ### Coverage Summary
21
21
 
22
22
  | Metric | Value |
23
23
  |--------|-------|
24
- | Total Statements | 11,242 |
25
- | Covered Statements | 9,325 |
26
- | Missing Statements | 1,917 |
27
- | Coverage Percentage | 82.9% |
28
- | Total Tests | 1127 |
24
+ | Total Statements | 11,611 |
25
+ | Covered Statements | 9,646 |
26
+ | Missing Statements | 1,965 |
27
+ | Coverage Percentage | 83.1% |
28
+ | Total Tests | 1145 |
29
29
  | Test Status | ✅ All Passing |
30
30
 
31
31
  ### Files Needing Attention (< 80% coverage)
@@ -43,7 +43,7 @@
43
43
  | 63.4% | 86 | `domains/communities/services/community_service.py` |
44
44
  | 64.0% | 41 | `domains/files/services/s3_file_service.py` |
45
45
 
46
- *... and 20 more files with < 80% coverage*
46
+ *... and 22 more files with < 80% coverage*
47
47
 
48
48
  ### Running Tests
49
49
 
@@ -55,7 +55,7 @@
55
55
  open reports/coverage/index.html
56
56
  ```
57
57
 
58
- *Last updated: 2025-10-15 22:38:06*
58
+ *Last updated: 2025-10-16 13:22:11*
59
59
 
60
60
  ---
61
61
 
@@ -0,0 +1,240 @@
1
+ """
2
+ Example: Using File Lineage System
3
+
4
+ This example demonstrates how to track file transformations through
5
+ a data processing pipeline.
6
+
7
+ Geek Cafe, LLC
8
+ MIT License. See Project Root for the license information.
9
+ """
10
+
11
+ from boto3_assist.dynamodb.dynamodb import DynamoDB
12
+ from boto3_assist.s3.s3_connection import S3Connection
13
+ from boto3_assist.s3.s3_object import S3Object
14
+ from boto3_assist.s3.s3_bucket import S3Bucket
15
+
16
+ from geek_cafe_saas_sdk.domains.files.services import (
17
+ FileSystemService,
18
+ S3FileService,
19
+ FileLineageService
20
+ )
21
+
22
+
23
+ def setup_services():
24
+ """Initialize file system services."""
25
+ db = DynamoDB()
26
+ connection = S3Connection()
27
+
28
+ s3_service = S3FileService(
29
+ s3_object=S3Object(connection=connection),
30
+ s3_bucket=S3Bucket(connection=connection),
31
+ default_bucket="my-files-bucket"
32
+ )
33
+
34
+ file_service = FileSystemService(
35
+ dynamodb=db,
36
+ table_name="files-table",
37
+ s3_service=s3_service,
38
+ default_bucket="my-files-bucket"
39
+ )
40
+
41
+ lineage_service = FileLineageService(
42
+ file_service=file_service,
43
+ s3_service=s3_service
44
+ )
45
+
46
+ return file_service, lineage_service
47
+
48
+
49
+ def example_data_pipeline():
50
+ """
51
+ Example: Data processing pipeline with lineage tracking.
52
+
53
+ Flow:
54
+ 1. User uploads original file (measurements.xls)
55
+ 2. System converts to main file (measurements.csv)
56
+ 3. Data cleaning produces derived files (v1, v2, v3...)
57
+ 4. User selects derived file for lineage
58
+ 5. System bundles selected + main + original
59
+ """
60
+
61
+ file_service, lineage_service = setup_services()
62
+
63
+ tenant_id = "tenant-123"
64
+ user_id = "user-456"
65
+
66
+ # Step 1: Upload original file
67
+ print("Step 1: Uploading original file...")
68
+ with open("measurements.xls", "rb") as f:
69
+ xls_data = f.read()
70
+
71
+ original_result = file_service.create(
72
+ tenant_id=tenant_id,
73
+ user_id=user_id,
74
+ file_name="measurements.xls",
75
+ file_data=xls_data,
76
+ mime_type="application/vnd.ms-excel",
77
+ file_role="original" # Mark as original
78
+ )
79
+
80
+ if not original_result.success:
81
+ print(f"Error: {original_result.message}")
82
+ return
83
+
84
+ original_file = original_result.data
85
+ print(f"✓ Original file uploaded: {original_file.file_id}")
86
+
87
+ # Step 2: Convert to main file (XLS → CSV)
88
+ print("\nStep 2: Converting to CSV...")
89
+
90
+ # Simulate conversion (replace with actual conversion logic)
91
+ csv_data = convert_xls_to_csv(xls_data)
92
+
93
+ main_result = lineage_service.create_main_file(
94
+ tenant_id=tenant_id,
95
+ user_id=user_id,
96
+ original_file_id=original_file.file_id,
97
+ file_name="measurements.csv",
98
+ file_data=csv_data,
99
+ mime_type="text/csv",
100
+ transformation_operation="xls_to_csv",
101
+ transformation_metadata={
102
+ 'converter_version': '1.0',
103
+ 'source_format': 'xls',
104
+ 'target_format': 'csv'
105
+ }
106
+ )
107
+
108
+ if not main_result.success:
109
+ print(f"Error: {main_result.message}")
110
+ return
111
+
112
+ main_file = main_result.data
113
+ print(f"✓ Main file created: {main_file.file_id}")
114
+ print(f" Role: {main_file.file_role}")
115
+ print(f" Operation: {main_file.transformation_operation}")
116
+
117
+ # Step 3: Create derived files (data cleaning)
118
+ print("\nStep 3: Creating cleaned versions...")
119
+
120
+ derived_files = []
121
+ for version in range(1, 4):
122
+ # Simulate data cleaning
123
+ cleaned_data = perform_data_cleaning(csv_data, version)
124
+
125
+ derived_result = lineage_service.create_derived_file(
126
+ tenant_id=tenant_id,
127
+ user_id=user_id,
128
+ main_file_id=main_file.file_id,
129
+ file_name=f"measurements_clean_v{version}.csv",
130
+ file_data=cleaned_data,
131
+ transformation_operation=f"data_cleaning_v{version}",
132
+ transformation_metadata={
133
+ 'cleaning_version': version,
134
+ 'operations': ['remove_nulls', 'normalize_units'],
135
+ 'rows_processed': 1000
136
+ }
137
+ )
138
+
139
+ if derived_result.success:
140
+ derived_file = derived_result.data
141
+ derived_files.append(derived_file)
142
+ print(f"✓ Derived v{version} created: {derived_file.file_id}")
143
+
144
+ # Step 4: Get lineage for a derived file
145
+ print("\nStep 4: Getting lineage for derived v2...")
146
+
147
+ selected_file_id = derived_files[1].file_id # v2
148
+ lineage_result = lineage_service.get_lineage(
149
+ file_id=selected_file_id,
150
+ tenant_id=tenant_id,
151
+ user_id=user_id
152
+ )
153
+
154
+ if lineage_result.success:
155
+ lineage = lineage_result.data
156
+ print(f"Selected: {lineage['selected'].file_name}")
157
+ print(f"Main: {lineage['main'].file_name}")
158
+ print(f"Original: {lineage['original'].file_name}")
159
+ print(f"All derived versions: {len(lineage['all_derived'])}")
160
+
161
+ # Step 5: Prepare lineage bundle
162
+ print("\nStep 5: Preparing lineage bundle...")
163
+
164
+ bundle_result = lineage_service.prepare_lineage_bundle(
165
+ selected_file_id=selected_file_id,
166
+ tenant_id=tenant_id,
167
+ user_id=user_id
168
+ )
169
+
170
+ if bundle_result.success:
171
+ bundle = bundle_result.data
172
+ print("Bundle contents:")
173
+ print(f" - Selected: {bundle['selected_file'].file_name}")
174
+ print(f" - Main: {bundle['main_file'].file_name}")
175
+ print(f" - Original: {bundle['original_file'].file_name}")
176
+ print(f"\nTransformation chain:")
177
+ for step in bundle['metadata']['transformation_chain']:
178
+ print(f" {step['step']}. {step['type']}: {step['file_name']}")
179
+ if 'operation' in step:
180
+ print(f" Operation: {step['operation']}")
181
+
182
+ # Step 6: Download complete bundle
183
+ print("\nStep 6: Downloading complete bundle...")
184
+
185
+ download_result = lineage_service.download_lineage_bundle(
186
+ selected_file_id=selected_file_id,
187
+ tenant_id=tenant_id,
188
+ user_id=user_id
189
+ )
190
+
191
+ if download_result.success:
192
+ download_bundle = download_result.data
193
+
194
+ # Save each file
195
+ if download_bundle['original']:
196
+ save_file('output/original/', download_bundle['original'])
197
+
198
+ if download_bundle['main']:
199
+ save_file('output/main/', download_bundle['main'])
200
+
201
+ if download_bundle['selected']:
202
+ save_file('output/processed/', download_bundle['selected'])
203
+
204
+ print("✓ Bundle downloaded successfully!")
205
+
206
+
207
+ def convert_xls_to_csv(xls_data: bytes) -> bytes:
208
+ """Simulate XLS to CSV conversion."""
209
+ # In production, use a library like openpyxl or pandas
210
+ # For example:
211
+ # import pandas as pd
212
+ # df = pd.read_excel(io.BytesIO(xls_data))
213
+ # return df.to_csv().encode('utf-8')
214
+
215
+ return b"mock,csv,data\n1,2,3\n4,5,6"
216
+
217
+
218
+ def perform_data_cleaning(csv_data: bytes, version: int) -> bytes:
219
+ """Simulate data cleaning."""
220
+ # In production, implement actual cleaning logic
221
+ # For example: remove nulls, normalize units, etc.
222
+
223
+ return csv_data + f"\n# Cleaned v{version}".encode('utf-8')
224
+
225
+
226
+ def save_file(directory: str, file_bundle: dict):
227
+ """Save file to disk."""
228
+ import os
229
+
230
+ os.makedirs(directory, exist_ok=True)
231
+
232
+ file_path = os.path.join(directory, file_bundle['file'].file_name)
233
+ with open(file_path, 'wb') as f:
234
+ f.write(file_bundle['data'])
235
+
236
+ print(f" Saved: {file_path}")
237
+
238
+
239
+ if __name__ == "__main__":
240
+ example_data_pipeline()
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "geek_cafe_saas_sdk"
3
- version = "0.6.0"
3
+ version = "0.7.0"
4
4
  description = "Base Reusable Services for SaaS"
5
5
  authors = [{ name = "Eric Wilson", email = "eric.wilson@geekcafe.com" }]
6
6
  requires-python = ">=3.8"
@@ -1,9 +1,9 @@
1
1
  """
2
2
  Geek Cafe Services - Base Reusable Services for SaaS
3
3
 
4
- Version 0.2.0 adds Lambda Handler Wrappers for reducing boilerplate code.
4
+ Version 0.6.0 adds File System Service
5
5
  """
6
- __version__ = "0.6.0"
6
+ __version__ = "0.7.0"
7
7
 
8
8
  # Import main modules for easier access
9
9
  from . import services