fastapi-fullstack 0.1.7__py3-none-any.whl
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.1.7.dist-info/METADATA +739 -0
- fastapi_fullstack-0.1.7.dist-info/RECORD +241 -0
- fastapi_fullstack-0.1.7.dist-info/WHEEL +4 -0
- fastapi_fullstack-0.1.7.dist-info/entry_points.txt +2 -0
- fastapi_fullstack-0.1.7.dist-info/licenses/LICENSE +21 -0
- fastapi_gen/__init__.py +3 -0
- fastapi_gen/cli.py +442 -0
- fastapi_gen/config.py +356 -0
- fastapi_gen/generator.py +207 -0
- fastapi_gen/prompts.py +874 -0
- fastapi_gen/template/VARIABLES.md +276 -0
- fastapi_gen/template/cookiecutter.json +93 -0
- fastapi_gen/template/hooks/post_gen_project.py +355 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/.env.prod.example +56 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/.github/workflows/ci.yml +150 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/.gitignore +109 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/AGENTS.md +55 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/CLAUDE.md +99 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/Makefile +315 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/README.md +768 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/.dockerignore +60 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/.env.example +155 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/.pre-commit-config.yaml +32 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/Dockerfile +56 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/env.py +76 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/script.py.mako +30 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic/versions/.gitkeep +0 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/alembic.ini +48 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/__init__.py +3 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/admin.py +447 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/__init__.py +23 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/assistant.py +226 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/langchain_assistant.py +226 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/prompts.py +10 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/__init__.py +13 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/agents/tools/datetime_tool.py +17 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/__init__.py +1 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/deps.py +541 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/exception_handlers.py +98 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/router.py +10 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/__init__.py +9 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/__init__.py +87 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/agent.py +902 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/auth.py +395 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/conversations.py +498 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/health.py +227 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/items.py +275 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/oauth.py +205 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/sessions.py +168 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/users.py +333 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/webhooks.py +477 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/routes/v1/ws.py +46 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/api/versioning.py +221 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/clients/__init__.py +14 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/clients/redis.py +88 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/commands/__init__.py +117 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/commands/cleanup.py +75 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/commands/example.py +28 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/commands/seed.py +266 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/__init__.py +5 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/cache.py +23 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/config.py +267 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/csrf.py +153 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/exceptions.py +122 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/logfire_setup.py +101 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/middleware.py +99 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/oauth.py +23 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/rate_limit.py +58 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/sanitize.py +271 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/core/security.py +102 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/__init__.py +7 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/base.py +41 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/__init__.py +31 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/conversation.py +319 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/item.py +96 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/session.py +126 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/user.py +218 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/models/webhook.py +244 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/db/session.py +130 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/main.py +334 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/pipelines/__init__.py +9 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/pipelines/base.py +73 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/__init__.py +49 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/base.py +154 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/conversation.py +838 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/item.py +222 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/session.py +318 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/user.py +322 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/repositories/webhook.py +358 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/__init__.py +50 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/base.py +57 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/conversation.py +192 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/item.py +52 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/session.py +42 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/token.py +31 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/user.py +64 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/schemas/webhook.py +89 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/__init__.py +38 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/conversation.py +850 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/item.py +246 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/session.py +333 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/user.py +432 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/services/webhook.py +561 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/worker/__init__.py +5 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/worker/celery_app.py +64 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/worker/taskiq_app.py +38 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/__init__.py +25 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/examples.py +106 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/schedules.py +29 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/app/worker/tasks/taskiq_examples.py +92 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/cli/__init__.py +1 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/cli/commands.py +438 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/pyproject.toml +180 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/scripts/.gitkeep +0 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/__init__.py +1 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/api/__init__.py +1 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/api/test_auth.py +242 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/api/test_exceptions.py +151 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/api/test_health.py +113 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/api/test_items.py +310 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/api/test_users.py +253 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/conftest.py +151 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_admin.py +890 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_agents.py +261 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_clients.py +183 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_commands.py +173 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_core.py +143 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_pipelines.py +118 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_repositories.py +181 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_security.py +124 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_services.py +363 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/backend/tests/test_worker.py +85 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.dev.yml +242 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.frontend.yml +31 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.prod.yml +435 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/docker-compose.yml +241 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/docs/adding_features.md +132 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/docs/architecture.md +63 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/docs/patterns.md +161 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/docs/testing.md +120 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/.dockerignore +40 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/.env.example +12 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/.gitignore +45 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/.prettierignore +19 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/.prettierrc +11 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/Dockerfile +44 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/README.md +648 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/e2e/auth.setup.ts +49 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/e2e/auth.spec.ts +134 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/e2e/chat.spec.ts +207 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/e2e/home.spec.ts +73 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/instrumentation.ts +14 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/messages/en.json +84 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/messages/pl.json +84 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/next.config.ts +76 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/package.json +69 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/playwright.config.ts +101 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/postcss.config.mjs +7 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(auth)/layout.tsx +11 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(auth)/login/page.tsx +5 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(auth)/register/page.tsx +5 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/chat/page.tsx +48 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/dashboard/page.tsx +99 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/layout.tsx +17 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/(dashboard)/profile/page.tsx +152 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/auth/callback/page.tsx +113 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/layout.tsx +46 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/[locale]/page.tsx +73 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/login/route.ts +58 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/logout/route.ts +24 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/me/route.ts +39 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/oauth-callback/route.ts +50 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/refresh/route.ts +54 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/api/auth/register/route.ts +26 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/[id]/messages/route.ts +41 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/[id]/route.ts +108 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/api/conversations/route.ts +73 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/api/health/route.ts +21 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/globals.css +323 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/layout.tsx +22 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/app/providers.tsx +29 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/auth/index.ts +2 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/auth/login-form.tsx +120 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/auth/register-form.tsx +153 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-container.tsx +234 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/chat-input.tsx +72 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/conversation-sidebar.tsx +328 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/copy-button.tsx +46 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/index.ts +11 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/local-conversation-sidebar.tsx +295 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/markdown-content.tsx +167 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-item.tsx +79 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/message-list.tsx +18 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/chat/tool-call-card.tsx +79 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/icons/google-icon.tsx +32 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/icons/index.ts +3 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/language-switcher.tsx +97 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/header.tsx +65 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/index.ts +2 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/layout/sidebar.tsx +82 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/theme/index.ts +7 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/theme/theme-provider.tsx +53 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/theme/theme-toggle.tsx +105 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/badge.tsx +35 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/button.test.tsx +75 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/button.tsx +56 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/card.tsx +82 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/index.ts +13 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/input.tsx +21 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/label.tsx +21 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/components/ui/sheet.tsx +109 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/index.ts +7 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-auth.ts +97 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-chat.ts +203 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-conversations.ts +181 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-local-chat.ts +165 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/hooks/use-websocket.ts +105 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/i18n.ts +37 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/api-client.ts +90 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/constants.ts +39 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/server-api.ts +78 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/utils.test.ts +44 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/lib/utils.ts +44 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/middleware.ts +31 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/auth-store.test.ts +72 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/auth-store.ts +64 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/chat-sidebar-store.ts +17 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/chat-store.ts +65 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/conversation-store.ts +76 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/index.ts +9 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/local-chat-store.ts +255 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/sidebar-store.ts +17 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/stores/theme-store.ts +44 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/api.ts +27 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/auth.ts +52 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/chat.ts +83 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/conversation.ts +49 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/src/types/index.ts +10 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/tsconfig.json +28 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/vitest.config.ts +36 -0
- fastapi_gen/template/{{cookiecutter.project_slug}}/frontend/vitest.setup.ts +56 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Pydantic schemas."""
|
|
2
|
+
{%- set schemas = [] %}
|
|
3
|
+
{%- if cookiecutter.use_jwt or cookiecutter.include_example_crud or cookiecutter.enable_conversation_persistence or cookiecutter.enable_webhooks %}
|
|
4
|
+
# ruff: noqa: I001, RUF022 - Imports structured for Jinja2 template conditionals
|
|
5
|
+
{%- endif %}
|
|
6
|
+
{%- if cookiecutter.use_jwt %}
|
|
7
|
+
{%- set _ = schemas.extend(["UserCreate", "UserRead", "UserUpdate", "Token", "TokenPayload"]) %}
|
|
8
|
+
|
|
9
|
+
from app.schemas.token import Token, TokenPayload
|
|
10
|
+
from app.schemas.user import UserCreate, UserRead, UserUpdate
|
|
11
|
+
{%- endif %}
|
|
12
|
+
{%- if cookiecutter.enable_session_management and cookiecutter.use_jwt %}
|
|
13
|
+
{%- set _ = schemas.extend(["SessionRead", "SessionListResponse", "LogoutAllResponse"]) %}
|
|
14
|
+
|
|
15
|
+
from app.schemas.session import SessionRead, SessionListResponse, LogoutAllResponse
|
|
16
|
+
{%- endif %}
|
|
17
|
+
{%- if cookiecutter.include_example_crud and cookiecutter.use_database %}
|
|
18
|
+
{%- set _ = schemas.extend(["ItemCreate", "ItemRead", "ItemUpdate"]) %}
|
|
19
|
+
|
|
20
|
+
from app.schemas.item import ItemCreate, ItemRead, ItemUpdate
|
|
21
|
+
{%- endif %}
|
|
22
|
+
{%- if cookiecutter.enable_conversation_persistence and cookiecutter.use_database %}
|
|
23
|
+
{%- set _ = schemas.extend(["ConversationCreate", "ConversationRead", "ConversationUpdate", "MessageCreate", "MessageRead", "ToolCallRead"]) %}
|
|
24
|
+
|
|
25
|
+
from app.schemas.conversation import (
|
|
26
|
+
ConversationCreate,
|
|
27
|
+
ConversationRead,
|
|
28
|
+
ConversationUpdate,
|
|
29
|
+
MessageCreate,
|
|
30
|
+
MessageRead,
|
|
31
|
+
ToolCallRead,
|
|
32
|
+
)
|
|
33
|
+
{%- endif %}
|
|
34
|
+
{%- if cookiecutter.enable_webhooks and cookiecutter.use_database %}
|
|
35
|
+
{%- set _ = schemas.extend(["WebhookCreate", "WebhookRead", "WebhookUpdate", "WebhookDeliveryRead", "WebhookListResponse", "WebhookDeliveryListResponse", "WebhookTestResponse"]) %}
|
|
36
|
+
|
|
37
|
+
from app.schemas.webhook import (
|
|
38
|
+
WebhookCreate,
|
|
39
|
+
WebhookRead,
|
|
40
|
+
WebhookUpdate,
|
|
41
|
+
WebhookDeliveryRead,
|
|
42
|
+
WebhookListResponse,
|
|
43
|
+
WebhookDeliveryListResponse,
|
|
44
|
+
WebhookTestResponse,
|
|
45
|
+
)
|
|
46
|
+
{%- endif %}
|
|
47
|
+
{%- if schemas %}
|
|
48
|
+
|
|
49
|
+
__all__ = {{ schemas }}
|
|
50
|
+
{%- endif %}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Base Pydantic schemas."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from typing import Any
|
|
5
|
+
from zoneinfo import ZoneInfo
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, ConfigDict
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def serialize_datetime(dt: datetime) -> str:
|
|
11
|
+
"""Serialize datetime to ISO format with timezone.
|
|
12
|
+
|
|
13
|
+
Ensures all datetimes have explicit timezone (defaults to UTC).
|
|
14
|
+
"""
|
|
15
|
+
if dt.tzinfo is None:
|
|
16
|
+
dt = dt.replace(tzinfo=ZoneInfo("UTC"))
|
|
17
|
+
return dt.isoformat()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class BaseSchema(BaseModel):
|
|
21
|
+
"""Base schema with common configuration."""
|
|
22
|
+
|
|
23
|
+
model_config = ConfigDict(
|
|
24
|
+
from_attributes=True,
|
|
25
|
+
populate_by_name=True,
|
|
26
|
+
str_strip_whitespace=True,
|
|
27
|
+
json_encoders={datetime: serialize_datetime},
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def serializable_dict(self, **kwargs: Any) -> dict[str, Any]:
|
|
31
|
+
"""Return a dict with only JSON-serializable fields."""
|
|
32
|
+
from fastapi.encoders import jsonable_encoder
|
|
33
|
+
|
|
34
|
+
return jsonable_encoder(self.model_dump(**kwargs))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class TimestampSchema(BaseModel):
|
|
38
|
+
"""Schema with timestamp fields."""
|
|
39
|
+
|
|
40
|
+
created_at: datetime
|
|
41
|
+
updated_at: datetime | None = None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class BaseResponse(BaseModel):
|
|
45
|
+
"""Standard API response."""
|
|
46
|
+
|
|
47
|
+
success: bool = True
|
|
48
|
+
message: str | None = None
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ErrorResponse(BaseModel):
|
|
52
|
+
"""Standard error response."""
|
|
53
|
+
|
|
54
|
+
success: bool = False
|
|
55
|
+
error: str
|
|
56
|
+
detail: str | None = None
|
|
57
|
+
code: str | None = None
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
{%- if cookiecutter.enable_conversation_persistence %}
|
|
2
|
+
"""Conversation schemas for AI chat persistence.
|
|
3
|
+
|
|
4
|
+
This module contains Pydantic schemas for Conversation, Message, and ToolCall entities.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from typing import Literal
|
|
9
|
+
|
|
10
|
+
{%- if cookiecutter.use_postgresql %}
|
|
11
|
+
from uuid import UUID
|
|
12
|
+
{%- endif %}
|
|
13
|
+
|
|
14
|
+
from pydantic import Field
|
|
15
|
+
|
|
16
|
+
from app.schemas.base import BaseSchema, TimestampSchema
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# =============================================================================
|
|
20
|
+
# Tool Call Schemas
|
|
21
|
+
# =============================================================================
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ToolCallBase(BaseSchema):
|
|
25
|
+
"""Base tool call schema."""
|
|
26
|
+
|
|
27
|
+
tool_call_id: str = Field(..., description="External tool call ID from AI framework")
|
|
28
|
+
tool_name: str = Field(..., max_length=100, description="Name of the tool called")
|
|
29
|
+
args: dict = Field(default_factory=dict, description="Tool arguments")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ToolCallCreate(ToolCallBase):
|
|
33
|
+
"""Schema for creating a tool call record."""
|
|
34
|
+
|
|
35
|
+
started_at: datetime | None = Field(default=None, description="When the tool call started")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class ToolCallComplete(BaseSchema):
|
|
39
|
+
"""Schema for completing a tool call."""
|
|
40
|
+
|
|
41
|
+
result: str = Field(..., description="Tool execution result")
|
|
42
|
+
completed_at: datetime | None = Field(default=None, description="When the tool call completed")
|
|
43
|
+
success: bool = Field(default=True, description="Whether the tool call succeeded")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ToolCallRead(ToolCallBase):
|
|
47
|
+
"""Schema for reading a tool call (API response)."""
|
|
48
|
+
|
|
49
|
+
{%- if cookiecutter.use_postgresql %}
|
|
50
|
+
id: UUID
|
|
51
|
+
message_id: UUID
|
|
52
|
+
{%- else %}
|
|
53
|
+
id: str
|
|
54
|
+
message_id: str
|
|
55
|
+
{%- endif %}
|
|
56
|
+
result: str | None = None
|
|
57
|
+
status: Literal["pending", "running", "completed", "failed"] = "pending"
|
|
58
|
+
started_at: datetime
|
|
59
|
+
completed_at: datetime | None = None
|
|
60
|
+
duration_ms: int | None = None
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# =============================================================================
|
|
64
|
+
# Message Schemas
|
|
65
|
+
# =============================================================================
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class MessageBase(BaseSchema):
|
|
69
|
+
"""Base message schema."""
|
|
70
|
+
|
|
71
|
+
role: Literal["user", "assistant", "system"] = Field(..., description="Message role")
|
|
72
|
+
content: str = Field(..., description="Message content")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class MessageCreate(MessageBase):
|
|
76
|
+
"""Schema for creating a message."""
|
|
77
|
+
|
|
78
|
+
model_name: str | None = Field(default=None, max_length=100, description="AI model used")
|
|
79
|
+
tokens_used: int | None = Field(default=None, ge=0, description="Token count")
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class MessageRead(MessageBase, TimestampSchema):
|
|
83
|
+
"""Schema for reading a message (API response)."""
|
|
84
|
+
|
|
85
|
+
{%- if cookiecutter.use_postgresql %}
|
|
86
|
+
id: UUID
|
|
87
|
+
conversation_id: UUID
|
|
88
|
+
{%- else %}
|
|
89
|
+
id: str
|
|
90
|
+
conversation_id: str
|
|
91
|
+
{%- endif %}
|
|
92
|
+
model_name: str | None = None
|
|
93
|
+
tokens_used: int | None = None
|
|
94
|
+
tool_calls: list[ToolCallRead] = Field(default_factory=list)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class MessageReadSimple(MessageBase, TimestampSchema):
|
|
98
|
+
"""Simplified message schema without tool calls."""
|
|
99
|
+
|
|
100
|
+
{%- if cookiecutter.use_postgresql %}
|
|
101
|
+
id: UUID
|
|
102
|
+
conversation_id: UUID
|
|
103
|
+
{%- else %}
|
|
104
|
+
id: str
|
|
105
|
+
conversation_id: str
|
|
106
|
+
{%- endif %}
|
|
107
|
+
model_name: str | None = None
|
|
108
|
+
tokens_used: int | None = None
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# =============================================================================
|
|
112
|
+
# Conversation Schemas
|
|
113
|
+
# =============================================================================
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class ConversationBase(BaseSchema):
|
|
117
|
+
"""Base conversation schema."""
|
|
118
|
+
|
|
119
|
+
title: str | None = Field(default=None, max_length=255, description="Conversation title")
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class ConversationCreate(ConversationBase):
|
|
123
|
+
"""Schema for creating a conversation."""
|
|
124
|
+
|
|
125
|
+
{%- if cookiecutter.use_jwt %}
|
|
126
|
+
{%- if cookiecutter.use_postgresql %}
|
|
127
|
+
user_id: UUID | None = Field(default=None, description="Owner user ID")
|
|
128
|
+
{%- else %}
|
|
129
|
+
user_id: str | None = Field(default=None, description="Owner user ID")
|
|
130
|
+
{%- endif %}
|
|
131
|
+
{%- endif %}
|
|
132
|
+
pass
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class ConversationUpdate(BaseSchema):
|
|
136
|
+
"""Schema for updating a conversation."""
|
|
137
|
+
|
|
138
|
+
title: str | None = Field(default=None, max_length=255)
|
|
139
|
+
is_archived: bool | None = None
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class ConversationRead(ConversationBase, TimestampSchema):
|
|
143
|
+
"""Schema for reading a conversation (API response)."""
|
|
144
|
+
|
|
145
|
+
{%- if cookiecutter.use_postgresql %}
|
|
146
|
+
id: UUID
|
|
147
|
+
{%- if cookiecutter.use_jwt %}
|
|
148
|
+
user_id: UUID | None = None
|
|
149
|
+
{%- endif %}
|
|
150
|
+
{%- else %}
|
|
151
|
+
id: str
|
|
152
|
+
{%- if cookiecutter.use_jwt %}
|
|
153
|
+
user_id: str | None = None
|
|
154
|
+
{%- endif %}
|
|
155
|
+
{%- endif %}
|
|
156
|
+
is_archived: bool = False
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class ConversationReadWithMessages(ConversationRead):
|
|
160
|
+
"""Conversation with all messages."""
|
|
161
|
+
|
|
162
|
+
messages: list[MessageRead] = Field(default_factory=list)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class ConversationList(BaseSchema):
|
|
166
|
+
"""Schema for listing conversations."""
|
|
167
|
+
|
|
168
|
+
items: list[ConversationRead]
|
|
169
|
+
total: int
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
# =============================================================================
|
|
173
|
+
# Aggregated Schemas for API Responses
|
|
174
|
+
# =============================================================================
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class MessageList(BaseSchema):
|
|
178
|
+
"""Schema for listing messages."""
|
|
179
|
+
|
|
180
|
+
items: list[MessageReadSimple]
|
|
181
|
+
total: int
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
class ConversationWithLatestMessage(ConversationRead):
|
|
185
|
+
"""Conversation with its latest message for list views."""
|
|
186
|
+
|
|
187
|
+
latest_message: MessageReadSimple | None = None
|
|
188
|
+
message_count: int = 0
|
|
189
|
+
|
|
190
|
+
{%- else %}
|
|
191
|
+
"""Conversation schemas - not configured."""
|
|
192
|
+
{%- endif %}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{%- if cookiecutter.include_example_crud %}
|
|
2
|
+
"""Item schemas - example CRUD entity.
|
|
3
|
+
|
|
4
|
+
This module demonstrates standard Pydantic schemas for a CRUD entity.
|
|
5
|
+
You can use it as a template for creating your own schemas.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
{%- if cookiecutter.use_postgresql %}
|
|
9
|
+
from uuid import UUID
|
|
10
|
+
{%- endif %}
|
|
11
|
+
|
|
12
|
+
from pydantic import Field
|
|
13
|
+
|
|
14
|
+
from app.schemas.base import BaseSchema, TimestampSchema
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ItemBase(BaseSchema):
|
|
18
|
+
"""Base item schema with common fields."""
|
|
19
|
+
|
|
20
|
+
title: str = Field(max_length=255, description="Item title")
|
|
21
|
+
description: str | None = Field(default=None, description="Item description")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ItemCreate(ItemBase):
|
|
25
|
+
"""Schema for creating an item."""
|
|
26
|
+
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ItemUpdate(BaseSchema):
|
|
31
|
+
"""Schema for updating an item.
|
|
32
|
+
|
|
33
|
+
All fields are optional to allow partial updates.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
title: str | None = Field(default=None, max_length=255)
|
|
37
|
+
description: str | None = Field(default=None)
|
|
38
|
+
is_active: bool | None = None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ItemRead(ItemBase, TimestampSchema):
|
|
42
|
+
"""Schema for reading an item (API response)."""
|
|
43
|
+
|
|
44
|
+
{%- if cookiecutter.use_postgresql %}
|
|
45
|
+
id: UUID
|
|
46
|
+
{%- else %}
|
|
47
|
+
id: str
|
|
48
|
+
{%- endif %}
|
|
49
|
+
is_active: bool = True
|
|
50
|
+
{%- else %}
|
|
51
|
+
"""Item schemas - not configured."""
|
|
52
|
+
{%- endif %}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{%- if cookiecutter.enable_session_management and cookiecutter.use_jwt %}
|
|
2
|
+
"""Session schemas."""
|
|
3
|
+
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
{%- if cookiecutter.use_postgresql %}
|
|
6
|
+
from uuid import UUID
|
|
7
|
+
{%- endif %}
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SessionRead(BaseModel):
|
|
13
|
+
"""Session response schema."""
|
|
14
|
+
|
|
15
|
+
{%- if cookiecutter.use_postgresql %}
|
|
16
|
+
id: UUID
|
|
17
|
+
{%- else %}
|
|
18
|
+
id: str
|
|
19
|
+
{%- endif %}
|
|
20
|
+
device_name: str | None = None
|
|
21
|
+
device_type: str | None = None
|
|
22
|
+
ip_address: str | None = None
|
|
23
|
+
is_current: bool = False
|
|
24
|
+
created_at: datetime
|
|
25
|
+
last_used_at: datetime
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SessionListResponse(BaseModel):
|
|
29
|
+
"""Response for list of sessions."""
|
|
30
|
+
|
|
31
|
+
sessions: list[SessionRead]
|
|
32
|
+
total: int
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class LogoutAllResponse(BaseModel):
|
|
36
|
+
"""Response for logout all sessions."""
|
|
37
|
+
|
|
38
|
+
message: str
|
|
39
|
+
sessions_logged_out: int
|
|
40
|
+
{%- else %}
|
|
41
|
+
"""Session schemas - not configured."""
|
|
42
|
+
{%- endif %}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{%- if cookiecutter.use_jwt %}
|
|
2
|
+
"""Token schemas."""
|
|
3
|
+
|
|
4
|
+
from typing import Literal
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Token(BaseModel):
|
|
10
|
+
"""OAuth2 token response with refresh token."""
|
|
11
|
+
|
|
12
|
+
access_token: str
|
|
13
|
+
refresh_token: str
|
|
14
|
+
token_type: str = "bearer"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TokenPayload(BaseModel):
|
|
18
|
+
"""JWT token payload."""
|
|
19
|
+
|
|
20
|
+
sub: str | None = None
|
|
21
|
+
exp: int | None = None
|
|
22
|
+
type: Literal["access", "refresh"] | None = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class RefreshTokenRequest(BaseModel):
|
|
26
|
+
"""Request body for token refresh."""
|
|
27
|
+
|
|
28
|
+
refresh_token: str
|
|
29
|
+
{%- else %}
|
|
30
|
+
"""Token schemas - not configured."""
|
|
31
|
+
{%- endif %}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{%- if cookiecutter.use_jwt %}
|
|
2
|
+
"""User schemas."""
|
|
3
|
+
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from uuid import UUID
|
|
6
|
+
|
|
7
|
+
from pydantic import EmailStr, Field
|
|
8
|
+
|
|
9
|
+
from app.schemas.base import BaseSchema, TimestampSchema
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class UserRole(str, Enum):
|
|
13
|
+
"""User role enumeration for API schemas."""
|
|
14
|
+
|
|
15
|
+
ADMIN = "admin"
|
|
16
|
+
USER = "user"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class UserBase(BaseSchema):
|
|
20
|
+
"""Base user schema."""
|
|
21
|
+
|
|
22
|
+
email: EmailStr = Field(max_length=255)
|
|
23
|
+
full_name: str | None = Field(default=None, max_length=255)
|
|
24
|
+
is_active: bool = True
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class UserCreate(BaseSchema):
|
|
28
|
+
"""Schema for creating a user."""
|
|
29
|
+
|
|
30
|
+
email: EmailStr = Field(max_length=255)
|
|
31
|
+
password: str = Field(min_length=8, max_length=128)
|
|
32
|
+
full_name: str | None = Field(default=None, max_length=255)
|
|
33
|
+
role: UserRole = UserRole.USER
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class UserUpdate(BaseSchema):
|
|
37
|
+
"""Schema for updating a user."""
|
|
38
|
+
|
|
39
|
+
email: EmailStr | None = Field(default=None, max_length=255)
|
|
40
|
+
password: str | None = Field(default=None, min_length=8, max_length=128)
|
|
41
|
+
full_name: str | None = Field(default=None, max_length=255)
|
|
42
|
+
is_active: bool | None = None
|
|
43
|
+
role: UserRole | None = None
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class UserRead(UserBase, TimestampSchema):
|
|
47
|
+
"""Schema for reading a user."""
|
|
48
|
+
|
|
49
|
+
{%- if cookiecutter.use_postgresql %}
|
|
50
|
+
id: UUID
|
|
51
|
+
{%- elif cookiecutter.use_sqlite or cookiecutter.use_mongodb %}
|
|
52
|
+
id: str
|
|
53
|
+
{%- endif %}
|
|
54
|
+
is_superuser: bool = False
|
|
55
|
+
role: UserRole = UserRole.USER
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class UserInDB(UserRead):
|
|
59
|
+
"""User schema with hashed password (internal use)."""
|
|
60
|
+
|
|
61
|
+
hashed_password: str
|
|
62
|
+
{%- else %}
|
|
63
|
+
"""User schemas - not configured."""
|
|
64
|
+
{%- endif %}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{%- if cookiecutter.enable_webhooks and cookiecutter.use_database %}
|
|
2
|
+
"""Webhook schemas."""
|
|
3
|
+
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
{%- if cookiecutter.use_postgresql %}
|
|
6
|
+
from uuid import UUID
|
|
7
|
+
{%- endif %}
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, Field, HttpUrl
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class WebhookCreate(BaseModel):
|
|
13
|
+
"""Schema for creating a webhook."""
|
|
14
|
+
|
|
15
|
+
name: str = Field(..., min_length=1, max_length=255)
|
|
16
|
+
url: HttpUrl
|
|
17
|
+
events: list[str] = Field(..., min_length=1)
|
|
18
|
+
description: str | None = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class WebhookUpdate(BaseModel):
|
|
22
|
+
"""Schema for updating a webhook."""
|
|
23
|
+
|
|
24
|
+
name: str | None = Field(None, min_length=1, max_length=255)
|
|
25
|
+
url: HttpUrl | None = None
|
|
26
|
+
events: list[str] | None = Field(None, min_length=1)
|
|
27
|
+
is_active: bool | None = None
|
|
28
|
+
description: str | None = None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class WebhookRead(BaseModel):
|
|
32
|
+
"""Schema for reading a webhook."""
|
|
33
|
+
|
|
34
|
+
{%- if cookiecutter.use_postgresql %}
|
|
35
|
+
id: UUID
|
|
36
|
+
{%- else %}
|
|
37
|
+
id: str
|
|
38
|
+
{%- endif %}
|
|
39
|
+
name: str
|
|
40
|
+
url: str
|
|
41
|
+
events: list[str]
|
|
42
|
+
is_active: bool
|
|
43
|
+
description: str | None
|
|
44
|
+
created_at: datetime
|
|
45
|
+
updated_at: datetime
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class WebhookDeliveryRead(BaseModel):
|
|
49
|
+
"""Schema for reading a webhook delivery."""
|
|
50
|
+
|
|
51
|
+
{%- if cookiecutter.use_postgresql %}
|
|
52
|
+
id: UUID
|
|
53
|
+
webhook_id: UUID
|
|
54
|
+
{%- else %}
|
|
55
|
+
id: str
|
|
56
|
+
webhook_id: str
|
|
57
|
+
{%- endif %}
|
|
58
|
+
event_type: str
|
|
59
|
+
response_status: int | None
|
|
60
|
+
error_message: str | None
|
|
61
|
+
attempt_count: int
|
|
62
|
+
success: bool
|
|
63
|
+
created_at: datetime
|
|
64
|
+
delivered_at: datetime | None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class WebhookListResponse(BaseModel):
|
|
68
|
+
"""Response for list of webhooks."""
|
|
69
|
+
|
|
70
|
+
items: list[WebhookRead]
|
|
71
|
+
total: int
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class WebhookDeliveryListResponse(BaseModel):
|
|
75
|
+
"""Response for list of webhook deliveries."""
|
|
76
|
+
|
|
77
|
+
items: list[WebhookDeliveryRead]
|
|
78
|
+
total: int
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class WebhookTestResponse(BaseModel):
|
|
82
|
+
"""Response for webhook test."""
|
|
83
|
+
|
|
84
|
+
success: bool
|
|
85
|
+
status_code: int | None
|
|
86
|
+
message: str
|
|
87
|
+
{%- else %}
|
|
88
|
+
"""Webhook schemas - not configured."""
|
|
89
|
+
{%- endif %}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Services layer - business logic.
|
|
2
|
+
|
|
3
|
+
Services orchestrate business operations, using repositories for data access
|
|
4
|
+
and raising domain exceptions for error handling.
|
|
5
|
+
"""
|
|
6
|
+
{%- set services = [] %}
|
|
7
|
+
{%- if cookiecutter.use_jwt or cookiecutter.include_example_crud or cookiecutter.enable_conversation_persistence or cookiecutter.enable_webhooks %}
|
|
8
|
+
# ruff: noqa: I001, RUF022 - Imports structured for Jinja2 template conditionals
|
|
9
|
+
{%- endif %}
|
|
10
|
+
{%- if cookiecutter.use_jwt %}
|
|
11
|
+
{%- set _ = services.append("UserService") %}
|
|
12
|
+
|
|
13
|
+
from app.services.user import UserService
|
|
14
|
+
{%- endif %}
|
|
15
|
+
{%- if cookiecutter.enable_session_management and cookiecutter.use_jwt %}
|
|
16
|
+
{%- set _ = services.append("SessionService") %}
|
|
17
|
+
|
|
18
|
+
from app.services.session import SessionService
|
|
19
|
+
{%- endif %}
|
|
20
|
+
{%- if cookiecutter.include_example_crud and cookiecutter.use_database %}
|
|
21
|
+
{%- set _ = services.append("ItemService") %}
|
|
22
|
+
|
|
23
|
+
from app.services.item import ItemService
|
|
24
|
+
{%- endif %}
|
|
25
|
+
{%- if cookiecutter.enable_conversation_persistence and cookiecutter.use_database %}
|
|
26
|
+
{%- set _ = services.append("ConversationService") %}
|
|
27
|
+
|
|
28
|
+
from app.services.conversation import ConversationService
|
|
29
|
+
{%- endif %}
|
|
30
|
+
{%- if cookiecutter.enable_webhooks and cookiecutter.use_database %}
|
|
31
|
+
{%- set _ = services.append("WebhookService") %}
|
|
32
|
+
|
|
33
|
+
from app.services.webhook import WebhookService
|
|
34
|
+
{%- endif %}
|
|
35
|
+
{%- if services %}
|
|
36
|
+
|
|
37
|
+
__all__ = {{ services }}
|
|
38
|
+
{%- endif %}
|