tina4-python 3.13.122__tar.gz → 3.13.124__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 (170) hide show
  1. {tina4_python-3.13.122 → tina4_python-3.13.124}/PKG-INFO +1 -1
  2. {tina4_python-3.13.122 → tina4_python-3.13.124}/pyproject.toml +1 -1
  3. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/__init__.py +1 -1
  4. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/cli/__init__.py +26 -1
  5. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/session/__init__.py +21 -7
  6. {tina4_python-3.13.122 → tina4_python-3.13.124}/.gitignore +0 -0
  7. {tina4_python-3.13.122 → tina4_python-3.13.124}/README.md +0 -0
  8. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/CLAUDE.md +0 -0
  9. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/HtmlElement.py +0 -0
  10. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/Testing.py +0 -0
  11. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/_import_helper.py +0 -0
  12. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/ai/__init__.py +0 -0
  13. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/ai/client.py +0 -0
  14. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/api/__init__.py +0 -0
  15. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/auth/__init__.py +0 -0
  16. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/cache/__init__.py +0 -0
  17. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/container/__init__.py +0 -0
  18. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/context/__init__.py +0 -0
  19. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/context/chunker.py +0 -0
  20. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/core/__init__.py +0 -0
  21. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/core/cache.py +0 -0
  22. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/core/constants.py +0 -0
  23. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/core/events.py +0 -0
  24. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/core/middleware.py +0 -0
  25. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/core/port_takeover.py +0 -0
  26. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/core/rate_limiter.py +0 -0
  27. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/core/request.py +0 -0
  28. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/core/response.py +0 -0
  29. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/core/router.py +0 -0
  30. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/core/server.py +0 -0
  31. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/crud/__init__.py +0 -0
  32. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/database/__init__.py +0 -0
  33. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/database/adapter.py +0 -0
  34. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/database/connection.py +0 -0
  35. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/database/database_url.py +0 -0
  36. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/database/firebird.py +0 -0
  37. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/database/mongodb.py +0 -0
  38. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/database/mssql.py +0 -0
  39. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/database/mysql.py +0 -0
  40. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/database/odbc.py +0 -0
  41. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/database/postgres.py +0 -0
  42. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/database/sql_translator.py +0 -0
  43. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/database/sqlite.py +0 -0
  44. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/debug/__init__.py +0 -0
  45. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/debug/error_overlay.py +0 -0
  46. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/dev_admin/__init__.py +0 -0
  47. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/dev_admin/metrics.py +0 -0
  48. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/dev_admin/plan.py +0 -0
  49. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/dev_admin/project_index.py +0 -0
  50. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/docs.py +0 -0
  51. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/docstore/__init__.py +0 -0
  52. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/dotenv/__init__.py +0 -0
  53. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/env.py +0 -0
  54. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/frond/FROND.md +0 -0
  55. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/frond/__init__.py +0 -0
  56. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/frond/compiler.py +0 -0
  57. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/frond/engine.py +0 -0
  58. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/frond/parser.py +0 -0
  59. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/auth/meta.json +0 -0
  60. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/auth/src/routes/api/gallery_auth.py +0 -0
  61. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/database/meta.json +0 -0
  62. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/database/src/routes/api/gallery_db.py +0 -0
  63. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/error-overlay/meta.json +0 -0
  64. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/error-overlay/src/routes/api/gallery_crash.py +0 -0
  65. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/orm/meta.json +0 -0
  66. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/orm/src/orm/Product.py +0 -0
  67. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/orm/src/routes/api/gallery_products.py +0 -0
  68. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/queue/meta.json +0 -0
  69. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/queue/src/routes/api/gallery_queue.py +0 -0
  70. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/rest-api/meta.json +0 -0
  71. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/rest-api/src/routes/api/gallery_hello.py +0 -0
  72. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/templates/meta.json +0 -0
  73. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/templates/src/routes/gallery_page.py +0 -0
  74. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/gallery/templates/src/templates/gallery_page.twig +0 -0
  75. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/graph/__init__.py +0 -0
  76. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/graph/adapter.py +0 -0
  77. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/graph/adapters/__init__.py +0 -0
  78. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/graph/adapters/arango.py +0 -0
  79. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/graph/adapters/bolt.py +0 -0
  80. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/graph/adapters/ultipa.py +0 -0
  81. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/graph/graph_url.py +0 -0
  82. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/graphql/__init__.py +0 -0
  83. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/i18n/__init__.py +0 -0
  84. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/mcp/__init__.py +0 -0
  85. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/mcp/protocol.py +0 -0
  86. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/mcp/tools.py +0 -0
  87. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/messenger/__init__.py +0 -0
  88. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/migration/__init__.py +0 -0
  89. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/migration/runner.py +0 -0
  90. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/mqtt/__init__.py +0 -0
  91. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/mqtt/message.py +0 -0
  92. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/orm/__init__.py +0 -0
  93. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/orm/fields.py +0 -0
  94. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/orm/model.py +0 -0
  95. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/orm/point.py +0 -0
  96. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/public/__feedback/widget.js +0 -0
  97. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/public/css/tina4.css +0 -0
  98. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/public/css/tina4.min.css +0 -0
  99. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/public/favicon.ico +0 -0
  100. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/public/images/logo.svg +0 -0
  101. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/public/images/tina4-logo-icon.webp +0 -0
  102. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/public/js/frond.js +0 -0
  103. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/public/js/frond.min.js +0 -0
  104. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/public/js/tina4-dev-admin.min.js +0 -0
  105. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/public/js/tina4.min.js +0 -0
  106. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/public/js/tina4js.min.js +0 -0
  107. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/public/swagger/index.html +0 -0
  108. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
  109. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/query_builder/__init__.py +0 -0
  110. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/queue/__init__.py +0 -0
  111. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/queue/amqp_url.py +0 -0
  112. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/queue/job.py +0 -0
  113. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/queue/kafka_backend.py +0 -0
  114. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/queue/lite_backend.py +0 -0
  115. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/queue/mongo_backend.py +0 -0
  116. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/queue/rabbitmq_backend.py +0 -0
  117. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/queue_backends/__init__.py +0 -0
  118. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/queue_backends/kafka_backend.py +0 -0
  119. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/queue_backends/mongo_backend.py +0 -0
  120. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/queue_backends/rabbitmq_backend.py +0 -0
  121. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/realtime/__init__.py +0 -0
  122. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/realtime/models/Attachment.py +0 -0
  123. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/realtime/models/Channel.py +0 -0
  124. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/realtime/models/ChannelMember.py +0 -0
  125. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/realtime/models/Message.py +0 -0
  126. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/realtime/models/Workspace.py +0 -0
  127. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/realtime/models/__init__.py +0 -0
  128. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/realtime/storage.py +0 -0
  129. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/seeder/__init__.py +0 -0
  130. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/service/__init__.py +0 -0
  131. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/session_handlers/__init__.py +0 -0
  132. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/session_handlers/memcached_handler.py +0 -0
  133. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/session_handlers/mongodb_handler.py +0 -0
  134. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/session_handlers/redis_handler.py +0 -0
  135. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/session_handlers/valkey_handler.py +0 -0
  136. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/sso.py +0 -0
  137. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/swagger/__init__.py +0 -0
  138. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/components/crud.twig +0 -0
  139. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/docker/distroless/Dockerfile +0 -0
  140. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/docker/poetry/Dockerfile +0 -0
  141. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/docker/python/Dockerfile +0 -0
  142. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/docker/uv/Dockerfile +0 -0
  143. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/errors/302.twig +0 -0
  144. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/errors/401.twig +0 -0
  145. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/errors/403.twig +0 -0
  146. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/errors/404.twig +0 -0
  147. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/errors/500.twig +0 -0
  148. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/errors/502.twig +0 -0
  149. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/errors/503.twig +0 -0
  150. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/errors/base.twig +0 -0
  151. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/frontend/README.md +0 -0
  152. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/templates/readme.md +0 -0
  153. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/test/__init__.py +0 -0
  154. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/test_client/__init__.py +0 -0
  155. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/translations/af/LC_MESSAGES/messages.mo +0 -0
  156. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/translations/af/LC_MESSAGES/messages.po +0 -0
  157. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
  158. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
  159. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/translations/es/LC_MESSAGES/messages.mo +0 -0
  160. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/translations/es/LC_MESSAGES/messages.po +0 -0
  161. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
  162. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
  163. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/translations/ja/LC_MESSAGES/messages.mo +0 -0
  164. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/translations/ja/LC_MESSAGES/messages.po +0 -0
  165. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/translations/zh/LC_MESSAGES/messages.mo +0 -0
  166. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/translations/zh/LC_MESSAGES/messages.po +0 -0
  167. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/validator/__init__.py +0 -0
  168. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/websocket/__init__.py +0 -0
  169. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/websocket/backplane.py +0 -0
  170. {tina4_python-3.13.122 → tina4_python-3.13.124}/tina4_python/wsdl/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: tina4-python
3
- Version: 3.13.122
3
+ Version: 3.13.124
4
4
  Summary: Tina4 Python v3 — Zero-dependency, lightweight web framework
5
5
  Author-email: Andre van Zuydam <andrevanzuydam@gmail.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tina4-python"
3
- version = "3.13.122"
3
+ version = "3.13.124"
4
4
  description = "Tina4 Python v3 — Zero-dependency, lightweight web framework"
5
5
  authors = [
6
6
  {name = "Andre van Zuydam", email = "andrevanzuydam@gmail.com"}
@@ -51,7 +51,7 @@ def _resolve_version() -> str:
51
51
  #
52
52
  # test_version_constant.py now asserts this literal equals the pyproject
53
53
  # version, so the release bump cannot leave it behind again.
54
- return "3.13.122"
54
+ return "3.13.124"
55
55
 
56
56
 
57
57
  __version__ = _resolve_version()
@@ -1003,7 +1003,7 @@ def _ai(args):
1003
1003
  # The four generators wired for the envelope. Others (crud, service, queue,
1004
1004
  # validator, seeder, websocket, listener, auth, test, form, view) keep their
1005
1005
  # existing behaviour — this is the minimum surface the plan calls out.
1006
- _RESOLUTION_TARGETS = {"model", "route", "migration", "middleware"}
1006
+ _RESOLUTION_TARGETS = {"model", "route", "migration", "middleware", "queue"}
1007
1007
 
1008
1008
  # Envelope schema version. Bump when the SHAPE changes; adding an optional
1009
1009
  # key on the resolution object is not a break.
@@ -1149,6 +1149,16 @@ def _next_steps_for(target: str, name: str, resolution: dict, flags: dict) -> li
1149
1149
  f"Run the co-emitted test: .venv/bin/python -m pytest tests/test_{snake}.py",
1150
1150
  ]
1151
1151
 
1152
+ if target == "queue":
1153
+ topic = name.lstrip("/")
1154
+ slug = _to_snake(re.sub(r"[^0-9a-zA-Z]+", "_", topic)).strip("_") or "topic"
1155
+ return [
1156
+ f"Edit src/services/{slug}_consumer.py: implement handle_{slug}(data) to process ONE job",
1157
+ f"Produce a job: from src.services.{slug}_consumer import publish_{slug}; publish_{slug}({{...}})",
1158
+ f"The consumer is discovered by ServiceRunner (src/services); tina4 serve runs it",
1159
+ f"Run the co-emitted test: .venv/bin/python -m pytest tests/test_{slug}.py",
1160
+ ]
1161
+
1152
1162
  return []
1153
1163
 
1154
1164
 
@@ -1236,6 +1246,21 @@ def _resolve_generation(target: str, name: str, flags: dict,
1236
1246
  "test_paths": [f"tests/test_{snake}.py"],
1237
1247
  }
1238
1248
 
1249
+ if target == "queue":
1250
+ # Slug computed EXACTLY as _gen_queue does, so the envelope's paths
1251
+ # equal the on-disk filenames byte-for-byte.
1252
+ topic = name.lstrip("/")
1253
+ slug = _to_snake(re.sub(r"[^0-9a-zA-Z]+", "_", topic)).strip("_") or "topic"
1254
+ return {
1255
+ "class_name": None,
1256
+ "table_name": None,
1257
+ "file_path": f"src/services/{slug}_consumer.py",
1258
+ "migration_path": None,
1259
+ "transformations": [],
1260
+ "routes": [],
1261
+ "test_paths": [f"tests/test_{slug}.py"],
1262
+ }
1263
+
1239
1264
  return {} # never reached; guarded by _RESOLUTION_TARGETS
1240
1265
 
1241
1266
 
@@ -174,18 +174,32 @@ class DatabaseSessionHandler(SessionHandler):
174
174
  # The table is now created on first use, inside that policy.
175
175
  self._table_ready = False
176
176
 
177
+ # The portable statement that shipped for every engine. VARCHAR(255) carries
178
+ # TEXT affinity and DOUBLE PRECISION an 8-byte float on SQLite; it is DOUBLE
179
+ # PRECISION (never REAL - REAL is single-precision float4 on PostgreSQL, which
180
+ # test_session_expiry_contract pins) on the networked engines. Correct on
181
+ # sqlite/postgres/mysql/mssql, which is why it was never per-engine before.
182
+ _CREATE_TABLE_DEFAULT = "CREATE TABLE tina4_session (session_id VARCHAR(255) PRIMARY KEY, data TEXT NOT NULL, expires_at DOUBLE PRECISION NOT NULL)"
183
+ # Firebird is the one engine that needs a different statement: it has NO TEXT
184
+ # type, so the payload must be a VARCHAR (ceiling 8191 characters on this
185
+ # engine alone), matching PHP/Ruby/Node. The prior single "data TEXT" CREATE
186
+ # failed on Firebird with -607 "source column TEXT does not exist", so the
187
+ # database session backend never worked there. table_exists() below covers
188
+ # Firebird's lack of IF NOT EXISTS.
189
+ _CREATE_TABLE_SQL = {
190
+ "firebird": "CREATE TABLE tina4_session (session_id VARCHAR(255) NOT NULL PRIMARY KEY, data VARCHAR(8191) NOT NULL, expires_at DOUBLE PRECISION NOT NULL)",
191
+ }
192
+
177
193
  def _ensure_table(self):
178
194
  if self._table_ready:
179
195
  return
180
196
  self._table_ready = True
181
197
  if not self._db.table_exists("tina4_session"):
182
- self._db.execute("""
183
- CREATE TABLE tina4_session (
184
- session_id VARCHAR(255) PRIMARY KEY,
185
- data TEXT NOT NULL,
186
- expires_at DOUBLE PRECISION NOT NULL
187
- )
188
- """)
198
+ try:
199
+ engine = (self._db.get_database_type() or "").lower()
200
+ except Exception:
201
+ engine = ""
202
+ self._db.execute(self._CREATE_TABLE_SQL.get(engine, self._CREATE_TABLE_DEFAULT))
189
203
  self._db.commit()
190
204
 
191
205
  def read(self, session_id: str) -> dict: