Zippi manages all database schema changes through Flask-Migrate, which wraps Alembic and integrates it into the Flask CLI. Migration scripts live inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/CRISTIANCAMACH34/Zippi/llms.txt
Use this file to discover all available pages before exploring further.
backend/migrations/versions/ and are version-controlled alongside application code. The database is MySQL 8 in production; the same workflow works with a local MySQL instance during development.
How the Migration Stack Is Wired
Flask-Migrate is initialised inbackend/app/bootstrap/extensions.py:
compare_type=True ensures that column type changes (e.g. VARCHAR length) are detected during autogeneration. render_as_batch=True enables Alembic’s batch mode, which is required for certain ALTER TABLE operations on databases that don’t support transactional DDL.
The create_app() factory in backend/app/bootstrap/app_factory.py binds both extensions:
app.infrastructure.db.models before the app starts, so Alembic’s autogenerate can diff the full metadata against the live schema.
Alembic’s runtime configuration — database URL resolution, metadata target, and the process-revision-directives hook — is defined in backend/migrations/env.py.
The migrations directory is
backend/migrations/versions/, not
backend/app/infrastructure/db/migrations/. All flask db commands must be
run from the backend/ directory with the virtual environment active.Applying Existing Migrations
Run all pending migrations against the database configured inbackend/.env:
head revision. To upgrade to a specific revision instead:
Checking Migration Status
Two commands help you understand the current schema state:history output (abbreviated from the actual versions/ directory):
Creating and Applying a New Migration
Define or update your SQLAlchemy model
Add or modify a model class that inherits from
Base
(app.infrastructure.db.base.Base). For example, adding a notes column
to an existing model:Autogenerate the migration script
Flask-Migrate diffs your model metadata against the live schema and writes
a new script into A new file such as
backend/migrations/versions/:migrations/versions/a1b2c3d4_add_notes_column_to_orders.py
is created with upgrade() and downgrade() functions.Review the generated script
Always inspect the generated file before applying it. Autogenerate is not
perfect — it may miss table renames, partial indexes, or check constraints.A typical generated script looks like:
Rolling Back Migrations
Roll back one step (the most recently applied revision):Multi-Tenant Considerations
Zippi supports multi-branch and multi-tenant deployments. Every new entity table that belongs to a branch (sucursal) must include a sucursal_id discriminator column so that queries can be scoped without cross-contaminating data:
- The
sucursal_idforeign key is present in theupgrade()function. - A matching index is generated alongside it for query performance.
- The
downgrade()function drops both the column and the index cleanly.
CI Integration
The GitHub Actions CI pipeline (ci.yml) installs all backend dependencies and runs pytest on every push to main, master, and develop, and on all pull requests. Migrations themselves are not re-run in CI, but the test suite exercises the schema through SQLAlchemy models — meaning a broken migration that produces an inconsistent model will surface as a test failure before it reaches staging.
.pre-commit-config.yaml) run ruff, ruff-format, and a subset of the pytest suite on every local commit to backend/, catching issues before they reach the remote branch.