feat(backend): add video_url and video_position to properties

- Model: video_url VARCHAR(512) nullable, video_position VARCHAR(20) default 'section'
- Migration: k3l4m5n6o7p8_add_video_to_properties
- Admin route: expose/accept video_url (sanitize empty->NULL) and video_position
- Public schema: PropertyDetailOut exposes both fields
This commit is contained in:
MatheusAlves96 2026-04-22 23:57:28 -03:00
parent 7a53865408
commit d363a09f36
4 changed files with 40 additions and 1 deletions

View file

@ -51,6 +51,8 @@ class Property(db.Model):
index=True,
)
created_at = db.Column(db.DateTime, nullable=False, server_default=db.func.now())
video_url = db.Column(db.String(512), nullable=True)
video_position = db.Column(db.String(20), nullable=False, server_default='section')
photos = db.relationship(
"PropertyPhoto",

View file

@ -4,7 +4,7 @@ import re
import bcrypt
from datetime import datetime, date
from decimal import Decimal
from typing import Optional
from typing import Optional, Literal
from flask import Blueprint, request, jsonify, current_app, send_from_directory
from werkzeug.utils import secure_filename
from pydantic import BaseModel, ValidationError
@ -168,6 +168,8 @@ class PropertyAdminOut(BaseModel):
is_featured: bool
photos: list[PhotoAdminOut] = []
amenity_ids: list[int] = []
video_url: Optional[str] = None
video_position: Literal['carousel', 'section'] = 'section'
@classmethod
def from_prop(cls, p: Property) -> "PropertyAdminOut":
@ -203,6 +205,8 @@ class PropertyAdminOut(BaseModel):
for ph in p.photos
],
amenity_ids=[a.id for a in p.amenities],
video_url=p.video_url,
video_position=p.video_position,
)
@ -348,10 +352,15 @@ def admin_update_property(property_id: str):
"area_m2",
"city_id",
"neighborhood_id",
"video_position",
)
for field in _SCALAR_FIELDS:
if field in body:
setattr(prop, field, body[field])
# video_url: sanitizar e tratar string vazia como NULL
if 'video_url' in body:
raw = body['video_url']
prop.video_url = raw.strip() if raw and raw.strip() else None
# code: tratar string vazia como NULL
if "code" in body:
prop.code = body["code"] if body["code"] else None

View file

@ -61,3 +61,5 @@ class PropertyDetailOut(PropertyOut):
address: str | None = None
code: str | None = None
description: str | None = None
video_url: str | None = None
video_position: Literal['carousel', 'section'] = 'section'

View file

@ -0,0 +1,26 @@
"""add video to properties
Revision ID: k3l4m5n6o7p8
Revises: j2k3l4m5n6o7
Create Date: 2026-04-22
"""
import sqlalchemy as sa
from alembic import op
revision = 'k3l4m5n6o7p8'
down_revision = 'j2k3l4m5n6o7'
branch_labels = None
depends_on = None
def upgrade() -> None:
op.add_column('properties',
sa.Column('video_url', sa.String(512), nullable=True))
op.add_column('properties',
sa.Column('video_position', sa.String(20),
nullable=False, server_default='section'))
def downgrade() -> None:
op.drop_column('properties', 'video_position')
op.drop_column('properties', 'video_url')