Operator Card
src/features/operator_card/ — спільна Stack-картка оператора або кандидата, яку відкривають із рекрутингової воронки та списків команд.
Суть
Operator Card об’єднує персональні, облікові, рекрутингові й робочі дані Stack-користувача з роллю operator. Це глобальна картка користувача: її маршрут не містить Family, а Family-зв’язок редагується всередині секції Cooperation.
Не плутати з My profile самого оператора: /operator/my_profile має окрему реалізацію і використовує з цього feature лише Referral link. Власний профіль описаний у my-profile.
Use cases
- Director створює або редагує кандидата з
Operators applicants, а також відкриває картку оператора зі структури Teamleads. - HR manager створює та редагує кандидатів і відкриває картки операторів у доступних командах.
- Recruiter працює з поточним кандидатом; після появи hiring history картка переходить у захищений від редагування режим.
- Top manager переглядає картку оператора зі своєї структури команд і оновлює лише дозволену частину даних.
- Supervisor відкриває картку оператора зі вкладки
Operatorsі працює з обмеженим набором полів.
Доступ і маршрути
| Роль | Create | Existing card | Режим |
|---|---|---|---|
director | /ceo/operator_card/create | /ceo/operator_card/:id | повний |
hr | /hr/operator_card/create | /hr/operator_card/:id | повний |
recruiter | /recruiter/operator_card/create | /recruiter/operator_card/:id | залежить від hiring history |
topManager | — | /top_manager/operator_card/:id | обмежений |
supervisor | — | /teamlead/operator_card/:id | обмежений |
Роль operator не відкриває цей екран для себе. Її сторінка — /operator/my_profile.
Режими
Create
Create mode визначається значенням create замість :id.
- Запит на отримання картки не виконується.
- У форму додається порожнє поле Surname.
- Якщо картку створює HR manager, він одразу встановлюється як hiring HR.
- Основна кнопка має текст
CREATE. - Telegram bot, system log і дії над наявним password не показуються.
Existing card
Картка завантажує основні дані користувача. Для всіх ролей, крім supervisor, паралельно запитується Academy progress. Помилка Academy показується окремо і не блокує основну картку.
Recruiter hiring history
Якщо у картки є hiringAt, recruiter бачить історичний read-only режим:
- немає
UPDATE; - приховані Social media, System log та Achievements;
- Login details не показуються;
- основні hiring-поля та DeepL API key не редагуються;
- Telegram і Phone не показуються;
- додавання та видалення persisted comments недоступне.
Секції й доступ
| Секція | Повний режим | Top manager | Supervisor | Recruiter hiring history |
|---|---|---|---|---|
| General info | редагування | read-only | read-only | частковий read-only |
| Passport / Documents | редагування | приховано | приховано | приховано |
| Login details | редагування | email read-only | email read-only | приховано |
| Referral link | copy, якщо код існує | copy | copy | copy |
| Translator | API key редагується | API key редагується | API key редагується | read-only |
| Notifications Telegram bot | для existing card | для existing card | для existing card | для existing card |
| Payment Details | Director | read-only | read-only | приховано |
| Social media | редагування | приховано | приховано | приховано |
| Comments | редагування | редагування | без видалення persisted comments | read-only |
| System log | existing card | приховано | приховано | приховано |
| Hiring | Director / HR / Recruiter | приховано | приховано | read-only |
| Cooperation | Director / HR / Recruiter | значення read-only, status змінюється окремо | приховано | обмежено |
| Training | якщо Academy повернула дані | якщо Academy повернула дані | не завантажується | якщо Academy повернула дані |
| Achievements | редагування | перегляд | перегляд | приховано |
Повний режим використовують Director і HR manager. Recruiter без hiringAt також отримує editable card, але nickname, Hiring assignment, password actions і server access для нього недоступні.
General info і валідація
- Surname є обов’язковим лише тоді, коли поле присутнє в моделі картки. Create mode додає це поле, тому нову картку без Surname створити не можна.
- Name у поточній frontend-валідації не є обов’язковим.
- Непорожній Email має бути валідним, але порожній Email не блокує save.
- Змінений Nickname проходить перевірку формату; незмінене legacy-значення допускається.
- Якщо Date of birth задана, дата має бути валідною, а оператору має бути щонайменше 18 років.
- Telegram нормалізується до одного початкового
@. - Country обирається з searchable country list.
Ця валідація запускається також перед обмеженим UPDATE Top manager або Supervisor. Некоректне read-only значення може заблокувати збереження DeepL/comments.
Login details
Для existing card доступні копіювання email password і генерація нового Stack password. Password mutation виконується одразу та синхронізує поточний і початковий стани картки.
Server access:
- Director перемикає
Production / Development; - Top manager бачить поточне значення без можливості змінити;
- іншим ролям поле не показується.
Hiring
Hiring показує Source, HR manager, Recruiter, Stack status і дату найму.
- Після появи
hiringAtсекція стає read-only. - У create mode HR manager не може змінити самого себе як hiring HR.
- Recruiter selector активується лише після вибору HR.
- Зміна HR очищає раніше вибраного recruiter.
- Recruiter не редагує HR/Recruiter assignment навіть до появи hiring history.
Cooperation
Секція показує Project, TeamLead, HR manager, Stack status і, крім recruiter, суму bonuses.
- Зміна Project очищає поточного TeamLead.
- TeamLead list завантажується в контексті вибраної Family та ролі користувача.
- HR manager у своїй картці може вибрати лише
Freeабо себе; Director отримує список активних HR managers. - Recruiter може змінювати Project і TeamLead лише для status
NewабоIn progressі лише до появи hiring history. - Recruiter не змінює HR або Stack status.
- Director, HR manager і Top manager можуть блокувати або розблоковувати existing operator; блокування потребує confirmation.
Comments і медіа
Comments редагуються локально й потрапляють в основний save. Нові вкладення завантажуються після успішного створення або оновлення основних даних.
- Comment створюється лише з непорожнім після trim текстом.
- Максимальний розмір одного comment attachment — 20 MB.
- Тип і кількість comment attachments окремо не обмежуються.
- Supervisor не видаляє persisted comment, але може видалити щойно доданий локальний comment.
- Recruiter hiring history не додає і не видаляє comments.
Passport, Documents і кожне Achievement приймають не більше трьох existing + pending файлів:
- Passport і Achievements — JPEG/JPG/PNG;
- Documents — JPEG/JPG/PNG, TXT, PDF або MP4.
Медіа має локальний preview до save. Видалення existing file залишається локальною зміною до загального UPDATE.
Achievements
Картка містить StartBox, AirPods, iPhone, MacBook. Установка achievement потребує confirmation; після фіксації givenAt checkbox стає disabled.
Top manager і Supervisor бачать achievements без checkbox і upload action. Поточний UI все ще показує delete-кнопку біля вкладень, але їхній обмежений payload не зберігає зміни Achievements. Це фактична розбіжність, а не окреме право.
Save і незбережені зміни
- Director, HR manager і recruiter без hiring history надсилають повні дані картки.
- Top manager і Supervisor надсилають лише DeepL API key та Comments.
- Основна картка зберігається першою; після неї окремо завантажуються pending media.
- System log не враховується у визначенні unsaved changes.
Returnіз незбереженими змінами потребує confirmation.- Після успішного save поточний і початковий стани синхронізуються.
Loading та помилки
- Initial load, save, password/status/access mutations і selector requests використовують global loader.
- Помилка основного load показує global notification і повертає на попередній route.
- Помилка Academy progress не закриває картку.
- Окремого page-level error або empty state немає.
- Backend message показується без зміни; за його відсутності використовується frontend fallback.
Нюанси
- Назви
hrManagerDate,operator applicantта route-група/recruit/operatorCard/*є legacy/backend boundaries; UI-екран після найму залишається Operator Card. - User-facing Family name має бути
Chathouse, хоча в одному selector поточний код рендеритьChatsHouse. - Fallback помилки upload без backend message зараз не всюди має кінцеву крапку; це не слід копіювати в новий UI-текст.
Зв’язки
- operators-applicants — create/edit кандидата.
- operators — перехід із команди Supervisor.
- teamleads — перехід зі структури команд Director, HR manager і Top manager.
- my-profile — окрема сторінка власного профілю.
- media-renderer — preview та fullscreen медіа.
- swagger — реєстр backend Swagger UI.
- API route constants:
src/utils/hrManagerDate.ts,src/utils/usersData.js,src/utils/directorData.js,src/utils/recruiterData.js,src/utils/academyData.js. - TODO: додати перевірені operation deeplink-и для Operator Card, password/status/access, recruiter/HR selectors та Academy progress.