nene2-python 1.8.17__tar.gz → 1.8.18__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 (256) hide show
  1. {nene2_python-1.8.17 → nene2_python-1.8.18}/CHANGELOG.md +12 -0
  2. {nene2_python-1.8.17 → nene2_python-1.8.18}/PKG-INFO +1 -1
  3. nene2_python-1.8.18/docs/field-trials/2026-05-field-trial-65.md +54 -0
  4. nene2_python-1.8.18/docs/field-trials/2026-05-field-trial-66.md +52 -0
  5. nene2_python-1.8.18/docs/field-trials/2026-05-field-trial-67.md +75 -0
  6. {nene2_python-1.8.17 → nene2_python-1.8.18}/pyproject.toml +1 -1
  7. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/database/sqlalchemy_executor.py +17 -1
  8. {nene2_python-1.8.17 → nene2_python-1.8.18}/uv.lock +1 -1
  9. {nene2_python-1.8.17 → nene2_python-1.8.18}/.env.example +0 -0
  10. {nene2_python-1.8.17 → nene2_python-1.8.18}/.github/workflows/ci.yml +0 -0
  11. {nene2_python-1.8.17 → nene2_python-1.8.18}/.github/workflows/docs.yml +0 -0
  12. {nene2_python-1.8.17 → nene2_python-1.8.18}/.github/workflows/publish.yml +0 -0
  13. {nene2_python-1.8.17 → nene2_python-1.8.18}/.gitignore +0 -0
  14. {nene2_python-1.8.17 → nene2_python-1.8.18}/.vitepress/config.mts +0 -0
  15. {nene2_python-1.8.17 → nene2_python-1.8.18}/.vitepress/theme/custom.css +0 -0
  16. {nene2_python-1.8.17 → nene2_python-1.8.18}/.vitepress/theme/index.ts +0 -0
  17. {nene2_python-1.8.17 → nene2_python-1.8.18}/AGENTS.md +0 -0
  18. {nene2_python-1.8.17 → nene2_python-1.8.18}/CLAUDE.md +0 -0
  19. {nene2_python-1.8.17 → nene2_python-1.8.18}/Dockerfile +0 -0
  20. {nene2_python-1.8.17 → nene2_python-1.8.18}/LICENSE +0 -0
  21. {nene2_python-1.8.17 → nene2_python-1.8.18}/README.md +0 -0
  22. {nene2_python-1.8.17 → nene2_python-1.8.18}/alembic/README +0 -0
  23. {nene2_python-1.8.17 → nene2_python-1.8.18}/alembic/env.py +0 -0
  24. {nene2_python-1.8.17 → nene2_python-1.8.18}/alembic/script.py.mako +0 -0
  25. {nene2_python-1.8.17 → nene2_python-1.8.18}/alembic/versions/001_create_notes_and_tags_tables.py +0 -0
  26. {nene2_python-1.8.17 → nene2_python-1.8.18}/alembic.ini +0 -0
  27. {nene2_python-1.8.17 → nene2_python-1.8.18}/compose.yaml +0 -0
  28. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/adr/0001-toolchain.md +0 -0
  29. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/adr/0002-clean-architecture.md +0 -0
  30. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/adr/0003-security-first.md +0 -0
  31. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/adr/0004-ai-first-design.md +0 -0
  32. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/adr/0005-logging.md +0 -0
  33. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/adr/0006-rate-limiting.md +0 -0
  34. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/adr/0009-mcp-design.md +0 -0
  35. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/adr/0010-async-use-case.md +0 -0
  36. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/adr/0011-mcp-as-core-dependency.md +0 -0
  37. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/de/index.md +0 -0
  38. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/de/tutorials/getting-started.md +0 -0
  39. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/explanation/architecture.md +0 -0
  40. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/explanation/design-philosophy.md +0 -0
  41. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-1.md +0 -0
  42. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-10.md +0 -0
  43. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-11.md +0 -0
  44. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-12.md +0 -0
  45. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-13.md +0 -0
  46. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-14.md +0 -0
  47. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-15.md +0 -0
  48. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-16.md +0 -0
  49. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-17.md +0 -0
  50. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-18.md +0 -0
  51. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-19.md +0 -0
  52. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-2.md +0 -0
  53. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-20.md +0 -0
  54. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-21.md +0 -0
  55. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-22.md +0 -0
  56. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-23.md +0 -0
  57. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-24.md +0 -0
  58. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-25.md +0 -0
  59. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-26.md +0 -0
  60. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-27.md +0 -0
  61. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-28.md +0 -0
  62. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-29.md +0 -0
  63. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-3.md +0 -0
  64. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-30.md +0 -0
  65. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-31.md +0 -0
  66. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-32.md +0 -0
  67. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-33.md +0 -0
  68. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-34.md +0 -0
  69. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-35.md +0 -0
  70. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-36.md +0 -0
  71. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-37.md +0 -0
  72. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-38.md +0 -0
  73. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-39.md +0 -0
  74. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-4.md +0 -0
  75. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-40.md +0 -0
  76. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-41.md +0 -0
  77. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-42.md +0 -0
  78. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-43.md +0 -0
  79. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-44.md +0 -0
  80. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-45.md +0 -0
  81. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-46.md +0 -0
  82. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-47.md +0 -0
  83. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-48.md +0 -0
  84. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-49.md +0 -0
  85. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-5.md +0 -0
  86. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-50.md +0 -0
  87. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-51.md +0 -0
  88. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-52.md +0 -0
  89. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-53.md +0 -0
  90. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-54.md +0 -0
  91. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-55.md +0 -0
  92. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-56.md +0 -0
  93. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-57.md +0 -0
  94. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-58.md +0 -0
  95. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-59.md +0 -0
  96. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-6.md +0 -0
  97. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-60.md +0 -0
  98. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-61.md +0 -0
  99. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-62.md +0 -0
  100. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-63.md +0 -0
  101. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-64.md +0 -0
  102. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-7.md +0 -0
  103. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-8.md +0 -0
  104. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/field-trials/2026-05-field-trial-9.md +0 -0
  105. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/fr/index.md +0 -0
  106. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/fr/tutorials/getting-started.md +0 -0
  107. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/how-to/add-new-domain.md +0 -0
  108. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/how-to/async-use-case.md +0 -0
  109. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/how-to/configure-auth.md +0 -0
  110. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/how-to/new-project.md +0 -0
  111. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/how-to/problem-details.md +0 -0
  112. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/how-to/run-tests.md +0 -0
  113. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/how-to/sqlalchemy-repository.md +0 -0
  114. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/how-to/validation.md +0 -0
  115. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/howto/mcp-setup.md +0 -0
  116. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/index.md +0 -0
  117. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/explanation/architecture.md +0 -0
  118. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/explanation/design-philosophy.md +0 -0
  119. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/how-to/add-new-domain.md +0 -0
  120. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/how-to/configure-auth.md +0 -0
  121. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/how-to/new-project.md +0 -0
  122. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/how-to/run-tests.md +0 -0
  123. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/how-to/sqlalchemy-repository.md +0 -0
  124. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/howto/mcp-setup.md +0 -0
  125. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/index.md +0 -0
  126. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/reference/api.md +0 -0
  127. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/reference/configuration.md +0 -0
  128. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/reference/framework-modules.md +0 -0
  129. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/tutorials/first-domain.md +0 -0
  130. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/ja/tutorials/getting-started.md +0 -0
  131. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/pt-br/index.md +0 -0
  132. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/pt-br/tutorials/getting-started.md +0 -0
  133. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/reference/api.md +0 -0
  134. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/reference/configuration.md +0 -0
  135. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/reference/framework-modules.md +0 -0
  136. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/roadmap.md +0 -0
  137. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/todo/current.md +0 -0
  138. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/tutorials/first-domain.md +0 -0
  139. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/tutorials/getting-started.md +0 -0
  140. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/zh/index.md +0 -0
  141. {nene2_python-1.8.17 → nene2_python-1.8.18}/docs/zh/tutorials/getting-started.md +0 -0
  142. {nene2_python-1.8.17 → nene2_python-1.8.18}/package-lock.json +0 -0
  143. {nene2_python-1.8.17 → nene2_python-1.8.18}/package.json +0 -0
  144. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/__init__.py +0 -0
  145. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/__main__.py +0 -0
  146. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/app.py +0 -0
  147. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/comment/__init__.py +0 -0
  148. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/comment/entity.py +0 -0
  149. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/comment/exceptions.py +0 -0
  150. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/comment/handler.py +0 -0
  151. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/comment/repository.py +0 -0
  152. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/comment/sqlalchemy_repository.py +0 -0
  153. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/comment/use_case.py +0 -0
  154. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/mcp.py +0 -0
  155. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/note/__init__.py +0 -0
  156. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/note/async_use_case.py +0 -0
  157. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/note/entity.py +0 -0
  158. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/note/exceptions.py +0 -0
  159. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/note/handler.py +0 -0
  160. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/note/repository.py +0 -0
  161. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/note/sqlalchemy_repository.py +0 -0
  162. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/note/use_case.py +0 -0
  163. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/schema.py +0 -0
  164. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/tag/__init__.py +0 -0
  165. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/tag/entity.py +0 -0
  166. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/tag/exceptions.py +0 -0
  167. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/tag/handler.py +0 -0
  168. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/tag/repository.py +0 -0
  169. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/tag/sqlalchemy_repository.py +0 -0
  170. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/example/tag/use_case.py +0 -0
  171. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/__init__.py +0 -0
  172. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/auth/__init__.py +0 -0
  173. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/auth/api_key.py +0 -0
  174. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/auth/bearer_token.py +0 -0
  175. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/auth/exceptions.py +0 -0
  176. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/auth/interfaces.py +0 -0
  177. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/auth/local_verifier.py +0 -0
  178. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/config/__init__.py +0 -0
  179. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/config/settings.py +0 -0
  180. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/database/__init__.py +0 -0
  181. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/database/exceptions.py +0 -0
  182. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/database/health.py +0 -0
  183. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/database/interfaces.py +0 -0
  184. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/database/utils.py +0 -0
  185. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/http/__init__.py +0 -0
  186. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/http/health.py +0 -0
  187. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/http/pagination.py +0 -0
  188. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/http/problem_details.py +0 -0
  189. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/log/__init__.py +0 -0
  190. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/log/setup.py +0 -0
  191. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/mcp/__init__.py +0 -0
  192. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/mcp/http_client.py +0 -0
  193. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/mcp/server.py +0 -0
  194. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/middleware/__init__.py +0 -0
  195. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/middleware/domain_exception.py +0 -0
  196. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/middleware/error_handler.py +0 -0
  197. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/middleware/request_id.py +0 -0
  198. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/middleware/request_logging.py +0 -0
  199. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/middleware/request_size_limit.py +0 -0
  200. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/middleware/security_headers.py +0 -0
  201. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/middleware/throttle.py +0 -0
  202. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/py.typed +0 -0
  203. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/use_case/__init__.py +0 -0
  204. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/use_case/protocols.py +0 -0
  205. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/validation/__init__.py +0 -0
  206. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/nene2/validation/exceptions.py +0 -0
  207. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/scripts/__init__.py +0 -0
  208. {nene2_python-1.8.17 → nene2_python-1.8.18}/src/scripts/export_openapi.py +0 -0
  209. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/__init__.py +0 -0
  210. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/__init__.py +0 -0
  211. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/comment/__init__.py +0 -0
  212. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/comment/test_comment_http.py +0 -0
  213. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/comment/test_comment_repository.py +0 -0
  214. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/comment/test_comment_use_case.py +0 -0
  215. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/conftest.py +0 -0
  216. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/note/__init__.py +0 -0
  217. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/note/test_async_note_use_case.py +0 -0
  218. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/note/test_list_notes.py +0 -0
  219. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/note/test_note_repository.py +0 -0
  220. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/tag/__init__.py +0 -0
  221. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/tag/test_tag_repository.py +0 -0
  222. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/tag/test_tags.py +0 -0
  223. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/test_cors.py +0 -0
  224. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/example/test_mcp.py +0 -0
  225. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/__init__.py +0 -0
  226. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/auth/__init__.py +0 -0
  227. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/auth/test_api_key.py +0 -0
  228. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/auth/test_bearer_token.py +0 -0
  229. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/auth/test_token_issuer.py +0 -0
  230. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/config/__init__.py +0 -0
  231. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/config/test_settings.py +0 -0
  232. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/database/__init__.py +0 -0
  233. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/database/test_transaction.py +0 -0
  234. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/database/test_utils.py +0 -0
  235. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/http/__init__.py +0 -0
  236. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/http/test_health.py +0 -0
  237. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/http/test_pagination.py +0 -0
  238. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/http/test_problem_details.py +0 -0
  239. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/log/__init__.py +0 -0
  240. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/log/test_setup.py +0 -0
  241. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/mcp/__init__.py +0 -0
  242. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/mcp/test_http_client.py +0 -0
  243. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/middleware/__init__.py +0 -0
  244. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/middleware/test_error_handler.py +0 -0
  245. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/middleware/test_request_id.py +0 -0
  246. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/middleware/test_request_logging.py +0 -0
  247. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/middleware/test_request_size_limit.py +0 -0
  248. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/middleware/test_security_headers.py +0 -0
  249. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/middleware/test_simple_domain_handler.py +0 -0
  250. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/middleware/test_throttle.py +0 -0
  251. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/use_case/__init__.py +0 -0
  252. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/use_case/test_protocols.py +0 -0
  253. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/validation/__init__.py +0 -0
  254. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/nene2/validation/test_exceptions.py +0 -0
  255. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/scripts/__init__.py +0 -0
  256. {nene2_python-1.8.17 → nene2_python-1.8.18}/tests/scripts/test_export_openapi.py +0 -0
@@ -5,6 +5,18 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
6
  ---
7
7
 
8
+ ## [1.8.18] — 2026-05-20
9
+
10
+ FT67 フィールドトライアル — SqlAlchemyTransactionManager 実運用検証。
11
+
12
+ ### Changed
13
+ - `SqlAlchemyQueryExecutor` の docstring に SQLite `:memory:` + `StaticPool` の注意書きを追加 (#305) (FT67)
14
+
15
+ ### Added
16
+ - Field trial reports: `docs/field-trials/2026-05-field-trial-65.md` 〜 `2026-05-field-trial-67.md` (FT65〜FT67)
17
+
18
+ ---
19
+
8
20
  ## [1.8.17] — 2026-05-20
9
21
 
10
22
  FT64 フィールドトライアル — ValidationException 複数エラー実運用検証。
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nene2-python
3
- Version: 1.8.17
3
+ Version: 1.8.18
4
4
  Summary: NENE2 Python — minimal API framework following NENE2's design philosophy
5
5
  Project-URL: Homepage, https://github.com/hideyukiMORI/nene2-python
6
6
  Project-URL: Repository, https://github.com/hideyukiMORI/nene2-python
@@ -0,0 +1,54 @@
1
+ # FT65: DatabaseHealthCheck 実運用検証
2
+
3
+ **日付**: 2026-05-20
4
+ **テーマ**: DB接続ヘルスチェック (`DatabaseHealthCheck`) と `CompositeHealthCheck` の組み合わせ実運用確認
5
+ **バージョン**: v1.8.17
6
+ **FTディレクトリ**: `/home/xi/docker/nene2-python-FT/ft65-db-health/`
7
+
8
+ ---
9
+
10
+ ## 概要
11
+
12
+ `nene2.database.DatabaseHealthCheck` を `SqlAlchemyQueryExecutor` と組み合わせ、
13
+ `CompositeHealthCheck` に渡して FastAPI の `/health` エンドポイントで利用するパターンを検証した。
14
+ SQLite in-memory DB(正常)と存在しない DB(異常)の両方を確認。
15
+
16
+ ---
17
+
18
+ ## 実装内容
19
+
20
+ - `SqlAlchemyQueryExecutor(create_engine("sqlite:///:memory:"))`: SQLite in-memory DB
21
+ - `DatabaseHealthCheck(executor)`: `SELECT 1` で接続確認
22
+ - `CompositeHealthCheck([db_health])`: 集約して `/health` で返却
23
+ - 存在しない DB パスで 503 になることも確認
24
+
25
+ ---
26
+
27
+ ## テスト結果
28
+
29
+ **4/4 passed**
30
+
31
+ | テスト | 結果 |
32
+ |---|---|
33
+ | `test_healthy_db_returns_200` | PASSED |
34
+ | `test_broken_db_returns_503` | PASSED |
35
+ | `test_direct_database_health_check` | PASSED |
36
+ | `test_in_memory_db_composite_check` | PASSED |
37
+
38
+ ---
39
+
40
+ ## Friction Points
41
+
42
+ なし。`DatabaseHealthCheck` → `CompositeHealthCheck` → FastAPI の流れは直感的で問題なし。
43
+
44
+ **特筆点**:
45
+ - `DatabaseHealthCheck` の `SELECT 1` は軽量で本番運用に適している
46
+ - DB 接続失敗時は例外をキャッチして `status="error"` を返す設計で、
47
+ ヘルスエンドポイント自体が 500 になることがない
48
+
49
+ ---
50
+
51
+ ## 結論
52
+
53
+ `DatabaseHealthCheck` は実運用で問題なく使用できる。
54
+ `SqlAlchemyQueryExecutor` と `CompositeHealthCheck` の組み合わせが自然に機能する。
@@ -0,0 +1,52 @@
1
+ # FT66: AppSettings 実運用検証
2
+
3
+ **日付**: 2026-05-20
4
+ **テーマ**: 型付き設定オブジェクト (`AppSettings`) の実運用確認
5
+ **バージョン**: v1.8.17
6
+ **FTディレクトリ**: `/home/xi/docker/nene2-python-FT/ft66-app-settings/`
7
+
8
+ ---
9
+
10
+ ## 概要
11
+
12
+ `nene2.config.AppSettings` を直接インスタンス化し、環境変数によるオーバーライド・
13
+ バリデーション・`db_url` プロパティ・`SecretStr` の動作を検証した。
14
+
15
+ ---
16
+
17
+ ## 実装内容
18
+
19
+ - `AppSettings()`: デフォルト値確認
20
+ - `monkeypatch.setenv()`: 環境変数でのオーバーライド
21
+ - 不正値(`APP_ENV=staging`、`LOG_LEVEL=VERBOSE`)でのバリデーション確認
22
+ - `db_url` プロパティで SQLAlchemy URL 生成を確認
23
+ - `CORS_ORIGINS` の JSON リスト形式パース確認
24
+
25
+ ---
26
+
27
+ ## テスト結果
28
+
29
+ **10/10 passed**
30
+
31
+ ---
32
+
33
+ ## Friction Points
34
+
35
+ ### FP-1 (軽微): `str(SecretStr(""))` が `""` を返す
36
+
37
+ **発生箇所**: `assert str(settings.db_password) != ""` テストが失敗
38
+
39
+ **症状**: 空の `SecretStr("")` を `str()` に渡すと `""` が返る(マスクされない)。
40
+ 非空 `SecretStr("secret")` は `**********` が返る。
41
+
42
+ **原因**: Pydantic の設計上の挙動で、空文字列は空文字列のまま。
43
+ `repr()` では `SecretStr('')` と表示される。
44
+
45
+ **対応**: テストを `get_secret_value() == ""` で修正。フレームワーク側は変更不要。
46
+
47
+ ---
48
+
49
+ ## 結論
50
+
51
+ `AppSettings` は実運用で問題なく使用できる。
52
+ 環境変数からの自動パース(bool・int・list[str] の JSON 形式)が便利。
@@ -0,0 +1,75 @@
1
+ # FT67: SqlAlchemyTransactionManager 実運用検証
2
+
3
+ **日付**: 2026-05-20
4
+ **テーマ**: トランザクション管理 (`SqlAlchemyTransactionManager`) の実運用確認
5
+ **バージョン**: v1.8.17 → v1.8.18 (ドキュメント追加)
6
+ **FTディレクトリ**: `/home/xi/docker/nene2-python-FT/ft67-transaction-manager/`
7
+
8
+ ---
9
+
10
+ ## 概要
11
+
12
+ `nene2.database.SqlAlchemyTransactionManager` を使って口座振替アプリを実装し、
13
+ `transactional()` コールバック API・ロールバック動作・コミット確認を検証した。
14
+
15
+ ---
16
+
17
+ ## 実装内容
18
+
19
+ - SQLite in-memory DB に `accounts` テーブルを作成
20
+ - `transactional(callback)`: 振替処理を 1 トランザクションで実行
21
+ - 残高不足時は `ValueError` を raise → ロールバック
22
+ - GET `/accounts/{name}` と POST `/transfers` エンドポイント
23
+
24
+ ---
25
+
26
+ ## テスト結果
27
+
28
+ **7/7 passed** (StaticPool 修正後)
29
+
30
+ | テスト | 結果 |
31
+ |---|---|
32
+ | `test_get_existing_account` | PASSED |
33
+ | `test_get_nonexistent_account_returns_404` | PASSED |
34
+ | `test_successful_transfer` | PASSED |
35
+ | `test_insufficient_balance_returns_422` | PASSED |
36
+ | `test_transaction_rollback_on_error` | PASSED |
37
+ | `test_transfer_to_nonexistent_account` | PASSED |
38
+ | `test_transactional_commits_on_success` | PASSED |
39
+
40
+ ---
41
+
42
+ ## Friction Points
43
+
44
+ ### FP-1: SQLite `:memory:` と `SqlAlchemyQueryExecutor` の接続分離問題
45
+
46
+ **発生箇所**: `setup_db()` でテーブル作成後、`executor.fetch_one()` が `no such table: accounts` エラー
47
+
48
+ **症状**:
49
+ ```
50
+ DatabaseConnectionException: (sqlite3.OperationalError) no such table: accounts
51
+ ```
52
+
53
+ **原因**: SQLAlchemy のデフォルトコネクションプールでは `sqlite:///:memory:` への接続ごとに
54
+ 新しいインメモリDBが生成される。`setup_db()` と `executor.fetch_one()` が別DBを参照する。
55
+
56
+ **修正**:
57
+ ```python
58
+ from sqlalchemy.pool import StaticPool
59
+
60
+ engine = create_engine(
61
+ "sqlite:///:memory:",
62
+ connect_args={"check_same_thread": False},
63
+ poolclass=StaticPool,
64
+ )
65
+ ```
66
+
67
+ `SqlAlchemyQueryExecutor` の docstring に注意書きを追加 (Issue #305, v1.8.18)。
68
+
69
+ ---
70
+
71
+ ## 結論
72
+
73
+ `SqlAlchemyTransactionManager.transactional()` は実運用で問題なく使用できる。
74
+ コールバック内の例外でロールバックが正しく機能することも確認。
75
+ SQLite in-memory DB 使用時の `StaticPool` 要件はドキュメント化済み。
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nene2-python"
3
- version = "1.8.17"
3
+ version = "1.8.18"
4
4
  description = "NENE2 Python — minimal API framework following NENE2's design philosophy"
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}
@@ -14,7 +14,23 @@ from .interfaces import DatabaseQueryExecutorInterface, DatabaseTransactionManag
14
14
 
15
15
 
16
16
  class SqlAlchemyQueryExecutor(DatabaseQueryExecutorInterface):
17
- """Execute queries using SQLAlchemy Core (connection-per-call, no ORM)."""
17
+ """Execute queries using SQLAlchemy Core (connection-per-call, no ORM).
18
+
19
+ .. note:: SQLite in-memory databases
20
+
21
+ When using ``sqlite:///:memory:`` in tests, each new connection receives
22
+ a separate empty database. To share one in-memory DB across all
23
+ connections (including ``setup_db`` / schema creation) use
24
+ ``StaticPool``::
25
+
26
+ from sqlalchemy.pool import StaticPool
27
+
28
+ engine = create_engine(
29
+ "sqlite:///:memory:",
30
+ connect_args={"check_same_thread": False},
31
+ poolclass=StaticPool,
32
+ )
33
+ """
18
34
 
19
35
  def __init__(self, engine: Engine) -> None:
20
36
  self._engine = engine
@@ -925,7 +925,7 @@ wheels = [
925
925
 
926
926
  [[package]]
927
927
  name = "nene2-python"
928
- version = "1.8.17"
928
+ version = "1.8.18"
929
929
  source = { editable = "." }
930
930
  dependencies = [
931
931
  { name = "alembic" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes