uxname revised this gist 3 days ago. Go to revision
1 file changed, 94 insertions
Testovoe.md(file created)
| @@ -0,0 +1,94 @@ | |||
| 1 | + | Чтобы тестовое задание не отпугнуло сильных кандидатов, оно должно отвечать трем правилам: | |
| 2 | + | 1. **Быть реалистичным** (отражать ваши реальные задачи). | |
| 3 | + | 2. **Иметь границы** (не требовать написания бэкенда, занимать 4–6 часов). | |
| 4 | + | 3. **Оставлять место для архитектурных решений** (чтобы вы увидели, как кандидат думает). | |
| 5 | + | ||
| 6 | + | Ниже представлен готовый текст тестового задания, который вы можете отправлять кандидатам. Он охватывает 100% вашего стека. | |
| 7 | + | ||
| 8 | + | --- | |
| 9 | + | ||
| 10 | + | # Тестовое задание: «Real-time Дашборд Заявок» (Frontend) | |
| 11 | + | ||
| 12 | + | **Привет!** | |
| 13 | + | Спасибо за интерес к нашей команде. Чтобы мы могли оценить твои навыки работы с нашим техническим стеком (React, TS, TanStack экосистема, WebSockets), мы подготовили небольшое практическое задание. | |
| 14 | + | ||
| 15 | + | Мы ценим твое время, поэтому **не ждем от тебя написания бэкенда**. Всю серверную часть (API и WebSockets) достаточно замокать на клиенте (через `setTimeout` / `setInterval` или библиотеку вроде `msw`). | |
| 16 | + | ||
| 17 | + | **Ожидаемое время выполнения:** 4–6 часов. | |
| 18 | + | **Главный критерий:** Качество архитектуры, типизации и чистота кода важнее, чем 100% реализованного функционала «на костылях». | |
| 19 | + | ||
| 20 | + | --- | |
| 21 | + | ||
| 22 | + | ### 📝 Легенда | |
| 23 | + | Тебе нужно разработать мини-SPA для оператора технической поддержки — **Дашборд управления заявками (Tickets)**. | |
| 24 | + | ||
| 25 | + | ### 🛠 Технический стек (Обязательно) | |
| 26 | + | * **Сборка:** Vite | |
| 27 | + | * **Фреймворк:** React 18+ | |
| 28 | + | * **Типизация:** Strict TypeScript | |
| 29 | + | * **Роутинг:** TanStack Router (File-based routing) | |
| 30 | + | * **Данные:** TanStack Query (React Query) | |
| 31 | + | * **Стейт:** Zustand | |
| 32 | + | * **UI/Формы:** React Hook Form + Zod, CSS Modules / SCSS (или Mantine, если удобно) | |
| 33 | + | * **Таблицы:** `mantine-react-table` (или аналог, если с Mantine не работал) | |
| 34 | + | ||
| 35 | + | --- | |
| 36 | + | ||
| 37 | + | ### 🚀 Задачи | |
| 38 | + | ||
| 39 | + | #### 1. Роутинг (TanStack Router) | |
| 40 | + | Настрой Type-safe роутинг для двух страниц: | |
| 41 | + | * `/` — Страница со списком заявок (Таблица). | |
| 42 | + | * `/tickets/new` — Страница создания новой заявки (Форма). | |
| 43 | + | ||
| 44 | + | #### 2. Таблица заявок (TanStack Query + Mantine React Table) | |
| 45 | + | На главной странице отобрази таблицу заявок. | |
| 46 | + | * **Поля:** `id`, `title`, `status` (Open, In Progress, Resolved), `createdAt`, `priority` (Low, Medium, High). | |
| 47 | + | * **Функционал:** Реализуй **Infinite Scroll** (бесконечную подгрузку) или серверную пагинацию, используя `useInfiniteQuery` / `useQuery`. | |
| 48 | + | * Сделай имитацию задержки ответа сервера (500ms), чтобы показать состояния загрузки (скелетоны или спиннеры). | |
| 49 | + | ||
| 50 | + | #### 3. Real-time обновления (WebSockets / STOMP) | |
| 51 | + | * Напиши мок (фальшивый) WebSocket-клиент, который раз в 10–15 секунд присылает событие: *«Статус заявки [ID] изменен на [Новый статус]»*. | |
| 52 | + | * **Главная задача:** При получении этого события обнови данные в кэше **TanStack Query** точечно (без полного рефетча всего списка), чтобы статус в таблице изменился в реальном времени. | |
| 53 | + | ||
| 54 | + | #### 4. Глобальный стейт (Zustand) | |
| 55 | + | * Реализуй систему уведомлений (Toasts). | |
| 56 | + | * Когда по WebSocket приходит изменение статуса, показывай всплывающее уведомление (через Zustand-стор) в углу экрана. | |
| 57 | + | ||
| 58 | + | #### 5. Форма создания (React Hook Form + Zod) | |
| 59 | + | На странице `/tickets/new` создай форму добавления заявки: | |
| 60 | + | * Поля: Название (строка, мин 5 символов), Описание (текст), Приоритет (селект). | |
| 61 | + | * Настрой строгую валидацию через **Zod**. | |
| 62 | + | * При успешном сабмите: используй `useMutation` (имитация отправки на сервер), инвалидируй кэш списка заявок и сделай редирект на главную страницу (`/`). | |
| 63 | + | ||
| 64 | + | --- | |
| 65 | + | ||
| 66 | + | ### 🌟 Будет плюсом (Nice to have) | |
| 67 | + | *Если у тебя останется время и желание выделиться:* | |
| 68 | + | 1. Добавь клиентскую или "серверную" (мокированную) фильтрацию по статусу заявки в URL (через Search Params TanStack Router'а). | |
| 69 | + | 2. Напиши 1-2 Unit-теста (Vitest) на утилитарную функцию или хук. | |
| 70 | + | 3. Напиши простейший E2E тест (Playwright) на прохождение флоу «Заполнение и отправка формы». | |
| 71 | + | ||
| 72 | + | --- | |
| 73 | + | ||
| 74 | + | ### 📦 Что мы будем оценивать (Критерии приемки) | |
| 75 | + | 1. **Type Safety:** Отсутствие `any`, грамотное использование Generics для ответов "API" и типизация роутов. | |
| 76 | + | 2. **Оптимизация:** Как ты работаешь с рендерами таблицы при поступлении WS-сообщений (не тормозит ли интерфейс). | |
| 77 | + | 3. **Архитектура:** Разделение логики (UI отдельно, работа с API отдельно, WS-клиент вынесен логично). | |
| 78 | + | 4. **Качество работы с TanStack Query:** Правильное использование `queryKey`, мутаций и инвалидации кэша. | |
| 79 | + | ||
| 80 | + | ### 📥 Формат сдачи | |
| 81 | + | * Код выложить на GitHub/GitLab (публичный или приватный репозиторий — во втором случае дай нам доступы). | |
| 82 | + | * В `README.md` укажи команду для запуска (`npm run dev`) и кратко опиши принятые архитектурные решения (почему сделал так, а не иначе). | |
| 83 | + | * Если задеплоишь на Vercel/Netlify — это будет супер! | |
| 84 | + | ||
| 85 | + | Удачи! Если возникнут вопросы по логике задания — смело пиши, мы на связи. | |
| 86 | + | ||
| 87 | + | --- | |
| 88 | + | ||
| 89 | + | ### 💡 Рекомендации для вас (нанимающего): | |
| 90 | + | **Как проверять это задание, когда кандидат его пришлет:** | |
| 91 | + | 1. **Смотрите на `package.json`:** Использовал ли он ровно то, что просили? | |
| 92 | + | 2. **Смотрите на папку `types` или `interfaces`:** Если там каша или `any`, кандидат не знает TypeScript. | |
| 93 | + | 3. **Проверьте интеграцию WS + React Query:** Слабый кандидат при получении события по сокету вызовет `queryClient.invalidateQueries()` (это вызовет лишний запрос на сервер). Сильный кандидат сделает `queryClient.setQueryData()` (точечно обновит кэш). Это маркер Senior-разработчика. | |
| 94 | + | 4. **Роутер:** Проверьте, использует ли он генерацию типов TanStack Router, или пишет роуты руками как в старом React Router. | |
Newer
Older