Late Workers
Веб-платформа, где задачи бизнеса собраны в каталог с рейтингом готовности 0–100 и уровнем.
О проекте
Команда: late workers
Кейс HackAlem.ai: Образование — AI Sana
Стадия: Рабочий MVP
Задача кейса: Challenge Hub: превратить задачу бизнеса в задание для студенческих команд
Суть
Веб-платформа, где задачи бизнеса собраны в каталог с рейтингом готовности 0–100 и уровнем. Студенты фильтруют и сохраняют задачи, бизнес видит «Мои задачи» с черновиками.
Как устроено
FastAPI + PostgreSQL (SQLAlchemy async, Alembic) хранят пользователей с ролями, задачи с карточкой из 9 полей, отрасли и сохранённые задачи. Уровень готовности вычисляется кодом из рейтинга (0–39/40–69/70–89/90–100). В коммитах есть конструктор карточки с AI-операциями на OpenAI Responses API и offline fallback, а также миграции для команд, предложений, этапов и бейджей; по README AI-чат доступен только как API-эндпоинт с SSE. Redis ограничивает частоту запросов к AI.
Ключевые решения
- rule-based readiness levels
- JWT HttpOnly cookie auth
- role guards
- Redis rate limiting
- SSE streaming
- Alembic migrations
- Playwright e2e
Особенности
README подробно разделяет реализованное и отсутствующее: команды студентов по README не реализованы, хотя в коммитах есть миграции teams/proposals и конструктор карточки с AI. Трёхъязычный интерфейс (ru/kk/en), приложена презентация pptx.
Стек
Python 3.12 · FastAPI · SQLAlchemy 2 · asyncpg · Alembic · PostgreSQL 16 · Redis 7 · React 19 · React Router 7 · Vite 8 · Tailwind CSS 4 · TanStack Query · Zustand · i18next · Docker Compose · uv
Модели
OpenAI gpt-5.5
Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-f8263889-late-workers.
README
README.md1. Late Workers — каталог бизнес-задач для студенческих команд
Презентация проекта: Late Workers.pptx
2. Краткое описание
Малому и среднему бизнесу нужны исполнители для прикладных задач, а студентам — реальные задачи для практики. Проект — веб-платформа, где задачи бизнеса собраны в общий каталог с рейтингом готовности 0–100 и уровнем, а студенты просматривают каталог, фильтруют его и сохраняют интересные задачи. Текущая версия реализует регистрацию по ролям, каталог, страницу задачи, «Интересное» студента и «Мои задачи» бизнеса.
3. Что реализовано
Бизнес
- Регистрация: email, пароль, название компании, контактное лицо, телефон. Вход, выход, восстановление сессии после перезагрузки страницы.
- Раздел «Мои задачи» (
/business): таблица всех задач компании во всех статусах, включая черновики, с рейтингом, уровнем, числом откликов и датой изменения. Из таблицы открывается страница задачи. - Просмотр своих черновиков: задача в статусе «Черновик» видна только владельцу, для остальных — 404.
- Просмотр общего каталога.
Студент
- Регистрация: email, пароль, имя, навыки и технологии (теги). Вход, выход, восстановление сессии.
- Каталог (
/catalog): опубликованные задачи и задачи в работе, по 20 на страницу.- Сортировка по рейтингу, дате публикации, числу откликов.
- Фильтры по отрасли (10 отраслей) и уровню готовности, можно выбрать несколько значений.
- Сортировка, фильтры и страница хранятся в адресе, ссылку можно скопировать.
- Страница задачи (
/catalog/:id): название, компания, отрасль, статус, рейтинг, уровень, число откликов, дата публикации и 9 полей карточки: контекст, потребность, пользователи, данные и материалы, ограничения, ожидаемый результат, критерии успеха, контакт, формат взаимодействия. - Кнопка «В интересное» и раздел «Интересное» (
/student) со списком сохранённых задач.
Команда
Команды студентов в коде не реализованы: нет сущности команды, капитана, участников и откликов. См. раздел 10.
Общее
- Доступ по ролям: гость перенаправляется на вход, пользователь другой роли — в свой раздел. На сервере роль проверяется по записи в БД (401 без входа, 403 при чужой роли).
- Интерфейс на русском, казахском и английском, светлая и тёмная темы.
- Уровень готовности вычисляется кодом из рейтинга: 0–39 «Требует уточнения», 40–69 «Рабочая», 70–89 «Готовая», 90–100 «Приоритетная» (
backend/app/core/catalog.py). - AI-чат через OpenAI доступен только как API-эндпоинт (
/api/v1/ai/chat), без экрана в интерфейсе. См. раздел 6.
4. Как работает решение
flowchart LR
A[Регистрация или вход] --> B{Роль}
B -- бизнес --> C["Мои задачи: все задачи компании"]
B -- студент --> D["Каталог: сортировка и фильтры"]
C --> E[Страница задачи]
D --> E
E -- студент --> F["В интересное"]
F --> G["Раздел Интересное"]
- Пользователь регистрируется как бизнес или студент. Сервер создаёт аккаунт и профиль, ставит HttpOnly-cookie с JWT.
- Бизнес попадает в «Мои задачи», студент — в каталог.
- Каталог запрашивает
GET /api/tasksс параметрамиsort,industry,level,page. Сервер показывает только задачи в статусах «Опубликована» и «В работе» и для каждой карточки добавляет уровень по рейтингу. - Страница задачи загружает полную карточку через
GET /api/tasks/{id}. - Студент сохраняет задачу (
POST /api/tasks/{id}/save) и видит её в «Интересном» (GET /api/me/saved-tasks).
Задачи, их рейтинги и число откликов сейчас попадают в БД только из демо-данных (seed): интерфейса и API для создания задач нет.
5. Технологии
| Слой | Технология | Где подтверждается |
|---|---|---|
| Язык бэкенда | Python 3.12 | backend/.python-version, backend/pyproject.toml |
| Веб-фреймворк | FastAPI, Uvicorn | backend/pyproject.toml |
| ORM и миграции | SQLAlchemy 2 (async), asyncpg, Alembic | backend/pyproject.toml, backend/alembic/versions/ |
| Валидация и настройки | Pydantic 2, pydantic-settings | backend/app/core/config.py |
| Аутентификация | PyJWT (HS256), pwdlib (argon2, bcrypt), HttpOnly-cookie | backend/app/core/security.py |
| База данных | PostgreSQL 16 | docker-compose.yml (postgres:16-alpine) |
| Кеш и лимиты | Redis 7 (необязателен, лимит запросов к AI) | docker-compose.yml, backend/app/api/rate_limit.py |
| AI API | OpenAI Responses API, SDK openai | backend/app/services/ai.py |
| AI-модель | gpt-5.5 по умолчанию, меняется переменной OPENAI_MODEL | backend/app/core/config.py |
| Язык фронтенда | TypeScript | frontend/package.json |
| UI | React 19, React Router 7, Tailwind CSS 4, lucide-react | frontend/package.json |
| Сборка | Vite 8 | frontend/vite.config.ts |
| Данные и формы | TanStack Query, Zustand, Axios, React Hook Form, Zod | frontend/package.json |
| Локализация | i18next (ru, kk, en) | frontend/public/locales/ |
| Тесты | pytest, pytest-asyncio, httpx (бэкенд); Playwright (фронтенд) | backend/tests/, frontend/e2e/ |
| Линтеры | Ruff; ESLint, Prettier, tsc | backend/pyproject.toml, frontend/package.json |
| Инфраструктура | Docker, Docker Compose, Make, uv, Yarn 1 | docker-compose.yml, Makefile, frontend/yarn.lock |
6. Архитектура
flowchart LR
U[Браузер] --> W["Frontend: React + Vite, :5173"]
W -- "прокси /api, cookie" --> A["Backend: FastAPI, :8000"]
A --> P[(PostgreSQL)]
A -. "лимит запросов к AI, необязателен" .-> R[(Redis)]
A -. "только /api/v1/ai/*" .-> O[OpenAI Responses API]
- Фронтенд обращается к относительному пути
/api; dev-сервер Vite проксирует его на FastAPI (API_PROXY_TARGET), поэтому cookie работает без CORS-настроек в браузере. - Бэкенд разделён на роутеры (
app/api), сервисы (app/services), модели (app/models) и схемы (app/schemas). Миграции Alembic применяются при старте API, еслиAUTO_MIGRATE=true. - Таблицы:
users,businesses,students,industries(справочник заполняется миграцией),tasks,saved_tasks, а такжеnotesиз шаблона проекта. - Redis используется только для ограничения числа запросов к AI-эндпоинтам (фиксированное окно, по умолчанию 20 в минуту на пользователя). Без
REDIS_URLограничение отключается. GET /healthсообщает состояние API, базы данных и Redis.
Эндпоинты
| Метод и путь | Доступ | Назначение |
|---|---|---|
POST /api/auth/register/business | гость | Регистрация бизнеса |
POST /api/auth/register/student | гость | Регистрация студента |
POST /api/auth/login, POST /api/auth/logout, GET /api/auth/me | — | Вход, выход, текущий пользователь |
GET /api/industries | вошедший | Справочник отраслей |
GET /api/tasks | вошедший | Каталог: sort, industry, level, page |
GET /api/tasks/{id} | вошедший | Страница задачи |
POST, DELETE /api/tasks/{id}/save | студент | Добавить в «Интересное» или убрать |
GET /api/me/saved-tasks | студент | «Интересное» |
GET /api/business/tasks | бизнес | «Мои задачи» |
POST /api/v1/ai/chat, POST /api/v1/ai/chat/stream | вошедший | AI-чат, ответ целиком или SSE-поток |
/api/v1/auth/login, /api/v1/users/me, /api/v1/notes | — | Шаблонные эндпоинты, в интерфейсе не используются |
GET /health | все | Проверка состояния |
Полная схема: http://localhost:8000/docs.
AI-модуль
Модуль backend/app/services/ai.py — универсальный чат поверх OpenAI Responses API.
- Операции:
chat(ответ целиком) иchat_stream(Server-Sent Events:delta, затемdoneилиerror). Обе читают один потоковый ответ OpenAI. - Промпт: системный промпт из
AI_SYSTEM_PROMPT(по умолчанию общий промпт ассистента) или полеsystemиз запроса. Предметных промптов для задач нет. - Ошибки OpenAI (неверный ключ, лимит, недоступность, отказ модели) переводятся в единый JSON-формат ошибок API.
- Лимит запросов — через Redis, см. выше.
Структурированных ответов (Structured Outputs), проверки фактов по источникам, резервного режима без OpenAI, кеша ответов и журнала вызовов в коде нет. Без OPENAI_API_KEY AI-эндпоинты возвращают ошибку; остальные функции платформы от OpenAI не зависят.
7. Установка и запуск
Требования
| Инструмент | Версия | Источник |
|---|---|---|
| Python | 3.12+ | backend/.python-version, requires-python |
| uv | любая актуальная | backend/Makefile |
| Node.js | 22.12+ | frontend/Dockerfile (node:22), frontend/README.md |
| Yarn | 1.x (1.22) | frontend/yarn.lock, frontend/Dockerfile |
| Docker с Compose v2 | — | docker-compose.yml |
| make | — | Makefile |
Клонирование
git clone [email protected]:BAITC-Hacks/hack-f8263889-late-workers.git
cd hack-f8263889-late-workers
Вариант А. Весь стек в Docker
Файл backend/.env необязателен; без него AI-эндпоинты не работают, остальное работает.
make env
make docker-up
Поднимаются PostgreSQL, Redis, API и фронтенд; миграции применяются при старте API. Демо-данные загружаются во втором терминале (команда удаляет все существующие аккаунты и их данные):
docker compose exec api python -m app.seed
Остановка: make docker-down, остановка с удалением базы: make docker-reset.
Вариант Б. Локальный запуск
- Установить зависимости и создать
backend/.envиfrontend/.envиз примеров:
make setup
- Запустить PostgreSQL (порт
5439) и Redis в Docker:
make infra
- Применить миграции (они также применяются автоматически при старте API):
make -C backend migrate
- Загрузить демо-данные. Команда удаляет все существующие аккаунты и связанные данные:
make -C backend seed
- Запустить API и фронтенд вместе:
make dev
По отдельности: make backend и make frontend.
Адреса
| Что | Адрес |
|---|---|
| Веб-приложение | http://localhost:5173 |
| API и Swagger | http://localhost:8000/docs |
| Проверка состояния | http://localhost:8000/health |
| PostgreSQL для внешних клиентов | localhost:5439, база app, пользователь и пароль postgres (только для локальной разработки) |
Переменные окружения бэкенда (backend/.env)
| Переменная | Пример в .env.example | Назначение |
|---|---|---|
ENV | dev | dev, test или prod. При prod обязателен свой SECRET_KEY, cookie получает Secure, seed отказывается запускаться |
DEBUG | true | Режим отладки |
LOG_LEVEL | INFO | Уровень логирования |
CORS_ORIGINS | http://localhost:3000,... | Разрешённые источники через запятую |
DATABASE_URL | postgresql+asyncpg://...@localhost:5439/app | Подключение к PostgreSQL |
TEST_DATABASE_URL | ...@localhost:5439/app_test | База для тестов |
AUTO_MIGRATE | true | Применять миграции при старте API |
REDIS_URL | закомментирована | Redis для лимита запросов к AI; пусто — лимит выключен |
AI_RATE_LIMIT_PER_MINUTE | 20 | Лимит запросов к AI на пользователя в минуту |
SECRET_KEY | заглушка | Ключ подписи JWT, сгенерировать: openssl rand -hex 32 |
ACCESS_TOKEN_EXPIRE_MINUTES | 10080 | Срок жизни токена и cookie (7 дней) |
AUTH_COOKIE_SAMESITE | Lax | Lax, Strict или None |
OPENAI_API_KEY | пусто | Ключ OpenAI, нужен только для AI-эндпоинтов |
OPENAI_BASE_URL | закомментирована | Прокси или совместимый с OpenAI адрес |
OPENAI_MODEL | gpt-5.5 | Модель OpenAI |
OPENAI_MAX_OUTPUT_TOKENS | 4096 | Лимит токенов ответа |
OPENAI_REASONING_EFFORT | закомментирована | Уровень рассуждений модели; пусто — по умолчанию провайдера |
AI_SYSTEM_PROMPT | общий промпт ассистента | Системный промпт AI-чата по умолчанию |
Переменные окружения фронтенда (frontend/.env)
| Переменная | Пример в .env.example | Назначение |
|---|---|---|
AUTH_MOCKS | false | true — моки авторизации и каталога в dev-сервере Vite, без бэкенда |
API_PROXY_TARGET | http://127.0.0.1:8000 | Куда Vite проксирует /api |
VITE_APP_ENV | development | Метка окружения: development, staging, production |
Тесты и проверки
Тесты бэкенда (нужен запущенный make infra; тестовая база app_test создаётся автоматически):
make test
Линтеры и проверка типов обоих приложений:
make lint
Сборка фронтенда:
cd frontend && yarn build
Браузерные тесты фронтенда (работают на моках, Chromium устанавливается один раз):
cd frontend && npx playwright install chromium && yarn test:e2e
8. Как проверить решение
Перед проверкой выполните установку из раздела 7 вместе с seed. Пароль всех демо-аккаунтов — [скрыто].
| Роль | Пароль | |
|---|---|---|
| Бизнес, Кофейня «Зерно» | [email protected] | demo2026 |
| Бизнес, Караван Логистика | [email скрыт] | demo2026 |
| Бизнес, Медцентр «Саулык» | [email скрыт] | demo2026 |
| Студент, Арман Сейтказы | [email скрыт] | demo2026 |
Остальные студенты из seed: aisha@, daniyar@, madina@, timur@, [email скрыт], пароль тот же.
- Откройте http://localhost:5173. Гость попадает на страницу входа.
- Войдите как
[email protected]. Откроется «Мои задачи» с тремя задачами: «Программа лояльности для постоянных гостей» (92, «Приоритетная»), «Прогноз спроса на выпечку» (78, «Готовая») и черновик «Чат-бот для брони столиков» (0, «Требует уточнения»). - Откройте черновик. Страница задачи доступна владельцу; заполнено только поле «потребность», остальные помечены «Не указано».
- Перейдите в «Каталог». В нём 6 задач трёх компаний; черновика нет. По умолчанию сортировка по рейтингу, первой идёт задача с рейтингом 92.
- Смените сортировку на «по откликам» и выберите фильтр уровня «Готовая»: останутся задачи с рейтингом 70–89 (78 и 70). Параметры видны в адресной строке.
- Выйдите и войдите как
[email скрыт]. Откроется каталог. - Откройте любую задачу и нажмите «В интересное». Надпись кнопки сменится на «В интересном». Та же кнопка есть на карточках каталога.
- Перейдите в «Интересное»: там сохранённая задача. Нажмите «В интересном» на её карточке, чтобы убрать её из сохранённых.
- Переключите язык (RU, KK, EN) и тему в верхней панели.
- Необязательно: откройте http://localhost:8000/docs и проверьте эндпоинты. Для AI-чата нужен
OPENAI_API_KEYвbackend/.env.
9. Данные и интеграции
Синтетические данные
Команда seed (backend/app/seed.py) удаляет всех пользователей со связанными данными и загружает JSON-файлы из backend/seed/:
| Файл | Объём | Содержание |
|---|---|---|
businesses.json | 3 | Кофейня «Зерно», Караван Логистика, Медцентр «Саулык» |
students.json | 6 | Имена, навыки и технологии |
tasks.json | 7 | 5 опубликованных, 1 в работе, 1 черновик; рейтинги от 0 до 92, число откликов от 0 до 6 |
Справочник из 10 отраслей создаётся миграцией. Все даты в seed фиксированы, повторный запуск даёт те же данные. При ENV=prod seed не запускается.
Для работы фронтенда без бэкенда (AUTH_MOCKS=true) есть отдельный набор моков в frontend/dev/: 26 задач и другие пароли ([скрыто] / coffee2026, [email скрыт] / arman2026), см. frontend/README.md.
Внешние API
Единственный внешний API — OpenAI. В него отправляются только данные из тела запроса к /api/v1/ai/chat и /api/v1/ai/chat/stream: сообщения диалога, системный промпт и параметры модели. Сервис AI не читает базу данных, поэтому аккаунты, профили, контакты бизнеса и задачи в OpenAI не передаются.
10. Ограничения
Из замысла не реализовано:
- Конструктор задачи: ввод черновика, уточняющие вопросы AI, сборка карточки AI, редактирование и публикация. Создать или изменить задачу через интерфейс или API нельзя; задачи появляются только из seed.
- Расчёт рейтинга по 7 блокам с весами, оценка качества блоков AI, расшифровка рейтинга и подсказки. Рейтинг хранится готовым числом из seed; код вычисляет из него только уровень.
- Предметные AI-операции (анализ, сборка карточки, оценка блоков), Structured Outputs, проверка источников
D*/A*, резервный режим без OpenAI, кеш ответов AI в Redis, журнал вызововai_calls. - Команды студентов (капитан, участники до 5 человек), отклики на задачи, правка и отзыв откликов, «Мои отклики». Поле «число откликов» заполняется только из seed.
- Выбор и отклонение откликов бизнесом, этапы и баллы команд, рекомендации задач, прогресс-бар, бейджи, индикатор отклика рынка.
- Поиск по тексту в каталоге.
Известные ограничения текущей версии:
- AI-чат доступен только через API и не работает без
OPENAI_API_KEY. - Нет восстановления пароля, подтверждения email и редактирования профиля.
seedудаляет всех пользователей базы.- Выход не отзывает JWT на сервере: токен действует до истечения срока, cookie удаляется.
- В репозитории остались шаблонные модули (заметки, AI-чат, список пользователей) без маршрутов в интерфейсе.
- Docker-конфигурация рассчитана на разработку (dev-сервер Vite,
--reload); production-сборки и конфигурации деплоя нет.
11. Deployed-версия
Ссылка на развёрнутую версию будет добавлена.
Авторы коммитов
История коммитов
- 2026-09-23 17:50refactor(auth): remove unused BrandLogo import from AuthFormShellsdklover1-800
- 2026-09-23 17:46chore: merge taskbridge branding into mainsolo
- 2026-09-23 17:46feat(frontend): add taskbridge brandingsolo
- 2026-09-23 17:44docs: add pitch deck and link it from readmesdklover1-800
- 2026-09-23 17:20Merge pull request #16 from BAITC-Hacks/frontendRahim Arman
- 2026-09-23 17:19Merge remote-tracking branch 'origin/frontend' into frontendArman Rakhim
- 2026-09-23 17:17feat(frontend): add business proposal selection and milestonesArman Rakhim
- 2026-09-23 17:15feat(frontend): add readiness badges and market feedbacksolo
Все коммиты (71)
- 2026-09-23 16:58Merge pull request #15 from BAITC-Hacks/backendsdklover
- 2026-09-23 16:57Merge pull request #14 from BAITC-Hacks/mainsdklover
- 2026-09-23 16:56Merge pull request #13 from BAITC-Hacks/backendsdklover
- 2026-09-23 16:55test(gamification): cover badges, views, market and the demo seedsdklover1-800
- 2026-09-23 16:50feat(seed): demo gamification datasdklover1-800
- 2026-09-23 16:48Merge pull request #12 from BAITC-Hacks/frontendRahim Arman
- 2026-09-23 16:48Merge remote-tracking branch 'origin/main' into frontendArman Rakhim
- 2026-09-23 16:47feat(market): record student views and expose the market indicatorsdklover1-800
- 2026-09-23 16:47Merge remote-tracking branch 'origin/frontend' into frontendArman Rakhim
- 2026-09-23 16:45feat(badges): award badges from the confirmed card and filter the cataloguesdklover1-800
- 2026-09-23 16:43feat(frontend): add student teams, proposals and profile pagesArman Rakhim
- 2026-09-23 16:42chore: merge frontend into mainsolo
- 2026-09-23 16:38feat(frontend): add business task buildersolo
- 2026-09-23 16:37Merge pull request #11 from BAITC-Hacks/backendsdklover
- 2026-09-23 16:35test(selection): cover selection, milestones and the seeded demosdklover1-800
- 2026-09-23 16:31feat(selection): let a business decide on proposals and confirm milestonessdklover1-800
- 2026-09-23 16:24Merge pull request #10 from BAITC-Hacks/mainsdklover
- 2026-09-23 16:23Merge pull request #9 from BAITC-Hacks/backendsdklover
- 2026-09-23 16:19docs(backend): document teams, proposals and the response countersdklover1-800
- 2026-09-23 16:19feat(teams): extend the seed and cover teams and proposals with testssdklover1-800
- 2026-09-23 16:17Merge pull request #8 from BAITC-Hacks/readmeRahim Arman
- 2026-09-23 16:16docs: readmeArman Rakhim
- 2026-09-23 16:13feat(teams): add teams, membership and proposalssdklover1-800
- 2026-09-23 16:06Merge pull request #7 from BAITC-Hacks/frontendsdklover
- 2026-09-23 16:05docs(frontend): describe the real-API acceptance runAsset Zhansharipov
- 2026-09-23 16:05test(frontend): run catalog acceptance against the real APIAsset Zhansharipov
- 2026-09-23 16:05fix(frontend): explain an empty catalog page past the endAsset Zhansharipov
- 2026-09-23 16:01Merge pull request #6 from BAITC-Hacks/mainsdklover
- 2026-09-23 15:58Merge pull request #5 from BAITC-Hacks/backendsdklover
- 2026-09-23 15:58docs(backend): document the card builder and its AI layersdklover1-800
- 2026-09-23 15:57test(builder): cover the constructor and the AI clientsdklover1-800
- 2026-09-23 15:50feat(builder): add the card constructor endpoints and serializersdklover1-800
- 2026-09-23 15:46Merge pull request #4 from BAITC-Hacks/frontendRahim Arman
- 2026-09-23 15:43feat(ai): add prompts, the three AI operations and the offline fallbacksdklover1-800
- 2026-09-23 15:42feat(frontend): connect to real backend by defaultsolo
- 2026-09-23 15:38feat(ai): add block table, rating and the structured AI clientsdklover1-800
- 2026-09-23 15:36feat(ai): wire the OpenAI client and add card builder tablessdklover1-800
- 2026-09-23 15:19Merge pull request #3 from BAITC-Hacks/backendAsset Zhansharipov
- 2026-09-23 15:16test(catalog): cover the catalogue acceptance checklistsdklover1-800
- 2026-09-23 15:13Merge pull request #2 from BAITC-Hacks/frontendsdklover
- 2026-09-23 15:12feat(catalog): add catalogue, task page, saved tasks and business taskssdklover1-800
- 2026-09-23 15:11feat(frontend): add the student saved tasks pageAsset Zhansharipov
- 2026-09-23 15:11docs(frontend): document the catalog and check its translationsAsset Zhansharipov
- 2026-09-23 15:11feat(frontend): add task detail pageAsset Zhansharipov
- 2026-09-23 15:11feat(frontend): add business my tasks tableAsset Zhansharipov
- 2026-09-23 15:11feat(frontend): let students save tasks to their saved listAsset Zhansharipov
- 2026-09-23 15:11feat(frontend): add catalog routes and role section navigationAsset Zhansharipov
- 2026-09-23 15:11feat(frontend): add catalog task list with sorting and paginationAsset Zhansharipov
- 2026-09-23 15:11feat(frontend): add industry and level filters to the catalogAsset Zhansharipov
- 2026-09-23 15:11feat(frontend): add catalog contract types, api client and dev mockAsset Zhansharipov
- 2026-09-23 15:08feat(catalog): add task, industry and saved-task modelssdklover1-800
- 2026-09-23 14:58Merge pull request #1 from BAITC-Hacks/backendRahim Arman
- 2026-09-23 14:56feat(docs): update AGENTS.md and add frontend-auth-migration.md for role-based auth changes feat(tests): add tests for accounts model and auth registration endpoints feat(tests): implement tests for asdklover1-800
- 2026-09-23 14:52feat(tests): enhance test suite with student registration and validation testssdklover1-800
- 2026-09-23 14:46feat(auth): implement account registration and login endpoints with cookie-based authentication feat(deps): add role guard and support for cookie-based authentication refactor(users): update user retrsdklover1-800
- 2026-09-23 14:43feat(schemas): add account contracts and field validation rulessdklover1-800
- 2026-09-23 14:42feat(models): add user role and business/student profilessdklover1-800
- 2026-09-23 14:40feat(security): switch to bcrypt, add role claim and auth cookie helperssdklover1-800
- 2026-09-23 14:39refactor(errors)!: use SCREAMING_SNAKE codes and a fields mapsdklover1-800
- 2026-09-23 14:39build(backend): run postgres in docker for dev and testssdklover1-800
- 2026-09-23 14:33feat(frontend): add role-based cookie authenticationsolo
- 2026-09-23 13:43delete tests taskssdklover1-800
- 2026-09-23 13:20initArman Rakhim
Структура репозитория (445 файлов)
.gitignore AGENTS.md CLAUDE.md Late Workers.pptx Makefile README.md backend/.dockerignore backend/.env.example backend/.gitignore backend/.python-version backend/AGENTS.md backend/CLAUDE.md backend/Dockerfile backend/Makefile backend/README.md backend/alembic.ini backend/alembic/env.py backend/alembic/script.py.mako backend/alembic/versions/20260911_1022_17bf3cdf8fd8_initial.py backend/alembic/versions/20260923_1441_a22ff0986288_add_user_role_and_profiles.py backend/alembic/versions/20260923_1507_18fc904f124b_add_task_catalogue.py backend/alembic/versions/20260923_1535_f48093ef2675_add_card_builder.py backend/alembic/versions/20260923_1608_e03e652c01d0_add_teams_and_proposals.py backend/alembic/versions/20260923_1628_2ebe6405f1b3_add_milestones.py backend/alembic/versions/20260923_1644_50bbcf115e3a_add_badges_and_task_views.py backend/app/__init__.py backend/app/api/__init__.py backend/app/api/auth.py backend/app/api/builder.py backend/app/api/catalog.py backend/app/api/catalog_params.py backend/app/api/deps.py backend/app/api/rate_limit.py backend/app/api/router.py backend/app/api/selection.py backend/app/api/teams.py backend/app/api/v1/__init__.py backend/app/api/v1/ai.py backend/app/api/v1/auth.py backend/app/api/v1/health.py backend/app/api/v1/notes.py backend/app/api/v1/users.py backend/app/core/__init__.py backend/app/core/badges.py backend/app/core/blocks.py backend/app/core/catalog.py backend/app/core/config.py backend/app/core/exceptions.py backend/app/core/logging.py backend/app/core/messages.py backend/app/core/middleware.py backend/app/core/redis.py backend/app/core/security.py backend/app/core/validation.py backend/app/db/__init__.py backend/app/db/base.py backend/app/db/migrations.py backend/app/db/session.py backend/app/main.py backend/app/models/__init__.py backend/app/models/ai_call.py backend/app/models/business.py backend/app/models/clarification.py backend/app/models/industry.py backend/app/models/milestone.py backend/app/models/note.py backend/app/models/proposal.py backend/app/models/saved_task.py backend/app/models/student.py backend/app/models/task.py backend/app/models/task_view.py backend/app/models/team.py backend/app/models/user.py backend/app/schemas/__init__.py backend/app/schemas/account.py backend/app/schemas/ai.py backend/app/schemas/auth.py backend/app/schemas/base.py backend/app/schemas/builder.py backend/app/schemas/common.py backend/app/schemas/note.py backend/app/schemas/proposal.py backend/app/schemas/selection.py backend/app/schemas/task.py backend/app/schemas/team.py backend/app/schemas/user.py backend/app/seed.py backend/app/services/__init__.py backend/app/services/accounts.py backend/app/services/ai.py backend/app/services/ai_client.py backend/app/services/auth.py backend/app/services/builder.py backend/app/services/builder_ai.py backend/app/services/fallback.py backend/app/services/market.py backend/app/services/notes.py backend/app/services/prompts.py backend/app/services/proposals.py backend/app/services/rating.py backend/app/services/tasks.py backend/app/services/teams.py backend/app/services/users.py backend/docker-compose.yml backend/docs/frontend-auth-migration.md backend/pyproject.toml backend/scripts/check_openai.py backend/seed/businesses.json backend/seed/engagement.json backend/seed/proposals.json backend/seed/students.json backend/seed/tasks.json backend/seed/teams.json backend/tests/__init__.py backend/tests/conftest.py backend/tests/fakes.py backend/tests/test_accounts_model.py backend/tests/test_ai.py backend/tests/test_ai_client.py backend/tests/test_auth.py backend/tests/test_auth_register.py backend/tests/test_auth_session.py backend/tests/test_badges_api.py backend/tests/test_badges_unit.py backend/tests/test_blocks.py backend/tests/test_builder.py backend/tests/test_business_tasks.py backend/tests/test_catalog.py backend/tests/test_catalog_units.py backend/tests/test_health.py backend/tests/test_industries.py backend/tests/test_market.py backend/tests/test_migrations.py backend/tests/test_milestones.py backend/tests/test_notes.py backend/tests/test_proposals.py backend/tests/test_rate_limit.py backend/tests/test_rating.py backend/tests/test_saved_tasks.py backend/tests/test_seed.py backend/tests/test_selection.py backend/tests/test_student_profile.py backend/tests/test_task_page.py backend/tests/test_task_views.py backend/tests/test_teams.py backend/tests/test_teams_model.py backend/tests/test_validation.py backend/uv.lock docker-compose.yml frontend/.dockerignore frontend/.env.example frontend/.flowbite-react/.gitignore frontend/.flowbite-react/config.json frontend/.flowbite-react/init.tsx frontend/.gitignore frontend/.husky/pre-commit frontend/.prettierignore frontend/.prettierrc frontend/AGENTS.md frontend/CLAUDE.md frontend/Dockerfile frontend/README.md frontend/components.json frontend/dev/authMock.ts frontend/dev/catalogData.ts frontend/dev/catalogMock.ts frontend/dev/http.ts frontend/e2e/auth.spec.ts frontend/e2e/catalog.spec.ts frontend/e2e/helpers.ts frontend/e2e/presentation.spec.ts frontend/e2e/real/catalog.spec.ts frontend/e2e/real/global-setup.ts frontend/e2e/real/helpers.ts frontend/e2e/tags.spec.ts frontend/eslint.config.js frontend/index.html frontend/package.json frontend/playwright.config.ts frontend/playwright.real.config.ts frontend/public/locales/en/translation.json frontend/public/locales/kk/translation.json frontend/public/locales/ru/translation.json frontend/public/mockServiceWorker.js frontend/public/taskbridge-icon.svg frontend/public/vite.svg frontend/src/assets/react.svg frontend/src/common/components/BrandLogo.tsx frontend/src/common/components/TopBar.tsx frontend/src/common/components/layout/Footer.tsx frontend/src/common/components/layout/Page.tsx frontend/src/common/components/layout/Section.tsx frontend/src/common/components/layout/Stack.tsx frontend/src/common/components/layout/index.ts frontend/src/common/components/ui/badge.tsx frontend/src/common/components/ui/button.tsx frontend/src/common/components/ui/card.tsx frontend/src/common/components/ui/clamped-text.tsx frontend/src/common/components/ui/confirm-dialog.tsx frontend/src/common/components/ui/error-state.tsx frontend/src/common/components/ui/form-error.tsx frontend/src/common/components/ui/form-field.tsx frontend/src/common/components/ui/index.ts frontend/src/common/components/ui/pagination.tsx frontend/src/common/components/ui/pending-button.tsx frontend/src/common/components/ui/select.tsx frontend/src/common/components/ui/textarea-field.tsx frontend/src/common/components/ui/toaster.tsx frontend/src/common/components/ui/tooltip.tsx frontend/src/common/hooks/useTooltip.ts frontend/src/common/lib/forms.ts frontend/src/common/lib/query.ts frontend/src/common/lib/toast.ts frontend/src/common/lib/tooltip.ts frontend/src/common/lib/useIsClamped.ts frontend/src/common/lib/useModalDialog.ts frontend/src/common/lib/utils.ts frontend/src/common/styles/classes.ts frontend/src/common/styles/index.ts frontend/src/core/App.tsx frontend/src/core/ErrorBoundary.tsx frontend/src/core/api/client.ts frontend/src/core/api/dates.ts frontend/src/core/api/errors.ts frontend/src/core/api/index.ts frontend/src/core/api/session.ts frontend/src/core/api/sse.ts frontend/src/core/api/types.ts frontend/src/core/env.ts frontend/src/core/i18n.ts frontend/src/core/index.css frontend/src/core/main.tsx frontend/src/core/query/QueryProvider.tsx frontend/src/core/query/index.ts frontend/src/core/query/queryClient.ts frontend/src/core/router/appRoutes.tsx frontend/src/mocks/browser.ts frontend/src/mocks/users.data.ts frontend/src/mocks/users.handlers.ts frontend/src/modules/ai/api/chat.ts frontend/src/modules/ai/components/ChatPanel.tsx frontend/src/modules/ai/hooks/useChat.ts frontend/src/modules/ai/hooks/useChatStream.ts frontend/src/modules/ai/index.ts frontend/src/modules/ai/pages/ChatPage.tsx frontend/src/modules/auth/api/auth.ts frontend/src/modules/auth/components/AuthBootstrap.tsx frontend/src/modules/auth/components/AuthForm.tsx frontend/src/modules/auth/components/AuthFormShell.tsx frontend/src/modules/auth/components/AuthSubmit.tsx frontend/src/modules/auth/components/GuestOnly.tsx frontend/src/modules/auth/components/RegistrationLinks.tsx frontend/src/modules/auth/components/RequireAuth.tsx frontend/src/modules/auth/components/TagsInput.tsx frontend/src/modules/auth/components/formHelpers.ts frontend/src/modules/auth/helpers.ts frontend/src/modules/auth/hooks/useAuthBootstrap.ts frontend/src/modules/auth/hooks/useBusinessRegisterForm.ts frontend/src/modules/auth/hooks/useLogin.ts frontend/src/modules/auth/hooks/useLoginForm.ts frontend/src/modules/auth/hooks/useLogout.ts frontend/src/modules/auth/hooks/useMe.ts frontend/src/modules/auth/hooks/useProfileForm.ts frontend/src/modules/auth/hooks/useRegister.ts frontend/src/modules/auth/hooks/useSessionMutation.ts frontend/src/modules/auth/hooks/useStudentRegisterForm.ts frontend/src/modules/auth/hooks/useTagsInput.ts frontend/src/modules/auth/hooks/useUpdateProfile.ts frontend/src/modules/auth/index.ts frontend/src/modules/auth/pages/BusinessRegisterPage.tsx frontend/src/modules/auth/pages/LoginPage.tsx frontend/src/modules/auth/pages/ProfilePage.tsx frontend/src/modules/auth/pages/RegisterPage.tsx frontend/src/modules/auth/pages/StudentRegisterPage.tsx frontend/src/modules/auth/queryKeys.ts frontend/src/modules/auth/sessionTransition.ts frontend/src/modules/auth/stores/useAuthStore.ts frontend/src/modules/auth/types.ts frontend/src/modules/auth/validation.ts frontend/src/modules/builder/api/builder.ts frontend/src/modules/builder/components/AssessmentPanel.tsx frontend/src/modules/builder/components/BuilderBadges.tsx frontend/src/modules/builder/components/BuilderContent.tsx frontend/src/modules/builder/components/BuilderSteps.tsx frontend/src/modules/builder/components/CardEditor.tsx frontend/src/modules/builder/components/CardFields.tsx frontend/src/modules/builder/components/DraftText.tsx frontend/src/modules/builder/components/Feedback.tsx frontend/src/modules/builder/components/Publication.tsx frontend/src/modules/builder/components/RatingHintList.tsx frontend/src/modules/builder/components/RatingPanel.tsx frontend/src/modules/builder/components/ReadinessProgress.tsx frontend/src/modules/builder/components/RoundForm.tsx frontend/src/modules/builder/helpers.ts frontend/src/modules/builder/hooks/useAnalyzeDraft.ts frontend/src/modules/builder/hooks/useAnswersForm.ts frontend/src/modules/builder/hooks/useBuilderTask.ts frontend/src/modules/builder/hooks/useCardDefaults.ts frontend/src/modules/builder/hooks/useCardEditor.ts frontend/src/modules/builder/hooks/useLeaveGuard.ts frontend/src/modules/builder/hooks/useNewTaskForm.ts frontend/src/modules/builder/hooks/useScrollToTop.ts frontend/src/modules/builder/hooks/useTaskCache.ts frontend/src/modules/builder/index.ts frontend/src/modules/builder/pages/BuilderPage.tsx frontend/src/modules/builder/pages/NewTaskPage.tsx frontend/src/modules/builder/queryKeys.ts frontend/src/modules/builder/types.ts frontend/src/modules/catalog/api/industries.ts frontend/src/modules/catalog/api/tasks.ts frontend/src/modules/catalog/components/BusinessTasksTable.tsx frontend/src/modules/catalog/components/CatalogFilters.tsx frontend/src/modules/catalog/components/FilterChip.tsx frontend/src/modules/catalog/components/SaveTaskButton.tsx frontend/src/modules/catalog/components/SortSelect.tsx frontend/src/modules/catalog/components/TaskBadges.tsx frontend/src/modules/catalog/components/TaskCard.tsx frontend/src/modules/catalog/components/TaskCardSkeletons.tsx frontend/src/modules/catalog/components/TaskFields.tsx frontend/src/modules/catalog/components/TaskPageSkeleton.tsx frontend/src/modules/catalog/helpers.ts frontend/src/modules/catalog/hooks/useBusinessTasks.ts frontend/src/modules/catalog/hooks/useCatalogSearch.ts frontend/src/modules/catalog/hooks/useIndustries.ts frontend/src/modules/catalog/hooks/useSavedTasks.ts frontend/src/modules/catalog/hooks/useTask.ts frontend/src/modules/catalog/hooks/useTasks.ts frontend/src/modules/catalog/hooks/useToggleSave.ts frontend/src/modules/catalog/index.ts frontend/src/modules/catalog/pages/BusinessTasksPage.tsx frontend/src/modules/catalog/pages/CatalogPage.tsx frontend/src/modules/catalog/pages/SavedTasksPage.tsx frontend/src/modules/catalog/pages/TaskPage.tsx frontend/src/modules/catalog/queryKeys.ts frontend/src/modules/catalog/types.ts frontend/src/modules/dashboard/index.ts frontend/src/modules/dashboard/pages/ContactFormPage.tsx frontend/src/modules/dashboard/pages/HomePage.tsx frontend/src/modules/dashboard/stores/useAppStore.ts frontend/src/modules/gamification/api/gamification.ts frontend/src/modules/gamification/components/EarnedBadges.tsx frontend/src/modules/gamification/components/MarketPanel.tsx frontend/src/modules/gamification/helpers.ts frontend/src/modules/gamification/hooks/useBadges.ts frontend/src/modules/gamification/hooks/useTaskMarket.ts frontend/src/modules/gamification/index.ts frontend/src/modules/gamification/queryKeys.ts frontend/src/modules/gamification/types.ts frontend/src/modules/notes/api/notes.ts frontend/src/modules/notes/components/NoteForm.tsx frontend/src/modules/notes/components/NoteList.tsx frontend/src/modules/notes/components/Pagination.tsx frontend/src/modules/notes/hooks/useCreateNote.ts frontend/src/modules/notes/hooks/useDeleteNote.ts frontend/src/modules/notes/hooks/useNote.ts frontend/src/modules/notes/hooks/useNotes.ts frontend/src/modules/notes/hooks/useUpdateNote.ts frontend/src/modules/notes/index.ts frontend/src/modules/notes/pages/NotesPage.tsx frontend/src/modules/notes/queryKeys.ts frontend/src/modules/proposals/api/proposals.ts frontend/src/modules/proposals/components/FormPageShell.tsx frontend/src/modules/proposals/components/MilestonesSummary.tsx frontend/src/modules/proposals/components/ProposalCard.tsx frontend/src/modules/proposals/components/ProposalCardSkeletons.tsx frontend/src/modules/proposals/components/ProposalForm.tsx frontend/src/modules/proposals/components/StatusBadge.tsx frontend/src/modules/proposals/components/TaskHeading.tsx frontend/src/modules/proposals/components/TaskProposalsBlock.tsx frontend/src/modules/proposals/helpers.ts frontend/src/modules/proposals/hooks/useProposalForm.ts frontend/src/modules/proposals/hooks/useProposalMutations.ts frontend/src/modules/proposals/hooks/useProposalQueries.ts frontend/src/modules/proposals/index.ts frontend/src/modules/proposals/pages/MyProposalsPage.tsx frontend/src/modules/proposals/pages/ProposalCreatePage.tsx frontend/src/modules/proposals/pages/ProposalEditPage.tsx frontend/src/modules/proposals/queryKeys.ts frontend/src/modules/proposals/types.ts frontend/src/modules/selection/api/selection.ts frontend/src/modules/selection/components/BusinessProposalCard.tsx frontend/src/modules/selection/components/CompareBar.tsx frontend/src/modules/selection/components/CompareDialog.tsx frontend/src/modules/selection/components/DecisionDialog.tsx frontend/src/modules/selection/components/MilestonesBlock.tsx frontend/src/modules/selection/components/ProposalTabs.tsx frontend/src/modules/selection/components/ProposalsHeader.tsx frontend/src/modules/selection/components/TeamRoster.tsx frontend/src/modules/selection/helpers.ts frontend/src/modules/selection/hooks/useDecisionFlow.ts frontend/src/modules/selection/hooks/useMilestones.ts frontend/src/modules/selection/hooks/useSelectionMutations.ts frontend/src/modules/selection/hooks/useTaskProposals.ts frontend/src/modules/selection/index.ts frontend/src/modules/selection/pages/BusinessProposalsPage.tsx frontend/src/modules/selection/queryKeys.ts frontend/src/modules/selection/types.ts frontend/src/modules/system/api/health.ts frontend/src/modules/system/components/ApiStatus.tsx frontend/src/modules/system/hooks/useHealth.ts frontend/src/modules/system/index.ts frontend/src/modules/system/queryKeys.ts frontend/src/modules/teams/api/teams.ts frontend/src/modules/teams/components/AddMemberForm.tsx frontend/src/modules/teams/components/MemberList.tsx frontend/src/modules/teams/components/RoleBadge.tsx frontend/src/modules/teams/components/Skeletons.tsx frontend/src/modules/teams/components/TagList.tsx frontend/src/modules/teams/components/TeamCard.tsx frontend/src/modules/teams/components/TeamForm.tsx frontend/src/modules/teams/helpers.ts frontend/src/modules/teams/hooks/useMyTeams.ts frontend/src/modules/teams/hooks/useTeam.ts frontend/src/modules/teams/hooks/useTeamForm.ts frontend/src/modules/teams/hooks/useTeamMutations.ts frontend/src/modules/teams/index.ts frontend/src/modules/teams/pages/TeamCreatePage.tsx frontend/src/modules/teams/pages/TeamPage.tsx frontend/src/modules/teams/pages/TeamsPage.tsx frontend/src/modules/teams/queryKeys.ts frontend/src/modules/teams/types.ts frontend/src/modules/theme/ThemeProvider.tsx frontend/src/modules/theme/components/ThemeToggle.tsx frontend/src/modules/theme/index.ts frontend/src/modules/theme/stores/useThemeStore.ts frontend/src/modules/users/api/users.ts frontend/src/modules/users/components/UsersPagination.tsx frontend/src/modules/users/components/UsersTable.tsx frontend/src/modules/users/components/UsersTableSkeleton.tsx frontend/src/modules/users/components/UsersToolbar.tsx frontend/src/modules/users/helpers.ts frontend/src/modules/users/hooks/useDebouncedValue.ts frontend/src/modules/users/hooks/useUsers.ts frontend/src/modules/users/hooks/useUsersQueryState.ts frontend/src/modules/users/index.ts frontend/src/modules/users/pages/UsersPage.tsx frontend/src/modules/users/queryKeys.ts frontend/tsconfig.app.json frontend/tsconfig.e2e.json frontend/tsconfig.json frontend/tsconfig.node.json frontend/vite.config.ts frontend/yarn.lock memory/README.md memory/log.md
Обсуждение 0 комментариев
Войдите, чтобы комментироватьПока нет комментариев — будьте первым.