- Create SQLite database schema with all tables - Implement REST API endpoints for properties, leads, testimonials, FAQ, services - Add seed data with sample properties, testimonials, FAQ - Create Docker configuration for deployment - Add i18n system for translations - Add API client for frontend integration - Create Technical Documentation (TZ.md) - Add detailed README with deployment instructions 🚀 Project is now fully functional: - API: http://localhost:8080/api/* - Properties CRUD with filtering - Lead management - Settings, Testimonials, FAQ, Services APIs - SQLite database with seed data
390 lines
15 KiB
Markdown
390 lines
15 KiB
Markdown
# Техническое Задание (ТЗ)
|
||
# TenerifeProp - Агентство недвижимости на Тенерифе
|
||
|
||
## 1. Введение
|
||
|
||
### 1.1 Назначение документа
|
||
Данный документ содержит полное техническое задание на разработку веб-приложения для агентства недвижимости TenerifeProp, расположенного на острове Тенерифе (Канарские острова, Испания).
|
||
|
||
### 1.2 Область применения
|
||
Веб-приложение предназначено для:
|
||
- Публичного показа объектов недвижимости (участки, дома, квартиры)
|
||
- Сбора заявок от потенциальных клиентов
|
||
- Управления контентом и объектами через административную панель
|
||
- Работы на испанском и русском языках
|
||
|
||
### 1.3 Термины и определения
|
||
|
||
| Термин | Определение |
|
||
|--------|-------------|
|
||
| Property | Объект недвижимости (участок, дом, квартира) |
|
||
| Lead | Потенциальный клиент, оставивший заявку |
|
||
| Agricultural land | Сельскохозяйственный участок (terreno agrícola) |
|
||
| Urban land | Городской участок (terreno urbano) |
|
||
| Ruins | Руины, здания под восстановление |
|
||
|
||
---
|
||
|
||
## 2. Сущности данных
|
||
|
||
### 2.1 Property (Недвижимость)
|
||
|
||
#### Атрибуты
|
||
|
||
| Поле | Тип | Обязательно | Описание |
|
||
|------|-----|--------------|----------|
|
||
| id | TEXT (UUID) | Да | Уникальный идентификатор |
|
||
| slug | TEXT | Да | URL-friendly идентификатор |
|
||
| reference | TEXT | Да | Человекочитаемый ID (TP-001) |
|
||
| type | ENUM | Да | agricultural, urban, house, apartment, ruins |
|
||
| status | ENUM | Да | active, reserved, sold, inactive |
|
||
| land_type | ENUM | Да | agricultural, urban, rustic, buildable |
|
||
| title_es | TEXT | Да | Название на испанском |
|
||
| title_ru | TEXT | Да | Название на русском |
|
||
| description_es | TEXT | Да | Описание на испанском |
|
||
| description_ru | TEXT | Да | Описание на русском |
|
||
| short_description_es | TEXT | Нет | Краткое описание ES |
|
||
| short_description_ru | TEXT | Нет | Краткое описание RU |
|
||
| address | TEXT | Да | Адрес |
|
||
| city | TEXT | Да | Город |
|
||
| province | TEXT | Да | Провинция |
|
||
| postal_code | TEXT | Да | Почтовый индекс |
|
||
| zone | TEXT | Нет | Район/зона |
|
||
| lat | REAL | Да | Широта |
|
||
| lng | REAL | Да | Долгота |
|
||
| area | INTEGER | Да | Площадь (m²) |
|
||
| price | INTEGER | Да | Цена (EUR) |
|
||
| price_per_m2 | INTEGER | Нет | Цена за m² |
|
||
| bedrooms | INTEGER | Нет | Спальни (для домов) |
|
||
| bathrooms | INTEGER | Нет | Ванные (для домов) |
|
||
| water | TEXT | Да | water status: available, unavailable, planned |
|
||
| electricity | TEXT | Да | electricity status |
|
||
| phone | TEXT | Да | phone status |
|
||
| drainage | TEXT | Да | drainage status |
|
||
| road | TEXT | Да | road type: asphalt, dirt, planned |
|
||
| gas | TEXT | Да | gas status |
|
||
| orientation | TEXT | Да | north, south, east, west |
|
||
| views_sea | BOOLEAN | Да | Вид на море |
|
||
| views_mountain | BOOLEAN | Да | Вид на горы |
|
||
| views_valley | BOOLEAN | Да | Вид на долину |
|
||
| topography | TEXT | Да | flat, slope, terraced |
|
||
| has_ruins | BOOLEAN | Да | Есть руины |
|
||
| has_license | BOOLEAN | Да | Есть лицензия |
|
||
| is_buildable | BOOLEAN | Да | Можно строить |
|
||
| max_floors | INTEGER | Нет | Макс. этажей |
|
||
| buildability_ratio | REAL | Нет | Коэф. застройки |
|
||
| images | TEXT (JSON) | Да | Массив URL изображений |
|
||
| videos | TEXT (JSON) | Нет | Массив URL видео |
|
||
| badges | TEXT (JSON) | Нет | Метки: new, exclusive, featured |
|
||
| meta_title_es | TEXT | Нет | SEO title ES |
|
||
| meta_title_ru | TEXT | Нет | SEO title RU |
|
||
| meta_description_es | TEXT | Нет | SEO description ES |
|
||
| meta_description_ru | TEXT | Нет | SEO description RU |
|
||
| views_count | INTEGER | Да | Счётчик просмотров |
|
||
| favorite_count | INTEGER | Да | Счётчик избранного |
|
||
| inquiry_count | INTEGER | Да | Счётчик заявок |
|
||
| is_featured | BOOLEAN | Да | Рекомендуемый |
|
||
| is_exclusive | BOOLEAN | Да | Эксклюзивный |
|
||
| agent_id | TEXT | Да | ID агента |
|
||
| created_at | TEXT (ISO) | Да | Дата создания |
|
||
| updated_at | TEXT (ISO) | Да | Дата обновления |
|
||
| published_at | TEXT (ISO) | Нет | Дата публикации |
|
||
|
||
#### Индексы
|
||
- `idx_property_slug` ON slug
|
||
- `idx_property_type` ON type
|
||
- `idx_property_status` ON status
|
||
- `idx_property_city` ON city
|
||
- `idx_property_price` ON price
|
||
|
||
### 2.2 Lead (Заявка)
|
||
|
||
| Поле | Тип | Обязательно | Описание |
|
||
|------|-----|--------------|----------|
|
||
| id | TEXT (UUID) | Да | Уникальный идентификатор |
|
||
| name | TEXT | Да | Имя клиента |
|
||
| email | TEXT | Да | Email |
|
||
| phone | TEXT | Да | Телефон |
|
||
| message | TEXT | Нет | Сообщение |
|
||
| property_id | TEXT | Нет | ID интересующего объекта |
|
||
| property_ids | TEXT (JSON) | Нет | Массив ID объектов |
|
||
| budget_min | INTEGER | Нет | Мин. бюджет |
|
||
| budget_max | INTEGER | Нет | Макс. бюджет |
|
||
| currency | TEXT | Да | EUR, USD, RUB |
|
||
| language | TEXT | Да | Предпочитаемый язык |
|
||
| source | TEXT | Да | whatsapp, webform, phone, email |
|
||
| utm_source | TEXT | Нет | UTM Source |
|
||
| utm_medium | TEXT | Нет | UTM Medium |
|
||
| utm_campaign | TEXT | Нет | UTM Campaign |
|
||
| status | TEXT | Да | new, contacted, qualified, negotiating, closed, lost |
|
||
| priority | TEXT | Да | low, medium, high, urgent |
|
||
| notes | TEXT | Нет | Заметки |
|
||
| assigned_to | TEXT | Нет | ID агента |
|
||
| created_at | TEXT (ISO) | Да | Дата создания |
|
||
| updated_at | TEXT (ISO) | Да | Дата обновления |
|
||
|
||
### 2.3 User (Пользователь)
|
||
|
||
| Поле | Тип | Обязательно | Описание |
|
||
|------|-----|--------------|----------|
|
||
| id | TEXT (UUID) | Да | Уникальный идентификатор |
|
||
| email | TEXT | Да | Email (уникальный) |
|
||
| password_hash | TEXT | Да | Хеш пароля |
|
||
| name | TEXT | Да | Имя |
|
||
| role | TEXT | Да | admin, agent, editor |
|
||
| avatar | TEXT | Нет | URL аватара |
|
||
| phone | TEXT | Нет | Телефон |
|
||
| language | TEXT | Да | es, ru |
|
||
| is_active | BOOLEAN | Да | Активен |
|
||
| last_login_at | TEXT (ISO) | Нет | Последний вход |
|
||
| created_at | TEXT (ISO) | Да | Дата создания |
|
||
| updated_at | TEXT (ISO) | Да | Дата обновления |
|
||
|
||
### 2.4 Testimonial (Отзыв)
|
||
|
||
| Поле | Тип | Обязательно | Описание |
|
||
|------|-----|--------------|----------|
|
||
| id | TEXT (UUID) | Да | Уникальный идентификатор |
|
||
| name | TEXT | Да | Имя клиента |
|
||
| avatar | TEXT | Нет | URL аватара |
|
||
| location | TEXT | Да | Местоположение |
|
||
| rating | INTEGER | Да | Оценка 1-5 |
|
||
| text_es | TEXT | Да | Текст ES |
|
||
| text_ru | TEXT | Да | Текст RU |
|
||
| property_id | TEXT | Нет | ID объекта |
|
||
| is_approved | BOOLEAN | Да | Одобрен |
|
||
| is_featured | BOOLEAN | Да | Рекомендуемый |
|
||
| created_at | TEXT (ISO) | Да | Дата создания |
|
||
|
||
### 2.5 FAQ (Вопрос-ответ)
|
||
|
||
| Поле | Тип | Обязательно | Описание |
|
||
|------|-----|--------------|----------|
|
||
| id | TEXT (UUID) | Да | Уникальный идентификатор |
|
||
| question_es | TEXT | Да | Вопрос ES |
|
||
| question_ru | TEXT | Да | Вопрос RU |
|
||
| answer_es | TEXT | Да | Ответ ES |
|
||
| answer_ru | TEXT | Да | Ответ RU |
|
||
| category | TEXT | Да | Категория |
|
||
| order_num | INTEGER | Да | Порядок |
|
||
| is_active | BOOLEAN | Да | Активен |
|
||
|
||
### 2.6 Service (Услуга)
|
||
|
||
| Поле | Тип | Обязательно | Описание |
|
||
|------|-----|--------------|----------|
|
||
| id | TEXT (UUID) | Да | Уникальный идентификатор |
|
||
| icon | TEXT | Да | Имя иконки |
|
||
| title_es | TEXT | Да | Название ES |
|
||
| title_ru | TEXT | Да | Название RU |
|
||
| description_es | TEXT | Да | Описание ES |
|
||
| description_ru | TEXT | Да | Описание RU |
|
||
| order_num | INTEGER | Да | Порядок |
|
||
| is_active | BOOLEAN | Да | Активна |
|
||
|
||
### 2.7 Settings (Настройки)
|
||
|
||
| Поле | Тип | Описание |
|
||
|------|-----|----------|
|
||
| key | TEXT | Ключ настройки |
|
||
| value | TEXT | Значение (JSON) |
|
||
|
||
**Системные настройки:**
|
||
- `site_name` - Название сайта
|
||
- `phone` - Телефон
|
||
- `whatsapp` - WhatsApp номер
|
||
- `email` - Email
|
||
- `address` - Адрес (JSON)
|
||
- `social` - Социальные сети (JSON)
|
||
- `default_map_center` - Центр карты по умолчанию (JSON)
|
||
- `default_map_zoom` - Масштаб карты
|
||
|
||
### 2.8 Analytics Event (Событие аналитики)
|
||
|
||
| Поле | Тип | Описание |
|
||
|------|-----|----------|
|
||
| id | TEXT (UUID) | Уникальный идентификатор |
|
||
| type | TEXT | Тип события |
|
||
| property_id | TEXT | ID объекта (если применимо) |
|
||
| session_id | TEXT | ID сессии |
|
||
| ip_address | TEXT | IP адрес |
|
||
| user_agent | TEXT | User Agent |
|
||
| metadata | TEXT (JSON) | Метаданные |
|
||
| created_at | TEXT (ISO) | Дата создания |
|
||
|
||
---
|
||
|
||
## 3. API Endpoints
|
||
|
||
### 3.1 Недвижимость
|
||
|
||
```
|
||
GET /api/properties # Список объектов (?type=&status=&city=&minPrice=&maxPrice=&minArea=&maxArea=&page=&limit=)
|
||
GET /api/properties/:slug # Детали по slug
|
||
GET /api/properties/featured # Рекомендуемые
|
||
POST /api/properties # Создать (admin)
|
||
PUT /api/properties/:id # Обновить (admin)
|
||
DELETE /api/properties/:id # Удалить (admin)
|
||
GET /api/properties/search # Поиск (?q=)
|
||
```
|
||
|
||
### 3.2 Заявки
|
||
|
||
```
|
||
GET /api/leads # Список заявок (admin)
|
||
GET /api/leads/:id # Детали заявки (admin)
|
||
POST /api/leads # Создать заявку (public)
|
||
PUT /api/leads/:id # Обновить (admin)
|
||
PUT /api/leads/:id/status # Изменить статус (admin)
|
||
DELETE /api/leads/:id # Удалить (admin)
|
||
```
|
||
|
||
### 3.3 Контент
|
||
|
||
```
|
||
GET /api/testimonials # Список отзывов
|
||
POST /api/testimonials # Создать (admin)
|
||
GET /api/faq # Список FAQ
|
||
GET /api/services # Список услуг
|
||
GET /api/settings # Настройки сайта
|
||
```
|
||
|
||
### 3.4 Аналитика
|
||
|
||
```
|
||
POST /api/analytics/event # Записать событие
|
||
GET /api/analytics/stats # Статистика (admin)
|
||
```
|
||
|
||
### 3.5 Авторизация
|
||
|
||
```
|
||
POST /api/auth/login # Вход
|
||
POST /api/auth/logout # Выход
|
||
GET /api/auth/me # Текущий пользователь
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Страницы Frontend
|
||
|
||
### 4.1 Публичные страницы
|
||
|
||
1. **Landing Page** (`/`)
|
||
- Hero секция с CTA
|
||
- Преимущества
|
||
- Каталог с фильтрами
|
||
- Интерактивная карта
|
||
- Статистика
|
||
- Услуги
|
||
- Отзывы
|
||
- FAQ
|
||
- Контактная форма
|
||
- Footer
|
||
|
||
2. **Страница объекта** (`/property/:slug`)
|
||
- Галерея изображений
|
||
- Характеристики
|
||
- Коммуникации
|
||
- Документы
|
||
- Карта
|
||
- Калькулятор
|
||
- Форма запроса
|
||
- Похожие объекты
|
||
|
||
3. **Страница 404** (`/404`)
|
||
|
||
### 4.2 Админ-панель (`/admin`)
|
||
|
||
1. **Dashboard**
|
||
- Статистика
|
||
- Графики
|
||
- Последние заявки
|
||
|
||
2. **Управление объектами**
|
||
- Таблица с фильтрами
|
||
- CRUD операции
|
||
|
||
3. **Управление заявками**
|
||
- Таблица
|
||
- Детали
|
||
- Изменение статуса
|
||
|
||
4. **Управление контентом**
|
||
- Отзывы
|
||
- FAQ
|
||
- Услуги
|
||
|
||
5. **Настройки**
|
||
- Контакты
|
||
- Социальные сети
|
||
- SEO
|
||
|
||
---
|
||
|
||
## 5. Технологии
|
||
|
||
### Frontend
|
||
- HTML5 + CSS3
|
||
- Bootstrap 5.3
|
||
- Bootstrap Icons
|
||
- Leaflet (карты)
|
||
- Chart.js (графики)
|
||
- DataTables (таблицы)
|
||
- AOS (анимации)
|
||
- Lightbox2 (галерея)
|
||
|
||
### Backend
|
||
- Bun runtime
|
||
- Hono framework
|
||
- SQLite база данных
|
||
- Zod валидация
|
||
|
||
### Deployment
|
||
- Docker контейнер
|
||
- Порт 8080
|
||
|
||
---
|
||
|
||
## 6. Требования к проекту
|
||
|
||
### 6.1 Функциональные требования
|
||
|
||
1. **Мультиязычность**
|
||
- Испанский (ES) - основной
|
||
- Русский (RU)
|
||
- Переключение без перезагрузки
|
||
|
||
2. **Каталог недвижимости**
|
||
- Фильтрация по типу, цене, площади
|
||
- Фильтрация по коммуникациям
|
||
- Поиск по названию/городу
|
||
- Карта с маркерами объектов
|
||
|
||
3. **Заявки**
|
||
- Форма на странице объекта
|
||
- Форма в контактах
|
||
- WhatsApp интеграция
|
||
- Email уведомления
|
||
|
||
4. **Админ-панель**
|
||
- Авторизация
|
||
- CRUD для объектов
|
||
- Управление заявками
|
||
- Статистика и аналитика
|
||
|
||
### 6.2 Нефункциональные требования
|
||
|
||
1. **Производительность**
|
||
- Время загрузки страницы < 3 сек
|
||
- Время ответа API < 500 мс
|
||
|
||
2. **Безопасность**
|
||
- Хеширование паролей (bcrypt)
|
||
- Защита от CSRF
|
||
- Валидация входных данных
|
||
|
||
3. **Доступность**
|
||
- Responsive дизайн
|
||
- Поддержка мобильных устройств
|
||
- SEO оптимизация |