PrintedItem (catalog: code, name, image, cached quantityonhand, per-item threshold, bin) and PrintedItemTransaction (the ledger: signed quantity change attributed to a badge-resolved employee). Both registered in PLUGIN_TABLE_OWNERS; 0001 is a post-cutover real baseline. The migration-guard test learns the new expected head. Routes are a placeholder ping until the next stage - the scaffold's list route imported the deleted scaffold model, which surfaces as an empty 'Migration error' because the alembic env imports the models package.
72 lines
3.2 KiB
Python
72 lines
3.2 KiB
Python
"""printedparts plugin baseline (real create).
|
|
|
|
Post-ADR-008 plugin: this per-plugin chain is the sole authoritative creator
|
|
of printeditems and printeditemtransactions - the core chain never knew them.
|
|
Runs from `flask plugin install printedparts` (and `flask plugin upgrade-all`)
|
|
after `flask db upgrade` builds the core schema.
|
|
|
|
Both tables are self-contained (the only FK is transactions -> items inside
|
|
the plugin), so the shared create_plugin_tables helper would work here; the
|
|
ops are written out explicitly anyway to match the measuringtools exemplar
|
|
and keep the baseline reviewable.
|
|
"""
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision = 'printedparts0001baseline'
|
|
down_revision = None
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade():
|
|
op.create_table(
|
|
'printeditems',
|
|
sa.Column('printeditemid', sa.Integer(), nullable=False),
|
|
sa.Column('itemcode', sa.String(length=20), nullable=True),
|
|
sa.Column('itemname', sa.String(length=120), nullable=False),
|
|
sa.Column('itemdescription', sa.String(length=500), nullable=True),
|
|
sa.Column('imageurl', sa.String(length=255), nullable=True),
|
|
sa.Column('quantityonhand', sa.Integer(), nullable=False),
|
|
sa.Column('lowstockthreshold', sa.Integer(), nullable=False),
|
|
sa.Column('binlocation', sa.String(length=100), nullable=True),
|
|
sa.Column('printnotes', sa.Text(), nullable=True),
|
|
sa.Column('createddate', sa.DateTime(), nullable=False),
|
|
sa.Column('modifieddate', sa.DateTime(), nullable=False),
|
|
sa.Column('isactive', sa.Boolean(), nullable=False),
|
|
sa.PrimaryKeyConstraint('printeditemid'),
|
|
sa.UniqueConstraint('itemcode'),
|
|
)
|
|
op.create_index('ix_printeditems_itemcode', 'printeditems', ['itemcode'])
|
|
|
|
op.create_table(
|
|
'printeditemtransactions',
|
|
sa.Column('transactionid', sa.Integer(), nullable=False),
|
|
sa.Column('printeditemid', sa.Integer(), nullable=False),
|
|
sa.Column('transactiontype', sa.String(length=10), nullable=False),
|
|
sa.Column('quantitychange', sa.Integer(), nullable=False),
|
|
sa.Column('employeesso', sa.String(length=20), nullable=False),
|
|
sa.Column('employeename', sa.String(length=120), nullable=True),
|
|
sa.Column('reason', sa.String(length=255), nullable=True),
|
|
sa.Column('transactiondate', sa.DateTime(), nullable=False),
|
|
sa.Column('createddate', sa.DateTime(), nullable=False),
|
|
sa.Column('modifieddate', sa.DateTime(), nullable=False),
|
|
sa.Column('isactive', sa.Boolean(), nullable=False),
|
|
sa.ForeignKeyConstraint(['printeditemid'], ['printeditems.printeditemid'],
|
|
ondelete='CASCADE'),
|
|
sa.PrimaryKeyConstraint('transactionid'),
|
|
)
|
|
op.create_index('ix_printeditemtransactions_printeditemid',
|
|
'printeditemtransactions', ['printeditemid'])
|
|
op.create_index('ix_printeditemtransactions_employeesso',
|
|
'printeditemtransactions', ['employeesso'])
|
|
op.create_index('ix_printeditemtransactions_transactiondate',
|
|
'printeditemtransactions', ['transactiondate'])
|
|
|
|
|
|
def downgrade():
|
|
op.drop_table('printeditemtransactions')
|
|
op.drop_table('printeditems')
|