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.
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/PKG-INFO +17 -16
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/README.md +1 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/fastapi_gen/cli.py +42 -6
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/fastapi_gen/config.py +10 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/pyproject.toml +19 -18
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/hooks/post_gen_project.py +72 -1
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.gitignore +1 -1
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/README.md +12 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/.env.example +1 -1
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/alembic/env.py +24 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/deps.py +81 -16
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/exception_handlers.py +6 -15
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/__init__.py +4 -1
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/admin_conversations.py +166 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/admin_ratings.py +261 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/agent.py +169 -400
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/channels.py +33 -33
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/conversations.py +331 -22
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/files.py +14 -15
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/health.py +4 -21
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/oauth.py +21 -85
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/projects.py +1 -1
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/rag.py +50 -255
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/sessions.py +4 -49
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/slack_webhook.py +76 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/telegram_webhook.py +123 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/users.py +39 -45
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/webhooks.py +65 -26
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/channels/router.py +8 -5
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/channels/slack.py +2 -3
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/channels/telegram.py +2 -3
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/commands/channel.py +270 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/commands/rag.py +24 -42
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/commands/seed.py +42 -77
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/config.py +1 -1
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/__init__.py +4 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/db/models/message_rating.py +295 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/session.py +5 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/ingestion.py +24 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/vectorstore.py +38 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/__init__.py +2 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/chat_file.py +47 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/conversation.py +377 -1
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/repositories/message_rating.py +661 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/rag_document.py +22 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/sync_log.py +4 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/user.py +152 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/webhook.py +48 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/conversation.py +19 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/file.py +2 -2
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/schemas/message_rating.py +126 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/user.py +16 -1
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/services/agent.py +41 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/channel_bot.py +42 -3
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/conversation.py +663 -60
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/file_upload.py +18 -20
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/services/health.py +23 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/services/message_rating.py +1193 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/project.py +3 -3
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/rag_document.py +107 -83
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/rag_sync.py +84 -60
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/session.py +57 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/sync_source.py +113 -48
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/user.py +202 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/webhook.py +6 -8
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/tasks/__init__.py +1 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/tasks/channel.py +35 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/backend/app/tasks/rag.py +140 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/rag_tasks.py +34 -50
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/pyproject.toml +23 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_services_conversation.py +15 -6
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/architecture.md +4 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/configuration.md +1 -1
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/docs/howto/use-ratings.md +132 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/permissions.md +11 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/.editorconfig +12 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/.husky/pre-commit +1 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/.prettierrc +1 -1
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/eslint.config.mjs +5 -4
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/messages/en.json +84 -3
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/messages/pl.json +84 -3
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/package.json +12 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/admin/conversations/page.tsx +354 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/admin/ratings/page.tsx +336 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/chat/page.tsx +29 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/dashboard/page.tsx +40 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/rag/page.tsx +3 -2
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/login/route.ts +3 -1
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/me/route.ts +4 -1
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/refresh/route.ts +4 -1
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/[id]/messages/[messageId]/rate/route.ts +95 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/admin/conversations/route.ts +48 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/admin/ratings/export/route.ts +58 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/admin/ratings/route.ts +42 -0
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/app/api/v1/admin/ratings/summary/route.ts +35 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/auth/login-form.tsx +12 -10
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/auth/register-form.tsx +15 -13
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-container.tsx +21 -4
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-input.tsx +3 -2
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/conversation-sidebar.tsx +14 -10
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-item.tsx +25 -1
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/rating-buttons.tsx +257 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/share-dialog.tsx +52 -16
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-approval-dialog.tsx +2 -2
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-call-card.tsx +8 -8
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/breadcrumb.tsx +2 -1
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/theme/theme-toggle.tsx +2 -2
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-auth.ts +18 -8
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-chat.ts +70 -8
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-conversations.ts +7 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-websocket.ts +5 -2
- fastapi_fullstack-0.2.7/template/{{cookiecutter.project_slug}}/frontend/src/lib/admin-auth.ts +47 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/constants.ts +4 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/server-api.ts +7 -1
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/auth-store.ts +7 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/chat-store.ts +9 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/chat.ts +20 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/conversation.ts +42 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/tsconfig.json +1 -0
- fastapi_fullstack-0.2.5/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/admin_conversations.py +0 -400
- fastapi_fullstack-0.2.5/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/slack_webhook.py +0 -128
- fastapi_fullstack-0.2.5/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/telegram_webhook.py +0 -181
- fastapi_fullstack-0.2.5/template/{{cookiecutter.project_slug}}/backend/app/commands/channel.py +0 -309
- fastapi_fullstack-0.2.5/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/admin/conversations/page.tsx +0 -273
- fastapi_fullstack-0.2.5/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/chat/page.tsx +0 -16
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/.gitignore +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/LICENSE +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/fastapi_gen/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/fastapi_gen/generator.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/fastapi_gen/prompts.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/VARIABLES.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/cookiecutter.json +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/commands/add-endpoint.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/commands/fix-issue.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/commands/review.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/api-conventions.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/architecture.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/code-style.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/exceptions-security.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/frontend.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/schemas-models.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/rules/testing.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.claude/settings.json +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.env.prod.example +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.github/workflows/ci.yml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/.gitlab-ci.yml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/AGENTS.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/CLAUDE.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/Makefile +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/.dockerignore +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/.pre-commit-config.yaml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/Dockerfile +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/alembic/script.py.mako +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/alembic/versions/.gitkeep +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/alembic.ini +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/admin.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/assistant.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/crewai_assistant.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/deepagents_assistant.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/langchain_assistant.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/langgraph_assistant.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/prompts.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/pydantic_deep_assistant.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/datetime_tool.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/rag_tool.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/web_search.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/router.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/auth.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/api/versioning.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/channels/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/channels/base.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/clients/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/clients/redis.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/commands/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/commands/cleanup.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/commands/example.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/cache.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/channel_crypto.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/csrf.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/exceptions.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/logfire_setup.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/logging.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/middleware.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/oauth.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/rate_limit.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/sanitize.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/core/security.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/base.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/channel_bot.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/channel_identity.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/channel_session.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/chat_file.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/conversation.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/conversation_share.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/project.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/rag_document.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/session.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/sync_log.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/sync_source.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/user.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/db/models/webhook.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/main.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/config.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/connectors/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/connectors/google_drive.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/connectors/s3.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/documents.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/embeddings.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/image_describer.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/models.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/reranker.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/retrieval.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/sources/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/sources/base.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/sources/google_drive.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/rag/sources/s3.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/channel_bot.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/channel_identity.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/channel_session.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/conversation_share.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/project.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/session.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/repositories/sync_source.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/base.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/channel_bot.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/conversation_share.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/project.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/rag.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/session.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/sync_source.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/token.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/schemas/webhook.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/agent_invocation.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/conversation_share.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/services/file_storage.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/arq_app.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/celery_app.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/taskiq_app.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/examples.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/schedules.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/taskiq_examples.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/cli/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/cli/commands.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/scripts/.gitkeep +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/__init__.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/test_auth.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/test_exceptions.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/test_health.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/test_metrics.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/test_openapi.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/api/test_users.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/conftest.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_admin.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_agents.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_clients.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_commands.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_core.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_migrations.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_repositories.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_security.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_services.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_ssrf.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/backend/tests/test_worker.py +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docker-compose.dev.yml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docker-compose.frontend.yml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docker-compose.prod.yml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docker-compose.yml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/adding_features.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/commands.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/file-processing.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/add-agent-tool.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/add-api-endpoint.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/add-background-task.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/add-rag-source.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/add-sync-connector.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/configure-sync-sources.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/howto/customize-agent-prompt.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/patterns.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/docs/testing.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/.dockerignore +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/.env.example +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/.gitignore +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/.prettierignore +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/Dockerfile +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/README.md +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/e2e/auth.setup.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/e2e/auth.spec.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/e2e/chat.spec.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/e2e/home.spec.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/instrumentation.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/next.config.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/playwright.config.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/postcss.config.mjs +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(auth)/layout.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(auth)/login/page.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(auth)/register/page.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/layout.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/profile/page.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/settings/page.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/auth/callback/page.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/error.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/layout.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/page.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/shared/[token]/page.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/logout/route.ts +0 -0
- {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
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/register/route.ts +0 -0
- {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
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/[id]/route.ts +0 -0
- {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
- {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
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/export/route.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/route.ts +0 -0
- {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
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/files/[id]/route.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/files/upload/route.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/api/health/route.ts +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/global-error.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/globals.css +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/layout.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/not-found.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/app/providers.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/auth/index.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/copy-button.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/index.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/markdown-content.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-list.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/icons/google-icon.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/icons/index.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/language-switcher.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/auth-guard.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/header.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/index.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/landing-nav.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/page-transition.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/sidebar.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/theme/index.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/theme/theme-provider.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/accordion.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/alert-dialog.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/avatar.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/badge.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/button.test.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/button.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/card.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/checkbox.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/dialog.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/dropdown-menu.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/index.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/input.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/label.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/popover.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/progress.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/radio-group.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/scroll-area.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/select.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/separator.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/sheet.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/skeleton.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/spinner.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/switch.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/table.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/tabs.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/textarea.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/tooltip.tsx +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/index.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-admin-conversations.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-conversation-shares.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-projects.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/i18n.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/api-client.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/file-api.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/rag-api.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/utils.test.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/lib/utils.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/middleware.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/auth-store.test.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/chat-sidebar-store.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/conversation-store.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/index.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/project-store.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/sidebar-store.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/stores/theme-store.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/api.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/auth.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/index.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/project.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/src/types/speech.d.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/vercel.json +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/vitest.config.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/frontend/vitest.setup.ts +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/configmap.yaml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/deployment.yaml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/ingress.yaml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/kustomization.yaml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/namespace.yaml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/secret.yaml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/kubernetes/service.yaml +0 -0
- {fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/nginx/nginx.conf +0 -0
- {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.
|
|
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.
|
|
23
|
-
Requires-Dist: cookiecutter>=2.
|
|
24
|
-
Requires-Dist: email-validator>=2.
|
|
25
|
-
Requires-Dist: pydantic-settings>=2.
|
|
26
|
-
Requires-Dist: pydantic>=2.
|
|
27
|
-
Requires-Dist: questionary>=2.
|
|
28
|
-
Requires-Dist: rich>=
|
|
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>=
|
|
31
|
-
Requires-Dist: pytest-cov>=
|
|
32
|
-
Requires-Dist: pytest>=
|
|
33
|
-
Requires-Dist: ruff>=0.
|
|
34
|
-
Requires-Dist: ty>=0.0.
|
|
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.
|
|
37
|
-
Requires-Dist: mkdocs>=1.6.
|
|
38
|
-
Requires-Dist: pymdown-extensions>=10.
|
|
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
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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.
|
|
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.
|
|
48
|
-
"cookiecutter>=2.
|
|
49
|
-
"rich>=
|
|
50
|
-
"questionary>=2.
|
|
51
|
-
"pydantic>=2.
|
|
52
|
-
"pydantic-settings>=2.
|
|
53
|
-
"email-validator>=2.
|
|
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>=
|
|
59
|
-
"pytest-cov>=
|
|
60
|
-
"ruff>=0.
|
|
61
|
-
"ty>=0.0.
|
|
62
|
-
"pre-commit>=
|
|
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.
|
|
66
|
-
"mkdocs-material>=9.
|
|
67
|
-
"pymdown-extensions>=10.
|
|
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.
|
|
172
|
-
"pytest-cov>=7.
|
|
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
|
-
|
|
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")
|
{fastapi_fullstack-0.2.5 → fastapi_fullstack-0.2.7}/template/{{cookiecutter.project_slug}}/README.md
RENAMED
|
@@ -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,
|
|
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
|
-
"""
|
|
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
|
-
|
|
524
|
-
|
|
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
|
-
|
|
535
|
-
|
|
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
|
-
|
|
575
|
-
|
|
576
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
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:
|
|
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)
|
|
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 %}
|