fastapi-fullstack 0.2.5__tar.gz → 0.2.7__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 (433) hide show
  1. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/PKG-INFO +17 -16
  2. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/README.md +1 -0
  3. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/fastapi_gen/cli.py +42 -6
  4. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/fastapi_gen/config.py +10 -0
  5. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/pyproject.toml +19 -18
  6. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/hooks/post_gen_project.py +72 -1
  7. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.gitignore +1 -1
  8. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/README.md +12 -0
  9. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/.env.example +1 -1
  10. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/alembic/env.py +24 -0
  11. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/deps.py +81 -16
  12. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/exception_handlers.py +6 -15
  13. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/__init__.py +4 -1
  14. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/admin_conversations.py +166 -0
  15. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/admin_ratings.py +261 -0
  16. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/agent.py +169 -400
  17. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/channels.py +33 -33
  18. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/conversations.py +331 -22
  19. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/files.py +14 -15
  20. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/health.py +4 -21
  21. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/oauth.py +21 -85
  22. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/projects.py +1 -1
  23. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/rag.py +50 -255
  24. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/sessions.py +4 -49
  25. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/slack_webhook.py +76 -0
  26. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/telegram_webhook.py +123 -0
  27. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/users.py +39 -45
  28. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/webhooks.py +65 -26
  29. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/channels/router.py +8 -5
  30. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/channels/slack.py +2 -3
  31. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/channels/telegram.py +2 -3
  32. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/commands/channel.py +270 -0
  33. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/commands/rag.py +24 -42
  34. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/commands/seed.py +42 -77
  35. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/config.py +1 -1
  36. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/__init__.py +4 -0
  37. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/db/models/message_rating.py +295 -0
  38. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/session.py +5 -0
  39. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/ingestion.py +24 -0
  40. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/vectorstore.py +38 -0
  41. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/__init__.py +2 -0
  42. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/chat_file.py +47 -0
  43. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/conversation.py +377 -1
  44. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/repositories/message_rating.py +661 -0
  45. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/rag_document.py +22 -0
  46. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/sync_log.py +4 -0
  47. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/user.py +152 -0
  48. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/webhook.py +48 -0
  49. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/conversation.py +19 -0
  50. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/file.py +2 -2
  51. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/schemas/message_rating.py +126 -0
  52. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/user.py +16 -1
  53. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/services/agent.py +41 -0
  54. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/channel_bot.py +42 -3
  55. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/conversation.py +663 -60
  56. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/file_upload.py +18 -20
  57. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/services/health.py +23 -0
  58. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/services/message_rating.py +1193 -0
  59. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/project.py +3 -3
  60. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/rag_document.py +107 -83
  61. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/rag_sync.py +84 -60
  62. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/session.py +57 -0
  63. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/sync_source.py +113 -48
  64. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/user.py +202 -0
  65. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/webhook.py +6 -8
  66. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/tasks/__init__.py +1 -0
  67. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/tasks/channel.py +35 -0
  68. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/tasks/rag.py +140 -0
  69. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/rag_tasks.py +34 -50
  70. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/pyproject.toml +23 -0
  71. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_services_conversation.py +15 -6
  72. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/architecture.md +4 -0
  73. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/configuration.md +1 -1
  74. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/docs/howto/use-ratings.md +132 -0
  75. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/permissions.md +11 -0
  76. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/.editorconfig +12 -0
  77. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/.husky/pre-commit +1 -0
  78. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/.prettierrc +1 -1
  79. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/eslint.config.mjs +5 -4
  80. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/messages/en.json +84 -3
  81. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/messages/pl.json +84 -3
  82. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/package.json +12 -0
  83. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/admin/conversations/page.tsx +354 -0
  84. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/admin/ratings/page.tsx +336 -0
  85. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/chat/page.tsx +29 -0
  86. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/dashboard/page.tsx +40 -0
  87. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/rag/page.tsx +3 -2
  88. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/login/route.ts +3 -1
  89. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/me/route.ts +4 -1
  90. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/refresh/route.ts +4 -1
  91. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/[id]/messages/[messageId]/rate/route.ts +95 -0
  92. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/admin/conversations/route.ts +48 -0
  93. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/admin/ratings/export/route.ts +58 -0
  94. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/admin/ratings/route.ts +42 -0
  95. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/admin/ratings/summary/route.ts +35 -0
  96. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/auth/login-form.tsx +12 -10
  97. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/auth/register-form.tsx +15 -13
  98. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-container.tsx +21 -4
  99. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-input.tsx +3 -2
  100. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/conversation-sidebar.tsx +14 -10
  101. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-item.tsx +25 -1
  102. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/rating-buttons.tsx +257 -0
  103. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/share-dialog.tsx +52 -16
  104. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-approval-dialog.tsx +2 -2
  105. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-call-card.tsx +8 -8
  106. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/breadcrumb.tsx +2 -1
  107. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/theme/theme-toggle.tsx +2 -2
  108. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-auth.ts +18 -8
  109. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-chat.ts +70 -8
  110. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-conversations.ts +7 -0
  111. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-websocket.ts +5 -2
  112. fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/lib/admin-auth.ts +47 -0
  113. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/constants.ts +4 -0
  114. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/server-api.ts +7 -1
  115. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/auth-store.ts +7 -0
  116. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/chat-store.ts +9 -0
  117. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/chat.ts +20 -0
  118. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/conversation.ts +42 -0
  119. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/tsconfig.json +1 -0
  120. fastapi_fullstack-0.2.5/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/admin_conversations.py +0 -400
  121. fastapi_fullstack-0.2.5/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/slack_webhook.py +0 -128
  122. fastapi_fullstack-0.2.5/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/telegram_webhook.py +0 -181
  123. fastapi_fullstack-0.2.5/template/{{cookiecutter.project_slug}}/backend/app/commands/channel.py +0 -309
  124. fastapi_fullstack-0.2.5/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/admin/conversations/page.tsx +0 -273
  125. fastapi_fullstack-0.2.5/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/chat/page.tsx +0 -16
  126. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/.gitignore +0 -0
  127. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/LICENSE +0 -0
  128. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/fastapi_gen/__init__.py +0 -0
  129. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/fastapi_gen/generator.py +0 -0
  130. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/fastapi_gen/prompts.py +0 -0
  131. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/VARIABLES.md +0 -0
  132. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/cookiecutter.json +0 -0
  133. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/commands/add-endpoint.md +0 -0
  134. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/commands/fix-issue.md +0 -0
  135. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/commands/review.md +0 -0
  136. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/api-conventions.md +0 -0
  137. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/architecture.md +0 -0
  138. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/code-style.md +0 -0
  139. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/exceptions-security.md +0 -0
  140. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/frontend.md +0 -0
  141. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/schemas-models.md +0 -0
  142. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/testing.md +0 -0
  143. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/settings.json +0 -0
  144. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.env.prod.example +0 -0
  145. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.github/workflows/ci.yml +0 -0
  146. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.gitlab-ci.yml +0 -0
  147. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/AGENTS.md +0 -0
  148. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/CLAUDE.md +0 -0
  149. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/Makefile +0 -0
  150. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/.dockerignore +0 -0
  151. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/.pre-commit-config.yaml +0 -0
  152. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/Dockerfile +0 -0
  153. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/alembic/script.py.mako +0 -0
  154. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/alembic/versions/.gitkeep +0 -0
  155. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/alembic.ini +0 -0
  156. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/__init__.py +0 -0
  157. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/admin.py +0 -0
  158. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/__init__.py +0 -0
  159. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/assistant.py +0 -0
  160. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/crewai_assistant.py +0 -0
  161. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/deepagents_assistant.py +0 -0
  162. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/langchain_assistant.py +0 -0
  163. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/langgraph_assistant.py +0 -0
  164. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/prompts.py +0 -0
  165. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/pydantic_deep_assistant.py +0 -0
  166. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/__init__.py +0 -0
  167. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/datetime_tool.py +0 -0
  168. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/rag_tool.py +0 -0
  169. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/web_search.py +0 -0
  170. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/__init__.py +0 -0
  171. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/router.py +0 -0
  172. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/__init__.py +0 -0
  173. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/auth.py +0 -0
  174. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/versioning.py +0 -0
  175. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/channels/__init__.py +0 -0
  176. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/channels/base.py +0 -0
  177. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/clients/__init__.py +0 -0
  178. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/clients/redis.py +0 -0
  179. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/commands/__init__.py +0 -0
  180. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/commands/cleanup.py +0 -0
  181. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/commands/example.py +0 -0
  182. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/__init__.py +0 -0
  183. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/cache.py +0 -0
  184. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/channel_crypto.py +0 -0
  185. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/csrf.py +0 -0
  186. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/exceptions.py +0 -0
  187. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/logfire_setup.py +0 -0
  188. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/logging.py +0 -0
  189. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/middleware.py +0 -0
  190. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/oauth.py +0 -0
  191. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/rate_limit.py +0 -0
  192. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/sanitize.py +0 -0
  193. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/security.py +0 -0
  194. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/__init__.py +0 -0
  195. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/base.py +0 -0
  196. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/channel_bot.py +0 -0
  197. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/channel_identity.py +0 -0
  198. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/channel_session.py +0 -0
  199. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/chat_file.py +0 -0
  200. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/conversation.py +0 -0
  201. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/conversation_share.py +0 -0
  202. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/project.py +0 -0
  203. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/rag_document.py +0 -0
  204. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/session.py +0 -0
  205. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/sync_log.py +0 -0
  206. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/sync_source.py +0 -0
  207. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/user.py +0 -0
  208. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/webhook.py +0 -0
  209. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/main.py +0 -0
  210. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/__init__.py +0 -0
  211. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/config.py +0 -0
  212. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/connectors/__init__.py +0 -0
  213. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/connectors/google_drive.py +0 -0
  214. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/connectors/s3.py +0 -0
  215. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/documents.py +0 -0
  216. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/embeddings.py +0 -0
  217. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/image_describer.py +0 -0
  218. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/models.py +0 -0
  219. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/reranker.py +0 -0
  220. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/retrieval.py +0 -0
  221. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/sources/__init__.py +0 -0
  222. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/sources/base.py +0 -0
  223. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/sources/google_drive.py +0 -0
  224. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/sources/s3.py +0 -0
  225. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/channel_bot.py +0 -0
  226. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/channel_identity.py +0 -0
  227. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/channel_session.py +0 -0
  228. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/conversation_share.py +0 -0
  229. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/project.py +0 -0
  230. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/session.py +0 -0
  231. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/sync_source.py +0 -0
  232. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/__init__.py +0 -0
  233. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/base.py +0 -0
  234. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/channel_bot.py +0 -0
  235. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/conversation_share.py +0 -0
  236. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/project.py +0 -0
  237. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/rag.py +0 -0
  238. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/session.py +0 -0
  239. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/sync_source.py +0 -0
  240. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/token.py +0 -0
  241. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/webhook.py +0 -0
  242. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/__init__.py +0 -0
  243. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/agent_invocation.py +0 -0
  244. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/conversation_share.py +0 -0
  245. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/file_storage.py +0 -0
  246. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/__init__.py +0 -0
  247. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/arq_app.py +0 -0
  248. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/celery_app.py +0 -0
  249. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/taskiq_app.py +0 -0
  250. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/__init__.py +0 -0
  251. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/examples.py +0 -0
  252. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/schedules.py +0 -0
  253. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/taskiq_examples.py +0 -0
  254. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/cli/__init__.py +0 -0
  255. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/cli/commands.py +0 -0
  256. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/scripts/.gitkeep +0 -0
  257. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/__init__.py +0 -0
  258. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/__init__.py +0 -0
  259. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/test_auth.py +0 -0
  260. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/test_exceptions.py +0 -0
  261. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/test_health.py +0 -0
  262. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/test_metrics.py +0 -0
  263. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/test_openapi.py +0 -0
  264. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/test_users.py +0 -0
  265. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/conftest.py +0 -0
  266. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_admin.py +0 -0
  267. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_agents.py +0 -0
  268. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_clients.py +0 -0
  269. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_commands.py +0 -0
  270. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_core.py +0 -0
  271. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_migrations.py +0 -0
  272. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_repositories.py +0 -0
  273. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_security.py +0 -0
  274. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_services.py +0 -0
  275. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_ssrf.py +0 -0
  276. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_worker.py +0 -0
  277. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docker-compose.dev.yml +0 -0
  278. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docker-compose.frontend.yml +0 -0
  279. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docker-compose.prod.yml +0 -0
  280. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docker-compose.yml +0 -0
  281. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/adding_features.md +0 -0
  282. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/commands.md +0 -0
  283. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/file-processing.md +0 -0
  284. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/add-agent-tool.md +0 -0
  285. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/add-api-endpoint.md +0 -0
  286. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/add-background-task.md +0 -0
  287. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/add-rag-source.md +0 -0
  288. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/add-sync-connector.md +0 -0
  289. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/configure-sync-sources.md +0 -0
  290. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/customize-agent-prompt.md +0 -0
  291. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/patterns.md +0 -0
  292. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/testing.md +0 -0
  293. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/.dockerignore +0 -0
  294. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/.env.example +0 -0
  295. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/.gitignore +0 -0
  296. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/.prettierignore +0 -0
  297. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/Dockerfile +0 -0
  298. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/README.md +0 -0
  299. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/e2e/auth.setup.ts +0 -0
  300. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/e2e/auth.spec.ts +0 -0
  301. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/e2e/chat.spec.ts +0 -0
  302. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/e2e/home.spec.ts +0 -0
  303. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/instrumentation.ts +0 -0
  304. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/next.config.ts +0 -0
  305. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/playwright.config.ts +0 -0
  306. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/postcss.config.mjs +0 -0
  307. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(auth)/layout.tsx +0 -0
  308. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(auth)/login/page.tsx +0 -0
  309. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(auth)/register/page.tsx +0 -0
  310. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/layout.tsx +0 -0
  311. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/profile/page.tsx +0 -0
  312. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/settings/page.tsx +0 -0
  313. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/auth/callback/page.tsx +0 -0
  314. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/error.tsx +0 -0
  315. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/layout.tsx +0 -0
  316. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/page.tsx +0 -0
  317. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/shared/[token]/page.tsx +0 -0
  318. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/logout/route.ts +0 -0
  319. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/oauth-callback/route.ts +0 -0
  320. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/register/route.ts +0 -0
  321. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/[id]/messages/route.ts +0 -0
  322. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/[id]/route.ts +0 -0
  323. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/[id]/shares/[shareId]/route.ts +0 -0
  324. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/[id]/shares/route.ts +0 -0
  325. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/export/route.ts +0 -0
  326. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/route.ts +0 -0
  327. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/shared-with-me/route.ts +0 -0
  328. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/files/[id]/route.ts +0 -0
  329. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/files/upload/route.ts +0 -0
  330. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/health/route.ts +0 -0
  331. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/users/avatar/[userId]/route.ts +0 -0
  332. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/users/me/avatar/route.ts +0 -0
  333. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/agent/models/route.ts +0 -0
  334. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/collections/[name]/documents/[documentId]/route.ts +0 -0
  335. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/collections/[name]/documents/route.ts +0 -0
  336. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/collections/[name]/info/route.ts +0 -0
  337. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/collections/[name]/ingest/route.ts +0 -0
  338. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/collections/[name]/route.ts +0 -0
  339. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/collections/route.ts +0 -0
  340. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/documents/[docId]/download/route.ts +0 -0
  341. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/documents/[docId]/route.ts +0 -0
  342. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/documents/route.ts +0 -0
  343. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/search/route.ts +0 -0
  344. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/supported-formats/route.ts +0 -0
  345. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/sync/[syncId]/route.ts +0 -0
  346. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/sync/connectors/route.ts +0 -0
  347. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/sync/local/route.ts +0 -0
  348. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/sync/sources/[sourceId]/route.ts +0 -0
  349. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/sync/sources/[sourceId]/trigger/route.ts +0 -0
  350. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/rag/sync/sources/route.ts +0 -0
  351. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/global-error.tsx +0 -0
  352. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/globals.css +0 -0
  353. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/layout.tsx +0 -0
  354. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/not-found.tsx +0 -0
  355. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/providers.tsx +0 -0
  356. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/auth/index.ts +0 -0
  357. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/copy-button.tsx +0 -0
  358. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/index.ts +0 -0
  359. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/markdown-content.tsx +0 -0
  360. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-list.tsx +0 -0
  361. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/icons/google-icon.tsx +0 -0
  362. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/icons/index.ts +0 -0
  363. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/language-switcher.tsx +0 -0
  364. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/auth-guard.tsx +0 -0
  365. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/header.tsx +0 -0
  366. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/index.ts +0 -0
  367. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/landing-nav.tsx +0 -0
  368. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/page-transition.tsx +0 -0
  369. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/sidebar.tsx +0 -0
  370. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/theme/index.ts +0 -0
  371. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/theme/theme-provider.tsx +0 -0
  372. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/accordion.tsx +0 -0
  373. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/alert-dialog.tsx +0 -0
  374. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/avatar.tsx +0 -0
  375. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/badge.tsx +0 -0
  376. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/button.test.tsx +0 -0
  377. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/button.tsx +0 -0
  378. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/card.tsx +0 -0
  379. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/checkbox.tsx +0 -0
  380. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/dialog.tsx +0 -0
  381. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/dropdown-menu.tsx +0 -0
  382. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/index.ts +0 -0
  383. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/input.tsx +0 -0
  384. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/label.tsx +0 -0
  385. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/popover.tsx +0 -0
  386. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/progress.tsx +0 -0
  387. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/radio-group.tsx +0 -0
  388. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/scroll-area.tsx +0 -0
  389. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/select.tsx +0 -0
  390. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/separator.tsx +0 -0
  391. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/sheet.tsx +0 -0
  392. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/skeleton.tsx +0 -0
  393. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/spinner.tsx +0 -0
  394. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/switch.tsx +0 -0
  395. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/table.tsx +0 -0
  396. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/tabs.tsx +0 -0
  397. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/textarea.tsx +0 -0
  398. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/tooltip.tsx +0 -0
  399. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/index.ts +0 -0
  400. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-admin-conversations.ts +0 -0
  401. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-conversation-shares.ts +0 -0
  402. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-projects.ts +0 -0
  403. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/i18n.ts +0 -0
  404. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/api-client.ts +0 -0
  405. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/file-api.ts +0 -0
  406. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/rag-api.ts +0 -0
  407. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/utils.test.ts +0 -0
  408. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/utils.ts +0 -0
  409. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/middleware.ts +0 -0
  410. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/auth-store.test.ts +0 -0
  411. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/chat-sidebar-store.ts +0 -0
  412. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/conversation-store.ts +0 -0
  413. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/index.ts +0 -0
  414. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/project-store.ts +0 -0
  415. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/sidebar-store.ts +0 -0
  416. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/theme-store.ts +0 -0
  417. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/api.ts +0 -0
  418. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/auth.ts +0 -0
  419. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/index.ts +0 -0
  420. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/project.ts +0 -0
  421. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/speech.d.ts +0 -0
  422. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/vercel.json +0 -0
  423. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/vitest.config.ts +0 -0
  424. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/vitest.setup.ts +0 -0
  425. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/configmap.yaml +0 -0
  426. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/deployment.yaml +0 -0
  427. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/ingress.yaml +0 -0
  428. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/kustomization.yaml +0 -0
  429. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/namespace.yaml +0 -0
  430. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/secret.yaml +0 -0
  431. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/service.yaml +0 -0
  432. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/nginx/nginx.conf +0 -0
  433. {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/nginx/ssl/.gitkeep +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-fullstack
3
- Version: 0.2.5
3
+ Version: 0.2.7
4
4
  Summary: Full-stack FastAPI + Next.js template generator with PydanticAI/LangChain agents, WebSocket streaming, 20+ enterprise integrations, and Logfire/LangSmith observability. Ship AI apps fast. CLI tool to generate production-ready FastAPI + Next.js projects with AI agents, auth, and observability.
5
5
  Project-URL: Homepage, https://github.com/vstorm-co/full-stack-ai-agent-template
6
6
  Project-URL: Documentation, https://github.com/vstorm-co/full-stack-ai-agent-template#readme
@@ -19,23 +19,23 @@ Classifier: Programming Language :: Python :: 3.11
19
19
  Classifier: Programming Language :: Python :: 3.12
20
20
  Classifier: Topic :: Software Development :: Code Generators
21
21
  Requires-Python: >=3.11
22
- Requires-Dist: click>=8.1.0
23
- Requires-Dist: cookiecutter>=2.6.0
24
- Requires-Dist: email-validator>=2.0.0
25
- Requires-Dist: pydantic-settings>=2.0.0
26
- Requires-Dist: pydantic>=2.0.0
27
- Requires-Dist: questionary>=2.0.0
28
- Requires-Dist: rich>=13.0.0
22
+ Requires-Dist: click>=8.3.0
23
+ Requires-Dist: cookiecutter>=2.7.0
24
+ Requires-Dist: email-validator>=2.3.0
25
+ Requires-Dist: pydantic-settings>=2.13.0
26
+ Requires-Dist: pydantic>=2.13.0
27
+ Requires-Dist: questionary>=2.1.0
28
+ Requires-Dist: rich>=15.0.0
29
29
  Provides-Extra: dev
30
- Requires-Dist: pre-commit>=3.0.0; extra == 'dev'
31
- Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
32
- Requires-Dist: pytest>=8.0.0; extra == 'dev'
33
- Requires-Dist: ruff>=0.8.0; extra == 'dev'
34
- Requires-Dist: ty>=0.0.29; extra == 'dev'
30
+ Requires-Dist: pre-commit>=4.0.0; extra == 'dev'
31
+ Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
32
+ Requires-Dist: pytest>=9.0.0; extra == 'dev'
33
+ Requires-Dist: ruff>=0.14.0; extra == 'dev'
34
+ Requires-Dist: ty>=0.0.31; extra == 'dev'
35
35
  Provides-Extra: docs
36
- Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
37
- Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
38
- Requires-Dist: pymdown-extensions>=10.0.0; extra == 'docs'
36
+ Requires-Dist: mkdocs-material>=9.7.0; extra == 'docs'
37
+ Requires-Dist: mkdocs>=1.6.1; extra == 'docs'
38
+ Requires-Dist: pymdown-extensions>=10.20; extra == 'docs'
39
39
  Description-Content-Type: text/markdown
40
40
 
41
41
  <p align="center">
@@ -397,6 +397,7 @@ Generated projects include **CLAUDE.md** and **AGENTS.md** files optimized for A
397
397
  - **Messaging Channels** - Telegram and Slack multi-bot integration with polling, webhooks, per-thread sessions, group concurrency control
398
398
  - **Conversation Sharing** - Share conversations with users or via public links, admin conversation browser
399
399
  - **Conversation Persistence** - Save chat history to database
400
+ - **Message Ratings** - Like/dislike responses with feedback, admin analytics
400
401
  - **Image Description** - Extract images from documents, describe via LLM vision
401
402
  - **Multimodal Embeddings** - Google Gemini embedding model (text + images)
402
403
  - **Document Sources** - Local files, API upload, Google Drive, S3/MinIO
@@ -357,6 +357,7 @@ Generated projects include **CLAUDE.md** and **AGENTS.md** files optimized for A
357
357
  - **Messaging Channels** - Telegram and Slack multi-bot integration with polling, webhooks, per-thread sessions, group concurrency control
358
358
  - **Conversation Sharing** - Share conversations with users or via public links, admin conversation browser
359
359
  - **Conversation Persistence** - Save chat history to database
360
+ - **Message Ratings** - Like/dislike responses with feedback, admin analytics
360
361
  - **Image Description** - Extract images from documents, describe via LLM vision
361
362
  - **Multimodal Embeddings** - Google Gemini embedding model (text + images)
362
363
  - **Document Sources** - Local files, API upload, Google Drive, S3/MinIO
@@ -56,15 +56,51 @@ def cli(ctx: click.Context) -> None:
56
56
  help="Use default values without prompts",
57
57
  )
58
58
  @click.option("--name", type=str, help="Project name (for --no-input mode)")
59
- def new(output: Path | None, no_input: bool, name: str | None) -> None:
59
+ @click.option(
60
+ "--minimal",
61
+ is_flag=True,
62
+ default=False,
63
+ help="Skip wizard — ask only for project name and use minimal defaults (SQLite, no Docker/Redis/CI)",
64
+ )
65
+ def new(output: Path | None, no_input: bool, name: str | None, minimal: bool) -> None:
60
66
  """Create a new FastAPI project interactively."""
61
67
  try:
62
- if no_input:
68
+ if no_input or minimal:
63
69
  if not name:
64
- console.print("[red]Error:[/] --name is required when using --no-input")
65
- raise SystemExit(1)
66
-
67
- config = ProjectConfig(project_name=name, background_tasks=BackgroundTaskType.NONE)
70
+ if minimal:
71
+ import questionary
72
+
73
+ name = questionary.text(
74
+ "Project name:",
75
+ validate=lambda v: bool(v) or "Name cannot be empty",
76
+ ).ask()
77
+ if not name:
78
+ console.print("\n[yellow]Cancelled.[/]")
79
+ return
80
+ else:
81
+ console.print("[red]Error:[/] --name is required when using --no-input")
82
+ raise SystemExit(1)
83
+
84
+ if minimal:
85
+ config = ProjectConfig(
86
+ project_name=name,
87
+ database=DatabaseType.SQLITE,
88
+ enable_logfire=False,
89
+ enable_redis=False,
90
+ enable_caching=False,
91
+ enable_rate_limiting=False,
92
+ enable_pagination=False,
93
+ enable_admin_panel=False,
94
+ enable_docker=False,
95
+ enable_kubernetes=False,
96
+ background_tasks=BackgroundTaskType.NONE,
97
+ ci_type=CIType.NONE,
98
+ )
99
+ console.print(f"[cyan]Creating minimal project:[/] {name}")
100
+ console.print("[dim]SQLite · no Docker · no Redis · no CI[/]")
101
+ console.print()
102
+ else:
103
+ config = ProjectConfig(project_name=name, background_tasks=BackgroundTaskType.NONE)
68
104
  else:
69
105
  config = run_interactive_prompts()
70
106
  show_summary(config)
@@ -343,6 +343,16 @@ class ProjectConfig(BaseModel):
343
343
  "PydanticDeep uses Logfire for observability."
344
344
  )
345
345
 
346
+ # CrewAI 1.13.x pins opentelemetry-sdk<1.35 which conflicts with
347
+ # logfire>=4.30 (needs opentelemetry-sdk>=1.39). Disable logfire when
348
+ # using CrewAI to keep dependencies resolvable.
349
+ if self.ai_framework == AIFrameworkType.CREWAI and self.enable_logfire:
350
+ raise ValueError(
351
+ "CrewAI is incompatible with Logfire — CrewAI pins an older "
352
+ "opentelemetry-sdk that conflicts with current logfire. "
353
+ "Disable Logfire (enable_logfire=False) when using CrewAI."
354
+ )
355
+
346
356
  # Admin panel requires SQLAlchemy (SQLAdmin doesn't fully support SQLModel)
347
357
  if self.enable_admin_panel and self.orm_type == OrmType.SQLMODEL:
348
358
  raise ValueError(
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fastapi-fullstack"
3
- version = "0.2.5"
3
+ version = "0.2.7"
4
4
  description = "Full-stack FastAPI + Next.js template generator with PydanticAI/LangChain agents, WebSocket streaming, 20+ enterprise integrations, and Logfire/LangSmith observability. Ship AI apps fast. CLI tool to generate production-ready FastAPI + Next.js projects with AI agents, auth, and observability."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -44,27 +44,27 @@ classifiers = [
44
44
  ]
45
45
 
46
46
  dependencies = [
47
- "click>=8.1.0",
48
- "cookiecutter>=2.6.0",
49
- "rich>=13.0.0",
50
- "questionary>=2.0.0",
51
- "pydantic>=2.0.0",
52
- "pydantic-settings>=2.0.0",
53
- "email-validator>=2.0.0",
47
+ "click>=8.3.0",
48
+ "cookiecutter>=2.7.0",
49
+ "rich>=15.0.0",
50
+ "questionary>=2.1.0",
51
+ "pydantic>=2.13.0",
52
+ "pydantic-settings>=2.13.0",
53
+ "email-validator>=2.3.0",
54
54
  ]
55
55
 
56
56
  [project.optional-dependencies]
57
57
  dev = [
58
- "pytest>=8.0.0",
59
- "pytest-cov>=4.0.0",
60
- "ruff>=0.8.0",
61
- "ty>=0.0.29",
62
- "pre-commit>=3.0.0",
58
+ "pytest>=9.0.0",
59
+ "pytest-cov>=7.0.0",
60
+ "ruff>=0.14.0",
61
+ "ty>=0.0.31",
62
+ "pre-commit>=4.0.0",
63
63
  ]
64
64
  docs = [
65
- "mkdocs>=1.6.0",
66
- "mkdocs-material>=9.5.0",
67
- "pymdown-extensions>=10.0.0",
65
+ "mkdocs>=1.6.1",
66
+ "mkdocs-material>=9.7.0",
67
+ "pymdown-extensions>=10.20",
68
68
  ]
69
69
 
70
70
  [project.scripts]
@@ -168,6 +168,7 @@ exclude_lines = [
168
168
 
169
169
  [dependency-groups]
170
170
  dev = [
171
- "ty>=0.0.29",
172
- "pytest-cov>=7.0.0",
171
+ "ty>=0.0.31",
172
+ "pytest-cov>=7.1.0",
173
+ "sqlalchemy>=2.0.49",
173
174
  ]
@@ -47,6 +47,7 @@ enable_web_search = "{{ cookiecutter.enable_web_search }}" == "True"
47
47
  use_pydantic_deep = "{{ cookiecutter.use_pydantic_deep }}" == "True"
48
48
  use_telegram = "{{ cookiecutter.use_telegram }}" == "True"
49
49
  use_slack = "{{ cookiecutter.use_slack }}" == "True"
50
+ enable_docker = "{{ cookiecutter.enable_docker }}" == "True"
50
51
 
51
52
 
52
53
  def remove_file(path: str) -> None:
@@ -158,6 +159,18 @@ if not enable_rag:
158
159
  remove_file(os.path.join(backend_app, "worker", "tasks", "rag_ingestion.py"))
159
160
  # Remove RAG agent tool
160
161
  remove_file(os.path.join(backend_app, "agents", "tools", "rag_tool.py"))
162
+ # Remove RAG document repository/service/model stubs
163
+ remove_file(os.path.join(backend_app, "repositories", "rag_document.py"))
164
+ remove_file(os.path.join(backend_app, "services", "rag_document.py"))
165
+ remove_file(os.path.join(backend_app, "services", "rag_sync.py"))
166
+ remove_file(os.path.join(backend_app, "db", "models", "rag_document.py"))
167
+ # Remove sync source/log artifacts (they only exist for RAG)
168
+ remove_file(os.path.join(backend_app, "db", "models", "sync_source.py"))
169
+ remove_file(os.path.join(backend_app, "db", "models", "sync_log.py"))
170
+ remove_file(os.path.join(backend_app, "schemas", "sync_source.py"))
171
+ remove_file(os.path.join(backend_app, "repositories", "sync_source.py"))
172
+ remove_file(os.path.join(backend_app, "repositories", "sync_log.py"))
173
+ remove_file(os.path.join(backend_app, "services", "sync_source.py"))
161
174
  # Remove frontend RAG files
162
175
  if use_frontend:
163
176
  frontend_src = os.path.join(os.getcwd(), "frontend", "src")
@@ -178,7 +191,65 @@ else:
178
191
  remove_file(os.path.join(backend_app, "rag", "connectors", "s3.py"))
179
192
  if not enable_google_drive_ingestion and not enable_s3_ingestion:
180
193
  remove_dir(os.path.join(backend_app, "rag", "sources"))
181
- remove_dir(os.path.join(backend_app, "rag", "connectors"))
194
+ # Keep rag/connectors/ — its __init__.py defines CONNECTOR_REGISTRY which
195
+ # sync_source.py imports unconditionally even when no connectors are configured.
196
+
197
+ # --- Messaging channels (Slack / Telegram) ---
198
+ # Per-channel adapters & webhook routes
199
+ if not use_telegram:
200
+ remove_file(os.path.join(backend_app, "channels", "telegram.py"))
201
+ remove_file(os.path.join(backend_app, "api", "routes", "v1", "telegram_webhook.py"))
202
+ if not use_slack:
203
+ remove_file(os.path.join(backend_app, "channels", "slack.py"))
204
+ remove_file(os.path.join(backend_app, "api", "routes", "v1", "slack_webhook.py"))
205
+
206
+ # Shared channel infrastructure — only present when at least one channel is enabled
207
+ if not use_telegram and not use_slack:
208
+ remove_dir(os.path.join(backend_app, "channels"))
209
+ remove_file(os.path.join(backend_app, "api", "routes", "v1", "channels.py"))
210
+ remove_file(os.path.join(backend_app, "core", "channel_crypto.py"))
211
+ remove_file(os.path.join(backend_app, "commands", "channel.py"))
212
+ remove_file(os.path.join(backend_app, "services", "channel_bot.py"))
213
+ remove_file(os.path.join(backend_app, "services", "agent_invocation.py"))
214
+ remove_file(os.path.join(backend_app, "repositories", "channel_bot.py"))
215
+ remove_file(os.path.join(backend_app, "repositories", "channel_identity.py"))
216
+ remove_file(os.path.join(backend_app, "repositories", "channel_session.py"))
217
+ remove_file(os.path.join(backend_app, "schemas", "channel_bot.py"))
218
+ remove_file(os.path.join(backend_app, "db", "models", "channel_bot.py"))
219
+ remove_file(os.path.join(backend_app, "db", "models", "channel_identity.py"))
220
+ remove_file(os.path.join(backend_app, "db", "models", "channel_session.py"))
221
+ remove_file(os.path.join(backend_app, "tasks", "channel.py"))
222
+
223
+ # --- DeepAgents project files (only when use_pydantic_deep is enabled) ---
224
+ if not use_pydantic_deep:
225
+ remove_file(os.path.join(backend_app, "api", "routes", "v1", "projects.py"))
226
+ remove_file(os.path.join(backend_app, "db", "models", "project.py"))
227
+ remove_file(os.path.join(backend_app, "schemas", "project.py"))
228
+ remove_file(os.path.join(backend_app, "services", "project.py"))
229
+ remove_file(os.path.join(backend_app, "repositories", "project.py"))
230
+
231
+ # --- Test stubs that depend on disabled features ---
232
+ backend_tests = os.path.join(os.getcwd(), "backend", "tests")
233
+ if not enable_redis:
234
+ remove_file(os.path.join(backend_tests, "test_clients.py"))
235
+ if not (use_postgresql and use_sqlalchemy):
236
+ remove_file(os.path.join(backend_tests, "test_services_conversation.py"))
237
+ if not use_celery:
238
+ remove_file(os.path.join(backend_tests, "test_worker.py"))
239
+ if not (enable_admin_panel and use_postgresql):
240
+ remove_file(os.path.join(backend_tests, "test_admin.py"))
241
+
242
+ # --- Empty docker-compose placeholders ---
243
+ if not enable_docker:
244
+ project_root = os.getcwd()
245
+ for compose_file in (
246
+ "docker-compose.yml",
247
+ "docker-compose.dev.yml",
248
+ "docker-compose.prod.yml",
249
+ "docker-compose.frontend.yml",
250
+ ".env.prod.example",
251
+ ):
252
+ remove_file(os.path.join(project_root, compose_file))
182
253
 
183
254
  # --- Cleanup stub files (files with only docstring, no code) ---
184
255
  core_dir = os.path.join(backend_app, "core")
@@ -103,5 +103,5 @@ Thumbs.db
103
103
 
104
104
  # Project specific
105
105
  {%- if cookiecutter.use_sqlite %}
106
- {{ cookiecutter.project_slug }}.db
106
+ data/
107
107
  {%- endif %}
@@ -131,6 +131,18 @@ Chat with the agent at http://localhost:{{ cookiecutter.frontend_port }}/chat
131
131
  - **Add tools:** See `docs/howto/add-agent-tool.md`
132
132
  - **Agent config:** `.env` → `AI_MODEL`, `AI_TEMPERATURE`
133
133
 
134
+ ## Message Ratings
135
+
136
+ Users can rate AI responses with 👍/👎 and optional feedback comments.
137
+ Administrators can view analytics and export rating data.
138
+
139
+ {%- if cookiecutter.use_frontend %}
140
+ - Rate messages at http://localhost:{{ cookiecutter.frontend_port }}/chat
141
+ - Admin dashboard at http://localhost:{{ cookiecutter.frontend_port }}/admin/ratings
142
+ {%- endif %}
143
+
144
+ See `docs/howto/use-ratings.md` for full documentation.
145
+
134
146
  {%- if cookiecutter.enable_rag %}
135
147
 
136
148
  ## RAG (Knowledge Base)
@@ -39,7 +39,7 @@ MONGO_DB={{ cookiecutter.project_slug }}
39
39
  {%- if cookiecutter.use_sqlite %}
40
40
 
41
41
  # === SQLite ===
42
- SQLITE_PATH=./{{ cookiecutter.project_slug }}.db
42
+ SQLITE_PATH=./data/{{ cookiecutter.project_slug }}.db
43
43
  {%- endif %}
44
44
 
45
45
  {%- if cookiecutter.use_jwt %}
@@ -3,6 +3,7 @@
3
3
  # ruff: noqa: I001 - Imports structured for Jinja2 template conditionals
4
4
 
5
5
  from logging.config import fileConfig
6
+ from pathlib import Path
6
7
 
7
8
  from alembic import context
8
9
  from sqlalchemy import engine_from_config, pool
@@ -19,6 +20,22 @@ from app.db.base import Base
19
20
  {%- if cookiecutter.use_jwt %}
20
21
  from app.db.models.user import User # noqa: F401
21
22
  {%- endif %}
23
+ from app.db.models.conversation import Conversation, Message, ToolCall # noqa: F401
24
+ {%- if cookiecutter.use_jwt %}
25
+ from app.db.models.message_rating import MessageRating # noqa: F401
26
+ {%- endif %}
27
+ {%- if cookiecutter.enable_session_management and cookiecutter.use_jwt %}
28
+ from app.db.models.session import Session # noqa: F401
29
+ {%- endif %}
30
+ {%- if cookiecutter.enable_webhooks %}
31
+ from app.db.models.webhook import Webhook, WebhookDelivery # noqa: F401
32
+ {%- endif %}
33
+ from app.db.models.chat_file import ChatFile # noqa: F401
34
+ {%- if cookiecutter.enable_rag %}
35
+ from app.db.models.rag_document import RAGDocument # noqa: F401
36
+ from app.db.models.sync_log import SyncLog # noqa: F401
37
+ from app.db.models.sync_source import SyncSource # noqa: F401
38
+ {%- endif %}
22
39
 
23
40
  config = context.config
24
41
 
@@ -32,6 +49,13 @@ target_metadata = Base.metadata
32
49
  {%- endif %}
33
50
 
34
51
 
52
+ # Ensure SQLite data directory exists before connecting
53
+ {%- if cookiecutter.use_sqlite %}
54
+ db_path = Path(settings.SQLITE_PATH)
55
+ db_path.parent.mkdir(parents=True, exist_ok=True)
56
+ {%- endif %}
57
+
58
+
35
59
  def get_url() -> str:
36
60
  """Get database URL from settings."""
37
61
  {%- if cookiecutter.use_postgresql %}
@@ -198,6 +198,27 @@ def get_channel_bot_service() -> ChannelBotService:
198
198
 
199
199
  ChannelBotSvc = Annotated[ChannelBotService, Depends(get_channel_bot_service)]
200
200
  {%- endif %}
201
+ {%- if cookiecutter.use_database and cookiecutter.use_jwt %}
202
+
203
+ # Message rating service
204
+ from app.services.message_rating import MessageRatingService
205
+ {%- if cookiecutter.use_postgresql or cookiecutter.use_sqlite %}
206
+
207
+
208
+ def get_rating_service(db: DBSession) -> MessageRatingService:
209
+ """Create MessageRatingService instance with database session."""
210
+ return MessageRatingService(db)
211
+ {%- elif cookiecutter.use_mongodb %}
212
+
213
+
214
+ def get_rating_service() -> MessageRatingService:
215
+ """Create MessageRatingService instance."""
216
+ return MessageRatingService()
217
+ {%- endif %}
218
+
219
+
220
+ MessageRatingSvc = Annotated[MessageRatingService, Depends(get_rating_service)]
221
+ {%- endif %}
201
222
 
202
223
  {%- if cookiecutter.enable_rag and (cookiecutter.use_postgresql or cookiecutter.use_sqlite) %}
203
224
  from app.services.rag_document import RAGDocumentService
@@ -238,7 +259,6 @@ FileUploadSvc = Annotated[FileUploadService, Depends(get_file_upload_service)]
238
259
  {%- endif %}
239
260
 
240
261
  {%- if cookiecutter.use_jwt %}
241
-
242
262
  # === Authentication Dependencies ===
243
263
 
244
264
  from app.core.exceptions import AuthenticationError, AuthorizationError
@@ -247,8 +267,6 @@ from app.db.models.user import User, UserRole
247
267
  oauth2_scheme = OAuth2PasswordBearer(tokenUrl=f"{settings.API_V1_STR}/auth/login")
248
268
 
249
269
  {%- if cookiecutter.use_postgresql %}
250
-
251
-
252
270
  async def get_current_user(
253
271
  token: Annotated[str, Depends(oauth2_scheme)],
254
272
  user_service: UserSvc,
@@ -510,19 +528,44 @@ CurrentAdmin = Annotated[User, Depends(RoleChecker(UserRole.ADMIN))]
510
528
 
511
529
 
512
530
  # WebSocket authentication dependency
513
- from fastapi import WebSocket, Query, Cookie
531
+ from fastapi import WebSocket, Cookie
532
+
533
+
534
+ _WS_TOKEN_PROTOCOL_PREFIX = "access_token."
535
+
536
+
537
+ def _extract_ws_auth(websocket: WebSocket) -> tuple[str | None, str | None]:
538
+ """Parse Sec-WebSocket-Protocol header for an auth token + app subprotocol.
539
+
540
+ Clients pass the token as a subprotocol of the form
541
+ ``access_token.<JWT>`` alongside an optional application subprotocol
542
+ (e.g. ``chat``). Returns (token, app_subprotocol) — either may be None.
543
+ """
544
+ raw = websocket.headers.get("sec-websocket-protocol") or ""
545
+ token: str | None = None
546
+ app_subprotocol: str | None = None
547
+ for proto in (p.strip() for p in raw.split(",") if p.strip()):
548
+ if proto.startswith(_WS_TOKEN_PROTOCOL_PREFIX):
549
+ token = proto[len(_WS_TOKEN_PROTOCOL_PREFIX):]
550
+ elif app_subprotocol is None:
551
+ app_subprotocol = proto
552
+ return token, app_subprotocol
514
553
 
515
554
 
516
555
  async def get_current_user_ws(
517
556
  websocket: WebSocket,
518
- token: str | None = Query(None, alias="token"),
519
557
  access_token: str | None = Cookie(None),
520
558
  ) -> User:
521
- """Get current user from WebSocket JWT token.
559
+ """Authenticate a WebSocket connection.
560
+
561
+ Token sources, checked in order:
562
+ 1. ``Sec-WebSocket-Protocol`` header, in the form ``access_token.<JWT>``.
563
+ The chosen application subprotocol (e.g. ``chat``) is echoed back on
564
+ ``accept()`` via ``websocket.state.accept_subprotocol``.
565
+ 2. Same-origin ``access_token`` cookie (fallback for same-origin clients).
522
566
 
523
- Token can be passed either as:
524
- - Query parameter: ws://...?token=<jwt>
525
- - Cookie: access_token cookie (set by HTTP login)
567
+ Tokens in query strings are NOT accepted — they leak into logs and
568
+ Referer headers.
526
569
 
527
570
  Raises:
528
571
  AuthenticationError: If token is invalid or user not found.
@@ -531,8 +574,10 @@ async def get_current_user_ws(
531
574
 
532
575
  from app.core.security import verify_token
533
576
 
534
- # Try query parameter first, then cookie
535
- auth_token = token or access_token
577
+ subprotocol_token, app_subprotocol = _extract_ws_auth(websocket)
578
+ websocket.state.accept_subprotocol = app_subprotocol
579
+
580
+ auth_token = subprotocol_token or access_token
536
581
 
537
582
  if not auth_token:
538
583
  await websocket.close(code=4001, reason="Missing authentication token")
@@ -558,10 +603,26 @@ async def get_current_user_ws(
558
603
  async with get_db_context() as db:
559
604
  user_service = UserService(db)
560
605
  user = await user_service.get_by_id(UUID(user_id))
606
+
607
+ if not user.is_active:
608
+ await websocket.close(code=4001, reason="User account is disabled")
609
+ raise AuthenticationError(message="User account is disabled")
610
+
611
+ # Eagerly load all columns, then detach from session to avoid
612
+ # "instance not bound to a Session" errors after the context manager exits
613
+ await db.refresh(user)
614
+ db.expunge(user)
615
+ return user
561
616
  {%- elif cookiecutter.use_mongodb %}
562
617
 
563
618
  user_service = UserService()
564
619
  user = await user_service.get_by_id(user_id)
620
+
621
+ if not user.is_active:
622
+ await websocket.close(code=4001, reason="User account is disabled")
623
+ raise AuthenticationError(message="User account is disabled")
624
+
625
+ return user
565
626
  {%- elif cookiecutter.use_sqlite %}
566
627
 
567
628
  from contextlib import contextmanager
@@ -569,13 +630,17 @@ async def get_current_user_ws(
569
630
  with contextmanager(get_db_session)() as db:
570
631
  user_service = UserService(db)
571
632
  user = user_service.get_by_id(user_id)
572
- {%- endif %}
573
633
 
574
- if not user.is_active:
575
- await websocket.close(code=4001, reason="User account is disabled")
576
- raise AuthenticationError(message="User account is disabled")
634
+ if not user.is_active:
635
+ await websocket.close(code=4001, reason="User account is disabled")
636
+ raise AuthenticationError(message="User account is disabled")
577
637
 
578
- return user
638
+ # Eagerly load all columns, then detach from session for
639
+ # consistency with async behavior
640
+ db.refresh(user)
641
+ db.expunge(user)
642
+ return user
643
+ {%- endif %}
579
644
  {%- endif %}
580
645
 
581
646
  {%- if cookiecutter.use_api_key %}
@@ -4,9 +4,8 @@ These handlers convert domain exceptions to proper HTTP responses.
4
4
  """
5
5
 
6
6
  import logging
7
- from typing import Union
8
7
 
9
- from fastapi import FastAPI, Request, WebSocket
8
+ from fastapi import FastAPI, Request
10
9
  from fastapi.responses import JSONResponse
11
10
 
12
11
  from app.core.exceptions import AppException
@@ -15,25 +14,19 @@ logger = logging.getLogger(__name__)
15
14
 
16
15
 
17
16
  async def app_exception_handler(
18
- request: Union[Request, WebSocket], exc: AppException
17
+ request: Request, exc: AppException
19
18
  ) -> JSONResponse:
20
19
  """Handle application exceptions.
21
20
 
22
21
  Logs 5xx errors as errors and 4xx as warnings.
23
22
  Returns a standardized JSON error response.
24
-
25
- Note: For WebSocket connections, this handler may not be able to return
26
- a response if the connection was already closed.
27
23
  """
28
- # WebSocket objects don't have a method attribute
29
- method = getattr(request, "method", "WEBSOCKET")
30
-
31
24
  log_extra = {
32
25
  "error_code": exc.code,
33
26
  "status_code": exc.status_code,
34
27
  "details": exc.details,
35
28
  "path": request.url.path,
36
- "method": method,
29
+ "method": request.method,
37
30
  }
38
31
 
39
32
  if exc.status_code >= 500:
@@ -59,20 +52,18 @@ async def app_exception_handler(
59
52
 
60
53
 
61
54
  async def unhandled_exception_handler(
62
- request: Union[Request, WebSocket], exc: Exception
55
+ request: Request, exc: Exception
63
56
  ) -> JSONResponse:
64
57
  """Handle unexpected exceptions.
65
58
 
66
59
  Logs the full exception but returns a generic error to the client
67
60
  to avoid leaking sensitive information.
68
61
  """
69
- method = getattr(request, "method", "WEBSOCKET")
70
-
71
62
  logger.exception(
72
63
  "Unhandled exception",
73
64
  extra={
74
65
  "path": request.url.path,
75
- "method": method,
66
+ "method": request.method,
76
67
  },
77
68
  )
78
69
 
@@ -93,6 +84,6 @@ def register_exception_handlers(app: FastAPI) -> None:
93
84
 
94
85
  Call this after creating the FastAPI application instance.
95
86
  """
96
- app.add_exception_handler(AppException, app_exception_handler) # type: ignore[arg-type]
87
+ app.add_exception_handler(AppException, app_exception_handler)
97
88
  # Uncomment to catch all unhandled exceptions:
98
89
  # app.add_exception_handler(Exception, unhandled_exception_handler)
@@ -7,7 +7,7 @@ from fastapi import APIRouter
7
7
 
8
8
  from app.api.routes.v1 import health
9
9
  {%- if cookiecutter.use_jwt %}
10
- from app.api.routes.v1 import auth, users
10
+ from app.api.routes.v1 import admin_ratings, auth, users
11
11
  {%- endif %}
12
12
  {%- if cookiecutter.enable_oauth %}
13
13
  from app.api.routes.v1 import oauth
@@ -56,6 +56,9 @@ v1_router.include_router(auth.router, prefix="/auth", tags=["auth"])
56
56
 
57
57
  # User routes
58
58
  v1_router.include_router(users.router, prefix="/users", tags=["users"])
59
+
60
+ # Admin routes
61
+ v1_router.include_router(admin_ratings.router, prefix="/admin/ratings", tags=["admin:ratings"])
59
62
  {%- endif %}
60
63
 
61
64
  {%- if cookiecutter.enable_oauth %}