# Мониторинг земель

[![Version](https://img.shields.io/badge/version-v1.5.7-blue.svg)](https://192.168.1.111/viktor/landmonitoring) [![Python](https://img.shields.io/badge/python-3.8+-green.svg)](https://python.org) [![Flask](https://img.shields.io/badge/flask-2.3.3-red.svg)](https://flask.palletsprojects.com) [![PostgreSQL](https://img.shields.io/badge/postgresql-12+-blue.svg)](https://postgresql.org) [![License](https://img.shields.io/badge/license-Proprietary-orange.svg)](LICENSE)

Веб-приложение для мониторинга земель на основе картографических данных. Приложение предоставляет интерактивную карту с возможностью просмотра различных слоев данных о земельных ресурсах, систему заявок на услуги и документооборот.

## 📋 Содержание

- [🔧 Требования к окружению](#-требования-к-окружению)
- [🚀 Функциональность](#-функциональность)
- [🛠️ Технологии](#️-технологии)
- [🏗️ Архитектура](#️-архитектура)
- [⚡ Установка и запуск](#-установка-и-запуск)
- [🔌 API Endpoints](#-api-endpoints)
- [🗄️ База данных](#️-база-данных)
- [👥 Система ролей](#-система-ролей-и-прав-доступа)
- [🌍 Локализация](#-локализация)
- [🗜️ Gzip сжатие](#️-gzip-сжатие)
- [🛠️ Разработка](#️-разработка)
- [🧪 Тестирование](#-тестирование)
- [🔧 Устранение неполадок](#-устранение-неполадок)
- [🔄 Миграция на ArcGIS Server](#-миграция-на-arcgis-server)
- [🚀 Деплой](#-деплой)
- [🪟 Развертывание на Windows](#-развертывание-на-windows)
- [📋 История версий](#-история-версий)
- [📞 Контакты](#-контакты)

## 🔧 Требования к окружению

### 💻 Системные требования
- **ОС**: Linux (Ubuntu 18.04+), macOS 10.15+, Windows 10+
- **Python**: 3.8 или выше
- **PostgreSQL**: 12 или выше
- **RAM**: минимум 2GB, рекомендуется 4GB+
- **Дисковое пространство**: минимум 1GB свободного места

### 🌐 Сетевые требования
- Доступ к интернету для загрузки зависимостей
- Доступ к геосерверам (локальный и глобальный)
- Открытый порт 8080 для веб-интерфейса

## 🚀 Функциональность

### 🗺️ Картографическая система
- **Интерактивная карта**: Отображение картографических данных с использованием Leaflet.js и ESRI Leaflet
- **Многослойность**: Поддержка различных слоев (границы областей, почвенные карты, геоботанические карты, земельные участки)
- **Поиск по кадастровому номеру**: Быстрый поиск земельных участков по кадастровому номеру с визуализацией на карте
  - Интерактивный интерфейс поиска с автоматической подсветкой найденных участков
  - Модальное окно с детальными атрибутами участка (площадь, адрес, назначение и др.)
  - Автоматическое центрирование карты на найденном участке
  - Поддержка всех типов геометрии (Point, LineString, Polygon, MultiPolygon)
  - Интеграция с ЕГКН (Единый государственный кадастр недвижимости)
- **Поиск**: Поиск по областям, районам и наименованиям
- **Базовые карты**: Поддержка различных базовых карт (Google Maps, Bing Maps, OSM)
- **Настройка прозрачности**: Регулировка прозрачности слоев
- **Автоматическое переключение геосерверов**: Отказоустойчивость при недоступности серверов
- **ArcGIS Server интеграция**: Поддержка ArcGIS REST API для улучшенной производительности
- **Динамические слои**: Автоматическое получение метаданных и легенд слоев
- **Оптимизированные запросы**: Кэширование и оптимизация запросов к серверу
- **REST API интеграция**: Прямое подключение к ArcGIS Server через REST API
- **Динамические слои**: Автоматическое получение метаданных и управление видимостью слоев
- **Тестирование сервисов**: Страница `/test` для просмотра списка сервисов ArcGIS с измерением времени загрузки
- **ОЦСК сервисы**: Интеграция с ОЦСК (Открывая цифровая сельскохозяйственна карта) сервисами
  - Маршрут `/ocsk-services` для получения списка ОЦСК сервисов из JSON файла
  - Отображение ОЦСК сервисов на карте с элементами управления
  - Панель агрохимии с настройками для работы с ОЦСК данными
  - Интеграция с JavaScript модулем для управления ОЦСК сервисами

### 🔐 Система аутентификации и авторизации
- **Аутентификация по ЭЦП**: Система входа в приложение с использованием электронной цифровой подписи
- **Управление сессиями**: Flask-Session для безопасного хранения данных пользователей с настраиваемым временем жизни (3 часа по умолчанию)
- **Роли пользователей**: Система ролей (user, admin) с разграничением прав доступа
- **История авторизаций**: Отслеживание всех попыток входа/выхода пользователей
- **Управление пользователями**: Добавление, редактирование и удаление пользователей (для администраторов)

### 👤 Личный кабинет и настройки
- **Настройки пользователей**: Сохранение и загрузка персональных настроек (телефон, email)
- **Личный кабинет**: Управление заявками на услуги с реальными данными из БД
- **Профиль пользователя**: Просмотр и редактирование личной информации

### 📋 Система заявок и документооборота
- **Создание заявок**: Пошаговая форма создания заявок на услуги
- **Управление заявками**: Просмотр, редактирование и удаление заявок
- **Детальный просмотр заявок**: Модальное окно с полной информацией о заявке при клике на номер
- **Статусы заявок**: Отслеживание статуса выполнения заявок
- **Документооборот**: Прикрепление документов к заявкам с поддержкой различных форматов
- **Фильтрация и поиск**: Поиск заявок по различным критериям
- **Права доступа**: Разграничение прав на просмотр и управление заявками
- **Уведомления о приеме заявок**: Автоматическая генерация PDF уведомлений с QR-кодом для верификации

### 🏞️ Мои участки и отводы (в настройках)
- **CRUD**: добавление, редактирование, удаление записей
- **Хранение**: БД `giprozem.user_plots` (координаты в формате GeoJSON, JSONB)
- **Права**: доступно роли пользователя (00) и выше

### 🌍 Многоязычность и интерфейс
- **Многоязычность**: Поддержка русского и казахского языков
- **Адаптивный дизайн**: Современный интерфейс на основе Bootstrap 5
- **Уведомления**: Система уведомлений для пользователей
- **Модальные окна**: Интерактивные диалоги для различных операций
  - в т.ч. модалка редактирования участков с валидацией

### 📊 Система логирования и мониторинга
- **Детальное логирование**: Логирование всех операций в файл и консоль
- **Мониторинг геосерверов**: Автоматическая проверка доступности серверов
- **Отслеживание ошибок**: Логирование ошибок и исключений
- **Логирование действий пользователей**: Отслеживание всех действий пользователей с фильтрацией и экспортом
- **Системные логи**: Просмотр, скачивание и управление лог файлами системы
  - Ротация файлов: до 5 файлов, каждый не более 1 МБ
  - Просмотр содержимого лог файлов в веб-интерфейсе
  - Скачивание отдельных файлов и архива всех логов
  - Информация о размере, дате изменения и количестве строк

### 📈 Экспорт данных
- **Экспорт в Excel**: Функционал экспорта данных земельных участков в формат Excel
  - Маршрут `/export/zu-excel` для экспорта результатов поиска участков
  - Автоматическое форматирование данных для Excel с сохранением структуры
  - Интеграция с модулем поиска для экспорта найденных участков
  - Кнопка экспорта в модальном окне результатов поиска
  - Поддержка экспорта атрибутов участков (кадастровый номер, площадь, адрес и др.)

## 🛠️ Технологии

### ⚙️ Серверная часть
- **Python 3.8+**
- **Flask 2.3.3** - веб-фреймворк
- **Flask-Session 0.5.0** - управление сессиями пользователей
- **Flask-Compress 1.14** - gzip сжатие статических файлов и API ответов
- **PostgreSQL 12+** - база данных
- **psycopg2-binary 2.9.7** - драйвер для PostgreSQL
- **Requests 2.31.0** - HTTP клиент для проксирования запросов (GeoServer + ArcGIS Server)
- **cryptography 41.0.7** - работа с сертификатами ЭЦП
- **Flask-Babel 4.0.0** - локализация
- **python-dotenv 1.0.0** - управление переменными окружения
- **psycopg 3.x** - современный драйвер PostgreSQL (используется в коде)

### 🎨 Клиентская часть
- **HTML5/CSS3** - разметка и стили
- **Bootstrap 5** - UI фреймворк
- **Leaflet.js** - библиотека для интерактивных карт
- **ESRI Leaflet v2.1.4** - интеграция с ArcGIS Server (REST API, Dynamic Map Layers)
- **jQuery** - JavaScript библиотека
- **Bootstrap Icons** - иконки
- **ES6 Modules** - модульная система JavaScript
- **Proj4js** - проекции координат
- **Turf.js** - геопространственные вычисления

## 🏗️ Архитектура

### 🔧 Модульная архитектура backend (Flask)

Бэкенд разделён на модули с четким разделением ответственности:

#### Структура приложения
- **`app.py`** — точка входа Flask, использует `create_app()`
- **`app/__init__.py`** — фабрика `create_app()`: конфигурация, Babel, регистрация блюпринтов
- **`app/logging_setup.py`** — настройка логирования с ротацией файлов
- **`app/extensions.py`** — объявления экстеншенов (babel)
- **`app/i18n.py`** — выбор локали пользователя

#### Blueprints (маршруты)
- **`app/blueprints/public.py`** — публичные маршруты: `GET /`
- **`app/blueprints/proxy.py`** — проксирование запросов: `GET /Proxy/Wms`, `GET /Proxy/Wfs`, `GET /Proxy/Map/*`
- **`app/blueprints/account.py`** — аутентификация: `POST /Account/Login`, `GET /Account/Logout`
- **`app/blueprints/api.py`** — REST API: настройки, заявки, документы, справочники, пользователи

#### Сервисы и репозитории
- **`app/services/certificates.py`** — работа с сертификатами ЭЦП
- **`app/repositories/database_manager.py`** — слой доступа к данным, управление БД
  - автоматически гарантирует наличие ключевых таблиц/индексов (в т.ч. `giprozem.user_plots`, индексы логов)

### 🎯 Модульная архитектура фронтенда (ES Modules)

Реализована современная модульная система для JavaScript:

#### Структура JavaScript
- **`static/js/app.js`** — точка входа ES-модуля, инициализация всех UI-модулей
- **`static/js/notifications.js`** — модуль уведомлений
- **`static/js/map.js`** — картографический функционал (Leaflet + ESRI Leaflet, ArcGIS Server интеграция)
- **`static/js/modules/`** — функциональные модули:
  - `auth.js` — авторизация и управление сессиями
  - `documents.js` — загрузка и управление документами
  - `geojson.js` — работа с GeoJSON данными
  - `language.js` — смена языка интерфейса
  - `menu.js` — обработчики меню
  - `modals.js` — жизненный цикл модальных окон
  - `orders.js` — создание заявок на услуги
  - `personal.js` — личный кабинет и управление пользователями
  - `requests.js` — управление заявками и фильтрация
  - `request-details.js` — просмотр детальной информации о заявках
  - `search.js` — поиск земельных участков по кадастровому номеру
  - `services.js` — загрузка справочников
  - `settings.js` — настройки пользователя
  - `validators.js` — валидация форм

#### Подключение в HTML
- ES-модули подключаются через `type="module"`
- Обратная совместимость с legacy кодом через экспорт в `window`
- Единая точка входа через `app.js`

## ⚡ Установка и запуск

### 📋 Требования
- Python 3.8 или выше
- PostgreSQL 12+ 
- pip (менеджер пакетов Python)
- psycopg2-binary (драйвер PostgreSQL)
- Виртуальное окружение Python (venv)

### 🔧 Установка

1. Клонируйте репозиторий:
```bash
git clone <repository-url>
cd LandMonitoring
```

2. Создайте виртуальное окружение:
```bash
python3 -m venv venv
source venv/bin/activate  # На Windows: venv\Scripts\activate
```

3. Установите зависимости:
```bash
pip install -r requirements.txt
```

**Примечание**: Если возникают проблемы с установкой psycopg2-binary, установите системные зависимости:
```bash
# Ubuntu/Debian
sudo apt-get install python3-dev libpq-dev

# macOS
brew install postgresql

# CentOS/RHEL
sudo yum install python3-devel postgresql-devel
```

4. Настройте базу данных PostgreSQL:

**Важно**: Убедитесь, что PostgreSQL запущен и доступен:
```bash
# Проверка статуса PostgreSQL
sudo systemctl status postgresql

# Запуск PostgreSQL (если не запущен)
sudo systemctl start postgresql
```
```sql
-- Создайте схему giprozem
CREATE SCHEMA IF NOT EXISTS giprozem;

-- Таблица настроек пользователей
CREATE TABLE IF NOT EXISTS giprozem.user_settings (
    iin VARCHAR(12) PRIMARY KEY,
    phone VARCHAR(20),
    email VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Таблица истории авторизаций
CREATE TABLE IF NOT EXISTS giprozem.auth_history (
    id SERIAL PRIMARY KEY,
    iin VARCHAR(12) NOT NULL,
    fio VARCHAR(200),
    login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    logout_time TIMESTAMP,
    ip_address INET,
    user_agent TEXT,
    success BOOLEAN DEFAULT TRUE,
    error_message TEXT
);

-- Таблица ролей (справочник)
CREATE TABLE IF NOT EXISTS giprozem.roles (
    role_code VARCHAR(10) PRIMARY KEY,
    name_ru VARCHAR(100) NOT NULL,
    name_kk VARCHAR(100) NOT NULL
);

-- Наполнение ролей (без дубликатов)
INSERT INTO giprozem.roles (role_code, name_ru, name_kk) VALUES
('00','Пользователь','Пайдаланушы'),
('01','Исполнитель','Орындаушы'),
('02','Канцелярия','Кеңсе'),
('03','Руководитель','Басшы'),
('99','Администратор','Әкімші')
ON CONFLICT (role_code) DO NOTHING;

-- Таблица ролей пользователей (многие-ко-многим)
CREATE TABLE IF NOT EXISTS giprozem.user_roles (
    iin VARCHAR(12) NOT NULL,
    role_code VARCHAR(10) NOT NULL
);

-- Таблица услуг
CREATE TABLE IF NOT EXISTS giprozem.services (
    id SERIAL PRIMARY KEY,
    code VARCHAR(10) UNIQUE NOT NULL,
    name_ru VARCHAR(200) NOT NULL,
    name_kk VARCHAR(200) NOT NULL,
    description_ru TEXT,
    description_kk TEXT,
    price DECIMAL(10,2) DEFAULT 0.00,
    duration_days INTEGER DEFAULT 30,
    is_active BOOLEAN DEFAULT TRUE
);

-- Таблица статусов заявок
CREATE TABLE IF NOT EXISTS giprozem.request_statuses (
    id SERIAL PRIMARY KEY,
    code VARCHAR(10) UNIQUE NOT NULL,
    name_ru VARCHAR(100) NOT NULL,
    name_kk VARCHAR(100) NOT NULL,
    color VARCHAR(20) DEFAULT '#007bff'
);

-- Таблица заявок
CREATE TABLE IF NOT EXISTS giprozem.requests (
    id SERIAL PRIMARY KEY,
    request_number VARCHAR(30) UNIQUE NOT NULL,
    user_iin VARCHAR(12) NOT NULL,
    service_id INTEGER REFERENCES giprozem.services(id),
    status_id INTEGER REFERENCES giprozem.request_statuses(id),
    title VARCHAR(200) NOT NULL,
    description TEXT,
    address TEXT,
    coordinates JSONB,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    completed_at TIMESTAMP
);

-- Таблица документов (хранение бинарных данных файла)
CREATE TABLE IF NOT EXISTS giprozem.documents (
    id SERIAL PRIMARY KEY,
    request_id INTEGER REFERENCES giprozem.requests(id) ON DELETE CASCADE,
    filename VARCHAR(255) NOT NULL,
    original_filename VARCHAR(255) NOT NULL,
    file_data BYTEA NOT NULL,
    file_size BIGINT NOT NULL,
    mime_type VARCHAR(100),
    description VARCHAR(500),
    uploaded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    uploaded_by VARCHAR(12) NOT NULL
);

-- Таблица последовательности номеров заявок
CREATE TABLE IF NOT EXISTS giprozem.request_number_sequence (
    service_code VARCHAR(10) NOT NULL,
    date_part VARCHAR(6) NOT NULL,
    last_sequence INTEGER NOT NULL DEFAULT 0,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Таблица участков пользователя (вкладка "Мои участки и отводы")
CREATE TABLE IF NOT EXISTS giprozem.user_plots (
    id SERIAL PRIMARY KEY,
    user_iin VARCHAR(12) NOT NULL,
    name TEXT NOT NULL,
    location TEXT,
    cadastral_number VARCHAR(20),
    egkn_id VARCHAR(20),
    coordinates JSONB,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Журнал действий пользователей
CREATE TABLE IF NOT EXISTS giprozem.user_activity_logs (
    id SERIAL PRIMARY KEY,
    user_iin VARCHAR(12) NOT NULL,
    action_type VARCHAR(50) NOT NULL,
    action_description TEXT,
    resource_type VARCHAR(50),
    resource_id VARCHAR(100),
    ip_address INET,
    user_agent TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    additional_data JSONB
);

-- Индексы для оптимизации
CREATE INDEX IF NOT EXISTS idx_auth_history_iin ON giprozem.auth_history(iin);
CREATE INDEX IF NOT EXISTS idx_auth_history_login_time ON giprozem.auth_history(login_time);
CREATE INDEX IF NOT EXISTS idx_requests_user_iin ON giprozem.requests(user_iin);
CREATE INDEX IF NOT EXISTS idx_requests_status_id ON giprozem.requests(status_id);
CREATE INDEX IF NOT EXISTS idx_documents_request_id ON giprozem.documents(request_id);
CREATE UNIQUE INDEX IF NOT EXISTS ux_user_roles_iin_role ON giprozem.user_roles (iin, role_code);
CREATE UNIQUE INDEX IF NOT EXISTS ux_reqnum_seq_service_date ON giprozem.request_number_sequence (service_code, date_part);
CREATE INDEX IF NOT EXISTS idx_user_plots_user_iin ON giprozem.user_plots (user_iin);
CREATE INDEX IF NOT EXISTS idx_user_activity_logs_user_iin ON giprozem.user_activity_logs (user_iin);
CREATE INDEX IF NOT EXISTS idx_user_activity_logs_created_at ON giprozem.user_activity_logs (created_at);
CREATE INDEX IF NOT EXISTS idx_user_activity_logs_action_type ON giprozem.user_activity_logs (action_type);
```

### 🚀 Запуск

1. Активируйте виртуальное окружение (если не активировано):
```bash
source venv/bin/activate  # На Windows: venv\Scripts\activate
```

**Проверка активации**: В начале командной строки должно появиться `(venv)`.

2. Настройте подключение к БД в файле `config.env`:
```bash
# Настройки базы данных PostgreSQL
DATABASE_HOST=192.168.1.100
DATABASE_PORT=5432
DATABASE_NAME=db
DATABASE_USER=postgres
DATABASE_PASSWORD=your_password
DATABASE_SCHEMA=giprozem

# ArcGIS Server URL
ARCGIS_SERV_URL=https://178.89.0.228:56443/arcgis/rest/services

# Геосервер - локальный доступ
GEOSERVER_LOCAL_URL=http://192.168.1.253:8080/geoserver
# Геосервер - глобальный доступ
GEOSERVER_GLOBAL_URL=http://178.89.245.2:8887/geoserver

# Настройки Flask
SECRET_KEY=your-super-secret-key-change-this-in-production
DEBUG=True
HOST=0.0.0.0
PORT=8080

# Настройки аутентификации
SESSION_TIMEOUT=3600

# Настройки логирования
LOG_LEVEL=INFO
LOG_FILE=app.log

# Настройки прокси
PROXY_TIMEOUT=30
PROXY_VERIFY_SSL=False

# Настройки карты (координаты центра Казахстана)
DEFAULT_MAP_CENTER_LAT=48.0196
DEFAULT_MAP_CENTER_LON=66.9237
DEFAULT_MAP_ZOOM=6

# Лимиты документов
MAX_DOCUMENTS_PER_REQUEST=10
MAX_DOCUMENT_SIZE_MB=10
```

3. Скомпилируйте переводы:
```bash
python compile_translations.py
```

4. Запустите приложение:
```bash
python3 app.py
```

**Проверка запуска**: В консоли должны появиться сообщения о запуске Flask и выборе геосервера.

5. Откройте браузер и перейдите по адресу:
```
http://localhost:8080
```

### ✅ Проверка установки

После запуска приложения проверьте:

1. **Доступность веб-интерфейса**:
   ```bash
   curl -I http://localhost:8080
   ```

2. **Статус геосервера**:
   ```bash
   curl http://localhost:8080/api/geoserver/status
   ```

3. **Проверка ArcGIS Server**:
   ```bash
   curl -I "http://localhost:8080/Proxy/Map/Kaz/MapServer?f=json"
   ```

4. **Подключение к БД**:
   - Проверьте логи в `logs/app.log`
   - Должны быть сообщения о подключении к БД

5. **Проверка зависимостей**:
   ```bash
   pip list | grep -E "(Flask|psycopg|requests|cryptography)"
   ```

## 📁 Структура проекта

```
LandMonitoring/
├── app.py                        # Точка входа Flask
├── run_server.py                 # Альтернативный запуск сервера
├── app/                          # Пакет приложения (бэкенд модули)
│   ├── __init__.py               # create_app(): конфиг, Babel, блюпринты
│   ├── logging_setup.py          # настройка логирования
│   ├── extensions.py             # экстеншены (babel)
│   ├── i18n.py                   # выбор локали
│   ├── blueprints/
│   │   ├── public.py             # GET /
│   │   ├── proxy.py              # GET /Proxy/Wms, GET /Proxy/Wfs, GET /Proxy/Map/*
│   │   ├── account.py            # POST /Account/Login, GET /Account/Logout
│   │   ├── api.py                # REST API (настройки, заявки, документы, справочники)
│   │   └── egkn.py               # GET /get-zu/<kad_nomer> - поиск по ЕГКН
│   ├── services/
│   │   ├── certificates.py       # CertificateWorker - работа с ЭЦП
│   │   ├── notifications.py     # NotificationService - генерация PDF уведомлений
│   │   ├── arcgis.py            # ArcGISService - работа с ArcGIS REST API
│   │   └── coordinates_parser.py # Парсинг координат
│   └── repositories/
│       └── database_manager.py   # DatabaseManager - слой доступа к данным
├── config.py                     # Конфигурация приложения
├── config.env                    # Переменные окружения
├── compile_translations.py       # Компиляция переводов
├── babel.cfg                     # Конфигурация Babel
├── requirements.txt              # Зависимости Python
├── README.md                     # Документация проекта
├── DEPLOYMENT.md                 # Инструкции по деплою
├── docker.md                     # Документация по Docker
├── IMPORT_FEATURES.md            # Документация по импорту функций
├── PyArmor.md                    # Документация по защите кода
├── windows.md                    # Инструкция развертывания на Windows
├── LICENSE                       # Лицензия проекта
├── Dockerfile                    # Docker образ приложения
├── compose.yaml                  # Docker Compose конфигурация
├── static/
│   ├── css/
│   │   ├── app.css
│   │   ├── map.css
│   │   └── notifications.css
│   ├── js/
│   │   ├── app.js                # Точка входа ES-модуля
│   │   ├── notifications.js      # Модуль уведомлений
│   │   ├── map.js                # Картографический функционал
│   │   ├── egkn_districts.json   # Справочник областей и районов для ЕГКН
│   │   ├── eds/
│   │   │   └── eds.js            # ЭЦП функционал
│   │   └── modules/              # Функциональные модули
│   │       ├── auth.js           # Авторизация и управление сессиями
│   │       ├── coordinates-import.js # Импорт координат
│   │       ├── coordinates-utils.js   # Утилиты для работы с координатами
│   │       ├── documents.js      # Загрузка и управление документами
│   │       ├── geojson.js        # Работа с GeoJSON данными
│   │       ├── language.js       # Смена языка интерфейса
│   │       ├── logging.js        # Модуль логирования действий пользователей
│   │       ├── menu.js           # Обработчики меню
│   │       ├── modals.js         # Жизненный цикл модальных окон
│   │       ├── order-map.js      # Карта в модалке создания заявки
│   │       ├── orders.js         # Создание заявок на услуги
│   │       ├── personal.js       # Личный кабинет и управление пользователями
│   │       ├── request-details.js # Просмотр детальной информации о заявках
│   │       ├── requests.js       # Управление заявками и фильтрация
│   │       ├── search.js         # Поиск земельных участков по кадастровому номеру
│   │       ├── services.js       # Загрузка справочников
│   │       ├── settings.js       # Настройки пользователя
│   │       ├── system-logs.js    # Работа с системными логами
│   │       └── validators.js     # Валидация форм
│   ├── data/
│   │   └── ocsk-services.json    # JSON файл с OCSK сервисами
│   ├── images/
│   │   └── logo.png
│   ├── icons/
│   │   └── bootstrap-icons/      # Bootstrap Icons
│   ├── favicon.ico               # Иконка сайта
│   └── lib/                      # Внешние библиотеки
│       ├── bootstrap/            # Bootstrap 5
│       ├── jquery/               # jQuery
│       ├── leaflet/              # Leaflet.js и плагины
│       ├── esri-leaflet-v2.1.4/  # ESRI Leaflet для ArcGIS
│       ├── proj4.js              # Проекции координат
│       ├── proj4leaflet.js       # Проекции для Leaflet
│       └── turf.min.js           # Геопространственные вычисления
├── templates/
│   ├── layouts/
│   │   └── base.html
│   ├── pages/
│   │   ├── index.html            # Главная страница
│   │   ├── test.html             # Страница тестирования ArcGIS сервисов
│   │   ├── testview.html         # Детальный просмотр сервиса
│   │   ├── license.html          # Страница лицензии
│   │   └── readme.html           # Страница README
│   ├── partials/
│   │   ├── navbar.html           # Навигационная панель
│   │   ├── footer.html           # Подвал страницы
│   │   ├── map_controls.html     # Элементы управления картой
│   │   ├── opacity_panel.html   # Панель прозрачности слоев
│   │   ├── personal_cabinet_button.html
│   │   └── toast.html            # Шаблон уведомлений
│   └── modals/
│       ├── agro_settings.html    # Настройки агрохимии
│       ├── confirm_delete.html   # Подтверждение удаления
│       ├── logging.html          # Логирование действий пользователей
│       ├── order_service.html    # Создание заявки на услугу
│       ├── personal_cabinet.html # Личный кабинет
│       ├── plots_edit.html       # Редактирование участков
│       ├── request_details.html # Детальный просмотр заявки
│       ├── requests.html         # Таблица заявок
│       ├── search_result.html    # Результаты поиска участков
│       ├── settings.html         # Настройки пользователя
│       ├── user_edit.html        # Редактирование пользователя
│       └── user_management.html  # Управление пользователями
└── translations/
    ├── messages.pot              # Шаблон переводов
    ├── ru/
    │   └── LC_MESSAGES/
    │       ├── messages.po        # Русские переводы
    │       └── messages.mo       # Скомпилированные переводы
    └── kk/
        └── LC_MESSAGES/
            ├── messages.po        # Казахские переводы
            └── messages.mo        # Скомпилированные переводы
```

## 🔌 API Endpoints

### Основные маршруты
- `GET /` - Главная страница приложения
- `GET /test` - Страница просмотра сервисов ArcGIS с измерением времени загрузки
- `GET /testview` - Детальный просмотр конкретного сервиса ArcGIS
- `GET /Proxy/Wms` - Прокси для WMS запросов (GeoServer)
- `GET /Proxy/Wfs` - Прокси для WFS запросов (GeoServer)
- `GET /Proxy/Map/<path:service_path>` - Прокси для ArcGIS REST API запросов

### API маршруты
- `GET /api/search` - Поиск областей и районов
- `POST /api/login` - Вход в систему
- `GET /api/map/layers` - Получение слоев карты
- `GET /api/map/basemaps` - Получение базовых карт
- `GET /api/geoserver/status` - Статус геосервера
- `GET /Proxy/Map/*` - Проксирование ArcGIS REST API запросов

### API для участков (настройки)
- `GET /api/settings/plots` — список участков текущего пользователя
- `POST /api/settings/plots` — добавление участка
- `PUT /api/settings/plots/<plot_id>` — обновление участка
- `DELETE /api/settings/plots/<plot_id>` — удаление участка

### API для настроек пользователей
- `POST /api/settings/save` - Сохранение настроек пользователя
- `GET /api/settings/get` - Получение настроек пользователя
- `GET /api/auth/history` - История авторизаций пользователя

### API для заявок и документов
- `GET /api/requests` - Заявки пользователя (с поддержкой `include_documents=true`)
- `GET /api/all-requests` - Все заявки (с поддержкой `include_documents=true`)
- `GET /api/services` - Список услуг
- `GET /api/request-statuses` - Статусы заявок
- `POST /api/requests/create` - Создание новой заявки
- `GET /api/document-limits` - Лимиты документов
- `POST /api/requests/<id>/documents` - Загрузка документа
- `GET /api/documents/<id>` - Скачивание документа
- `DELETE /api/requests/<id>/documents/<doc_id>` - Удаление документа
- `DELETE /api/requests/<id>` - Удаление заявки

### API для управления пользователями
- `GET /api/users` - Список всех пользователей
- `GET /api/users/<iin>` - Информация о пользователе
- `POST /api/users` - Добавление пользователя
- `PUT /api/users/<iin>` - Обновление пользователя
- `DELETE /api/users/<iin>` - Удаление пользователя
- `GET /api/roles` - Список ролей

### API для авторизации
- `POST /Account/Login` - Авторизация по сертификату ЭЦП
- `GET /Account/Logout` - Выход из системы
- `GET /api/auth/status` - Статус авторизации

### API для логов
- `GET /api/logs` — получение логов с фильтрами и пагинацией
- `GET /api/logs/users/<iin>` — логи по пользователю
- `GET /api/logs/export` — экспорт логов в CSV
- `DELETE /api/logs/cleanup?days=<N>` — очистка старых логов

### API для системных логов
- `GET /api/system-logs/files` — получение списка системных лог файлов
- `GET /api/system-logs/content/<filename>` — просмотр содержимого лог файла
- `GET /api/system-logs/download/<filename>` — скачивание отдельного лог файла
- `GET /api/system-logs/download-all` — скачивание архива всех лог файлов

### API для просмотра заявок
- `GET /api/requests/<request_id>/details` - Получение детальной информации о заявке

### API для уведомлений о приеме заявок
- `GET /api/download-notification/<request_id>` - Скачивание PDF уведомления о приеме заявки
- `GET /api/verify-notification/<request_number>` - Верификация уведомления через QR-код (публичный доступ, использует номер заявки)
- `GET /api/requests/<request_id>/notification-status` - Проверка наличия уведомления для заявки

### API для локализации
- `POST /api/set_language` - Смена языка интерфейса

### API для ОЦСК сервисов
- `GET /ocsk-services` - Получение списка ОЦСК сервисов из JSON файла

### API для экспорта данных
- `GET /export/zu-excel` - Экспорт данных земельных участков в формат Excel

## 🗄️ База данных

### Схема giprozem

#### Таблица user_settings
Хранит настройки пользователей:
- `iin` (VARCHAR(12)) - ИИН пользователя (первичный ключ)
- `phone` (VARCHAR(20)) - Номер телефона
- `email` (VARCHAR(100)) - Email адрес
- `created_at` (TIMESTAMP) - Дата создания записи
- `updated_at` (TIMESTAMP) - Дата последнего обновления

#### Таблица auth_history
Хранит историю авторизаций:
- `id` (SERIAL) - Уникальный идентификатор
- `iin` (VARCHAR(12)) - ИИН пользователя
- `fio` (VARCHAR(200)) - ФИО пользователя
- `login_time` (TIMESTAMP) - Время входа
- `logout_time` (TIMESTAMP) - Время выхода
- `ip_address` (VARCHAR(45)) - IP адрес
- `user_agent` (TEXT) - User-Agent браузера
- `success` (BOOLEAN) - Успешность авторизации
- `error_message` (TEXT) - Сообщение об ошибке

#### Таблица user_roles
Роли пользователей:
- `iin` (VARCHAR(12)) - ИИН пользователя
- `role_code` (VARCHAR(10)) - Код роли (user, admin)

#### Таблица services
Справочник услуг:
- `id` (SERIAL) - Уникальный идентификатор
- `code` (VARCHAR(10)) - Код услуги
- `name_ru` (VARCHAR(200)) - Название на русском
- `name_kk` (VARCHAR(200)) - Название на казахском
- `description_ru` (TEXT) - Описание на русском
- `description_kk` (TEXT) - Описание на казахском
- `price` (DECIMAL(10,2)) - Стоимость услуги
- `duration_days` (INTEGER) - Срок выполнения в днях
- `is_active` (BOOLEAN) - Активность услуги

#### Таблица request_statuses
Статусы заявок:
- `id` (SERIAL) - Уникальный идентификатор
- `code` (VARCHAR(10)) - Код статуса
- `name_ru` (VARCHAR(100)) - Название на русском
- `name_kk` (VARCHAR(100)) - Название на казахском
- `color` (VARCHAR(20)) - Цвет для отображения

#### Таблица requests
Заявки пользователей:
- `id` (SERIAL) - Уникальный идентификатор
- `request_number` (VARCHAR(20)) - Номер заявки
- `user_iin` (VARCHAR(12)) - ИИН пользователя
- `service_id` (INTEGER) - ID услуги
- `status_id` (INTEGER) - ID статуса
- `title` (VARCHAR(200)) - Название заявки
- `description` (TEXT) - Описание
- `address` (TEXT) - Адрес объекта
- `coordinates` (JSONB) - Геометрия в формате GeoJSON
- `created_at` (TIMESTAMP) - Время создания
- `updated_at` (TIMESTAMP) - Время обновления
- `completed_at` (TIMESTAMP) - Время завершения
- `notification_pdf` (BYTEA) - PDF уведомление о приеме заявки
- `notification_created_at` (TIMESTAMP) - Время создания уведомления

#### Таблица documents
Документы заявок:
- `id` (SERIAL) - Уникальный идентификатор
- `request_id` (INTEGER) - ID заявки
- `filename` (VARCHAR(255)) - Имя файла в системе
- `original_filename` (VARCHAR(255)) - Оригинальное имя файла
- `file_size` (BIGINT) - Размер файла в байтах
- `mime_type` (VARCHAR(100)) - MIME-тип файла
- `description` (VARCHAR(500)) - Описание документа
- `uploaded_at` (TIMESTAMP) - Время загрузки
- `uploaded_by` (VARCHAR(12)) - ИИН загрузившего

#### Таблица request_number_sequence
Последовательность номеров заявок:
- `service_code` (VARCHAR(10)) - Код услуги
- `date_part` (VARCHAR(6)) - Часть даты (YYYYMM)
- `last_sequence` (INTEGER) - Последний номер последовательности
- `updated_at` (TIMESTAMP) - Время обновления

#### Таблица user_plots
Участки пользователя (вкладка "Мои участки и отводы"):
- `id` (SERIAL) — первичный ключ
- `user_iin` (VARCHAR(12)) — ИИН владельца
- `name` (TEXT) — наименование (обязательно)
- `location` (TEXT) — местоположение
- `cadastral_number` (VARCHAR(20)) — кадастровый номер (необязательно)
- `egkn_id` (VARCHAR(20)) — идентификатор ЕГКН (необязательно)
- `coordinates` (JSONB) — координаты (GeoJSON, необязательно)
- `created_at` (TIMESTAMP) — дата создания
- `updated_at` (TIMESTAMP) — дата изменения

Рекомендуемые индексы:
- `CREATE INDEX IF NOT EXISTS idx_user_plots_user_iin ON giprozem.user_plots (user_iin);`

#### Таблица user_activity_logs
Журнал действий пользователя (для модалки "Логирование"):
- `id` (SERIAL), `user_iin` (VARCHAR(12))
- `action_type` (VARCHAR(50)) — тип действия (напр. login, add_plot, update_plot, delete_plot, ...)
- `action_description` (TEXT), `resource_type` (VARCHAR(50)), `resource_id` (VARCHAR(100))
- `ip_address` (INET), `user_agent` (TEXT)
- `created_at` (TIMESTAMP), `additional_data` (JSONB)

Индексы:
- `idx_user_activity_logs_user_iin`, `idx_user_activity_logs_created_at`, `idx_user_activity_logs_action_type`

## 👥 Система ролей и прав доступа

### Роли пользователей

#### user (обычный пользователь)
- Просмотр карты и слоев
- Создание и управление собственными заявками
- Загрузка документов к своим заявкам
- Просмотр истории авторизаций
- Изменение личных настроек

#### admin (администратор)
- Все права обычного пользователя
- Просмотр всех заявок в системе
- Управление пользователями (добавление, редактирование, удаление)
- Назначение ролей пользователям
- Доступ к административным функциям

### Авторизованные пользователи

В системе предустановлены следующие пользователи:

| ИИН | ФИО | Роль | Описание |
|-----|-----|------|----------|
| 745896125463 | Пользователь Ф | user | Обычный пользователь |
| 951735469875 | Пользователь Ю | admin | Администратор |
| 870629351133 | Виктор С | admin | Администратор |

## 📝 Система логирования

Приложение ведет детальное логирование всех операций:

### Логи
- **Файл**: `logs/app.log` (автоматическая ротация при 1MB)
- **Консоль**: Все логи выводятся в консоль
- **Формат**: `Время - Модуль - Уровень - Сообщение`

### Логируемые события
- **Геосервер**: Выбор доступного сервера, WMS/WFS запросы
- **Авторизация**: Попытки входа/выхода, ошибки сертификатов
- **Настройки**: Сохранение/получение пользовательских настроек
- **База данных**: Операции с БД, ошибки подключения
- **Заявки**: Создание, редактирование, удаление заявок
- **Документы**: Загрузка, скачивание, удаление документов
- **Пользователи**: Управление пользователями и ролями

### Уровни логирования
- **INFO**: Успешные операции, выбор геосервера
- **WARNING**: Попытки доступа без авторизации, неверные данные
- **ERROR**: Ошибки БД, сетевые ошибки, исключения

## ⚙️ Конфигурация

### 🗄️ Конфигурация схемы базы данных

Приложение поддерживает настраиваемую схему базы данных через переменную окружения `DATABASE_SCHEMA`:

#### Настройка схемы
```bash
# В файле config.env
DATABASE_SCHEMA=giprozem
```

#### Значения по умолчанию
- **По умолчанию**: `public` (если переменная не задана)
- **Текущая**: `giprozem` (настроена в config.env)

#### Архитектура
- **Динамическая схема**: Все SQL запросы используют схему из конфига
- **Безопасность**: Использование f-строк с параметризованными запросами
- **Гибкость**: Возможность легкой смены схемы без изменения кода
- **Обратная совместимость**: Поддержка существующих данных

#### Примеры использования
```python
# В коде приложения
schema = self._get_schema()  # Получение схемы из конфига
query = f"SELECT * FROM {schema}.users WHERE id = %s"  # Использование в SQL
```

#### Преимущества
- **Мультитенантность**: Возможность использования разных схем для разных окружений
- **Изоляция данных**: Четкое разделение данных по схемам
- **Упрощение деплоя**: Одно приложение для разных схем БД

### Автоматическое переключение геосерверов

Приложение автоматически проверяет доступность геосерверов при запуске:

1. **Сначала проверяется локальный URL** (`GEOSERVER_LOCAL_URL`)
2. **Если локальный недоступен**, используется глобальный URL (`GEOSERVER_GLOBAL_URL`)
3. **Если оба недоступны**, используется локальный по умолчанию

Для проверки текущего статуса геосервера используйте API:
```bash
curl http://localhost:8080/api/geoserver/status
```

### 🔄 Переход на ArcGIS Server

В версии v1.3.7 реализован переход отображения пространственных данных с **GeoServer** на **ArcGIS Server**. Это обеспечивает более стабильную работу с картографическими данными и улучшенную производительность.

#### Архитектура перехода

**Двойная система поддержки:**
- **GeoServer**: Сохранен для обратной совместимости (WMS/WFS запросы)
- **ArcGIS Server**: Новый основной источник данных (REST API)

#### Конфигурация ArcGIS Server

Добавлена новая переменная окружения `ARCGIS_SERV_URL`:

```bash
# ArcGIS Server URL
ARCGIS_SERV_URL=https://178.89.0.228:56443/arcgis/rest/services
```

#### Новые возможности

**1. REST API интеграция:**
- Прямое подключение к ArcGIS Server через REST API
- Поддержка динамических слоев (Dynamic Map Layers)
- Автоматическое получение метаданных слоев

**2. Улучшенная производительность:**
- Кэширование метаданных слоев
- Оптимизированные запросы к серверу
- Снижение нагрузки на сеть

**3. Расширенная функциональность:**
- Автоматическое получение списка слоев
- Динамическое управление видимостью слоев
- Улучшенная система легенд

#### Технические изменения

**Backend (Flask):**
- Новый маршрут `/Proxy/Map/<path:service_path>` для проксирования ArcGIS запросов
- Конфигурация `ARCGIS_SERV_URL` в `config.py`
- Улучшенная обработка ошибок в прокси-функциях

**Frontend (JavaScript):**
- Интеграция с ESRI Leaflet библиотекой
- Новые функции для работы с ArcGIS REST API:
  - `getLayerNames()` - получение списка слоев
  - `getLayerFeatures()` - получение объектов слоя
  - `getLegend()` - получение легенды слоя
- Замена WMS слоев на ESRI Dynamic Map Layers

**Структура URL для ArcGIS:**
```
/Proxy/Map/Kaz/MapServer          # Основные границы
/Proxy/Map/U/MapServer            # Земельные участки
/Proxy/Map/GR_Pch/MapServer       # Почвенные карты
/Proxy/Map/GR_Rst/MapServer       # Геоботанические карты
/Proxy/Map/Pch/MapServer          # Почвенные карты районов
/Proxy/Map/Rst/MapServer          # Геоботанические карты районов
```

#### Преимущества перехода

**Производительность:**
- ⚡ Быстрая загрузка слоев
- 🔄 Оптимизированное кэширование
- 📊 Снижение сетевого трафика

**Надежность:**
- 🛡️ Стабильная работа с большими объемами данных
- 🔧 Улучшенная обработка ошибок
- 📈 Масштабируемость

**Функциональность:**
- 🗺️ Расширенные возможности картографирования
- 📋 Автоматическое получение метаданных
- 🎨 Улучшенная система легенд

#### Обратная совместимость

Система полностью совместима с существующим кодом:
- ✅ WMS/WFS запросы продолжают работать через GeoServer
- ✅ Все существующие функции сохранены
- ✅ Плавный переход без потери данных

#### Миграция данных

Переход выполнен автоматически:
- 🔄 Автоматическое определение доступности серверов
- 📊 Сохранение всех существующих настроек
- 🎯 Прозрачная работа для пользователей

### Настройки в config.env

```bash
# ArcGIS Server URL
ARCGIS_SERV_URL=https://178.89.0.228:56443/arcgis/rest/services
```

## 🔐 Аутентификация

### Процесс авторизации

1. **Загрузка сертификата**: Пользователь загружает файл сертификата ЭЦП
2. **Валидация**: Система проверяет корректность сертификата
3. **Извлечение ИИН**: Из сертификата извлекается ИИН пользователя
4. **Проверка авторизации**: Проверяется наличие ИИН в списке авторизованных пользователей
5. **Создание сессии**: При успешной авторизации создается сессия пользователя с `session.permanent = True`
6. **Запись в историю**: Все попытки авторизации записываются в БД

### Управление сессиями (Flask-Session)

Приложение использует **Flask-Session** для безопасного управления сессиями пользователей:

#### Конфигурация сессий
- **Тип хранения**: `filesystem` - сессии хранятся в файловой системе
- **Директория**: `flask_session/` - папка для файлов сессий
- **Время жизни**: `10800` секунд (3 часа) - настраиваемое время жизни сессии
- **Максимум файлов**: `500` - ограничение на количество файлов сессий
- **Права доступа**: `384` (0o600) - безопасные права доступа к файлам

#### Параметры в config.env
```bash
# Настройки Flask-Session
SESSION_TYPE=filesystem
SESSION_FILE_DIR=flask_session
SESSION_FILE_THRESHOLD=500
SESSION_FILE_MODE=384
PERMANENT_SESSION_LIFETIME=10800
```

#### Преимущества Flask-Session
- **Безопасность**: Сессии не хранятся в cookies браузера
- **Надежность**: Файловое хранение обеспечивает сохранность данных
- **Масштабируемость**: Возможность переключения на Redis или другие бэкенды
- **Контроль**: Настраиваемое время жизни и автоматическая очистка
- **Производительность**: Быстрый доступ к данным сессий

#### Автоматическая очистка
- Старые сессии автоматически удаляются по истечении времени жизни
- Система контролирует количество файлов сессий (не более 500)
- При превышении лимита удаляются самые старые сессии

## 🌍 Локализация

Приложение поддерживает локализацию с использованием Flask-Babel. Реализована поддержка русского (ru) и казахского (kk) языков.

### Структура файлов локализации

```
translations/
├── messages.pot          # Шаблон переводов
├── ru/
│   └── LC_MESSAGES/
│       ├── messages.po   # Русские переводы
│       └── messages.mo   # Скомпилированные русские переводы
└── kk/
    └── LC_MESSAGES/
        ├── messages.po   # Казахские переводы
        └── messages.mo   # Скомпилированные казахские переводы
```

### Компиляция переводов

```bash
python compile_translations.py
```

### Добавление новых строк для перевода

1. Добавьте строку в HTML шаблон с функцией `_()`:
   ```html
   <span>{{ _('Новая строка') }}</span>
   ```

2. Извлеките новые строки:
   ```bash
pybabel extract -F babel.cfg -k _ -o translations/messages.pot .
   ```

3. Обновите файлы переводов:
   ```bash
   pybabel update -i translations/messages.pot -d translations -l ru
   pybabel update -i translations/messages.pot -d translations -l kk
   ```

4. Отредактируйте файлы `.po` в папках `translations/ru/LC_MESSAGES/` и `translations/kk/LC_MESSAGES/`

5. Скомпилируйте переводы:
   ```bash
   python compile_translations.py
   ```

6. Перезапустите приложение, чтобы применить новые `.mo` файлы.

### Использование в коде

#### В HTML шаблонах:
```html
{{ _('Текст для перевода') }}
```

#### В Python коде:
```python
from flask_babel import gettext as _

text = _('Текст для перевода')
```

### Смена языка

Пользователи могут сменить язык через интерфейс:
- Кнопка "ҚАЗ" - казахский язык
- Кнопка "РУС" - русский язык

Язык сохраняется в сессии и применяется при следующей загрузке страницы.

## ⚡ Оптимизация API

### Проблема и решение

Ранее для получения заявок и их документов требовалось делать множество отдельных HTTP запросов. Это приводило к медленной загрузке страниц и высокой нагрузке на сервер.

**Решение**: Добавлен параметр `include_documents` в API endpoints для получения заявок.

### Новые возможности

#### API `/api/requests`
```
GET /api/requests?include_documents=true
```

**Параметры:**
- `include_documents` (boolean) - включить документы в ответ
- `limit` - количество заявок (по умолчанию 50)
- `service` - фильтр по коду услуги
- `status` - фильтр по коду статуса
- `number` - фильтр по номеру заявки
- `date` - фильтр по дате создания

#### API `/api/all-requests`
```
GET /api/all-requests?include_documents=true
```

**Параметры:**
- `include_documents` (boolean) - включить документы в ответ
- `limit` - количество заявок (по умолчанию 100)
- `service` - фильтр по коду услуги
- `status` - фильтр по коду статуса
- `user` - фильтр по ИИН пользователя
- `number` - фильтр по номеру заявки
- `date` - фильтр по дате создания

### Примеры использования

#### Получение заявок без документов (по умолчанию)
```bash
curl "http://localhost:8080/api/requests"
```

#### Получение заявок с документами
```bash
curl "http://localhost:8080/api/requests?include_documents=true"
```

#### Получение всех заявок с документами и фильтрацией
```bash
curl "http://localhost:8080/api/all-requests?include_documents=true&limit=10&status=CREATED"
```

### Структура ответа

Когда `include_documents=true`, каждая заявка содержит массив документов:

```json
{
  "requests": [
    {
      "id": 1,
      "request_number": "240101SERVICE0000001",
      "title": "Заявка на услугу",
      "documents_count": 2,
      "total_size": 1048576,
      "documents": [
        {
          "id": 1,
          "request_id": 1,
          "filename": "uuid_filename.pdf",
          "original_filename": "document.pdf",
          "file_size": 524288,
          "file_size_formatted": "512.0 КБ",
          "mime_type": "application/pdf",
          "description": "Описание документа",
          "uploaded_at": "2024-01-01T10:00:00",
          "uploaded_by": "745896125463"
        }
      ]
    }
  ]
}
```

### Преимущества

1. **Производительность**: Один запрос вместо множества
2. **Скорость**: Быстрая загрузка страниц
3. **Эффективность**: Снижение нагрузки на сервер
4. **Удобство**: Простое использование API

## 🗜️ Gzip сжатие

Приложение использует Flask-Compress для автоматического gzip сжатия статических файлов и API ответов.

### Конфигурация сжатия

```python
# Настройки в config.py
COMPRESS_MIMETYPES = [
    'text/html', 'text/css', 'text/xml', 'application/json', 'application/javascript',
    'application/xml+rss', 'text/javascript', 'application/xml', 'text/plain'
]
COMPRESS_LEVEL = 6
COMPRESS_MIN_SIZE = 500
```

### Что сжимается

- **Статические файлы**: JavaScript, CSS, HTML файлы
- **API ответы**: JSON ответы от всех API endpoints
- **Условия**: Размер > 500 байт, клиент поддерживает gzip

### Экономия трафика

| Файл | Оригинальный размер | Сжатый размер | Экономия |
|------|-------------------|---------------|----------|
| `map.js` | 71KB | ~20-25KB | 65-70% |
| `personal.js` | 23KB | ~7-10KB | 60-70% |
| `settings.js` | 14KB | ~4-6KB | 60-70% |
| CSS файлы | 9.5KB | ~2-3KB | 70-80% |
| JSON API ответы | Зависит от данных | 60-80% сжатие | 60-80% |

### Проверка сжатия

```bash
# Проверка статических файлов
curl -H "Accept-Encoding: gzip" -I http://localhost:8080/static/js/map.js

# Проверка API ответов
curl -H "Accept-Encoding: gzip" -I http://localhost:8080/api/requests
```

### Заголовки ответа

При сжатии в заголовках ответа появляется:
```
Content-Encoding: gzip
Content-Length: [сжатый размер]
```

## 🛠️ Разработка

### Добавление новых слоев

Для добавления нового слоя карты:

1. **Для ArcGIS Server слоев:**
   - Добавьте URL сервиса в конфигурацию ArcGIS
   - Обновите JavaScript код в `static/js/map.js` с новыми переменными `_esri_*`
   - Добавьте функции для работы с новым слоем (`getLayerNames`, `getLayerFeatures`)

2. **Для GeoServer слоев:**
   - Добавьте информацию о слое в API `/api/map/layers`
   - Обновите клиентский JavaScript код в `static/js/map.js`
   - Добавьте соответствующие элементы управления в HTML шаблон

### Добавление новых базовых карт

Для добавления новой базовой карты:

1. Добавьте информацию в API `/api/map/basemaps`
2. Обновите клиентский код для поддержки нового типа карты

### Добавление новых пользователей

Для добавления нового авторизованного пользователя:

1. Отредактируйте функцию `_authorize_by_iin()` в `app/blueprints/account.py`
2. Добавьте нового пользователя в словарь `authorized_users`

### Добавление новых модулей JavaScript

1. Создайте модуль в `static/js/modules/your-module.js`
2. Импортируйте и инициализируйте его в `static/js/app.js`
3. Если требуется вызов из HTML/onclick — явно экспортируйте функцию в `window` внутри модуля
4. Не добавляйте новые `<script>` в шаблоны — используйте существующую точку входа `app.js`

## 🧪 Тестирование

### Запуск тестов API

```bash
python test_api.py
```

### Запуск тестов фронтенда

```bash
python test_frontend_fix.py
```

### Ручное тестирование

1. **Тестирование авторизации**:
   - Загрузите валидный сертификат ЭЦП
   - Проверьте вход в систему
   - Проверьте выход из системы

2. **Тестирование карты**:
   - Проверьте загрузку слоев (GeoServer + ArcGIS Server)
   - Проверьте переключение базовых карт
   - Проверьте настройку прозрачности
   - Проверьте работу с ArcGIS REST API
   - Проверьте автоматическое получение легенд слоев

3. **Тестирование локализации**:
   - Переключитесь между языками
   - Проверьте корректность переводов

4. **Тестирование заявок**:
   - Создайте новую заявку
   - Загрузите документы
   - Проверьте фильтрацию и поиск
   - Кликните на номер заявки для просмотра деталей
   - Проверьте отображение всех данных в модальном окне

5. **Тестирование управления пользователями** (для администраторов):
   - Добавьте нового пользователя
   - Назначьте роли
   - Проверьте права доступа

## 🔧 Устранение неполадок

### Проблемы с подключением к БД

1. Проверьте настройки в `config.env`
2. Убедитесь, что PostgreSQL запущен
3. Проверьте доступность сервера БД
4. Проверьте установку psycopg2-binary:
   ```bash
   pip list | grep psycopg
   ```
5. Если psycopg2-binary не установлен:
   ```bash
   pip install psycopg2-binary
   ```
6. Проверьте права доступа пользователя БД к схеме `giprozem`

### Проблемы с геосервером

1. Проверьте доступность геосерверов
2. Проверьте логи приложения
3. Используйте API для проверки статуса: `/api/geoserver/status`

### Проблемы с ArcGIS Server

1. Проверьте доступность ArcGIS Server:
   ```bash
   curl -I "http://localhost:8080/Proxy/Map/Kaz/MapServer?f=json"
   ```

2. Проверьте настройку `ARCGIS_SERV_URL` в `config.env`

3. Убедитесь, что ArcGIS Server доступен по указанному URL

4. Проверьте логи приложения на ошибки проксирования ArcGIS запросов

### Проблемы с авторизацией

1. Проверьте корректность сертификата ЭЦП
2. Убедитесь, что ИИН пользователя добавлен в список авторизованных
3. Проверьте логи авторизации

### Проблемы с сессиями

1. **Проверьте права доступа к папке сессий**:
   ```bash
   ls -la flask_session/
   chmod 755 flask_session/
   ```

2. **Очистите старые сессии**:
   ```bash
   rm -rf flask_session/*
   ```

3. **Проверьте настройки сессий в config.env**:
   - Убедитесь, что `PERMANENT_SESSION_LIFETIME` установлен корректно
   - Проверьте, что `SESSION_FILE_DIR` указывает на существующую папку

4. **Проверьте логи приложения** на ошибки, связанные с сессиями

### Проблемы с локализацией

1. Убедитесь, что переводы скомпилированы: `python compile_translations.py`
2. Проверьте корректность файлов `.po`
3. Перезапустите приложение

### Проблемы с загрузкой документов

1. Проверьте лимиты файлов в конфигурации
2. Убедитесь, что папка для загрузки доступна для записи
3. Проверьте логи приложения на наличие ошибок
4. Проверьте права доступа к папке `logs/`:
   ```bash
   chmod 755 logs/
   ```

### Проблемы с виртуальным окружением

1. Убедитесь, что виртуальное окружение активировано:
   ```bash
   echo $VIRTUAL_ENV
   ```
2. Если не активировано, активируйте:
   ```bash
   source venv/bin/activate
   ```
3. Проверьте установленные пакеты:
   ```bash
   pip list
   ```
4. Если пакеты отсутствуют, переустановите:
   ```bash
   pip install -r requirements.txt
   ```

## 🔄 Миграция на ArcGIS Server

### Краткое описание изменений

В версии v1.3.7 реализован переход отображения пространственных данных с **GeoServer** на **ArcGIS Server**. Основные изменения:

- ✅ Добавлена конфигурация `ARCGIS_SERV_URL`
- ✅ Новый маршрут `/Proxy/Map/<path:service_path>` для ArcGIS REST API
- ✅ Интеграция с ESRI Leaflet библиотекой
- ✅ Автоматическое получение метаданных слоев
- ✅ Улучшенная система легенд
- ✅ Оптимизированные запросы к серверу
- ✅ Сохранена обратная совместимость с GeoServer

### Техническая поддержка

При возникновении проблем с ArcGIS Server:
1. Проверьте доступность сервера по URL из `ARCGIS_SERV_URL`
2. Убедитесь в корректности настроек в `config.env`
3. Проверьте логи приложения на ошибки проксирования
4. Обратитесь к разделу "Устранение неполадок" в документации

## 🚀 Деплой

### Подготовка к продакшену

1. Измените `DEBUG=False` в `config.env`
2. Установите безопасный `SECRET_KEY`
3. Настройте HTTPS
4. Настройте reverse proxy (nginx)
5. Проверьте доступность ArcGIS Server по URL из `ARCGIS_SERV_URL`
6. Убедитесь, что все геосерверы доступны

### Docker (опционально)

Создайте `Dockerfile`:

```dockerfile
FROM python:3.8-slim

# Установка системных зависимостей для psycopg2
RUN apt-get update && apt-get install -y \
    python3-dev \
    libpq-dev \
    gcc \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

EXPOSE 8080
CMD ["python3", "app.py"]
```

**Docker Compose** (опционально):

Создайте `docker-compose.yml`:
```yaml
version: '3.8'
services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - DATABASE_HOST=postgres
      - DATABASE_PORT=5432
      - DATABASE_NAME=landmonitoring
      - DATABASE_USER=postgres
      - DATABASE_PASSWORD=password
      - ARCGIS_SERV_URL=https://178.89.0.228:56443/arcgis/rest/services
      - GEOSERVER_LOCAL_URL=http://192.168.1.253:8080/geoserver
      - GEOSERVER_GLOBAL_URL=http://178.89.245.2:8887/geoserver
    depends_on:
      - postgres
    volumes:
      - ./logs:/app/logs
      
  postgres:
    image: postgres:13
    environment:
      - POSTGRES_DB=landmonitoring
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql

volumes:
  postgres_data:
```

### Systemd сервис

Создайте `/etc/systemd/system/landmonitoring.service`:

```ini
[Unitl]
Description=Land Monitoring
After=network.target postgresql.service
Wants=postgresql.service

[Service]
Type=simple
User=app-host
Group=app-host
WorkingDirectory=/opt/LandMonitoring
Environment=PATH=/opt/LandMonitoring/venv/bin
Environment=ARCGIS_SERV_URL=https://178.89.0.228:56443/arcgis/rest/services
Environment=GEOSERVER_LOCAL_URL=http://192.168.1.253:8080/geoserver
Environment=GEOSERVER_GLOBAL_URL=http://178.89.245.2:8887/geoserver
ExecStart=/opt/LandMonitoring/venv/bin/python /opt/LandMonitoring/app.py
ExecReload=/bin/kill -s HUP $MAINPID
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=app-host

[Install]
WantedBy=multi-user.target
```

## 🪟 Развертывание на Windows

Для развертывания приложения на Windows Server предусмотрена детальная инструкция с использованием современных инструментов:

### 📋 Что включено в инструкцию
- **Системные требования**: Windows Server 2019/2022, Python 3.13, nginx, Waitress
- **Пошаговая установка**: Полная настройка окружения от А до Я
- **WSGI сервер**: Использование Waitress для продакшена
- **Reverse Proxy**: Конфигурация nginx для Windows
- **Windows службы**: Автоматический запуск с помощью NSSM
- **SSL/HTTPS**: Настройка Let's Encrypt сертификатов
- **Мониторинг**: Логирование и управление службами
- **Безопасность**: Настройка файрвола и пользователей
- **Резервное копирование**: Автоматические бэкапы

### 🔗 Подробная инструкция
Полное руководство по развертыванию доступно в файле: **[windows.md](windows.md)**

### ✨ Ключевые особенности
- **Production-ready**: Готовое решение для продакшена
- **Автоматизация**: Службы Windows и планировщик задач
- **Отказоустойчивость**: Автоматический перезапуск служб
- **Масштабируемость**: Nginx + Waitress для высокой нагрузки
- **Безопасность**: HTTPS, файрвол, изоляция пользователей

## 📄 Система генерации уведомлений о приеме заявок

### Описание
Реализована система автоматической генерации PDF уведомлений о приеме заявок с QR-кодом для верификации.

### Архитектура

#### Компоненты системы

1. **NotificationService** (`app/services/notifications.py`)
   - Генерация PDF документов с использованием ReportLab
   - Создание QR-кодов для верификации
   - Форматирование данных заявки в документ

2. **DatabaseManager** (расширен)
   - Хранение PDF уведомлений в БД (поле `notification_pdf`)
   - Методы для работы с уведомлениями
   - Проверка наличия уведомлений

3. **API Endpoints** (расширен)
   - `/api/download-notification/<request_id>` - скачивание уведомления
   - `/api/verify-notification/<request_id>` - верификация через QR-код
   - `/api/requests/<request_id>/notification-status` - статус уведомления

4. **Frontend** (расширен)
   - Кнопка "Уведомление" в таблице заявок
   - JavaScript модуль для скачивания уведомлений

### Функциональность

#### Автоматическая генерация
- При создании заявки автоматически генерируется PDF уведомление
- Уведомление содержит все данные заявки и QR-код
- PDF сохраняется в БД в поле `notification_pdf`

#### Содержимое уведомления
- Заголовок "УВЕДОМЛЕНИЕ О ПРИЕМЕ ЗАЯВКИ"
- Номер заявки и дата приема
- Информация о заявителе (ФИО, ИИН)
- Данные об услуге и заявке
- Адрес и координаты объекта
- QR-код для верификации
- Место для подписи ответственного лица

#### QR-код верификации
- Содержит полный URL: `{NOTIFICATION_DOMAIN}/api/verify-notification/{request_number}`
- Домен настраивается в `config.env` (NOTIFICATION_DOMAIN)
- При сканировании открывается PDF уведомления
- Позволяет проверить подлинность документа

#### Интерфейс пользователя
- Кнопка "Уведомление" в таблице заявок
- Скачивание PDF файла с именем `Уведомление_{номер_заявки}.pdf`
- Уведомления об успешном скачивании

### Безопасность

- Проверка прав доступа к уведомлениям
- Валидация данных перед генерацией PDF
- Логирование всех операций с уведомлениями
- Безопасная обработка QR-кодов

### Зависимости

Добавлены в `requirements.txt`:
```
reportlab==4.0.7
qrcode[pil]==7.4.2
```

### Конфигурация

#### Настройка домена для QR-кодов
В файле `config.env` добавлена настройка:
```env
# Настройки для QR-кодов уведомлений
NOTIFICATION_DOMAIN=http://192.168.1.111:8080
```

Этот домен используется для генерации полных URL в QR-кодах уведомлений.

#### Билингвальность уведомлений
PDF уведомления генерируются на двух языках одновременно:
- **Русский язык**: основной язык системы
- **Казахский язык**: государственный язык Республики Казахстан

Все элементы документа дублируются на обоих языках:
- Заголовки и подзаголовки
- Названия полей и описания
- Названия услуг (берутся из базы данных)
- Подписи и служебная информация

#### Поддержка кириллицы в PDF
Для корректного отображения русских и казахских символов в PDF система автоматически ищет и использует системные шрифты с поддержкой кириллицы:

- **macOS**: SF Pro, New York, Geneva, SF Compact, Arial
- **Linux/Docker**: DejaVu Sans, Liberation Sans, FreeSans, Arial
- **Windows**: Arial, Calibri, Tahoma

**Важно для Docker**: В `Dockerfile` автоматически устанавливаются пакеты `fonts-dejavu`, `fonts-dejavu-core`, `fonts-dejavu-extra`, которые обеспечивают полную поддержку кириллицы в контейнерах Linux.

При отсутствии подходящих системных шрифтов используется Times-Roman как fallback (возможны проблемы с кириллицей).

### Использование

#### Создание заявки
При создании заявки через API автоматически генерируется уведомление:

```python
# В app/blueprints/api.py
request_id = db_manager.create_request(iin, service_id, title, description, address, coordinates)

if request_id:
    # Автоматическая генерация уведомления
    request_data = db_manager.get_request_with_service_info(request_id)
    user_data = {'iin': iin, 'fio': session.get('user_fio', 'Не указано')}
    pdf_data = notification_service.generate_notification_pdf(request_data, user_data)
    db_manager.save_notification_pdf(request_id, pdf_data)
```

#### Скачивание уведомления
```javascript
// В static/js/modules/requests.js
function downloadNotification(requestId) {
    const link = document.createElement('a');
    link.href = `/api/download-notification/${requestId}`;
    link.download = `Уведомление_${requestId}.pdf`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
}
```

### Тестирование

Система протестирована:
- ✅ Генерация PDF уведомлений
- ✅ Создание QR-кодов
- ✅ Сохранение в БД
- ✅ API endpoints
- ✅ Frontend интеграция

### Логирование

Все операции с уведомлениями логируются:
- Создание уведомления при создании заявки
- Скачивание уведомлений
- Ошибки генерации
- Попытки доступа к уведомлениям

### Расширение

Система легко расширяется:
- Добавление новых полей в уведомление
- Изменение дизайна PDF
- Дополнительные форматы (DOCX, HTML)
- Email отправка уведомлений
- Массовая генерация уведомлений

## 📋 История версий
### v1.5.7 - 2025-12-XX
- ✅ **Слой деградации**: добавлен новый слой деградации с полным функционалом управления
  - Реализованы функции включения и отключения слоя деградации
  - Добавлены элементы управления прозрачностью слоя деградации в UI
  - Обновлены привязки событий для управления состоянием слоя деградации вместе с существующими слоями
  - Улучшено взаимодействие с картой за счет интеграции полей данных деградации для улучшения пользовательского опыта
- ✅ **Обновление ОЦСК сервисов**: расширена и обновлена база данных ОЦСК сервисов
  - Обновлены URL в `ocsk-services.json` для сервисов Abay и VKO на новые endpoints
  - Добавлены новые записи сервисов для областей: Atyrau, Karagandy, Kostanay, Kyzylorda, Mangystau, Turkestan, Ulytau, Zhambyl, Zhetysu
  - Обновлены названия и URL для существующих сервисов (Abay, Akmola, Aktobe, Almaty)
  - Обеспечена корректная связь всех сервисов с их соответствующими MapServer URL для улучшенного доступа к данным

### v1.5.6 - 2025-12-XX
- ✅ **Улучшение системы загрузчиков**: реализована система управления несколькими загрузчиками
  - Введена система управления загрузчиками с `_loaderStack` для обработки множественных загрузчиков
  - Обновлены функции `showLoader` и `hideLoader` для управления видимостью загрузчиков на основе стека
  - Улучшена стабильность отображения индикаторов загрузки при параллельных операциях
- ✅ **Расширение кадастровых данных**: добавлены новые поля для улучшения обработки атрибутов
  - Добавлены новые поля `zuFields3` для дополнительной кадастровой информации
  - Улучшена обработка атрибутов земельных участков
- ✅ **Улучшения UI элементов**: обновлены элементы управления картой и подвала
  - Заменен `btn-zu-check` на `checkZU` для лучшей согласованности в обработке чекбоксов
  - Скорректированы привязки событий и UI элементы в элементах управления картой и подвала
  - Улучшен пользовательский опыт при работе с картой

### v1.5.5 - 2025-11-XX
- ✅ **Оптимизация запросов к слоям карты**: улучшена логика получения объектов слоев
  - Изменены параметры запроса с "1=1" на "np=1" в вызовах `getLayerFeatures` для слоев PCH и RST
  - Уточнена логика выборки данных для повышения точности получаемых результатов
- ✅ **Фильтрация объектов с нулевыми атрибутами**: оптимизирована отрисовка карты
  - Добавлено условие пропуска объектов, где все кадастровые атрибуты (gr_pch, gr_rst, gr_ah) равны нулю
  - Улучшена эффективность рендеринга карты за счет исключения неинформативных объектов
- ✅ **Расширение кадастровых данных**: добавлены новые поля и обновлена обработка атрибутов
  - Введены новые поля `zuFields2` для дополнительной кадастровой информации, включая "Кадастровый номер" и "Площадь земельного участка"
  - Обновлены ключи атрибутов с русского на английский язык для единообразия обработки данных
  - Скорректирована логика в `showIdentResult` для использования новых полей на основе атрибутов объектов

### v1.5.4 - 2025-11-XX
- ✅ **Улучшения UI настроек агрохимии**: добавлена легенда с цветовыми индикаторами в модальном окне агрохимии
  - Добавлена новая секция легенды для визуального представления диапазонов данных
  - Введены CSS стили для легенды, включая цветовые индикаторы и метки для лучшей ясности
  - Обновлен JavaScript для динамической настройки стилей меток в зависимости от уровня масштабирования
- ✅ **Исправление обработки состояния PCH**: исправлено значение data-value чекбокса для корректной обработки состояния почвенных карт (PCH) в функции setRaion

### v1.5.3 - 2025-11-XX
- ✅ **Оптимизация управления агрохимическими данными**: улучшена логика работы с агрохимией
  - Добавлена переменная `_firstTimePchLoad` для отслеживания первого загрузки почвенных карт (PCH)
  - Обновлено значение переменной `_minZoomToShowAgroLabels` с 8 до 9 для оптимизации производительности
  - Введены новые поля `agroFields` для агрохимических данных (номер поля, площадь поля)
  - Улучшена логика переключения между слоями: почвенные карты, геоботанические карты и агрохимия
  - Обновлены функции обработки состояния агрохимии (`enableAgro`, `disableAgro`) для корректной работы при смене районов
  - Оптимизирована последовательность загрузки слоев при выборе района на карте

### v1.5.2 - 2025-11-XX
- ✅ **Улучшения агрохимии**: обновлены настройки агрохимии и улучшена доступность
  - Изменено название заголовка в модальном окне агрохимии на "Агрохимические показатели"
  - Добавлен чекбокс для выбора всех годов в настройках агрохимии
  - Обновлены стили в `app.css` для улучшения доступности и визуального оформления
  - Обновлены переводы для новых строк в `messages.po` (русский и казахский языки)
  - Расширены функции управления агрохимическими данными в `map.js`

### v1.5.1 - 2025-10-XX
- ✅ **Улучшенная обработка ошибок ЕГКН**: добавлена интеллектуальная обработка ошибок в маршруте `/get-zu/`
  - Реализована проверка текста ошибок от EGKN_WFS на наличие "map.gov4c.kz"
  - Ошибки с "map.gov4c.kz" заменяются на "Internal Server Error - сервис временно недоступен"
  - Остальные ошибки отображаются в оригинальном виде для лучшей диагностики
  - Добавлено детальное логирование ошибок для отладки и мониторинга
  - Улучшена стабильность работы с внешними сервисами ЕГКН

### v1.5.0 - 2025-10-XX
- ✅ **ОЦСК сервисы**: добавлена интеграция с ОЦСК сервисами
  - Реализован маршрут `/ocsk-services` для получения списка ОЦСК сервисов из JSON файла
  - Добавлены элементы управления для отображения ОЦСК сервисов на карте в `map_controls.html`
  - Обновлен JavaScript для загрузки и управления ОЦСК сервисами на карте
  - Интеграция с модулем `map.js` для работы с ОЦСК данными
- ✅ **Агрохимия**: расширен функционал работы с агрохимическими данными
  - **Интеграция с сервисом Ah**: подключение к ArcGIS сервису `https://ags.giprozem.kz/arcgis/rest/services/Ah/MapServer`
  - **Фильтры по годам**: комбобокс для выбора года из поля `yearob` для анализа агрохимических показателей
  - **Фильтры по показателям**: комбобокс для выбора агрохимических показателей:
    - n – Азот, p – Фосфор, k – Калий, ph – Кислотность, gum – Гумус
    - b – Бор, mn – Марганец, zn – Цинк, cu – Медь, co – Кобальт
  - **Динамическая загрузка данных**: получение объектов в зависимости от выбранных значений в комбобоксах
  - **Цветовая схема раскраски**: автоматическая раскраска по полю `gr{показатель}` (grn, grp, grk и т.д.):
    - 1 - #fd0000, 2 - #ffa803, 3 - #fffd01, 4 - #52ff00, 5 - #00ffff, 6 - #0004fa
  - **Интерактивные подписи**: отображение показателя в подписи (центроид) при наведении
  - **Клиентская обработка**: рисование и раскраска данных на стороне клиента для оптимальной производительности
  - Обновлены стили для панели агрохимии и добавлены новые элементы управления
  - Создан модальный диалог `agro_settings.html` для настройки параметров агрохимии
  - Интеграция с картографическим модулем для отображения агрохимических данных
- ✅ **Экспорт в Excel**: реализован функционал экспорта данных земельных участков в формат Excel
  - Новый маршрут `/export/zu-excel` для экспорта результатов поиска участков
  - Автоматическое форматирование данных для Excel с сохранением структуры
  - Интеграция с модулем `search.js` для экспорта найденных участков
  - Кнопка экспорта в модальном окне результатов поиска
  - Поддержка экспорта атрибутов участков (кадастровый номер, площадь, адрес и др.)
  - Обновлены стили для панели настроек агрохимии в `app.css`
  - Расширен функционал картографических операций в `map.js`

### v1.4.1 - 2025-10-XX
- ✅ **Исправление кириллицы в PDF**: решена проблема с отображением русских и казахских символов в PDF уведомлениях
  - Добавлена установка шрифтов DejaVu Sans в Docker-контейнер (`fonts-dejavu`, `fonts-dejavu-core`, `fonts-dejavu-extra`)
  - Расширен список путей поиска шрифтов в `NotificationService` для Linux/Docker окружения
  - Шрифт DejaVu Sans обеспечивает полную поддержку кириллицы (русский и казахский языки)
  - Обновлен `Dockerfile` для автоматической установки необходимых шрифтов при сборке образа
  - Теперь вместо квадратиков (■■■) отображается корректный текст на русском и казахском языках

### v1.4.0 - 2025-10-XX
- ✅ **Поиск по кадастровому номеру**: реализован полнофункциональный модуль поиска земельных участков по кадастровому номеру
  - Новый модуль `search.js` для обработки логики поиска с полной документацией
  - Интерфейс поиска в navbar с кнопкой очистки и индикатором загрузки
  - Модальное окно `search_result.html` для отображения детальных атрибутов найденного участка
  - Визуализация найденных участков на карте с автоматическим центрированием и подсветкой
  - Расширенные стили для панели результатов поиска в `app.css` (137 строк новых стилей)
  - Интеграция с существующим API ЕГКН (`/get-zu/<kad_nomer>`)
  - Поддержка всех типов геометрии (Point, LineString, Polygon, MultiPolygon)
  - Автоматическое форматирование и отображение атрибутов участка (кадастровый номер, площадь, адрес и др.)
  - Очистка предыдущих результатов поиска при новом запросе
  - Полная поддержка локализации (русский/казахский) для всех элементов интерфейса
  - Обработка ошибок с информативными уведомлениями пользователю
- ✅ **Улучшения картографии**: расширены функции работы с геометрией в `map.js`
  - Новые функции для преобразования координат и работы с различными типами геометрии
  - Улучшена поддержка отображения результатов поиска на карте

### v1.3.18 - 2025-10-XX
- ✅ **Улучшения базы данных**: добавлено поле `created_at` в запросы создания заявок с безопасной обработкой дат
- ✅ **Отображение координат на карте**: реализована функция `showRequestOnMap` для визуализации геометрии заявок на карте
- ✅ **Обработка геометрии**: добавлены функции `simpleReverseCooridnates` для реверсирования координат различных геометрических типов
- ✅ **Поддержка проекций**: подключена библиотека `proj4leaflet.js` для работы с различными системами координат
- ✅ **Интерфейс кадастровых номеров**: улучшен UI для ввода и обработки кадастровых номеров с индикаторами загрузки
- ✅ **Восстановление порядка скриптов**: исправлен порядок подключения `proj4.js` и `proj4leaflet.js` в `base.html`
- ✅ **Улучшенная обработка ошибок**: обновлены сообщения об ошибках и добавлено логирование для отладки слоев

### v1.3.17 - 2025-10-XX
- ✅ **Интеграция с ЕГКН**: добавлен новый модуль `app/blueprints/egkn.py` для работы с Единым государственным кадастром недвижимости
- ✅ **API поиска участков**: новый endpoint `GET /get-zu/<kad_nomer>` для поиска земельных участков по кадастровому номеру
- ✅ **Справочник районов**: добавлен файл `static/js/egkn_districts.json` с полным справочником областей и районов Казахстана
- ✅ **Конфигурация WFS**: новая настройка `EGKN_WFS` в `config.py` для настраиваемого шаблона WFS-запросов к ЕГКН
- ✅ **Валидация кадастровых номеров**: проверка формата (только цифры, длина 11-12 символов) и автоматическое определение района
- ✅ **Поддержка SRS**: автоматическое определение системы координат (SRS) для каждого района
- ✅ **UTF-8 кодировка**: корректная обработка кириллицы в ответах API
- ✅ **Расширенное логирование**: детальное логирование WFS-запросов и ошибок для отладки

### v1.3.16 - 2025-10-XX
- Маршрут `GET /get-zu/<kad_nomer>`: поиск участка по кадастровому номеру с валидацией (только цифры, длина 11–12) и определением `district_id` из `static/js/egkn_districts.json`.
- Конфигурация `EGKN_WFS` в `config.py` — шаблон WFS-запроса настраивается через `config.env`; серверный WFS-запрос возвращает GeoJSON или 404, если `features` пустой.
- Ответы API и логирование: ответы возвращаются в UTF-8 (кириллица сохраняется), добавлено логирование пути к `egkn_districts.json` и информативные ошибки.

### v1.3.15 - 2025-09-XX
- Обработка слоёв и сообщения об ошибках
  - Переработаны тексты ошибок: убрано лишнее «по выбранному региону», формулировки стали короче и понятнее.
  - Унифицированы сообщения и поведение во всех функциях включения/отключения слоёв.
- Диагностическое логирование
  - Добавлены консольные логи: отслеживание состояний чекбоксов и вызовов функций для упрощения отладки.

### v1.3.14 - 2025-09-XX
- Улучшены элементы управления картой и прозрачность слоёв/базовой карты
  - Доработана логика обработки ползунков прозрачности и UX мелочи
- Документация
  - Добавлен файл `AGENTS.md` с правилами взаимодействия, код-стайлом и ревью
- Обслуживание репозитория
  - Удалён устаревший артефакт `landmonitoring-image.tar`
  - Папка `flask_session/` исключена из трекинга git

### v1.3.13 - 2025-09-XX
- Добавлена настройка прозрачности базовой карты
  - В панели «Прозрачность» появился отдельный ползунок «Базовая карта»
  - Диапазон 0–100%: 0% — полностью прозрачная, 100% — полностью непрозрачная
  - Прозрачность применяется к активной базовой карте через `setOpacity` и хранится в состоянии карты
  - UI: `templates/partials/map_controls.html` — блок `opacity-main` с `#basemapOpacityRange`
  - JS: `static/js/map.js` — обработчик `$('input[type=range].range-opacity')` вызывает `handlePkGkOpacity('basemap', value)`,
    где для базовой карты выполняется `_mapLayer?.setOpacity(opacity)` и сохраняется `_basemapOpacity`
  - Стили: `static/css/map.css` — оформление панели прозрачности и ползунка
- Улучшения картографического UI и локализации
  - Обновлены переводы подсказок (tooltip) и подписей для панели прозрачности, базовых карт и легенды
  - Уточнены заголовки и тексты в легенде, подтверждена двуязычность
- Технические обновления и обслуживание
  - Обновлена документация по PyArmor и runtime-файлам
  - Обновлены инструкции по Docker/WSGI; улучшен `.dockerignore`
  - Удалены устаревшие артефакты (`landmonitoring-image.tar`) и мелкие исправления репозитория
  - Уточнена интеграция ArcGIS сервисов и обработка результатов (result file)

### v1.3.12 - 2025-09-XX
- Локализация и тултипы на главной странице
  - Переведены все подсказки: «Почвенная карта», «Карта земельных участков», «Прозрачность», «Полный экстент», «Увеличить», «Уменьшить» и др.
  - Исправлены атрибуты Bootstrap тултипов (`data-bs-toggle`), удалены устаревшие `data-bs-toggle2`
  - Добавлен централизованный словарь JS переводов (`_translations`) и автоперевод заголовка/сообщения в системе уведомлений
- Полная чистка и обновление переводов (ru/kk)
  - Очищены `.po` от устаревших записей `#~`, удалены дубликаты, сняты `fuzzy`
  - Исправлен путь к каталогам переводов, пересобраны `.mo`
  - Добавлены недостающие переводы уведомлений: «Успешно», «Заявка обновлена», «Файл загружен», «Результат загружен», «Документ удален» и др.
- Улучшения UX уведомлений
  - Все вызовы `window.notifications.*` теперь автоматически переводятся при наличии словаря `_translations`
  - Единые переводы для заголовков «Ошибка», «Внимание», «Информация»

### v1.3.11 - 2025-09-XX
- Окно «Просмотр заявки»: полное редактирование для роли 01 (Исполнитель) и администратора
  - Редактируемые поля: Статус, Заголовок, Описание, Адрес, Документы (загрузка/удаление), Уведомление (генерация), Результат (загрузка файла), Координаты (GeoJSON)
  - Геометрия редактируется как GeoJSON (jsonb). Пустое значение очищает координаты
  - Кнопка «Показать на карте» доступна всегда; при наличии геометрии передаёт на карту
- База данных (schema `app`)
  - Таблица `requests`: подтверждена поддержка поля `coordinates jsonb`
  - Добавлены поля: `result_file BYTEA`, `result_created_at TIMESTAMP`
  - DDL выполняется безопасно: `lock_timeout = 3s`, `statement_timeout = 10s`
- API
  - PUT `/api/requests/<id>`: принимает `title`, `description`, `address`, `status_code`, `coordinates` (json)
  - POST `/api/requests/<id>/result`: загрузка файла результата (роль 01/админ)
  - GET `/api/requests/<id>/result-status`: наличие результата
  - GET `/api/download-result/<id>`: скачивание результата
  - GET `/api/requests/<id>/details`: флаг `has_result`
- Frontend
  - `request-details.html`: добавлены инпуты для Заголовка/Описание/Адрес, редактор GeoJSON
  - `request-details.js`: корректный режим редактирования, строгий сброс состояния при открытии/закрытии, валидация GeoJSON, обновление таблиц «Заявки»/«Личный кабинет» после сохранения
  - Кнопка «Редактировать» корректно отображается (дозагрузка статуса авторизации при необходимости)
- Исправления
  - Зависание при инициализации индексов/DDL — добавлены таймауты
  - JSON serialization bytes — возвращается только `has_result`
  - GROUP BY для `has_result` — использован `bool_or(...)`
  - `result_text` удалён из PUT; результат — отдельный endpoint
  - Серая подложка после Сохранить/Загрузить/Генерации — модалка не пересоздаётся, корректно закрывается
  - Обновление списков после сохранения — определяется активная модалка и обновляется соответствующий список

### v1.3.10 - 2025-09-XX
- ✅ Исправлено отсутствие дат/времени в модалке «Логирование» и в «Настройки» → «История авторизаций»
  - Backend: гарантирована установка времени при вставке записей
    - `DatabaseManager.save_auth_history(...)` теперь явно задаёт `login_time = CURRENT_TIMESTAMP`
    - В `_ensure_indexes` добавлена проверка/установка DEFAULT и безопасный backfill для:
      - `app.user_activity_logs.created_at`
      - `app.auth_history.login_time`
  - База данных (schema `app`):
    - Установлены DEFAULT значения для указанных колонок
    - Выполнен разовый backfill `NULL` значений (миграция данных без простоя)
  - Frontend: форматирование дат на месте (dd.mm.yyyy HH:MM:SS) продолжает работать корректно

### v1.3.9 - 2025-09-XX
- ✅ Окно «Просмотр заявки»: разграничение прав и режим редактирования
  - Роль 01 (Исполнитель): редактирование всех полей — «Статус», «Документы» (загрузка/удаление), «Уведомление» (генерация), «Результат» (загрузка файла)
  - Прочие роли: только просмотр; добавлено отображение поля «Результат»
- ✅ Поле «Результат» переведено в файловый формат и хранится в БД аналогично уведомлениям
  - БД: в таблицу `requests` добавлены поля `result_file BYTEA` и `result_created_at TIMESTAMP`
  - Репозиторий: добавлены методы `save_result_file`, `get_result_file`, `has_result`
  - API:
    - `POST /api/requests/<id>/result` — загрузка результата (доступ для роли 01 и администратора)
    - `GET /api/requests/<id>/result-status` — проверка наличия результата
    - `GET|HEAD /api/download-result/<id>` — скачивание результата (права, как для уведомлений)
    - `GET /api/requests/<id>/details` — добавлен флаг `has_result`
  - UI:
    - В модалке «Просмотр заявки» добавлена кнопка «Скачать» для результата и загрузка результата в режиме редактирования (роль 01)
    - В таблицах «Личный кабинет» и «Заявки» столбец «Результат» показывает кнопку «Скачать» при наличии результата
  - JS:
    - `documents.js`: добавлена функция `downloadResult(requestId)`
    - `requests.js`, `personal.js`: вывод кнопки скачивания результата по `has_result`
    - `request-details.js`: загрузка результата (POST) и отображение кнопки скачивания

### v1.3.8 - 2025-09-XX
- ✅ **Страница тестирования ArcGIS сервисов**: добавлена страница `/test` для просмотра списка сервисов ArcGIS с возможностью детального просмотра и измерения времени загрузки
- ✅ **ArcGIS Service интеграция**: новый сервис `ArcGISService` для работы с ArcGIS REST API
- ✅ **Тестовые представления**: добавлены страницы `/test` и `/testview` для тестирования и мониторинга ArcGIS сервисов
- ✅ **Демо-режим**: автоматическое переключение на тестовые данные при недоступности ArcGIS сервера
- ✅ **Измерение производительности**: отображение времени загрузки сервисов для мониторинга производительности
- ✅ **Обновление переводов**: расширена поддержка локализации для новых функций
- ✅ **Улучшения картографических функций**: обновления в CSS и JavaScript для лучшей работы с картами

### v1.3.7 - 2025-08-XX
- ✅ **Переход на ArcGIS Server**: реализован переход отображения пространственных данных с GeoServer на ArcGIS Server
- ✅ **Новая конфигурация ARCGIS_SERV_URL**: добавлена поддержка ArcGIS REST API
- ✅ **Двойная система поддержки**: сохранена совместимость с GeoServer (WMS/WFS) и добавлена поддержка ArcGIS Server
- ✅ **Улучшенная производительность**: оптимизированные запросы к серверу, кэширование метаданных
- ✅ **Расширенная функциональность**: автоматическое получение списка слоев, улучшенная система легенд
- ✅ **Новый маршрут прокси**: `/Proxy/Map/<path:service_path>` для ArcGIS REST API запросов
- ✅ **Интеграция с ESRI Leaflet**: поддержка динамических слоев и REST API
- ✅ **Настраиваемая схема базы данных**: вынесена схема БД в конфиг (`DATABASE_SCHEMA`)
- ✅ **Динамическое использование схемы**: все SQL запросы используют схему из конфига
- ✅ **Гибкость конфигурации**: по умолчанию `public`, текущая `giprozem`
- ✅ **Обратная совместимость**: поддержка существующих данных
- ✅ **Улучшенная архитектура**: централизованное управление схемой через `_get_schema()`
- ✅ **Документация Windows**: добавлена ссылка на подробную инструкцию развертывания на Windows

### v1.3.6 - 2025-08-XX
- ✅ **Детальный просмотр заявок**: новое модальное окно с полной информацией о заявке при клике на номер
- ✅ **Интерактивные номера заявок**: кликабельные номера заявок в таблицах "Заявки" и "Личный кабинет"
- ✅ **API для детальной информации**: новый endpoint `/api/requests/<id>/details` для получения полных данных заявки
- ✅ **Модульная архитектура**: добавлен модуль `request-details.js` для управления просмотром заявок
- ✅ **Улучшенная система модальных окон**: корректная обработка z-index и жизненного цикла для нового окна

### v1.3.5 - 2025-08-XX
- ✅ **Билингвальные PDF уведомления**: все уведомления генерируются на русском и казахском языках одновременно
- ✅ **Исправление скачивания уведомлений**: решена проблема с зависанием запросов при скачивании PDF
- ✅ **Улучшенная обработка ошибок**: корректные сообщения об отсутствии уведомлений и ошибках доступа

### v1.3.4 - 2025-08-XX
- ✅ **Система уведомлений о приеме заявок**: автоматическая генерация PDF уведомлений с QR-кодом для верификации (NotificationService, ReportLab, хранение в БД, API endpoints, frontend интеграция)
- ✅ **QR-код верификации**: публичный доступ к уведомлениям через QR-код для проверки подлинности документов
- ✅ **Расширение БД**: добавлены поля `notification_pdf` и `notification_created_at` в таблицу `requests`
- ✅ **Исправление кодировки**: решена проблема с отображением кириллицы в PDF (использование шрифта Times-Roman с поддержкой Unicode)
- ✅ **Исправление QR-кода**: QR-код теперь содержит полный URL с доменом и номером заявки (настраиваемый домен в config.env)

### v1.3.3 - 2025-08-XX
- ✅ **Системные логи**: полный функционал для работы с лог файлами (просмотр, скачивание, управление, ротация до 5 файлов по 1 МБ, веб-интерфейс, API endpoints, проверка прав администратора, модуль `system-logs.js`)
- ✅ **Gzip сжатие**: автоматическое сжатие статических файлов и API ответов (экономия трафика 60-80%, поддержка JavaScript/CSS/HTML/JSON, уровень сжатия 6, минимальный размер 500 байт)

### v1.3.2 - 2025-08-XX
- ✅ Добавлена галочка "Получать уведомления" в настройки пользователя
- ✅ Расширена таблица `user_settings` полем `notifications_enabled`
- ✅ Обновлены API endpoints для работы с настройками уведомлений
- ✅ Добавлены переводы для нового функционала (русский/казахский)
- ✅ Улучшена валидация данных в формах настроек

### v1.3.1 - 2025-08-XX
- ✅ Исправлены критические ошибки в работе с БД (psycopg3)
- ✅ Улучшена обработка ошибок и валидация данных
- ✅ Оптимизированы SQL-запросы и индексация
- ✅ Добавлена поддержка современных драйверов PostgreSQL

### v1.3.0 - 2025-08-XX
- ✅ Система ролей пользователей (user, admin)
- ✅ Управление пользователями для администраторов
- ✅ Модульная архитектура JavaScript (ES6 Modules)
- ✅ Улучшенная система уведомлений
- ✅ Оптимизация производительности API
- ✅ Расширенная система логирования
- ✅ Вкладка "Мои участки и отводы" в "Настройки" (CRUD, хранение в БД, GeoJSON)

### v1.2.0 - 2025-08-XX
- ✅ Оптимизация API для получения документов
- ✅ Улучшенная система логирования
- ✅ Поддержка локализации (русский/казахский)
- ✅ Система заявок и документооборота
- ✅ Автоматическое переключение геосерверов
- ✅ История авторизаций пользователей

### v1.1.0 - 2025-08-XX
- ✅ Аутентификация по ЭЦП
- ✅ Настройки пользователей
- ✅ Интерактивная карта с множественными слоями
- ✅ Поиск по областям и районам

### v1.0.0 - 2025-07-XX
- ✅ Базовая функциональность карты
- ✅ Подключение к геосерверу
- ✅ Проксирование WMS/WFS запросов

## 📄 Лицензия

Проект разработан для **РГП "ГИПРОЗем"** и является проприетарным программным обеспечением.

---

## 📞 Контакты

### 🏢 РГП "ГИПРОЗем"
**Республиканское государственное предприятие "ГИПРОЗем"**

| Контакт | Информация |
|---------|------------|
| 📧 **Email** | [giprozem@giprozem.kz](mailto:giprozem@giprozem.kz) |
| 📞 **Телефон** | +7 700 232 7830 |
| 🌐 **Веб-сайт** | [giprozem.kz](https://giprozem.kz) |
| 📍 **Адрес** | Республика Казахстан, город Астана, Проспект Республики 70 |

### 👨‍💻 Разработчик
**Виктор С.** - Ведущий разработчик
[![Email](https://img.shields.io/badge/Email-viktor.kz%40gmail.com-blue?style=flat-square&logo=gmail)](mailto:viktor.kz@gmail.com) [![Telegram](https://img.shields.io/badge/Telegram-%40viktor__kz-blue?style=flat-square&logo=telegram)](https://t.me/viktor_kz)

---

**Для получения дополнительной информации, технической поддержки или коммерческих предложений обращайтесь в РГП "ГИПРОЗем".**
