diff --git a/.copier/.copier-answers.yml.jinja b/.copier/.copier-answers.yml.jinja
deleted file mode 100644
index 0028a2398a..0000000000
--- a/.copier/.copier-answers.yml.jinja
+++ /dev/null
@@ -1 +0,0 @@
-{{ _copier_answers|to_json -}}
diff --git a/.copier/update_dotenv.py b/.copier/update_dotenv.py
deleted file mode 100644
index 6576885626..0000000000
--- a/.copier/update_dotenv.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from pathlib import Path
-import json
-
-# Update the .env file with the answers from the .copier-answers.yml file
-# without using Jinja2 templates in the .env file, this way the code works as is
-# without needing Copier, but if Copier is used, the .env file will be updated
-root_path = Path(__file__).parent.parent
-answers_path = Path(__file__).parent / ".copier-answers.yml"
-answers = json.loads(answers_path.read_text())
-env_path = root_path / ".env"
-env_content = env_path.read_text()
-lines = []
-for line in env_content.splitlines():
- for key, value in answers.items():
- upper_key = key.upper()
- if line.startswith(f"{upper_key}="):
- if " " in value:
- content = f"{upper_key}={value!r}"
- else:
- content = f"{upper_key}={value}"
- new_line = line.replace(line, content)
- lines.append(new_line)
- break
- else:
- lines.append(line)
-env_path.write_text("\n".join(lines))
diff --git a/.env b/.env
deleted file mode 100644
index 1d44286e25..0000000000
--- a/.env
+++ /dev/null
@@ -1,45 +0,0 @@
-# Domain
-# This would be set to the production domain with an env var on deployment
-# used by Traefik to transmit traffic and aqcuire TLS certificates
-DOMAIN=localhost
-# To test the local Traefik config
-# DOMAIN=localhost.tiangolo.com
-
-# Used by the backend to generate links in emails to the frontend
-FRONTEND_HOST=http://localhost:5173
-# In staging and production, set this env var to the frontend host, e.g.
-# FRONTEND_HOST=https://dashboard.example.com
-
-# Environment: local, staging, production
-ENVIRONMENT=local
-
-PROJECT_NAME="Full Stack FastAPI Project"
-STACK_NAME=full-stack-fastapi-project
-
-# Backend
-BACKEND_CORS_ORIGINS="http://localhost,http://localhost:5173,https://localhost,https://localhost:5173,http://localhost.tiangolo.com"
-SECRET_KEY=changethis
-FIRST_SUPERUSER=admin@example.com
-FIRST_SUPERUSER_PASSWORD=changethis
-
-# Emails
-SMTP_HOST=
-SMTP_USER=
-SMTP_PASSWORD=
-EMAILS_FROM_EMAIL=info@example.com
-SMTP_TLS=True
-SMTP_SSL=False
-SMTP_PORT=587
-
-# Postgres
-POSTGRES_SERVER=localhost
-POSTGRES_PORT=5432
-POSTGRES_DB=app
-POSTGRES_USER=postgres
-POSTGRES_PASSWORD=changethis
-
-SENTRY_DSN=
-
-# Configure these with your own Docker registry images
-DOCKER_IMAGE_BACKEND=backend
-DOCKER_IMAGE_FRONTEND=frontend
diff --git a/.github/DISCUSSION_TEMPLATE/questions.yml b/.github/DISCUSSION_TEMPLATE/questions.yml
deleted file mode 100644
index af6abf4661..0000000000
--- a/.github/DISCUSSION_TEMPLATE/questions.yml
+++ /dev/null
@@ -1,118 +0,0 @@
-labels: [question]
-body:
- - type: markdown
- attributes:
- value: |
- Thanks for your interest in this project! π
-
- Please follow these instructions, fill every question, and do every step. π
-
- I'm asking this because answering questions and solving problems in GitHub is what consumes most of the time.
-
- I end up not being able to add new features, fix bugs, review pull requests, etc. as fast as I wish because I have to spend too much time handling questions.
-
- All that, on top of all the incredible help provided by a bunch of community members, that give a lot of their time to come here and help others.
-
- That's a lot of work, but if more users came to help others like them just a little bit more, it would be much less effort for them (and you and me π
).
-
- By asking questions in a structured way (following this) it will be much easier to help you.
-
- And there's a high chance that you will find the solution along the way and you won't even have to submit it and wait for an answer. π
-
- As there are too many questions, I'll have to discard and close the incomplete ones. That will allow me (and others) to focus on helping people like you that follow the whole process and help us help you. π€
- - type: checkboxes
- id: checks
- attributes:
- label: First Check
- description: Please confirm and check all the following options.
- options:
- - label: I added a very descriptive title here.
- required: true
- - label: I used the GitHub search to find a similar question and didn't find it.
- required: true
- - label: I searched in the documentation/README.
- required: true
- - label: I already searched in Google "How to do X" and didn't find any information.
- required: true
- - label: I already read and followed all the tutorial in the docs/README and didn't find an answer.
- required: true
- - type: checkboxes
- id: help
- attributes:
- label: Commit to Help
- description: |
- After submitting this, I commit to one of:
-
- * Read open questions until I find 2 where I can help someone and add a comment to help there.
- * I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
-
- options:
- - label: I commit to help with one of those options π
- required: true
- - type: textarea
- id: example
- attributes:
- label: Example Code
- description: |
- Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
-
- If I (or someone) can copy it, run it, and see it right away, there's a much higher chance I (or someone) will be able to help you.
-
- placeholder: |
- Write your example code here.
- render: Text
- validations:
- required: true
- - type: textarea
- id: description
- attributes:
- label: Description
- description: |
- What is the problem, question, or error?
-
- Write a short description telling me what you are doing, what you expect to happen, and what is currently happening.
- placeholder: |
- * Open the browser and call the endpoint `/`.
- * It returns a JSON with `{"message": "Hello World"}`.
- * But I expected it to return `{"message": "Hello Morty"}`.
- validations:
- required: true
- - type: dropdown
- id: os
- attributes:
- label: Operating System
- description: What operating system are you on?
- multiple: true
- options:
- - Linux
- - Windows
- - macOS
- - Other
- validations:
- required: true
- - type: textarea
- id: os-details
- attributes:
- label: Operating System Details
- description: You can add more details about your operating system here, in particular if you chose "Other".
- validations:
- required: true
- - type: input
- id: python-version
- attributes:
- label: Python Version
- description: |
- What Python version are you using?
-
- You can find the Python version with:
-
- ```bash
- python --version
- ```
- validations:
- required: true
- - type: textarea
- id: context
- attributes:
- label: Additional Context
- description: Add any additional context information or screenshots you think are useful.
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index 0ffc101a3f..0000000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1 +0,0 @@
-github: [tiangolo]
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
deleted file mode 100644
index 50bde36072..0000000000
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-blank_issues_enabled: false
-contact_links:
- - name: Security Contact
- about: Please report security vulnerabilities to security@tiangolo.com
- - name: Question or Problem
- about: Ask a question or ask about a problem in GitHub Discussions.
- url: https://github.com/fastapi/full-stack-fastapi-template/discussions/categories/questions
- - name: Feature Request
- about: To suggest an idea or ask about a feature, please start with a question saying what you would like to achieve. There might be a way to do it already.
- url: https://github.com/fastapi/full-stack-fastapi-template/discussions/categories/questions
diff --git a/.github/ISSUE_TEMPLATE/privileged.yml b/.github/ISSUE_TEMPLATE/privileged.yml
deleted file mode 100644
index 6438848c83..0000000000
--- a/.github/ISSUE_TEMPLATE/privileged.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-name: Privileged
-description: You are @tiangolo or he asked you directly to create an issue here. If not, check the other options. π
-body:
- - type: markdown
- attributes:
- value: |
- Thanks for your interest in this project! π
-
- If you are not @tiangolo or he didn't ask you directly to create an issue here, please start the conversation in a [Question in GitHub Discussions](https://github.com/tiangolo/full-stack-fastapi-template/discussions/categories/questions) instead.
- - type: checkboxes
- id: privileged
- attributes:
- label: Privileged issue
- description: Confirm that you are allowed to create an issue here.
- options:
- - label: I'm @tiangolo or he asked me directly to create an issue here.
- required: true
- - type: textarea
- id: content
- attributes:
- label: Issue Content
- description: Add the content of the issue here.
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index 854069dfa6..0000000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-version: 2
-updates:
- # GitHub Actions
- - package-ecosystem: github-actions
- directory: /
- schedule:
- interval: daily
- commit-message:
- prefix: β¬
- # Python
- - package-ecosystem: pip
- directory: /
- schedule:
- interval: daily
- commit-message:
- prefix: β¬
diff --git a/.github/labeler.yml b/.github/labeler.yml
deleted file mode 100644
index ed657c23d7..0000000000
--- a/.github/labeler.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-docs:
- - all:
- - changed-files:
- - any-glob-to-any-file:
- - '**/*.md'
- - all-globs-to-all-files:
- - '!frontend/**'
- - '!backend/**'
- - '!.github/**'
- - '!scripts/**'
- - '!.gitignore'
- - '!.pre-commit-config.yaml'
-
-internal:
- - all:
- - changed-files:
- - any-glob-to-any-file:
- - .github/**
- - scripts/**
- - .gitignore
- - .pre-commit-config.yaml
- - all-globs-to-all-files:
- - '!./**/*.md'
- - '!frontend/**'
- - '!backend/**'
diff --git a/.github/workflows/add-to-project.yml b/.github/workflows/add-to-project.yml
deleted file mode 100644
index dccea83f35..0000000000
--- a/.github/workflows/add-to-project.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-name: Add to Project
-
-on:
- pull_request_target:
- issues:
- types:
- - opened
- - reopened
-
-jobs:
- add-to-project:
- name: Add to project
- runs-on: ubuntu-latest
- steps:
- - uses: actions/add-to-project@v1.0.2
- with:
- project-url: https://github.com/orgs/fastapi/projects/2
- github-token: ${{ secrets.PROJECTS_TOKEN }}
diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml
deleted file mode 100644
index a64d02a156..0000000000
--- a/.github/workflows/deploy-production.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-name: Deploy to Production
-
-on:
- release:
- types:
- - published
-
-jobs:
- deploy:
- # Do not deploy in the main repository, only in user projects
- if: github.repository_owner != 'fastapi'
- runs-on:
- - self-hosted
- - production
- env:
- ENVIRONMENT: production
- DOMAIN: ${{ secrets.DOMAIN_PRODUCTION }}
- STACK_NAME: ${{ secrets.STACK_NAME_PRODUCTION }}
- SECRET_KEY: ${{ secrets.SECRET_KEY }}
- FIRST_SUPERUSER: ${{ secrets.FIRST_SUPERUSER }}
- FIRST_SUPERUSER_PASSWORD: ${{ secrets.FIRST_SUPERUSER_PASSWORD }}
- SMTP_HOST: ${{ secrets.SMTP_HOST }}
- SMTP_USER: ${{ secrets.SMTP_USER }}
- SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }}
- EMAILS_FROM_EMAIL: ${{ secrets.EMAILS_FROM_EMAIL }}
- POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
- SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - run: docker compose -f docker-compose.yml --project-name ${{ secrets.STACK_NAME_PRODUCTION }} build
- - run: docker compose -f docker-compose.yml --project-name ${{ secrets.STACK_NAME_PRODUCTION }} up -d
diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml
deleted file mode 100644
index 26bd692fd8..0000000000
--- a/.github/workflows/deploy-staging.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-name: Deploy to Staging
-
-on:
- push:
- branches:
- - master
-
-jobs:
- deploy:
- # Do not deploy in the main repository, only in user projects
- if: github.repository_owner != 'fastapi'
- runs-on:
- - self-hosted
- - staging
- env:
- ENVIRONMENT: staging
- DOMAIN: ${{ secrets.DOMAIN_STAGING }}
- STACK_NAME: ${{ secrets.STACK_NAME_STAGING }}
- SECRET_KEY: ${{ secrets.SECRET_KEY }}
- FIRST_SUPERUSER: ${{ secrets.FIRST_SUPERUSER }}
- FIRST_SUPERUSER_PASSWORD: ${{ secrets.FIRST_SUPERUSER_PASSWORD }}
- SMTP_HOST: ${{ secrets.SMTP_HOST }}
- SMTP_USER: ${{ secrets.SMTP_USER }}
- SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }}
- EMAILS_FROM_EMAIL: ${{ secrets.EMAILS_FROM_EMAIL }}
- POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
- SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - run: docker compose -f docker-compose.yml --project-name ${{ secrets.STACK_NAME_STAGING }} build
- - run: docker compose -f docker-compose.yml --project-name ${{ secrets.STACK_NAME_STAGING }} up -d
diff --git a/.github/workflows/generate-client.yml b/.github/workflows/generate-client.yml
deleted file mode 100644
index 304363ce96..0000000000
--- a/.github/workflows/generate-client.yml
+++ /dev/null
@@ -1,61 +0,0 @@
-name: Generate Client
-
-on:
- pull_request:
- types:
- - opened
- - synchronize
-
-jobs:
- generate-client:
- permissions:
- contents: write
- runs-on: ubuntu-latest
- steps:
- # For PRs from forks
- - uses: actions/checkout@v4
- # For PRs from the same repo
- - uses: actions/checkout@v4
- if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' )
- with:
- ref: ${{ github.head_ref }}
- token: ${{ secrets.FULL_STACK_FASTAPI_TEMPLATE_REPO_TOKEN }}
- - uses: actions/setup-node@v4
- with:
- node-version: lts/*
- - uses: actions/setup-python@v5
- with:
- python-version: "3.10"
- - name: Install uv
- uses: astral-sh/setup-uv@v5
- with:
- version: "0.4.15"
- enable-cache: true
- - name: Install dependencies
- run: npm ci
- working-directory: frontend
- - run: uv sync
- working-directory: backend
- - run: uv run bash scripts/generate-client.sh
- env:
- VIRTUAL_ENV: backend/.venv
- ENVIRONMENT: production
- SECRET_KEY: just-for-generating-client
- POSTGRES_PASSWORD: just-for-generating-client
- FIRST_SUPERUSER_PASSWORD: just-for-generating-client
- - name: Add changes to git
- run: |
- git config --local user.email "github-actions@github.com"
- git config --local user.name "github-actions"
- git add frontend/src/client
- # Same repo PRs
- - name: Push changes
- if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' )
- run: |
- git diff --staged --quiet || git commit -m "β¨ Autogenerate frontend client"
- git push
- # Fork PRs
- - name: Check changes
- if: ( github.event_name == 'pull_request' && github.secret_source != 'Actions' )
- run: |
- git diff --staged --quiet || (echo "Changes detected in generated client, run scripts/generate-client.sh and commit the changes" && exit 1)
diff --git a/.github/workflows/issue-manager.yml b/.github/workflows/issue-manager.yml
deleted file mode 100644
index 109ac0e989..0000000000
--- a/.github/workflows/issue-manager.yml
+++ /dev/null
@@ -1,47 +0,0 @@
-name: Issue Manager
-
-on:
- schedule:
- - cron: "21 17 * * *"
- issue_comment:
- types:
- - created
- issues:
- types:
- - labeled
- pull_request_target:
- types:
- - labeled
- workflow_dispatch:
-
-permissions:
- issues: write
- pull-requests: write
-
-jobs:
- issue-manager:
- if: github.repository_owner == 'fastapi'
- runs-on: ubuntu-latest
- steps:
- - name: Dump GitHub context
- env:
- GITHUB_CONTEXT: ${{ toJson(github) }}
- run: echo "$GITHUB_CONTEXT"
- - uses: tiangolo/issue-manager@0.5.1
- with:
- token: ${{ secrets.GITHUB_TOKEN }}
- config: >
- {
- "answered": {
- "delay": 864000,
- "message": "Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs."
- },
- "waiting": {
- "delay": 2628000,
- "message": "As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR."
- },
- "invalid": {
- "delay": 0,
- "message": "This was marked as invalid and will be closed now. If this is an error, please provide additional details."
- }
- }
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
deleted file mode 100644
index e8e58015a2..0000000000
--- a/.github/workflows/labeler.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-name: Labels
-on:
- pull_request_target:
- types:
- - opened
- - synchronize
- - reopened
- # For label-checker
- - labeled
- - unlabeled
-
-jobs:
- labeler:
- permissions:
- contents: read
- pull-requests: write
- runs-on: ubuntu-latest
- steps:
- - uses: actions/labeler@v5
- if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }}
- - run: echo "Done adding labels"
- # Run this after labeler applied labels
- check-labels:
- needs:
- - labeler
- permissions:
- pull-requests: read
- runs-on: ubuntu-latest
- steps:
- - uses: docker://agilepathway/pull-request-label-checker:latest
- with:
- one_of: breaking,security,feature,bug,refactor,upgrade,docs,lang-all,internal
- repo_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/latest-changes.yml b/.github/workflows/latest-changes.yml
deleted file mode 100644
index 607c5243b0..0000000000
--- a/.github/workflows/latest-changes.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-name: Latest Changes
-
-on:
- pull_request_target:
- branches:
- - master
- types:
- - closed
- workflow_dispatch:
- inputs:
- number:
- description: PR number
- required: true
- debug_enabled:
- description: "Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)"
- required: false
- default: "false"
-
-jobs:
- latest-changes:
- runs-on: ubuntu-latest
- permissions:
- pull-requests: read
- steps:
- - name: Dump GitHub context
- env:
- GITHUB_CONTEXT: ${{ toJson(github) }}
- run: echo "$GITHUB_CONTEXT"
- - uses: actions/checkout@v4
- with:
- # To allow latest-changes to commit to the main branch
- token: ${{ secrets.LATEST_CHANGES }}
- - uses: tiangolo/latest-changes@0.3.2
- with:
- token: ${{ secrets.GITHUB_TOKEN }}
- latest_changes_file: ./release-notes.md
- latest_changes_header: "## Latest Changes"
- end_regex: "^## "
- debug_logs: true
- label_header_prefix: "### "
diff --git a/.github/workflows/lint-backend.yml b/.github/workflows/lint-backend.yml
deleted file mode 100644
index a6e536bffe..0000000000
--- a/.github/workflows/lint-backend.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-name: Lint Backend
-
-on:
- push:
- branches:
- - master
- pull_request:
- types:
- - opened
- - synchronize
-
-jobs:
- lint-backend:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - name: Set up Python
- uses: actions/setup-python@v5
- with:
- python-version: "3.10"
- - name: Install uv
- uses: astral-sh/setup-uv@v5
- with:
- version: "0.4.15"
- enable-cache: true
- - run: uv run bash scripts/lint.sh
- working-directory: backend
diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml
deleted file mode 100644
index 5b13c58689..0000000000
--- a/.github/workflows/playwright.yml
+++ /dev/null
@@ -1,131 +0,0 @@
-name: Playwright Tests
-
-on:
- push:
- branches:
- - master
- pull_request:
- types:
- - opened
- - synchronize
- workflow_dispatch:
- inputs:
- debug_enabled:
- description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
- required: false
- default: 'false'
-
-jobs:
- changes:
- runs-on: ubuntu-latest
- # Set job outputs to values from filter step
- outputs:
- changed: ${{ steps.filter.outputs.changed }}
- steps:
- - uses: actions/checkout@v4
- # For pull requests it's not necessary to checkout the code but for the main branch it is
- - uses: dorny/paths-filter@v3
- id: filter
- with:
- filters: |
- changed:
- - backend/**
- - frontend/**
- - .env
- - docker-compose*.yml
- - .github/workflows/playwright.yml
-
- test-playwright:
- needs:
- - changes
- if: ${{ needs.changes.outputs.changed == 'true' }}
- timeout-minutes: 60
- runs-on: ubuntu-latest
- strategy:
- matrix:
- shardIndex: [1, 2, 3, 4]
- shardTotal: [4]
- fail-fast: false
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: lts/*
- - uses: actions/setup-python@v5
- with:
- python-version: '3.10'
- - name: Setup tmate session
- uses: mxschmitt/action-tmate@v3
- if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
- with:
- limit-access-to-actor: true
- - name: Install uv
- uses: astral-sh/setup-uv@v5
- with:
- version: "0.4.15"
- enable-cache: true
- - run: uv sync
- working-directory: backend
- - run: npm ci
- working-directory: frontend
- - run: uv run bash scripts/generate-client.sh
- env:
- VIRTUAL_ENV: backend/.venv
- - run: docker compose build
- - run: docker compose down -v --remove-orphans
- - name: Run Playwright tests
- run: docker compose run --rm playwright npx playwright test --fail-on-flaky-tests --trace=retain-on-failure --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
- - run: docker compose down -v --remove-orphans
- - name: Upload blob report to GitHub Actions Artifacts
- if: ${{ !cancelled() }}
- uses: actions/upload-artifact@v4
- with:
- name: blob-report-${{ matrix.shardIndex }}
- path: frontend/blob-report
- include-hidden-files: true
- retention-days: 1
-
- merge-playwright-reports:
- needs:
- - test-playwright
- - changes
- # Merge reports after playwright-tests, even if some shards have failed
- if: ${{ !cancelled() && needs.changes.outputs.changed == 'true' }}
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: 20
- - name: Install dependencies
- run: npm ci
- working-directory: frontend
- - name: Download blob reports from GitHub Actions Artifacts
- uses: actions/download-artifact@v4
- with:
- path: frontend/all-blob-reports
- pattern: blob-report-*
- merge-multiple: true
- - name: Merge into HTML Report
- run: npx playwright merge-reports --reporter html ./all-blob-reports
- working-directory: frontend
- - name: Upload HTML report
- uses: actions/upload-artifact@v4
- with:
- name: html-report--attempt-${{ github.run_attempt }}
- path: frontend/playwright-report
- retention-days: 30
- include-hidden-files: true
-
- # https://github.com/marketplace/actions/alls-green#why
- alls-green-playwright: # This job does nothing and is only used for the branch protection
- if: always()
- needs:
- - test-playwright
- runs-on: ubuntu-latest
- steps:
- - name: Decide whether the needed jobs succeeded or failed
- uses: re-actors/alls-green@release/v1
- with:
- jobs: ${{ toJSON(needs) }}
- allowed-skips: test-playwright
diff --git a/.github/workflows/smokeshow.yml b/.github/workflows/smokeshow.yml
deleted file mode 100644
index 61fde520ea..0000000000
--- a/.github/workflows/smokeshow.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-name: Smokeshow
-
-on:
- workflow_run:
- workflows: [Test Backend]
- types: [completed]
-
-jobs:
- smokeshow:
- if: ${{ github.event.workflow_run.conclusion == 'success' }}
- runs-on: ubuntu-latest
- permissions:
- actions: read
- statuses: write
-
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-python@v5
- with:
- python-version: "3.10"
- - run: pip install smokeshow
- - uses: actions/download-artifact@v4
- with:
- name: coverage-html
- path: backend/htmlcov
- github-token: ${{ secrets.GITHUB_TOKEN }}
- run-id: ${{ github.event.workflow_run.id }}
- - run: smokeshow upload backend/htmlcov
- env:
- SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Coverage {coverage-percentage}
- SMOKESHOW_GITHUB_COVERAGE_THRESHOLD: 90
- SMOKESHOW_GITHUB_CONTEXT: coverage
- SMOKESHOW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- SMOKESHOW_GITHUB_PR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
- SMOKESHOW_AUTH_KEY: ${{ secrets.SMOKESHOW_AUTH_KEY }}
diff --git a/.github/workflows/test-backend.yml b/.github/workflows/test-backend.yml
deleted file mode 100644
index cbbb78de46..0000000000
--- a/.github/workflows/test-backend.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-name: Test Backend
-
-on:
- push:
- branches:
- - master
- pull_request:
- types:
- - opened
- - synchronize
-
-jobs:
- test-backend:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - name: Set up Python
- uses: actions/setup-python@v5
- with:
- python-version: "3.10"
- - name: Install uv
- uses: astral-sh/setup-uv@v5
- with:
- version: "0.4.15"
- enable-cache: true
- - run: docker compose down -v --remove-orphans
- - run: docker compose up -d db mailcatcher
- - name: Migrate DB
- run: uv run bash scripts/prestart.sh
- working-directory: backend
- - name: Run tests
- run: uv run bash scripts/tests-start.sh "Coverage for ${{ github.sha }}"
- working-directory: backend
- - run: docker compose down -v --remove-orphans
- - name: Store coverage files
- uses: actions/upload-artifact@v4
- with:
- name: coverage-html
- path: backend/htmlcov
- include-hidden-files: true
diff --git a/.github/workflows/test-docker-compose.yml b/.github/workflows/test-docker-compose.yml
deleted file mode 100644
index 17792ede50..0000000000
--- a/.github/workflows/test-docker-compose.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: Test Docker Compose
-
-on:
- push:
- branches:
- - master
- pull_request:
- types:
- - opened
- - synchronize
-
-jobs:
-
- test-docker-compose:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - run: docker compose build
- - run: docker compose down -v --remove-orphans
- - run: docker compose up -d --wait backend frontend adminer
- - name: Test backend is up
- run: curl http://localhost:8000/api/v1/utils/health-check
- - name: Test frontend is up
- run: curl http://localhost:5173
- - run: docker compose down -v --remove-orphans
diff --git a/.gitignore b/.gitignore
index a6dd346572..5997da43b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ node_modules/
/playwright-report/
/blob-report/
/playwright/.cache/
+.env
\ No newline at end of file
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
deleted file mode 100644
index 512da0105c..0000000000
--- a/.pre-commit-config.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-# See https://pre-commit.com for more information
-# See https://pre-commit.com/hooks.html for more hooks
-repos:
- - repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.4.0
- hooks:
- - id: check-added-large-files
- - id: check-toml
- - id: check-yaml
- args:
- - --unsafe
- - id: end-of-file-fixer
- exclude: |
- (?x)^(
- frontend/src/client/.*|
- backend/app/email-templates/build/.*
- )$
- - id: trailing-whitespace
- exclude: ^frontend/src/client/.*
- - repo: https://github.com/charliermarsh/ruff-pre-commit
- rev: v0.2.2
- hooks:
- - id: ruff
- args:
- - --fix
- - id: ruff-format
-
-ci:
- autofix_commit_msg: π¨ [pre-commit.ci] Auto format from pre-commit.com hooks
- autoupdate_commit_msg: β¬ [pre-commit.ci] pre-commit autoupdate
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index f11987b50c..0000000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2019 SebastiΓ‘n RamΓrez
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README.md b/README.md
index afe124f3fb..db0444b48d 100644
--- a/README.md
+++ b/README.md
@@ -1,239 +1,91 @@
-# Full Stack FastAPI Template
-
-
-
-
-## Technology Stack and Features
-
-- β‘ [**FastAPI**](https://fastapi.tiangolo.com) for the Python backend API.
- - π§° [SQLModel](https://sqlmodel.tiangolo.com) for the Python SQL database interactions (ORM).
- - π [Pydantic](https://docs.pydantic.dev), used by FastAPI, for the data validation and settings management.
- - πΎ [PostgreSQL](https://www.postgresql.org) as the SQL database.
-- π [React](https://react.dev) for the frontend.
- - π Using TypeScript, hooks, Vite, and other parts of a modern frontend stack.
- - π¨ [Chakra UI](https://chakra-ui.com) for the frontend components.
- - π€ An automatically generated frontend client.
- - π§ͺ [Playwright](https://playwright.dev) for End-to-End testing.
- - π¦ Dark mode support.
-- π [Docker Compose](https://www.docker.com) for development and production.
-- π Secure password hashing by default.
-- π JWT (JSON Web Token) authentication.
-- π« Email based password recovery.
-- β
Tests with [Pytest](https://pytest.org).
-- π [Traefik](https://traefik.io) as a reverse proxy / load balancer.
-- π’ Deployment instructions using Docker Compose, including how to set up a frontend Traefik proxy to handle automatic HTTPS certificates.
-- π CI (continuous integration) and CD (continuous deployment) based on GitHub Actions.
-
-### Dashboard Login
-
-[](https://github.com/fastapi/full-stack-fastapi-template)
-
-### Dashboard - Admin
-
-[](https://github.com/fastapi/full-stack-fastapi-template)
-
-### Dashboard - Create User
-
-[](https://github.com/fastapi/full-stack-fastapi-template)
-
-### Dashboard - Items
-
-[](https://github.com/fastapi/full-stack-fastapi-template)
-
-### Dashboard - User Settings
-
-[](https://github.com/fastapi/full-stack-fastapi-template)
-
-### Dashboard - Dark Mode
-
-[](https://github.com/fastapi/full-stack-fastapi-template)
-
-### Interactive API Documentation
-
-[](https://github.com/fastapi/full-stack-fastapi-template)
-
-## How To Use It
-
-You can **just fork or clone** this repository and use it as is.
-
-β¨ It just works. β¨
-
-### How to Use a Private Repository
-
-If you want to have a private repository, GitHub won't allow you to simply fork it as it doesn't allow changing the visibility of forks.
-
-But you can do the following:
-
-- Create a new GitHub repo, for example `my-full-stack`.
-- Clone this repository manually, set the name with the name of the project you want to use, for example `my-full-stack`:
-
-```bash
-git clone git@github.com:fastapi/full-stack-fastapi-template.git my-full-stack
-```
-
-- Enter into the new directory:
+# π BetterLMS π
+BetterLMS is a lightweight Learning Management System (LMS) built with **FastAPI** for the backend and **React (TypeScript + Vite + Chakra UI)** for the frontend. It supports **role-based access control**, **user management**, **course assignments**, and **tests for employees**.
+### Getting started
```bash
-cd my-full-stack
+./start.sh # starts frontend and backend, run this after setup.
```
-- Set the new origin to your new repository, copy it from the GitHub interface, for example:
-
+### Python environment
```bash
-git remote set-url origin git@github.com:octocat/my-full-stack.git
+cd backend
+uv sync
+source .venv/bin/activate
```
-- Add this repo as another "remote" to allow you to get updates later:
-
+### Backend (FastAPI)
```bash
-git remote add upstream git@github.com:fastapi/full-stack-fastapi-template.git
+cd backend
+fastapi run app/main.py
```
-- Push the code to your new repository:
-
+### NODE environment
+[Install nvm](https://github.com/nvm-sh/nvm)
```bash
-git push -u origin master
+nvm install node # "node" is an alias for the latest version
+nvm install-latest-npm
```
-### Update From the Original Template
-
-After cloning the repository, and after doing changes, you might want to get the latest changes from this original template.
-
-- Make sure you added the original repository as a remote, you can check it with:
-
+### Frontend (React + Vite)
```bash
-git remote -v
-
-origin git@github.com:octocat/my-full-stack.git (fetch)
-origin git@github.com:octocat/my-full-stack.git (push)
-upstream git@github.com:fastapi/full-stack-fastapi-template.git (fetch)
-upstream git@github.com:fastapi/full-stack-fastapi-template.git (push)
+cd frontend
+npm install
+npm run dev
```
-- Pull the latest changes without merging:
-
-```bash
-git pull --no-commit upstream master
-```
-
-This will download the latest changes from this template without committing them, that way you can check everything is right before committing.
-
-- If there are conflicts, solve them in your editor.
-
-- Once you are done, commit the changes:
-
-```bash
-git merge --continue
-```
-
-### Configure
-
-You can then update configs in the `.env` files to customize your configurations.
-
-Before deploying it, make sure you change at least the values for:
-
-- `SECRET_KEY`
-- `FIRST_SUPERUSER_PASSWORD`
-- `POSTGRES_PASSWORD`
-
-You can (and should) pass these as environment variables from secrets.
-
-Read the [deployment.md](./deployment.md) docs for more details.
-
-### Generate Secret Keys
-
-Some environment variables in the `.env` file have a default value of `changethis`.
-
-You have to change them with a secret key, to generate secret keys you can run the following command:
-
-```bash
-python -c "import secrets; print(secrets.token_urlsafe(32))"
-```
-
-Copy the content and use that as password / secret key. And run that again to generate another secure key.
-
-## How To Use It - Alternative With Copier
-
-This repository also supports generating a new project using [Copier](https://copier.readthedocs.io).
-
-It will copy all the files, ask you configuration questions, and update the `.env` files with your answers.
-
-### Install Copier
-
-You can install Copier with:
-
-```bash
-pip install copier
-```
-
-Or better, if you have [`pipx`](https://pipx.pypa.io/), you can run it with:
-
-```bash
-pipx install copier
-```
-
-**Note**: If you have `pipx`, installing copier is optional, you could run it directly.
-
-### Generate a Project With Copier
-
-Decide a name for your new project's directory, you will use it below. For example, `my-awesome-project`.
-
-Go to the directory that will be the parent of your project, and run the command with your project's name:
-
-```bash
-copier copy https://github.com/fastapi/full-stack-fastapi-template my-awesome-project --trust
-```
-
-If you have `pipx` and you didn't install `copier`, you can run it directly:
-
-```bash
-pipx run copier copy https://github.com/fastapi/full-stack-fastapi-template my-awesome-project --trust
-```
-
-**Note** the `--trust` option is necessary to be able to execute a [post-creation script](https://github.com/fastapi/full-stack-fastapi-template/blob/master/.copier/update_dotenv.py) that updates your `.env` files.
-
-### Input Variables
-
-Copier will ask you for some data, you might want to have at hand before generating the project.
-
-But don't worry, you can just update any of that in the `.env` files afterwards.
-
-The input variables, with their default values (some auto generated) are:
-
-- `project_name`: (default: `"FastAPI Project"`) The name of the project, shown to API users (in .env).
-- `stack_name`: (default: `"fastapi-project"`) The name of the stack used for Docker Compose labels and project name (no spaces, no periods) (in .env).
-- `secret_key`: (default: `"changethis"`) The secret key for the project, used for security, stored in .env, you can generate one with the method above.
-- `first_superuser`: (default: `"admin@example.com"`) The email of the first superuser (in .env).
-- `first_superuser_password`: (default: `"changethis"`) The password of the first superuser (in .env).
-- `smtp_host`: (default: "") The SMTP server host to send emails, you can set it later in .env.
-- `smtp_user`: (default: "") The SMTP server user to send emails, you can set it later in .env.
-- `smtp_password`: (default: "") The SMTP server password to send emails, you can set it later in .env.
-- `emails_from_email`: (default: `"info@example.com"`) The email account to send emails from, you can set it later in .env.
-- `postgres_password`: (default: `"changethis"`) The password for the PostgreSQL database, stored in .env, you can generate one with the method above.
-- `sentry_dsn`: (default: "") The DSN for Sentry, if you are using it, you can set it later in .env.
-
-## Backend Development
-
-Backend docs: [backend/README.md](./backend/README.md).
-
-## Frontend Development
-
-Frontend docs: [frontend/README.md](./frontend/README.md).
-
-## Deployment
-
-Deployment docs: [deployment.md](./deployment.md).
-
-## Development
-
-General development docs: [development.md](./development.md).
-
-This includes using Docker Compose, custom local domains, `.env` configurations, etc.
-
-## Release Notes
-
-Check the file [release-notes.md](./release-notes.md).
-
-## License
-
-The Full Stack FastAPI Template is licensed under the terms of the MIT license.
+### Project Structure
+
+### **Backend (`backend/` - FastAPI)**
+#### `app/`
+- `api/` - API routes and dependencies
+ - `deps.py` - Dependency injection utilities
+ - `main.py` - API router
+ - `routes/` - API endpoints
+ - `items.py` - CRUD operations for items
+ - `login.py` - Authentication endpoints
+ - `private.py` - Private routes requiring authentication
+ - `users.py` - User-related operations
+ - `utils.py` - Helper functions
+- `core/` - Core configuration and security
+ - `config.py` - Application settings
+ - `db.py` - Database connection setup
+ - `security.py` - Password hashing and authentication
+- `crud.py` - CRUD operations for users and items
+- `models.py` - SQLModel database schemas
+- `utils.py` - Additional utility functions
+- `data/` - Contains SQLite database file (`app.db`)
+- `tests/` - Unit and integration tests
+
+#### Other Files
+- `pyproject.toml` - Backend dependencies
+- `README.md` - Project documentation
+- `start.sh` - Shell script for starting the backend and frontend
+
+---
+
+### **Frontend (`frontend/` - React + TypeScript + Vite)**
+
+#### `src/`
+- `components/` - UI components
+ - `Admin/` - Admin panel components
+ - `Common/` - Navbar, sidebar, modals, etc.
+ - `Items/` - Item management components
+ - `UserSettings/` - User profile settings
+- `hooks/` - Custom React hooks
+- `routes/` - Frontend routes
+ - `login.tsx` - Login page
+ - `signup.tsx` - User registration
+ - `settings.tsx` - User settings
+ - `admin.tsx` - Admin dashboard
+ - `items.tsx` - Item management page
+- `client/` - OpenAPI client for backend communication
+- `theme.tsx` - Chakra UI theme configuration
+- `utils.ts` - Helper functions
+
+#### Other Files
+- `index.html` - Entry point
+- `package.json` - Frontend dependencies
+- `vite.config.ts` - Vite configuration
+- `tests/` - End-to-end tests (Playwright)
+
+---
diff --git a/SECURITY.md b/SECURITY.md
deleted file mode 100644
index 0045fb8182..0000000000
--- a/SECURITY.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# Security Policy
-
-Security is very important for this project and its community. π
-
-Learn more about it below. π
-
-## Versions
-
-The latest version or release is supported.
-
-You are encouraged to write tests for your application and update your versions frequently after ensuring that your tests are passing. This way you will benefit from the latest features, bug fixes, and **security fixes**.
-
-## Reporting a Vulnerability
-
-If you think you found a vulnerability, and even if you are not sure about it, please report it right away by sending an email to: security@tiangolo.com. Please try to be as explicit as possible, describing all the steps and example code to reproduce the security issue.
-
-I (the author, [@tiangolo](https://twitter.com/tiangolo)) will review it thoroughly and get back to you.
-
-## Public Discussions
-
-Please restrain from publicly discussing a potential security vulnerability. π
-
-It's better to discuss privately and try to find a solution first, to limit the potential impact as much as possible.
-
----
-
-Thanks for your help!
-
-The community and I thank you for that. π
diff --git a/backend/.dockerignore b/backend/.dockerignore
deleted file mode 100644
index c0de4abf73..0000000000
--- a/backend/.dockerignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Python
-__pycache__
-app.egg-info
-*.pyc
-.mypy_cache
-.coverage
-htmlcov
-.venv
diff --git a/backend/.gitignore b/backend/.gitignore
index 63f67bcd21..d4c2ad010e 100644
--- a/backend/.gitignore
+++ b/backend/.gitignore
@@ -6,3 +6,5 @@ app.egg-info
htmlcov
.cache
.venv
+backend/data/*.db
+.env
\ No newline at end of file
diff --git a/backend/Dockerfile b/backend/Dockerfile
deleted file mode 100644
index 44c53f0365..0000000000
--- a/backend/Dockerfile
+++ /dev/null
@@ -1,43 +0,0 @@
-FROM python:3.10
-
-ENV PYTHONUNBUFFERED=1
-
-WORKDIR /app/
-
-# Install uv
-# Ref: https://docs.astral.sh/uv/guides/integration/docker/#installing-uv
-COPY --from=ghcr.io/astral-sh/uv:0.5.11 /uv /uvx /bin/
-
-# Place executables in the environment at the front of the path
-# Ref: https://docs.astral.sh/uv/guides/integration/docker/#using-the-environment
-ENV PATH="/app/.venv/bin:$PATH"
-
-# Compile bytecode
-# Ref: https://docs.astral.sh/uv/guides/integration/docker/#compiling-bytecode
-ENV UV_COMPILE_BYTECODE=1
-
-# uv Cache
-# Ref: https://docs.astral.sh/uv/guides/integration/docker/#caching
-ENV UV_LINK_MODE=copy
-
-# Install dependencies
-# Ref: https://docs.astral.sh/uv/guides/integration/docker/#intermediate-layers
-RUN --mount=type=cache,target=/root/.cache/uv \
- --mount=type=bind,source=uv.lock,target=uv.lock \
- --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
- uv sync --frozen --no-install-project
-
-ENV PYTHONPATH=/app
-
-COPY ./scripts /app/scripts
-
-COPY ./pyproject.toml ./uv.lock ./alembic.ini /app/
-
-COPY ./app /app/app
-
-# Sync the project
-# Ref: https://docs.astral.sh/uv/guides/integration/docker/#intermediate-layers
-RUN --mount=type=cache,target=/root/.cache/uv \
- uv sync
-
-CMD ["fastapi", "run", "--workers", "4", "app/main.py"]
diff --git a/backend/alembic.ini b/backend/alembic.ini
deleted file mode 100755
index 24841c2bfb..0000000000
--- a/backend/alembic.ini
+++ /dev/null
@@ -1,71 +0,0 @@
-# A generic, single database configuration.
-
-[alembic]
-# path to migration scripts
-script_location = app/alembic
-
-# template used to generate migration files
-# file_template = %%(rev)s_%%(slug)s
-
-# timezone to use when rendering the date
-# within the migration file as well as the filename.
-# string value is passed to dateutil.tz.gettz()
-# leave blank for localtime
-# timezone =
-
-# max length of characters to apply to the
-# "slug" field
-#truncate_slug_length = 40
-
-# set to 'true' to run the environment during
-# the 'revision' command, regardless of autogenerate
-# revision_environment = false
-
-# set to 'true' to allow .pyc and .pyo files without
-# a source .py file to be detected as revisions in the
-# versions/ directory
-# sourceless = false
-
-# version location specification; this defaults
-# to alembic/versions. When using multiple version
-# directories, initial revisions must be specified with --version-path
-# version_locations = %(here)s/bar %(here)s/bat alembic/versions
-
-# the output encoding used when revision files
-# are written from script.py.mako
-# output_encoding = utf-8
-
-# Logging configuration
-[loggers]
-keys = root,sqlalchemy,alembic
-
-[handlers]
-keys = console
-
-[formatters]
-keys = generic
-
-[logger_root]
-level = WARN
-handlers = console
-qualname =
-
-[logger_sqlalchemy]
-level = WARN
-handlers =
-qualname = sqlalchemy.engine
-
-[logger_alembic]
-level = INFO
-handlers =
-qualname = alembic
-
-[handler_console]
-class = StreamHandler
-args = (sys.stderr,)
-level = NOTSET
-formatter = generic
-
-[formatter_generic]
-format = %(levelname)-5.5s [%(name)s] %(message)s
-datefmt = %H:%M:%S
diff --git a/backend/app/alembic/README b/backend/app/alembic/README
deleted file mode 100755
index 2500aa1bcf..0000000000
--- a/backend/app/alembic/README
+++ /dev/null
@@ -1 +0,0 @@
-Generic single-database configuration.
diff --git a/backend/app/alembic/env.py b/backend/app/alembic/env.py
deleted file mode 100755
index 7f29c04680..0000000000
--- a/backend/app/alembic/env.py
+++ /dev/null
@@ -1,84 +0,0 @@
-import os
-from logging.config import fileConfig
-
-from alembic import context
-from sqlalchemy import engine_from_config, pool
-
-# this is the Alembic Config object, which provides
-# access to the values within the .ini file in use.
-config = context.config
-
-# Interpret the config file for Python logging.
-# This line sets up loggers basically.
-fileConfig(config.config_file_name)
-
-# add your model's MetaData object here
-# for 'autogenerate' support
-# from myapp import mymodel
-# target_metadata = mymodel.Base.metadata
-# target_metadata = None
-
-from app.models import SQLModel # noqa
-from app.core.config import settings # noqa
-
-target_metadata = SQLModel.metadata
-
-# other values from the config, defined by the needs of env.py,
-# can be acquired:
-# my_important_option = config.get_main_option("my_important_option")
-# ... etc.
-
-
-def get_url():
- return str(settings.SQLALCHEMY_DATABASE_URI)
-
-
-def run_migrations_offline():
- """Run migrations in 'offline' mode.
-
- This configures the context with just a URL
- and not an Engine, though an Engine is acceptable
- here as well. By skipping the Engine creation
- we don't even need a DBAPI to be available.
-
- Calls to context.execute() here emit the given string to the
- script output.
-
- """
- url = get_url()
- context.configure(
- url=url, target_metadata=target_metadata, literal_binds=True, compare_type=True
- )
-
- with context.begin_transaction():
- context.run_migrations()
-
-
-def run_migrations_online():
- """Run migrations in 'online' mode.
-
- In this scenario we need to create an Engine
- and associate a connection with the context.
-
- """
- configuration = config.get_section(config.config_ini_section)
- configuration["sqlalchemy.url"] = get_url()
- connectable = engine_from_config(
- configuration,
- prefix="sqlalchemy.",
- poolclass=pool.NullPool,
- )
-
- with connectable.connect() as connection:
- context.configure(
- connection=connection, target_metadata=target_metadata, compare_type=True
- )
-
- with context.begin_transaction():
- context.run_migrations()
-
-
-if context.is_offline_mode():
- run_migrations_offline()
-else:
- run_migrations_online()
diff --git a/backend/app/alembic/script.py.mako b/backend/app/alembic/script.py.mako
deleted file mode 100755
index 217a9a8b7b..0000000000
--- a/backend/app/alembic/script.py.mako
+++ /dev/null
@@ -1,25 +0,0 @@
-"""${message}
-
-Revision ID: ${up_revision}
-Revises: ${down_revision | comma,n}
-Create Date: ${create_date}
-
-"""
-from alembic import op
-import sqlalchemy as sa
-import sqlmodel.sql.sqltypes
-${imports if imports else ""}
-
-# revision identifiers, used by Alembic.
-revision = ${repr(up_revision)}
-down_revision = ${repr(down_revision)}
-branch_labels = ${repr(branch_labels)}
-depends_on = ${repr(depends_on)}
-
-
-def upgrade():
- ${upgrades if upgrades else "pass"}
-
-
-def downgrade():
- ${downgrades if downgrades else "pass"}
diff --git a/backend/app/alembic/versions/.keep b/backend/app/alembic/versions/.keep
deleted file mode 100755
index e69de29bb2..0000000000
diff --git a/backend/app/alembic/versions/1a31ce608336_add_cascade_delete_relationships.py b/backend/app/alembic/versions/1a31ce608336_add_cascade_delete_relationships.py
deleted file mode 100644
index 10e47a1456..0000000000
--- a/backend/app/alembic/versions/1a31ce608336_add_cascade_delete_relationships.py
+++ /dev/null
@@ -1,37 +0,0 @@
-"""Add cascade delete relationships
-
-Revision ID: 1a31ce608336
-Revises: d98dd8ec85a3
-Create Date: 2024-07-31 22:24:34.447891
-
-"""
-from alembic import op
-import sqlalchemy as sa
-import sqlmodel.sql.sqltypes
-
-
-# revision identifiers, used by Alembic.
-revision = '1a31ce608336'
-down_revision = 'd98dd8ec85a3'
-branch_labels = None
-depends_on = None
-
-
-def upgrade():
- # ### commands auto generated by Alembic - please adjust! ###
- op.alter_column('item', 'owner_id',
- existing_type=sa.UUID(),
- nullable=False)
- op.drop_constraint('item_owner_id_fkey', 'item', type_='foreignkey')
- op.create_foreign_key(None, 'item', 'user', ['owner_id'], ['id'], ondelete='CASCADE')
- # ### end Alembic commands ###
-
-
-def downgrade():
- # ### commands auto generated by Alembic - please adjust! ###
- op.drop_constraint(None, 'item', type_='foreignkey')
- op.create_foreign_key('item_owner_id_fkey', 'item', 'user', ['owner_id'], ['id'])
- op.alter_column('item', 'owner_id',
- existing_type=sa.UUID(),
- nullable=True)
- # ### end Alembic commands ###
diff --git a/backend/app/alembic/versions/9c0a54914c78_add_max_length_for_string_varchar_.py b/backend/app/alembic/versions/9c0a54914c78_add_max_length_for_string_varchar_.py
deleted file mode 100755
index 78a41773b9..0000000000
--- a/backend/app/alembic/versions/9c0a54914c78_add_max_length_for_string_varchar_.py
+++ /dev/null
@@ -1,69 +0,0 @@
-"""Add max length for string(varchar) fields in User and Items models
-
-Revision ID: 9c0a54914c78
-Revises: e2412789c190
-Create Date: 2024-06-17 14:42:44.639457
-
-"""
-from alembic import op
-import sqlalchemy as sa
-import sqlmodel.sql.sqltypes
-
-
-# revision identifiers, used by Alembic.
-revision = '9c0a54914c78'
-down_revision = 'e2412789c190'
-branch_labels = None
-depends_on = None
-
-
-def upgrade():
- # Adjust the length of the email field in the User table
- op.alter_column('user', 'email',
- existing_type=sa.String(),
- type_=sa.String(length=255),
- existing_nullable=False)
-
- # Adjust the length of the full_name field in the User table
- op.alter_column('user', 'full_name',
- existing_type=sa.String(),
- type_=sa.String(length=255),
- existing_nullable=True)
-
- # Adjust the length of the title field in the Item table
- op.alter_column('item', 'title',
- existing_type=sa.String(),
- type_=sa.String(length=255),
- existing_nullable=False)
-
- # Adjust the length of the description field in the Item table
- op.alter_column('item', 'description',
- existing_type=sa.String(),
- type_=sa.String(length=255),
- existing_nullable=True)
-
-
-def downgrade():
- # Revert the length of the email field in the User table
- op.alter_column('user', 'email',
- existing_type=sa.String(length=255),
- type_=sa.String(),
- existing_nullable=False)
-
- # Revert the length of the full_name field in the User table
- op.alter_column('user', 'full_name',
- existing_type=sa.String(length=255),
- type_=sa.String(),
- existing_nullable=True)
-
- # Revert the length of the title field in the Item table
- op.alter_column('item', 'title',
- existing_type=sa.String(length=255),
- type_=sa.String(),
- existing_nullable=False)
-
- # Revert the length of the description field in the Item table
- op.alter_column('item', 'description',
- existing_type=sa.String(length=255),
- type_=sa.String(),
- existing_nullable=True)
diff --git a/backend/app/alembic/versions/d98dd8ec85a3_edit_replace_id_integers_in_all_models_.py b/backend/app/alembic/versions/d98dd8ec85a3_edit_replace_id_integers_in_all_models_.py
deleted file mode 100755
index 37af1fa215..0000000000
--- a/backend/app/alembic/versions/d98dd8ec85a3_edit_replace_id_integers_in_all_models_.py
+++ /dev/null
@@ -1,90 +0,0 @@
-"""Edit replace id integers in all models to use UUID instead
-
-Revision ID: d98dd8ec85a3
-Revises: 9c0a54914c78
-Create Date: 2024-07-19 04:08:04.000976
-
-"""
-from alembic import op
-import sqlalchemy as sa
-import sqlmodel.sql.sqltypes
-from sqlalchemy.dialects import postgresql
-
-
-# revision identifiers, used by Alembic.
-revision = 'd98dd8ec85a3'
-down_revision = '9c0a54914c78'
-branch_labels = None
-depends_on = None
-
-
-def upgrade():
- # Ensure uuid-ossp extension is available
- op.execute('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"')
-
- # Create a new UUID column with a default UUID value
- op.add_column('user', sa.Column('new_id', postgresql.UUID(as_uuid=True), default=sa.text('uuid_generate_v4()')))
- op.add_column('item', sa.Column('new_id', postgresql.UUID(as_uuid=True), default=sa.text('uuid_generate_v4()')))
- op.add_column('item', sa.Column('new_owner_id', postgresql.UUID(as_uuid=True), nullable=True))
-
- # Populate the new columns with UUIDs
- op.execute('UPDATE "user" SET new_id = uuid_generate_v4()')
- op.execute('UPDATE item SET new_id = uuid_generate_v4()')
- op.execute('UPDATE item SET new_owner_id = (SELECT new_id FROM "user" WHERE "user".id = item.owner_id)')
-
- # Set the new_id as not nullable
- op.alter_column('user', 'new_id', nullable=False)
- op.alter_column('item', 'new_id', nullable=False)
-
- # Drop old columns and rename new columns
- op.drop_constraint('item_owner_id_fkey', 'item', type_='foreignkey')
- op.drop_column('item', 'owner_id')
- op.alter_column('item', 'new_owner_id', new_column_name='owner_id')
-
- op.drop_column('user', 'id')
- op.alter_column('user', 'new_id', new_column_name='id')
-
- op.drop_column('item', 'id')
- op.alter_column('item', 'new_id', new_column_name='id')
-
- # Create primary key constraint
- op.create_primary_key('user_pkey', 'user', ['id'])
- op.create_primary_key('item_pkey', 'item', ['id'])
-
- # Recreate foreign key constraint
- op.create_foreign_key('item_owner_id_fkey', 'item', 'user', ['owner_id'], ['id'])
-
-def downgrade():
- # Reverse the upgrade process
- op.add_column('user', sa.Column('old_id', sa.Integer, autoincrement=True))
- op.add_column('item', sa.Column('old_id', sa.Integer, autoincrement=True))
- op.add_column('item', sa.Column('old_owner_id', sa.Integer, nullable=True))
-
- # Populate the old columns with default values
- # Generate sequences for the integer IDs if not exist
- op.execute('CREATE SEQUENCE IF NOT EXISTS user_id_seq AS INTEGER OWNED BY "user".old_id')
- op.execute('CREATE SEQUENCE IF NOT EXISTS item_id_seq AS INTEGER OWNED BY item.old_id')
-
- op.execute('SELECT setval(\'user_id_seq\', COALESCE((SELECT MAX(old_id) + 1 FROM "user"), 1), false)')
- op.execute('SELECT setval(\'item_id_seq\', COALESCE((SELECT MAX(old_id) + 1 FROM item), 1), false)')
-
- op.execute('UPDATE "user" SET old_id = nextval(\'user_id_seq\')')
- op.execute('UPDATE item SET old_id = nextval(\'item_id_seq\'), old_owner_id = (SELECT old_id FROM "user" WHERE "user".id = item.owner_id)')
-
- # Drop new columns and rename old columns back
- op.drop_constraint('item_owner_id_fkey', 'item', type_='foreignkey')
- op.drop_column('item', 'owner_id')
- op.alter_column('item', 'old_owner_id', new_column_name='owner_id')
-
- op.drop_column('user', 'id')
- op.alter_column('user', 'old_id', new_column_name='id')
-
- op.drop_column('item', 'id')
- op.alter_column('item', 'old_id', new_column_name='id')
-
- # Create primary key constraint
- op.create_primary_key('user_pkey', 'user', ['id'])
- op.create_primary_key('item_pkey', 'item', ['id'])
-
- # Recreate foreign key constraint
- op.create_foreign_key('item_owner_id_fkey', 'item', 'user', ['owner_id'], ['id'])
diff --git a/backend/app/alembic/versions/e2412789c190_initialize_models.py b/backend/app/alembic/versions/e2412789c190_initialize_models.py
deleted file mode 100644
index 7529ea91fa..0000000000
--- a/backend/app/alembic/versions/e2412789c190_initialize_models.py
+++ /dev/null
@@ -1,54 +0,0 @@
-"""Initialize models
-
-Revision ID: e2412789c190
-Revises:
-Create Date: 2023-11-24 22:55:43.195942
-
-"""
-import sqlalchemy as sa
-import sqlmodel.sql.sqltypes
-from alembic import op
-
-# revision identifiers, used by Alembic.
-revision = "e2412789c190"
-down_revision = None
-branch_labels = None
-depends_on = None
-
-
-def upgrade():
- # ### commands auto generated by Alembic - please adjust! ###
- op.create_table(
- "user",
- sa.Column("email", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
- sa.Column("is_active", sa.Boolean(), nullable=False),
- sa.Column("is_superuser", sa.Boolean(), nullable=False),
- sa.Column("full_name", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
- sa.Column("id", sa.Integer(), nullable=False),
- sa.Column(
- "hashed_password", sqlmodel.sql.sqltypes.AutoString(), nullable=False
- ),
- sa.PrimaryKeyConstraint("id"),
- )
- op.create_index(op.f("ix_user_email"), "user", ["email"], unique=True)
- op.create_table(
- "item",
- sa.Column("description", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
- sa.Column("id", sa.Integer(), nullable=False),
- sa.Column("title", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
- sa.Column("owner_id", sa.Integer(), nullable=False),
- sa.ForeignKeyConstraint(
- ["owner_id"],
- ["user.id"],
- ),
- sa.PrimaryKeyConstraint("id"),
- )
- # ### end Alembic commands ###
-
-
-def downgrade():
- # ### commands auto generated by Alembic - please adjust! ###
- op.drop_table("item")
- op.drop_index(op.f("ix_user_email"), table_name="user")
- op.drop_table("user")
- # ### end Alembic commands ###
diff --git a/backend/app/api/deps.py b/backend/app/api/deps.py
index c2b83c841d..9f893f7637 100644
--- a/backend/app/api/deps.py
+++ b/backend/app/api/deps.py
@@ -2,6 +2,7 @@
from typing import Annotated
import jwt
+import uuid
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from jwt.exceptions import InvalidTokenError
@@ -29,16 +30,15 @@ def get_db() -> Generator[Session, None, None]:
def get_current_user(session: SessionDep, token: TokenDep) -> User:
try:
- payload = jwt.decode(
- token, settings.SECRET_KEY, algorithms=[security.ALGORITHM]
- )
+ payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[security.ALGORITHM])
+ print(f"{payload=}")
token_data = TokenPayload(**payload)
except (InvalidTokenError, ValidationError):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Could not validate credentials",
)
- user = session.get(User, token_data.sub)
+ user = session.get(User, uuid.UUID(token_data.sub))
if not user:
raise HTTPException(status_code=404, detail="User not found")
if not user.is_active:
diff --git a/backend/app/backend_pre_start.py b/backend/app/backend_pre_start.py
deleted file mode 100644
index c2f8e29ae1..0000000000
--- a/backend/app/backend_pre_start.py
+++ /dev/null
@@ -1,39 +0,0 @@
-import logging
-
-from sqlalchemy import Engine
-from sqlmodel import Session, select
-from tenacity import after_log, before_log, retry, stop_after_attempt, wait_fixed
-
-from app.core.db import engine
-
-logging.basicConfig(level=logging.INFO)
-logger = logging.getLogger(__name__)
-
-max_tries = 60 * 5 # 5 minutes
-wait_seconds = 1
-
-
-@retry(
- stop=stop_after_attempt(max_tries),
- wait=wait_fixed(wait_seconds),
- before=before_log(logger, logging.INFO),
- after=after_log(logger, logging.WARN),
-)
-def init(db_engine: Engine) -> None:
- try:
- with Session(db_engine) as session:
- # Try to create session to check if DB is awake
- session.exec(select(1))
- except Exception as e:
- logger.error(e)
- raise e
-
-
-def main() -> None:
- logger.info("Initializing service")
- init(engine)
- logger.info("Service finished initializing")
-
-
-if __name__ == "__main__":
- main()
diff --git a/backend/app/core/config.py b/backend/app/core/config.py
index 2370469d7a..edb1c2ee1e 100644
--- a/backend/app/core/config.py
+++ b/backend/app/core/config.py
@@ -1,20 +1,22 @@
import secrets
-import warnings
from typing import Annotated, Any, Literal
+from pathlib import Path
from pydantic import (
AnyUrl,
BeforeValidator,
- HttpUrl,
- PostgresDsn,
computed_field,
model_validator,
)
-from pydantic_core import MultiHostUrl
from pydantic_settings import BaseSettings, SettingsConfigDict
from typing_extensions import Self
+BASE_DIR = Path(__file__).resolve().parents[3]
+ENV_FILE = BASE_DIR / "backend" / ".env"
+# print(f"{BASE_DIR=}")
+# print(f"{ENV_FILE=}")
+
def parse_cors(v: Any) -> list[str] | str:
if isinstance(v, str) and not v.startswith("["):
return [i.strip() for i in v.split(",")]
@@ -25,11 +27,11 @@ def parse_cors(v: Any) -> list[str] | str:
class Settings(BaseSettings):
model_config = SettingsConfigDict(
- # Use top level .env file (one level above ./backend/)
- env_file="../.env",
+ env_file=str(ENV_FILE),
env_ignore_empty=True,
extra="ignore",
)
+
API_V1_STR: str = "/api/v1"
SECRET_KEY: str = secrets.token_urlsafe(32)
# 60 minutes * 24 hours * 8 days = 8 days
@@ -37,37 +39,17 @@ class Settings(BaseSettings):
FRONTEND_HOST: str = "http://localhost:5173"
ENVIRONMENT: Literal["local", "staging", "production"] = "local"
- BACKEND_CORS_ORIGINS: Annotated[
- list[AnyUrl] | str, BeforeValidator(parse_cors)
- ] = []
+ BACKEND_CORS_ORIGINS: Annotated[list[AnyUrl] | str, BeforeValidator(parse_cors)] = []
@computed_field # type: ignore[prop-decorator]
@property
def all_cors_origins(self) -> list[str]:
- return [str(origin).rstrip("/") for origin in self.BACKEND_CORS_ORIGINS] + [
- self.FRONTEND_HOST
- ]
+ return [str(origin).rstrip("/") for origin in self.BACKEND_CORS_ORIGINS] + [self.FRONTEND_HOST]
PROJECT_NAME: str
- SENTRY_DSN: HttpUrl | None = None
- POSTGRES_SERVER: str
- POSTGRES_PORT: int = 5432
- POSTGRES_USER: str
- POSTGRES_PASSWORD: str = ""
- POSTGRES_DB: str = ""
-
- @computed_field # type: ignore[prop-decorator]
- @property
- def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn:
- return MultiHostUrl.build(
- scheme="postgresql+psycopg",
- username=self.POSTGRES_USER,
- password=self.POSTGRES_PASSWORD,
- host=self.POSTGRES_SERVER,
- port=self.POSTGRES_PORT,
- path=self.POSTGRES_DB,
- )
-
+
+ SQLALCHEMY_DATABASE_URI: str = f"sqlite:///{BASE_DIR / 'backend' / 'data' / 'app.db'}"
+
SMTP_TLS: bool = True
SMTP_SSL: bool = False
SMTP_PORT: int = 587
@@ -97,26 +79,9 @@ def emails_enabled(self) -> bool:
FIRST_SUPERUSER: str
FIRST_SUPERUSER_PASSWORD: str
- def _check_default_secret(self, var_name: str, value: str | None) -> None:
- if value == "changethis":
- message = (
- f'The value of {var_name} is "changethis", '
- "for security, please change it, at least for deployments."
- )
- if self.ENVIRONMENT == "local":
- warnings.warn(message, stacklevel=1)
- else:
- raise ValueError(message)
-
- @model_validator(mode="after")
- def _enforce_non_default_secrets(self) -> Self:
- self._check_default_secret("SECRET_KEY", self.SECRET_KEY)
- self._check_default_secret("POSTGRES_PASSWORD", self.POSTGRES_PASSWORD)
- self._check_default_secret(
- "FIRST_SUPERUSER_PASSWORD", self.FIRST_SUPERUSER_PASSWORD
- )
-
- return self
-
-
settings = Settings() # type: ignore
+
+# print(settings.FIRST_SUPERUSER)
+# print(settings.FIRST_SUPERUSER_PASSWORD)
+# print(settings.SQLALCHEMY_DATABASE_URI)
+# print(settings.SECRET_KEY)
\ No newline at end of file
diff --git a/backend/app/core/db.py b/backend/app/core/db.py
index ba991fb36d..aa0a05ca8e 100644
--- a/backend/app/core/db.py
+++ b/backend/app/core/db.py
@@ -1,33 +1,25 @@
from sqlmodel import Session, create_engine, select
-from app import crud
+from sqlmodel import Session, create_engine, SQLModel, select
from app.core.config import settings
from app.models import User, UserCreate
-
-engine = create_engine(str(settings.SQLALCHEMY_DATABASE_URI))
+from app import crud
-# make sure all SQLModel models are imported (app.models) before initializing DB
-# otherwise, SQLModel might fail to initialize relationships properly
-# for more details: https://github.com/fastapi/full-stack-fastapi-template/issues/28
+engine = create_engine(str(settings.SQLALCHEMY_DATABASE_URI), connect_args={"check_same_thread": False}, echo=True)
-def init_db(session: Session) -> None:
- # Tables should be created with Alembic migrations
- # But if you don't want to use migrations, create
- # the tables un-commenting the next lines
- # from sqlmodel import SQLModel
+def init_db() -> None:
+ SQLModel.metadata.create_all(engine)
- # This works because the models are already imported and registered from app.models
- # SQLModel.metadata.create_all(engine)
+ with Session(engine) as session:
+ user: User | None = session.exec(select(User).where(User.email == settings.FIRST_SUPERUSER)).first()
+ if not user:
+ user_in = UserCreate(
+ email=settings.FIRST_SUPERUSER,
+ password=settings.FIRST_SUPERUSER_PASSWORD,
+ is_superuser=True,
+ )
+ user = crud.create_user(session=session, user_create=user_in)
- user = session.exec(
- select(User).where(User.email == settings.FIRST_SUPERUSER)
- ).first()
- if not user:
- user_in = UserCreate(
- email=settings.FIRST_SUPERUSER,
- password=settings.FIRST_SUPERUSER_PASSWORD,
- is_superuser=True,
- )
- user = crud.create_user(session=session, user_create=user_in)
+ print("Database initialized successfully!")
diff --git a/backend/app/crud.py b/backend/app/crud.py
index 905bf48724..929fde6010 100644
--- a/backend/app/crud.py
+++ b/backend/app/crud.py
@@ -8,9 +8,7 @@
def create_user(*, session: Session, user_create: UserCreate) -> User:
- db_obj = User.model_validate(
- user_create, update={"hashed_password": get_password_hash(user_create.password)}
- )
+ db_obj = User.model_validate(user_create, update={"hashed_password": get_password_hash(user_create.password)})
session.add(db_obj)
session.commit()
session.refresh(db_obj)
diff --git a/backend/app/initial_data.py b/backend/app/initial_data.py
deleted file mode 100644
index d806c3d381..0000000000
--- a/backend/app/initial_data.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import logging
-
-from sqlmodel import Session
-
-from app.core.db import engine, init_db
-
-logging.basicConfig(level=logging.INFO)
-logger = logging.getLogger(__name__)
-
-
-def init() -> None:
- with Session(engine) as session:
- init_db(session)
-
-
-def main() -> None:
- logger.info("Creating initial data")
- init()
- logger.info("Initial data created")
-
-
-if __name__ == "__main__":
- main()
diff --git a/backend/app/main.py b/backend/app/main.py
index 9a95801e74..84e74ed636 100644
--- a/backend/app/main.py
+++ b/backend/app/main.py
@@ -1,8 +1,6 @@
-import sentry_sdk
from fastapi import FastAPI
from fastapi.routing import APIRoute
from starlette.middleware.cors import CORSMiddleware
-
from app.api.main import api_router
from app.core.config import settings
@@ -10,17 +8,12 @@
def custom_generate_unique_id(route: APIRoute) -> str:
return f"{route.tags[0]}-{route.name}"
-
-if settings.SENTRY_DSN and settings.ENVIRONMENT != "local":
- sentry_sdk.init(dsn=str(settings.SENTRY_DSN), enable_tracing=True)
-
app = FastAPI(
title=settings.PROJECT_NAME,
openapi_url=f"{settings.API_V1_STR}/openapi.json",
generate_unique_id_function=custom_generate_unique_id,
)
-# Set all CORS enabled origins
if settings.all_cors_origins:
app.add_middleware(
CORSMiddleware,
diff --git a/backend/app/tests_pre_start.py b/backend/app/tests_pre_start.py
deleted file mode 100644
index 0ce6045635..0000000000
--- a/backend/app/tests_pre_start.py
+++ /dev/null
@@ -1,39 +0,0 @@
-import logging
-
-from sqlalchemy import Engine
-from sqlmodel import Session, select
-from tenacity import after_log, before_log, retry, stop_after_attempt, wait_fixed
-
-from app.core.db import engine
-
-logging.basicConfig(level=logging.INFO)
-logger = logging.getLogger(__name__)
-
-max_tries = 60 * 5 # 5 minutes
-wait_seconds = 1
-
-
-@retry(
- stop=stop_after_attempt(max_tries),
- wait=wait_fixed(wait_seconds),
- before=before_log(logger, logging.INFO),
- after=after_log(logger, logging.WARN),
-)
-def init(db_engine: Engine) -> None:
- try:
- # Try to create session to check if DB is awake
- with Session(db_engine) as session:
- session.exec(select(1))
- except Exception as e:
- logger.error(e)
- raise e
-
-
-def main() -> None:
- logger.info("Initializing service")
- init(engine)
- logger.info("Service finished initializing")
-
-
-if __name__ == "__main__":
- main()
diff --git a/backend/data/app.db b/backend/data/app.db
new file mode 100644
index 0000000000..394a1fd685
Binary files /dev/null and b/backend/data/app.db differ
diff --git a/backend/pyproject.toml b/backend/pyproject.toml
index 1c77b83ded..6a99582093 100644
--- a/backend/pyproject.toml
+++ b/backend/pyproject.toml
@@ -8,7 +8,6 @@ dependencies = [
"python-multipart<1.0.0,>=0.0.7",
"email-validator<3.0.0.0,>=2.1.0.post1",
"passlib[bcrypt]<2.0.0,>=1.7.4",
- "tenacity<9.0.0,>=8.2.3",
"pydantic>2.0",
"emails<1.0,>=0.6",
"jinja2<4.0.0,>=3.1.4",
@@ -19,7 +18,6 @@ dependencies = [
# Pin bcrypt until passlib supports the latest
"bcrypt==4.0.1",
"pydantic-settings<3.0.0,>=2.2.1",
- "sentry-sdk[fastapi]<2.0.0,>=1.40.6",
"pyjwt<3.0.0,>=2.8.0",
]
diff --git a/backend/scripts/format.sh b/backend/scripts/format.sh
deleted file mode 100755
index 7be2f81205..0000000000
--- a/backend/scripts/format.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh -e
-set -x
-
-ruff check app scripts --fix
-ruff format app scripts
diff --git a/backend/scripts/lint.sh b/backend/scripts/lint.sh
deleted file mode 100644
index b3b2b4ecc7..0000000000
--- a/backend/scripts/lint.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-set -x
-
-mypy app
-ruff check app
-ruff format app --check
diff --git a/backend/scripts/prestart.sh b/backend/scripts/prestart.sh
deleted file mode 100644
index 1b395d513f..0000000000
--- a/backend/scripts/prestart.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#! /usr/bin/env bash
-
-set -e
-set -x
-
-# Let the DB start
-python app/backend_pre_start.py
-
-# Run migrations
-alembic upgrade head
-
-# Create initial data in DB
-python app/initial_data.py
diff --git a/backend/scripts/test.sh b/backend/scripts/test.sh
deleted file mode 100755
index df23f702e3..0000000000
--- a/backend/scripts/test.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env bash
-
-set -e
-set -x
-
-coverage run --source=app -m pytest
-coverage report --show-missing
-coverage html --title "${@-coverage}"
diff --git a/backend/scripts/tests-start.sh b/backend/scripts/tests-start.sh
deleted file mode 100644
index 89dcb0da23..0000000000
--- a/backend/scripts/tests-start.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#! /usr/bin/env bash
-set -e
-set -x
-
-python app/tests_pre_start.py
-
-bash scripts/test.sh "$@"
diff --git a/copier.yml b/copier.yml
deleted file mode 100644
index f98e3fc861..0000000000
--- a/copier.yml
+++ /dev/null
@@ -1,100 +0,0 @@
-project_name:
- type: str
- help: The name of the project, shown to API users (in .env)
- default: FastAPI Project
-
-stack_name:
- type: str
- help: The name of the stack used for Docker Compose labels (no spaces) (in .env)
- default: fastapi-project
-
-secret_key:
- type: str
- help: |
- 'The secret key for the project, used for security,
- stored in .env, you can generate one with:
- python -c "import secrets; print(secrets.token_urlsafe(32))"'
- default: changethis
-
-first_superuser:
- type: str
- help: The email of the first superuser (in .env)
- default: admin@example.com
-
-first_superuser_password:
- type: str
- help: The password of the first superuser (in .env)
- default: changethis
-
-smtp_host:
- type: str
- help: The SMTP server host to send emails, you can set it later in .env
- default: ""
-
-smtp_user:
- type: str
- help: The SMTP server user to send emails, you can set it later in .env
- default: ""
-
-smtp_password:
- type: str
- help: The SMTP server password to send emails, you can set it later in .env
- default: ""
-
-emails_from_email:
- type: str
- help: The email account to send emails from, you can set it later in .env
- default: info@example.com
-
-postgres_password:
- type: str
- help: |
- 'The password for the PostgreSQL database, stored in .env,
- you can generate one with:
- python -c "import secrets; print(secrets.token_urlsafe(32))"'
- default: changethis
-
-sentry_dsn:
- type: str
- help: The DSN for Sentry, if you are using it, you can set it later in .env
- default: ""
-
-_exclude:
- # Global
- - .vscode
- - .mypy_cache
- # Python
- - __pycache__
- - app.egg-info
- - "*.pyc"
- - .mypy_cache
- - .coverage
- - htmlcov
- - .cache
- - .venv
- # Frontend
- # Logs
- - logs
- - "*.log"
- - npm-debug.log*
- - yarn-debug.log*
- - yarn-error.log*
- - pnpm-debug.log*
- - lerna-debug.log*
- - node_modules
- - dist
- - dist-ssr
- - "*.local"
- # Editor directories and files
- - .idea
- - .DS_Store
- - "*.suo"
- - "*.ntvs*"
- - "*.njsproj"
- - "*.sln"
- - "*.sw?"
-
-_answers_file: .copier/.copier-answers.yml
-
-_tasks:
- - ["{{ _copier_python }}", .copier/update_dotenv.py]
diff --git a/deployment.md b/deployment.md
deleted file mode 100644
index eadf76ddae..0000000000
--- a/deployment.md
+++ /dev/null
@@ -1,309 +0,0 @@
-# FastAPI Project - Deployment
-
-You can deploy the project using Docker Compose to a remote server.
-
-This project expects you to have a Traefik proxy handling communication to the outside world and HTTPS certificates.
-
-You can use CI/CD (continuous integration and continuous deployment) systems to deploy automatically, there are already configurations to do it with GitHub Actions.
-
-But you have to configure a couple things first. π€
-
-## Preparation
-
-* Have a remote server ready and available.
-* Configure the DNS records of your domain to point to the IP of the server you just created.
-* Configure a wildcard subdomain for your domain, so that you can have multiple subdomains for different services, e.g. `*.fastapi-project.example.com`. This will be useful for accessing different components, like `dashboard.fastapi-project.example.com`, `api.fastapi-project.example.com`, `traefik.fastapi-project.example.com`, `adminer.fastapi-project.example.com`, etc. And also for `staging`, like `dashboard.staging.fastapi-project.example.com`, `adminer.staging..fastapi-project.example.com`, etc.
-* Install and configure [Docker](https://docs.docker.com/engine/install/) on the remote server (Docker Engine, not Docker Desktop).
-
-## Public Traefik
-
-We need a Traefik proxy to handle incoming connections and HTTPS certificates.
-
-You need to do these next steps only once.
-
-### Traefik Docker Compose
-
-* Create a remote directory to store your Traefik Docker Compose file:
-
-```bash
-mkdir -p /root/code/traefik-public/
-```
-
-Copy the Traefik Docker Compose file to your server. You could do it by running the command `rsync` in your local terminal:
-
-```bash
-rsync -a docker-compose.traefik.yml root@your-server.example.com:/root/code/traefik-public/
-```
-
-### Traefik Public Network
-
-This Traefik will expect a Docker "public network" named `traefik-public` to communicate with your stack(s).
-
-This way, there will be a single public Traefik proxy that handles the communication (HTTP and HTTPS) with the outside world, and then behind that, you could have one or more stacks with different domains, even if they are on the same single server.
-
-To create a Docker "public network" named `traefik-public` run the following command in your remote server:
-
-```bash
-docker network create traefik-public
-```
-
-### Traefik Environment Variables
-
-The Traefik Docker Compose file expects some environment variables to be set in your terminal before starting it. You can do it by running the following commands in your remote server.
-
-* Create the username for HTTP Basic Auth, e.g.:
-
-```bash
-export USERNAME=admin
-```
-
-* Create an environment variable with the password for HTTP Basic Auth, e.g.:
-
-```bash
-export PASSWORD=changethis
-```
-
-* Use openssl to generate the "hashed" version of the password for HTTP Basic Auth and store it in an environment variable:
-
-```bash
-export HASHED_PASSWORD=$(openssl passwd -apr1 $PASSWORD)
-```
-
-To verify that the hashed password is correct, you can print it:
-
-```bash
-echo $HASHED_PASSWORD
-```
-
-* Create an environment variable with the domain name for your server, e.g.:
-
-```bash
-export DOMAIN=fastapi-project.example.com
-```
-
-* Create an environment variable with the email for Let's Encrypt, e.g.:
-
-```bash
-export EMAIL=admin@example.com
-```
-
-**Note**: you need to set a different email, an email `@example.com` won't work.
-
-### Start the Traefik Docker Compose
-
-Go to the directory where you copied the Traefik Docker Compose file in your remote server:
-
-```bash
-cd /root/code/traefik-public/
-```
-
-Now with the environment variables set and the `docker-compose.traefik.yml` in place, you can start the Traefik Docker Compose running the following command:
-
-```bash
-docker compose -f docker-compose.traefik.yml up -d
-```
-
-## Deploy the FastAPI Project
-
-Now that you have Traefik in place you can deploy your FastAPI project with Docker Compose.
-
-**Note**: You might want to jump ahead to the section about Continuous Deployment with GitHub Actions.
-
-## Environment Variables
-
-You need to set some environment variables first.
-
-Set the `ENVIRONMENT`, by default `local` (for development), but when deploying to a server you would put something like `staging` or `production`:
-
-```bash
-export ENVIRONMENT=production
-```
-
-Set the `DOMAIN`, by default `localhost` (for development), but when deploying you would use your own domain, for example:
-
-```bash
-export DOMAIN=fastapi-project.example.com
-```
-
-You can set several variables, like:
-
-* `PROJECT_NAME`: The name of the project, used in the API for the docs and emails.
-* `STACK_NAME`: The name of the stack used for Docker Compose labels and project name, this should be different for `staging`, `production`, etc. You could use the same domain replacing dots with dashes, e.g. `fastapi-project-example-com` and `staging-fastapi-project-example-com`.
-* `BACKEND_CORS_ORIGINS`: A list of allowed CORS origins separated by commas.
-* `SECRET_KEY`: The secret key for the FastAPI project, used to sign tokens.
-* `FIRST_SUPERUSER`: The email of the first superuser, this superuser will be the one that can create new users.
-* `FIRST_SUPERUSER_PASSWORD`: The password of the first superuser.
-* `SMTP_HOST`: The SMTP server host to send emails, this would come from your email provider (E.g. Mailgun, Sparkpost, Sendgrid, etc).
-* `SMTP_USER`: The SMTP server user to send emails.
-* `SMTP_PASSWORD`: The SMTP server password to send emails.
-* `EMAILS_FROM_EMAIL`: The email account to send emails from.
-* `POSTGRES_SERVER`: The hostname of the PostgreSQL server. You can leave the default of `db`, provided by the same Docker Compose. You normally wouldn't need to change this unless you are using a third-party provider.
-* `POSTGRES_PORT`: The port of the PostgreSQL server. You can leave the default. You normally wouldn't need to change this unless you are using a third-party provider.
-* `POSTGRES_PASSWORD`: The Postgres password.
-* `POSTGRES_USER`: The Postgres user, you can leave the default.
-* `POSTGRES_DB`: The database name to use for this application. You can leave the default of `app`.
-* `SENTRY_DSN`: The DSN for Sentry, if you are using it.
-
-## GitHub Actions Environment Variables
-
-There are some environment variables only used by GitHub Actions that you can configure:
-
-* `LATEST_CHANGES`: Used by the GitHub Action [latest-changes](https://github.com/tiangolo/latest-changes) to automatically add release notes based on the PRs merged. It's a personal access token, read the docs for details.
-* `SMOKESHOW_AUTH_KEY`: Used to handle and publish the code coverage using [Smokeshow](https://github.com/samuelcolvin/smokeshow), follow their instructions to create a (free) Smokeshow key.
-
-### Generate secret keys
-
-Some environment variables in the `.env` file have a default value of `changethis`.
-
-You have to change them with a secret key, to generate secret keys you can run the following command:
-
-```bash
-python -c "import secrets; print(secrets.token_urlsafe(32))"
-```
-
-Copy the content and use that as password / secret key. And run that again to generate another secure key.
-
-### Deploy with Docker Compose
-
-With the environment variables in place, you can deploy with Docker Compose:
-
-```bash
-docker compose -f docker-compose.yml up -d
-```
-
-For production you wouldn't want to have the overrides in `docker-compose.override.yml`, that's why we explicitly specify `docker-compose.yml` as the file to use.
-
-## Continuous Deployment (CD)
-
-You can use GitHub Actions to deploy your project automatically. π
-
-You can have multiple environment deployments.
-
-There are already two environments configured, `staging` and `production`. π
-
-### Install GitHub Actions Runner
-
-* On your remote server, create a user for your GitHub Actions:
-
-```bash
-sudo adduser github
-```
-
-* Add Docker permissions to the `github` user:
-
-```bash
-sudo usermod -aG docker github
-```
-
-* Temporarily switch to the `github` user:
-
-```bash
-sudo su - github
-```
-
-* Go to the `github` user's home directory:
-
-```bash
-cd
-```
-
-* [Install a GitHub Action self-hosted runner following the official guide](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners#adding-a-self-hosted-runner-to-a-repository).
-
-* When asked about labels, add a label for the environment, e.g. `production`. You can also add labels later.
-
-After installing, the guide would tell you to run a command to start the runner. Nevertheless, it would stop once you terminate that process or if your local connection to your server is lost.
-
-To make sure it runs on startup and continues running, you can install it as a service. To do that, exit the `github` user and go back to the `root` user:
-
-```bash
-exit
-```
-
-After you do it, you will be on the previous user again. And you will be on the previous directory, belonging to that user.
-
-Before being able to go the `github` user directory, you need to become the `root` user (you might already be):
-
-```bash
-sudo su
-```
-
-* As the `root` user, go to the `actions-runner` directory inside of the `github` user's home directory:
-
-```bash
-cd /home/github/actions-runner
-```
-
-* Install the self-hosted runner as a service with the user `github`:
-
-```bash
-./svc.sh install github
-```
-
-* Start the service:
-
-```bash
-./svc.sh start
-```
-
-* Check the status of the service:
-
-```bash
-./svc.sh status
-```
-
-You can read more about it in the official guide: [Configuring the self-hosted runner application as a service](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/configuring-the-self-hosted-runner-application-as-a-service).
-
-### Set Secrets
-
-On your repository, configure secrets for the environment variables you need, the same ones described above, including `SECRET_KEY`, etc. Follow the [official GitHub guide for setting repository secrets](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository).
-
-The current Github Actions workflows expect these secrets:
-
-* `DOMAIN_PRODUCTION`
-* `DOMAIN_STAGING`
-* `STACK_NAME_PRODUCTION`
-* `STACK_NAME_STAGING`
-* `EMAILS_FROM_EMAIL`
-* `FIRST_SUPERUSER`
-* `FIRST_SUPERUSER_PASSWORD`
-* `POSTGRES_PASSWORD`
-* `SECRET_KEY`
-* `LATEST_CHANGES`
-* `SMOKESHOW_AUTH_KEY`
-
-## GitHub Action Deployment Workflows
-
-There are GitHub Action workflows in the `.github/workflows` directory already configured for deploying to the environments (GitHub Actions runners with the labels):
-
-* `staging`: after pushing (or merging) to the branch `master`.
-* `production`: after publishing a release.
-
-If you need to add extra environments you could use those as a starting point.
-
-## URLs
-
-Replace `fastapi-project.example.com` with your domain.
-
-### Main Traefik Dashboard
-
-Traefik UI: `https://traefik.fastapi-project.example.com`
-
-### Production
-
-Frontend: `https://dashboard.fastapi-project.example.com`
-
-Backend API docs: `https://api.fastapi-project.example.com/docs`
-
-Backend API base URL: `https://api.fastapi-project.example.com`
-
-Adminer: `https://adminer.fastapi-project.example.com`
-
-### Staging
-
-Frontend: `https://dashboard.staging.fastapi-project.example.com`
-
-Backend API docs: `https://api.staging.fastapi-project.example.com/docs`
-
-Backend API base URL: `https://api.staging.fastapi-project.example.com`
-
-Adminer: `https://adminer.staging.fastapi-project.example.com`
diff --git a/development.md b/development.md
deleted file mode 100644
index d7d41d73f1..0000000000
--- a/development.md
+++ /dev/null
@@ -1,207 +0,0 @@
-# FastAPI Project - Development
-
-## Docker Compose
-
-* Start the local stack with Docker Compose:
-
-```bash
-docker compose watch
-```
-
-* Now you can open your browser and interact with these URLs:
-
-Frontend, built with Docker, with routes handled based on the path: http://localhost:5173
-
-Backend, JSON based web API based on OpenAPI: http://localhost:8000
-
-Automatic interactive documentation with Swagger UI (from the OpenAPI backend): http://localhost:8000/docs
-
-Adminer, database web administration: http://localhost:8080
-
-Traefik UI, to see how the routes are being handled by the proxy: http://localhost:8090
-
-**Note**: The first time you start your stack, it might take a minute for it to be ready. While the backend waits for the database to be ready and configures everything. You can check the logs to monitor it.
-
-To check the logs, run (in another terminal):
-
-```bash
-docker compose logs
-```
-
-To check the logs of a specific service, add the name of the service, e.g.:
-
-```bash
-docker compose logs backend
-```
-
-## Local Development
-
-The Docker Compose files are configured so that each of the services is available in a different port in `localhost`.
-
-For the backend and frontend, they use the same port that would be used by their local development server, so, the backend is at `http://localhost:8000` and the frontend at `http://localhost:5173`.
-
-This way, you could turn off a Docker Compose service and start its local development service, and everything would keep working, because it all uses the same ports.
-
-For example, you can stop that `frontend` service in the Docker Compose, in another terminal, run:
-
-```bash
-docker compose stop frontend
-```
-
-And then start the local frontend development server:
-
-```bash
-cd frontend
-npm run dev
-```
-
-Or you could stop the `backend` Docker Compose service:
-
-```bash
-docker compose stop backend
-```
-
-And then you can run the local development server for the backend:
-
-```bash
-cd backend
-fastapi dev app/main.py
-```
-
-## Docker Compose in `localhost.tiangolo.com`
-
-When you start the Docker Compose stack, it uses `localhost` by default, with different ports for each service (backend, frontend, adminer, etc).
-
-When you deploy it to production (or staging), it will deploy each service in a different subdomain, like `api.example.com` for the backend and `dashboard.example.com` for the frontend.
-
-In the guide about [deployment](deployment.md) you can read about Traefik, the configured proxy. That's the component in charge of transmitting traffic to each service based on the subdomain.
-
-If you want to test that it's all working locally, you can edit the local `.env` file, and change:
-
-```dotenv
-DOMAIN=localhost.tiangolo.com
-```
-
-That will be used by the Docker Compose files to configure the base domain for the services.
-
-Traefik will use this to transmit traffic at `api.localhost.tiangolo.com` to the backend, and traffic at `dashboard.localhost.tiangolo.com` to the frontend.
-
-The domain `localhost.tiangolo.com` is a special domain that is configured (with all its subdomains) to point to `127.0.0.1`. This way you can use that for your local development.
-
-After you update it, run again:
-
-```bash
-docker compose watch
-```
-
-When deploying, for example in production, the main Traefik is configured outside of the Docker Compose files. For local development, there's an included Traefik in `docker-compose.override.yml`, just to let you test that the domains work as expected, for example with `api.localhost.tiangolo.com` and `dashboard.localhost.tiangolo.com`.
-
-## Docker Compose files and env vars
-
-There is a main `docker-compose.yml` file with all the configurations that apply to the whole stack, it is used automatically by `docker compose`.
-
-And there's also a `docker-compose.override.yml` with overrides for development, for example to mount the source code as a volume. It is used automatically by `docker compose` to apply overrides on top of `docker-compose.yml`.
-
-These Docker Compose files use the `.env` file containing configurations to be injected as environment variables in the containers.
-
-They also use some additional configurations taken from environment variables set in the scripts before calling the `docker compose` command.
-
-After changing variables, make sure you restart the stack:
-
-```bash
-docker compose watch
-```
-
-## The .env file
-
-The `.env` file is the one that contains all your configurations, generated keys and passwords, etc.
-
-Depending on your workflow, you could want to exclude it from Git, for example if your project is public. In that case, you would have to make sure to set up a way for your CI tools to obtain it while building or deploying your project.
-
-One way to do it could be to add each environment variable to your CI/CD system, and updating the `docker-compose.yml` file to read that specific env var instead of reading the `.env` file.
-
-## Pre-commits and code linting
-
-we are using a tool called [pre-commit](https://pre-commit.com/) for code linting and formatting.
-
-When you install it, it runs right before making a commit in git. This way it ensures that the code is consistent and formatted even before it is committed.
-
-You can find a file `.pre-commit-config.yaml` with configurations at the root of the project.
-
-#### Install pre-commit to run automatically
-
-`pre-commit` is already part of the dependencies of the project, but you could also install it globally if you prefer to, following [the official pre-commit docs](https://pre-commit.com/).
-
-After having the `pre-commit` tool installed and available, you need to "install" it in the local repository, so that it runs automatically before each commit.
-
-Using `uv`, you could do it with:
-
-```bash
-β― uv run pre-commit install
-pre-commit installed at .git/hooks/pre-commit
-```
-
-Now whenever you try to commit, e.g. with:
-
-```bash
-git commit
-```
-
-...pre-commit will run and check and format the code you are about to commit, and will ask you to add that code (stage it) with git again before committing.
-
-Then you can `git add` the modified/fixed files again and now you can commit.
-
-#### Running pre-commit hooks manually
-
-you can also run `pre-commit` manually on all the files, you can do it using `uv` with:
-
-```bash
-β― uv run pre-commit run --all-files
-check for added large files..............................................Passed
-check toml...............................................................Passed
-check yaml...............................................................Passed
-ruff.....................................................................Passed
-ruff-format..............................................................Passed
-eslint...................................................................Passed
-prettier.................................................................Passed
-```
-
-## URLs
-
-The production or staging URLs would use these same paths, but with your own domain.
-
-### Development URLs
-
-Development URLs, for local development.
-
-Frontend: http://localhost:5173
-
-Backend: http://localhost:8000
-
-Automatic Interactive Docs (Swagger UI): http://localhost:8000/docs
-
-Automatic Alternative Docs (ReDoc): http://localhost:8000/redoc
-
-Adminer: http://localhost:8080
-
-Traefik UI: http://localhost:8090
-
-MailCatcher: http://localhost:1080
-
-### Development URLs with `localhost.tiangolo.com` Configured
-
-Development URLs, for local development.
-
-Frontend: http://dashboard.localhost.tiangolo.com
-
-Backend: http://api.localhost.tiangolo.com
-
-Automatic Interactive Docs (Swagger UI): http://api.localhost.tiangolo.com/docs
-
-Automatic Alternative Docs (ReDoc): http://api.localhost.tiangolo.com/redoc
-
-Adminer: http://localhost.tiangolo.com:8080
-
-Traefik UI: http://localhost.tiangolo.com:8090
-
-MailCatcher: http://localhost.tiangolo.com:1080
\ No newline at end of file
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
deleted file mode 100644
index 0751abe901..0000000000
--- a/docker-compose.override.yml
+++ /dev/null
@@ -1,133 +0,0 @@
-services:
-
- # Local services are available on their ports, but also available on:
- # http://api.localhost.tiangolo.com: backend
- # http://dashboard.localhost.tiangolo.com: frontend
- # etc. To enable it, update .env, set:
- # DOMAIN=localhost.tiangolo.com
- proxy:
- image: traefik:3.0
- volumes:
- - /var/run/docker.sock:/var/run/docker.sock
- ports:
- - "80:80"
- - "8090:8080"
- # Duplicate the command from docker-compose.yml to add --api.insecure=true
- command:
- # Enable Docker in Traefik, so that it reads labels from Docker services
- - --providers.docker
- # Add a constraint to only use services with the label for this stack
- - --providers.docker.constraints=Label(`traefik.constraint-label`, `traefik-public`)
- # Do not expose all Docker services, only the ones explicitly exposed
- - --providers.docker.exposedbydefault=false
- # Create an entrypoint "http" listening on port 80
- - --entrypoints.http.address=:80
- # Create an entrypoint "https" listening on port 443
- - --entrypoints.https.address=:443
- # Enable the access log, with HTTP requests
- - --accesslog
- # Enable the Traefik log, for configurations and errors
- - --log
- # Enable debug logging for local development
- - --log.level=DEBUG
- # Enable the Dashboard and API
- - --api
- # Enable the Dashboard and API in insecure mode for local development
- - --api.insecure=true
- labels:
- # Enable Traefik for this service, to make it available in the public network
- - traefik.enable=true
- - traefik.constraint-label=traefik-public
- # Dummy https-redirect middleware that doesn't really redirect, only to
- # allow running it locally
- - traefik.http.middlewares.https-redirect.contenttype.autodetect=false
- networks:
- - traefik-public
- - default
-
- db:
- restart: "no"
- ports:
- - "5432:5432"
-
- adminer:
- restart: "no"
- ports:
- - "8080:8080"
-
- backend:
- restart: "no"
- ports:
- - "8000:8000"
- build:
- context: ./backend
- # command: sleep infinity # Infinite loop to keep container alive doing nothing
- command:
- - fastapi
- - run
- - --reload
- - "app/main.py"
- develop:
- watch:
- - path: ./backend
- action: sync
- target: /app
- ignore:
- - ./backend/.venv
- - .venv
- - path: ./backend/pyproject.toml
- action: rebuild
- # TODO: remove once coverage is done locally
- volumes:
- - ./backend/htmlcov:/app/htmlcov
- environment:
- SMTP_HOST: "mailcatcher"
- SMTP_PORT: "1025"
- SMTP_TLS: "false"
- EMAILS_FROM_EMAIL: "noreply@example.com"
-
- mailcatcher:
- image: schickling/mailcatcher
- ports:
- - "1080:1080"
- - "1025:1025"
-
- frontend:
- restart: "no"
- ports:
- - "5173:80"
- build:
- context: ./frontend
- args:
- - VITE_API_URL=http://localhost:8000
- - NODE_ENV=development
-
- playwright:
- build:
- context: ./frontend
- dockerfile: Dockerfile.playwright
- args:
- - VITE_API_URL=http://backend:8000
- - NODE_ENV=production
- ipc: host
- depends_on:
- - backend
- - mailcatcher
- env_file:
- - .env
- environment:
- - VITE_API_URL=http://backend:8000
- - MAILCATCHER_HOST=http://mailcatcher:1080
- # For the reports when run locally
- - PLAYWRIGHT_HTML_HOST=0.0.0.0
- - CI=${CI}
- volumes:
- - ./frontend/blob-report:/app/blob-report
- - ./frontend/test-results:/app/test-results
- ports:
- - 9323:9323
-
-networks:
- traefik-public:
- # For local dev, don't expect an external Traefik network
- external: false
diff --git a/docker-compose.traefik.yml b/docker-compose.traefik.yml
deleted file mode 100644
index 886d6dcc2f..0000000000
--- a/docker-compose.traefik.yml
+++ /dev/null
@@ -1,77 +0,0 @@
-services:
- traefik:
- image: traefik:3.0
- ports:
- # Listen on port 80, default for HTTP, necessary to redirect to HTTPS
- - 80:80
- # Listen on port 443, default for HTTPS
- - 443:443
- restart: always
- labels:
- # Enable Traefik for this service, to make it available in the public network
- - traefik.enable=true
- # Use the traefik-public network (declared below)
- - traefik.docker.network=traefik-public
- # Define the port inside of the Docker service to use
- - traefik.http.services.traefik-dashboard.loadbalancer.server.port=8080
- # Make Traefik use this domain (from an environment variable) in HTTP
- - traefik.http.routers.traefik-dashboard-http.entrypoints=http
- - traefik.http.routers.traefik-dashboard-http.rule=Host(`traefik.${DOMAIN?Variable not set}`)
- # traefik-https the actual router using HTTPS
- - traefik.http.routers.traefik-dashboard-https.entrypoints=https
- - traefik.http.routers.traefik-dashboard-https.rule=Host(`traefik.${DOMAIN?Variable not set}`)
- - traefik.http.routers.traefik-dashboard-https.tls=true
- # Use the "le" (Let's Encrypt) resolver created below
- - traefik.http.routers.traefik-dashboard-https.tls.certresolver=le
- # Use the special Traefik service api@internal with the web UI/Dashboard
- - traefik.http.routers.traefik-dashboard-https.service=api@internal
- # https-redirect middleware to redirect HTTP to HTTPS
- - traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
- - traefik.http.middlewares.https-redirect.redirectscheme.permanent=true
- # traefik-http set up only to use the middleware to redirect to https
- - traefik.http.routers.traefik-dashboard-http.middlewares=https-redirect
- # admin-auth middleware with HTTP Basic auth
- # Using the environment variables USERNAME and HASHED_PASSWORD
- - traefik.http.middlewares.admin-auth.basicauth.users=${USERNAME?Variable not set}:${HASHED_PASSWORD?Variable not set}
- # Enable HTTP Basic auth, using the middleware created above
- - traefik.http.routers.traefik-dashboard-https.middlewares=admin-auth
- volumes:
- # Add Docker as a mounted volume, so that Traefik can read the labels of other services
- - /var/run/docker.sock:/var/run/docker.sock:ro
- # Mount the volume to store the certificates
- - traefik-public-certificates:/certificates
- command:
- # Enable Docker in Traefik, so that it reads labels from Docker services
- - --providers.docker
- # Do not expose all Docker services, only the ones explicitly exposed
- - --providers.docker.exposedbydefault=false
- # Create an entrypoint "http" listening on port 80
- - --entrypoints.http.address=:80
- # Create an entrypoint "https" listening on port 443
- - --entrypoints.https.address=:443
- # Create the certificate resolver "le" for Let's Encrypt, uses the environment variable EMAIL
- - --certificatesresolvers.le.acme.email=${EMAIL?Variable not set}
- # Store the Let's Encrypt certificates in the mounted volume
- - --certificatesresolvers.le.acme.storage=/certificates/acme.json
- # Use the TLS Challenge for Let's Encrypt
- - --certificatesresolvers.le.acme.tlschallenge=true
- # Enable the access log, with HTTP requests
- - --accesslog
- # Enable the Traefik log, for configurations and errors
- - --log
- # Enable the Dashboard and API
- - --api
- networks:
- # Use the public network created to be shared between Traefik and
- # any other service that needs to be publicly available with HTTPS
- - traefik-public
-
-volumes:
- # Create a volume to store the certificates, even if the container is recreated
- traefik-public-certificates:
-
-networks:
- # Use the previously created public network "traefik-public", shared with other
- # services that need to be publicly available via this Traefik
- traefik-public:
- external: true
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index c92d5d4451..0000000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,171 +0,0 @@
-services:
-
- db:
- image: postgres:12
- restart: always
- healthcheck:
- test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
- interval: 10s
- retries: 5
- start_period: 30s
- timeout: 10s
- volumes:
- - app-db-data:/var/lib/postgresql/data/pgdata
- env_file:
- - .env
- environment:
- - PGDATA=/var/lib/postgresql/data/pgdata
- - POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set}
- - POSTGRES_USER=${POSTGRES_USER?Variable not set}
- - POSTGRES_DB=${POSTGRES_DB?Variable not set}
-
- adminer:
- image: adminer
- restart: always
- networks:
- - traefik-public
- - default
- depends_on:
- - db
- environment:
- - ADMINER_DESIGN=pepa-linha-dark
- labels:
- - traefik.enable=true
- - traefik.docker.network=traefik-public
- - traefik.constraint-label=traefik-public
- - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-http.rule=Host(`adminer.${DOMAIN?Variable not set}`)
- - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-http.entrypoints=http
- - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-http.middlewares=https-redirect
- - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-https.rule=Host(`adminer.${DOMAIN?Variable not set}`)
- - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-https.entrypoints=https
- - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-https.tls=true
- - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-https.tls.certresolver=le
- - traefik.http.services.${STACK_NAME?Variable not set}-adminer.loadbalancer.server.port=8080
-
- prestart:
- image: '${DOCKER_IMAGE_BACKEND?Variable not set}:${TAG-latest}'
- build:
- context: ./backend
- networks:
- - traefik-public
- - default
- depends_on:
- db:
- condition: service_healthy
- restart: true
- command: bash scripts/prestart.sh
- env_file:
- - .env
- environment:
- - DOMAIN=${DOMAIN}
- - FRONTEND_HOST=${FRONTEND_HOST?Variable not set}
- - ENVIRONMENT=${ENVIRONMENT}
- - BACKEND_CORS_ORIGINS=${BACKEND_CORS_ORIGINS}
- - SECRET_KEY=${SECRET_KEY?Variable not set}
- - FIRST_SUPERUSER=${FIRST_SUPERUSER?Variable not set}
- - FIRST_SUPERUSER_PASSWORD=${FIRST_SUPERUSER_PASSWORD?Variable not set}
- - SMTP_HOST=${SMTP_HOST}
- - SMTP_USER=${SMTP_USER}
- - SMTP_PASSWORD=${SMTP_PASSWORD}
- - EMAILS_FROM_EMAIL=${EMAILS_FROM_EMAIL}
- - POSTGRES_SERVER=db
- - POSTGRES_PORT=${POSTGRES_PORT}
- - POSTGRES_DB=${POSTGRES_DB}
- - POSTGRES_USER=${POSTGRES_USER?Variable not set}
- - POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set}
- - SENTRY_DSN=${SENTRY_DSN}
-
- backend:
- image: '${DOCKER_IMAGE_BACKEND?Variable not set}:${TAG-latest}'
- restart: always
- networks:
- - traefik-public
- - default
- depends_on:
- db:
- condition: service_healthy
- restart: true
- prestart:
- condition: service_completed_successfully
- env_file:
- - .env
- environment:
- - DOMAIN=${DOMAIN}
- - FRONTEND_HOST=${FRONTEND_HOST?Variable not set}
- - ENVIRONMENT=${ENVIRONMENT}
- - BACKEND_CORS_ORIGINS=${BACKEND_CORS_ORIGINS}
- - SECRET_KEY=${SECRET_KEY?Variable not set}
- - FIRST_SUPERUSER=${FIRST_SUPERUSER?Variable not set}
- - FIRST_SUPERUSER_PASSWORD=${FIRST_SUPERUSER_PASSWORD?Variable not set}
- - SMTP_HOST=${SMTP_HOST}
- - SMTP_USER=${SMTP_USER}
- - SMTP_PASSWORD=${SMTP_PASSWORD}
- - EMAILS_FROM_EMAIL=${EMAILS_FROM_EMAIL}
- - POSTGRES_SERVER=db
- - POSTGRES_PORT=${POSTGRES_PORT}
- - POSTGRES_DB=${POSTGRES_DB}
- - POSTGRES_USER=${POSTGRES_USER?Variable not set}
- - POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set}
- - SENTRY_DSN=${SENTRY_DSN}
-
- healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/utils/health-check/"]
- interval: 10s
- timeout: 5s
- retries: 5
-
- build:
- context: ./backend
- labels:
- - traefik.enable=true
- - traefik.docker.network=traefik-public
- - traefik.constraint-label=traefik-public
-
- - traefik.http.services.${STACK_NAME?Variable not set}-backend.loadbalancer.server.port=8000
-
- - traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.rule=Host(`api.${DOMAIN?Variable not set}`)
- - traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.entrypoints=http
-
- - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.rule=Host(`api.${DOMAIN?Variable not set}`)
- - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.entrypoints=https
- - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.tls=true
- - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.tls.certresolver=le
-
- # Enable redirection for HTTP and HTTPS
- - traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.middlewares=https-redirect
-
- frontend:
- image: '${DOCKER_IMAGE_FRONTEND?Variable not set}:${TAG-latest}'
- restart: always
- networks:
- - traefik-public
- - default
- build:
- context: ./frontend
- args:
- - VITE_API_URL=https://api.${DOMAIN?Variable not set}
- - NODE_ENV=production
- labels:
- - traefik.enable=true
- - traefik.docker.network=traefik-public
- - traefik.constraint-label=traefik-public
-
- - traefik.http.services.${STACK_NAME?Variable not set}-frontend.loadbalancer.server.port=80
-
- - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.rule=Host(`dashboard.${DOMAIN?Variable not set}`)
- - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.entrypoints=http
-
- - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.rule=Host(`dashboard.${DOMAIN?Variable not set}`)
- - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.entrypoints=https
- - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.tls=true
- - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.tls.certresolver=le
-
- # Enable redirection for HTTP and HTTPS
- - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.middlewares=https-redirect
-volumes:
- app-db-data:
-
-networks:
- traefik-public:
- # Allow setting it to false for testing
- external: true
diff --git a/frontend/.dockerignore b/frontend/.dockerignore
deleted file mode 100644
index f06235c460..0000000000
--- a/frontend/.dockerignore
+++ /dev/null
@@ -1,2 +0,0 @@
-node_modules
-dist
diff --git a/frontend/.gitignore b/frontend/.gitignore
index 75e25e0ef4..ec4423fddc 100644
--- a/frontend/.gitignore
+++ b/frontend/.gitignore
@@ -27,4 +27,6 @@ openapi.json
/playwright-report/
/blob-report/
/playwright/.cache/
-/playwright/.auth/
\ No newline at end of file
+/playwright/.auth/
+
+.env
\ No newline at end of file
diff --git a/frontend/Dockerfile b/frontend/Dockerfile
deleted file mode 100644
index 8728c7b029..0000000000
--- a/frontend/Dockerfile
+++ /dev/null
@@ -1,23 +0,0 @@
-# Stage 0, "build-stage", based on Node.js, to build and compile the frontend
-FROM node:20 AS build-stage
-
-WORKDIR /app
-
-COPY package*.json /app/
-
-RUN npm install
-
-COPY ./ /app/
-
-ARG VITE_API_URL=${VITE_API_URL}
-
-RUN npm run build
-
-
-# Stage 1, based on Nginx, to have only the compiled app, ready for production with Nginx
-FROM nginx:1
-
-COPY --from=build-stage /app/dist/ /usr/share/nginx/html
-
-COPY ./nginx.conf /etc/nginx/conf.d/default.conf
-COPY ./nginx-backend-not-found.conf /etc/nginx/extra-conf.d/backend-not-found.conf
diff --git a/frontend/Dockerfile.playwright b/frontend/Dockerfile.playwright
deleted file mode 100644
index e76ac15f65..0000000000
--- a/frontend/Dockerfile.playwright
+++ /dev/null
@@ -1,13 +0,0 @@
-FROM node:20
-
-WORKDIR /app
-
-COPY package*.json /app/
-
-RUN npm install
-
-RUN npx -y playwright install --with-deps
-
-COPY ./ /app/
-
-ARG VITE_API_URL=${VITE_API_URL}
diff --git a/frontend/README.md b/frontend/README.md
deleted file mode 100644
index 569af503b4..0000000000
--- a/frontend/README.md
+++ /dev/null
@@ -1,160 +0,0 @@
-# FastAPI Project - Frontend
-
-The frontend is built with [Vite](https://vitejs.dev/), [React](https://reactjs.org/), [TypeScript](https://www.typescriptlang.org/), [TanStack Query](https://tanstack.com/query), [TanStack Router](https://tanstack.com/router) and [Chakra UI](https://chakra-ui.com/).
-
-## Frontend development
-
-Before you begin, ensure that you have either the Node Version Manager (nvm) or Fast Node Manager (fnm) installed on your system.
-
-* To install fnm follow the [official fnm guide](https://github.com/Schniz/fnm#installation). If you prefer nvm, you can install it using the [official nvm guide](https://github.com/nvm-sh/nvm#installing-and-updating).
-
-* After installing either nvm or fnm, proceed to the `frontend` directory:
-
-```bash
-cd frontend
-```
-* If the Node.js version specified in the `.nvmrc` file isn't installed on your system, you can install it using the appropriate command:
-
-```bash
-# If using fnm
-fnm install
-
-# If using nvm
-nvm install
-```
-
-* Once the installation is complete, switch to the installed version:
-
-```bash
-# If using fnm
-fnm use
-
-# If using nvm
-nvm use
-```
-
-* Within the `frontend` directory, install the necessary NPM packages:
-
-```bash
-npm install
-```
-
-* And start the live server with the following `npm` script:
-
-```bash
-npm run dev
-```
-
-* Then open your browser at http://localhost:5173/.
-
-Notice that this live server is not running inside Docker, it's for local development, and that is the recommended workflow. Once you are happy with your frontend, you can build the frontend Docker image and start it, to test it in a production-like environment. But building the image at every change will not be as productive as running the local development server with live reload.
-
-Check the file `package.json` to see other available options.
-
-### Removing the frontend
-
-If you are developing an API-only app and want to remove the frontend, you can do it easily:
-
-* Remove the `./frontend` directory.
-
-* In the `docker-compose.yml` file, remove the whole service / section `frontend`.
-
-* In the `docker-compose.override.yml` file, remove the whole service / section `frontend` and `playwright`.
-
-Done, you have a frontend-less (api-only) app. π€
-
----
-
-If you want, you can also remove the `FRONTEND` environment variables from:
-
-* `.env`
-* `./scripts/*.sh`
-
-But it would be only to clean them up, leaving them won't really have any effect either way.
-
-## Generate Client
-
-### Automatically
-
-* Activate the backend virtual environment.
-* From the top level project directory, run the script:
-
-```bash
-./scripts/generate-frontend-client.sh
-```
-
-* Commit the changes.
-
-### Manually
-
-* Start the Docker Compose stack.
-
-* Download the OpenAPI JSON file from `http://localhost/api/v1/openapi.json` and copy it to a new file `openapi.json` at the root of the `frontend` directory.
-
-* To simplify the names in the generated frontend client code, modify the `openapi.json` file by running the following script:
-
-```bash
-node modify-openapi-operationids.js
-```
-
-* To generate the frontend client, run:
-
-```bash
-npm run generate-client
-```
-
-* Commit the changes.
-
-Notice that everytime the backend changes (changing the OpenAPI schema), you should follow these steps again to update the frontend client.
-
-## Using a Remote API
-
-If you want to use a remote API, you can set the environment variable `VITE_API_URL` to the URL of the remote API. For example, you can set it in the `frontend/.env` file:
-
-```env
-VITE_API_URL=https://api.my-domain.example.com
-```
-
-Then, when you run the frontend, it will use that URL as the base URL for the API.
-
-## Code Structure
-
-The frontend code is structured as follows:
-
-* `frontend/src` - The main frontend code.
-* `frontend/src/assets` - Static assets.
-* `frontend/src/client` - The generated OpenAPI client.
-* `frontend/src/components` - The different components of the frontend.
-* `frontend/src/hooks` - Custom hooks.
-* `frontend/src/routes` - The different routes of the frontend which include the pages.
-* `theme.tsx` - The Chakra UI custom theme.
-
-## End-to-End Testing with Playwright
-
-The frontend includes initial end-to-end tests using Playwright. To run the tests, you need to have the Docker Compose stack running. Start the stack with the following command:
-
-```bash
-docker compose up -d --wait backend
-```
-
-Then, you can run the tests with the following command:
-
-```bash
-npx playwright test
-```
-
-You can also run your tests in UI mode to see the browser and interact with it running:
-
-```bash
-npx playwright test --ui
-```
-
-To stop and remove the Docker Compose stack and clean the data created in tests, use the following command:
-
-```bash
-docker compose down -v
-```
-
-To update the tests, navigate to the tests directory and modify the existing test files or add new ones as needed.
-
-For more information on writing and running Playwright tests, refer to the official [Playwright documentation](https://playwright.dev/docs/intro).
diff --git a/frontend/nginx-backend-not-found.conf b/frontend/nginx-backend-not-found.conf
deleted file mode 100644
index f6fea66358..0000000000
--- a/frontend/nginx-backend-not-found.conf
+++ /dev/null
@@ -1,9 +0,0 @@
-location /api {
- return 404;
-}
-location /docs {
- return 404;
-}
-location /redoc {
- return 404;
-}
diff --git a/frontend/nginx.conf b/frontend/nginx.conf
deleted file mode 100644
index ba4d9aad6c..0000000000
--- a/frontend/nginx.conf
+++ /dev/null
@@ -1,11 +0,0 @@
-server {
- listen 80;
-
- location / {
- root /usr/share/nginx/html;
- index index.html index.htm;
- try_files $uri /index.html =404;
- }
-
- include /etc/nginx/extra-conf.d/*.conf;
-}
diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py
deleted file mode 100644
index 2ca5260dac..0000000000
--- a/hooks/post_gen_project.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from pathlib import Path
-
-
-path: Path
-for path in Path(".").glob("**/*.sh"):
- data = path.read_bytes()
- lf_data = data.replace(b"\r\n", b"\n")
- path.write_bytes(lf_data)
diff --git a/release-notes.md b/release-notes.md
deleted file mode 100644
index 7a55e34c8a..0000000000
--- a/release-notes.md
+++ /dev/null
@@ -1,540 +0,0 @@
-# Release Notes
-
-## Latest Changes
-
-### Features
-
-* β¨ Add private, local only, API for usage in E2E tests. PR [#1429](https://github.com/fastapi/full-stack-fastapi-template/pull/1429) by [@patrick91](https://github.com/patrick91).
-* β¨ Migrate to latest openapi-ts. PR [#1430](https://github.com/fastapi/full-stack-fastapi-template/pull/1430) by [@patrick91](https://github.com/patrick91).
-
-### Fixes
-
-* π§βπ§ Replace correct value for 'htmlFor'. PR [#1456](https://github.com/fastapi/full-stack-fastapi-template/pull/1456) by [@wesenbergg](https://github.com/wesenbergg).
-
-### Refactors
-
-* π¨ Move `prefix` and `tags` to routers. PR [#1439](https://github.com/fastapi/full-stack-fastapi-template/pull/1439) by [@patrick91](https://github.com/patrick91).
-* β»οΈ Remove modify id script in favor of openapi-ts config. PR [#1434](https://github.com/fastapi/full-stack-fastapi-template/pull/1434) by [@patrick91](https://github.com/patrick91).
-* π· Improve Playwright CI speed: sharding (paralel runs), run in Docker to use cache, use env vars. PR [#1405](https://github.com/fastapi/full-stack-fastapi-template/pull/1405) by [@tiangolo](https://github.com/tiangolo).
-* β»οΈ Add PaginationFooter component. PR [#1381](https://github.com/fastapi/full-stack-fastapi-template/pull/1381) by [@saltie2193](https://github.com/saltie2193).
-* β»οΈ Refactored code to use encryption algorithm name from settings for consistency. PR [#1160](https://github.com/fastapi/full-stack-fastapi-template/pull/1160) by [@sameeramin](https://github.com/sameeramin).
-* π Enable logging for email utils by default. PR [#1374](https://github.com/fastapi/full-stack-fastapi-template/pull/1374) by [@ihmily](https://github.com/ihmily).
-* π§ Add `ENV PYTHONUNBUFFERED=1` to log output directly to Docker. PR [#1378](https://github.com/fastapi/full-stack-fastapi-template/pull/1378) by [@tiangolo](https://github.com/tiangolo).
-* π‘ Remove unnecessary comment. PR [#1260](https://github.com/fastapi/full-stack-fastapi-template/pull/1260) by [@sebhani](https://github.com/sebhani).
-
-### Upgrades
-
-* β¬οΈ Update Dockerfile to use uv version 0.5.11. PR [#1454](https://github.com/fastapi/full-stack-fastapi-template/pull/1454) by [@alejsdev](https://github.com/alejsdev).
-
-### Docs
-
-* π Update `frontend/README.md` to also remove Playwright when removing Frontend. PR [#1452](https://github.com/fastapi/full-stack-fastapi-template/pull/1452) by [@youben11](https://github.com/youben11).
-* π Update `deployment.md`, instructions to install GitHub Runner in non-root VMs. PR [#1412](https://github.com/fastapi/full-stack-fastapi-template/pull/1412) by [@tiangolo](https://github.com/tiangolo).
-* π Add MailCatcher to `development.md`. PR [#1387](https://github.com/fastapi/full-stack-fastapi-template/pull/1387) by [@tobiase](https://github.com/tobiase).
-
-### Internal
-
-* β¬ Bump astral-sh/setup-uv from 4 to 5. PR [#1453](https://github.com/fastapi/full-stack-fastapi-template/pull/1453) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* β¬ Bump astral-sh/setup-uv from 3 to 4. PR [#1433](https://github.com/fastapi/full-stack-fastapi-template/pull/1433) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* β¬ Bump tiangolo/latest-changes from 0.3.1 to 0.3.2. PR [#1418](https://github.com/fastapi/full-stack-fastapi-template/pull/1418) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* π· Update issue manager workflow. PR [#1398](https://github.com/fastapi/full-stack-fastapi-template/pull/1398) by [@alejsdev](https://github.com/alejsdev).
-* π· Fix smokeshow, checkout files on CI. PR [#1395](https://github.com/fastapi/full-stack-fastapi-template/pull/1395) by [@tiangolo](https://github.com/tiangolo).
-* π· Update `labeler.yml`. PR [#1388](https://github.com/fastapi/full-stack-fastapi-template/pull/1388) by [@tiangolo](https://github.com/tiangolo).
-* π§ Add .auth playwright folder to `.gitignore`. PR [#1383](https://github.com/fastapi/full-stack-fastapi-template/pull/1383) by [@justin-p](https://github.com/justin-p).
-* β¬οΈ Bump rollup from 4.6.1 to 4.22.5 in /frontend. PR [#1379](https://github.com/fastapi/full-stack-fastapi-template/pull/1379) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* β¬ Bump astral-sh/setup-uv from 2 to 3. PR [#1364](https://github.com/fastapi/full-stack-fastapi-template/pull/1364) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* π· Update pre-commit end-of-file-fixer hook to exclude email-templates. PR [#1296](https://github.com/fastapi/full-stack-fastapi-template/pull/1296) by [@goabonga](https://github.com/goabonga).
-* β¬ Bump tiangolo/issue-manager from 0.5.0 to 0.5.1. PR [#1332](https://github.com/fastapi/full-stack-fastapi-template/pull/1332) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* π§ Run task by the same Python environment used to run Copier. PR [#1157](https://github.com/fastapi/full-stack-fastapi-template/pull/1157) by [@waketzheng](https://github.com/waketzheng).
-* π· Tweak generate client to error out if there are errors. PR [#1377](https://github.com/fastapi/full-stack-fastapi-template/pull/1377) by [@tiangolo](https://github.com/tiangolo).
-* π· Generate and commit client only on same repo PRs, on forks, show the error. PR [#1376](https://github.com/fastapi/full-stack-fastapi-template/pull/1376) by [@tiangolo](https://github.com/tiangolo).
-
-## 0.7.1
-
-### Highlights
-
-* Migrate from Poetry to [`uv`](https://github.com/astral-sh/uv).
-* Simplifications and improvements for Docker Compose files, Traefik Dockerfiles.
-* Make the API use its own domain `api.example.com` and the frontend use `dashboard.example.com`. This would make it easier to deploy them separately if you needed that.
-* The backend and frontend on Docker Compose now listen on the same port as the local development servers, this way you can stop the Docker Compose services and run the local development servers without changing the frontend configuration.
-
-### Features
-
-* π©Ί Add DB healthcheck. PR [#1342](https://github.com/fastapi/full-stack-fastapi-template/pull/1342) by [@tiangolo](https://github.com/tiangolo).
-
-### Refactors
-
-* β»οΈ Update settings to use top level `.env` file. PR [#1359](https://github.com/fastapi/full-stack-fastapi-template/pull/1359) by [@tiangolo](https://github.com/tiangolo).
-* β¬οΈ Migrate from Poetry to uv. PR [#1356](https://github.com/fastapi/full-stack-fastapi-template/pull/1356) by [@tiangolo](https://github.com/tiangolo).
-* π₯ Remove logic for development dependencies and Jupyter, it was never documented, and I no longer use that trick. PR [#1355](https://github.com/fastapi/full-stack-fastapi-template/pull/1355) by [@tiangolo](https://github.com/tiangolo).
-* β»οΈ Use Docker Compose `watch`. PR [#1354](https://github.com/fastapi/full-stack-fastapi-template/pull/1354) by [@tiangolo](https://github.com/tiangolo).
-* π§ Use plain base official Python Docker image. PR [#1351](https://github.com/fastapi/full-stack-fastapi-template/pull/1351) by [@tiangolo](https://github.com/tiangolo).
-* π Move location of scripts to simplify file structure. PR [#1352](https://github.com/fastapi/full-stack-fastapi-template/pull/1352) by [@tiangolo](https://github.com/tiangolo).
-* β»οΈ Refactor prestart (migrations), move that to its own container. PR [#1350](https://github.com/fastapi/full-stack-fastapi-template/pull/1350) by [@tiangolo](https://github.com/tiangolo).
-* β»οΈ Include `FRONTEND_HOST` in CORS origins by default. PR [#1348](https://github.com/fastapi/full-stack-fastapi-template/pull/1348) by [@tiangolo](https://github.com/tiangolo).
-* β»οΈ Simplify domains with `api.example.com` for API and `dashboard.example.com` for frontend, improve local development with `localhost`. PR [#1344](https://github.com/fastapi/full-stack-fastapi-template/pull/1344) by [@tiangolo](https://github.com/tiangolo).
-* π₯ Simplify Traefik, remove www-redirects that add complexity. PR [#1343](https://github.com/fastapi/full-stack-fastapi-template/pull/1343) by [@tiangolo](https://github.com/tiangolo).
-* π₯ Enable support for Arm Docker images in Mac, remove old patch. PR [#1341](https://github.com/fastapi/full-stack-fastapi-template/pull/1341) by [@tiangolo](https://github.com/tiangolo).
-* β»οΈ Remove duplicate information in the ItemCreate model. PR [#1287](https://github.com/fastapi/full-stack-fastapi-template/pull/1287) by [@jjaakko](https://github.com/jjaakko).
-
-### Upgrades
-
-* β¬οΈ Upgrade FastAPI. PR [#1349](https://github.com/fastapi/full-stack-fastapi-template/pull/1349) by [@tiangolo](https://github.com/tiangolo).
-
-### Docs
-
-* π‘ Add comments to Dockerfile with uv references. PR [#1357](https://github.com/fastapi/full-stack-fastapi-template/pull/1357) by [@tiangolo](https://github.com/tiangolo).
-* π Add Email Templates to `backend/README.md`. PR [#1311](https://github.com/fastapi/full-stack-fastapi-template/pull/1311) by [@alejsdev](https://github.com/alejsdev).
-
-### Internal
-
-* π· Do not sync labels as it overrides manually added labels. PR [#1307](https://github.com/fastapi/full-stack-fastapi-template/pull/1307) by [@tiangolo](https://github.com/tiangolo).
-* π· Use uv cache on GitHub Actions. PR [#1366](https://github.com/fastapi/full-stack-fastapi-template/pull/1366) by [@tiangolo](https://github.com/tiangolo).
-* π· Update GitHub Actions format. PR [#1363](https://github.com/fastapi/full-stack-fastapi-template/pull/1363) by [@tiangolo](https://github.com/tiangolo).
-* π· Use `uv` for Python env to generate client. PR [#1362](https://github.com/fastapi/full-stack-fastapi-template/pull/1362) by [@tiangolo](https://github.com/tiangolo).
-* π· Run tests from Python environment (with `uv`), not from Docker container. PR [#1361](https://github.com/fastapi/full-stack-fastapi-template/pull/1361) by [@tiangolo](https://github.com/tiangolo).
-* π¨ Update `generate-client.sh` script, make it fail on errors, fix generation. PR [#1360](https://github.com/fastapi/full-stack-fastapi-template/pull/1360) by [@tiangolo](https://github.com/tiangolo).
-* π· Add GitHub Actions workflow to lint backend apart from tests. PR [#1358](https://github.com/fastapi/full-stack-fastapi-template/pull/1358) by [@tiangolo](https://github.com/tiangolo).
-* π· Improve playwright CI job. PR [#1335](https://github.com/fastapi/full-stack-fastapi-template/pull/1335) by [@patrick91](https://github.com/patrick91).
-* π· Update `issue-manager.yml`. PR [#1329](https://github.com/fastapi/full-stack-fastapi-template/pull/1329) by [@tiangolo](https://github.com/tiangolo).
-* π Set `include-hidden-files` to `True` when using the `upload-artifact` GH action. PR [#1327](https://github.com/fastapi/full-stack-fastapi-template/pull/1327) by [@svlandeg](https://github.com/svlandeg).
-* π·π» Auto-generate frontend client . PR [#1320](https://github.com/fastapi/full-stack-fastapi-template/pull/1320) by [@alejsdev](https://github.com/alejsdev).
-* π Fix in `.github/labeler.yml`. PR [#1322](https://github.com/fastapi/full-stack-fastapi-template/pull/1322) by [@alejsdev](https://github.com/alejsdev).
-* π· Update `.github/labeler.yml`. PR [#1321](https://github.com/fastapi/full-stack-fastapi-template/pull/1321) by [@alejsdev](https://github.com/alejsdev).
-* π· Update `latest-changes` GitHub Action. PR [#1315](https://github.com/fastapi/full-stack-fastapi-template/pull/1315) by [@tiangolo](https://github.com/tiangolo).
-* π· Update configs for labeler. PR [#1308](https://github.com/fastapi/full-stack-fastapi-template/pull/1308) by [@tiangolo](https://github.com/tiangolo).
-* π· Update GitHub Action labeler to add only one label. PR [#1304](https://github.com/fastapi/full-stack-fastapi-template/pull/1304) by [@tiangolo](https://github.com/tiangolo).
-* β¬οΈ Bump axios from 1.6.2 to 1.7.4 in /frontend. PR [#1301](https://github.com/fastapi/full-stack-fastapi-template/pull/1301) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* π· Update GitHub Action labeler dependencies. PR [#1302](https://github.com/fastapi/full-stack-fastapi-template/pull/1302) by [@tiangolo](https://github.com/tiangolo).
-* π· Update GitHub Action labeler permissions. PR [#1300](https://github.com/fastapi/full-stack-fastapi-template/pull/1300) by [@tiangolo](https://github.com/tiangolo).
-* π· Add GitHub Action label-checker. PR [#1299](https://github.com/fastapi/full-stack-fastapi-template/pull/1299) by [@tiangolo](https://github.com/tiangolo).
-* π· Add GitHub Action labeler. PR [#1298](https://github.com/fastapi/full-stack-fastapi-template/pull/1298) by [@tiangolo](https://github.com/tiangolo).
-* π· Add GitHub Action add-to-project. PR [#1297](https://github.com/fastapi/full-stack-fastapi-template/pull/1297) by [@tiangolo](https://github.com/tiangolo).
-* π· Update issue-manager. PR [#1288](https://github.com/fastapi/full-stack-fastapi-template/pull/1288) by [@tiangolo](https://github.com/tiangolo).
-
-## 0.7.0
-
-Lots of new things! π
-
-* E2E tests with Playwright.
-* Mailcatcher configuration, to develop and test email handling.
-* Pagination.
-* UUIDs for database keys.
-* New user sign up.
-* Support for deploying to multiple environments (staging, prod).
-* Many refactors and improvements.
-* Several dependency upgrades.
-
-### Features
-
-* β¨ Add User Settings e2e tests. PR [#1271](https://github.com/tiangolo/full-stack-fastapi-template/pull/1271) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add Reset Password e2e tests. PR [#1270](https://github.com/tiangolo/full-stack-fastapi-template/pull/1270) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add Sign Up e2e tests. PR [#1268](https://github.com/tiangolo/full-stack-fastapi-template/pull/1268) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add Sign Up and make `OPEN_USER_REGISTRATION=True` by default. PR [#1265](https://github.com/tiangolo/full-stack-fastapi-template/pull/1265) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add Login e2e tests. PR [#1264](https://github.com/tiangolo/full-stack-fastapi-template/pull/1264) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add initial setup for frontend / end-to-end tests with Playwright. PR [#1261](https://github.com/tiangolo/full-stack-fastapi-template/pull/1261) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add mailcatcher configuration. PR [#1244](https://github.com/tiangolo/full-stack-fastapi-template/pull/1244) by [@patrick91](https://github.com/patrick91).
-* β¨ Introduce pagination in items. PR [#1239](https://github.com/tiangolo/full-stack-fastapi-template/pull/1239) by [@patrick91](https://github.com/patrick91).
-* ποΈ Add max_length validation for database models and input data. PR [#1233](https://github.com/tiangolo/full-stack-fastapi-template/pull/1233) by [@estebanx64](https://github.com/estebanx64).
-* β¨ Add TanStack React Query devtools in dev build. PR [#1217](https://github.com/tiangolo/full-stack-fastapi-template/pull/1217) by [@tomerb](https://github.com/tomerb).
-* β¨ Add support for deploying multiple environments (staging, production) to the same server. PR [#1128](https://github.com/tiangolo/full-stack-fastapi-template/pull/1128) by [@tiangolo](https://github.com/tiangolo).
-* π· Update CI GitHub Actions to allow running in private repos. PR [#1125](https://github.com/tiangolo/full-stack-fastapi-template/pull/1125) by [@tiangolo](https://github.com/tiangolo).
-
-### Fixes
-
-* π Fix welcome page to show logged-in user. PR [#1218](https://github.com/tiangolo/full-stack-fastapi-template/pull/1218) by [@tomerb](https://github.com/tomerb).
-* π Fix local Traefik proxy network config to fix Gateway Timeouts. PR [#1184](https://github.com/tiangolo/full-stack-fastapi-template/pull/1184) by [@JoelGotsch](https://github.com/JoelGotsch).
-* β»οΈ Fix tests when first superuser password is changed in .env. PR [#1165](https://github.com/tiangolo/full-stack-fastapi-template/pull/1165) by [@billzhong](https://github.com/billzhong).
-* π Fix bug when resetting password. PR [#1171](https://github.com/tiangolo/full-stack-fastapi-template/pull/1171) by [@alejsdev](https://github.com/alejsdev).
-* π Fix 403 when the frontend has a directory without an index.html. PR [#1094](https://github.com/tiangolo/full-stack-fastapi-template/pull/1094) by [@tiangolo](https://github.com/tiangolo).
-
-### Refactors
-
-* π¨ Fix Docker build warning. PR [#1283](https://github.com/tiangolo/full-stack-fastapi-template/pull/1283) by [@erip](https://github.com/erip).
-* β»οΈ Regenerate client to use UUID instead of id integers and update frontend. PR [#1281](https://github.com/tiangolo/full-stack-fastapi-template/pull/1281) by [@rehanabdul](https://github.com/rehanabdul).
-* β»οΈ Tweaks in frontend. PR [#1273](https://github.com/tiangolo/full-stack-fastapi-template/pull/1273) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Add random password util and refactor tests. PR [#1277](https://github.com/tiangolo/full-stack-fastapi-template/pull/1277) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Refactor models to use cascade delete relationships . PR [#1276](https://github.com/tiangolo/full-stack-fastapi-template/pull/1276) by [@alejsdev](https://github.com/alejsdev).
-* π₯ Remove `USERS_OPEN_REGISTRATION` config, make registration enabled by default. PR [#1274](https://github.com/tiangolo/full-stack-fastapi-template/pull/1274) by [@alejsdev](https://github.com/alejsdev).
-* π§ Reuse database url from config in alembic setup. PR [#1229](https://github.com/tiangolo/full-stack-fastapi-template/pull/1229) by [@patrick91](https://github.com/patrick91).
-* π§ Update Playwright config and tests to use env variables. PR [#1266](https://github.com/tiangolo/full-stack-fastapi-template/pull/1266) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Edit refactor db models to use UUID's instead of integer ID's. PR [#1259](https://github.com/tiangolo/full-stack-fastapi-template/pull/1259) by [@estebanx64](https://github.com/estebanx64).
-* β»οΈ Update form inputs width. PR [#1263](https://github.com/tiangolo/full-stack-fastapi-template/pull/1263) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Replace deprecated utcnow() with now(timezone.utc) in utils module. PR [#1247](https://github.com/tiangolo/full-stack-fastapi-template/pull/1247) by [@jalvarezz13](https://github.com/jalvarezz13).
-* π¨ Format frontend. PR [#1262](https://github.com/tiangolo/full-stack-fastapi-template/pull/1262) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Abstraction of specific AddModal component out of the Navbar. PR [#1246](https://github.com/tiangolo/full-stack-fastapi-template/pull/1246) by [@ajbloureiro](https://github.com/ajbloureiro).
-* β»οΈ Update `login.tsx` to prevent error if username or password are empty. PR [#1257](https://github.com/tiangolo/full-stack-fastapi-template/pull/1257) by [@jmondaud](https://github.com/jmondaud).
-* β»οΈ Refactor recover password. PR [#1242](https://github.com/tiangolo/full-stack-fastapi-template/pull/1242) by [@alejsdev](https://github.com/alejsdev).
-* π¨ Format and lint . PR [#1243](https://github.com/tiangolo/full-stack-fastapi-template/pull/1243) by [@alejsdev](https://github.com/alejsdev).
-* π¨ Run biome after OpenAPI client generation. PR [#1226](https://github.com/tiangolo/full-stack-fastapi-template/pull/1226) by [@tomerb](https://github.com/tomerb).
-* β»οΈ Update DeleteConfirmation component to use new service. PR [#1224](https://github.com/tiangolo/full-stack-fastapi-template/pull/1224) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Update client services. PR [#1223](https://github.com/tiangolo/full-stack-fastapi-template/pull/1223) by [@alejsdev](https://github.com/alejsdev).
-* βοΈ Add minor frontend tweaks. PR [#1210](https://github.com/tiangolo/full-stack-fastapi-template/pull/1210) by [@alejsdev](https://github.com/alejsdev).
-* π Move assets to public folder. PR [#1206](https://github.com/tiangolo/full-stack-fastapi-template/pull/1206) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Refactor redirect labels to simplify removing the frontend. PR [#1208](https://github.com/tiangolo/full-stack-fastapi-template/pull/1208) by [@tiangolo](https://github.com/tiangolo).
-* ποΈ Refactor migrate from python-jose to PyJWT. PR [#1203](https://github.com/tiangolo/full-stack-fastapi-template/pull/1203) by [@estebanx64](https://github.com/estebanx64).
-* π₯ Remove duplicated code. PR [#1185](https://github.com/tiangolo/full-stack-fastapi-template/pull/1185) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Add delete_user_me endpoint and corresponding test cases. PR [#1179](https://github.com/tiangolo/full-stack-fastapi-template/pull/1179) by [@alejsdev](https://github.com/alejsdev).
-* β
Update test to add verification database records. PR [#1178](https://github.com/tiangolo/full-stack-fastapi-template/pull/1178) by [@estebanx64](https://github.com/estebanx64).
-* πΈ Use `useSuspenseQuery` to fetch members and show skeleton. PR [#1174](https://github.com/tiangolo/full-stack-fastapi-template/pull/1174) by [@patrick91](https://github.com/patrick91).
-* π¨ Format Utils. PR [#1173](https://github.com/tiangolo/full-stack-fastapi-template/pull/1173) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Use suspense for items page. PR [#1167](https://github.com/tiangolo/full-stack-fastapi-template/pull/1167) by [@patrick91](https://github.com/patrick91).
-* πΈ Mark login field as required. PR [#1166](https://github.com/tiangolo/full-stack-fastapi-template/pull/1166) by [@patrick91](https://github.com/patrick91).
-* πΈ Improve login. PR [#1163](https://github.com/tiangolo/full-stack-fastapi-template/pull/1163) by [@patrick91](https://github.com/patrick91).
-* π₯
Handle AxiosErrors in Login page. PR [#1162](https://github.com/tiangolo/full-stack-fastapi-template/pull/1162) by [@patrick91](https://github.com/patrick91).
-* π¨ Format frontend. PR [#1161](https://github.com/tiangolo/full-stack-fastapi-template/pull/1161) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Regenerate frontend client. PR [#1156](https://github.com/tiangolo/full-stack-fastapi-template/pull/1156) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Refactor rename ModelsOut to ModelsPublic. PR [#1154](https://github.com/tiangolo/full-stack-fastapi-template/pull/1154) by [@estebanx64](https://github.com/estebanx64).
-* β»οΈ Migrate frontend client generation from `openapi-typescript-codegen` to `@hey-api/openapi-ts`. PR [#1151](https://github.com/tiangolo/full-stack-fastapi-template/pull/1151) by [@alejsdev](https://github.com/alejsdev).
-* π₯ Remove unused exports and update dependencies. PR [#1146](https://github.com/tiangolo/full-stack-fastapi-template/pull/1146) by [@alejsdev](https://github.com/alejsdev).
-* π§ Update sentry dns initialization following the environment settings. PR [#1145](https://github.com/tiangolo/full-stack-fastapi-template/pull/1145) by [@estebanx64](https://github.com/estebanx64).
-* β»οΈ Refactor and tweaks, rename `UserCreateOpen` to `UserRegister` and others. PR [#1143](https://github.com/tiangolo/full-stack-fastapi-template/pull/1143) by [@alejsdev](https://github.com/alejsdev).
-* π¨ Format imports. PR [#1140](https://github.com/tiangolo/full-stack-fastapi-template/pull/1140) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Refactor and remove `React.FC`. PR [#1139](https://github.com/tiangolo/full-stack-fastapi-template/pull/1139) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Add email pattern and refactor in frontend. PR [#1138](https://github.com/tiangolo/full-stack-fastapi-template/pull/1138) by [@alejsdev](https://github.com/alejsdev).
-* π₯
Set up Sentry for FastAPI applications. PR [#1136](https://github.com/tiangolo/full-stack-fastapi-template/pull/1136) by [@estebanx64](https://github.com/estebanx64).
-* π₯ Remove deprecated Docker Compose version key. PR [#1129](https://github.com/tiangolo/full-stack-fastapi-template/pull/1129) by [@tiangolo](https://github.com/tiangolo).
-* π¨ Format with Biome . PR [#1097](https://github.com/tiangolo/full-stack-fastapi-template/pull/1097) by [@alejsdev](https://github.com/alejsdev).
-* π¨ Update quote style in biome formatter. PR [#1095](https://github.com/tiangolo/full-stack-fastapi-template/pull/1095) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Replace ESLint and Prettier with Biome to format and lint frontend. PR [#719](https://github.com/tiangolo/full-stack-fastapi-template/pull/719) by [@santigandolfo](https://github.com/santigandolfo).
-* π¨ Replace buttons styling for variants for consistency. PR [#722](https://github.com/tiangolo/full-stack-fastapi-template/pull/722) by [@alejsdev](https://github.com/alejsdev).
-* π οΈ Improve `modify-openapi-operationids.js`. PR [#720](https://github.com/tiangolo/full-stack-fastapi-template/pull/720) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Replace pytest-mock with unittest.mock and remove pytest-cov. PR [#717](https://github.com/tiangolo/full-stack-fastapi-template/pull/717) by [@estebanx64](https://github.com/estebanx64).
-* π οΈ Minor changes in frontend. PR [#715](https://github.com/tiangolo/full-stack-fastapi-template/pull/715) by [@alejsdev](https://github.com/alejsdev).
-* β» Update Docker image to prevent errors in M1 Macs. PR [#710](https://github.com/tiangolo/full-stack-fastapi-template/pull/710) by [@dudil](https://github.com/dudil).
-* β Fix typo in variable names in `backend/app/api/routes/items.py` and `backend/app/api/routes/users.py`. PR [#711](https://github.com/tiangolo/full-stack-fastapi-template/pull/711) by [@disrupted](https://github.com/disrupted).
-
-### Upgrades
-
-* β¬οΈ Update SQLModel to version `>=0.0.21`. PR [#1275](https://github.com/tiangolo/full-stack-fastapi-template/pull/1275) by [@alejsdev](https://github.com/alejsdev).
-* β¬οΈ Upgrade Traefik. PR [#1241](https://github.com/tiangolo/full-stack-fastapi-template/pull/1241) by [@tiangolo](https://github.com/tiangolo).
-* β¬οΈ Bump requests from 2.31.0 to 2.32.0 in /backend. PR [#1211](https://github.com/tiangolo/full-stack-fastapi-template/pull/1211) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* β¬οΈ Bump jinja2 from 3.1.3 to 3.1.4 in /backend. PR [#1196](https://github.com/tiangolo/full-stack-fastapi-template/pull/1196) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* Bump gunicorn from 21.2.0 to 22.0.0 in /backend. PR [#1176](https://github.com/tiangolo/full-stack-fastapi-template/pull/1176) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* Bump idna from 3.6 to 3.7 in /backend. PR [#1168](https://github.com/tiangolo/full-stack-fastapi-template/pull/1168) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* π Update React Query to TanStack Query. PR [#1153](https://github.com/tiangolo/full-stack-fastapi-template/pull/1153) by [@patrick91](https://github.com/patrick91).
-* Bump vite from 5.0.12 to 5.0.13 in /frontend. PR [#1149](https://github.com/tiangolo/full-stack-fastapi-template/pull/1149) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* Bump follow-redirects from 1.15.5 to 1.15.6 in /frontend. PR [#734](https://github.com/tiangolo/full-stack-fastapi-template/pull/734) by [@dependabot[bot]](https://github.com/apps/dependabot).
-
-### Docs
-
-* π Update links from tiangolo repo to fastapi org repo. PR [#1285](https://github.com/fastapi/full-stack-fastapi-template/pull/1285) by [@tiangolo](https://github.com/tiangolo).
-* π Add End-to-End Testing with Playwright to frontend `README.md`. PR [#1279](https://github.com/tiangolo/full-stack-fastapi-template/pull/1279) by [@alejsdev](https://github.com/alejsdev).
-* π Update release-notes.md. PR [#1220](https://github.com/tiangolo/full-stack-fastapi-template/pull/1220) by [@alejsdev](https://github.com/alejsdev).
-* βοΈ Update `README.md`. PR [#1205](https://github.com/tiangolo/full-stack-fastapi-template/pull/1205) by [@Craz1k0ek](https://github.com/Craz1k0ek).
-* βοΈ Fix Adminer URL in `deployment.md`. PR [#1194](https://github.com/tiangolo/full-stack-fastapi-template/pull/1194) by [@PhilippWu](https://github.com/PhilippWu).
-* π Add `Enabling Open User Registration` to backend docs. PR [#1191](https://github.com/tiangolo/full-stack-fastapi-template/pull/1191) by [@alejsdev](https://github.com/alejsdev).
-* π Update release-notes.md. PR [#1164](https://github.com/tiangolo/full-stack-fastapi-template/pull/1164) by [@alejsdev](https://github.com/alejsdev).
-* π Update `README.md`. PR [#716](https://github.com/tiangolo/full-stack-fastapi-template/pull/716) by [@alejsdev](https://github.com/alejsdev).
-* π Update instructions to clone for a private repo, including updates. PR [#1127](https://github.com/tiangolo/full-stack-fastapi-template/pull/1127) by [@tiangolo](https://github.com/tiangolo).
-* π Add docs about CI keys, LATEST_CHANGES and SMOKESHOW_AUTH_KEY. PR [#1126](https://github.com/tiangolo/full-stack-fastapi-template/pull/1126) by [@tiangolo](https://github.com/tiangolo).
-* βοΈ Fix file path in `backend/README.md` when not wanting to use migrations. PR [#1116](https://github.com/tiangolo/full-stack-fastapi-template/pull/1116) by [@leonlowitzki](https://github.com/leonlowitzki).
-* π Add documentation for pre-commit and code linting. PR [#718](https://github.com/tiangolo/full-stack-fastapi-template/pull/718) by [@estebanx64](https://github.com/estebanx64).
-* π Fix localhost URLs in `development.md`. PR [#1099](https://github.com/tiangolo/full-stack-fastapi-template/pull/1099) by [@efonte](https://github.com/efonte).
-* β Update header titles for consistency. PR [#708](https://github.com/tiangolo/full-stack-fastapi-template/pull/708) by [@codesmith-emmy](https://github.com/codesmith-emmy).
-* π Update `README.md`, dark mode screenshot position. PR [#706](https://github.com/tiangolo/full-stack-fastapi-template/pull/706) by [@alejsdev](https://github.com/alejsdev).
-
-### Internal
-
-* π§ Update deploy workflows to exclude the main repository. PR [#1284](https://github.com/tiangolo/full-stack-fastapi-template/pull/1284) by [@alejsdev](https://github.com/alejsdev).
-* π· Update issue-manager.yml GitHub Action permissions. PR [#1278](https://github.com/tiangolo/full-stack-fastapi-template/pull/1278) by [@tiangolo](https://github.com/tiangolo).
-* β¬οΈ Bump setuptools from 69.1.1 to 70.0.0 in /backend. PR [#1255](https://github.com/tiangolo/full-stack-fastapi-template/pull/1255) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* β¬οΈ Bump certifi from 2024.2.2 to 2024.7.4 in /backend. PR [#1250](https://github.com/tiangolo/full-stack-fastapi-template/pull/1250) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* β¬οΈ Bump urllib3 from 2.2.1 to 2.2.2 in /backend. PR [#1235](https://github.com/tiangolo/full-stack-fastapi-template/pull/1235) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* π§ Ignore `src/routeTree.gen.ts` in biome. PR [#1175](https://github.com/tiangolo/full-stack-fastapi-template/pull/1175) by [@patrick91](https://github.com/patrick91).
-* π· Update Smokeshow download artifact GitHub Action. PR [#1198](https://github.com/tiangolo/full-stack-fastapi-template/pull/1198) by [@tiangolo](https://github.com/tiangolo).
-* π§ Update Node.js version in `.nvmrc`. PR [#1192](https://github.com/tiangolo/full-stack-fastapi-template/pull/1192) by [@alejsdev](https://github.com/alejsdev).
-* π₯ Remove ESLint and Prettier from pre-commit config. PR [#1096](https://github.com/tiangolo/full-stack-fastapi-template/pull/1096) by [@alejsdev](https://github.com/alejsdev).
-* π§ Update mypy config to ignore .venv directories. PR [#1155](https://github.com/tiangolo/full-stack-fastapi-template/pull/1155) by [@tiangolo](https://github.com/tiangolo).
-* π¨ Enable `ARG001` to prevent unused arguments. PR [#1152](https://github.com/tiangolo/full-stack-fastapi-template/pull/1152) by [@patrick91](https://github.com/patrick91).
-* π₯ Remove isort configuration, since we use Ruff now. PR [#1144](https://github.com/tiangolo/full-stack-fastapi-template/pull/1144) by [@patrick91](https://github.com/patrick91).
-* π§ Update pre-commit config to exclude generated client folder. PR [#1150](https://github.com/tiangolo/full-stack-fastapi-template/pull/1150) by [@alejsdev](https://github.com/alejsdev).
-* π§ Change `.nvmrc` format. PR [#1148](https://github.com/tiangolo/full-stack-fastapi-template/pull/1148) by [@patrick91](https://github.com/patrick91).
-* π¨ Ignore alembic from ruff lint and format. PR [#1131](https://github.com/tiangolo/full-stack-fastapi-template/pull/1131) by [@estebanx64](https://github.com/estebanx64).
-* π§ Add GitHub templates for discussions and issues, and security policy. PR [#1105](https://github.com/tiangolo/full-stack-fastapi-template/pull/1105) by [@alejsdev](https://github.com/alejsdev).
-* β¬ Bump dawidd6/action-download-artifact from 3.1.2 to 3.1.4. PR [#1103](https://github.com/tiangolo/full-stack-fastapi-template/pull/1103) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* π§ Add Biome to pre-commit config. PR [#1098](https://github.com/tiangolo/full-stack-fastapi-template/pull/1098) by [@alejsdev](https://github.com/alejsdev).
-* π₯ Delete leftover celery file. PR [#727](https://github.com/tiangolo/full-stack-fastapi-template/pull/727) by [@dr-neptune](https://github.com/dr-neptune).
-* βοΈ Update pre-commit config with Prettier and ESLint. PR [#714](https://github.com/tiangolo/full-stack-fastapi-template/pull/714) by [@alejsdev](https://github.com/alejsdev).
-
-## 0.6.0
-
-Latest FastAPI, Pydantic, SQLModel π
-
-Brand new frontend with React, TS, Vite, Chakra UI, TanStack Query/Router, generated client/SDK π¨
-
-CI/CD - GitHub Actions π€
-
-Test cov > 90% β
-
-### Features
-
-* β¨ Adopt SQLModel, create models, start using it. PR [#559](https://github.com/tiangolo/full-stack-fastapi-template/pull/559) by [@tiangolo](https://github.com/tiangolo).
-* β¨ Upgrade items router with new SQLModel models, simplified logic, and new FastAPI Annotated dependencies. PR [#560](https://github.com/tiangolo/full-stack-fastapi-template/pull/560) by [@tiangolo](https://github.com/tiangolo).
-* β¨ Migrate from pgAdmin to Adminer. PR [#692](https://github.com/tiangolo/full-stack-fastapi-template/pull/692) by [@tiangolo](https://github.com/tiangolo).
-* β¨ Add support for setting `POSTGRES_PORT`. PR [#333](https://github.com/tiangolo/full-stack-fastapi-template/pull/333) by [@uepoch](https://github.com/uepoch).
-* β¬ Upgrade Flower version and command. PR [#447](https://github.com/tiangolo/full-stack-fastapi-template/pull/447) by [@maurob](https://github.com/maurob).
-* π¨ Improve styles. PR [#673](https://github.com/tiangolo/full-stack-fastapi-template/pull/673) by [@alejsdev](https://github.com/alejsdev).
-* π¨ Update theme. PR [#666](https://github.com/tiangolo/full-stack-fastapi-template/pull/666) by [@alejsdev](https://github.com/alejsdev).
-* π· Add continuous deployment and refactors needed for it. PR [#667](https://github.com/tiangolo/full-stack-fastapi-template/pull/667) by [@tiangolo](https://github.com/tiangolo).
-* β¨ Create endpoint to show password recovery email content and update email template. PR [#664](https://github.com/tiangolo/full-stack-fastapi-template/pull/664) by [@alejsdev](https://github.com/alejsdev).
-* π¨ Format with Prettier. PR [#646](https://github.com/tiangolo/full-stack-fastapi-template/pull/646) by [@alejsdev](https://github.com/alejsdev).
-* β
Add tests to raise coverage to at least 90% and fix recover password logic. PR [#632](https://github.com/tiangolo/full-stack-fastapi-template/pull/632) by [@estebanx64](https://github.com/estebanx64).
-* βοΈ Add Prettier and ESLint config with pre-commit. PR [#640](https://github.com/tiangolo/full-stack-fastapi-template/pull/640) by [@alejsdev](https://github.com/alejsdev).
-* π· Add coverage with Smokeshow to CI and badge. PR [#638](https://github.com/tiangolo/full-stack-fastapi-template/pull/638) by [@estebanx64](https://github.com/estebanx64).
-* β¨ Migrate to TanStack Query (React Query) and TanStack Router. PR [#637](https://github.com/tiangolo/full-stack-fastapi-template/pull/637) by [@alejsdev](https://github.com/alejsdev).
-* β
Add setup and teardown database for tests. PR [#626](https://github.com/tiangolo/full-stack-fastapi-template/pull/626) by [@estebanx64](https://github.com/estebanx64).
-* β¨ Update new-frontend client. PR [#625](https://github.com/tiangolo/full-stack-fastapi-template/pull/625) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add password reset functionality. PR [#624](https://github.com/tiangolo/full-stack-fastapi-template/pull/624) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add private/public routing. PR [#621](https://github.com/tiangolo/full-stack-fastapi-template/pull/621) by [@alejsdev](https://github.com/alejsdev).
-* π§ Add VS Code debug configs. PR [#620](https://github.com/tiangolo/full-stack-fastapi-template/pull/620) by [@tiangolo](https://github.com/tiangolo).
-* β¨ Add `Not Found` page. PR [#595](https://github.com/tiangolo/full-stack-fastapi-template/pull/595) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add new pages, components, panels, modals, and theme; refactor and improvements in existing components. PR [#593](https://github.com/tiangolo/full-stack-fastapi-template/pull/593) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Support delete own account and other tweaks. PR [#614](https://github.com/tiangolo/full-stack-fastapi-template/pull/614) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Restructure folders, allow editing of users/items, and implement other refactors and improvements. PR [#603](https://github.com/tiangolo/full-stack-fastapi-template/pull/603) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add Copier, migrate from Cookiecutter, in a way that supports using the project as is, forking or cloning it. PR [#612](https://github.com/tiangolo/full-stack-fastapi-template/pull/612) by [@tiangolo](https://github.com/tiangolo).
-* β Replace black, isort, flake8, autoflake with ruff and upgrade mypy. PR [#610](https://github.com/tiangolo/full-stack-fastapi-template/pull/610) by [@tiangolo](https://github.com/tiangolo).
-* β» Refactor items and services endpoints to return count and data, and add CI tests. PR [#599](https://github.com/tiangolo/full-stack-fastapi-template/pull/599) by [@estebanx64](https://github.com/estebanx64).
-* β¨ Add support for updating items and upgrade SQLModel to 0.0.16 (which supports model object updates). PR [#601](https://github.com/tiangolo/full-stack-fastapi-template/pull/601) by [@tiangolo](https://github.com/tiangolo).
-* β¨ Add dark mode to new-frontend and conditional sidebar items. PR [#600](https://github.com/tiangolo/full-stack-fastapi-template/pull/600) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Migrate to RouterProvider and other refactors . PR [#598](https://github.com/tiangolo/full-stack-fastapi-template/pull/598) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add delete_user; refactor delete_item. PR [#594](https://github.com/tiangolo/full-stack-fastapi-template/pull/594) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add state store to new frontend. PR [#592](https://github.com/tiangolo/full-stack-fastapi-template/pull/592) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add form validation to Admin, Items and Login. PR [#616](https://github.com/tiangolo/full-stack-fastapi-template/pull/616) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add Sidebar to new frontend. PR [#587](https://github.com/tiangolo/full-stack-fastapi-template/pull/587) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add Login to new frontend. PR [#585](https://github.com/tiangolo/full-stack-fastapi-template/pull/585) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Include schemas in generated frontend client. PR [#584](https://github.com/tiangolo/full-stack-fastapi-template/pull/584) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Regenerate frontend client with recent changes. PR [#575](https://github.com/tiangolo/full-stack-fastapi-template/pull/575) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Refactor API in `utils.py`. PR [#573](https://github.com/tiangolo/full-stack-fastapi-template/pull/573) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Update code for login API. PR [#571](https://github.com/tiangolo/full-stack-fastapi-template/pull/571) by [@tiangolo](https://github.com/tiangolo).
-* β¨ Add client in frontend and client generation. PR [#569](https://github.com/tiangolo/full-stack-fastapi-template/pull/569) by [@alejsdev](https://github.com/alejsdev).
-* π³ Set up Docker config for new-frontend. PR [#564](https://github.com/tiangolo/full-stack-fastapi-template/pull/564) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Set up new frontend with Vite, TypeScript and React. PR [#563](https://github.com/tiangolo/full-stack-fastapi-template/pull/563) by [@alejsdev](https://github.com/alejsdev).
-* π Add NodeJS version management and instructions. PR [#551](https://github.com/tiangolo/full-stack-fastapi-template/pull/551) by [@alejsdev](https://github.com/alejsdev).
-* Add consistent errors for env vars not set. PR [#200](https://github.com/tiangolo/full-stack-fastapi-template/pull/200).
-* Upgrade Traefik to version 2, keeping in sync with DockerSwarm.rocks. PR [#199](https://github.com/tiangolo/full-stack-fastapi-template/pull/199).
-* Run tests with `TestClient`. PR [#160](https://github.com/tiangolo/full-stack-fastapi-template/pull/160).
-
-### Fixes
-
-* π Fix copier to handle string vars with spaces in quotes. PR [#631](https://github.com/tiangolo/full-stack-fastapi-template/pull/631) by [@estebanx64](https://github.com/estebanx64).
-* π Fix allowing a user to update the email to the same email they already have. PR [#696](https://github.com/tiangolo/full-stack-fastapi-template/pull/696) by [@alejsdev](https://github.com/alejsdev).
-* π Set up Sentry only when used. PR [#671](https://github.com/tiangolo/full-stack-fastapi-template/pull/671) by [@tiangolo](https://github.com/tiangolo).
-* π₯ Remove unnecessary validation. PR [#662](https://github.com/tiangolo/full-stack-fastapi-template/pull/662) by [@alejsdev](https://github.com/alejsdev).
-* π Fix bug when editing own user. PR [#651](https://github.com/tiangolo/full-stack-fastapi-template/pull/651) by [@alejsdev](https://github.com/alejsdev).
-* π Add `onClose` to `SidebarItems`. PR [#589](https://github.com/tiangolo/full-stack-fastapi-template/pull/589) by [@alejsdev](https://github.com/alejsdev).
-* π Fix positional argument bug in `init_db.py`. PR [#562](https://github.com/tiangolo/full-stack-fastapi-template/pull/562) by [@alejsdev](https://github.com/alejsdev).
-* π Fix flower Docker image, pin version. PR [#396](https://github.com/tiangolo/full-stack-fastapi-template/pull/396) by [@sanggusti](https://github.com/sanggusti).
-* π Fix Celery worker command. PR [#443](https://github.com/tiangolo/full-stack-fastapi-template/pull/443) by [@bechtold](https://github.com/bechtold).
-* π Fix Poetry installation in Dockerfile and upgrade Python version and packages to fix Docker build. PR [#480](https://github.com/tiangolo/full-stack-fastapi-template/pull/480) by [@little7Li](https://github.com/little7Li).
-
-### Refactors
-
-* π§ Add missing dotenv variables. PR [#554](https://github.com/tiangolo/full-stack-fastapi-template/pull/554) by [@tiangolo](https://github.com/tiangolo).
-* βͺ Revert "βοΈ Add Prettier and ESLint config with pre-commit". PR [#644](https://github.com/tiangolo/full-stack-fastapi-template/pull/644) by [@alejsdev](https://github.com/alejsdev).
-* π Add .prettierignore and include client folder. PR [#648](https://github.com/tiangolo/full-stack-fastapi-template/pull/648) by [@alejsdev](https://github.com/alejsdev).
-* π·οΈ Add mypy to the GitHub Action for tests and fixed types in the whole project. PR [#655](https://github.com/tiangolo/full-stack-fastapi-template/pull/655) by [@estebanx64](https://github.com/estebanx64).
-* ποΈ Ensure the default values of "changethis" are not deployed. PR [#698](https://github.com/tiangolo/full-stack-fastapi-template/pull/698) by [@tiangolo](https://github.com/tiangolo).
-* β Revert "πΈ Rename Dashboard to Home and update screenshots". PR [#697](https://github.com/tiangolo/full-stack-fastapi-template/pull/697) by [@alejsdev](https://github.com/alejsdev).
-* πΈ Rename Dashboard to Home and update screenshots. PR [#693](https://github.com/tiangolo/full-stack-fastapi-template/pull/693) by [@alejsdev](https://github.com/alejsdev).
-* π Fixed items count when retrieving data for all items by user. PR [#695](https://github.com/tiangolo/full-stack-fastapi-template/pull/695) by [@estebanx64](https://github.com/estebanx64).
-* π₯ Remove Celery and Flower, they are currently not used nor recommended. PR [#694](https://github.com/tiangolo/full-stack-fastapi-template/pull/694) by [@tiangolo](https://github.com/tiangolo).
-* β
Add test for deleting user without privileges. PR [#690](https://github.com/tiangolo/full-stack-fastapi-template/pull/690) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Refactor user update. PR [#689](https://github.com/tiangolo/full-stack-fastapi-template/pull/689) by [@alejsdev](https://github.com/alejsdev).
-* π Add Poetry lock to git. PR [#685](https://github.com/tiangolo/full-stack-fastapi-template/pull/685) by [@tiangolo](https://github.com/tiangolo).
-* π¨ Adjust color and spacing. PR [#684](https://github.com/tiangolo/full-stack-fastapi-template/pull/684) by [@alejsdev](https://github.com/alejsdev).
-* π· Avoid creating unnecessary *.pyc files with PYTHONDONTWRITEBYTECODE=1. PR [#677](https://github.com/tiangolo/full-stack-fastapi-template/pull/677) by [@estebanx64](https://github.com/estebanx64).
-* π§ Add `SMTP_SSL` option for older SMTP servers. PR [#365](https://github.com/tiangolo/full-stack-fastapi-template/pull/365) by [@Metrea](https://github.com/Metrea).
-* β»οΈ Refactor logic to allow running pytest tests locally. PR [#683](https://github.com/tiangolo/full-stack-fastapi-template/pull/683) by [@tiangolo](https://github.com/tiangolo).
-* β» Update error messages. PR [#417](https://github.com/tiangolo/full-stack-fastapi-template/pull/417) by [@qu3vipon](https://github.com/qu3vipon).
-* π§ Add a default Flower password. PR [#682](https://github.com/tiangolo/full-stack-fastapi-template/pull/682) by [@tiangolo](https://github.com/tiangolo).
-* π§ Update VS Code debug config. PR [#676](https://github.com/tiangolo/full-stack-fastapi-template/pull/676) by [@tiangolo](https://github.com/tiangolo).
-* β»οΈ Refactor code structure for tests. PR [#674](https://github.com/tiangolo/full-stack-fastapi-template/pull/674) by [@tiangolo](https://github.com/tiangolo).
-* π§ Set TanStack Router devtools only in dev mode. PR [#668](https://github.com/tiangolo/full-stack-fastapi-template/pull/668) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Refactor email logic to allow re-using util functions for testing and development. PR [#663](https://github.com/tiangolo/full-stack-fastapi-template/pull/663) by [@tiangolo](https://github.com/tiangolo).
-* π¬ Improve Delete Account description and confirmation. PR [#661](https://github.com/tiangolo/full-stack-fastapi-template/pull/661) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Refactor email templates. PR [#659](https://github.com/tiangolo/full-stack-fastapi-template/pull/659) by [@alejsdev](https://github.com/alejsdev).
-* π Update deployment files and docs. PR [#660](https://github.com/tiangolo/full-stack-fastapi-template/pull/660) by [@tiangolo](https://github.com/tiangolo).
-* π₯ Remove unused schemas. PR [#656](https://github.com/tiangolo/full-stack-fastapi-template/pull/656) by [@alejsdev](https://github.com/alejsdev).
-* π₯ Remove old frontend. PR [#649](https://github.com/tiangolo/full-stack-fastapi-template/pull/649) by [@tiangolo](https://github.com/tiangolo).
-* β» Move project source files to top level from src, update Sentry dependency. PR [#630](https://github.com/tiangolo/full-stack-fastapi-template/pull/630) by [@estebanx64](https://github.com/estebanx64).
-* β» Refactor Python folder tree. PR [#629](https://github.com/tiangolo/full-stack-fastapi-template/pull/629) by [@estebanx64](https://github.com/estebanx64).
-* β»οΈ Refactor old CRUD utils and tests. PR [#622](https://github.com/tiangolo/full-stack-fastapi-template/pull/622) by [@alejsdev](https://github.com/alejsdev).
-* π§ Update .env to allow local debug for the backend. PR [#618](https://github.com/tiangolo/full-stack-fastapi-template/pull/618) by [@tiangolo](https://github.com/tiangolo).
-* β»οΈ Refactor and update CORS, remove trailing slash from new Pydantic v2. PR [#617](https://github.com/tiangolo/full-stack-fastapi-template/pull/617) by [@tiangolo](https://github.com/tiangolo).
-* π¨ Format files with pre-commit and Ruff. PR [#611](https://github.com/tiangolo/full-stack-fastapi-template/pull/611) by [@tiangolo](https://github.com/tiangolo).
-* π Refactor and simplify backend file structure. PR [#609](https://github.com/tiangolo/full-stack-fastapi-template/pull/609) by [@tiangolo](https://github.com/tiangolo).
-* π₯ Clean up old files no longer relevant. PR [#608](https://github.com/tiangolo/full-stack-fastapi-template/pull/608) by [@tiangolo](https://github.com/tiangolo).
-* β» Re-structure Docker Compose files, discard Docker Swarm specific logic. PR [#607](https://github.com/tiangolo/full-stack-fastapi-template/pull/607) by [@tiangolo](https://github.com/tiangolo).
-* β»οΈ Refactor update endpoints and regenerate client for new-frontend. PR [#602](https://github.com/tiangolo/full-stack-fastapi-template/pull/602) by [@alejsdev](https://github.com/alejsdev).
-* β¨ Add Layout to App. PR [#588](https://github.com/tiangolo/full-stack-fastapi-template/pull/588) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Re-enable user update path operations for frontend client generation. PR [#574](https://github.com/tiangolo/full-stack-fastapi-template/pull/574) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Remove type ignores and add `response_model`. PR [#572](https://github.com/tiangolo/full-stack-fastapi-template/pull/572) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Refactor Users API and dependencies. PR [#561](https://github.com/tiangolo/full-stack-fastapi-template/pull/561) by [@alejsdev](https://github.com/alejsdev).
-* β»οΈ Refactor frontend Docker build setup, use plain NodeJS, use custom Nginx config, fix build for old Vue. PR [#555](https://github.com/tiangolo/full-stack-fastapi-template/pull/555) by [@tiangolo](https://github.com/tiangolo).
-* β»οΈ Refactor project generation, discard cookiecutter, use plain git/clone/fork. PR [#553](https://github.com/tiangolo/full-stack-fastapi-template/pull/553) by [@tiangolo](https://github.com/tiangolo).
-* Refactor backend:
- * Simplify configs for tools and format to better support editor integration.
- * Add mypy configurations and plugins.
- * Add types to all the codebase.
- * Update types for SQLAlchemy models with plugin.
- * Update and refactor CRUD utils.
- * Refactor DB sessions to use dependencies with `yield`.
- * Refactor dependencies, security, CRUD, models, schemas, etc. To simplify code and improve autocompletion.
- * Change from PyJWT to Python-JOSE as it supports additional use cases.
- * Fix JWT tokens using user email/ID as the subject in `sub`.
- * PR [#158](https://github.com/tiangolo/full-stack-fastapi-template/pull/158).
-* Simplify `docker-compose.*.yml` files, refactor deployment to reduce config files. PR [#153](https://github.com/tiangolo/full-stack-fastapi-template/pull/153).
-* Simplify env var files, merge to a single `.env` file. PR [#151](https://github.com/tiangolo/full-stack-fastapi-template/pull/151).
-
-### Upgrades
-
-* π Upgrade Poetry lock dependencies. PR [#702](https://github.com/tiangolo/full-stack-fastapi-template/pull/702) by [@tiangolo](https://github.com/tiangolo).
-* β¬οΈ Upgrade Python version and dependencies. PR [#558](https://github.com/tiangolo/full-stack-fastapi-template/pull/558) by [@tiangolo](https://github.com/tiangolo).
-* β¬ Bump tiangolo/issue-manager from 0.2.0 to 0.5.0. PR [#591](https://github.com/tiangolo/full-stack-fastapi-template/pull/591) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* Bump follow-redirects from 1.15.3 to 1.15.5 in /frontend. PR [#654](https://github.com/tiangolo/full-stack-fastapi-template/pull/654) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* Bump vite from 5.0.4 to 5.0.12 in /frontend. PR [#653](https://github.com/tiangolo/full-stack-fastapi-template/pull/653) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* Bump fastapi from 0.104.1 to 0.109.1 in /backend. PR [#687](https://github.com/tiangolo/full-stack-fastapi-template/pull/687) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* Bump python-multipart from 0.0.6 to 0.0.7 in /backend. PR [#686](https://github.com/tiangolo/full-stack-fastapi-template/pull/686) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* β¬ Add `uvicorn[standard]` to include `watchgod` and `uvloop`. PR [#438](https://github.com/tiangolo/full-stack-fastapi-template/pull/438) by [@alonme](https://github.com/alonme).
-* β¬ Upgrade code to support pydantic V2. PR [#615](https://github.com/tiangolo/full-stack-fastapi-template/pull/615) by [@estebanx64](https://github.com/estebanx64).
-
-### Docs
-
-* π¦ Add dark mode to `README.md`. PR [#703](https://github.com/tiangolo/full-stack-fastapi-template/pull/703) by [@alejsdev](https://github.com/alejsdev).
-* π± Update GitHub image. PR [#701](https://github.com/tiangolo/full-stack-fastapi-template/pull/701) by [@tiangolo](https://github.com/tiangolo).
-* π± Add GitHub image. PR [#700](https://github.com/tiangolo/full-stack-fastapi-template/pull/700) by [@tiangolo](https://github.com/tiangolo).
-* π Rename project to Full Stack FastAPI Template. PR [#699](https://github.com/tiangolo/full-stack-fastapi-template/pull/699) by [@tiangolo](https://github.com/tiangolo).
-* π Update `README.md`. PR [#691](https://github.com/tiangolo/full-stack-fastapi-template/pull/691) by [@alejsdev](https://github.com/alejsdev).
-* β Fix typo in `development.md`. PR [#309](https://github.com/tiangolo/full-stack-fastapi-template/pull/309) by [@graue70](https://github.com/graue70).
-* π Add docs for wildcard domains. PR [#681](https://github.com/tiangolo/full-stack-fastapi-template/pull/681) by [@tiangolo](https://github.com/tiangolo).
-* π Add the required GitHub Actions secrets to docs. PR [#679](https://github.com/tiangolo/full-stack-fastapi-template/pull/679) by [@tiangolo](https://github.com/tiangolo).
-* π Update `README.md` and `deployment.md`. PR [#678](https://github.com/tiangolo/full-stack-fastapi-template/pull/678) by [@alejsdev](https://github.com/alejsdev).
-* π Update frontend `README.md`. PR [#675](https://github.com/tiangolo/full-stack-fastapi-template/pull/675) by [@alejsdev](https://github.com/alejsdev).
-* π Update deployment docs to use a different directory for traefik-public. PR [#670](https://github.com/tiangolo/full-stack-fastapi-template/pull/670) by [@tiangolo](https://github.com/tiangolo).
-* πΈ Add new screenshots . PR [#657](https://github.com/tiangolo/full-stack-fastapi-template/pull/657) by [@alejsdev](https://github.com/alejsdev).
-* π Refactor README into separate README.md files for backend, frontend, deployment, development. PR [#639](https://github.com/tiangolo/full-stack-fastapi-template/pull/639) by [@tiangolo](https://github.com/tiangolo).
-* π Update README. PR [#628](https://github.com/tiangolo/full-stack-fastapi-template/pull/628) by [@tiangolo](https://github.com/tiangolo).
-* π· Update GitHub Action latest-changes and move release notes to independent file. PR [#619](https://github.com/tiangolo/full-stack-fastapi-template/pull/619) by [@tiangolo](https://github.com/tiangolo).
-* π Update internal README and referred files. PR [#613](https://github.com/tiangolo/full-stack-fastapi-template/pull/613) by [@tiangolo](https://github.com/tiangolo).
-* π Update README with in construction notice. PR [#552](https://github.com/tiangolo/full-stack-fastapi-template/pull/552) by [@tiangolo](https://github.com/tiangolo).
-* Add docs about reporting test coverage in HTML. PR [#161](https://github.com/tiangolo/full-stack-fastapi-template/pull/161).
-* Add docs about removing the frontend, for an API-only app. PR [#156](https://github.com/tiangolo/full-stack-fastapi-template/pull/156).
-
-### Internal
-
-* π· Add Lint to GitHub Actions outside of tests. PR [#688](https://github.com/tiangolo/full-stack-fastapi-template/pull/688) by [@tiangolo](https://github.com/tiangolo).
-* β¬ Bump dawidd6/action-download-artifact from 2.28.0 to 3.1.2. PR [#643](https://github.com/tiangolo/full-stack-fastapi-template/pull/643) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* β¬ Bump actions/upload-artifact from 3 to 4. PR [#642](https://github.com/tiangolo/full-stack-fastapi-template/pull/642) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* β¬ Bump actions/setup-python from 4 to 5. PR [#641](https://github.com/tiangolo/full-stack-fastapi-template/pull/641) by [@dependabot[bot]](https://github.com/apps/dependabot).
-* π· Tweak test GitHub Action names. PR [#672](https://github.com/tiangolo/full-stack-fastapi-template/pull/672) by [@tiangolo](https://github.com/tiangolo).
-* π§ Add `.gitattributes` file to ensure LF endings for `.sh` files. PR [#658](https://github.com/tiangolo/full-stack-fastapi-template/pull/658) by [@estebanx64](https://github.com/estebanx64).
-* π Move new-frontend to frontend. PR [#652](https://github.com/tiangolo/full-stack-fastapi-template/pull/652) by [@alejsdev](https://github.com/alejsdev).
-* π§ Add script for ESLint. PR [#650](https://github.com/tiangolo/full-stack-fastapi-template/pull/650) by [@alejsdev](https://github.com/alejsdev).
-* βοΈ Add Prettier config. PR [#647](https://github.com/tiangolo/full-stack-fastapi-template/pull/647) by [@alejsdev](https://github.com/alejsdev).
-* π§ Update pre-commit config. PR [#645](https://github.com/tiangolo/full-stack-fastapi-template/pull/645) by [@alejsdev](https://github.com/alejsdev).
-* π· Add dependabot. PR [#547](https://github.com/tiangolo/full-stack-fastapi-template/pull/547) by [@tiangolo](https://github.com/tiangolo).
-* π· Fix latest-changes GitHub Action token, strike 2. PR [#546](https://github.com/tiangolo/full-stack-fastapi-template/pull/546) by [@tiangolo](https://github.com/tiangolo).
-* π· Fix latest-changes GitHub Action token config. PR [#545](https://github.com/tiangolo/full-stack-fastapi-template/pull/545) by [@tiangolo](https://github.com/tiangolo).
-* π· Add latest-changes GitHub Action. PR [#544](https://github.com/tiangolo/full-stack-fastapi-template/pull/544) by [@tiangolo](https://github.com/tiangolo).
-* Update issue-manager. PR [#211](https://github.com/tiangolo/full-stack-fastapi-template/pull/211).
-* Add [GitHub Sponsors](https://github.com/sponsors/tiangolo) button. PR [#201](https://github.com/tiangolo/full-stack-fastapi-template/pull/201).
-* Simplify scripts and development, update docs and configs. PR [#155](https://github.com/tiangolo/full-stack-fastapi-template/pull/155).
-
-## 0.5.0
-
-* Make the Traefik public network a fixed default of `traefik-public` as done in DockerSwarm.rocks, to simplify development and iteration of the project generator. PR [#150](https://github.com/tiangolo/full-stack-fastapi-template/pull/150).
-* Update to PostgreSQL 12. PR [#148](https://github.com/tiangolo/full-stack-fastapi-template/pull/148). by [@RCheese](https://github.com/RCheese).
-* Use Poetry for package management. Initial PR [#144](https://github.com/tiangolo/full-stack-fastapi-template/pull/144) by [@RCheese](https://github.com/RCheese).
-* Fix Windows line endings for shell scripts after project generation with Cookiecutter hooks. PR [#149](https://github.com/tiangolo/full-stack-fastapi-template/pull/149).
-* Upgrade Vue CLI to version 4. PR [#120](https://github.com/tiangolo/full-stack-fastapi-template/pull/120) by [@br3ndonland](https://github.com/br3ndonland).
-* Remove duplicate `login` tag. PR [#135](https://github.com/tiangolo/full-stack-fastapi-template/pull/135) by [@Nonameentered](https://github.com/Nonameentered).
-* Fix showing email in dashboard when there's no user's full name. PR [#129](https://github.com/tiangolo/full-stack-fastapi-template/pull/129) by [@rlonka](https://github.com/rlonka).
-* Format code with Black and Flake8. PR [#121](https://github.com/tiangolo/full-stack-fastapi-template/pull/121) by [@br3ndonland](https://github.com/br3ndonland).
-* Simplify SQLAlchemy Base class. PR [#117](https://github.com/tiangolo/full-stack-fastapi-template/pull/117) by [@airibarne](https://github.com/airibarne).
-* Update CRUD utils for users, handling password hashing. PR [#106](https://github.com/tiangolo/full-stack-fastapi-template/pull/106) by [@mocsar](https://github.com/mocsar).
-* Use `.` instead of `source` for interoperability. PR [#98](https://github.com/tiangolo/full-stack-fastapi-template/pull/98) by [@gucharbon](https://github.com/gucharbon).
-* Use Pydantic's `BaseSettings` for settings/configs and env vars. PR [#87](https://github.com/tiangolo/full-stack-fastapi-template/pull/87) by [@StephenBrown2](https://github.com/StephenBrown2).
-* Remove `package-lock.json` to let everyone lock their own versions (depending on OS, etc).
-* Simplify Traefik service labels PR [#139](https://github.com/tiangolo/full-stack-fastapi-template/pull/139).
-* Add email validation. PR [#40](https://github.com/tiangolo/full-stack-fastapi-template/pull/40) by [@kedod](https://github.com/kedod).
-* Fix typo in README. PR [#83](https://github.com/tiangolo/full-stack-fastapi-template/pull/83) by [@ashears](https://github.com/ashears).
-* Fix typo in README. PR [#80](https://github.com/tiangolo/full-stack-fastapi-template/pull/80) by [@abjoker](https://github.com/abjoker).
-* Fix function name `read_item` and response code. PR [#74](https://github.com/tiangolo/full-stack-fastapi-template/pull/74) by [@jcaguirre89](https://github.com/jcaguirre89).
-* Fix typo in comment. PR [#70](https://github.com/tiangolo/full-stack-fastapi-template/pull/70) by [@daniel-butler](https://github.com/daniel-butler).
-* Fix Flower Docker configuration. PR [#37](https://github.com/tiangolo/full-stack-fastapi-template/pull/37) by [@dmontagu](https://github.com/dmontagu).
-* Add new CRUD utils based on DB and Pydantic models. Initial PR [#23](https://github.com/tiangolo/full-stack-fastapi-template/pull/23) by [@ebreton](https://github.com/ebreton).
-* Add normal user testing Pytest fixture. PR [#20](https://github.com/tiangolo/full-stack-fastapi-template/pull/20) by [@ebreton](https://github.com/ebreton).
-
-## 0.4.0
-
-* Fix security on resetting a password. Receive token as body, not query. PR [#34](https://github.com/tiangolo/full-stack-fastapi-template/pull/34).
-
-* Fix security on resetting a password. Receive it as body, not query. PR [#33](https://github.com/tiangolo/full-stack-fastapi-template/pull/33) by [@dmontagu](https://github.com/dmontagu).
-
-* Fix SQLAlchemy class lookup on initialization. PR [#29](https://github.com/tiangolo/full-stack-fastapi-template/pull/29) by [@ebreton](https://github.com/ebreton).
-
-* Fix SQLAlchemy operation errors on database restart. PR [#32](https://github.com/tiangolo/full-stack-fastapi-template/pull/32) by [@ebreton](https://github.com/ebreton).
-
-* Fix locations of scripts in generated README. PR [#19](https://github.com/tiangolo/full-stack-fastapi-template/pull/19) by [@ebreton](https://github.com/ebreton).
-
-* Forward arguments from script to `pytest` inside container. PR [#17](https://github.com/tiangolo/full-stack-fastapi-template/pull/17) by [@ebreton](https://github.com/ebreton).
-
-* Update development scripts.
-
-* Read Alembic configs from env vars. PR #9 by @ebreton.
-
-* Create DB Item objects from all Pydantic model's fields.
-
-* Update Jupyter Lab installation and util script/environment variable for local development.
-
-## 0.3.0
-
-* PR #14:
- * Update CRUD utils to use types better.
- * Simplify Pydantic model names, from `UserInCreate` to `UserCreate`, etc.
- * Upgrade packages.
- * Add new generic "Items" models, crud utils, endpoints, and tests. To facilitate re-using them to create new functionality. As they are simple and generic (not like Users), it's easier to copy-paste and adapt them to each use case.
- * Update endpoints/*path operations* to simplify code and use new utilities, prefix and tags in `include_router`.
- * Update testing utils.
- * Update linting rules, relax vulture to reduce false positives.
- * Update migrations to include new Items.
- * Update project README.md with tips about how to start with backend.
-
-* Upgrade Python to 3.7 as Celery is now compatible too. PR #10 by @ebreton.
-
-## 0.2.2
-
-* Fix frontend hijacking /docs in development. Using latest https://github.com/tiangolo/node-frontend with custom Nginx configs in frontend. PR #6.
-
-## 0.2.1
-
-* Fix documentation for *path operation* to get user by ID. PR #4 by @mpclarkson in FastAPI.
-
-* Set `/start-reload.sh` as a command override for development by default.
-
-* Update generated README.
-
-## 0.2.0
-
-**PR #2**:
-
-* Simplify and update backend `Dockerfile`s.
-* Refactor and simplify backend code, improve naming, imports, modules and "namespaces".
-* Improve and simplify Vuex integration with TypeScript accessors.
-* Standardize frontend components layout, buttons order, etc.
-* Add local development scripts (to develop this project generator itself).
-* Add logs to startup modules to detect errors early.
-* Improve FastAPI dependency utilities, to simplify and reduce code (to require a superuser).
-
-## 0.1.2
-
-* Fix path operation to update self-user, set parameters as body payload.
-
-## 0.1.1
-
-Several bug fixes since initial publication, including:
-
-* Order of path operations for users.
-* Frontend sending login data in the correct format.
-* Add https://localhost variants to CORS.
diff --git a/scripts/build-push.sh b/scripts/build-push.sh
deleted file mode 100644
index 3fa3aa7e6b..0000000000
--- a/scripts/build-push.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /usr/bin/env sh
-
-# Exit in case of error
-set -e
-
-TAG=${TAG?Variable not set} \
-FRONTEND_ENV=${FRONTEND_ENV-production} \
-sh ./scripts/build.sh
-
-docker-compose -f docker-compose.yml push
diff --git a/scripts/build.sh b/scripts/build.sh
deleted file mode 100644
index 21528c538e..0000000000
--- a/scripts/build.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /usr/bin/env sh
-
-# Exit in case of error
-set -e
-
-TAG=${TAG?Variable not set} \
-FRONTEND_ENV=${FRONTEND_ENV-production} \
-docker-compose \
--f docker-compose.yml \
-build
diff --git a/scripts/deploy.sh b/scripts/deploy.sh
deleted file mode 100644
index 99faa96bf7..0000000000
--- a/scripts/deploy.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#! /usr/bin/env sh
-
-# Exit in case of error
-set -e
-
-DOMAIN=${DOMAIN?Variable not set} \
-STACK_NAME=${STACK_NAME?Variable not set} \
-TAG=${TAG?Variable not set} \
-docker-compose \
--f docker-compose.yml \
-config > docker-stack.yml
-
-docker-auto-labels docker-stack.yml
-
-docker stack deploy -c docker-stack.yml --with-registry-auth "${STACK_NAME?Variable not set}"
diff --git a/scripts/generate-client.sh b/scripts/generate-client.sh
deleted file mode 100644
index 1e76864d42..0000000000
--- a/scripts/generate-client.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#! /usr/bin/env bash
-
-set -e
-set -x
-
-cd backend
-python -c "import app.main; import json; print(json.dumps(app.main.app.openapi()))" > ../openapi.json
-cd ..
-mv openapi.json frontend/
-cd frontend
-npm run generate-client
-npx biome format --write ./src/client
diff --git a/scripts/test-local.sh b/scripts/test-local.sh
deleted file mode 100644
index 7f2fa9fbce..0000000000
--- a/scripts/test-local.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#! /usr/bin/env bash
-
-# Exit in case of error
-set -e
-
-docker-compose down -v --remove-orphans # Remove possibly previous broken stacks left hanging after an error
-
-if [ $(uname -s) = "Linux" ]; then
- echo "Remove __pycache__ files"
- sudo find . -type d -name __pycache__ -exec rm -r {} \+
-fi
-
-docker-compose build
-docker-compose up -d
-docker-compose exec -T backend bash scripts/tests-start.sh "$@"
diff --git a/scripts/test.sh b/scripts/test.sh
deleted file mode 100644
index 6dabef7471..0000000000
--- a/scripts/test.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#! /usr/bin/env sh
-
-# Exit in case of error
-set -e
-set -x
-
-docker compose build
-docker compose down -v --remove-orphans # Remove possibly previous broken stacks left hanging after an error
-docker compose up -d
-docker compose exec -T backend bash scripts/tests-start.sh "$@"
-docker compose down -v --remove-orphans
diff --git a/start.sh b/start.sh
new file mode 100755
index 0000000000..300eeaa4b2
--- /dev/null
+++ b/start.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+set -e # Exit on error
+
+# Function to clean up background processes
+cleanup() {
+ echo "Stopping backend and frontend..."
+ kill "$BACKEND_PID" "$FRONTEND_PID" 2>/dev/null
+ wait "$BACKEND_PID" "$FRONTEND_PID" 2>/dev/null
+ echo "All services stopped."
+ exit 0
+}
+
+# Trap SIGINT (Ctrl+C) and SIGTERM (for graceful shutdown)
+trap cleanup SIGINT SIGTERM
+
+# Start Backend
+cd backend || exit 1
+source .venv/bin/activate
+echo "Initializing database..."
+python -c "from app.core.db import init_db; init_db()"
+echo "Database initialization complete."
+uvicorn app.main:app --host 0.0.0.0 --port 8000 & # Run in background
+BACKEND_PID=$! # Store backend PID
+cd ..
+
+# Start Frontend
+cd frontend || exit 1
+npm run dev -- --host=0.0.0.0 --port=5173 & # Run in background
+FRONTEND_PID=$! # Store frontend PID
+cd ..
+
+# Display PIDs for reference
+echo "Backend PID: $BACKEND_PID"
+echo "Frontend PID: $FRONTEND_PID"
+
+# Wait for both processes
+wait "$BACKEND_PID" "$FRONTEND_PID"