From 7429782084cc3b5f4de4a51948d1d1ad78a1cca1 Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Fri, 21 Mar 2025 14:29:06 +0530 Subject: [PATCH 01/21] issue CI --- .github/workflows/add-to-project.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/add-to-project.yml b/.github/workflows/add-to-project.yml index dccea83f..473c8d09 100644 --- a/.github/workflows/add-to-project.yml +++ b/.github/workflows/add-to-project.yml @@ -1,7 +1,6 @@ name: Add to Project on: - pull_request_target: issues: types: - opened @@ -14,5 +13,5 @@ jobs: steps: - uses: actions/add-to-project@v1.0.2 with: - project-url: https://github.com/orgs/fastapi/projects/2 + project-url: https://github.com/orgs/ProjectTech4DevAI/projects/3 github-token: ${{ secrets.PROJECTS_TOKEN }} From 31f8432099e2d9d7a2b745ac392b354e92633590 Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Fri, 21 Mar 2025 19:51:50 +0530 Subject: [PATCH 02/21] first stab at continuous integration --- .github/workflows/add-to-project.yml | 17 --- .github/workflows/continuous_integration.yml | 54 ++++++++ .github/workflows/deploy-production.yml | 32 ----- .github/workflows/deploy-staging.yml | 32 ----- .github/workflows/generate-client.yml | 61 --------- .github/workflows/issue-manager.yml | 47 ------- .github/workflows/labeler.yml | 33 ----- .github/workflows/latest-changes.yml | 40 ------ .github/workflows/lint-backend.yml | 28 ---- .github/workflows/playwright.yml | 131 ------------------- .github/workflows/smokeshow.yml | 35 ----- .github/workflows/test-backend.yml | 41 ------ 12 files changed, 54 insertions(+), 497 deletions(-) delete mode 100644 .github/workflows/add-to-project.yml create mode 100644 .github/workflows/continuous_integration.yml delete mode 100644 .github/workflows/deploy-production.yml delete mode 100644 .github/workflows/deploy-staging.yml delete mode 100644 .github/workflows/generate-client.yml delete mode 100644 .github/workflows/issue-manager.yml delete mode 100644 .github/workflows/labeler.yml delete mode 100644 .github/workflows/latest-changes.yml delete mode 100644 .github/workflows/lint-backend.yml delete mode 100644 .github/workflows/playwright.yml delete mode 100644 .github/workflows/smokeshow.yml delete mode 100644 .github/workflows/test-backend.yml diff --git a/.github/workflows/add-to-project.yml b/.github/workflows/add-to-project.yml deleted file mode 100644 index 473c8d09..00000000 --- a/.github/workflows/add-to-project.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Add to Project - -on: - 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/ProjectTech4DevAI/projects/3 - github-token: ${{ secrets.PROJECTS_TOKEN }} diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml new file mode 100644 index 00000000..9843add8 --- /dev/null +++ b/.github/workflows/continuous_integration.yml @@ -0,0 +1,54 @@ +name: AI Platform CI + +on: + push: + branches: [staging] + pull_request: + branches: [staging] + +jobs: + checks: + runs-on: ubuntu-latest + services: + postgres: + image: postgres:16 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: ai_platform + ports: + - 5432:5432 + options: --health-cmd "pg_isready -U ddp" --health-interval 10s --health-timeout 5s --health-retries 5 + + strategy: + matrix: + python-version: ["3.13.2"] + redis-version: [6] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + version: "0.4.15" + enable-cache: true + + - name: Run tests + run: uv run bash scripts/tests-start.sh "Coverage for ${{ github.sha }}" + working-directory: backend + + - name: Upload coverage reports to codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + + - name: Check coverage percentage + run: | + coverage report --fail-under=70 diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml deleted file mode 100644 index a64d02a1..00000000 --- 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 26bd692f..00000000 --- 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 304363ce..00000000 --- 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 109ac0e9..00000000 --- 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 e8e58015..00000000 --- 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 607c5243..00000000 --- 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 a6e536bf..00000000 --- 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 5b13c586..00000000 --- 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 61fde520..00000000 --- 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 cbbb78de..00000000 --- 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 From 2c9ee076a9bafbab6cbf02a6e2358be17e03ff83 Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Fri, 21 Mar 2025 20:39:22 +0530 Subject: [PATCH 03/21] fixing testcases and migrations --- backend/app/alembic/env.py | 2 +- .../versions/0d84ca709cfd_add_organization.py | 64 +++++++++++++++++++ backend/app/api/routes/users.py | 2 +- backend/app/models/__init__.py | 2 + backend/app/tests/api/routes/test_users.py | 3 +- 5 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 backend/app/alembic/versions/0d84ca709cfd_add_organization.py diff --git a/backend/app/alembic/env.py b/backend/app/alembic/env.py index 65ad841d..331f40ac 100755 --- a/backend/app/alembic/env.py +++ b/backend/app/alembic/env.py @@ -2,7 +2,7 @@ from logging.config import fileConfig from alembic import context -from sqlmodel import SQLModel +from app.models import SQLModel from sqlalchemy import engine_from_config, pool # this is the Alembic Config object, which provides diff --git a/backend/app/alembic/versions/0d84ca709cfd_add_organization.py b/backend/app/alembic/versions/0d84ca709cfd_add_organization.py new file mode 100644 index 00000000..4ab77a08 --- /dev/null +++ b/backend/app/alembic/versions/0d84ca709cfd_add_organization.py @@ -0,0 +1,64 @@ +"""add_organization + +Revision ID: 0d84ca709cfd +Revises: 1a31ce608336 +Create Date: 2025-03-21 20:22:30.716746 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes + + +# revision identifiers, used by Alembic. +revision = '0d84ca709cfd' +down_revision = '1a31ce608336' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('organization', + sa.Column('name', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('is_active', sa.Boolean(), nullable=False), + sa.Column('id', sa.Integer(), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_organization_name'), 'organization', ['name'], unique=True) + op.create_table('project', + sa.Column('name', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('description', sqlmodel.sql.sqltypes.AutoString(length=500), nullable=True), + sa.Column('is_active', sa.Boolean(), nullable=False), + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('organization_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_project_name'), 'project', ['name'], unique=False) + op.create_index(op.f('ix_project_organization_id'), 'project', ['organization_id'], unique=False) + op.create_table('projectuser', + sa.Column('project_id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Uuid(), nullable=False), + sa.Column('is_admin', sa.Boolean(), nullable=False), + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.Column('is_deleted', sa.Boolean(), nullable=False), + sa.Column('deleted_at', sa.DateTime(), nullable=True), + sa.ForeignKeyConstraint(['project_id'], ['project.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('projectuser') + op.drop_index(op.f('ix_project_organization_id'), table_name='project') + op.drop_index(op.f('ix_project_name'), table_name='project') + op.drop_table('project') + op.drop_index(op.f('ix_organization_name'), table_name='organization') + op.drop_table('organization') + # ### end Alembic commands ### diff --git a/backend/app/api/routes/users.py b/backend/app/api/routes/users.py index 6edbfbeb..1d6a4f70 100644 --- a/backend/app/api/routes/users.py +++ b/backend/app/api/routes/users.py @@ -178,7 +178,7 @@ def read_user_by_id( dependencies=[Depends(get_current_active_superuser)], response_model=UserPublic, ) -def update_user( +def update_user_endpoint( *, session: SessionDep, user_id: uuid.UUID, diff --git a/backend/app/models/__init__.py b/backend/app/models/__init__.py index 75789039..cf39b3c1 100644 --- a/backend/app/models/__init__.py +++ b/backend/app/models/__init__.py @@ -1,3 +1,5 @@ +from sqlmodel import SQLModel + from .auth import Token, TokenPayload from .item import Item, ItemCreate, ItemPublic, ItemsPublic, ItemUpdate from .message import Message diff --git a/backend/app/tests/api/routes/test_users.py b/backend/app/tests/api/routes/test_users.py index ba9be654..3f52f757 100644 --- a/backend/app/tests/api/routes/test_users.py +++ b/backend/app/tests/api/routes/test_users.py @@ -110,7 +110,7 @@ def test_get_existing_user_permissions_error( headers=normal_user_token_headers, ) assert r.status_code == 403 - assert r.json() == {"detail": "The user doesn't have enough privileges"} + assert r.json()["detail"] == "The user doesn't have enough privileges" def test_create_user_existing_username( @@ -334,6 +334,7 @@ def test_update_user( headers=superuser_token_headers, json=data, ) + print(r) assert r.status_code == 200 updated_user = r.json() From 3da8b05b96c1c67131fcc48c64c5514050729088 Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Fri, 21 Mar 2025 21:58:37 +0530 Subject: [PATCH 04/21] syncing with master --- .../versions/0d84ca709cfd_add_organization.py | 64 ------------------- backend/app/tests/api/routes/test_users.py | 1 - 2 files changed, 65 deletions(-) delete mode 100644 backend/app/alembic/versions/0d84ca709cfd_add_organization.py diff --git a/backend/app/alembic/versions/0d84ca709cfd_add_organization.py b/backend/app/alembic/versions/0d84ca709cfd_add_organization.py deleted file mode 100644 index 4ab77a08..00000000 --- a/backend/app/alembic/versions/0d84ca709cfd_add_organization.py +++ /dev/null @@ -1,64 +0,0 @@ -"""add_organization - -Revision ID: 0d84ca709cfd -Revises: 1a31ce608336 -Create Date: 2025-03-21 20:22:30.716746 - -""" -from alembic import op -import sqlalchemy as sa -import sqlmodel.sql.sqltypes - - -# revision identifiers, used by Alembic. -revision = '0d84ca709cfd' -down_revision = '1a31ce608336' -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('organization', - sa.Column('name', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), - sa.Column('is_active', sa.Boolean(), nullable=False), - sa.Column('id', sa.Integer(), nullable=False), - sa.PrimaryKeyConstraint('id') - ) - op.create_index(op.f('ix_organization_name'), 'organization', ['name'], unique=True) - op.create_table('project', - sa.Column('name', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), - sa.Column('description', sqlmodel.sql.sqltypes.AutoString(length=500), nullable=True), - sa.Column('is_active', sa.Boolean(), nullable=False), - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('organization_id', sa.Integer(), nullable=False), - sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_index(op.f('ix_project_name'), 'project', ['name'], unique=False) - op.create_index(op.f('ix_project_organization_id'), 'project', ['organization_id'], unique=False) - op.create_table('projectuser', - sa.Column('project_id', sa.Integer(), nullable=False), - sa.Column('user_id', sa.Uuid(), nullable=False), - sa.Column('is_admin', sa.Boolean(), nullable=False), - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('created_at', sa.DateTime(), nullable=False), - sa.Column('updated_at', sa.DateTime(), nullable=False), - sa.Column('is_deleted', sa.Boolean(), nullable=False), - sa.Column('deleted_at', sa.DateTime(), nullable=True), - sa.ForeignKeyConstraint(['project_id'], ['project.id'], ondelete='CASCADE'), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ondelete='CASCADE'), - sa.PrimaryKeyConstraint('id') - ) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('projectuser') - op.drop_index(op.f('ix_project_organization_id'), table_name='project') - op.drop_index(op.f('ix_project_name'), table_name='project') - op.drop_table('project') - op.drop_index(op.f('ix_organization_name'), table_name='organization') - op.drop_table('organization') - # ### end Alembic commands ### diff --git a/backend/app/tests/api/routes/test_users.py b/backend/app/tests/api/routes/test_users.py index 3f52f757..68cb3ada 100644 --- a/backend/app/tests/api/routes/test_users.py +++ b/backend/app/tests/api/routes/test_users.py @@ -334,7 +334,6 @@ def test_update_user( headers=superuser_token_headers, json=data, ) - print(r) assert r.status_code == 200 updated_user = r.json() From 005fe7db2ee409cd646aa9dfffac2a956b4a783f Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 15:31:07 +0530 Subject: [PATCH 05/21] moving to python version 3.11.7 --- .github/workflows/continuous_integration.yml | 2 +- .github/workflows/test-docker-compose.yml | 26 -------------------- 2 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 .github/workflows/test-docker-compose.yml diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 9843add8..02eafe5b 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: - python-version: ["3.13.2"] + python-version: ["3.11.7"] redis-version: [6] steps: diff --git a/.github/workflows/test-docker-compose.yml b/.github/workflows/test-docker-compose.yml deleted file mode 100644 index 17792ede..00000000 --- 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 From 0166a99b583dcdb371c924ab38a264a3b6897986 Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 18:58:29 +0530 Subject: [PATCH 06/21] making copy of env --- .github/workflows/continuous_integration.yml | 3 +++ envSample | 19 +++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 02eafe5b..04868069 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -39,6 +39,9 @@ jobs: version: "0.4.15" enable-cache: true + - name: Making env file + run: cp envSample .env + - name: Run tests run: uv run bash scripts/tests-start.sh "Coverage for ${{ github.sha }}" working-directory: backend diff --git a/envSample b/envSample index 764b41b2..78324c25 100644 --- a/envSample +++ b/envSample @@ -1,29 +1,39 @@ # 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 +ENVIRONMENT=local PROJECT_NAME="AI Platform" STACK_NAME=ai-platform # Backend + BACKEND_CORS_ORIGINS="http://localhost:5173" SECRET_KEY=changethis FIRST_SUPERUSER=admin@example.com FIRST_SUPERUSER_PASSWORD=changethis # Emails + SMTP_HOST= SMTP_USER= SMTP_PASSWORD= @@ -33,6 +43,7 @@ SMTP_SSL=False SMTP_PORT=587 # Postgres + POSTGRES_SERVER=localhost POSTGRES_PORT=5432 POSTGRES_DB=app @@ -42,5 +53,9 @@ POSTGRES_PASSWORD=changethis SENTRY_DSN= # Configure these with your own Docker registry images + DOCKER_IMAGE_BACKEND=backend -DOCKER_IMAGE_FRONTEND=frontend \ No newline at end of file +DOCKER_IMAGE_FRONTEND=frontend + +CI="" +OPENAI_API_KEY="this_is_not_a_secret" From 30e3c7387c020bdf654bd9ef111bc73adb942bac Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 18:59:55 +0530 Subject: [PATCH 07/21] updating env --- envSample | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/envSample b/envSample index 78324c25..fcb50611 100644 --- a/envSample +++ b/envSample @@ -46,9 +46,9 @@ SMTP_PORT=587 POSTGRES_SERVER=localhost POSTGRES_PORT=5432 -POSTGRES_DB=app +POSTGRES_DB=ai_platform POSTGRES_USER=postgres -POSTGRES_PASSWORD=changethis +POSTGRES_PASSWORD=postgres SENTRY_DSN= From 995f8e24eabf68189d301907573b81c9fa7de128 Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:02:37 +0530 Subject: [PATCH 08/21] added migrations --- .github/workflows/continuous_integration.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 04868069..9000e96c 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -18,7 +18,7 @@ jobs: POSTGRES_DB: ai_platform ports: - 5432:5432 - options: --health-cmd "pg_isready -U ddp" --health-interval 10s --health-timeout 5s --health-retries 5 + options: --health-cmd "pg_isready -U ai_platform" --health-interval 10s --health-timeout 5s --health-retries 5 strategy: matrix: @@ -42,6 +42,10 @@ jobs: - name: Making env file run: cp envSample .env + - name: Run migrations + run: alembic upgrade head + working-directory: backend + - name: Run tests run: uv run bash scripts/tests-start.sh "Coverage for ${{ github.sha }}" working-directory: backend From 341cb1af4a36694d8318f5eb0981cf50707461ad Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:04:56 +0530 Subject: [PATCH 09/21] added uv sync --- .github/workflows/continuous_integration.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 9000e96c..563b7117 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -39,6 +39,9 @@ jobs: version: "0.4.15" enable-cache: true + - name: Install dependencies + run: uv sync + - name: Making env file run: cp envSample .env From 2c67bee9f52f83ec75c1e2a2e471184d9ced9b37 Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:06:17 +0530 Subject: [PATCH 10/21] updating working directory --- .github/workflows/continuous_integration.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 563b7117..fd640cb4 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -33,6 +33,9 @@ jobs: with: python-version: ${{ matrix.python-version }} + - name: Making env file + run: cp envSample .env + - name: Install uv uses: astral-sh/setup-uv@v5 with: @@ -41,9 +44,7 @@ jobs: - name: Install dependencies run: uv sync - - - name: Making env file - run: cp envSample .env + working-directory: backend - name: Run migrations run: alembic upgrade head From 0345461d3efcf33461c0ceeb3847800f80776dbd Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:13:37 +0530 Subject: [PATCH 11/21] added step to activate env --- .github/workflows/continuous_integration.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index fd640cb4..64e0aabe 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -46,9 +46,10 @@ jobs: run: uv sync working-directory: backend - - name: Run migrations - run: alembic upgrade head - working-directory: backend + - name: Activate virtual environment and run Alembic migrations + run: | + source .venv/bin/activate + alembic upgrade head - name: Run tests run: uv run bash scripts/tests-start.sh "Coverage for ${{ github.sha }}" From de3730d2775c397eafcc10f9f788e856b9d69d5e Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:15:25 +0530 Subject: [PATCH 12/21] updating working directory --- .github/workflows/continuous_integration.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 64e0aabe..aa008ac9 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -50,6 +50,7 @@ jobs: run: | source .venv/bin/activate alembic upgrade head + working-directory: backend - name: Run tests run: uv run bash scripts/tests-start.sh "Coverage for ${{ github.sha }}" From d66241517d0fa679d39986aa744047c2292f1371 Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:18:25 +0530 Subject: [PATCH 13/21] updating working directory for codecov upload --- .github/workflows/continuous_integration.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index aa008ac9..52e89089 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -61,6 +61,7 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: true + working-directory: backend - name: Check coverage percentage run: | From 8c3dc44e472a8db2e5f5364b99318560014f2be4 Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:28:00 +0530 Subject: [PATCH 14/21] updating script to upload to codecov --- backend/scripts/test.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/backend/scripts/test.sh b/backend/scripts/test.sh index df23f702..8355f8e1 100755 --- a/backend/scripts/test.sh +++ b/backend/scripts/test.sh @@ -1,8 +1,15 @@ -#!/usr/bin/env bash - +#!/bin/bash set -e set -x +# Run tests with coverage tracking coverage run --source=app -m pytest + +# Generate a human-readable coverage report in the terminal coverage report --show-missing + +# Generate an HTML report for local viewing coverage html --title "${@-coverage}" + +# Generate the XML report for Codecov +coverage xml \ No newline at end of file From 742eb747727b38ba744207c39781df41f10676d7 Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:29:52 +0530 Subject: [PATCH 15/21] remove working directory --- .github/workflows/continuous_integration.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 52e89089..aa008ac9 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -61,7 +61,6 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: true - working-directory: backend - name: Check coverage percentage run: | From 01c682955e128484eb12970f3afddea498b96cc2 Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:32:12 +0530 Subject: [PATCH 16/21] added working directory for % check --- .github/workflows/continuous_integration.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index aa008ac9..f04de320 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -65,3 +65,4 @@ jobs: - name: Check coverage percentage run: | coverage report --fail-under=70 + working-directory: backend From 30d262bfe0251d37b8723532f929b23d2f5f194e Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:35:51 +0530 Subject: [PATCH 17/21] clenaup --- .github/workflows/continuous_integration.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index f04de320..ed8a3a5e 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -63,6 +63,5 @@ jobs: fail_ci_if_error: true - name: Check coverage percentage - run: | - coverage report --fail-under=70 + run: coverage report --fail-under=70 working-directory: backend From 4603eacfe42c7ba810f3278dc406403a7c0fffe9 Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:37:53 +0530 Subject: [PATCH 18/21] cleanup --- .github/workflows/continuous_integration.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index ed8a3a5e..732b40e9 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -63,5 +63,6 @@ jobs: fail_ci_if_error: true - name: Check coverage percentage - run: coverage report --fail-under=70 - working-directory: backend + run: | + cd backend + coverage report --fail-under=70 From 5811daa044ea8759cc650c6203902ec212beabca Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:44:53 +0530 Subject: [PATCH 19/21] activating env --- .github/workflows/continuous_integration.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 732b40e9..18ecffce 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -18,7 +18,7 @@ jobs: POSTGRES_DB: ai_platform ports: - 5432:5432 - options: --health-cmd "pg_isready -U ai_platform" --health-interval 10s --health-timeout 5s --health-retries 5 + options: --health-cmd "pg_isready -U postgres" --health-interval 10s --health-timeout 5s --health-retries 5 strategy: matrix: @@ -64,5 +64,6 @@ jobs: - name: Check coverage percentage run: | - cd backend + source .venv/bin/activate coverage report --fail-under=70 + working-directory: backend From 3f38e4edb725afbc841e426d25cb9e83842d2857 Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:49:10 +0530 Subject: [PATCH 20/21] update the issue template --- .github/PULL_REQUEST_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 51e01133..8b548a42 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,13 +1,13 @@ ## Summary Target issue is #_PLEASE_TYPE_ISSUE_NUMBER_ - Explain the **motivation** for making this change. What existing problem does the pull request solve? +Explain the **motivation** for making this change. What existing problem does the pull request solve? ## Checklist Before submitting a pull request, please ensure that you mark these task. -- [ ] Ran `poetry run uvicorn src.app.main:app --reload` in the repository root and test. +- [ ] Ran `fastapi run --reload app/main.py` or `docker compose up` in the repository root and test. - [ ] If you've fixed a bug or added code that is tested and has test cases. ## Notes From 6d7d86975cc80f2193d13ceb9cca0377a525b7fe Mon Sep 17 00:00:00 2001 From: Akhilesh Negi Date: Mon, 24 Mar 2025 19:50:49 +0530 Subject: [PATCH 21/21] update readme and env file --- envSample => .env.example | 0 .github/workflows/continuous_integration.yml | 2 +- README.md | 8 ++++---- 3 files changed, 5 insertions(+), 5 deletions(-) rename envSample => .env.example (100%) diff --git a/envSample b/.env.example similarity index 100% rename from envSample rename to .env.example diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 18ecffce..0d1d2e94 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -34,7 +34,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Making env file - run: cp envSample .env + run: cp .env.example .env - name: Install uv uses: astral-sh/setup-uv@v5 diff --git a/README.md b/README.md index 701bb0a3..57cf5af3 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ You can **just fork or clone** this repository and use it as is. Create env file using example file ```bash -cp envSample .env +cp .env.example .env ``` You can then update configs in the `.env` files to customize your configurations. @@ -26,7 +26,8 @@ Before deploying it, make sure you change at least the values for: - `SECRET_KEY` - `FIRST_SUPERUSER_PASSWORD` - `POSTGRES_PASSWORD` -```bash + +````bash ### Generate Secret Keys @@ -36,7 +37,7 @@ You have to change them with a secret key, to generate secret keys you can run t ```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. @@ -62,7 +63,6 @@ or by visiting: http://[your-domain]:8000/api/v1/utils/health-check/ in the brow Backend docs: [backend/README.md](./backend/README.md). - ## Deployment Deployment docs: [deployment.md](./deployment.md).