Initial commit: SIBU 2.0 MISSION
This commit is contained in:
95
backend/alembic/env.py
Normal file
95
backend/alembic/env.py
Normal file
@ -0,0 +1,95 @@
|
||||
"""Alembic environment configuration."""
|
||||
from logging.config import fileConfig
|
||||
from sqlmodel import SQLModel
|
||||
from sqlalchemy import engine_from_config
|
||||
from sqlalchemy import pool
|
||||
from sqlalchemy import text as sa_text
|
||||
from alembic import context
|
||||
|
||||
# Import your models and database configuration
|
||||
from app.core.config import settings
|
||||
from app.models import * # noqa: F401, F403
|
||||
|
||||
# this is the Alembic Config object, which provides
|
||||
# access to the values within the .ini file in use.
|
||||
config = context.config
|
||||
|
||||
# Interpret the config file for Python logging.
|
||||
# This line sets up loggers basically.
|
||||
if config.config_file_name is not None:
|
||||
fileConfig(config.config_file_name)
|
||||
|
||||
# Set the sqlalchemy.url from our settings
|
||||
# Convert asyncpg URL to psycopg2 for Alembic (Alembic doesn't support async)
|
||||
database_url = settings.database_url.replace("+asyncpg", "+psycopg2")
|
||||
config.set_main_option("sqlalchemy.url", database_url)
|
||||
|
||||
# add your model's MetaData object here
|
||||
# for 'autogenerate' support
|
||||
|
||||
|
||||
# Import all models to ensure they're registered
|
||||
|
||||
target_metadata = SQLModel.metadata
|
||||
|
||||
# other values from the config, defined by the needs of env.py,
|
||||
# can be acquired:
|
||||
# my_important_option = config.get_main_option("my_important_option")
|
||||
# ... etc.
|
||||
|
||||
|
||||
def run_migrations_offline() -> None:
|
||||
"""Run migrations in 'offline' mode.
|
||||
|
||||
This configures the context with just a URL
|
||||
and not an Engine, though an Engine is acceptable
|
||||
here as well. By skipping the Engine creation
|
||||
we don't even need a DBAPI to be available.
|
||||
|
||||
Calls to context.execute() here emit the given string to the
|
||||
script output.
|
||||
|
||||
"""
|
||||
url = config.get_main_option("sqlalchemy.url")
|
||||
context.configure(
|
||||
url=url,
|
||||
target_metadata=target_metadata,
|
||||
literal_binds=True,
|
||||
dialect_opts={"paramstyle": "named"},
|
||||
)
|
||||
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
|
||||
|
||||
def run_migrations_online() -> None:
|
||||
"""Run migrations in 'online' mode.
|
||||
|
||||
In this scenario we need to create an Engine
|
||||
and associate a connection with the context.
|
||||
|
||||
"""
|
||||
connectable = engine_from_config(
|
||||
config.get_section(config.config_ini_section, {}),
|
||||
prefix="sqlalchemy.",
|
||||
poolclass=pool.NullPool,
|
||||
)
|
||||
|
||||
with connectable.connect() as connection:
|
||||
# Set search_path to public schema
|
||||
connection.execute(sa_text("SET search_path TO public"))
|
||||
connection.commit()
|
||||
|
||||
context.configure(
|
||||
connection=connection, target_metadata=target_metadata
|
||||
)
|
||||
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
|
||||
|
||||
if context.is_offline_mode():
|
||||
run_migrations_offline()
|
||||
else:
|
||||
run_migrations_online()
|
||||
|
||||
27
backend/alembic/script.py.mako
Normal file
27
backend/alembic/script.py.mako
Normal file
@ -0,0 +1,27 @@
|
||||
"""${message}
|
||||
|
||||
Revision ID: ${up_revision}
|
||||
Revises: ${down_revision | comma,n}
|
||||
Create Date: ${create_date}
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
${imports if imports else ""}
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = ${repr(up_revision)}
|
||||
down_revision: Union[str, None] = ${repr(down_revision)}
|
||||
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
|
||||
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
${upgrades if upgrades else "pass"}
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
${downgrades if downgrades else "pass"}
|
||||
|
||||
32
backend/alembic/versions/2088667c3a5f_add_search_indexes.py
Normal file
32
backend/alembic/versions/2088667c3a5f_add_search_indexes.py
Normal file
@ -0,0 +1,32 @@
|
||||
"""add_search_indexes
|
||||
|
||||
Revision ID: 2088667c3a5f
|
||||
Revises: 4c9211307d7a
|
||||
Create Date: 2026-01-28 18:35:15.269274
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '2088667c3a5f'
|
||||
down_revision: Union[str, None] = '4c9211307d7a'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_index(op.f('ix_coupons_title'), 'coupons', ['title'], unique=False)
|
||||
op.create_index(op.f('ix_users_full_name'), 'users', ['full_name'], unique=False)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_index(op.f('ix_users_full_name'), table_name='users')
|
||||
op.drop_index(op.f('ix_coupons_title'), table_name='coupons')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
88
backend/alembic/versions/2f4936eb86f0_initial_schema.py
Normal file
88
backend/alembic/versions/2f4936eb86f0_initial_schema.py
Normal file
@ -0,0 +1,88 @@
|
||||
"""initial_schema
|
||||
|
||||
Revision ID: 2f4936eb86f0
|
||||
Revises:
|
||||
Create Date: 2025-12-02 21:34:08.468033
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '2f4936eb86f0'
|
||||
down_revision: Union[str, None] = None
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('bus_stops',
|
||||
sa.Column('id', sa.Uuid(), nullable=False),
|
||||
sa.Column('name', sa.String(), nullable=False),
|
||||
sa.Column('latitude', sa.Float(), nullable=False),
|
||||
sa.Column('longitude', sa.Float(), nullable=False),
|
||||
sa.Column('city', sa.String(), nullable=False),
|
||||
sa.Column('address', sa.String(), nullable=True),
|
||||
sa.Column('stop_type', sa.Enum('TERMINAL', 'REGULAR', 'EXPRESS_ONLY', name='stoptype'), nullable=False),
|
||||
sa.Column('has_shelter', sa.Boolean(), nullable=False),
|
||||
sa.Column('has_seating', sa.Boolean(), nullable=False),
|
||||
sa.Column('is_accessible', sa.Boolean(), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_table('routes',
|
||||
sa.Column('id', sa.Uuid(), nullable=False),
|
||||
sa.Column('name', sa.String(), nullable=False),
|
||||
sa.Column('description', sa.String(), nullable=True),
|
||||
sa.Column('origin_city', sa.String(), nullable=False),
|
||||
sa.Column('destination_city', sa.String(), nullable=False),
|
||||
sa.Column('distance_km', sa.Float(), nullable=True),
|
||||
sa.Column('estimated_duration_minutes', sa.Integer(), nullable=True),
|
||||
sa.Column('status', sa.Enum('ACTIVE', 'INACTIVE', 'MAINTENANCE', name='routestatus'), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_routes_name'), 'routes', ['name'], unique=True)
|
||||
op.create_table('bus_schedules',
|
||||
sa.Column('id', sa.Uuid(), nullable=False),
|
||||
sa.Column('route_id', sa.Uuid(), nullable=False),
|
||||
sa.Column('departure_time', sa.Time(), nullable=False),
|
||||
sa.Column('frequency_minutes', sa.Integer(), nullable=True),
|
||||
sa.Column('schedule_type', sa.Enum('WEEKDAY', 'WEEKEND', 'HOLIDAY', name='busscheduletype'), nullable=False),
|
||||
sa.Column('is_active', sa.Boolean(), nullable=False),
|
||||
sa.Column('notes', sa.String(), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
||||
sa.ForeignKeyConstraint(['route_id'], ['routes.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_table('route_stops',
|
||||
sa.Column('id', sa.Uuid(), nullable=False),
|
||||
sa.Column('route_id', sa.Uuid(), nullable=False),
|
||||
sa.Column('stop_id', sa.Uuid(), nullable=False),
|
||||
sa.Column('stop_order', sa.Integer(), nullable=False),
|
||||
sa.Column('travel_time_minutes', sa.Integer(), nullable=True),
|
||||
sa.Column('is_pickup_point', sa.Boolean(), nullable=False),
|
||||
sa.Column('is_dropoff_point', sa.Boolean(), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
||||
sa.ForeignKeyConstraint(['route_id'], ['routes.id'], ),
|
||||
sa.ForeignKeyConstraint(['stop_id'], ['bus_stops.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table('route_stops')
|
||||
op.drop_table('bus_schedules')
|
||||
op.drop_index(op.f('ix_routes_name'), table_name='routes')
|
||||
op.drop_table('routes')
|
||||
op.drop_table('bus_stops')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
46
backend/alembic/versions/3fe72cd3f722_sync_shuttle_fields.py
Normal file
46
backend/alembic/versions/3fe72cd3f722_sync_shuttle_fields.py
Normal file
@ -0,0 +1,46 @@
|
||||
"""Sync shuttle fields
|
||||
|
||||
Revision ID: 3fe72cd3f722
|
||||
Revises: 5caf8ba3ed4d
|
||||
Create Date: 2026-02-15 16:20:02.326548
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '3fe72cd3f722'
|
||||
down_revision: Union[str, None] = '5caf8ba3ed4d'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# 1. Reparar valores nulos existentes en driver_profiles antes de restringir
|
||||
op.execute("UPDATE driver_profiles SET speaks_english = FALSE WHERE speaks_english IS NULL")
|
||||
|
||||
op.alter_column('driver_profiles', 'speaks_english',
|
||||
existing_type=sa.BOOLEAN(),
|
||||
nullable=False)
|
||||
|
||||
# 2. Asegurar campos de Shuttles (solo si no existen, usando try/except o verificando primero)
|
||||
# Nota: Alembic no los detectó, pero los forzamos por si acaso
|
||||
with op.get_context().autocommit_block():
|
||||
op.execute("ALTER TABLE shuttles ADD COLUMN IF NOT EXISTS company_name VARCHAR")
|
||||
op.execute("ALTER TABLE shuttles ADD COLUMN IF NOT EXISTS trip_type VARCHAR DEFAULT 'one_way'")
|
||||
op.execute("ALTER TABLE shuttles ADD COLUMN IF NOT EXISTS price_private_trip FLOAT")
|
||||
op.execute("ALTER TABLE shuttles ADD COLUMN IF NOT EXISTS departure_times VARCHAR")
|
||||
op.execute("ALTER TABLE shuttles ADD COLUMN IF NOT EXISTS contact_whatsapp VARCHAR")
|
||||
op.execute("ALTER TABLE shuttles ADD COLUMN IF NOT EXISTS estimated_duration VARCHAR")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.alter_column('driver_profiles', 'speaks_english',
|
||||
existing_type=sa.BOOLEAN(),
|
||||
nullable=True)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
57
backend/alembic/versions/414da6754b1e_add_user_roles.py
Normal file
57
backend/alembic/versions/414da6754b1e_add_user_roles.py
Normal file
@ -0,0 +1,57 @@
|
||||
"""add_user_roles
|
||||
|
||||
Revision ID: 414da6754b1e
|
||||
Revises: aac025d432f0
|
||||
Create Date: 2026-01-27 15:26:58.408563
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import sqlmodel
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '414da6754b1e'
|
||||
down_revision: Union[str, None] = 'aac025d432f0'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('users',
|
||||
sa.Column('id', sa.Uuid(), nullable=False),
|
||||
sa.Column('email', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||
sa.Column('hashed_password', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||
sa.Column('full_name', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||
sa.Column('role', sa.Enum('ADMIN', 'PASSENGER', 'DRIVER', name='userrole'), nullable=False),
|
||||
sa.Column('is_active', sa.Boolean(), nullable=False),
|
||||
sa.Column('is_verified', sa.Boolean(), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
|
||||
op.create_table('driver_profiles',
|
||||
sa.Column('id', sa.Uuid(), nullable=False),
|
||||
sa.Column('user_id', sa.Uuid(), nullable=False),
|
||||
sa.Column('cedula', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||
sa.Column('vehicle_type', sa.Enum('TAXI', 'BUS', name='vehicletype'), nullable=False),
|
||||
sa.Column('license_plate', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||
sa.Column('photo_url', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||
sa.Column('vehicle_photo_url', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||
sa.Column('cooperative_name', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table('driver_profiles')
|
||||
op.drop_index(op.f('ix_users_email'), table_name='users')
|
||||
op.drop_table('users')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
"""add_user_profile_photo
|
||||
|
||||
Revision ID: 4c9211307d7a
|
||||
Revises: 8a5661aac24b
|
||||
Create Date: 2026-01-28 18:13:37.548321
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '4c9211307d7a'
|
||||
down_revision: Union[str, None] = '8a5661aac24b'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('users', sa.Column('profile_photo_url', sa.String(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('users', 'profile_photo_url')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
"""add_speaks_english_to_driver_profile
|
||||
|
||||
Revision ID: 5caf8ba3ed4d
|
||||
Revises: 9f2fbe81a055
|
||||
Create Date: 2026-01-31 16:02:13.521306
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import sqlmodel
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '5caf8ba3ed4d'
|
||||
down_revision: Union[str, None] = '9f2fbe81a055'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('driver_profiles', sa.Column('shift', sqlmodel.sql.sqltypes.AutoString(), nullable=True))
|
||||
op.add_column('driver_profiles', sa.Column('payment_methods', sqlmodel.sql.sqltypes.AutoString(), nullable=True))
|
||||
op.add_column('driver_profiles', sa.Column('speaks_english', sa.Boolean(), nullable=True))
|
||||
op.add_column('taxis', sa.Column('rating', sa.Float(), nullable=False, server_default=sa.text('5.0')))
|
||||
op.add_column('taxis', sa.Column('english_speaking', sa.Boolean(), nullable=False, server_default=sa.text('false')))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('taxis', 'english_speaking')
|
||||
op.drop_column('taxis', 'rating')
|
||||
op.drop_column('driver_profiles', 'speaks_english')
|
||||
op.drop_column('driver_profiles', 'payment_methods')
|
||||
op.drop_column('driver_profiles', 'shift')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
44
backend/alembic/versions/8a5661aac24b_add_user_coupons.py
Normal file
44
backend/alembic/versions/8a5661aac24b_add_user_coupons.py
Normal file
@ -0,0 +1,44 @@
|
||||
"""add_user_coupons
|
||||
|
||||
Revision ID: 8a5661aac24b
|
||||
Revises: e5fb60c22245
|
||||
Create Date: 2026-01-28 18:01:08.102678
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '8a5661aac24b'
|
||||
down_revision: Union[str, None] = 'e5fb60c22245'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('user_coupons',
|
||||
sa.Column('id', sa.Uuid(), nullable=False),
|
||||
sa.Column('user_id', sa.Uuid(), nullable=False),
|
||||
sa.Column('coupon_id', sa.Uuid(), nullable=False),
|
||||
sa.Column('status', sa.Enum('CLAIMED', 'REDEEMED', 'EXPIRED', name='usercouponstatus'), nullable=False),
|
||||
sa.Column('redemption_code', sa.String(), nullable=True),
|
||||
sa.Column('claimed_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
|
||||
sa.Column('redeemed_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.ForeignKeyConstraint(['coupon_id'], ['coupons.id'], ),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_user_coupons_redemption_code'), 'user_coupons', ['redemption_code'], unique=True)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_index(op.f('ix_user_coupons_redemption_code'), table_name='user_coupons')
|
||||
op.drop_table('user_coupons')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
"""add_is_published_to_bus_schedule
|
||||
|
||||
Revision ID: 8b3e5b0a3e67
|
||||
Revises: 414da6754b1e
|
||||
Create Date: 2026-01-27 17:05:19.915106
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '8b3e5b0a3e67'
|
||||
down_revision: Union[str, None] = '414da6754b1e'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('bus_schedules', sa.Column('is_published', sa.Boolean(), nullable=True))
|
||||
op.execute("UPDATE bus_schedules SET is_published = false")
|
||||
op.alter_column('bus_schedules', 'is_published', nullable=False)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('bus_schedules', 'is_published')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
"""add_coupons_and_promoter_role
|
||||
|
||||
Revision ID: 93054da1a687
|
||||
Revises: ceda6a5abf0e
|
||||
Create Date: 2026-01-28 10:41:47.113948
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
import sqlmodel
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '93054da1a687'
|
||||
down_revision: Union[str, None] = 'ceda6a5abf0e'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# Add 'promoter' to UserRole enum
|
||||
# Postgres specific command to add value to existing Enum
|
||||
with op.get_context().autocommit_block():
|
||||
op.execute("ALTER TYPE userrole ADD VALUE IF NOT EXISTS 'promoter'")
|
||||
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('coupons',
|
||||
sa.Column('id', sa.Uuid(), nullable=False),
|
||||
sa.Column('title', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||
sa.Column('description', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||
sa.Column('discount_percentage', sa.Integer(), nullable=True),
|
||||
sa.Column('discount_amount', sa.Float(), nullable=True),
|
||||
sa.Column('category', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||
sa.Column('valid_from', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('valid_until', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('is_active', sa.Boolean(), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table('coupons')
|
||||
# ### end Alembic commands ###
|
||||
# Note: Removing a value from a Postgres Enum is complex and usually not done in migrations
|
||||
# unless you recreate the whole type.
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
"""add_social_media_to_coupons
|
||||
|
||||
Revision ID: 94b4cb57c6c1
|
||||
Revises: dfbcee895f78
|
||||
Create Date: 2026-01-28 11:31:47.625569
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import sqlmodel
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '94b4cb57c6c1'
|
||||
down_revision: Union[str, None] = 'dfbcee895f78'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('coupons', sa.Column('social_media', sqlmodel.sql.sqltypes.AutoString(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('coupons', 'social_media')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
"""add area to business
|
||||
|
||||
Revision ID: 9f2fbe81a055
|
||||
Revises: c9bb64354775
|
||||
Create Date: 2026-01-29 13:36:34.379966
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import sqlmodel
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '9f2fbe81a055'
|
||||
down_revision: Union[str, None] = 'c9bb64354775'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('businesses', sa.Column('area', sqlmodel.sql.sqltypes.AutoString(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('businesses', 'area')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
"""Add average_speed and stop_delay
|
||||
|
||||
Revision ID: aac025d432f0
|
||||
Revises: bb5c406b9af5
|
||||
Create Date: 2026-01-02 22:36:27.855381
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'aac025d432f0'
|
||||
down_revision: Union[str, None] = 'bb5c406b9af5'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('route_stops', sa.Column('stop_delay_minutes', sa.Integer(), server_default='0', nullable=False))
|
||||
op.add_column('routes', sa.Column('average_speed_kmh', sa.Float(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('routes', 'average_speed_kmh')
|
||||
op.drop_column('route_stops', 'stop_delay_minutes')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
"""add_stop_order_to_bus_stop
|
||||
|
||||
Revision ID: bb5c406b9af5
|
||||
Revises: 2f4936eb86f0
|
||||
Create Date: 2026-01-02 16:16:02.081811
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'bb5c406b9af5'
|
||||
down_revision: Union[str, None] = '2f4936eb86f0'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('bus_stops', sa.Column('stop_order', sa.Integer(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('bus_stops', 'stop_order')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
"""Add taxi and favorite models
|
||||
|
||||
Revision ID: c88628a640b6
|
||||
Revises: 8b3e5b0a3e67
|
||||
Create Date: 2026-01-27 19:54:26.038491
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import sqlmodel
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'c88628a640b6'
|
||||
down_revision: Union[str, None] = '8b3e5b0a3e67'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('taxis',
|
||||
sa.Column('id', sa.Uuid(), nullable=False),
|
||||
sa.Column('owner_name', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||
sa.Column('phone_number', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||
sa.Column('license_plate', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||
sa.Column('cooperative', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||
sa.Column('corregimiento', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||
sa.Column('shift', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||
sa.Column('is_active', sa.Boolean(), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_taxis_corregimiento'), 'taxis', ['corregimiento'], unique=False)
|
||||
op.create_index(op.f('ix_taxis_license_plate'), 'taxis', ['license_plate'], unique=True)
|
||||
op.create_table('favorites',
|
||||
sa.Column('id', sa.Uuid(), nullable=False),
|
||||
sa.Column('user_id', sa.Uuid(), nullable=False),
|
||||
sa.Column('item_type', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||
sa.Column('item_id', sa.Uuid(), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_favorites_item_id'), 'favorites', ['item_id'], unique=False)
|
||||
op.create_index(op.f('ix_favorites_item_type'), 'favorites', ['item_type'], unique=False)
|
||||
op.create_index(op.f('ix_favorites_user_id'), 'favorites', ['user_id'], unique=False)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_index(op.f('ix_favorites_user_id'), table_name='favorites')
|
||||
op.drop_index(op.f('ix_favorites_item_type'), table_name='favorites')
|
||||
op.drop_index(op.f('ix_favorites_item_id'), table_name='favorites')
|
||||
op.drop_table('favorites')
|
||||
op.drop_index(op.f('ix_taxis_license_plate'), table_name='taxis')
|
||||
op.drop_index(op.f('ix_taxis_corregimiento'), table_name='taxis')
|
||||
op.drop_table('taxis')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
33
backend/alembic/versions/c9bb64354775_add_business_coords.py
Normal file
33
backend/alembic/versions/c9bb64354775_add_business_coords.py
Normal file
@ -0,0 +1,33 @@
|
||||
"""add_business_coords
|
||||
|
||||
Revision ID: c9bb64354775
|
||||
Revises: 2088667c3a5f
|
||||
Create Date: 2026-01-29 09:34:11.595352
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'c9bb64354775'
|
||||
down_revision: Union[str, None] = '2088667c3a5f'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('businesses', sa.Column('latitude', sa.Float(), nullable=True))
|
||||
op.add_column('businesses', sa.Column('longitude', sa.Float(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('businesses', 'longitude')
|
||||
op.drop_column('businesses', 'latitude')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
46
backend/alembic/versions/ceda6a5abf0e_add_telemetry_table.py
Normal file
46
backend/alembic/versions/ceda6a5abf0e_add_telemetry_table.py
Normal file
@ -0,0 +1,46 @@
|
||||
"""add telemetry table
|
||||
|
||||
Revision ID: ceda6a5abf0e
|
||||
Revises: c88628a640b6
|
||||
Create Date: 2026-01-27 20:51:06.463716
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'ceda6a5abf0e'
|
||||
down_revision: Union[str, None] = 'c88628a640b6'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('telemetry',
|
||||
sa.Column('id', sa.Uuid(), nullable=False),
|
||||
sa.Column('user_id', sa.Uuid(), nullable=False),
|
||||
sa.Column('latitude', sa.Float(), nullable=False),
|
||||
sa.Column('longitude', sa.Float(), nullable=False),
|
||||
sa.Column('speed', sa.Float(), nullable=True),
|
||||
sa.Column('heading', sa.Float(), nullable=True),
|
||||
sa.Column('status', sa.Enum('ACTIVE', 'OFFLINE', 'BREAK', name='vehiclestatus'), nullable=False),
|
||||
sa.Column('timestamp', sa.DateTime(), server_default=sa.text('now()'), nullable=True),
|
||||
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_telemetry_timestamp'), 'telemetry', ['timestamp'], unique=False)
|
||||
op.create_index(op.f('ix_telemetry_user_id'), 'telemetry', ['user_id'], unique=False)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_index(op.f('ix_telemetry_user_id'), table_name='telemetry')
|
||||
op.drop_index(op.f('ix_telemetry_timestamp'), table_name='telemetry')
|
||||
op.drop_table('telemetry')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
"""enrich_coupons_with_business_details
|
||||
|
||||
Revision ID: dfbcee895f78
|
||||
Revises: 93054da1a687
|
||||
Create Date: 2026-01-28 11:08:39.830857
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import sqlmodel
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'dfbcee895f78'
|
||||
down_revision: Union[str, None] = '93054da1a687'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('coupons', sa.Column('business_name', sqlmodel.sql.sqltypes.AutoString(), nullable=True))
|
||||
op.add_column('coupons', sa.Column('business_address', sqlmodel.sql.sqltypes.AutoString(), nullable=True))
|
||||
op.add_column('coupons', sa.Column('business_phone', sqlmodel.sql.sqltypes.AutoString(), nullable=True))
|
||||
op.add_column('coupons', sa.Column('image_url', sqlmodel.sql.sqltypes.AutoString(), nullable=True))
|
||||
op.add_column('coupons', sa.Column('terms', sqlmodel.sql.sqltypes.AutoString(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('coupons', 'terms')
|
||||
op.drop_column('coupons', 'image_url')
|
||||
op.drop_column('coupons', 'business_phone')
|
||||
op.drop_column('coupons', 'business_address')
|
||||
op.drop_column('coupons', 'business_name')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
"""create_businesses_table_and_link_coupons
|
||||
|
||||
Revision ID: e5fb60c22245
|
||||
Revises: 94b4cb57c6c1
|
||||
Create Date: 2026-01-28 12:47:52.191359
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
import sqlmodel
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'e5fb60c22245'
|
||||
down_revision: Union[str, None] = '94b4cb57c6c1'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('businesses',
|
||||
sa.Column('id', sa.Uuid(), nullable=False),
|
||||
sa.Column('name', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
|
||||
sa.Column('address', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||
sa.Column('phone', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||
sa.Column('image_url', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||
sa.Column('social_media', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||
sa.Column('category', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.add_column('coupons', sa.Column('business_id', sa.Uuid(), nullable=True))
|
||||
op.create_foreign_key(None, 'coupons', 'businesses', ['business_id'], ['id'])
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint(None, 'coupons', type_='foreignkey')
|
||||
op.drop_column('coupons', 'business_id')
|
||||
op.drop_table('businesses')
|
||||
# ### end Alembic commands ###
|
||||
|
||||
Reference in New Issue
Block a user