tempest-fastapi-sdk 0.34.0__tar.gz → 0.36.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.
Files changed (362) hide show
  1. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/CHANGELOG.md +155 -0
  2. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/PKG-INFO +9 -5
  3. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/README.md +5 -4
  4. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/installation.en.md +1 -0
  5. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/installation.md +1 -0
  6. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/admin.en.md +25 -3
  7. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/admin.md +25 -3
  8. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/auth-flow.en.md +2 -1
  9. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/auth-flow.md +2 -1
  10. tempest_fastapi_sdk-0.36.0/docs/recipes/mfa.en.md +319 -0
  11. tempest_fastapi_sdk-0.36.0/docs/recipes/mfa.md +319 -0
  12. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/reference.md +10 -0
  13. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/roadmap.en.md +28 -4
  14. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/roadmap.md +28 -4
  15. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/mkdocs.yml +2 -0
  16. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/pyproject.toml +12 -1
  17. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/__init__.py +17 -1
  18. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/admin/auth.py +85 -1
  19. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/admin/config.py +31 -0
  20. tempest_fastapi_sdk-0.36.0/tempest_fastapi_sdk/admin/forms.py +363 -0
  21. tempest_fastapi_sdk-0.36.0/tempest_fastapi_sdk/admin/router.py +1492 -0
  22. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/admin/session.py +17 -1
  23. tempest_fastapi_sdk-0.36.0/tempest_fastapi_sdk/admin/static/admin.css +642 -0
  24. tempest_fastapi_sdk-0.36.0/tempest_fastapi_sdk/admin/templates/dashboard.html +47 -0
  25. tempest_fastapi_sdk-0.36.0/tempest_fastapi_sdk/admin/templates/detail.html +44 -0
  26. tempest_fastapi_sdk-0.36.0/tempest_fastapi_sdk/admin/templates/form.html +53 -0
  27. tempest_fastapi_sdk-0.36.0/tempest_fastapi_sdk/admin/templates/list.html +110 -0
  28. tempest_fastapi_sdk-0.36.0/tempest_fastapi_sdk/admin/templates/mfa.html +20 -0
  29. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/auth/__init__.py +10 -0
  30. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/auth/router.py +136 -1
  31. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/auth/schemas.py +202 -24
  32. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/auth/service.py +288 -2
  33. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/db/__init__.py +10 -0
  34. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/db/mixins.py +70 -1
  35. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/db/user_model.py +10 -0
  36. tempest_fastapi_sdk-0.36.0/tempest_fastapi_sdk/db/user_recovery_code_model.py +110 -0
  37. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/settings/mixins.py +87 -5
  38. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/__init__.py +2 -0
  39. tempest_fastapi_sdk-0.36.0/tempest_fastapi_sdk/utils/totp.py +135 -0
  40. tempest_fastapi_sdk-0.36.0/tests/admin/test_forms.py +98 -0
  41. tempest_fastapi_sdk-0.36.0/tests/admin/test_mfa.py +170 -0
  42. tempest_fastapi_sdk-0.36.0/tests/admin/test_router.py +919 -0
  43. tempest_fastapi_sdk-0.36.0/tests/auth/test_mfa.py +777 -0
  44. tempest_fastapi_sdk-0.36.0/tests/auth/test_service.py +1251 -0
  45. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/uv.lock +19 -2
  46. tempest_fastapi_sdk-0.34.0/tempest_fastapi_sdk/admin/router.py +0 -598
  47. tempest_fastapi_sdk-0.34.0/tempest_fastapi_sdk/admin/static/admin.css +0 -245
  48. tempest_fastapi_sdk-0.34.0/tempest_fastapi_sdk/admin/templates/dashboard.html +0 -28
  49. tempest_fastapi_sdk-0.34.0/tempest_fastapi_sdk/admin/templates/detail.html +0 -18
  50. tempest_fastapi_sdk-0.34.0/tempest_fastapi_sdk/admin/templates/list.html +0 -62
  51. tempest_fastapi_sdk-0.34.0/tests/admin/test_router.py +0 -213
  52. tempest_fastapi_sdk-0.34.0/tests/auth/test_service.py +0 -597
  53. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/.github/workflows/ci.yml +0 -0
  54. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/.github/workflows/docs.yml +0 -0
  55. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/.github/workflows/release-pypi.yml +0 -0
  56. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/.gitignore +0 -0
  57. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/.python-version +0 -0
  58. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/CLAUDE.md +0 -0
  59. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/Makefile +0 -0
  60. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/architecture.en.md +0 -0
  61. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/architecture.md +0 -0
  62. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/changelog.en.md +0 -0
  63. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/changelog.md +0 -0
  64. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/contributing.en.md +0 -0
  65. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/contributing.md +0 -0
  66. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/index.en.md +0 -0
  67. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/index.md +0 -0
  68. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/learning/index.en.md +0 -0
  69. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/learning/index.md +0 -0
  70. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/learning/marketplace/api.en.md +0 -0
  71. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/learning/marketplace/api.md +0 -0
  72. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/learning/marketplace/business-rules.en.md +0 -0
  73. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/learning/marketplace/business-rules.md +0 -0
  74. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/learning/marketplace/domain.en.md +0 -0
  75. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/learning/marketplace/domain.md +0 -0
  76. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/learning/marketplace/flows.en.md +0 -0
  77. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/learning/marketplace/flows.md +0 -0
  78. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/learning/marketplace/index.en.md +0 -0
  79. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/learning/marketplace/index.md +0 -0
  80. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/migration.en.md +0 -0
  81. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/migration.md +0 -0
  82. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/br-helpers.en.md +0 -0
  83. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/br-helpers.md +0 -0
  84. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/cache.en.md +0 -0
  85. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/cache.md +0 -0
  86. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/cli.en.md +0 -0
  87. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/cli.md +0 -0
  88. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/database.en.md +0 -0
  89. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/database.md +0 -0
  90. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/http.en.md +0 -0
  91. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/http.md +0 -0
  92. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/idempotency.en.md +0 -0
  93. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/idempotency.md +0 -0
  94. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/index.en.md +0 -0
  95. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/index.md +0 -0
  96. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/logging.en.md +0 -0
  97. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/logging.md +0 -0
  98. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/metrics.en.md +0 -0
  99. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/metrics.md +0 -0
  100. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/queue-tasks.en.md +0 -0
  101. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/queue-tasks.md +0 -0
  102. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/realtime.en.md +0 -0
  103. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/realtime.md +0 -0
  104. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/security.en.md +0 -0
  105. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/security.md +0 -0
  106. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/sessions.en.md +0 -0
  107. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/sessions.md +0 -0
  108. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/storage.en.md +0 -0
  109. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/storage.md +0 -0
  110. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/testing.en.md +0 -0
  111. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/testing.md +0 -0
  112. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/uploads.en.md +0 -0
  113. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/uploads.md +0 -0
  114. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/websocket.en.md +0 -0
  115. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/recipes/websocket.md +0 -0
  116. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/reference.en.md +0 -0
  117. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/tutorial.en.md +0 -0
  118. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/docs/tutorial.md +0 -0
  119. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/scripts/extract_recipe.py +0 -0
  120. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/admin/__init__.py +0 -0
  121. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/admin/site.py +0 -0
  122. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/admin/templates/base.html +0 -0
  123. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/admin/templates/login.html +0 -0
  124. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/__init__.py +0 -0
  125. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/cookies.py +0 -0
  126. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/dependencies/__init__.py +0 -0
  127. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/dependencies/auth.py +0 -0
  128. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/handlers.py +0 -0
  129. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/middlewares/__init__.py +0 -0
  130. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/middlewares/body_size.py +0 -0
  131. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/middlewares/cors.py +0 -0
  132. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/middlewares/csrf.py +0 -0
  133. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/middlewares/idempotency.py +0 -0
  134. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/middlewares/rate_limit.py +0 -0
  135. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/middlewares/request_id.py +0 -0
  136. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/oauth.py +0 -0
  137. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/routers/__init__.py +0 -0
  138. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/routers/health.py +0 -0
  139. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/routers/logs.py +0 -0
  140. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/routers/metrics.py +0 -0
  141. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/routers/tool_spec.py +0 -0
  142. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/server.py +0 -0
  143. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/static.py +0 -0
  144. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/api/webhooks.py +0 -0
  145. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/auth/page_renderer.py +0 -0
  146. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/auth/templates/activation.html +0 -0
  147. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/auth/templates/activation_error.html +0 -0
  148. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/auth/templates/activation_success.html +0 -0
  149. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/auth/templates/password_reset.html +0 -0
  150. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/auth/templates/password_reset_error.html +0 -0
  151. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/auth/templates/password_reset_form.html +0 -0
  152. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/auth/templates/password_reset_success.html +0 -0
  153. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cache/__init__.py +0 -0
  154. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cache/decorator.py +0 -0
  155. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cache/redis_manager.py +0 -0
  156. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/__init__.py +0 -0
  157. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/README.md.tmpl +0 -0
  158. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/env.example.tmpl +0 -0
  159. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/gitignore.tmpl +0 -0
  160. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/main.py.tmpl +0 -0
  161. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/pyproject.toml.tmpl +0 -0
  162. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/__init__.py.tmpl +0 -0
  163. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/api/__init__.py.tmpl +0 -0
  164. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/api/app.py.tmpl +0 -0
  165. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/__init__.py.tmpl +0 -0
  166. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/api/dependencies/auth.py.tmpl +0 -0
  167. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/api/routers/__init__.py.tmpl +0 -0
  168. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/controllers/__init__.py.tmpl +0 -0
  169. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/core/__init__.py.tmpl +0 -0
  170. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/core/exceptions.py.tmpl +0 -0
  171. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/core/settings.py.tmpl +0 -0
  172. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/db/__init__.py.tmpl +0 -0
  173. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/db/models/__init__.py.tmpl +0 -0
  174. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/db/models/user.py.tmpl +0 -0
  175. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/db/repositories/__init__.py.tmpl +0 -0
  176. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/schemas/__init__.py.tmpl +0 -0
  177. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/server.py.tmpl +0 -0
  178. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/services/__init__.py.tmpl +0 -0
  179. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/src/utils/__init__.py.tmpl +0 -0
  180. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/tests/__init__.py.tmpl +0 -0
  181. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/_templates/tests/test_smoke.py.tmpl +0 -0
  182. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/db.py +0 -0
  183. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/docker_compose.py +0 -0
  184. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/generate.py +0 -0
  185. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/lint.py +0 -0
  186. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/main.py +0 -0
  187. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/new.py +0 -0
  188. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/cli/user.py +0 -0
  189. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/controllers/__init__.py +0 -0
  190. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/controllers/base.py +0 -0
  191. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/core/__init__.py +0 -0
  192. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/core/context.py +0 -0
  193. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/core/enums.py +0 -0
  194. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/core/logging.py +0 -0
  195. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/db/_alembic_templates/__init__.py +0 -0
  196. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/db/_alembic_templates/env.py.template +0 -0
  197. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/db/alembic_hooks.py +0 -0
  198. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/db/connection.py +0 -0
  199. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/db/migrations.py +0 -0
  200. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/db/model.py +0 -0
  201. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/db/repository.py +0 -0
  202. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/db/user_token_model.py +0 -0
  203. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/exceptions/__init__.py +0 -0
  204. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/exceptions/base.py +0 -0
  205. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/exceptions/conflict.py +0 -0
  206. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/exceptions/forbidden.py +0 -0
  207. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/exceptions/jwt.py +0 -0
  208. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/exceptions/not_found.py +0 -0
  209. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/exceptions/too_many_requests.py +0 -0
  210. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/exceptions/unauthorized.py +0 -0
  211. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/exceptions/upload.py +0 -0
  212. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/exceptions/validation.py +0 -0
  213. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/py.typed +0 -0
  214. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/queue/__init__.py +0 -0
  215. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/queue/manager.py +0 -0
  216. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/schemas/__init__.py +0 -0
  217. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/schemas/base.py +0 -0
  218. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/schemas/link_headers.py +0 -0
  219. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/schemas/logs.py +0 -0
  220. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/schemas/pagination.py +0 -0
  221. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/schemas/response.py +0 -0
  222. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/services/__init__.py +0 -0
  223. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/services/base.py +0 -0
  224. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/sessions/__init__.py +0 -0
  225. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/sessions/dependencies.py +0 -0
  226. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/sessions/middleware.py +0 -0
  227. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/sessions/router.py +0 -0
  228. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/sessions/schemas.py +0 -0
  229. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/sessions/service.py +0 -0
  230. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/sessions/store.py +0 -0
  231. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/settings/__init__.py +0 -0
  232. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/settings/base.py +0 -0
  233. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/sse/__init__.py +0 -0
  234. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/sse/event_stream.py +0 -0
  235. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/storage/__init__.py +0 -0
  236. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/storage/minio_client.py +0 -0
  237. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/tasks/__init__.py +0 -0
  238. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/tasks/manager.py +0 -0
  239. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/tasks/scheduler.py +0 -0
  240. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/testing/__init__.py +0 -0
  241. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/testing/database.py +0 -0
  242. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/client_ip.py +0 -0
  243. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/datetime.py +0 -0
  244. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/dict.py +0 -0
  245. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/download.py +0 -0
  246. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/email.py +0 -0
  247. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/http_client.py +0 -0
  248. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/jwt.py +0 -0
  249. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/log.py +0 -0
  250. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/metrics.py +0 -0
  251. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/opaque_token.py +0 -0
  252. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/password.py +0 -0
  253. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/regex.py +0 -0
  254. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/storage_backends.py +0 -0
  255. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/throttle.py +0 -0
  256. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/utils/upload.py +0 -0
  257. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/webpush/__init__.py +0 -0
  258. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/webpush/dispatcher.py +0 -0
  259. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/webpush/schemas.py +0 -0
  260. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/websockets/__init__.py +0 -0
  261. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/websockets/hub.py +0 -0
  262. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/websockets/router.py +0 -0
  263. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tempest_fastapi_sdk/websockets/schemas.py +0 -0
  264. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/__init__.py +0 -0
  265. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/admin/__init__.py +0 -0
  266. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/admin/test_auth.py +0 -0
  267. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/admin/test_site.py +0 -0
  268. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/admin/test_user_model.py +0 -0
  269. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/__init__.py +0 -0
  270. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_body_size.py +0 -0
  271. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_cookies.py +0 -0
  272. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_cors.py +0 -0
  273. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_csrf.py +0 -0
  274. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_dependencies_auth.py +0 -0
  275. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_handlers.py +0 -0
  276. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_health_router.py +0 -0
  277. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_idempotency.py +0 -0
  278. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_jwt_dependency.py +0 -0
  279. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_logs_router.py +0 -0
  280. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_oauth.py +0 -0
  281. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_prometheus.py +0 -0
  282. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_rate_limit.py +0 -0
  283. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_request_id_middleware.py +0 -0
  284. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_role_dependency.py +0 -0
  285. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_server.py +0 -0
  286. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_static.py +0 -0
  287. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_tool_spec.py +0 -0
  288. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_webhooks.py +0 -0
  289. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/api/test_webhooks_rsa.py +0 -0
  290. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/auth/__init__.py +0 -0
  291. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/cache/__init__.py +0 -0
  292. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/cache/test_decorator.py +0 -0
  293. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/cache/test_redis_manager.py +0 -0
  294. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/cli/__init__.py +0 -0
  295. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/cli/test_db.py +0 -0
  296. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/cli/test_docker_compose.py +0 -0
  297. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/cli/test_generate.py +0 -0
  298. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/cli/test_main.py +0 -0
  299. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/cli/test_user.py +0 -0
  300. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/conftest.py +0 -0
  301. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/controllers/__init__.py +0 -0
  302. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/controllers/test_base.py +0 -0
  303. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/core/__init__.py +0 -0
  304. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/core/test_context.py +0 -0
  305. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/core/test_enums.py +0 -0
  306. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/core/test_logging.py +0 -0
  307. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/db/__init__.py +0 -0
  308. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/db/test_alembic_hooks.py +0 -0
  309. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/db/test_bulk_ops.py +0 -0
  310. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/db/test_connection.py +0 -0
  311. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/db/test_migrations.py +0 -0
  312. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/db/test_mixins.py +0 -0
  313. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/db/test_model.py +0 -0
  314. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/db/test_repository.py +0 -0
  315. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/exceptions/__init__.py +0 -0
  316. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/exceptions/test_exceptions.py +0 -0
  317. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/queue/__init__.py +0 -0
  318. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/queue/test_manager.py +0 -0
  319. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/schemas/__init__.py +0 -0
  320. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/schemas/test_base.py +0 -0
  321. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/schemas/test_cursor_pagination.py +0 -0
  322. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/schemas/test_link_headers.py +0 -0
  323. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/schemas/test_pagination.py +0 -0
  324. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/schemas/test_response.py +0 -0
  325. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/services/__init__.py +0 -0
  326. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/services/test_base.py +0 -0
  327. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/sessions/__init__.py +0 -0
  328. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/sessions/test_sessions.py +0 -0
  329. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/settings/__init__.py +0 -0
  330. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/settings/test_base.py +0 -0
  331. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/settings/test_mixins.py +0 -0
  332. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/sse/__init__.py +0 -0
  333. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/sse/test_event_stream.py +0 -0
  334. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/storage/__init__.py +0 -0
  335. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/storage/test_minio_client.py +0 -0
  336. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/tasks/__init__.py +0 -0
  337. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/tasks/test_manager.py +0 -0
  338. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/tasks/test_scheduler.py +0 -0
  339. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/testing/__init__.py +0 -0
  340. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/testing/test_database.py +0 -0
  341. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/__init__.py +0 -0
  342. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_client_ip.py +0 -0
  343. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_datetime.py +0 -0
  344. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_dict.py +0 -0
  345. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_download.py +0 -0
  346. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_email.py +0 -0
  347. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_http_client.py +0 -0
  348. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_jwt.py +0 -0
  349. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_lazy_extras.py +0 -0
  350. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_log.py +0 -0
  351. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_metrics.py +0 -0
  352. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_opaque_token.py +0 -0
  353. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_password.py +0 -0
  354. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_regex.py +0 -0
  355. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_storage_backends.py +0 -0
  356. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_throttle.py +0 -0
  357. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/utils/test_upload.py +0 -0
  358. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/webpush/__init__.py +0 -0
  359. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/webpush/test_dispatcher.py +0 -0
  360. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/webpush/test_schemas.py +0 -0
  361. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/websockets/__init__.py +0 -0
  362. {tempest_fastapi_sdk-0.34.0 → tempest_fastapi_sdk-0.36.0}/tests/websockets/test_hub_and_router.py +0 -0
@@ -5,6 +5,161 @@ All notable changes to **tempest-fastapi-sdk** are listed below.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.36.0] — 2026-06-06
9
+
10
+ Admin panel brought to Django-admin parity: the list view, write CRUD,
11
+ bulk actions, dashboard, login, and audit trail all landed across the
12
+ phases below.
13
+
14
+ ### Added
15
+
16
+ - **Admin list view — Phase 1 (read-only enhancements + responsive).**
17
+ - Clickable **column sorting** on the list view
18
+ (`?sort=<column>&dir=asc|desc`), validated against the displayed
19
+ real columns; the admin's configured `ordering` remains the
20
+ default.
21
+ - **CSV / JSON export** endpoint
22
+ (`GET /admin/m/{slug}/export.csv` / `.json`) honoring the active
23
+ search / filters / sort. New `make_admin_router(export_max_rows=…)`
24
+ caps export size (default 5000).
25
+ - **Responsive admin UI** — bundled templates + CSS now adapt to
26
+ mobile (≤600px): stacked header, full-width search/filters/actions,
27
+ horizontal-scroll table wrappers, single-column detail grid.
28
+ Verified at 390px (mobile) and 1280px (desktop).
29
+
30
+ - **Admin write CRUD — Phase 2a (create / edit / delete).**
31
+ - `GET/POST /admin/m/{slug}/new` (create), `GET/POST
32
+ /admin/m/{slug}/{identity}/edit` (edit), and `POST
33
+ /admin/m/{slug}/{identity}/delete` (delete), each gated by new
34
+ `AdminModel(can_create=…, can_edit=…, can_delete=…)` flags
35
+ (default `True`; a disabled view returns `404`).
36
+ - **CSRF-protected** mutations — every write form carries the
37
+ session CSRF token, verified server-side (`403` on mismatch).
38
+ - **Type-aware field widgets** — text / textarea (long strings) /
39
+ number / checkbox / `datetime-local` / date / enum `select`,
40
+ derived from the column types, with required-field + per-field
41
+ validation errors re-rendered on the form, and integrity errors
42
+ surfaced inline.
43
+ - Detail view gains Edit / Delete controls; list view gains a
44
+ "+ New" button. All responsive (verified at 390px / 1280px).
45
+
46
+ - **Admin bulk actions — Phase 2b.**
47
+ - List view gains row checkboxes + a select-all toggle and a bulk
48
+ action bar. `POST /admin/m/{slug}/bulk` applies **delete**
49
+ (`can_delete`), **activate** / **deactivate** (`can_edit`, toggling
50
+ the `is_active` flag) to the selected rows, CSRF-verified.
51
+ Backed by `BaseRepository.delete_batch` / `bulk_update`.
52
+ Responsive (verified at 390px / 1280px).
53
+
54
+ - **Admin foreign-key select — Phase 2c.**
55
+ - A foreign-key column whose referenced table has its own
56
+ `AdminModel` now renders as a **dropdown of the related rows**
57
+ (Django's FK select) on the create/edit form, instead of a raw
58
+ UUID input. Option labels come from the referenced admin's first
59
+ `search_fields` entry (falling back to a `name`/`title`/`email`
60
+ attribute, then the id). Capped at 1000 rows. FKs to unmanaged
61
+ tables stay plain UUID inputs.
62
+
63
+ - **Admin dashboard — counts + metrics (Phase 3a).**
64
+ - The dashboard now renders each registered model as a card with its
65
+ **live row count** and Browse / + New links, plus a **system
66
+ metrics panel** (CPU / RAM / disk) via `MetricsUtils`. The panel
67
+ is on by default, silently omitted when the `[metrics]` extra is
68
+ absent, and disabled with `make_admin_router(show_metrics=False)`.
69
+ Responsive card grids (verified at 390px / 1280px).
70
+
71
+ - **Admin MFA login — Phase 3b.**
72
+ - The admin login now supports a TOTP second factor. After the
73
+ password step, a principal with MFA enabled gets a short
74
+ `mfa_pending` session and is redirected to `GET/POST /admin/mfa`
75
+ (a CSRF-protected TOTP challenge); only a valid code upgrades the
76
+ session to full access. `AdminAuthBackend` gains `mfa_enabled` /
77
+ `verify_mfa` (default off); `UserModelAuthBackend` implements them
78
+ against `MFAMixin`'s `totp_secret` / `totp_enabled_at` via
79
+ `TOTPHelper` (new `mfa_issuer` / `mfa_window` ctor args). Pending
80
+ sessions are denied every admin page until the challenge passes.
81
+
82
+ - **Admin audit trail — Phase 3c.**
83
+ - Create/edit through the admin now **stamps** `created_by` /
84
+ `updated_by` (from `AuditMixin`) with the acting admin's id. The
85
+ detail view gained an **Audit panel** showing created/updated
86
+ timestamps and — when the model has the audit columns — the actor,
87
+ with the stored UUID resolved to a display name via the auth
88
+ backend. Models without `AuditMixin` show the timestamps only.
89
+
90
+ File-upload widget and inline/related editing remain tracked as later
91
+ admin phases on the roadmap.
92
+
93
+ ## [0.35.0] — 2026-06-06
94
+
95
+ ### Added
96
+
97
+ - **MFA / TOTP (RFC 6238)** — the bundled auth flow now supports
98
+ two-factor authentication with Authenticator apps. New `[mfa]`
99
+ extra (`pyotp>=2.9.0`). Public surface:
100
+ - `TOTPHelper(issuer=...)` — stateless TOTP issuer/verifier
101
+ (`generate_secret`, `provisioning_uri`, `verify` with a
102
+ configurable clock-drift window). Lazy-imports `pyotp`, so
103
+ `import tempest_fastapi_sdk` still works without the extra.
104
+ - `BaseUserRecoveryCodeModel` + `make_user_recovery_code_model`
105
+ — single-use recovery-code table (stores only the SHA-256
106
+ hash of each code, mirroring `BaseUserTokenModel`).
107
+ - `MFAMixin` — opt-in SQLAlchemy mixin adding `totp_secret` +
108
+ `totp_enabled_at` columns (plus an `is_mfa_active` property).
109
+ Mix it into the concrete user model
110
+ (`class UserModel(MFAMixin, BaseUserModel)`) only when MFA is
111
+ adopted, so projects that never enable it carry no dead
112
+ columns. `totp_enabled_at IS NULL` means MFA is
113
+ staged-but-not-active, so login stays single-step until the
114
+ user confirms.
115
+ - `UserAuthService` MFA methods: `is_mfa_enrolled`,
116
+ `issue_mfa_token`, `mfa_enroll`, `mfa_confirm`, `mfa_verify`,
117
+ `mfa_disable`.
118
+ - `make_auth_router(..., recovery_code_model=...)` mounts four
119
+ endpoints behind the `AUTH_MFA_ENABLED` kill-switch:
120
+ `POST /auth/mfa/enroll`, `/auth/mfa/confirm`,
121
+ `/auth/mfa/disable`, `/auth/mfa/verify`. `POST /auth/login`
122
+ now returns `mfa_required=True` + a short-lived `mfa_token`
123
+ (instead of the JWT pair) for enrolled users; step 2 swaps
124
+ `mfa_token` + code for the real tokens.
125
+ - New schemas: `MFAEnrollResponseSchema`, `MFAConfirmSchema`,
126
+ `MFADisableSchema`, `MFAVerifySchema`. `LoginResponseSchema`
127
+ gains `mfa_required` + `mfa_token` (and `access_token` /
128
+ `refresh_token` are now nullable for the MFA-pending case).
129
+ - New `AuthSettings`: `AUTH_MFA_ENABLED`, `AUTH_MFA_ISSUER`,
130
+ `AUTH_MFA_RECOVERY_CODES_COUNT`, `AUTH_MFA_TOKEN_TTL_SECONDS`,
131
+ `AUTH_MFA_VERIFY_WINDOW`.
132
+ - **Optional password complexity** — new
133
+ `AUTH_PASSWORD_REQUIRE_COMPLEXITY` flag (default `False`). When off,
134
+ any password meeting `AUTH_PASSWORD_MIN_LENGTH` is accepted; when on,
135
+ signup + reset additionally require at least one lowercase letter,
136
+ one uppercase letter, one digit, and one special (non-alphanumeric)
137
+ character, and the effective length floor is raised to at least 8
138
+ (a configured `AUTH_PASSWORD_MIN_LENGTH` below 8 is ignored while
139
+ complexity is on). Enforced server-side on both `service.signup` and
140
+ `service.confirm_password_reset`.
141
+
142
+ ### Fixed
143
+
144
+ - **Password minimum length is now honored end-to-end.**
145
+ `SignupSchema.password` and `PasswordResetConfirmSchema.new_password`
146
+ hardcoded `min_length=12`, which overrode `AUTH_PASSWORD_MIN_LENGTH`
147
+ on the router path — a project lowering the floor still got a 422
148
+ from Pydantic, and raising it above 12 was enforced only by the
149
+ service. The schemas now reject only empty strings;
150
+ `AUTH_PASSWORD_MIN_LENGTH` is the single source of truth (now `ge=1`,
151
+ fully configurable down to 4 or any value, default 12), applied
152
+ server-side.
153
+
154
+ ### Notes
155
+
156
+ - Enabling MFA requires a migration: mix `MFAMixin` into the concrete
157
+ user model (`class UserModel(MFAMixin, BaseUserModel)`) to add the
158
+ `totp_secret` / `totp_enabled_at` columns, and create the
159
+ recovery-code table. `AUTH_MFA_ENABLED=True` without passing
160
+ `recovery_code_model` to `make_auth_router` raises at
161
+ router-build time.
162
+
8
163
  ## [0.34.0] — 2026-06-04
9
164
 
10
165
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tempest-fastapi-sdk
3
- Version: 0.34.0
3
+ Version: 0.36.0
4
4
  Summary: Shared FastAPI building blocks: base schemas, ORM model, async repository, exceptions, pagination and settings — the conventions used across Tempest projects.
5
5
  Project-URL: Homepage, https://github.com/mauriciobenjamin700/tempest-fastapi-sdk
6
6
  Project-URL: Repository, https://github.com/mauriciobenjamin700/tempest-fastapi-sdk
@@ -44,6 +44,7 @@ Requires-Dist: nvidia-ml-py>=12.560.30; extra == 'all'
44
44
  Requires-Dist: prometheus-client>=0.20.0; extra == 'all'
45
45
  Requires-Dist: psutil>=6.0.0; extra == 'all'
46
46
  Requires-Dist: pyjwt>=2.12.1; extra == 'all'
47
+ Requires-Dist: pyotp>=2.9.0; extra == 'all'
47
48
  Requires-Dist: python-multipart>=0.0.12; extra == 'all'
48
49
  Requires-Dist: pywebpush>=2.0.0; extra == 'all'
49
50
  Requires-Dist: redis>=5.0.0; extra == 'all'
@@ -63,6 +64,8 @@ Requires-Dist: httpx>=0.28.0; extra == 'http'
63
64
  Provides-Extra: metrics
64
65
  Requires-Dist: nvidia-ml-py>=12.560.30; extra == 'metrics'
65
66
  Requires-Dist: psutil>=6.0.0; extra == 'metrics'
67
+ Provides-Extra: mfa
68
+ Requires-Dist: pyotp>=2.9.0; extra == 'mfa'
66
69
  Provides-Extra: minio
67
70
  Requires-Dist: minio>=7.2.0; extra == 'minio'
68
71
  Provides-Extra: prometheus
@@ -171,7 +174,7 @@ Via `pyproject.toml`:
171
174
 
172
175
  ```toml
173
176
  dependencies = [
174
- "tempest-fastapi-sdk>=0.32.0",
177
+ "tempest-fastapi-sdk>=0.36.0",
175
178
  ]
176
179
  ```
177
180
 
@@ -195,6 +198,7 @@ Feature-rich helpers pull in third-party dependencies that you only need when yo
195
198
  | `[minio]` | `minio` | `AsyncMinIOClient`, `ObjectStat`, `MinIOSettings` |
196
199
  | `[http]` | `httpx` | `HTTPClient`, `RetryPolicy`, `CircuitOpenError`, OAuth2 / OIDC providers |
197
200
  | `[prometheus]` | `prometheus-client` | `PrometheusMiddleware`, `make_prometheus_router`, `make_prometheus_registry` |
201
+ | `[mfa]` | `pyotp` | `TOTPHelper` + MFA/2FA endpoints on the bundled auth flow |
198
202
  | `[all]` | everything above | every helper |
199
203
 
200
204
  ```bash
@@ -211,11 +215,11 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
211
215
  | Module | Exports |
212
216
  | --- | --- |
213
217
  | `tempest_fastapi_sdk.schemas` | `BaseSchema`, `BaseResponseSchema`, `BasePaginationFilterSchema`, `BasePaginationSchema[T]`, `CursorPaginationFilterSchema`, `CursorPaginationSchema`, `LogEntrySchema`, `encode_cursor`, `decode_cursor`, `build_pagination_link_header` |
214
- | `tempest_fastapi_sdk.db` | `BaseModel`, `BaseUserModel`, `BaseUserTokenModel`, `UserTokenPurpose`, `BaseRepository[ModelType]`, `AsyncDatabaseManager`, `AlembicHelper`, `NAMING_CONVENTION`, `AuditMixin`, `SoftDeleteMixin`, `BASE_COLUMN_ORDER`, `reorder_base_columns_first`, `compose_hooks` |
218
+ | `tempest_fastapi_sdk.db` | `BaseModel`, `BaseUserModel`, `BaseUserTokenModel`, `BaseUserRecoveryCodeModel`, `make_user_recovery_code_model`, `UserTokenPurpose`, `BaseRepository[ModelType]`, `AsyncDatabaseManager`, `AlembicHelper`, `NAMING_CONVENTION`, `AuditMixin`, `SoftDeleteMixin`, `MFAMixin`, `BASE_COLUMN_ORDER`, `reorder_base_columns_first`, `compose_hooks` |
215
219
  | `tempest_fastapi_sdk.exceptions` | `AppException`, `NotFoundException`, `ConflictException`, `ValidationException`, `UnauthorizedException`, `ForbiddenException`, `InvalidTokenException`, `ExpiredTokenException`, `FileTooLargeException`, `InvalidFileTypeException`, `TooManyRequestsException` |
216
220
  | `tempest_fastapi_sdk.settings` | `BaseAppSettings`, `ServerSettings`, `LogSettings`, `DatabaseSettings`, `RedisSettings`, `RabbitMQSettings`, `JWTSettings`, `CORSSettings`, `EmailSettings`, `UploadSettings`, `TokenSettings`, `WebPushSettings`, `TaskIQSettings`, `MinIOSettings`, `AuthSettings` |
217
221
  | `tempest_fastapi_sdk.api` | `register_exception_handlers`, `app_exception_handler`, `apply_cors`, `make_health_router`, `make_logs_router`, `make_prometheus_router`, `make_prometheus_registry`, `PrometheusMiddleware`, `LogSource`, `make_tool_spec_router`, `make_token_dependency`, `make_bearer_token_dependency`, `make_jwt_user_dependency`, `make_role_dependency`, `make_permission_dependency`, `require_x_token`, `run_server`, `RequestIDMiddleware`, `RateLimitMiddleware`, `IdempotencyMiddleware`, `MemoryIdempotencyStore`, `RedisIdempotencyStore`, `BodySizeLimitMiddleware`, `CSRFMiddleware`, `make_csrf_token_dependency`, `WebhookSignatureVerifier`, `RSAWebhookSignatureVerifier`, OAuth2 (`GoogleOAuthClient`, `GitHubOAuthClient`, `OIDCProvider`), `HardenedStaticFiles`, `DEFAULT_STATIC_SECURITY_HEADERS`, `set_cookie`, `clear_cookie`, `SameSite`, `HealthCheck` |
218
- | `tempest_fastapi_sdk.auth` *(extra: `[auth]`, opcional `[email]`)* | `UserAuthService`, `make_auth_router`, `SignupSchema` / `LoginSchema` / `PasswordResetRequestSchema` / `PasswordResetConfirmSchema` + responses, `ActivationToken`, `PasswordResetToken` — signup/activate/login/reset out of the box |
222
+ | `tempest_fastapi_sdk.auth` *(extra: `[auth]`, opcional `[email]`, `[mfa]`)* | `UserAuthService`, `make_auth_router`, `SignupSchema` / `LoginSchema` / `PasswordResetRequestSchema` / `PasswordResetConfirmSchema` + responses, `ActivationToken`, `PasswordResetToken`, MFA schemas (`MFAEnrollResponseSchema` / `MFAConfirmSchema` / `MFAVerifySchema` / `MFADisableSchema`) — signup/activate/login/reset + TOTP 2FA out of the box |
219
223
  | `tempest_fastapi_sdk.controllers` | `BaseController` |
220
224
  | `tempest_fastapi_sdk.services` | `BaseService` |
221
225
  | `tempest_fastapi_sdk.core` | `configure_logging`, `JSONFormatter`, `get_request_id`/`set_request_id`/`clear_request_id`, `request_id_ctx`, `BaseStrEnum`, `BaseIntEnum` |
@@ -228,7 +232,7 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
228
232
  | `tempest_fastapi_sdk.utils.http_client` *(extra: `[http]`)* | `HTTPClient`, `RetryPolicy`, `CircuitOpenError`, `REQUEST_ID_HEADER` — typed httpx wrapper |
229
233
  | `tempest_fastapi_sdk.utils.storage_backends` *(extra: `[upload]`)* | `UploadStorage` protocol, `LocalUploadStorage`, `MinIOUploadStorage`, `UploadResult`, `ContentValidator` |
230
234
  | `tempest_fastapi_sdk.tasks` *(extra: `[tasks]`)* | `AsyncTaskBrokerManager` (TaskIQ lifecycle wrapper), `AsyncTaskScheduler` (periodic / cron tasks) |
231
- | `tempest_fastapi_sdk.utils` | `to_utc`, `utcnow`, `modify_dict`, `LogUtils`, `AttemptThrottle`/`ThrottleBackend`/`ThrottleStatus`, `generate_opaque_token`/`hash_opaque_token`/`verify_opaque_token`, `get_client_ip`/`get_client_ip_from_scope`, `PasswordUtils` *(extra: `[auth]`)*, `JWTUtils` *(extra: `[auth]`)*, `EmailUtils` *(extra: `[email]`)*, `UploadUtils`/`sniff_mime` *(extra: `[upload]`)*, `DownloadUtils`/`build_content_disposition` *(no extra)*, `MetricsUtils`/`CPUMetrics`/`MemoryMetrics`/`DiskMetrics`/`GPUMetrics`/`SystemMetrics` *(extra: `[metrics]`)*, BR regex helpers (`CPF`, `CNPJ`, `CPFOrCNPJ`, `PhoneBR`, `CEP`, `is_valid_*`, `normalize_*`, `only_digits`, `*_PATTERN`) |
235
+ | `tempest_fastapi_sdk.utils` | `to_utc`, `utcnow`, `modify_dict`, `LogUtils`, `AttemptThrottle`/`ThrottleBackend`/`ThrottleStatus`, `generate_opaque_token`/`hash_opaque_token`/`verify_opaque_token`, `get_client_ip`/`get_client_ip_from_scope`, `PasswordUtils` *(extra: `[auth]`)*, `JWTUtils` *(extra: `[auth]`)*, `TOTPHelper` *(extra: `[mfa]`)*, `EmailUtils` *(extra: `[email]`)*, `UploadUtils`/`sniff_mime` *(extra: `[upload]`)*, `DownloadUtils`/`build_content_disposition` *(no extra)*, `MetricsUtils`/`CPUMetrics`/`MemoryMetrics`/`DiskMetrics`/`GPUMetrics`/`SystemMetrics` *(extra: `[metrics]`)*, BR regex helpers (`CPF`, `CNPJ`, `CPFOrCNPJ`, `PhoneBR`, `CEP`, `is_valid_*`, `normalize_*`, `only_digits`, `*_PATTERN`) |
232
236
  | `tempest_fastapi_sdk.cli` | `tempest` console script — `new <name>` (scaffold layered service), `lint` / `format` / `fmt-check` / `type` / `test` / `check` (run preferred quality gates), `version` / `--version` |
233
237
 
234
238
  Core primitives are re-exported from `tempest_fastapi_sdk` at the top level — `from tempest_fastapi_sdk import BaseModel, BaseRepository, AppException` always works. The extras-gated managers in `tempest_fastapi_sdk.cache`, `tempest_fastapi_sdk.queue` and `tempest_fastapi_sdk.tasks` must be imported from their own submodule (`from tempest_fastapi_sdk.queue import AsyncBrokerManager`).
@@ -89,7 +89,7 @@ Via `pyproject.toml`:
89
89
 
90
90
  ```toml
91
91
  dependencies = [
92
- "tempest-fastapi-sdk>=0.32.0",
92
+ "tempest-fastapi-sdk>=0.36.0",
93
93
  ]
94
94
  ```
95
95
 
@@ -113,6 +113,7 @@ Feature-rich helpers pull in third-party dependencies that you only need when yo
113
113
  | `[minio]` | `minio` | `AsyncMinIOClient`, `ObjectStat`, `MinIOSettings` |
114
114
  | `[http]` | `httpx` | `HTTPClient`, `RetryPolicy`, `CircuitOpenError`, OAuth2 / OIDC providers |
115
115
  | `[prometheus]` | `prometheus-client` | `PrometheusMiddleware`, `make_prometheus_router`, `make_prometheus_registry` |
116
+ | `[mfa]` | `pyotp` | `TOTPHelper` + MFA/2FA endpoints on the bundled auth flow |
116
117
  | `[all]` | everything above | every helper |
117
118
 
118
119
  ```bash
@@ -129,11 +130,11 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
129
130
  | Module | Exports |
130
131
  | --- | --- |
131
132
  | `tempest_fastapi_sdk.schemas` | `BaseSchema`, `BaseResponseSchema`, `BasePaginationFilterSchema`, `BasePaginationSchema[T]`, `CursorPaginationFilterSchema`, `CursorPaginationSchema`, `LogEntrySchema`, `encode_cursor`, `decode_cursor`, `build_pagination_link_header` |
132
- | `tempest_fastapi_sdk.db` | `BaseModel`, `BaseUserModel`, `BaseUserTokenModel`, `UserTokenPurpose`, `BaseRepository[ModelType]`, `AsyncDatabaseManager`, `AlembicHelper`, `NAMING_CONVENTION`, `AuditMixin`, `SoftDeleteMixin`, `BASE_COLUMN_ORDER`, `reorder_base_columns_first`, `compose_hooks` |
133
+ | `tempest_fastapi_sdk.db` | `BaseModel`, `BaseUserModel`, `BaseUserTokenModel`, `BaseUserRecoveryCodeModel`, `make_user_recovery_code_model`, `UserTokenPurpose`, `BaseRepository[ModelType]`, `AsyncDatabaseManager`, `AlembicHelper`, `NAMING_CONVENTION`, `AuditMixin`, `SoftDeleteMixin`, `MFAMixin`, `BASE_COLUMN_ORDER`, `reorder_base_columns_first`, `compose_hooks` |
133
134
  | `tempest_fastapi_sdk.exceptions` | `AppException`, `NotFoundException`, `ConflictException`, `ValidationException`, `UnauthorizedException`, `ForbiddenException`, `InvalidTokenException`, `ExpiredTokenException`, `FileTooLargeException`, `InvalidFileTypeException`, `TooManyRequestsException` |
134
135
  | `tempest_fastapi_sdk.settings` | `BaseAppSettings`, `ServerSettings`, `LogSettings`, `DatabaseSettings`, `RedisSettings`, `RabbitMQSettings`, `JWTSettings`, `CORSSettings`, `EmailSettings`, `UploadSettings`, `TokenSettings`, `WebPushSettings`, `TaskIQSettings`, `MinIOSettings`, `AuthSettings` |
135
136
  | `tempest_fastapi_sdk.api` | `register_exception_handlers`, `app_exception_handler`, `apply_cors`, `make_health_router`, `make_logs_router`, `make_prometheus_router`, `make_prometheus_registry`, `PrometheusMiddleware`, `LogSource`, `make_tool_spec_router`, `make_token_dependency`, `make_bearer_token_dependency`, `make_jwt_user_dependency`, `make_role_dependency`, `make_permission_dependency`, `require_x_token`, `run_server`, `RequestIDMiddleware`, `RateLimitMiddleware`, `IdempotencyMiddleware`, `MemoryIdempotencyStore`, `RedisIdempotencyStore`, `BodySizeLimitMiddleware`, `CSRFMiddleware`, `make_csrf_token_dependency`, `WebhookSignatureVerifier`, `RSAWebhookSignatureVerifier`, OAuth2 (`GoogleOAuthClient`, `GitHubOAuthClient`, `OIDCProvider`), `HardenedStaticFiles`, `DEFAULT_STATIC_SECURITY_HEADERS`, `set_cookie`, `clear_cookie`, `SameSite`, `HealthCheck` |
136
- | `tempest_fastapi_sdk.auth` *(extra: `[auth]`, opcional `[email]`)* | `UserAuthService`, `make_auth_router`, `SignupSchema` / `LoginSchema` / `PasswordResetRequestSchema` / `PasswordResetConfirmSchema` + responses, `ActivationToken`, `PasswordResetToken` — signup/activate/login/reset out of the box |
137
+ | `tempest_fastapi_sdk.auth` *(extra: `[auth]`, opcional `[email]`, `[mfa]`)* | `UserAuthService`, `make_auth_router`, `SignupSchema` / `LoginSchema` / `PasswordResetRequestSchema` / `PasswordResetConfirmSchema` + responses, `ActivationToken`, `PasswordResetToken`, MFA schemas (`MFAEnrollResponseSchema` / `MFAConfirmSchema` / `MFAVerifySchema` / `MFADisableSchema`) — signup/activate/login/reset + TOTP 2FA out of the box |
137
138
  | `tempest_fastapi_sdk.controllers` | `BaseController` |
138
139
  | `tempest_fastapi_sdk.services` | `BaseService` |
139
140
  | `tempest_fastapi_sdk.core` | `configure_logging`, `JSONFormatter`, `get_request_id`/`set_request_id`/`clear_request_id`, `request_id_ctx`, `BaseStrEnum`, `BaseIntEnum` |
@@ -146,7 +147,7 @@ Since `0.7.1` every optional dependency is imported lazily at first instantiatio
146
147
  | `tempest_fastapi_sdk.utils.http_client` *(extra: `[http]`)* | `HTTPClient`, `RetryPolicy`, `CircuitOpenError`, `REQUEST_ID_HEADER` — typed httpx wrapper |
147
148
  | `tempest_fastapi_sdk.utils.storage_backends` *(extra: `[upload]`)* | `UploadStorage` protocol, `LocalUploadStorage`, `MinIOUploadStorage`, `UploadResult`, `ContentValidator` |
148
149
  | `tempest_fastapi_sdk.tasks` *(extra: `[tasks]`)* | `AsyncTaskBrokerManager` (TaskIQ lifecycle wrapper), `AsyncTaskScheduler` (periodic / cron tasks) |
149
- | `tempest_fastapi_sdk.utils` | `to_utc`, `utcnow`, `modify_dict`, `LogUtils`, `AttemptThrottle`/`ThrottleBackend`/`ThrottleStatus`, `generate_opaque_token`/`hash_opaque_token`/`verify_opaque_token`, `get_client_ip`/`get_client_ip_from_scope`, `PasswordUtils` *(extra: `[auth]`)*, `JWTUtils` *(extra: `[auth]`)*, `EmailUtils` *(extra: `[email]`)*, `UploadUtils`/`sniff_mime` *(extra: `[upload]`)*, `DownloadUtils`/`build_content_disposition` *(no extra)*, `MetricsUtils`/`CPUMetrics`/`MemoryMetrics`/`DiskMetrics`/`GPUMetrics`/`SystemMetrics` *(extra: `[metrics]`)*, BR regex helpers (`CPF`, `CNPJ`, `CPFOrCNPJ`, `PhoneBR`, `CEP`, `is_valid_*`, `normalize_*`, `only_digits`, `*_PATTERN`) |
150
+ | `tempest_fastapi_sdk.utils` | `to_utc`, `utcnow`, `modify_dict`, `LogUtils`, `AttemptThrottle`/`ThrottleBackend`/`ThrottleStatus`, `generate_opaque_token`/`hash_opaque_token`/`verify_opaque_token`, `get_client_ip`/`get_client_ip_from_scope`, `PasswordUtils` *(extra: `[auth]`)*, `JWTUtils` *(extra: `[auth]`)*, `TOTPHelper` *(extra: `[mfa]`)*, `EmailUtils` *(extra: `[email]`)*, `UploadUtils`/`sniff_mime` *(extra: `[upload]`)*, `DownloadUtils`/`build_content_disposition` *(no extra)*, `MetricsUtils`/`CPUMetrics`/`MemoryMetrics`/`DiskMetrics`/`GPUMetrics`/`SystemMetrics` *(extra: `[metrics]`)*, BR regex helpers (`CPF`, `CNPJ`, `CPFOrCNPJ`, `PhoneBR`, `CEP`, `is_valid_*`, `normalize_*`, `only_digits`, `*_PATTERN`) |
150
151
  | `tempest_fastapi_sdk.cli` | `tempest` console script — `new <name>` (scaffold layered service), `lint` / `format` / `fmt-check` / `type` / `test` / `check` (run preferred quality gates), `version` / `--version` |
151
152
 
152
153
  Core primitives are re-exported from `tempest_fastapi_sdk` at the top level — `from tempest_fastapi_sdk import BaseModel, BaseRepository, AppException` always works. The extras-gated managers in `tempest_fastapi_sdk.cache`, `tempest_fastapi_sdk.queue` and `tempest_fastapi_sdk.tasks` must be imported from their own submodule (`from tempest_fastapi_sdk.queue import AsyncBrokerManager`).
@@ -29,6 +29,7 @@ Feature-rich helpers pull in third-party dependencies that you only need when yo
29
29
  | `[minio]` | `minio` | `AsyncMinIOClient`, `MinIOUploadStorage` |
30
30
  | `[http]` | `httpx` | `HTTPClient` + `RetryPolicy` + circuit-breaker |
31
31
  | `[prometheus]` | `prometheus-client` | `PrometheusMiddleware`, `make_prometheus_router`, `make_prometheus_registry` |
32
+ | `[mfa]` | `pyotp` | `TOTPHelper` + MFA/2FA (TOTP) endpoints on the bundled auth flow |
32
33
  | `[all]` | everything above | every helper |
33
34
 
34
35
  === "Subset (recommended)"
@@ -29,6 +29,7 @@ Os helpers mais ricos puxam dependências de terceiros que só são necessárias
29
29
  | `[minio]` | `minio` | `AsyncMinIOClient`, `MinIOUploadStorage` |
30
30
  | `[http]` | `httpx` | `HTTPClient` + `RetryPolicy` + circuit-breaker |
31
31
  | `[prometheus]` | `prometheus-client` | `PrometheusMiddleware`, `make_prometheus_router`, `make_prometheus_registry` |
32
+ | `[mfa]` | `pyotp` | `TOTPHelper` + endpoints MFA/2FA (TOTP) do fluxo bundled de auth |
32
33
  | `[all]` | tudo acima | todos os helpers |
33
34
 
34
35
  === "Subconjunto (recomendado)"
@@ -120,11 +120,33 @@ app.include_router(
120
120
  `make_admin_router` mounts:
121
121
 
122
122
  - `GET /admin/login`, `POST /admin/login`, `POST /admin/logout` — auth flow.
123
- - `GET /admin/`dashboard listing every registered admin.
124
- - `GET /admin/m/{slug}/` — list view with pagination + free-text search (`?q=`) + per-field filters (`?filter_<field>=value`).
125
- - `GET /admin/m/{slug}/{identity}`read-only detail view.
123
+ - `GET/POST /admin/mfa`TOTP second-factor challenge between the password step and access, for MFA-enabled principals.
124
+ - `GET /admin/` — dashboard: a card per model with its **live row count** + Browse/New, plus a **metrics panel** (CPU/RAM/disk via `MetricsUtils`). On by default, omitted without the `[metrics]` extra, disable with `make_admin_router(show_metrics=False)`.
125
+ - `GET /admin/m/{slug}/`list view with pagination + free-text search (`?q=`) + per-field filters (`?filter_<field>=value`) + clickable **column sorting** (`?sort=<column>&dir=asc|desc`).
126
+ - `GET /admin/m/{slug}/export.csv` / `export.json` — **export** the current result set (honoring search/filters/sort) as CSV or JSON. Row cap via `make_admin_router(export_max_rows=…)` (default 5000).
127
+ - `POST /admin/m/{slug}/bulk` — **bulk actions** (delete / activate / deactivate) on the selected rows.
128
+ - `GET/POST /admin/m/{slug}/new` — **create** a record (when `can_create`).
129
+ - `GET /admin/m/{slug}/{identity}` — detail view with Edit/Delete controls.
130
+ - `GET/POST /admin/m/{slug}/{identity}/edit` — **edit** a record (when `can_edit`).
131
+ - `POST /admin/m/{slug}/{identity}/delete` — **delete** a record (when `can_delete`).
126
132
  - `GET /admin/static/{path}` — bundled CSS/HTMX assets.
127
133
 
134
+ !!! info "Write CRUD + permissions"
135
+ Create/edit/delete are gated by `AdminModel` flags: `can_create` / `can_edit` / `can_delete` (all `True` by default; a disabled view returns `404`). Every write POST carries the session CSRF token, verified server-side (`403` on mismatch). **Field widgets** are derived from the column type — text / textarea (long strings) / number / checkbox / `datetime-local` / date / `select` for enums — with required-field + per-field validation errors re-rendered on the form.
136
+
137
+ **Bulk actions**: the list view shows per-row checkboxes + select-all and an action bar (delete / activate / deactivate) operating on the checked rows via `POST .../bulk` (CSRF + `can_delete`/`can_edit` flags), backed by `BaseRepository.delete_batch` / `bulk_update`.
138
+
139
+ **FK-select**: a foreign-key column whose target has a registered `AdminModel` renders as a dropdown of the related rows (like Django's FK select) on the form, instead of a raw UUID input. The option label comes from the referenced admin's first `search_fields` entry (fallback: a `name`/`title`/`email` attribute, then the id). Capped at 1000 rows; FKs to unmanaged tables stay UUID inputs.
140
+
141
+ **MFA login**: a principal with MFA enabled (`MFAMixin`'s `totp_secret`/`totp_enabled_at`) goes through a TOTP challenge at `/admin/mfa` after the password — only a valid code grants access. Enable it via `UserModelAuthBackend(UserModel, mfa_issuer=...)`; custom backends override `mfa_enabled`/`verify_mfa`.
142
+
143
+ **Audit trail**: create/edit through the admin stamps `created_by`/`updated_by` (from `AuditMixin`) with the acting admin's id; the detail view shows an **Audit** panel with timestamps and — when the model has the audit columns — the actor (UUID resolved to a display name via the auth backend). Models without `AuditMixin` show timestamps only.
144
+
145
+ Not yet included (later roadmap phases): file upload, inline/related editing.
146
+
147
+ !!! tip "Responsive by default"
148
+ The bundled templates + CSS are responsive: on narrow screens (≤600px) the header stacks, search/filters/actions go full-width, tables get horizontal scroll (never breaking the layout), and the detail grid collapses to a single column. Column headers are clickable to toggle sort order (▲/▼).
149
+
128
150
  #### 4. Session security defaults
129
151
 
130
152
  `SignedCookieSessionStore` uses `itsdangerous.TimestampSigner` (HMAC-SHA256) to sign a single cookie:
@@ -120,11 +120,33 @@ app.include_router(
120
120
  `make_admin_router` monta:
121
121
 
122
122
  - `GET /admin/login`, `POST /admin/login`, `POST /admin/logout` — fluxo de auth.
123
- - `GET /admin/`dashboard listando todo admin registrado.
124
- - `GET /admin/m/{slug}/` — list view com paginação + busca em texto livre (`?q=`) + filtros por campo (`?filter_<field>=value`).
125
- - `GET /admin/m/{slug}/{identity}`detail view somente leitura.
123
+ - `GET/POST /admin/mfa`desafio TOTP (segundo fator) entre a senha e o acesso, para principais com MFA habilitado.
124
+ - `GET /admin/` — dashboard: card por modelo com **contagem de linhas** + Browse/New, e um **painel de métricas** (CPU/RAM/disco via `MetricsUtils`). Painel ligado por default, omitido sem o extra `[metrics]`, desligável com `make_admin_router(show_metrics=False)`.
125
+ - `GET /admin/m/{slug}/`list view com paginação + busca em texto livre (`?q=`) + filtros por campo (`?filter_<field>=value`) + **ordenação por coluna** clicável (`?sort=<coluna>&dir=asc|desc`).
126
+ - `GET /admin/m/{slug}/export.csv` / `export.json` — **exporta** o resultado atual (respeitando busca/filtros/ordenação) como CSV ou JSON. Limite de linhas via `make_admin_router(export_max_rows=…)` (default 5000).
127
+ - `POST /admin/m/{slug}/bulk` — **ações em massa** (delete / activate / deactivate) nas linhas selecionadas.
128
+ - `GET/POST /admin/m/{slug}/new` — **criar** registro (quando `can_create`).
129
+ - `GET /admin/m/{slug}/{identity}` — detail view com botões Edit/Delete.
130
+ - `GET/POST /admin/m/{slug}/{identity}/edit` — **editar** registro (quando `can_edit`).
131
+ - `POST /admin/m/{slug}/{identity}/delete` — **excluir** registro (quando `can_delete`).
126
132
  - `GET /admin/static/{path}` — assets CSS/HTMX embutidos.
127
133
 
134
+ !!! info "Escrita (CRUD) + permissões"
135
+ Create/edit/delete são controlados por flags no `AdminModel`: `can_create` / `can_edit` / `can_delete` (todas `True` por default; uma view desativada responde `404`). Todo POST de escrita carrega o token CSRF da sessão, validado no servidor (`403` em mismatch). Os **widgets de campo** são derivados do tipo da coluna — texto / textarea (strings longas) / number / checkbox / `datetime-local` / date / `select` para enums — com validação de obrigatórios + erros por campo re-renderizados no formulário.
136
+
137
+ **Ações em massa**: a list view mostra checkboxes por linha + select-all e uma barra de ação (delete / activate / deactivate) que opera nas linhas marcadas via `POST .../bulk` (CSRF + flags `can_delete`/`can_edit`), apoiada em `BaseRepository.delete_batch` / `bulk_update`.
138
+
139
+ **FK-select**: uma coluna FK cujo destino tem `AdminModel` registrado vira um dropdown das linhas relacionadas (igual ao FK select do Django) no formulário, em vez de um input UUID cru. O label da opção vem do primeiro `search_fields` do admin referenciado (fallback: atributo `name`/`title`/`email`, depois o id). Limitado a 1000 linhas; FK para tabela não-gerenciada continua input UUID.
140
+
141
+ **MFA no login**: um principal com MFA habilitado (colunas `totp_secret`/`totp_enabled_at` do `MFAMixin`) passa por um desafio TOTP em `/admin/mfa` depois da senha — só um código válido libera o acesso. Habilite passando um usuário com MFA via `UserModelAuthBackend(UserModel, mfa_issuer=...)`; backends customizados sobrescrevem `mfa_enabled`/`verify_mfa`.
142
+
143
+ **Audit trail**: create/edit pelo admin carimba `created_by`/`updated_by` (do `AuditMixin`) com o id do admin atuante; o detail mostra um painel **Audit** com timestamps e — quando o modelo tem as colunas de auditoria — o ator (UUID resolvido para nome via o auth backend). Modelos sem `AuditMixin` mostram só os timestamps.
144
+
145
+ Ainda **não** incluídos (fases futuras do roadmap): upload de arquivo, inline/related editing.
146
+
147
+ !!! tip "Responsivo por padrão"
148
+ Os templates + CSS embutidos são responsivos: em telas estreitas (≤600px) o header empilha, busca/filtros/ações viram full-width, as tabelas ganham scroll horizontal (nunca quebram o layout) e o grid do detail colapsa para uma coluna. Headers de coluna são clicáveis para alternar a ordenação (▲/▼).
149
+
128
150
  #### 4. Defaults de segurança de sessão
129
151
 
130
152
  `SignedCookieSessionStore` usa `itsdangerous.TimestampSigner` (HMAC-SHA256) para assinar um único cookie:
@@ -167,7 +167,8 @@ Variables (with production-safe defaults):
167
167
  # .env — email flow
168
168
  AUTH_AUTO_ACTIVATE=false # true = skip activation, return JWT immediately
169
169
  AUTH_RETURN_TOKEN_IN_RESPONSE=false # true = link in body instead of email
170
- AUTH_PASSWORD_MIN_LENGTH=12
170
+ AUTH_PASSWORD_MIN_LENGTH=12 # fully configurable (1+, e.g. 4); single source of truth
171
+ AUTH_PASSWORD_REQUIRE_COMPLEXITY=false # true = require lowercase + uppercase + digit + special AND force a floor of 8
171
172
 
172
173
  # .env — token TTL
173
174
  AUTH_ACTIVATION_TTL_SECONDS=604800 # 7 days
@@ -167,7 +167,8 @@ Variáveis (com defaults seguros pra produção):
167
167
  # .env — fluxo de e-mail
168
168
  AUTH_AUTO_ACTIVATE=false # true = pula activation, devolve JWT direto
169
169
  AUTH_RETURN_TOKEN_IN_RESPONSE=false # true = link no body em vez de e-mail
170
- AUTH_PASSWORD_MIN_LENGTH=12
170
+ AUTH_PASSWORD_MIN_LENGTH=12 # totalmente configurável (1+, ex.: 4); fonte única da verdade
171
+ AUTH_PASSWORD_REQUIRE_COMPLEXITY=false # true = exige minúscula + maiúscula + dígito + especial E força piso de 8
171
172
 
172
173
  # .env — TTL dos tokens
173
174
  AUTH_ACTIVATION_TTL_SECONDS=604800 # 7 dias