# RSS Parser для бизнес-новостей

Этот проект представляет собой многопарсерную систему для сбора бизнес-новостей с различных источников, разработанную на Spring Boot с сохранением данных в MongoDB.

## Описание

Система включает в себя два парсера:

- **Kursiv Media** (`https://kursiv.media/feed/`)
- **Kapital.kz** (`https://kapital.kz/rss/`)

Оба парсера получают данные из RSS-лент, обрабатывают их и сохраняют в общую базу данных MongoDB с дедупликацией по хэшу.

**🔄 Автоматический режим работы:** Оба парсера автоматически запускаются каждые 30 минут (в 0 и 30 минут каждого часа) для обеспечения актуальности данных.

## Технологический стек

- **Java 21**
- **Spring Boot 3.5.5**
- **Spring Data MongoDB**
- **Rome** - библиотека для парсинга RSS
- **JSoup** - для очистки HTML
- **MongoDB** - база данных

## Структура проекта

```
src/main/java/kz/konturai/parser/
├── ParserApplication.java          # Главный класс приложения
├── controller/
│   └── ParserController.java      # REST API контроллер
├── model/
│   └── MarketItem.java            # Модель данных для MongoDB
├── repository/
│   └── MarketItemRepository.java  # Репозиторий для работы с MongoDB
└── service/
    └── KursivParserService.java   # Основной сервис парсинга
```

## Установка и запуск

### Предварительные требования

1. **Java 21** или выше
2. **MongoDB** (локально или удаленно)
3. **Maven 3.6+**

### Шаги установки

1. **Клонируйте репозиторий:**

   ```bash
   git clone <repository-url>
   cd parser
   ```

2. **Установите MongoDB:**

   - Скачайте и установите MongoDB с официального сайта
   - Запустите MongoDB сервис
   - По умолчанию MongoDB работает на порту 27017

3. **Настройте конфигурацию:**

   Отредактируйте файл `src/main/resources/application.properties`:

   ```properties
   # MongoDB Configuration
   spring.data.mongodb.host=localhost
   spring.data.mongodb.port=27017
   spring.data.mongodb.database=parser_db

   # RSS Feed URL
   rss.feed.url=https://kursiv.media/feed/
   ```

4. **Соберите проект:**

   ```bash
   ./mvnw clean compile
   ```

5. **Запустите приложение:**

   ```bash
   ./mvnw spring-boot:run
   ```

   Приложение будет доступно по адресу: `http://localhost:8080`

## API Endpoints

### 1. Запуск парсинга Kursiv Media

```http
POST /api/parser/parse/kursiv
```

**Ответ:**

```json
{
  "success": true,
  "message": "Парсинг Kursiv завершен успешно",
  "source": "Kursiv",
  "processedItems": 15,
  "totalItemsInDb": 25
}
```

### 2. Запуск парсинга Kapital.kz

```http
POST /api/parser/parse/kapital
```

**Ответ:**

```json
{
  "success": true,
  "message": "Парсинг Kapital завершен успешно",
  "source": "Kapital",
  "processedItems": 12,
  "totalItemsInDb": 37
}
```

### 3. Запуск парсинга всех источников

```http
POST /api/parser/parse/all
```

**Ответ:**

```json
{
  "success": true,
  "message": "Парсинг всех источников завершен успешно",
  "kursivProcessed": 15,
  "kapitalProcessed": 12,
  "totalProcessed": 27,
  "totalItemsInDb": 37
}
```

### 2. Получение статистики

```http
GET /api/parser/stats
```

**Ответ:**

```json
{
  "success": true,
  "totalItems": 25,
  "message": "Статистика получена успешно"
}
```

### 3. Получение всех записей

```http
GET /api/parser/items
```

**Ответ:**

```json
{
  "success": true,
  "items": [...],
  "count": 25,
  "message": "Записи получены успешно"
}
```

### 4. Проверка состояния

```http
GET /api/parser/health
```

**Ответ:**

```json
{
  "status": "UP",
  "service": "RSS Parser System",
  "timestamp": 1703123456789,
  "scheduler": "Enabled - runs every 30 minutes"
}
```

### 4.1. Проверка подключения к MongoDB

```http
GET /api/parser/health/mongodb
```

**Ответ при успешном подключении:**

```json
{
  "status": "UP",
  "message": "MongoDB подключение успешно",
  "totalItems": 37,
  "timestamp": 1703123456789
}
```

**Ответ при ошибке:**

```json
{
  "status": "DOWN",
  "message": "Ошибка подключения к MongoDB: Command failed with error 13 (Unauthorized)",
  "suggestion": "Проверьте учетные данные в application.properties",
  "timestamp": 1703123456789
}
```

### 5. Информация о планировщике

```http
GET /api/parser/scheduler/info
```

**Ответ:**

```json
{
  "schedulerEnabled": true,
  "cronExpression": "0 0/30 * * * ?",
  "description": "Запуск каждые 30 минут (в 0 и 30 минут каждого часа)",
  "nextRun": "Следующий запуск будет в ближайшие 0 или 30 минут часа"
}
```

## Структура данных в MongoDB

Документы сохраняются в коллекции `market_items` со следующей структурой:

```json
{
  "_id": "ObjectId",
  "source_name": "Kursiv (Бизнес/экономика)",
  "url": "https://kursiv.media/article/...",
  "title": "Заголовок новости",
  "published_at": "2025-01-14T10:30:00",
  "added_at": "2025-01-14T12:00:00",
  "raw_text": "Очищенный от HTML текст статьи...",
  "hash": "sha256_hash_of_url_and_title",
  "category": "Бизнес",
  "analytics": {
    "summary": null,
    "sentiment": null,
    "tags": [],
    "entities": {}
  }
}
```

## Особенности реализации

### Дедупликация

- Каждая запись имеет уникальный хэш, сгенерированный по формуле: `SHA256(url + "::" + title)`
- При повторном парсинге существующие записи обновляются (upsert операция)

### Очистка данных

- HTML-теги удаляются из текста описания
- Даты приводятся к формату `LocalDateTime`
- Текстовое содержимое нормализуется

### Обработка ошибок

- Логирование всех операций
- Graceful handling ошибок парсинга отдельных записей
- Продолжение работы при ошибках в отдельных элементах RSS

### Автоматический планировщик

- **Автозапуск**: Оба парсера автоматически запускаются каждые 30 минут
- **Cron выражение**: `0 0/30 * * * ?` (запуск в 0 и 30 минут каждого часа)
- **Параллельная работа**: KursivParserService и KapitalParserService работают независимо
- **Логирование**: Все автоматические запуски логируются с эмодзи для удобства мониторинга
- **Обработка ошибок**: Ошибки в автоматическом режиме не останавливают планировщик

### Многопарсерная архитектура

- **Общая модель данных**: Оба парсера используют одну модель `MarketItem`
- **Общая коллекция**: Все новости сохраняются в коллекцию `market_items`
- **Дедупликация**: Хэш генерируется одинаково для всех источников
- **Разделение источников**: Поле `source_name` позволяет различать источники данных

## Тестирование

Запуск тестов:

```bash
./mvnw test
```

Тесты включают:

- Проверку парсинга RSS-лент обоих источников
- Проверку сохранения в MongoDB
- Проверку дедупликации
- Проверку структуры данных
- Проверку работы планировщика
- Проверку многопарсерной архитектуры

## Мониторинг и логирование

Приложение использует SLF4J для логирования. Уровень логирования можно настроить в `application.properties`:

```properties
logging.level.kz.konturai.parser=DEBUG
logging.level.org.springframework.data.mongodb=DEBUG
```

## Возможные проблемы и решения

### MongoDB требует аутентификацию

```
Command failed with error 13 (Unauthorized): 'Command find requires authentication'
```

**Решение:**

1. Проверьте учетные данные в `application.properties`
2. Убедитесь, что пользователь `parser_user` существует в MongoDB
3. Проверьте права доступа пользователя к базе данных `parser_db`
4. Используйте endpoint `GET /api/parser/health/mongodb` для диагностики

**Подробное руководство:** См. файл `MONGODB_TROUBLESHOOTING.md`

### MongoDB не запущен

```
Error: Could not connect to MongoDB
```

**Решение:** Убедитесь, что MongoDB запущен и доступен на указанном хосте и порту.

### RSS-лента недоступна

```
Error: Could not fetch RSS feed
```

**Решение:** Проверьте доступность URL RSS-лент и интернет-соединение.

### Проблемы с кодировкой

Если возникают проблемы с кодировкой текста, убедитесь, что в системе установлена правильная локаль.

## Развертывание в продакшене

1. **Настройте переменные окружения:**

   ```bash
   export SPRING_DATA_MONGODB_HOST=your-mongodb-host
   export SPRING_DATA_MONGODB_PORT=27017
   export SPRING_DATA_MONGODB_DATABASE=parser_prod
   ```

2. **Соберите JAR файл:**

   ```bash
   ./mvnw clean package
   ```

3. **Запустите приложение:**
   ```bash
   java -jar target/parser-0.0.1-SNAPSHOT.jar
   ```

## Лицензия

Этот проект разработан для внутреннего использования в рамках AI-платформы для маркетинговой аналитики.
