# IGF Admin - Универсальный интерфейс управления данными MongoDB

Мощный, полностью адаптивный интерфейс администратора на базе Streamlit для управления данными в MongoDB. Система разработана для работы с **любой структурой JSON**, **любой коллекцией** и **любой схемой полей** без изменения кода.

## 🌟 Ключевые возможности


### Универсальная поддержка JSON
- **Любая структура JSON**: Обрабатывает глубоко вложенные объекты, массивы, смешанные типы - неограниченная глубина
- **Без жёстко заданных полей**: Работает с ЛЮБЫМИ именами полей автоматически
- **Автоматическое сплющивание**: Преобразует вложенный JSON в плоские пары ключ-значение для табличного редактирования
- **Обработка без потерь**: Каждое поле из исходного JSON сохраняется - нулевая потеря данных

### Полностью адаптивная архитектура
- **Динамическое обнаружение коллекций**: Автоматически определяет доступные коллекции
- **Динамическое обнаружение полей**: Автоматически находит все поля во всех записях
- **Настраиваемые бизнес-ключи**: Определение правил сопоставления для каждой коллекции через YAML конфиг
- **Множественные стратегии сопоставления**: Первичные ключи, альтернативные ключи или комбинированное сопоставление

### Полный контроль данных
- **Предпросмотр перед импортом**: Просмотр всех записей до любых записей в базу данных
- **Редактирование на уровне полей**: Редактирование отдельных полей в интерфейсе типа электронной таблицы
- **Решения по каждой записи**: Импорт, пропуск или отметка как ожидающие для каждой записи
- **Требуется подтверждение**: Никаких автоматических записей - пользователь должен подтвердить все операции

## 🏗️ Архитектура

```
igf-admin/
├── app.py                    # Основное приложение Streamlit
├── config/
│   └── app_config.yaml       # Конфигурация коллекций и сопоставления
├── services/
│   ├── json_flattener.py     # Универсальное сплющивание JSON (любая глубина)
│   ├── json_loader.py        # Загрузка JSON файлов из директорий
│   ├── diff_engine.py        # Сравнение и сопоставление записей
│   ├── import_preview_engine.py  # Предпросмотр и редактирование импорта
│   ├── data_service.py       # Операции с данными MongoDB
│   ├── mongo.py              # Управление подключением к MongoDB
│   ├── settings_service.py   # Управление конфигурацией
│   ├── schema_manager.py     # Обнаружение и управление схемой
│   ├── update_engine.py      # Операции обновления записей
│   ├── backup_service.py     # Функциональность резервного копирования
│   └── foreign_key_validator.py  # Валидация внешних ключей
└── ui/
    └── tabs/
        ├── json_vs_db.py     # UI сравнения JSON vs MongoDB
        └── settings.py       # UI настроек и конфигурации
```

## 🔧 Основные компоненты

### JSONFlattener
Сердце универсальной поддержки JSON:
- Рекурсивно сплющивает ЛЮБУЮ вложенную структуру
- Использует точечную нотацию для путей: `parent.child.0.field`
- Обрабатывает массивы объектов и примитивов
- Поддерживает обратное преобразование для вставки в MongoDB
- **Никаких предположений об именах полей** - работает с любой схемой

### DiffEngine
Интеллектуальное сравнение записей:
- **Точное сопоставление**: Сравнение по SHA256 хешу
- **Сопоставление по бизнес-ключам**: Настраиваемые первичные ключи
- **Сопоставление по альтернативным ключам**: Резервная стратегия сопоставления
- **Сравнение поле-за-полем**: Выявление всех различий

### ImportPreviewEngine
Безопасный рабочий процесс импорта:
- Создаёт редактируемые DataFrame из любой структуры записей
- Отслеживает решения пользователя (импорт/пропуск/ожидание)
- Подготавливает записи для вставки в MongoDB
- Автоматически удаляет метаданные

## 📋 Конфигурация

### Конфигурация коллекций (app_config.yaml)

```yaml
collections:
  your_collection:
    enabled: true
    json_folder: folder_name        # Папка в источнике JSON
    business_keys:
      - field1                      # Поля для первичного сопоставления
      - field2
    alternative_keys:
      - alt_field1                  # Поля для резервного сопоставления
    matching_strategy: primary_or_alternative
    allow_manual_import: true
    description: Описание вашей коллекции
```

### Стратегии сопоставления
- `primary_only`: Сопоставление только по business_keys
- `primary_or_alternative`: Сначала business_keys, затем alternative_keys
- `alternative_only`: Сопоставление только по alternative_keys

## 🚀 Начало работы

### Требования
- **Python 3.10+** (обязательно)
- **Streamlit 1.36.0+** (для поддержки параметра width в кнопках)
- Экземпляр MongoDB
- Файлы данных JSON

### Установка

```bash
# Клонирование репозитория
git clone <repository-url>
cd igf-admin

# Установка зависимостей
pip install -r requirements.txt

# Настройка окружения
cp .env.example .env
# Отредактируйте .env с вашим MongoDB URI
```

### Конфигурация

1. **Установите MongoDB URI** в `.env`:
   ```
   MONGO_URI=mongodb://localhost:27017
   ```

2. **Настройте коллекции** в `config/app_config.yaml`:
   - Добавьте ваши коллекции
   - Определите бизнес-ключи для обнаружения дубликатов
   - Установите соответствия папок JSON

3. **Разместите JSON файлы** в настроенной директории источника

### Запуск (Локально)

```bash
python -m streamlit run app.py
```

### Запуск с Docker

```bash
# Сборка образа
docker build -t igf-admin .

# Запуск контейнера
docker run -d -p 8501:8501 \
  -e MONGO_URI=mongodb://your-host:27017 \
  -v $(pwd)/config:/app/config \
  -v $(pwd)/idf-json-sample:/app/idf-json-sample \
  igf-admin
```

Доступ к приложению: http://localhost:8501

## 📊 Рабочий процесс

### Сравнение JSON vs DB

1. **Выберите источник**: Выберите папку источника JSON (например, tokyo_2020)
2. **Выберите коллекцию**: Выберите целевую коллекцию (отфильтровано по доступным данным)
3. **Загрузить и сравнить**: Система сравнивает записи JSON с MongoDB
4. **Просмотр результатов**:
   - **Точные совпадения**: Записи идентичны в обоих источниках
   - **Дубликаты**: Записи с одинаковым бизнес-ключом, но разными значениями
   - **Новые записи**: Записи только в JSON, отсутствуют в MongoDB
5. **Принятие решений**: Отметьте записи для импорта или пропуска
6. **Применить импорт**: Подтвердите и выполните импорт

### Настройки

- Настройка бизнес-ключей для каждой коллекции
- Установка альтернативных ключей для резервного сопоставления
- Определение лимитов записей для сравнения
- Настройка связей внешних ключей

## 🔒 Функции безопасности

- **Никаких автоматических записей**: Все импорты требуют явного подтверждения пользователя
- **Предпросмотр всего**: Видите точно, что будет импортировано
- **Обратимые решения**: Изменяйте решения импорт/пропуск до применения
- **Поддержка резервного копирования**: Создание резервных копий перед крупными операциями
- **Валидация внешних ключей**: Проверка ссылок перед импортом

## 🎯 Примеры адаптивности

### Пример 1: Простой плоский JSON
```json
{"id": "001", "name": "John", "age": 30}
```
Обрабатывается автоматически - поля появляются как колонки.

### Пример 2: Вложенные объекты
```json
{
  "person": {
    "name": {"first": "John", "last": "Doe"},
    "contact": {"email": "john@example.com"}
  }
}
```
Сплющивается в: `person.name.first`, `person.name.last`, `person.contact.email`

### Пример 3: Массивы объектов
```json
{
  "participants": [
    {"id": "001", "score": 95},
    {"id": "002", "score": 87}
  ]
}
```
Сплющивается в: `participants.0.id`, `participants.0.score`, `participants.1.id` и т.д.

### Пример 4: Смешанная сложная структура
```json
{
  "event": {
    "name": "Olympics",
    "athletes": [
      {
        "person": {"name": "John"},
        "results": [{"round": 1, "score": 9.5}]
      }
    ]
  }
}
```
Все поля сохраняются с полной нотацией пути.

## 📝 Добавление новых коллекций

1. Добавьте коллекцию в `app_config.yaml`:
   ```yaml
   collections:
     new_collection:
       enabled: true
       json_folder: new_folder
       business_keys:
         - unique_field
       allow_manual_import: true
   ```

2. Разместите JSON файлы в `{json_source}/{json_folder}/`

3. Перезапустите приложение - новая коллекция появится автоматически

**Изменения кода не требуются!**

## 🛠️ Технические детали

### Поток данных
1. JSON файлы → JSONLoader → Сплющенные записи
2. Документы MongoDB → DataService → Сплющенные записи
3. DiffEngine сравнивает оба набора
4. ImportPreviewEngine создаёт редактируемый предпросмотр
5. Пользователь принимает решения
6. Записи разворачиваются и вставляются в MongoDB

### Обработка типов
- ObjectId → String (для отображения)
- DateTime → ISO String
- Вложенный Dict → Сплющивается с точечной нотацией
- Массивы → Индексируются числами (например, `items.0.name`)
- Null значения → Сохраняются

## 📄 Лицензия

[Ваша лицензия здесь]

## 🤝 Участие в разработке

Приветствуются вклады! Система разработана для расширяемости:
- Добавляйте новые сервисы в `/services`
- Добавляйте новые вкладки UI в `/ui/tabs`
- Расширяйте конфигурацию в `app_config.yaml`
