feat: add full project - backend, frontend, docker, specs and configs
This commit is contained in:
parent
b77c7d5a01
commit
e6cb06255b
24489 changed files with 61341 additions and 36 deletions
|
|
@ -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 ###
|
||||
42
backend/migrations/versions/a1b2c3d4e5f6_add_client_users.py
Normal file
42
backend/migrations/versions/a1b2c3d4e5f6_add_client_users.py
Normal 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")
|
||||
|
|
@ -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")
|
||||
|
|
@ -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")
|
||||
|
|
@ -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 ###
|
||||
|
|
@ -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")
|
||||
23
backend/migrations/versions/d0e1f2a3b4c5_merge_heads.py
Normal file
23
backend/migrations/versions/d0e1f2a3b4c5_merge_heads.py
Normal 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
|
||||
|
|
@ -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")
|
||||
41
backend/migrations/versions/e1f2a3b4c5d6_add_agents_table.py
Normal file
41
backend/migrations/versions/e1f2a3b4c5d6_add_agents_table.py
Normal 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")
|
||||
|
|
@ -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")
|
||||
|
|
@ -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 ###
|
||||
|
|
@ -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 ###
|
||||
28
backend/migrations/versions/f1a2b3c4d5e6_add_iptu_anual.py
Normal file
28
backend/migrations/versions/f1a2b3c4d5e6_add_iptu_anual.py
Normal 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")
|
||||
|
|
@ -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")
|
||||
Loading…
Add table
Add a link
Reference in a new issue