Home Library Properties

Properties

Description

Overview

Properties represent real estate objects that users can manage. Each property has a name, description, color, type, and address integrated with Nova Poshta API.

Country

Each property is linked to a country. This determines which address format is used, currency defaults, and other regional settings.

  • Country is a required field when creating or editing a property
  • Address format depends on selected country (Nova Poshta API for Ukraine)
  • Country is displayed in property cards, lists, and detail pages

Example Response

{
  "id": 1,
  "name": "My Apartment",
  "country": {
    "id": 1,
    "code": "UA",
    "name_key": "country.ua"
  },
  "property_type": {...},
  "address": {...}
}

User Roles

Each property can have multiple users with different roles:

Owner

PROPERTY_LANDLORD

Full access: view, edit, delete property and manage users. Assigned automatically when creating a property.

  • View
  • Edit
  • Delete
  • Manage users

Owner's Representative

PROPERTY_LANDLORD_AGENT

Can view and edit the property, but cannot delete or manage users.

  • View
  • Edit
  • Delete
  • Manage users

Tenant

PROPERTY_TENANT

View-only access. Can see property details but cannot modify.

  • View
  • Edit
  • Delete
  • Manage users

Tenant's Representative

PROPERTY_TENANT_AGENT

View only. Represents tenant interests.

  • View
  • Edit
  • Delete
  • Manage users

Maintenance

PROPERTY_MAINTENANCE

View only. For maintenance personnel.

  • View
  • Edit
  • Delete
  • Manage users

User Management

The property owner (PROPERTY_LANDLORD) can add and remove other users:

  • Adding users: Search by email or phone. Result is shown only if exactly 1 user is found (privacy protection).
  • One role per property: Each user can have only one role within a property.
  • PROPERTY_LANDLORD cannot be added manually: This role is assigned automatically when creating a property.
  • Owner cannot be removed: Administration required to change owner.

REST API

All API endpoints require JWT authentication.

Service layer note

Properties API

GET    /api/v1/properties          # List user's properties
POST   /api/v1/properties          # Create property (user becomes PROPERTY_LANDLORD)
GET    /api/v1/properties/{id}     # Property details
PUT    /api/v1/properties/{id}     # Update (LANDLORD/LANDLORD_AGENT)
DELETE /api/v1/properties/{id}     # Delete (LANDLORD only)

Property Users API

GET    /api/v1/properties/{id}/users              # List property users
POST   /api/v1/properties/{id}/users              # Add user
DELETE /api/v1/properties/{id}/users/{userId}     # Remove user
GET    /api/v1/properties/{id}/search-user?q=...  # Search user
GET    /api/v1/properties/{id}/available-roles    # Available roles

Property Descriptions (Translations) API

GET    /api/v1/properties/{id}/descriptions              # List description translations
POST   /api/v1/properties/{id}/descriptions              # Create/update translation (locale + description)
POST   /api/v1/properties/{id}/descriptions/translate    # AI translate to target locale

AI Features API

POST   /api/v1/properties/generate-description    # Generate description via Grok AI (from form data)
POST   /api/v1/geo/geocode                        # Geocode address to lat/lng (public)

Nova Poshta Address API

GET /api/v1/nova-poshta/areas                    # List areas (oblasts)
GET /api/v1/nova-poshta/cities?area_ref=...      # Cities in area
GET /api/v1/nova-poshta/streets?city_ref=...&search=... # Search streets (min 1 char)
GET /api/v1/nova-poshta/search-by-zip?zip=...    # Find city by postal code (5 digits)

Example: Adding a User

POST /api/v1/properties/1/users
Content-Type: application/json
Authorization: Bearer <token>

{
  "user_id": 5,
  "role_id": 12
}

Example Response

{
  "message": "User added successfully",
  "data": {
    "id": 3,
    "user_id": 5,
    "email": "[email protected]",
    "name": "John Smith",
    "role": {
      "id": 12,
      "code": "PROPERTY_TENANT",
      "name_key": "role.property_tenant"
    },
    "created_at": "2026-01-05T14:30:00+00:00"
  }
}

Example: Property Response

{
  "id": 1,
  "name": "My Apartment",
  "description": "Apartment in the city center",
  "color": "var(--color-primary)",
  "property_type": {
    "id": 2,
    "code": "APARTMENT",
    "name_key": "property_type.apartment.name"
  },
  "address": {
    "area_ref": "71508128-9b87-11de-822f-000c2965ae0e",
    "area_name": "Kyiv Oblast",
    "city_ref": "e221d627-391c-11dd-90d9-001a92567626",
    "city_name": "Kyiv",
    "street_ref": "18e2ffc8-d68d-11e3-9937-003048d2b473",
    "street_name": "Khreschatyk",
    "building_number": "1A",
    "apartment_number": "42",
    "full_address": "Kyiv Oblast, Kyiv, Khreschatyk, bld. 1A, apt. 42"
  },
  "living_area": "45.50",
  "total_area": "57.80",
  "latitude": "50.4500336",
  "longitude": "30.5241361",
  "descriptions": [
    {"locale": "en", "description": "<p>Spacious apartment in the city center...</p>"},
    {"locale": "de", "description": "<p>Geräumige Wohnung im Stadtzentrum...</p>"}
  ],
  "user_role": "PROPERTY_LANDLORD",
  "users": [
    {
      "id": 1,
      "user_id": 2,
      "email": "[email protected]",
      "name": "Property Owner",
      "role": {"id": 10, "code": "PROPERTY_LANDLORD", "name_key": "role.property_landlord"},
      "created_at": "2026-01-05T12:00:00+00:00"
    }
  ],
  "created_at": "2026-01-05T12:00:00+00:00",
  "updated_at": "2026-01-05T14:30:00+00:00"
}

Multilingual Descriptions

Property descriptions can be translated to multiple languages. The main description is stored on the Property entity, translations are stored in PropertyDescription entity (one per locale).

  • Entity: PropertyDescription (property_id + locale + HTML description)
  • Supported locales: uk, en, ru, pl, de
  • AI translation: Grok AI translates HTML description preserving tags. Available via API and in the property form.
  • Form UX: Translation editors appear when main description has 20+ characters. Each language has a WYSIWYG editor + AI translate button.

Save translation example

POST /api/v1/properties/1/descriptions
Content-Type: application/json
Authorization: Bearer <token>

{
  "locale": "en",
  "description": "<p>Spacious apartment in the city center with a great view.</p>"
}

AI translate example

POST /api/v1/properties/1/descriptions/translate
Content-Type: application/json
Authorization: Bearer <token>

{
  "target_locale": "de",
  "source_html": "<p>Простора квартира в центрі міста.</p>"
}

// Response:
{
  "html": "<p>Geräumige Wohnung im Stadtzentrum.</p>",
  "locale": "de"
}

Property Data Values (Characteristics)

Each property can have additional characteristics such as room count, floor number, building type, etc. These values are stored in PropertyDataValue entity and linked to PropertyDataType.

Data Structure

  • PropertyDataType: Defines the characteristic type (code, name, data type, group, unit, icon)
  • PropertyDataValue: Stores the actual value for a property + data type combination

Data Type Groups

building

Building characteristics: floor count, year built, wall material, etc.

apartment

Apartment: rooms, area, floor, layout, condition, etc.

infrastructure

Infrastructure: elevators, distance to metro, schools, etc.

utilities

Utilities: heating, gas, water, electricity, internet, etc.

security

Security: alarm, video surveillance, concierge, etc.

parking

Parking: type, spaces count, garage, etc.

land

Land: area, purpose, category, soil type, etc.

other

Other: furniture, appliances, pets allowed, etc.

Value Types

Type Description Example
bool Boolean value 0, 1, true, false, yes, no
int Integer with min/max constraints 3, 25, 2024
float Decimal number with min/max constraints 45.5, 2.8
string Text, often with allowed values list brick, panoramic, euro_repair

Property Data Values API

GET    /api/v1/properties/{id}/data-values           # List all values
GET    /api/v1/properties/{id}/data-values/grouped    # Values grouped by category
GET    /api/v1/properties/{id}/data-values/{code}     # Get single value by code
POST   /api/v1/properties/{id}/data-values            # Set/update a value
PUT    /api/v1/properties/{id}/data-values/batch      # Batch update multiple values
DELETE /api/v1/properties/{id}/data-values/{code}     # Delete a value

Property Data Types API (Reference)

GET /api/v1/property-data-types                  # List all active types
GET /api/v1/property-data-types/grouped          # Types grouped by category
GET /api/v1/property-data-types/{code}           # Get type by code
GET /api/v1/property-data-types/meta/groups      # List available groups
GET /api/v1/property-data-types/meta/data-types  # List available data types

Example: Set a Data Value

POST /api/v1/properties/1/data-values
Content-Type: application/json
Authorization: Bearer <token>

{
  "code": "ROOM_COUNT",
  "value": "3"
}

Example Response

{
  "message": "Value set successfully",
  "data": {
    "id": 42,
    "code": "ROOM_COUNT",
    "name_key": "property_data_type.room_count.name",
    "data_type": "int",
    "group_code": "apartment",
    "value": "3",
    "formatted_value": "3",
    "unit": null,
    "icon_url": "https://s3.example.com/property_data_type/room_count.svg",
    "created_at": "2026-01-17T12:00:00",
    "updated_at": "2026-01-17T12:00:00"
  }
}

Example: Batch Update Values

PUT /api/v1/properties/1/data-values/batch
Content-Type: application/json
Authorization: Bearer <token>

{
  "values": {
    "ROOM_COUNT": "3",
    "FLOOR_NUMBER": "5",
    "HAS_BALCONY": "1",
    "BUILDING_TYPE": "brick",
    "WINDOW_VIEW": "park",
    "APARTMENT_CONDITION": ""
  }
}

Example Response

{
  "message": "Values updated successfully",
  "updated": 5,
  "removed": 1,
  "errors": []
}

UI Integration

Property data values are displayed in:

  • Property form: Collapsible section with grouped inputs for setting values
  • Property view page: Grouped display of all set values with icons
  • Property list: Icons preview of first 8 values in property cards

Validation

Values are validated according to their data type:

  • bool: Must be 0, 1, true, false, yes, or no
  • int: Must be integer within defined min/max range (e.g., ROOM_COUNT: 1-30)
  • float: Must be numeric within defined min/max range (e.g., CEILING_HEIGHT: 1.5-10.0)
  • string: Must match allowed values if defined (e.g., BUILDING_TYPE: panel, brick, monolith, etc.)

Swagger / OpenAPI

Full API documentation is available in Swagger UI: /api/v1/doc

  • 03. Properties / Data Values - Property characteristics CRUD API
  • 05. References / Property Data Types - Reference data for property data types