281 lines
12 KiB
Markdown
281 lines
12 KiB
Markdown
|
||
# ВНИМАНИЕ
|
||
|
||
Просьба дочитать данный файл от начала и до КОНЦА, чтобы не упустить важную информацию касающуюся демонстрации проекта
|
||
|
||
# Трамплин
|
||
|
||
**Трамплин** — интерактивная карьерная платформа, которая объединяет талантливых студентов, выпускников, работодателей и кураторов вузов.
|
||
Соискатели находят стажировки, вакансии, менторские программы и карьерные мероприятия. Работодатели публикуют возможности и получают отклики. Кураторы модерируют контент, верифицируют компании и управляют пользователями.
|
||
|
||
Платформа включает:
|
||
- интерактивную карту с вакансиями и мероприятиями,
|
||
- карточки возможностей с тегами навыков,
|
||
- личные кабинеты трёх ролей,
|
||
- систему откликов и статусов,
|
||
- нетворкинг между соискателями,
|
||
- верификацию работодателей,
|
||
- модерацию контента.
|
||
|
||
## Наша команда Numerum
|
||
|
||
Дувакин Андрей — фуллстак + DevOps
|
||
Лучевников Лев — фронтенд-разработчик
|
||
Филимонов Михаил — бэкенд-разработчик
|
||
|
||
## Технологический стек
|
||
* Backend: FastAPI (Python), SQLAlchemy 2.0, PostgreSQL, JWT-аутентификация
|
||
* Frontend: React + Vite + JavaScript + Ant Design + RTK Query
|
||
* Инфраструктура: Docker, Kubernetes (microk8s), Helm-чарт, cert-manager + Let’s Encrypt
|
||
|
||
## Развернутый дистрибутив
|
||
WEB: https://springboard.numerum.team
|
||
API: https://api.springboard.numerum.team (с автоматической Swagger-документацией)
|
||
Хранение файлов: PersistentVolume с hostPath
|
||
|
||
## Структура проекта
|
||
### API
|
||
Бэкенд построен на FastAPI с луковой архитектурой.
|
||
```
|
||
api/
|
||
├── app/
|
||
│ ├── application/ — репозитории
|
||
│ ├── controllers/ — FastAPI-роутеры
|
||
│ ├── infrastructure/ — бизнес-сервисы
|
||
│ ├── domain/
|
||
│ │ ├── models/ — SQLAlchemy-модели (ORM)
|
||
│ │ └── entities/ — Pydantic-схемы (DTO)
|
||
│ ├── database/ — сессии, Alembic-миграции
|
||
│ ├── core/ — константы, настройки
|
||
│ └── main.py, settings.py
|
||
├── k8s/helm/springboard-api — Helm-чарт для продакшена
|
||
└── req.txt
|
||
```
|
||
API спроектирован так, что добавление новых сущностей (например, сертификаты, тесты, группы) требует минимум изменений — достаточно добавить модель, репозиторий, сервис и роутер.
|
||
|
||
### WEB
|
||
Фронтенд реализован на React + Vite + JavaScript с использованием UI-библиотеки Ant Design и state-менеджмента через RTK Query.
|
||
```
|
||
web/
|
||
├── src/
|
||
│ ├── Api/ — RTK Query слайсы (vacanciesApi, applicantProfilesApi и др.)
|
||
│ ├── App/ — роутинг, PrivateRoute, AdminRoute
|
||
│ ├── Components/
|
||
│ │ ├── Pages/ — HomePage (карта + лента), CabinetPage (три роли), OpportunityPage и др.
|
||
│ │ └── Widgets/
|
||
│ ├── Redux/ — store + слайсы
|
||
│ ├── Core/ — константы, конфиги
|
||
│ └── Hooks/
|
||
├── k8s/helm/springboard-web — Helm-чарт
|
||
└── Dockerfile
|
||
```
|
||
|
||
## Система ролей
|
||
|
||
Права проверяются как на бэкенде (Depends), так и на фронтенде (PrivateRoute / AdminRoute).
|
||
|
||
### Куратор с привелегией администратора
|
||
- Полный доступ к модерации
|
||
- Верификация компаний
|
||
- Управление пользователями и ролями
|
||
- Просмотр всех возможностей и откликов
|
||
|
||
### Работодатель
|
||
- Создание и управление вакансиями, стажировками, менторскими программами и карьерными мероприятиями
|
||
- Просмотр откликов и изменение их статусов
|
||
- Редактирование профиля компании
|
||
|
||
### Соискатель
|
||
- Просмотр карты и ленты возможностей
|
||
- Отклики и добавление в «Избранное»
|
||
- Личный кабинет с резюме, навыками, образованием, опытом и контактами
|
||
- Нетворкинг (профессиональные контакты)
|
||
- Настройка приватности профиля
|
||
|
||
### Администратор
|
||
|
||
- Всё, что может преподаватель
|
||
- Управление пользователями (создание, редактирование, удаление, смена роли)
|
||
- Управление ролями и статусами
|
||
- Просмотр и редактирование всех курсов и их содержимого
|
||
- Доступ ко всем журналам успеваемости
|
||
|
||
|
||
## Развертывание проекта
|
||
|
||
### API
|
||
|
||
Бэкенд можно запустить тремя способами — от самого простого до полноценного production-деплоймента.
|
||
|
||
#### 1. Локальный запуск (без Docker)
|
||
|
||
```bash
|
||
# Клонируем репозиторий
|
||
git clone https://git.numerum.team/andrei/it-planet-springboard.git
|
||
cd it-planet-springboard/api
|
||
|
||
# Создаём виртуальное окружение и устанавливаем зависимости
|
||
python -m venv .venv
|
||
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||
pip install -r req.txt
|
||
|
||
# Создаём файл .env в корне api/
|
||
cp .env.example .env
|
||
# Редактируем .env — обязательно заполняем:
|
||
DB_DRIVER=postgresql+asyncpg
|
||
DB_HOST=localhost
|
||
DB_PORT=5432
|
||
DB_USER=postgres
|
||
DB_PASSWORD=your_password
|
||
DB_NAME=springboard
|
||
DB_SCHEMA=public
|
||
SECRET_KEY=your_very_strong_secret_key_here
|
||
|
||
# Применяем миграции
|
||
alembic upgrade head
|
||
|
||
# Запускаем сервер
|
||
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
|
||
```
|
||
API: http://localhost:8000
|
||
|
||
#### 2. Запуск через Docker
|
||
|
||
Обратите внимание, что для хранения файлов необходимо создавать хранилище.
|
||
**Вариант A — просто тянуть готовый образ**
|
||
```bash
|
||
docker run -d \
|
||
--name springboard-api \
|
||
-p 8000:8000 \
|
||
-e DB_DRIVER=postgresql+asyncpg \
|
||
-e DB_HOST=host.docker.internal \
|
||
-e DB_PORT=5432 \
|
||
-e DB_USER=postgres \
|
||
-e DB_PASSWORD=your_password \
|
||
-e DB_NAME=springboard \
|
||
-e DB_SCHEMA=public \
|
||
-e SECRET_KEY=supersecretkey123 \
|
||
-v ./uploads:/app/uploads \
|
||
andreiduvakin/springboard-api:latest
|
||
```
|
||
|
||
**Вариант B — собрать локально**
|
||
Запускается из папки api:
|
||
```bash
|
||
docker build -t springboard-api . -а app/Dockerfile
|
||
docker run -d --name springboard-api -p 8000:8000 springboard-api
|
||
```
|
||
|
||
#### 3. Production-развёртывание в Kubernetes
|
||
Используется Helm-чарт **k8s/helm/springboard-api**.
|
||
```bash
|
||
# Устанавливаем чарт (пример для нашего microk8s)
|
||
helm upgrade --install springboard-api k8s/helm/springboard-api --namespace springboard-api --create-namespace
|
||
```
|
||
Что нужно настроить в **values.yaml**:
|
||
```
|
||
env:
|
||
DB_DRIVER: postgresql+asyncpg
|
||
DB_HOST: db.numerum.team
|
||
DB_PORT: 30000
|
||
DB_USER: springboard
|
||
DB_NAME: springboard
|
||
DB_SCHEMA: public
|
||
```
|
||
|
||
**Secret** с чувствительными данными:
|
||
```
|
||
# k8s/helm/springboard-api/templates/secrets.yaml
|
||
apiVersion: v1
|
||
kind: Secret
|
||
metadata:
|
||
name: springboard-api-secret
|
||
type: Opaque
|
||
data:
|
||
SECRET_KEY: base64_encoded_very_long_key==
|
||
DB_PASSWORD: base64_encoded_password==
|
||
```
|
||
|
||
**ОБРАТИТЕ ВНИМАНИЕ**
|
||
В настоящем решении не предоставлен действительный файл **k8s/helm/springboard-api/templates/secrets.yaml** - для предотвращения несанкционированного доступа к нашей базе данных. Для ВАШЕЙ конфигурации нужно создавать свой файл.
|
||
|
||
PersistentVolume автоматически создаётся через pvc.yaml и монтирует папку /mnt/k8s_storage/springboard-api/uploads на хосте — все загруженные студентами файлы сохраняются между перезапусками.
|
||
После деплоя:
|
||
|
||
API: https://api.springboard.numerum.team/
|
||
Swagger/ReDoc: https://api.springboard.numerum.team/docs
|
||
|
||
Именно так система работает в продакшене прямо сейчас — с HTTPS, Let’s Encrypt, персистентным хранилищем и автоматическим масштабированием.
|
||
|
||
### WEB
|
||
|
||
Фронтенд можно запустить тремя способами — от локальной разработки до production-развёртывания в Kubernetes.
|
||
|
||
### 1. Локальный запуск
|
||
|
||
```bash
|
||
git clone https://git.numerum.team/andrei/it-planet-springboard.git
|
||
cd it-planet-springboard/web
|
||
|
||
# Устанавливаем зависимости
|
||
npm install
|
||
|
||
# Создаём .env файл (в корне web/)
|
||
echo "VITE_BASE_URL=http://localhost:8000/api/v1" > .env
|
||
|
||
# Запускаем dev-сервер
|
||
npm run dev
|
||
```
|
||
Приложение будет доступно по адресу: http://localhost:5173
|
||
|
||
### 2. Запуск через Docker
|
||
Запускается из папки web:
|
||
**Вариант A — готовый образ**
|
||
Готовый образ уже собран с продакшен-настройками!
|
||
**VITE_BASE_URL** жёстко зашиты в образ на этапе сборки:
|
||
```Dockerfile
|
||
ENV VITE_BASE_URL=https://api.springboard.numerum.team/api/v1
|
||
ENV VITE_ROOT_ROLE_NAME=root
|
||
```
|
||
Поэтому запуск предельно прост:
|
||
```bash
|
||
docker run -d \
|
||
--name springboard-web \
|
||
-p 3000:3000 \
|
||
andreiduvakin/springboard-web:latest
|
||
```
|
||
|
||
**Вариант B — сборка локально**
|
||
```bash
|
||
docker run -d \
|
||
--name springboard-web \
|
||
-p 3000:3000 \
|
||
--build-arg VITE_BASE_URL=http://localhost:8000/api/v1 \
|
||
andreiduvakin/springboard-web:latest
|
||
```
|
||
Приложение доступно по адресу: http://localhost:3000
|
||
|
||
### 3. Production-развёртывание в Kubernetes
|
||
|
||
Используется Helm-чарт k8s/helm/springboard-web.
|
||
|
||
```bash
|
||
helm upgrade --install springboard-web k8s/helm/springboard-web --namespace springboard-web --create-namespace
|
||
```
|
||
|
||
Поскольку переменные окружения уже зашиты в образ на этапе **npm run build**, в **values.yaml** ничего передавать не нужно.
|
||
|
||
После деплоя приложение доступно по адресу:
|
||
https://springboard.numerum.team
|
||
Именно так работает продакшен прямо сейчас.
|
||
|
||
|
||
## Демонстрация
|
||
|
||
Видео ДЕМОНСТРАЦИИ проекта достпуно по ссылке: https://vkvideo.ru/video-237166148_456239017
|
||
|
||
Пожалуйста, досмотрите видео целиком.
|
||
|
||
## Регистрация
|
||
|
||
В системе можно зарегистрироваться перейдя на страницу регистрации из страницы входа. |