
This commit includes: - Project structure and FastAPI setup - SQLAlchemy models for users, vehicles, schedules, and tickets - Alembic migrations - User authentication and management - Vehicle and schedule management - Ticket purchase and cancellation with time restrictions - Comprehensive API documentation
104 lines
4.5 KiB
Python
104 lines
4.5 KiB
Python
"""Initial migration
|
|
|
|
Revision ID: 1f3a9c5d40a1
|
|
Revises:
|
|
Create Date: 2023-06-01 00:00:00.000000
|
|
|
|
"""
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision = '1f3a9c5d40a1'
|
|
down_revision = None
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
# Create users table
|
|
op.create_table(
|
|
'users',
|
|
sa.Column('id', sa.Integer(), nullable=False),
|
|
sa.Column('username', sa.String(), nullable=False),
|
|
sa.Column('email', sa.String(), nullable=False),
|
|
sa.Column('hashed_password', sa.String(), nullable=False),
|
|
sa.Column('is_active', sa.Boolean(), nullable=False, default=True),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
|
|
op.create_index(op.f('ix_users_id'), 'users', ['id'], unique=False)
|
|
op.create_index(op.f('ix_users_username'), 'users', ['username'], unique=True)
|
|
|
|
# Create vehicles table
|
|
op.create_table(
|
|
'vehicles',
|
|
sa.Column('id', sa.Integer(), nullable=False),
|
|
sa.Column('vehicle_number', sa.String(), nullable=False),
|
|
sa.Column('vehicle_type', sa.Enum('car', 'bus', 'train', name='vehicletype'), nullable=False),
|
|
sa.Column('capacity', sa.Integer(), nullable=False),
|
|
sa.Column('is_active', sa.Boolean(), nullable=False, default=True),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index(op.f('ix_vehicles_id'), 'vehicles', ['id'], unique=False)
|
|
op.create_index(op.f('ix_vehicles_vehicle_number'), 'vehicles', ['vehicle_number'], unique=True)
|
|
op.create_index(op.f('ix_vehicles_vehicle_type'), 'vehicles', ['vehicle_type'], unique=False)
|
|
|
|
# Create schedules table
|
|
op.create_table(
|
|
'schedules',
|
|
sa.Column('id', sa.Integer(), nullable=False),
|
|
sa.Column('vehicle_id', sa.Integer(), nullable=False),
|
|
sa.Column('departure_location', sa.String(), nullable=False),
|
|
sa.Column('arrival_location', sa.String(), nullable=False),
|
|
sa.Column('departure_time', sa.DateTime(), nullable=False),
|
|
sa.Column('arrival_time', sa.DateTime(), nullable=False),
|
|
sa.Column('available_seats', sa.Integer(), nullable=False),
|
|
sa.Column('is_active', sa.Boolean(), nullable=False, default=True),
|
|
sa.ForeignKeyConstraint(['vehicle_id'], ['vehicles.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index(op.f('ix_schedules_departure_time'), 'schedules', ['departure_time'], unique=False)
|
|
op.create_index(op.f('ix_schedules_id'), 'schedules', ['id'], unique=False)
|
|
|
|
# Create tickets table
|
|
op.create_table(
|
|
'tickets',
|
|
sa.Column('id', sa.Integer(), nullable=False),
|
|
sa.Column('user_id', sa.Integer(), nullable=False),
|
|
sa.Column('schedule_id', sa.Integer(), nullable=False),
|
|
sa.Column('seat_number', sa.String(), nullable=True),
|
|
sa.Column('purchase_time', sa.DateTime(), nullable=False),
|
|
sa.Column('status', sa.Enum('active', 'used', 'cancelled', 'expired', name='ticketstatus'), nullable=False),
|
|
sa.Column('is_active', sa.Boolean(), nullable=False, default=True),
|
|
sa.Column('ticket_number', sa.String(), nullable=False),
|
|
sa.ForeignKeyConstraint(['schedule_id'], ['schedules.id'], ),
|
|
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
op.create_index(op.f('ix_tickets_id'), 'tickets', ['id'], unique=False)
|
|
op.create_index(op.f('ix_tickets_ticket_number'), 'tickets', ['ticket_number'], unique=True)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_index(op.f('ix_tickets_ticket_number'), table_name='tickets')
|
|
op.drop_index(op.f('ix_tickets_id'), table_name='tickets')
|
|
op.drop_table('tickets')
|
|
|
|
op.drop_index(op.f('ix_schedules_id'), table_name='schedules')
|
|
op.drop_index(op.f('ix_schedules_departure_time'), table_name='schedules')
|
|
op.drop_table('schedules')
|
|
|
|
op.drop_index(op.f('ix_vehicles_vehicle_type'), table_name='vehicles')
|
|
op.drop_index(op.f('ix_vehicles_vehicle_number'), table_name='vehicles')
|
|
op.drop_index(op.f('ix_vehicles_id'), table_name='vehicles')
|
|
op.drop_table('vehicles')
|
|
|
|
op.drop_index(op.f('ix_users_username'), table_name='users')
|
|
op.drop_index(op.f('ix_users_id'), table_name='users')
|
|
op.drop_index(op.f('ix_users_email'), table_name='users')
|
|
op.drop_table('users')
|
|
|
|
# Remove enum types (SQLite ignores this, but important for other databases)
|
|
op.execute('DROP TYPE IF EXISTS vehicletype;')
|
|
op.execute('DROP TYPE IF EXISTS ticketstatus;') |