Some checks failed
CI / style (push) Has been cancelled
CI / build-client (push) Has been cancelled
CI / build-amd64 (push) Has been cancelled
CI / build-tester (push) Has been cancelled
CI / test (cockroachdb) (push) Has been cancelled
CI / test (mariadb) (push) Has been cancelled
CI / test (postgres) (push) Has been cancelled
CI / test (sqlite) (push) Has been cancelled
CI / build-arm64 (push) Has been cancelled
CI / build-armv7 (push) Has been cancelled
CI / publish-images (push) Has been cancelled
CI / publish-release (push) Has been cancelled
## Batch Operations (#13) - Add POST /spool/bulk/archive, /bulk/delete, /bulk/update endpoints - Add row selection with checkboxes to spool list - Add floating BatchActionBar with archive/unarchive/delete/move actions - Add confirmation modals for all batch operations ## Dashboard Redesign (#12) - Install recharts for pie charts - Add AlertCards (low stock, pending jobs, needs weighing) - Add MaterialDistributionChart (pie chart by material) - Add QuickStats row (total spools, filaments, vendors, weight) - Refactor home page layout with new components ## Hierarchical Locations (#9) - Add Location model with self-referential parent relationship - Add migration for location table and spool.location_id FK - Add location database operations (CRUD, tree, full path) - Add location API endpoints (list, tree, CRUD) - Add LocationTreeSelect component with nested tree display - Add LocationCreateModal for inline location creation - Keep legacy location string field for backward compatibility Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
62 lines
2.0 KiB
Python
62 lines
2.0 KiB
Python
"""Add hierarchical locations.
|
|
|
|
Revision ID: e5f6g7h8i9j0
|
|
Revises: d4e5f6g7h8i9
|
|
Create Date: 2025-01-21 01:00:00.000000
|
|
|
|
"""
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision = "e5f6g7h8i9j0"
|
|
down_revision = "d4e5f6g7h8i9"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
"""Create location table and add location_id to spool."""
|
|
# Create location table
|
|
op.create_table(
|
|
"location",
|
|
sa.Column("id", sa.Integer(), nullable=False),
|
|
sa.Column("name", sa.String(length=64), nullable=False),
|
|
sa.Column("parent_id", sa.Integer(), nullable=True),
|
|
sa.Column("location_type", sa.String(length=32), nullable=True),
|
|
sa.Column("description", sa.String(length=256), nullable=True),
|
|
sa.ForeignKeyConstraint(
|
|
["parent_id"],
|
|
["location.id"],
|
|
ondelete="SET NULL",
|
|
),
|
|
sa.PrimaryKeyConstraint("id"),
|
|
)
|
|
op.create_index(op.f("ix_location_id"), "location", ["id"], unique=False)
|
|
op.create_index(op.f("ix_location_parent_id"), "location", ["parent_id"], unique=False)
|
|
|
|
# Add location_id column to spool table
|
|
op.add_column(
|
|
"spool",
|
|
sa.Column("location_id", sa.Integer(), nullable=True),
|
|
)
|
|
op.create_foreign_key(
|
|
"fk_spool_location_id",
|
|
"spool",
|
|
"location",
|
|
["location_id"],
|
|
["id"],
|
|
ondelete="SET NULL",
|
|
)
|
|
op.create_index(op.f("ix_spool_location_id"), "spool", ["location_id"], unique=False)
|
|
|
|
|
|
def downgrade() -> None:
|
|
"""Drop location table and remove location_id from spool."""
|
|
op.drop_index(op.f("ix_spool_location_id"), table_name="spool")
|
|
op.drop_constraint("fk_spool_location_id", "spool", type_="foreignkey")
|
|
op.drop_column("spool", "location_id")
|
|
op.drop_index(op.f("ix_location_parent_id"), table_name="location")
|
|
op.drop_index(op.f("ix_location_id"), table_name="location")
|
|
op.drop_table("location")
|