Skip to content

feat(migrations): implement Alembic for database migrations (#2)#563

Merged
nanotaboada merged 10 commits intomasterfrom
feat/2-implement-alembic-database-migrations
Apr 10, 2026
Merged

feat(migrations): implement Alembic for database migrations (#2)#563
nanotaboada merged 10 commits intomasterfrom
feat/2-implement-alembic-database-migrations

Conversation

@nanotaboada
Copy link
Copy Markdown
Owner

@nanotaboada nanotaboada commented Apr 9, 2026

Summary

  • Adds Alembic with async SQLAlchemy support (env.py uses asyncio.run() via thread executor, render_as_batch=True for SQLite/PostgreSQL compatibility)
  • Three migrations: 001 creates the players table, 002 seeds 11 Starting XI players, 003 seeds 15 Substitute players — all using deterministic UUID v5 values; each independently reversible by UUID
  • alembic upgrade head runs automatically at app startup via the lifespan handler
  • storage/players-sqlite3.db removed from git; *.db added to .gitignore; storage/ directory deleted
  • Docker updated: removed COPY storage/ ./hold/ and hold→volume seed logic from entrypoint.sh; added COPY alembic/ and alembic.ini; compose.yaml switches from STORAGE_PATH to DATABASE_URL
  • alembic==1.18.4 and asyncpg==0.31.0 added to dependencies

Test plan

  • All 22 existing tests pass (uv run pytest)
  • Coverage ≥ 80% (uv run pytest --cov=./ --cov-report=term --cov-fail-under=80)
  • uv run alembic upgrade head applies all three migrations on a fresh DB
  • uv run alembic downgrade -1 removes only substitutes; re-upgrade restores them
  • docker compose up starts cleanly; migrations applied on first boot; DB persists across restarts via the storage volume
  • docker compose down -v followed by docker compose up re-applies migrations from scratch

🤖 Generated with Claude Code


This change is Reviewable

Summary by CodeRabbit

  • New Features

    • App now runs migrations at startup, seeds the player DB (initial roster), and supports local SQLite or remote DBs via a connection URL; runtime now uses a production web server.
  • Chores

    • Container startup simplified to run migrations instead of copying a pre-seeded DB; repository no longer tracks the DB file and now ignores *.db.
  • Documentation

    • Updated docs and changelog with migration-based workflow and developer guidance.
  • Tests

    • Added integration tests covering migration downgrade/upgrade behavior.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

Warning

Rate limit exceeded

@nanotaboada has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 34 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 3 minutes and 34 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7afc78de-8a84-48b9-b5d6-8bbf1fb8c101

📥 Commits

Reviewing files that changed from the base of the PR and between ec97c95 and c9a01d1.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • gunicorn.conf.py
  • tests/test_migrations.py

Walkthrough

Adds async Alembic migration infrastructure with three migrations (create players table, seed starting XI, seed substitutes); moves migration execution to container/Gunicorn startup and entrypoint; removes pre-seeded DB/seed scripts; prefers DATABASE_URL with STORAGE_PATH fallback; updates Docker, tests, dependencies, and docs.

Changes

Cohort / File(s) Summary
Alembic configs & templates
alembic.ini, alembic/README, alembic/script.py.mako, alembic/env.py
Add Alembic config, README, revision template, and async-aware env.py supporting offline/online runs and render_as_batch=True.
Migrations
alembic/versions/001_create_players_table.py, alembic/versions/002_seed_starting11.py, alembic/versions/003_seed_substitutes.py
Add three reversible migrations: create players table and deterministically insert Starting XI and Substitutes (UUIDv5 IDs); each provides targeted downgrade() deletions.
Container & startup
scripts/entrypoint.sh, Dockerfile, compose.yaml, gunicorn.conf.py
Remove image-bundled DB copy and seed-script flow; copy Alembic assets into image; switch runtime to Gunicorn with on_starting Alembic upgrade; compose supplies DATABASE_URL instead of STORAGE_PATH.
Database connection code
databases/player_database.py
Add get_database_url(); derive DATABASE_URL from env with SQLite fallback; apply SQLite-specific connect_args only when URL is SQLite.
Tests & CI
tests/conftest.py, tests/test_migrations.py, codecov.yaml
Apply migrations before tests via session fixture; add migration downgrade tests; exclude alembic/env.py from coverage.
Docs, ADRs & metadata
CHANGELOG.md, README.md, .github/copilot-instructions.md, docs/adr/*, pyproject.toml, .gitignore
Document Alembic adoption and new workflows; add deps (alembic, asyncpg, gunicorn) to pyproject.toml; add *.db to .gitignore; add ADR 0010 and update related ADRs.
Application entrypoint change
main.py
Remove prior lifespan migration messaging and update docstring/log indicating migrations are applied by entrypoint/Gunicorn.

Sequence Diagram

sequenceDiagram
    participant Entrypoint as Entrypoint Script
    participant Gunicorn as Gunicorn Master
    participant Alembic as Alembic CLI/Config
    participant Engine as Async DB Engine
    participant DB as Database (SQLite/Postgres)
    participant App as FastAPI Worker

    Entrypoint->>Gunicorn: exec gunicorn (reads config)
    Gunicorn->>Alembic: on_starting -> run `alembic upgrade head`
    Alembic->>Engine: create async engine (pool.NullPool)
    Engine->>DB: open connection / begin transaction
    Alembic->>DB: apply migrations (001 → 002 → 003)
    Engine->>DB: commit / close connection
    Alembic-->>Gunicorn: migrations complete
    Gunicorn->>App: fork workers (App starts serving)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 1 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 52.94% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The PR title follows Conventional Commits format with 'feat(migrations):' prefix, is descriptive and specific about implementing Alembic, and is 64 characters (well under the 80-character limit).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/2-implement-alembic-database-migrations
  • 🛠️ sync documentation: Commit on current branch
  • 🛠️ sync documentation: Create PR
  • 🛠️ enforce http error handling: Commit on current branch
  • 🛠️ enforce http error handling: Create PR
  • 🛠️ idiomatic review: Commit on current branch
  • 🛠️ idiomatic review: Create PR
  • 🛠️ verify api contract: Commit on current branch
  • 🛠️ verify api contract: Create PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (9151eee) to head (c9a01d1).
⚠️ Report is 11 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##            master      #563   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            3         7    +4     
  Lines          114       172   +58     
=========================================
+ Hits           114       172   +58     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
alembic/env.py (1)

25-27: Consider extracting shared DATABASE_URL logic.

The fallback logic for constructing DATABASE_URL is duplicated between this file and databases/player_database.py (lines 22-27). While they're currently identical, this could drift over time.

You could extract this to a shared utility, though the duplication is acceptable given Alembic's standalone execution requirements.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@alembic/env.py` around lines 25 - 27, The duplicated DATABASE_URL
construction (_storage_path, _default_url, database_url) should be extracted
into a single helper function (e.g., get_database_url or build_database_url)
that encapsulates reading STORAGE_PATH and DATABASE_URL and returning the final
URL; update both places that define _storage_path/_default_url/database_url to
call that helper (replace the duplicated logic in functions where these symbols
appear) so the behavior is centralized and future drift is prevented while
keeping Alembic-compatible import patterns (make the helper import-safe for
standalone execution).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@main.py`:
- Around line 39-41: The lifespan() hook currently calls _apply_migrations via
loop.run_in_executor (logger.info + await loop.run_in_executor(None,
_apply_migrations)), which will run once per FastAPI process and cause
concurrent Alembic upgrades; remove this direct call from lifespan() and either
(A) move invocation of _apply_migrations out of app startup into a one-shot
initialization step (entrypoint script, deployment job, or init container) or
(B) guard the migration function by implementing a DB-backed lock around
_apply_migrations (e.g., an advisory/locking table or transactional lock) so
only one process executes migrations; update any logging (logger.info) to
reflect the chosen approach and keep function name _apply_migrations as the
guarded/moved target.
- Around line 25-27: The call in _apply_migrations uses Config("alembic.ini")
which is cwd-dependent; change it to resolve alembic.ini relative to main.py so
migrations work regardless of working directory: compute the package file
location (e.g. Path(__file__).resolve().parent / "alembic.ini") and pass its
string path into Config, ensuring any required import (pathlib.Path) is added
and that the function _apply_migrations still calls command.upgrade(alembic_cfg,
"head") with the updated Config instance.

---

Nitpick comments:
In `@alembic/env.py`:
- Around line 25-27: The duplicated DATABASE_URL construction (_storage_path,
_default_url, database_url) should be extracted into a single helper function
(e.g., get_database_url or build_database_url) that encapsulates reading
STORAGE_PATH and DATABASE_URL and returning the final URL; update both places
that define _storage_path/_default_url/database_url to call that helper (replace
the duplicated logic in functions where these symbols appear) so the behavior is
centralized and future drift is prevented while keeping Alembic-compatible
import patterns (make the helper import-safe for standalone execution).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a79a3a98-8511-450d-aac6-e3df3f0c7465

📥 Commits

Reviewing files that changed from the base of the PR and between 9151eee and 3b645ab.

⛔ Files ignored due to path filters (2)
  • storage/players-sqlite3.db is excluded by !**/*.db, !**/storage/**, !**/*.db
  • uv.lock is excluded by !**/*.lock, !**/uv.lock
📒 Files selected for processing (15)
  • .gitignore
  • CHANGELOG.md
  • Dockerfile
  • alembic.ini
  • alembic/README
  • alembic/env.py
  • alembic/script.py.mako
  • alembic/versions/001_create_players_table.py
  • alembic/versions/002_seed_starting11.py
  • alembic/versions/003_seed_substitutes.py
  • compose.yaml
  • databases/player_database.py
  • main.py
  • pyproject.toml
  • scripts/entrypoint.sh

nanotaboada and others added 5 commits April 9, 2026 18:43
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…#2)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (4)
alembic/env.py (2)

49-56: Consider adding a brief docstring to do_run_migrations.

While this is a standard Alembic helper pattern, a one-line docstring would improve readability and silence the static analysis hint.

Suggested fix
 def do_run_migrations(connection: Connection) -> None:
+    """Configure Alembic context and run migrations within a transaction."""
     context.configure(
         connection=connection,
         target_metadata=target_metadata,
         render_as_batch=True,
     )
     with context.begin_transaction():
         context.run_migrations()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@alembic/env.py` around lines 49 - 56, Add a one-line docstring to the
do_run_migrations function describing its purpose (e.g., "Run Alembic migrations
using the provided DB connection") to improve readability and satisfy static
analysis; place it immediately after the def do_run_migrations(connection:
Connection) -> None: line so the function now has a concise explanatory
docstring.

59-67: Consider adding a brief docstring to run_async_migrations.

Suggested fix
 async def run_async_migrations() -> None:
+    """Create async engine, connect, and run migrations synchronously."""
     connectable = async_engine_from_config(
         config.get_section(config.config_ini_section, {}),
         prefix="sqlalchemy.",
         poolclass=pool.NullPool,
     )
     async with connectable.connect() as connection:
         await connection.run_sync(do_run_migrations)
     await connectable.dispose()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@alembic/env.py` around lines 59 - 67, Add a concise docstring to the async
function run_async_migrations describing its purpose (run Alembic migrations
against an async SQLAlchemy engine built from the alembic config), its behavior
(creates async engine via async_engine_from_config, opens an async connection
and calls do_run_migrations with connection.run_sync, then disposes the engine),
and the return type (None); place it immediately under the def
run_async_migrations() line so readers and tools can understand intent and side
effects.
tests/test_migrations.py (1)

24-24: Add return type hints to test functions.

Per coding guidelines, type hints are required everywhere.

Suggested fix
-def test_migration_downgrade_003_removes_substitutes_only():
+def test_migration_downgrade_003_removes_substitutes_only() -> None:
...
-def test_migration_downgrade_002_removes_starting11_only():
+def test_migration_downgrade_002_removes_starting11_only() -> None:
...
-def test_migration_downgrade_001_drops_players_table():
+def test_migration_downgrade_001_drops_players_table() -> None:

Also applies to: 39-39, 52-52

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_migrations.py` at line 24, Add missing return type annotations to
the test functions (e.g., test_migration_downgrade_003_removes_substitutes_only
and the other test functions at the indicated locations) so they follow project
typing guidelines; update each test function signature to include -> None (e.g.,
def test_migration_downgrade_003_removes_substitutes_only() -> None:) and run
the test/type checker to ensure no other typing issues remain.
tests/conftest.py (1)

18-21: Add return type hint to the fixture.

Per coding guidelines, type hints are required everywhere. The fixture should include -> None.

Suggested fix
 `@pytest.fixture`(scope="session", autouse=True)
-def apply_migrations():
+def apply_migrations() -> None:
     """Apply Alembic migrations once before the test session starts."""
     command.upgrade(ALEMBIC_CONFIG, "head")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/conftest.py` around lines 18 - 21, The apply_migrations pytest fixture
is missing a return type hint; update the function signature of apply_migrations
(the pytest.fixture that calls command.upgrade with ALEMBIC_CONFIG) to include a
-> None return type. Ensure the annotation is added to the def
apply_migrations(...) line and keep the fixture behavior (calling
command.upgrade(ALEMBIC_CONFIG, "head")) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/test_migrations.py`:
- Around line 52-64: The test test_migration_downgrade_001_drops_players_table
currently performs the assertion after command.upgrade, so move the assertion
that the players table is gone to immediately after you fetch the `table` value
following command.downgrade(ALEMBIC_CONFIG, "base") (i.e., assert `table is
None` before calling command.upgrade), or alternatively re-query the DB after
downgrade and then assert; ensure references to `command.downgrade`, the `table`
variable, and `command.upgrade` are updated accordingly so the test verifies the
downgrade result before performing the upgrade.
- Around line 39-49: The test
test_migration_downgrade_002_removes_starting11_only currently performs its
assertion after calling command.upgrade, so move the assertion checking total ==
0 to immediately after fetching/closing the DB connection (right after
conn.close() or immediately after computing total) and before calling
command.upgrade(ALEMBIC_CONFIG, "head"); keep the rest of the flow
(command.downgrade and command.upgrade) unchanged and reference the existing
variables command, ALEMBIC_CONFIG, total, conn, and DB_PATH to locate the
change.
- Around line 24-36: Move the assertions that check the downgraded state so they
run immediately after calling command.downgrade and before command.upgrade in
test_migration_downgrade_003_removes_substitutes_only; specifically, after
obtaining total and subs from the DB (the variables computed after
command.downgrade), assert total == 11 and subs == 0, then call
command.upgrade(ALEMBIC_CONFIG, "head") to restore state.
- Line 21: The test's DB_PATH computation is brittle because it assumes
DATABASE_URL is an SQLite URL; update the logic around DB_PATH/DATABASE_URL in
tests/test_migrations.py to detect the scheme and only extract a filesystem path
for sqlite URLs (e.g., check that DATABASE_URL starts with "sqlite+" or parse
the scheme), otherwise handle non-sqlite URLs explicitly (raise a clear error,
skip sqlite-specific tests, or use urllib.parse to extract path when scheme ==
"sqlite+aiosqlite"). Locate the DB_PATH assignment and replace the blind replace
with a guarded parse that uses urllib.parse (or an explicit startswith check) so
PostgreSQL or other DB URLs do not produce an invalid path.

---

Nitpick comments:
In `@alembic/env.py`:
- Around line 49-56: Add a one-line docstring to the do_run_migrations function
describing its purpose (e.g., "Run Alembic migrations using the provided DB
connection") to improve readability and satisfy static analysis; place it
immediately after the def do_run_migrations(connection: Connection) -> None:
line so the function now has a concise explanatory docstring.
- Around line 59-67: Add a concise docstring to the async function
run_async_migrations describing its purpose (run Alembic migrations against an
async SQLAlchemy engine built from the alembic config), its behavior (creates
async engine via async_engine_from_config, opens an async connection and calls
do_run_migrations with connection.run_sync, then disposes the engine), and the
return type (None); place it immediately under the def run_async_migrations()
line so readers and tools can understand intent and side effects.

In `@tests/conftest.py`:
- Around line 18-21: The apply_migrations pytest fixture is missing a return
type hint; update the function signature of apply_migrations (the pytest.fixture
that calls command.upgrade with ALEMBIC_CONFIG) to include a -> None return
type. Ensure the annotation is added to the def apply_migrations(...) line and
keep the fixture behavior (calling command.upgrade(ALEMBIC_CONFIG, "head"))
unchanged.

In `@tests/test_migrations.py`:
- Line 24: Add missing return type annotations to the test functions (e.g.,
test_migration_downgrade_003_removes_substitutes_only and the other test
functions at the indicated locations) so they follow project typing guidelines;
update each test function signature to include -> None (e.g., def
test_migration_downgrade_003_removes_substitutes_only() -> None:) and run the
test/type checker to ensure no other typing issues remain.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6efe6056-7059-4dda-b71b-1f49f5392bc8

📥 Commits

Reviewing files that changed from the base of the PR and between 3b645ab and 9df2373.

📒 Files selected for processing (13)
  • .github/copilot-instructions.md
  • CHANGELOG.md
  • README.md
  • alembic/env.py
  • codecov.yaml
  • databases/player_database.py
  • docs/adr/0002-no-alembic-manual-seed-scripts.md
  • docs/adr/0009-docker-and-compose-strategy.md
  • docs/adr/0010-alembic-migration-based-schema-management.md
  • main.py
  • scripts/entrypoint.sh
  • tests/conftest.py
  • tests/test_migrations.py
✅ Files skipped from review due to trivial changes (6)
  • codecov.yaml
  • main.py
  • docs/adr/0002-no-alembic-manual-seed-scripts.md
  • docs/adr/0010-alembic-migration-based-schema-management.md
  • databases/player_database.py
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/entrypoint.sh

nanotaboada and others added 2 commits April 9, 2026 19:13
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
… hook (#2)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
gunicorn.conf.py (1)

21-21: Add parameter typing and mark unused hook arg explicitly.

on_starting is missing a type hint for its parameter, and the arg is intentionally unused.

Suggested patch
-def on_starting(server) -> None:
+def on_starting(_server: object) -> None:
     """Apply Alembic migrations once before workers are spawned."""

As per coding guidelines, **/*.py: "Use type hints for function parameters and return values".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@gunicorn.conf.py` at line 21, The on_starting hook lacks a parameter type and
the argument is intentionally unused; import typing.Any and update the function
signature for on_starting to annotate the parameter (e.g., def
on_starting(_server: Any) -> None) or keep the name server but annotate it and
explicitly mark it unused (e.g., assign to _ or prefix name with underscore) so
linters/readers know it's intentionally unused.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@gunicorn.conf.py`:
- Line 21: The on_starting hook lacks a parameter type and the argument is
intentionally unused; import typing.Any and update the function signature for
on_starting to annotate the parameter (e.g., def on_starting(_server: Any) ->
None) or keep the name server but annotate it and explicitly mark it unused
(e.g., assign to _ or prefix name with underscore) so linters/readers know it's
intentionally unused.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c831d3bf-27b2-4f28-9191-43724a1ce44a

📥 Commits

Reviewing files that changed from the base of the PR and between 9df2373 and ec97c95.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock, !**/uv.lock
📒 Files selected for processing (6)
  • CHANGELOG.md
  • Dockerfile
  • compose.yaml
  • gunicorn.conf.py
  • pyproject.toml
  • scripts/entrypoint.sh
✅ Files skipped from review due to trivial changes (1)
  • pyproject.toml
🚧 Files skipped from review as they are similar to previous changes (3)
  • compose.yaml
  • scripts/entrypoint.sh
  • CHANGELOG.md

nanotaboada and others added 2 commits April 9, 2026 19:37
…store (#2)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@nanotaboada nanotaboada force-pushed the feat/2-implement-alembic-database-migrations branch from 77a2426 to c9a01d1 Compare April 9, 2026 22:54
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 9, 2026

@nanotaboada nanotaboada merged commit 52902c8 into master Apr 10, 2026
11 checks passed
@nanotaboada nanotaboada deleted the feat/2-implement-alembic-database-migrations branch April 10, 2026 01:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Alembic Database Migration Support Implement Alembic for database migrations

1 participant