feat: add full project - backend, frontend, docker, specs and configs

This commit is contained in:
MatheusAlves96 2026-04-20 23:59:45 -03:00
parent b77c7d5a01
commit e6cb06255b
24489 changed files with 61341 additions and 36 deletions

View file

@ -0,0 +1,79 @@
"""add property types amenities parking condo fee
Revision ID: 64dcf652e0b5
Revises: f030e6aef123
Create Date: 2026-04-13 18:55:09.490479
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '64dcf652e0b5'
down_revision = 'f030e6aef123'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('amenities',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=100), nullable=False),
sa.Column('slug', sa.String(length=120), nullable=False),
sa.Column('group', sa.Enum('caracteristica', 'lazer', 'condominio', 'seguranca', name='amenity_group'), nullable=False),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('amenities', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_amenities_slug'), ['slug'], unique=True)
op.create_table('property_types',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=100), nullable=False),
sa.Column('slug', sa.String(length=120), nullable=False),
sa.Column('parent_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['parent_id'], ['property_types.id'], ondelete='SET NULL'),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('property_types', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_property_types_parent_id'), ['parent_id'], unique=False)
batch_op.create_index(batch_op.f('ix_property_types_slug'), ['slug'], unique=True)
op.create_table('property_amenity',
sa.Column('property_id', sa.UUID(), nullable=False),
sa.Column('amenity_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['amenity_id'], ['amenities.id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['property_id'], ['properties.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('property_id', 'amenity_id')
)
with op.batch_alter_table('properties', schema=None) as batch_op:
batch_op.add_column(sa.Column('condo_fee', sa.Numeric(precision=10, scale=2), nullable=True))
batch_op.add_column(sa.Column('subtype_id', sa.Integer(), nullable=True))
batch_op.add_column(sa.Column('parking_spots', sa.Integer(), nullable=False))
batch_op.create_index(batch_op.f('ix_properties_subtype_id'), ['subtype_id'], unique=False)
batch_op.create_foreign_key(None, 'property_types', ['subtype_id'], ['id'], ondelete='SET NULL')
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('properties', schema=None) as batch_op:
batch_op.drop_constraint(None, type_='foreignkey')
batch_op.drop_index(batch_op.f('ix_properties_subtype_id'))
batch_op.drop_column('parking_spots')
batch_op.drop_column('subtype_id')
batch_op.drop_column('condo_fee')
op.drop_table('property_amenity')
with op.batch_alter_table('property_types', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_property_types_slug'))
batch_op.drop_index(batch_op.f('ix_property_types_parent_id'))
op.drop_table('property_types')
with op.batch_alter_table('amenities', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_amenities_slug'))
op.drop_table('amenities')
# ### end Alembic commands ###

View file

@ -0,0 +1,42 @@
"""add client_users table
Revision ID: a1b2c3d4e5f6
Revises: ec0a90848eff
Create Date: 2026-04-13 20:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "a1b2c3d4e5f6"
down_revision = "ec0a90848eff"
branch_labels = None
depends_on = None
def upgrade():
op.create_table(
"client_users",
sa.Column("id", sa.String(length=36), nullable=False),
sa.Column("name", sa.String(length=150), nullable=False),
sa.Column("email", sa.String(length=254), nullable=False),
sa.Column("password_hash", sa.String(length=100), nullable=False),
sa.Column(
"role", sa.String(length=20), nullable=False, server_default="client"
),
sa.Column(
"created_at", sa.DateTime(), nullable=False, server_default=sa.text("now()")
),
sa.PrimaryKeyConstraint("id"),
)
with op.batch_alter_table("client_users", schema=None) as batch_op:
batch_op.create_index("ix_client_users_email", ["email"], unique=True)
def downgrade():
with op.batch_alter_table("client_users", schema=None) as batch_op:
batch_op.drop_index("ix_client_users_email")
op.drop_table("client_users")

View file

@ -0,0 +1,52 @@
"""enrich_client_users
Revision ID: a2b3c4d5e6f7
Revises: f1a2b3c4d5e6
Create Date: 2026-04-14 00:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "a2b3c4d5e6f7"
down_revision = "f1a2b3c4d5e6"
branch_labels = None
depends_on = None
def upgrade():
with op.batch_alter_table("client_users") as batch_op:
batch_op.add_column(sa.Column("phone", sa.String(20), nullable=True))
batch_op.add_column(sa.Column("whatsapp", sa.String(20), nullable=True))
batch_op.add_column(sa.Column("cpf", sa.String(14), nullable=True))
batch_op.add_column(sa.Column("birth_date", sa.Date, nullable=True))
batch_op.add_column(sa.Column("address_street", sa.String(200), nullable=True))
batch_op.add_column(sa.Column("address_number", sa.String(20), nullable=True))
batch_op.add_column(
sa.Column("address_complement", sa.String(100), nullable=True)
)
batch_op.add_column(
sa.Column("address_neighborhood", sa.String(100), nullable=True)
)
batch_op.add_column(sa.Column("address_city", sa.String(100), nullable=True))
batch_op.add_column(sa.Column("address_state", sa.String(2), nullable=True))
batch_op.add_column(sa.Column("address_zip", sa.String(9), nullable=True))
batch_op.add_column(sa.Column("notes", sa.Text, nullable=True))
def downgrade():
with op.batch_alter_table("client_users") as batch_op:
batch_op.drop_column("notes")
batch_op.drop_column("address_zip")
batch_op.drop_column("address_state")
batch_op.drop_column("address_city")
batch_op.drop_column("address_neighborhood")
batch_op.drop_column("address_complement")
batch_op.drop_column("address_number")
batch_op.drop_column("address_street")
batch_op.drop_column("birth_date")
batch_op.drop_column("cpf")
batch_op.drop_column("whatsapp")
batch_op.drop_column("phone")

View file

@ -0,0 +1,117 @@
"""add saved_properties, visit_requests, boletos
Revision ID: b7c8d9e0f1a2
Revises: a1b2c3d4e5f6
Create Date: 2026-04-13 21:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "b7c8d9e0f1a2"
down_revision = "a1b2c3d4e5f6"
branch_labels = None
depends_on = None
def upgrade():
op.create_table(
"saved_properties",
sa.Column("id", sa.String(length=36), primary_key=True),
sa.Column(
"user_id",
sa.String(length=36),
sa.ForeignKey("client_users.id", ondelete="CASCADE"),
nullable=False,
index=True,
),
sa.Column(
"property_id",
sa.UUID(as_uuid=True),
sa.ForeignKey("properties.id", ondelete="SET NULL"),
nullable=True,
index=True,
),
sa.Column(
"created_at", sa.DateTime(), nullable=False, server_default=sa.text("now()")
),
sa.UniqueConstraint(
"user_id", "property_id", name="uq_saved_properties_user_property"
),
)
op.create_table(
"visit_requests",
sa.Column("id", sa.String(length=36), primary_key=True),
sa.Column(
"user_id",
sa.String(length=36),
sa.ForeignKey("client_users.id", ondelete="SET NULL"),
nullable=True,
index=True,
),
sa.Column(
"property_id",
sa.UUID(as_uuid=True),
sa.ForeignKey("properties.id", ondelete="SET NULL"),
nullable=True,
index=True,
),
sa.Column("message", sa.Text(), nullable=False),
sa.Column(
"status", sa.String(length=20), nullable=False, server_default="pending"
),
sa.Column("scheduled_at", sa.DateTime(), nullable=True),
sa.Column(
"created_at", sa.DateTime(), nullable=False, server_default=sa.text("now()")
),
)
op.create_table(
"boletos",
sa.Column("id", sa.String(length=36), primary_key=True),
sa.Column(
"user_id",
sa.String(length=36),
sa.ForeignKey("client_users.id", ondelete="SET NULL"),
nullable=True,
index=True,
),
sa.Column(
"property_id",
sa.UUID(as_uuid=True),
sa.ForeignKey("properties.id", ondelete="SET NULL"),
nullable=True,
index=True,
),
sa.Column("description", sa.String(length=200), nullable=False),
sa.Column("amount", sa.Numeric(12, 2), nullable=False),
sa.Column("due_date", sa.Date(), nullable=False),
sa.Column(
"status", sa.String(length=20), nullable=False, server_default="pending"
),
sa.Column("url", sa.String(length=500), nullable=True),
sa.Column(
"created_at", sa.DateTime(), nullable=False, server_default=sa.text("now()")
),
)
def downgrade():
with op.batch_alter_table("boletos", schema=None) as batch_op:
batch_op.drop_index("ix_boletos_property_id")
batch_op.drop_index("ix_boletos_user_id")
op.drop_table("boletos")
with op.batch_alter_table("visit_requests", schema=None) as batch_op:
batch_op.drop_index("ix_visit_requests_property_id")
batch_op.drop_index("ix_visit_requests_user_id")
op.drop_table("visit_requests")
with op.batch_alter_table("saved_properties", schema=None) as batch_op:
batch_op.drop_index("ix_saved_properties_property_id")
batch_op.drop_index("ix_saved_properties_user_id")
op.drop_table("saved_properties")

View file

@ -0,0 +1,74 @@
"""add cities neighborhoods location filters
Revision ID: c33f6a342c20
Revises: 64dcf652e0b5
Create Date: 2026-04-13 19:32:35.258299
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'c33f6a342c20'
down_revision = '64dcf652e0b5'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('cities',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=100), nullable=False),
sa.Column('slug', sa.String(length=120), nullable=False),
sa.Column('state', sa.String(length=2), nullable=False),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('cities', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_cities_slug'), ['slug'], unique=True)
op.create_table('neighborhoods',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=100), nullable=False),
sa.Column('slug', sa.String(length=120), nullable=False),
sa.Column('city_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['city_id'], ['cities.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('slug', 'city_id', name='uq_neighborhood_slug_city')
)
with op.batch_alter_table('neighborhoods', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_neighborhoods_city_id'), ['city_id'], unique=False)
batch_op.create_index(batch_op.f('ix_neighborhoods_slug'), ['slug'], unique=False)
with op.batch_alter_table('properties', schema=None) as batch_op:
batch_op.add_column(sa.Column('city_id', sa.Integer(), nullable=True))
batch_op.add_column(sa.Column('neighborhood_id', sa.Integer(), nullable=True))
batch_op.create_index(batch_op.f('ix_properties_city_id'), ['city_id'], unique=False)
batch_op.create_index(batch_op.f('ix_properties_neighborhood_id'), ['neighborhood_id'], unique=False)
batch_op.create_foreign_key(None, 'neighborhoods', ['neighborhood_id'], ['id'], ondelete='SET NULL')
batch_op.create_foreign_key(None, 'cities', ['city_id'], ['id'], ondelete='SET NULL')
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('properties', schema=None) as batch_op:
batch_op.drop_constraint(None, type_='foreignkey')
batch_op.drop_constraint(None, type_='foreignkey')
batch_op.drop_index(batch_op.f('ix_properties_neighborhood_id'))
batch_op.drop_index(batch_op.f('ix_properties_city_id'))
batch_op.drop_column('neighborhood_id')
batch_op.drop_column('city_id')
with op.batch_alter_table('neighborhoods', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_neighborhoods_slug'))
batch_op.drop_index(batch_op.f('ix_neighborhoods_city_id'))
op.drop_table('neighborhoods')
with op.batch_alter_table('cities', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_cities_slug'))
op.drop_table('cities')
# ### end Alembic commands ###

View file

@ -0,0 +1,42 @@
"""add page_views table
Revision ID: c8d9e0f1a2b3
Revises: b7c8d9e0f1a2
Create Date: 2026-04-14 00:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "c8d9e0f1a2b3"
down_revision = "b7c8d9e0f1a2"
branch_labels = None
depends_on = None
def upgrade():
op.create_table(
"page_views",
sa.Column("id", sa.Integer(), primary_key=True, autoincrement=True),
sa.Column("path", sa.String(length=512), nullable=False),
sa.Column("property_id", sa.String(length=36), nullable=True),
sa.Column(
"accessed_at",
sa.DateTime(timezone=True),
nullable=False,
server_default=sa.text("now()"),
),
sa.Column("ip_hash", sa.String(length=64), nullable=True),
sa.Column("user_agent", sa.String(length=512), nullable=True),
)
op.create_index("ix_page_views_accessed_at", "page_views", ["accessed_at"])
op.create_index("ix_page_views_property_id", "page_views", ["property_id"])
def downgrade():
op.drop_index("ix_page_views_property_id", table_name="page_views")
op.drop_index("ix_page_views_accessed_at", table_name="page_views")
op.drop_table("page_views")

View file

@ -0,0 +1,23 @@
"""merge heads
Revision ID: d0e1f2a3b4c5
Revises: a2b3c4d5e6f7, c8d9e0f1a2b3
Create Date: 2026-04-17 00:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'd0e1f2a3b4c5'
down_revision = ('a2b3c4d5e6f7', 'd1e2f3a4b5c6')
branch_labels = None
depends_on = None
def upgrade():
pass
def downgrade():
pass

View file

@ -0,0 +1,27 @@
"""add hero_image_url to homepage_config
Revision ID: d1e2f3a4b5c6
Revises: c8d9e0f1a2b3
Create Date: 2026-04-18 00:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
revision = "d1e2f3a4b5c6"
down_revision = "c8d9e0f1a2b3"
branch_labels = None
depends_on = None
def upgrade():
op.add_column(
"homepage_config",
sa.Column("hero_image_url", sa.String(length=512), nullable=True),
)
def downgrade():
op.drop_column("homepage_config", "hero_image_url")

View file

@ -0,0 +1,41 @@
"""add agents table
Revision ID: e1f2a3b4c5d6
Revises: d1e2f3a4b5c6
Create Date: 2026-04-17 00:00:00.000000
"""
import sqlalchemy as sa
from alembic import op
revision = "e1f2a3b4c5d6"
down_revision = "d1e2f3a4b5c6"
branch_labels = None
depends_on = None
def upgrade():
op.create_table(
"agents",
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
sa.Column("name", sa.String(length=200), nullable=False),
sa.Column("photo_url", sa.String(length=512), nullable=True),
sa.Column("creci", sa.String(length=50), nullable=False),
sa.Column("email", sa.String(length=200), nullable=False),
sa.Column("phone", sa.String(length=30), nullable=False),
sa.Column("bio", sa.Text(), nullable=True),
sa.Column("is_active", sa.Boolean(), nullable=False, server_default=sa.text("true")),
sa.Column("display_order", sa.Integer(), nullable=False, server_default=sa.text("0")),
sa.Column("created_at", sa.DateTime(), nullable=False, server_default=sa.func.now()),
sa.Column("updated_at", sa.DateTime(), nullable=False, server_default=sa.func.now()),
sa.PrimaryKeyConstraint("id"),
)
op.create_index("ix_agents_is_active", "agents", ["is_active"])
op.create_index("ix_agents_display_order", "agents", ["display_order"])
def downgrade():
op.drop_index("ix_agents_display_order", table_name="agents")
op.drop_index("ix_agents_is_active", table_name="agents")
op.drop_table("agents")

View file

@ -0,0 +1,34 @@
"""add parking_spots_covered to properties
Revision ID: e9f0a1b2c3d4
Revises: b7c8d9e0f1a2
Create Date: 2026-04-14 00:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "e9f0a1b2c3d4"
down_revision = "b7c8d9e0f1a2"
branch_labels = None
depends_on = None
def upgrade():
with op.batch_alter_table("properties", schema=None) as batch_op:
batch_op.add_column(
sa.Column(
"parking_spots_covered",
sa.Integer(),
nullable=False,
server_default="0",
)
)
def downgrade():
with op.batch_alter_table("properties", schema=None) as batch_op:
batch_op.drop_column("parking_spots_covered")

View file

@ -0,0 +1,54 @@
"""add contact_leads and property detail fields
Revision ID: ec0a90848eff
Revises: c33f6a342c20
Create Date: 2026-04-13 19:59:51.904013
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'ec0a90848eff'
down_revision = 'c33f6a342c20'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('contact_leads',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('property_id', sa.UUID(), nullable=True),
sa.Column('name', sa.String(length=150), nullable=False),
sa.Column('email', sa.String(length=254), nullable=False),
sa.Column('phone', sa.String(length=20), nullable=True),
sa.Column('message', sa.Text(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False),
sa.ForeignKeyConstraint(['property_id'], ['properties.id'], ondelete='SET NULL'),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('contact_leads', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_contact_leads_property_id'), ['property_id'], unique=False)
with op.batch_alter_table('properties', schema=None) as batch_op:
batch_op.add_column(sa.Column('code', sa.String(length=30), nullable=True))
batch_op.add_column(sa.Column('description', sa.Text(), nullable=True))
batch_op.create_unique_constraint(None, ['code'])
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('properties', schema=None) as batch_op:
batch_op.drop_constraint(None, type_='unique')
batch_op.drop_column('description')
batch_op.drop_column('code')
with op.batch_alter_table('contact_leads', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_contact_leads_property_id'))
op.drop_table('contact_leads')
# ### end Alembic commands ###

View file

@ -0,0 +1,69 @@
"""initial schema: properties, property_photos, homepage_config
Revision ID: f030e6aef123
Revises:
Create Date: 2026-04-13 17:39:07.705944
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'f030e6aef123'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('homepage_config',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('hero_headline', sa.String(length=120), nullable=False),
sa.Column('hero_subheadline', sa.String(length=240), nullable=True),
sa.Column('hero_cta_label', sa.String(length=40), nullable=False),
sa.Column('hero_cta_url', sa.String(length=200), nullable=False),
sa.Column('featured_properties_limit', sa.Integer(), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_table('properties',
sa.Column('id', sa.UUID(), nullable=False),
sa.Column('title', sa.String(length=200), nullable=False),
sa.Column('slug', sa.String(length=220), nullable=False),
sa.Column('address', sa.String(length=300), nullable=True),
sa.Column('price', sa.Numeric(precision=12, scale=2), nullable=False),
sa.Column('type', sa.Enum('venda', 'aluguel', name='property_type'), nullable=False),
sa.Column('bedrooms', sa.Integer(), nullable=False),
sa.Column('bathrooms', sa.Integer(), nullable=False),
sa.Column('area_m2', sa.Integer(), nullable=False),
sa.Column('is_featured', sa.Boolean(), nullable=False),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.PrimaryKeyConstraint('id')
)
with op.batch_alter_table('properties', schema=None) as batch_op:
batch_op.create_index(batch_op.f('ix_properties_slug'), ['slug'], unique=True)
op.create_table('property_photos',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('property_id', sa.UUID(), nullable=False),
sa.Column('url', sa.String(length=500), nullable=False),
sa.Column('alt_text', sa.String(length=200), nullable=False),
sa.Column('display_order', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['property_id'], ['properties.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('property_photos')
with op.batch_alter_table('properties', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_properties_slug'))
op.drop_table('properties')
op.drop_table('homepage_config')
# ### end Alembic commands ###

View file

@ -0,0 +1,28 @@
"""add iptu_anual to properties
Revision ID: f1a2b3c4d5e6
Revises: e9f0a1b2c3d4
Create Date: 2026-04-14 00:01:00.000000
"""
from alembic import op
import sqlalchemy as sa
revision = "f1a2b3c4d5e6"
down_revision = "e9f0a1b2c3d4"
branch_labels = None
depends_on = None
def upgrade():
with op.batch_alter_table("properties", schema=None) as batch_op:
batch_op.add_column(
sa.Column("iptu_anual", sa.Numeric(precision=12, scale=2), nullable=True)
)
def downgrade():
with op.batch_alter_table("properties", schema=None) as batch_op:
batch_op.drop_column("iptu_anual")

View file

@ -0,0 +1,51 @@
"""merge heads and add imobiliarias table
Revision ID: f2a3b4c5d6e7
Revises: d0e1f2a3b4c5, e1f2a3b4c5d6
Create Date: 2026-04-18 00:00:00.000000
"""
import sqlalchemy as sa
from alembic import op
revision = "f2a3b4c5d6e7"
down_revision = ("d0e1f2a3b4c5", "e1f2a3b4c5d6")
branch_labels = None
depends_on = None
def upgrade():
op.create_table(
"imobiliarias",
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
sa.Column("name", sa.String(length=200), nullable=False),
sa.Column("logo_url", sa.String(length=512), nullable=True),
sa.Column("website", sa.String(length=512), nullable=True),
sa.Column("is_active", sa.Boolean(), nullable=False, server_default="true"),
sa.Column("display_order", sa.Integer(), nullable=False, server_default="0"),
sa.Column(
"created_at",
sa.DateTime(),
nullable=False,
server_default=sa.text("now()"),
),
sa.PrimaryKeyConstraint("id"),
)
op.add_column(
"properties",
sa.Column(
"imobiliaria_id",
sa.Integer(),
sa.ForeignKey("imobiliarias.id", ondelete="SET NULL"),
nullable=True,
),
)
op.create_index("ix_properties_imobiliaria_id", "properties", ["imobiliaria_id"])
def downgrade():
op.drop_index("ix_properties_imobiliaria_id", table_name="properties")
op.drop_column("properties", "imobiliaria_id")
op.drop_table("imobiliarias")