- Update technology stack with implemented backend - Mark completed phases - Add src/server/ and data/ to file structure - Add validation.ts to structure
416 lines
16 KiB
Markdown
416 lines
16 KiB
Markdown
# TenerifeProp - Архитектура агентства недвижимости на Тенерифе
|
||
|
||
## 📋 Обзор проекта
|
||
|
||
**TenerifeProp** — веб-приложение для агентства недвижимости на острове Тенерифе (Канарские острова, Испания). Позволяет просматривать, фильтровать и подбирать земельные участки, дома и квартиры. Включает публичную часть (Landing, каталог, страница объекта) и административную панель.
|
||
|
||
## 🏗️ Сущности данных
|
||
|
||
### Основные сущности
|
||
|
||
| Сущность | Описание | Файл |
|
||
|----------|----------|------|
|
||
| **Property** | Недвижимость (участки, дома, квартиры) | `src/types/property.ts` |
|
||
| **Lead** | Потенциальный клиент (заявка) | `src/types/user.ts` |
|
||
| **User** | Пользователь системы (админ, агент) | `src/types/user.ts` |
|
||
| **Testimonial** | Отзыв клиента | `src/types/content.ts` |
|
||
| **Service** | Услуга агентства | `src/types/content.ts` |
|
||
| **FAQ** | Вопрос-ответ | `src/types/content.ts` |
|
||
| **Settings** | Настройки сайта | `src/types/content.ts` |
|
||
|
||
### Типы недвижимости
|
||
|
||
```typescript
|
||
type PropertyType =
|
||
| 'agricultural' // Сельскохозяйственный участок
|
||
| 'urban' // Городской участок
|
||
| 'house' // Дом/вилла
|
||
| 'apartment' // Квартира
|
||
| 'ruins' // Руины (под восстановление)
|
||
```
|
||
|
||
### Статусы недвижимости
|
||
|
||
```typescript
|
||
type PropertyStatus =
|
||
| 'active' // Активен (в продаже)
|
||
| 'reserved' // Зарезервирован
|
||
| 'sold' // Продан
|
||
| 'inactive' // Неактивен
|
||
```
|
||
|
||
### Статусы лидов
|
||
|
||
```typescript
|
||
type LeadStatus =
|
||
| 'new' // Новая заявка
|
||
| 'contacted' // Связались
|
||
| 'qualified' // Квалифицирован
|
||
| 'negotiating' // Переговоры
|
||
| 'closed' // Сделка закрыта
|
||
| 'lost' // Потерян
|
||
```
|
||
|
||
## 📁 Структура файлов
|
||
|
||
```
|
||
TenerifeProp/
|
||
├── public/ # Публичные файлы
|
||
│ ├── index.html # Главная страница (Landing)
|
||
│ ├── property.html # Страница объекта
|
||
│ ├── admin.html # Админ-панель
|
||
│ ├── css/
|
||
│ │ ├── variables.css # CSS переменные (цвета, шрифты)
|
||
│ │ ├── main.css # Основные стили
|
||
│ │ ├── property.css # Стили страницы объекта
|
||
│ │ └── admin.css # Стили админки
|
||
│ ├── js/
|
||
│ │ ├── app.js # Главная логика приложения
|
||
│ │ ├── property.js # Логика страницы объекта
|
||
│ │ ├── admin.js # Логика админки
|
||
│ │ ├── api.js # API клиент
|
||
│ │ ├── i18n.js # Система переводов
|
||
│ │ ├── map.js # Инициализация карты (Leaflet)
|
||
│ │ ├── charts.js # Графики (Chart.js)
|
||
│ │ └── utils.js # Утилиты
|
||
│ └── images/
|
||
│ ├── properties/ # Фото объектов
|
||
│ ├── agents/ # Фото агентов
|
||
│ └── icons/ # Иконки
|
||
├── src/
|
||
│ ├── server/ # Backend сервер
|
||
│ │ ├── index.ts # API сервер (Bun + Hono)
|
||
│ │ └── validation.ts # Zod схемы валидации
|
||
│ ├── types/ # TypeScript типы
|
||
│ │ ├── property.ts # Типы недвижимости
|
||
│ │ ├── user.ts # Типы пользователей и лидов
|
||
│ │ ├── content.ts # Типы контента
|
||
│ │ └── index.ts # Экспорт
|
||
│ ├── data/ # JSON база данных (deprecated - now using SQLite)
|
||
│ │ ├── properties.json # Объекты недвижимости
|
||
│ │ ├── leads.json # Заявки
|
||
│ │ ├── testimonials.json # Отзывы
|
||
│ │ ├── faq.json # FAQ
|
||
│ │ └── services.json # Услуги
|
||
│ ├── i18n/ # Переводы
|
||
│ │ ├── es.json # Испанский (основной)
|
||
│ │ ├── ru.json # Русский
|
||
│ │ └── en.json # Английский
|
||
│ └── utils/
|
||
│ ├── format.ts # Форматирование данных
|
||
│ ├── validation.ts # Валидация форм
|
||
│ └── api.ts # API клиент
|
||
├── data/ # SQLite база данных
|
||
│ └── tenerifeprop.db # Файл базы данных
|
||
├── docs/ # Документация
|
||
│ ├── ARCHITECTURE.md # Этот файл
|
||
│ ├── API.md # Документация API
|
||
│ └── DEPLOYMENT.md # Инструкции по деплою
|
||
├── .gitignore # Игнорируемые файлы
|
||
├── package.json # Зависимости проекта
|
||
├── tsconfig.json # Конфигурация TypeScript
|
||
└── README.md # Описание проекта
|
||
```
|
||
|
||
## 🔗 API Endpoints
|
||
|
||
### Недвижимость (Properties)
|
||
|
||
| Метод | Endpoint | Описание |
|
||
|-------|----------|----------|
|
||
| `GET` | `/api/properties` | Список объектов с фильтрами |
|
||
| `GET` | `/api/properties/:id` | Детали объекта |
|
||
| `GET` | `/api/properties/:slug` | Детали по slug |
|
||
| `POST` | `/api/properties` | Создать объект |
|
||
| `PUT` | `/api/properties/:id` | Обновить объект |
|
||
| `DELETE` | `/api/properties/:id` | Удалить объект |
|
||
| `GET` | `/api/properties/featured` | Избранные объекты |
|
||
| `GET` | `/api/properties/search` | Поиск с фильтрами |
|
||
|
||
### Заявки (Leads)
|
||
|
||
| Метод | Endpoint | Описание |
|
||
|-------|----------|----------|
|
||
| `GET` | `/api/leads` | Список заявок |
|
||
| `GET` | `/api/leads/:id` | Детали заявки |
|
||
| `POST` | `/api/leads` | Создать заявку (форма) |
|
||
| `PUT` | `/api/leads/:id` | Обновить заявку |
|
||
| `PUT` | `/api/leads/:id/status` | Изменить статус |
|
||
| `POST` | `/api/leads/:id/interaction` | Добавить взаимодействие |
|
||
|
||
### Пользователи (Users)
|
||
|
||
| Метод | Endpoint | Описание |
|
||
|-------|----------|----------|
|
||
| `POST` | `/api/auth/login` | Авторизация |
|
||
| `POST` | `/api/auth/logout` | Выход |
|
||
| `GET` | `/api/users/me` | Текущий пользователь |
|
||
| `PUT` | `/api/users/me` | Обновить профиль |
|
||
|
||
### Аналитика (Analytics)
|
||
|
||
| Метод | Endpoint | Описание |
|
||
|-------|----------|----------|
|
||
| `GET` | `/api/analytics/stats` | Статистика (Dashboard) |
|
||
| `GET` | `/api/analytics/events` | События |
|
||
| `POST` | `/api/analytics/event` | Записать событие |
|
||
|
||
### Контент (Content)
|
||
|
||
| Метод | Endpoint | Описание |
|
||
|-------|----------|----------|
|
||
| `GET` | `/api/testimonials` | Отзывы |
|
||
| `GET` | `/api/faq` | FAQ |
|
||
| `GET` | `/api/services` | Услуги |
|
||
| `GET` | `/api/pages/:slug` | Страница по slug |
|
||
| `GET` | `/api/settings` | Настройки сайта |
|
||
|
||
## 🎨 Компоненты UI
|
||
|
||
### Публичная часть (Landing)
|
||
|
||
1. **Header/Navbar** - Навигация, переключатель языка
|
||
2. **Hero** - Главный баннер с CTA
|
||
3. **Advantages** - Преимущества агентства
|
||
4. **Catalog** - Каталог с фильтрами
|
||
5. **PropertyCard** - Карточка объекта
|
||
6. **Map** - Интерактивная карта (Leaflet)
|
||
7. **Statistics** - Статистика в цифрах
|
||
8. **Services** - Услуги агентства
|
||
9. **Testimonials** - Отзывы клиентов
|
||
10. **FAQ** - Вопросы-ответы
|
||
11. **Contact** - Форма контакта
|
||
12. **Footer** - Подвал с контактами
|
||
|
||
### Страница объекта (Property)
|
||
|
||
1. **Gallery** - Галерея изображений
|
||
2. **PropertyHeader** - Заголовок, цена, характеристики
|
||
3. **Utilities** - Коммуникации (вода, свет, etc.)
|
||
4. **Documents** - Документы
|
||
5. **Map** - Карта с местоположением
|
||
6. **Calculator** - Калькулятор ипотеки/налогов
|
||
7. **ContactForm** - Форма запроса
|
||
8. **SimilarProperties** - Похожие объекты
|
||
|
||
### Админ-панель
|
||
|
||
1. **Sidebar** - Навигация по разделам
|
||
2. **Topbar** - Поиск, уведомления, профиль
|
||
3. **Dashboard** - Статистика, графики
|
||
4. **PropertyTable** - Таблица объектов (DataTables)
|
||
5. **PropertyForm** - Форма создания/редактирования
|
||
6. **LeadTable** - Таблица заявок
|
||
7. **LeadDetail** - Детали заявки
|
||
8. **ContentEditor** - Редактор контента
|
||
|
||
## 🛠️ Технологии
|
||
|
||
### Frontend
|
||
|
||
| Технология | Версия | Назначение |
|
||
|------------|--------|------------|
|
||
| HTML5 | - | Семантическая разметка |
|
||
| CSS3 | - | Стили, анимации |
|
||
| Bootstrap | 5.3.2 | UI Framework |
|
||
| Bootstrap Icons | 1.11.1 | Иконки |
|
||
| Leaflet | 1.9.4 | Интерактивные карты |
|
||
| Chart.js | 4.4.1 | Графики |
|
||
| DataTables | 1.13.8 | Таблицы с пагинацией |
|
||
| AOS | 2.3.4 | Анимации при скролле |
|
||
| Lightbox2 | 2.11.4 | Галерея изображений |
|
||
|
||
### Backend (Implemented)
|
||
|
||
| Технология | Назначение |
|
||
|------------|------------|
|
||
| **Bun** | Runtime |
|
||
| **Hono** | Web framework |
|
||
| **SQLite** | База данных |
|
||
| **Zod** | Валидация данных |
|
||
| **Bun.password** | Хеширование паролей |
|
||
|
||
### Implemented API
|
||
|
||
The API is implemented in `src/server/index.ts` with:
|
||
- Session-based authentication with HTTP-only cookies
|
||
- Full CRUD for properties, leads, testimonials, FAQ, services
|
||
- Admin endpoints protected by authentication middleware
|
||
- Input validation using Zod schemas
|
||
- Global error handling
|
||
|
||
See `docs/API.md` for complete API documentation.
|
||
|
||
## 🔄 Рефакторинг из HTML артефактов
|
||
|
||
### Переименование файлов
|
||
|
||
| Артефакт | Новый файл |
|
||
|----------|------------|
|
||
| `artifact-...-6.html` | `public/index.html` |
|
||
| `artifact-...-7.html` | `public/property.html` |
|
||
| `artifact-...-8.html` | `public/admin.html` |
|
||
|
||
### Извлечение CSS
|
||
|
||
CSS встроен в `<style>` внутри HTML. Нужно:
|
||
|
||
1. Создать `public/css/variables.css` с CSS-переменными:
|
||
- `--primary: #1a5f4a`
|
||
- `--secondary: #d4a853`
|
||
- `--accent: #e85d04`
|
||
- и т.д.
|
||
|
||
2. Создать `public/css/main.css` с общими стилями для Landing
|
||
|
||
3. Создать `public/css/property.css` со стилями страницы объекта
|
||
|
||
4. Создать `public/css/admin.css` со стилями админки
|
||
|
||
### Извлечение JavaScript
|
||
|
||
JavaScript встроен в `<script>` внутри HTML. Нужно:
|
||
|
||
1. Создать `public/js/i18n.js` для системы переводов:
|
||
- Загрузка JSON файла языка
|
||
- Функция `t(key)` для перевода
|
||
- Переключение языка
|
||
|
||
2. Создать `public/js/app.js`:
|
||
- Инициализация компонентов
|
||
- Фильтрация каталога
|
||
- Карта Leaflet
|
||
- Обработка форм
|
||
|
||
3. Создать `public/js/admin.js`:
|
||
- Инициализация DataTables
|
||
- CRUD операции
|
||
- Графики Chart.js
|
||
|
||
## 🌍 Система переводов (i18n)
|
||
|
||
### Структура JSON перевода
|
||
|
||
```json
|
||
// src/i18n/es.json
|
||
{
|
||
"nav": {
|
||
"home": "Inicio",
|
||
"catalog": "Catálogo",
|
||
...
|
||
},
|
||
"hero": {
|
||
"title1": "Terrenos y Propiedades",
|
||
...
|
||
}
|
||
}
|
||
```
|
||
|
||
### HTML атрибуты
|
||
|
||
```html
|
||
<h1 data-i18n="hero.title1">Terrenos y Propiedades</h1>
|
||
<p data-i18n="hero.subtitle">Encuentra tu terreno perfecto...</p>
|
||
```
|
||
|
||
### JavaScript
|
||
|
||
```javascript
|
||
// public/js/i18n.js
|
||
class I18n {
|
||
constructor() {
|
||
this.lang = 'es';
|
||
this.translations = {};
|
||
}
|
||
|
||
async setLanguage(lang) {
|
||
this.lang = lang;
|
||
this.translations = await fetch(`/src/i18n/${lang}.json`).then(r => r.json());
|
||
this.updateElements();
|
||
}
|
||
|
||
updateElements() {
|
||
document.querySelectorAll('[data-i18n]').forEach(el => {
|
||
const key = el.getAttribute('data-i18n');
|
||
el.textContent = this.t(key);
|
||
});
|
||
}
|
||
|
||
t(key) {
|
||
const keys = key.split('.');
|
||
let value = this.translations;
|
||
keys.forEach(k => value = value?.[k]);
|
||
return value || key;
|
||
}
|
||
}
|
||
```
|
||
|
||
## 📊 Пример данных
|
||
|
||
### Недвижимость
|
||
|
||
```json
|
||
{
|
||
"id": "prop-001",
|
||
"slug": "terreno-urbano-adeje",
|
||
"type": "urban",
|
||
"status": "active",
|
||
"title": {
|
||
"es": "Terreno Urbano en Adeje",
|
||
"ru": "Городской участок в Адехе"
|
||
},
|
||
"area": 2500,
|
||
"price": 385000,
|
||
"pricePerM2": 154,
|
||
"location": {
|
||
"city": "Adeje",
|
||
"zone": "Costa Adeje",
|
||
"coordinates": { "lat": 28.1227, "lng": -16.6942 }
|
||
},
|
||
"utilities": {
|
||
"water": "available",
|
||
"electricity": "available",
|
||
"road": "asphalt"
|
||
}
|
||
}
|
||
```
|
||
|
||
## 🚀 План реализации
|
||
|
||
### Фаза 1: Подготовка ✅ (Завершено)
|
||
- [x] Создать структуру директорий
|
||
- [x] Переименовать артефакты
|
||
- [x] Создать TypeScript типы
|
||
- [x] Создать JSON данные
|
||
- [x] Создать i18n файлы (es, ru, en)
|
||
|
||
### Фаза 2: Рефакторинг (В процессе)
|
||
- [ ] Вынести CSS в отдельные файлы
|
||
- [x] Вынести JS в модули (app.js, property.js, admin.js, api.js, i18n.js)
|
||
- [x] Настроить систему i18n
|
||
- [ ] Рефакторинг HTML компонентов
|
||
|
||
### Фаза 3: Backend ✅ (Завершено)
|
||
- [x] Настроить API сервер (Bun + Hono)
|
||
- [x] Реализовать CRUD для Property
|
||
- [x] Реализовать CRUD для Lead
|
||
- [x] Реализовать CRUD для Testimonials, FAQ, Services
|
||
- [x] Добавить авторизацию (сессии, cookies)
|
||
- [x] Добавить валидацию (Zod)
|
||
- [x] Docker конфигурация
|
||
|
||
### Фаза 4: Frontend (В процессе)
|
||
- [x] Подключить API к Frontend
|
||
- [x] Реализовать базовые фильтры
|
||
- [ ] Настроить карты (Leaflet)
|
||
- [ ] Оптимизация
|
||
|
||
### Фаза 5: Деплой (Ожидание)
|
||
- [ ] Сборка проекта
|
||
- [ ] Деплой на продакшн
|
||
- [ ] Тестирование
|
||
- [ ] Мониторинг
|
||
|
||
## 📝 Лицензия
|
||
|
||
MIT License - проект создан для UniqueSoft. |