Skip to content

Duzer61/career_tracker

Repository files navigation

Career Tracker 🎯

Веб-приложение для отслеживания статуса откликов на вакансии в процессе поиска работы.
Реализовано в формате канбан-доски с Drag & Drop, историей изменений статусов и админ-панелью.


Содержание


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

Компонент Технология
Бэкенд Python 3.14+, FastAPI, SQLAlchemy 2.0 (async), Alembic
База данных PostgreSQL 16 (asyncpg)
Кэш/сессии Redis 7
Аутентификация JWT (access + refresh tokens), bcrypt (passlib)
Фронтенд HTML, CSS, JavaScript (vanilla), Jinja2-шаблоны, Chart.js
Инфраструктура Docker, Docker Compose
Защита Yandex SmartCaptcha, rate limiting
Тестирование pytest, pytest-asyncio, httpx, aiosqlite

Функциональность

🔐 Аутентификация и управление сессиями

  • Регистрация и вход с JWT-токенами (access + refresh)
  • HttpOnly cookies для безопасного хранения токенов
  • Возможность выйти с одного устройства или со всех устройств
  • Автоматическое обновление refresh-токенов (rotation)
  • Хранение активных сессий в Redis

📋 Управление заявками

  • CRUD заявок: компания, название вакансии, контакты, URL вакансии, комментарии
  • Статусы заявок:
    • created — создана
    • hr_interview — HR-собеседование
    • tech_interview — техническое собеседование
    • offer — оффер
    • rejected — отказ
    • auto_reject — автоматический отказ
    • ignored — игнорировано
  • История изменения статусов с временными метками
  • Drag & Drop на канбан-доске для быстрого изменения статуса

📅 Фильтрация и автоматизация

  • Фильтрация заявок по периодам: today, yesterday, week, month, old
  • Фильтрация по произвольному интервалу дат
  • Автоматический перевод старых заявок в статус ignored (настраиваемый период в днях)

📊 Статистика и аналитика

  • Отдельная страница /statistics с аналитикой по откликам
  • Фильтрация по произвольному диапазону дат (по умолчанию — последние 6 месяцев)
  • Счётчики: всего откликов, активных, отказов, автоотказов, в игноре, офферов
  • Воронка откликов — визуализация прохождения заявок по этапам: created → hr_interview → tech_interview → offer, с процентами конверсии
  • Время между этапами — столбчатая диаграмма и детальная таблица со средним, медианой, минимумом и максимумом в днях
  • Графики построены на Chart.js

👑 Админ-панель

  • Просмотр всех пользователей с сортировкой
  • Назначение/снятие роли администратора (только суперадмин)
  • Удаление пользователей
  • Защита:
    • Суперадмина нельзя удалить
    • Последнего администратора нельзя удалить (чтобы не потерять доступ)
  • Страница /admin с веб-интерфейсом

🛡️ Безопасность

  • Yandex SmartCaptcha на регистрацию и вход
  • Rate limiting на endpoint логина (10 попыток за 5 минут)
  • Валидация пароля: минимум 8 символов, заглавные/строчные буквы, цифры, только ASCII
  • Режим ONLY_ALLOWED_USERNAMES_MODE — доступ только по белому списку логинов
  • JWT с проверкой подписи и срока действия
  • Защита от удаления первой записи истории статуса

Модели данных

User

Поле Тип Описание
id int Первичный ключ
login str(50) Уникальный логин пользователя
hashed_password str(255) Хеш пароля (bcrypt)
is_admin bool Флаг администратора
created_at datetime Дата регистрации

Application

Поле Тип Описание
id int Первичный ключ
user_id FK -> User Владелец заявки
company_name str(255) Название компании
vacancy_name str(255) Название вакансии
contacts str(500) Контакты (опционально)
comments Text Комментарии (опционально)
vacancy_url str(500) URL вакансии (опционально)
status Enum Текущий статус
created_at datetime Дата создания
updated_at datetime Дата последнего обновления

ApplicationStatusHistory

Поле Тип Описание
id int Первичный ключ
application_id FK -> Application Заявка
status Enum Статус на момент записи
changed_at datetime Дата изменения

API Endpoints

Аутентификация — /api/auth

Метод Путь Описание
POST /register Регистрация нового пользователя
POST /login Вход в систему
POST /refresh Обновление access/refresh токенов
POST /logout Выход из текущей сессии
POST /logout-all Выход из всех сессий

Пользователи — /api/users

Метод Путь Описание
GET / Список пользователей (admin)
GET /me Информация о текущем пользователе
DELETE /me Удаление своего аккаунта
DELETE /{user_id} Удаление пользователя (admin)
PATCH /{user_id}/admin Назначение/снятие admin (суперадмин)

Заявки — /api/applications

Метод Путь Описание
GET / Список заявок с фильтрацией
POST / Создание заявки
GET /{id} Заявка по ID
PATCH /{id} Обновление заявки
DELETE /{id} Удаление заявки
GET /{id}/history История изменения статусов
DELETE /{id}/history/{history_id} Удаление записи истории
POST /auto-ignore Авто-игнорирование старых заявок

Прочие

Метод Путь Описание
GET / Главная страница (HTML)
GET /api/statistics Статистика текущего пользователя (параметры: date_from, date_to)
GET /statistics Страница статистики (HTML)
GET /admin Админ-панель (HTML, только admin)
GET /docs Swagger-документация (только dev)
GET /redoc ReDoc-документация (только dev)

Быстрый старт

Через Docker (рекомендуется)

# 1. Клонировать репозиторий
git clone https://github.com/Duzer61/career_tracker.git
cd career_tracker

# 2. Скопировать и настроить .env
cp .env.example .env
# Отредактировать .env под свои параметры

# 3. Запустить
docker compose up -d

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

Локальный запуск

Требования: Python 3.14+, PostgreSQL, Redis

# 1. Установить uv (если ещё не установлен)
pip install uv

# 2. Создать виртуальное окружение и установить зависимости
uv venv
source .venv/bin/activate
uv pip install -e .

# 3. Настроить .env (пример в .env.example)

# 4. Применить миграции
alembic upgrade head

# 5. Запустить
python main.py

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

Все настройки задаются через переменные окружения (файл .env).
Подробный пример — в .env.example.

Переменная Описание
POSTGRES_* Параметры подключения к PostgreSQL
REDIS_* Параметры подключения к Redis
SECRET_KEY Ключ для подписи JWT
ALGORITHM Алгоритм JWT (по умолчанию HS256)
ACCESS_TOKEN_EXP_MINUTES Время жизни access-токена (в минутах)
REFRESH_TOKEN_EXP_DAYS Время жизни refresh-токена (в днях)
ENVIRON Окружение: dev или prod
SMARTCAPTCHA_* Ключи Yandex SmartCaptcha
ONLY_ALLOWED_USERNAMES_MODE Включить режим белого списка логинов
ALLOWED_USERNAMES Список разрешённых логинов через запятую
SUPERADMIN_LOGIN Логин суперадминистратора
AUTO_IGNORE_DAYS Через сколько дней заявка автоматически игнорируется

Миграции базы данных

Управление миграциями — через Alembic.

# Создать новую миграцию
alembic revision --autogenerate -m "описание изменений"

# Применить все миграции
alembic upgrade head

# Откатить на одну миграцию назад
alembic downgrade -1

При запуске через Docker миграции применяются автоматически.


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

Проект использует pytest с асинхронными тестами.
Для тестов используется SQLite in-memory вместо PostgreSQL и in-memory mock вместо Redis.

# Запустить все тесты
pytest -v

# Запустить с отчётом о покрытии
pytest --cov=app -v

В тестовом окружении:

  • Суперадмин: superadmin
  • Redis заменяется на InMemoryRedisMock
  • PostgreSQL заменяется на sqlite+aiosqlite:///:memory:
  • Captcha отключена

Лицензия

Проект распространяется под лицензией MIT. Подробнее — в файле LICENSE.

Releases

No releases published

Packages

 
 
 

Contributors