Skip to content

Commit 9087fba

Browse files
docs: добавлена полная документация проекта (10 файлов)
1 parent 03c4680 commit 9087fba

10 files changed

Lines changed: 1664 additions & 0 deletions

docs/01-overview.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# 📖 HH.ru Analytics — Обзор проекта
2+
3+
## Что это?
4+
5+
**HH.ru Analytics** — профессиональная ETL-система для сбора, обработки и анализа вакансий с HH.ru с автоматическим извлечением навыков (Hard Skills, Soft Skills, Tools) и формированием аналитических отчётов.
6+
7+
## Ключевые возможности
8+
9+
### 📊 Аналитика в реальном времени
10+
- **8 KPI метрик** с трендами (Средняя ЗП, Медиана, Вакансий, Навыков, Компаний, Регионов, Hard Skills, Soft Skills)
11+
- **Топ-20 навыков** по категориям (Hard Skills, Soft Skills, Tools)
12+
- **Фильтры аналитики**: период, домен, регион, опыт, зарплата
13+
- **Sparklines** — мини-графики трендов в KPI-карточках (14 дней)
14+
15+
### 🔍 Поиск и фильтрация
16+
- Автодополнение вакансий, регионов и навыков
17+
- Расширенные фильтры (опыт, зарплата, навыки)
18+
- Пагинация результатов
19+
- Сортировка по зарплате и дате
20+
21+
### 📥 Экспорт данных
22+
- **PDF** — отчёты с KPI и топ навыков
23+
- **Excel** — 5 листов (KPI, Hard, Soft, Tools, Данные)
24+
- **CSV** — сырые данные для импорта
25+
26+
### 🤖 Парсер вакансий
27+
- Оптимизированный сбор данных с API HH.ru
28+
- Кэширование запросов (SQLite, автоочистка >7 дней)
29+
- Инкрементальное обновление (только новые вакансии)
30+
- Прогресс в реальном времени
31+
- **Защита**: обязательная настройка email перед запуском парсера
32+
33+
### 🎨 UX/UI
34+
- **Hero-секция** с призывом к действию
35+
- **Onboarding Wizard** — пошаговый гайд из 3 шагов
36+
- **Skeleton-анимации** загрузки для всех секций дашборда
37+
- **Vue.js 3** SPA (Single Page Application)
38+
- **Chart.js** для графиков
39+
- **Tailwind CSS** для стилей
40+
41+
## Технологический стек
42+
43+
| Компонент | Технология |
44+
|-----------|-----------|
45+
| **Backend** | FastAPI + Uvicorn (Python 3.10+) |
46+
| **Frontend** | Vue.js 3 + Chart.js + Tailwind CSS (CDN) |
47+
| **БД** | SQLite (dev) → PostgreSQL (prod) |
48+
| **ORM** | SQLAlchemy 2.0 |
49+
| **Парсер** | requests + tenacity (retry logic) |
50+
| **Аналитика** | pandas + numpy + openpyxl |
51+
52+
## Архитектура (высокоуровневая)
53+
54+
```
55+
┌─────────────────────────────────────────────────────┐
56+
│ Пользователь (браузер) │
57+
│ Vue.js 3 SPA → API запросы │
58+
└──────────────────┬──────────────────────────────────┘
59+
│ HTTP
60+
61+
┌─────────────────────────────────────────────────────┐
62+
│ FastAPI (web/app/main.py) │
63+
│ ├── /api/dashboard → KPI, навыки, вакансии │
64+
│ ├── /api/parser/start → запуск парсера (bg task) │
65+
│ ├── /api/analytics/* → расширенная аналитика │
66+
│ ├── /api/export/* → PDF/Excel/CSV │
67+
│ └── /api/user/email → настройка email │
68+
└──────────┬──────────────────────────────┬────────────┘
69+
│ │
70+
▼ ▼
71+
┌──────────────────────┐ ┌──────────────────────────┐
72+
│ SQLite (hh_vacancies│ │ APICache (api_cache.db) │
73+
│ db) │ │ Кэш HH API запросов │
74+
│ ├── vacancies │ │ (автоочистка >7 дней) │
75+
│ ├── parser_runs │ └──────────────────────────┘
76+
│ └── app_settings │
77+
└──────────────────────┘
78+
79+
80+
┌─────────────────────────────────────────────────────┐
81+
│ Оптимизированный парсер (optimized_parser.py) │
82+
│ ├── HH API client → сбор вакансий │
83+
│ ├── Кэширование ответов │
84+
│ └── Инкрементальный режим │
85+
└─────────────────────────────────────────────────────┘
86+
```
87+
88+
## Быстрый старт
89+
90+
```bash
91+
cd hh_analytics
92+
python -m venv venv
93+
venv\Scripts\activate # Windows
94+
pip install -r requirements.txt
95+
python web/run.py
96+
# Открой http://localhost:8000
97+
```
98+
99+
## Лицензия
100+
101+
MIT

docs/02-architecture.md

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# 🏗 Архитектура и схема работы
2+
3+
## Общая архитектура
4+
5+
Проект построен на **ETL-архитектуре** (Extract → Transform → Load → Analyze):
6+
7+
```
8+
[HH.ru API] → Extract → [Raw JSON] → Transform → [Processed DataFrame]
9+
10+
Load → [SQLite/PostgreSQL] → Analyze → [Dashboard/Reports]
11+
```
12+
13+
## Компоненты системы
14+
15+
### 1. Парсер (Extract)
16+
17+
**Файлы:**
18+
- `optimized_parser.py` — основной парсер
19+
- `src/api_client.py` — клиент HH API
20+
- `src/collector.py` — сборщик вакансий
21+
22+
**Поток данных:**
23+
```
24+
User запускает парсер
25+
26+
Проверка email (403 если не настроен)
27+
28+
Для каждого запроса:
29+
1. Проверка кэша (api_cache.db)
30+
2. Если нет в кэше → запрос к HH API
31+
3. Сохранение в кэш (24 часа TTL)
32+
4. Сохранение в raw JSON
33+
34+
Векторизованная обработка навыков
35+
36+
Загрузка в БД (upsert)
37+
```
38+
39+
**Кэширование:**
40+
```python
41+
# APICache в optimized_parser.py
42+
class APICache:
43+
# Таблица: api_cache
44+
# Поля: url, response_json, timestamp
45+
# Автоочистка: >7 дней
46+
```
47+
48+
**Rate Limiting:**
49+
- Задержка между запросами: `API_REQUEST_DELAY=1.0s`
50+
- Retry logic: tenacity (экспоненциальный backoff)
51+
- Обработка 429 ошибок
52+
53+
### 2. Процессор (Transform)
54+
55+
**Файлы:**
56+
- `src/processor.py` — VacancyProcessor
57+
- `config.yaml` — словари навыков
58+
59+
**Что делает:**
60+
```python
61+
class VacancyProcessor:
62+
def process_vacancies(df):
63+
# 1. Извлечение hard_skills из description
64+
# 2. Извлечение soft_skills
65+
# 3. Извлечение tools/технологий
66+
# 4. Подсчёт skill_count
67+
# 5. Нормализация зарплат
68+
return processed_df
69+
```
70+
71+
### 3. Хранилище (Load)
72+
73+
**Файлы:**
74+
- `src/storage.py` — VacancyStorage
75+
76+
**Таблицы:**
77+
```sql
78+
-- vacancies (основная)
79+
id, vacancy_id (UNIQUE), vacancy_name, published_at,
80+
all_skills, hard_skills, soft_skills, tools,
81+
skill_count, hard_skill_count, soft_skill_count, tools_count,
82+
salary_from, salary_to, salary_currency, salary_gross,
83+
employer_name, employer_id, employer_url, vacancy_url,
84+
experience, employment, schedule, area,
85+
created_at, updated_at
86+
87+
-- parser_runs (журнал парсингов)
88+
id, started_at, completed_at, status,
89+
keywords (JSON), max_pages, days_back,
90+
is_incremental, use_cache,
91+
vacancies_collected, vacancies_new, vacancies_updated,
92+
errors_count, error_message, created_at
93+
94+
-- app_settings (синглтон, id=1)
95+
id=1, last_parse_at, last_successful_parse_at,
96+
total_parses, total_vacancies_collected,
97+
app_version, config_version, updated_at
98+
```
99+
100+
**Индексы:**
101+
```sql
102+
idx_vacancy_id, idx_employer, idx_area,
103+
idx_published_at, idx_experience,
104+
idx_salary_from, idx_created_at
105+
```
106+
107+
**Режимы сохранения:**
108+
- `save_dataframe()` — полная замена (if_exists='replace')
109+
- `save_vacancies_incremental()` — upsert логика (INSERT OR UPDATE)
110+
111+
### 4. Аналитика (Analyze)
112+
113+
**Файлы:**
114+
- `src/analyzer.py` — базовая аналитика
115+
- `src/advanced_analyzer.py` — расширенная аналитика
116+
117+
**Что считает:**
118+
```python
119+
class VacancyAnalyzer:
120+
# Частота навыков (hard/soft/tools)
121+
# Статистика зарплат (по опыту, регионам, занятости)
122+
# Excel-отчёты с графиками (openpyxl)
123+
124+
class AdvancedAnalytics:
125+
# Группировки: LLM, Vector DB, RAG, ML libs, Cloud, Docker, CI/CD
126+
# Карта связей "вакансия-навык"
127+
# Детальный Excel-отчёт (6 листов)
128+
```
129+
130+
### 5. Веб-приложение (Serve)
131+
132+
**Файлы:**
133+
- `web/app/main.py` — FastAPI сервер
134+
- `web/static/index.html` — Vue.js 3 SPA
135+
- `web/run.py` — точка входа (uvicorn)
136+
137+
**Endpoints:**
138+
```
139+
GET / → index.html
140+
GET /analytics → analytics.html
141+
GET /api/health → {"status": "ok"}
142+
GET /api/dashboard → KPI, навыки, вакансии, sparklines
143+
GET /api/vacancies → список с фильтрами/сортировкой
144+
GET /api/analytics/kpi → 8 KPI метрик с трендами
145+
GET /api/analytics/top-skills → топ навыков (hard/soft/tools)
146+
GET /api/analytics/distribution → опыт, занятость, зарплаты, регионы
147+
GET /api/analytics/advanced → технологии, hard/soft skills
148+
GET /api/parser/status → статус парсера
149+
POST /api/parser/start → запуск парсера (требует email!)
150+
GET /api/parser/stop → остановка
151+
GET /api/parser/last-run → последний запуск
152+
GET /api/parser/history → история запусков
153+
GET /api/user/email → статус email
154+
POST /api/user/email → сохранить email
155+
GET /api/app/settings → настройки приложения
156+
GET /api/reports/list → список отчётов
157+
GET /api/export/vacancies → экспорт (xlsx/csv)
158+
POST /api/export/analytics → экспорт аналитики
159+
GET /api/professions/* → каталог профессий
160+
GET /api/autocomplete/* → автодополнение
161+
```
162+
163+
**Фоновые задачи:**
164+
- Парсер запускается через `BackgroundTasks` FastAPI
165+
- Автоматическое обновление статуса каждые 2 сек (polling)
166+
- Генерация отчётов в фоне
167+
168+
## Поток запроса пользователя
169+
170+
```
171+
1. Пользователь открывает http://localhost:8000
172+
2. FastAPI отдаёт index.html (статический файл)
173+
3. Vue.js делает fetch('/api/dashboard')
174+
4. FastAPI читает из SQLite → возвращает JSON
175+
5. Vue.js рендерит графики Chart.js
176+
6. Парсинг: POST /api/parser/start → BackgroundTask → in-progress polling
177+
```
178+
179+
## Безопасность
180+
181+
- **Email required**: 403 при попытке запустить парсер без настроенного email
182+
- **Rate limiting**: задержка 1с между запросами к HH API
183+
- **.env**: не коммитится в Git (секреты)
184+
- **CORS**: разрешены все origins (для dev, изменить для prod)

0 commit comments

Comments
 (0)