60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
"""Record who handed a drive back, not just when.
|
|
|
|
usbcheckouts held the checkout identity (sso, checkoutname) and, for the
|
|
return, only checkintime. Returning a drive for a colleague is a supported
|
|
kiosk flow - usb_kiosk_allow_return_for_others gates it and the kiosk asks for
|
|
confirmation - but the row it wrote attributed the check-in to the HOLDER. The
|
|
person who actually walked the drive back was recorded nowhere, so the custody
|
|
history and the audit report both named somebody who was not there.
|
|
|
|
Two columns rather than one: the badge is what the scanner emits and what joins
|
|
to a directory, and the name is what a report has to print when the directory
|
|
no longer resolves that badge.
|
|
|
|
Nullable, and not backfilled. A row closed before this column existed is one
|
|
where the returner was not recorded; copying the holder's badge into it would
|
|
manufacture evidence that the holder returned it, which is the exact claim this
|
|
migration exists to stop making.
|
|
|
|
Idempotent, so a re-run on an already-migrated database is a no-op.
|
|
|
|
Revision ID: usb0004checkinidentity
|
|
Revises: usb0003scanfields
|
|
"""
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
|
|
|
|
revision = 'usb0004checkinidentity'
|
|
down_revision = 'usb0003scanfields'
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
NEW_COLUMNS = (
|
|
('checkinsso', sa.String(length=20)),
|
|
('checkinname', sa.String(length=100)),
|
|
)
|
|
|
|
|
|
def upgrade():
|
|
bind = op.get_bind()
|
|
insp = sa.inspect(bind)
|
|
if 'usbcheckouts' not in insp.get_table_names():
|
|
return
|
|
cols = {c['name'] for c in insp.get_columns('usbcheckouts')}
|
|
for name, coltype in NEW_COLUMNS:
|
|
if name not in cols:
|
|
op.add_column('usbcheckouts',
|
|
sa.Column(name, coltype, nullable=True))
|
|
|
|
|
|
def downgrade():
|
|
bind = op.get_bind()
|
|
insp = sa.inspect(bind)
|
|
if 'usbcheckouts' not in insp.get_table_names():
|
|
return
|
|
cols = {c['name'] for c in insp.get_columns('usbcheckouts')}
|
|
for name, _ in NEW_COLUMNS:
|
|
if name in cols:
|
|
op.drop_column('usbcheckouts', name)
|