Javis OS
Javis OS is an Agentic AI that assists entrepreneurs in business tasks, helping them grow their work.
AI translation
Свежие вакансии из Telegram-каналов, SuperJob, «Работы России» и от прямых работодателей: IT, digital и другие профессии. Сопроводительное письмо под каждую вакансию пишет ИИ.
Translation pending
BusinessTypeScript · PythonGitHub @dan1la1337OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗AI-биржа вакансий. Вакансии собираются из Telegram-каналов и нормализуются нейросетью. Кандидат откликается в один клик с сопроводительным письмом, которое пишет ИИ под конкретную вакансию. Работодатели публикуют вакансии напрямую и разбирают отклики в своём кабинете.
| Часть | Где | Что делает |
|---|---|---|
| Сайт | src/ | Next.js 16 + Tailwind. Лента с фильтрами, Smart Apply, кабинеты кандидата и работодателя |
| API писем | src/app/api/cover-letter | Генерирует сопроводительное через Gemini. Только для вошедших, с лимитом запросов |
| Сборщик | main.py | Раз в 6 часов (GitHub Actions) забирает новые посты из каналов таблицы channels, нормализует их через Gemini и сохраняет вакансии со ссылкой на оригинал |
| База | supabase/migrations/ | Таблицы, триггеры и правила доступа (RLS) для Supabase, по миграциям |
Роли. Роль (candidate или employer) выбирается при регистрации и потом не меняется: это гарантирует триггер в базе. Работодатель попадает в /employer, кандидат — на главную и в /applications.
.env.example в .env.local и заполните ключи.supabase/migrations/
(по возрастанию имени). Базовую миграцию безопасно запускать повторно.npm install
npm run dev
Сайт откроется на http://localhost:3000.pip install -r requirements.txt
python main.py
Каналы для парсинга добавляются в таблицу channels (username, is_active = true).
Тесты сборщика (без сети): python -m pytest -q tests.psql; база fastcv_test пересоздаётся):
FASTCV_DB_TESTS=1 PGHOST=localhost PGUSER=postgres PGPASSWORD=postgres python -m pytest -v tests/db
В CI они идут на каждый PR вместе с тестами сборщика и сборкой сайта.
Lighthouse (скорость и доступность fastcv.ru на мобильном) запускается после каждого
выката в продакшн; баллы приходят комментарием к коммиту.Каждое изменение схемы — новый файл supabase/migrations/<ГГГГММДДччммсс>_<что_меняем>.sql.
Файлы применяются по возрастанию имени; уже применённые не правятся.
supabase db push) или SQL Editor, тем же содержимым файла.npm run db:types).Миграции, изменяющие данные, пишите так, чтобы повторный запуск ничего не ломал
(create ... if not exists, create or replace, проверки в do $$ ... $$).
Новая таблица — сразу с grant. Supabase больше не выдаёт права на новые таблицы
автоматически: без явного grant select, insert, … to authenticated правила RLS ничего
не открывают, и запросы молча возвращают ошибку. Тест «у каждого правила RLS есть права
на таблицу для его роли» ловит это до слияния.
Типы таблиц для TypeScript лежат в src/lib/database.types.ts и генерируются из схемы.
После новой миграции обновите их (нужен Supabase CLI
и supabase login):
npm run db:types
Клиенты Supabase типизированы этими типами: опечатка в имени колонки или неверный тип
значения ловится на npx tsc --noEmit и в CI.
last_post_id. Сборщик берёт посты новее него и, если с прошлого запуска вышло больше страницы, листает историю назад (до 5 страниц, около 100 постов). Новый канал начинается с 10 последних постов.source_post = канал/id), поэтому отредактированный пост не создаёт вторую запись. Одинаковый текст в разных каналах отсекается по хешу.stack). Модели перебираются по очереди (gemini-3.1-flash-lite → gemini-3.5-flash-lite → gemini-3.6-flash, переопределяется переменной GEMINI_MODELS): если одна перегружена (503), упёрлась в лимит (429) или снята с поддержки (404), запрос уходит в следующую. Таймаут запроса — 60 секунд. Если не ответила ни одна, канал останавливается на этом посте и продолжит с него в следующий запуск; после трёх таких каналов подряд остальные откладываются целиком.archived_at и пропадают из ленты. Данные не удаляются. Вакансии прямых работодателей не архивируются.failed_runs, а причина пишется в last_error. Список таких каналов выводится в конце лога.Ботов два, у каждого свой токен:
| Бот | Токен | Для чего |
|---|---|---|
| Оповещения | TELEGRAM_BOT_TOKEN + TELEGRAM_CHAT_ID (секреты GitHub) | сбои сборщика и утренняя сводка — только владельцу |
| Подборки | TELEGRAM_JOBS_BOT_TOKEN (Vercel, Production + секрет GitHub) | кандидатам: привязка чата и новые подходящие вакансии |
Бот подборок отвечает сразу: Telegram присылает сообщения на /api/telegram/webhook
(подпись — заголовок X-Telegram-Bot-Api-Secret-Token). Webhook и имя бота для ссылки в
профилях настраивает кнопка «Подключить бота подборок» в /admin; после смены токена её
нужно нажать снова. Подборки рассылает сборщик после каждого запуска.
Перед показом демо-аккаунты возвращаются в исходное состояние одной кнопкой: Actions → Demo Reset → Run workflow
(или python demo_reset.py с переменными SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, DEMO_CANDIDATE_EMAIL, DEMO_EMPLOYER_EMAIL).
Сбрасываются отклики, письма, отметки и лимиты ИИ демо-кандидата; профиль кандидата очищается (кроме имени — на показе
его заполняет ИИ по резюме), три вакансии демо-работодателя создаются заново (функция reset_demo). Аккаунты заводятся обычной регистрацией на сайте, их адреса — в переменных
репозитория DEMO_CANDIDATE_EMAIL и DEMO_EMPLOYER_EMAIL.
| База Supabase | Сайт | |
|---|---|---|
| Рабочее | First_DB (wyanvkaoqxgceaxzlqvk) | fastcv.ru — ветка main |
| Тестовое (staging) | fastcv-staging (zcyccnlweanhcsumplbx) | превью Vercel для каждого PR |
Превью и локальная разработка (vercel env pull) ходят в тестовую базу: регистрация,
отклики и эксперименты на превью не трогают рабочие данные. Миграции сначала
применяются к тестовой базе, потом к рабочей.
NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY и GEMINI_API_KEY в Environment Variables. В NEXT_PUBLIC_SUPABASE_ANON_KEY — только публичный ключ (sb_publishable_… или anon): всё с префиксом NEXT_PUBLIC_ попадает в браузер. С секретным ключом сборка остановится. Переменные NEXT_PUBLIC_* вшиваются при сборке, поэтому после их изменения нужен редеплой.NEXT_PUBLIC_SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY и GEMINI_API_KEY.https://<ваш-домен>/auth/callback в Redirect URLs, чтобы работала ссылка подтверждения почты.