Компетенции и подход к разработке
Ниже — стек, с которым идёт работа, и инженерные практики, которые к нему прилагаются: как проверяется доступность, как закрываются типовые уязвимости и чем подтверждается, что изменение не сломало остальное.
Архитектура и стек
Фронтенд
- Нативные HTML, CSS и JavaScript без фреймворка и без этапа сборки — когда задача это позволяет, такой выбор даёт быструю первую отрисовку и минимум промежуточного кода.
- PWA: web app manifest, набор иконок, установка на домашний экран, запуск в полноэкранном режиме.
- Векторная SVG-графика; анимация через Web Animations API с пружинной физикой и прерываемыми переходами.
- Web Speech API — голосовой ввод вместо набора текста.
- Системные настройки как первый класс: prefers-color-scheme, prefers-reduced-motion.
- Плавная типографика на clamp() — один набор токенов от узкого экрана до широкого, без разрыва на брейкпоинте.
Данные и состояние
- Local-first: хранение в localStorage, работа без аккаунта и без обращения к серверу.
- Запись в хранилище обёрнута обработкой ошибок — переполнение квоты даёт сообщение, а не падение.
- Повреждённое состояние сбрасывается при старте, чтобы приложение не зависало на битых данных.
Бэкенд
- Python: FastAPI + Uvicorn, REST-эндпоинты, pydantic-валидация входа.
- Серверный прокси к языковой модели: ключ существует только на сервере, фронтенд его не видит.
- Кеширование повторяющейся части промпта, ограничение частоты запросов, режим мока для тестирования без обращения к модели.
- Таймауты и мягкая деградация: при недоступности сервиса интерфейс остаётся рабочим, функция просто закрывается с понятным сообщением.
Интеграция LLM
- Anthropic Claude API: проектирование системного промпта под заданный голос и формат ответа.
- Отбор и усечение полей в payload — на модель уходит минимум необходимого, а не весь объём данных.
- Явное согласие пользователя до первой отправки, кеш последнего результата.
Инфраструктура
- nginx как reverse proxy, сервисы под systemd, HTTPS с Let's Encrypt, редирект HTTP → HTTPS.
- Настройка CORS по собственному origin, деплой статики одной командой.
Смежное
- Expo / React Native + Skia + Reanimated — нативный прототип с кастомной графикой и анимацией.
- Supabase: схема, клиент, план миграции с локального хранения.
- Генерация аудио через TTS-пайплайн с фолбэком на синтез речи устройства.
Доступность и безопасность
- Контраст измеряется, а не оценивается на глаз. Расчёт по всем парам «текст — фон» скриптом, отдельные пороги для обычного и крупного текста, обе темы. Ориентир — WCAG AA.
- Тёмная тема — это задача типографики, а не инверсия цветов. Нужна компенсация начертания и веса, иначе текст в темноте читается хуже при формально том же контрасте.
- Тема-независимые токены для текста на цветной подложке. Типовой баг: белый текст на цветном фоне, где в тёмной теме «белый» токен инвертируется в тёмный — получается тёмное на тёмном. Лечится фиксированным значением, а не переменной темы.
- prefers-reduced-motion останавливает анимации, когда настройка включена в системе.
- Экранирование пользовательского текста единой функцией — закрывает класс stored-XSS. Разрозненные локальные хелперы сводятся к одному, иначе новый вывод рано или поздно уйдёт в разметку без обработки.
- Секреты только на серверной стороне. Ключи и токены не попадают в код фронтенда ни в каком виде.
- Критичные контуры не отключаются пользовательскими настройками — если экран отвечает за безопасность человека, он имеет приоритет над любыми тумблерами.
Контроль качества
- Каждое изменение проверяется вживую на мобильной ширине экрана, с контролем консоли браузера. Результат проверки фиксируется письменно — что именно прогнано и чем.
- Измерения вместо впечатлений. Контраст считается скриптом, кегли замеряются в браузере. «Кажется читаемо» не является результатом проверки.
- git diff как доказательство. Для хирургических правок проверяется, что диапазон изменений совпадает с заявленным — например, что заход по типографике не задел ни строки логики.
- Массовые правки по коду — скриптами с assert на число изменённых мест, а не руками. Так расхождение между «собирался изменить 12 мест» и «изменил 11» видно сразу.
- Контент сверяется с эталонным документом построчно — при сверке большого набора текстов находятся расхождения, которые на глаз не видны.
- Поведение проверяется на разных объёмах данных. Аналитика, корректная на сотне записей, по одной записи выдаёт выводы, которых данные не подтверждают, — поэтому раскрытие делается ступенчатым и проверяется на каждой ступени.
- Независимые аудиты: устойчивость к неожиданному поведению пользователя, доступность, типографика. С письменной фиксацией находок, severity и принятого решения по каждой.
- Находки, которые решено не исправлять, выписываются с причиной и готовым решением. Так отложенное остаётся управляемым, а не превращается в неизвестный долг.
- Именованные точки отката перед каждым крупным изменением — возврат к последнему рабочему состоянию занимает минуту.
Пример реализации
PWA-дневник эмоций. Mental health, 2026, в работе.
- Задача. Приложение для ведения дневника чувств: человек фиксирует состояние между сессиями со специалистом, специалист видит только то, что человек сам отметил к передаче.
- Фронтенд. Single-page приложение на нативном стеке, без фреймворка и без этапа сборки. Данные на устройстве, аккаунт не требуется. Голосовой ввод, озвученные практики, SVG-персонажи с пружинной анимацией.
- Серверная часть. FastAPI-прокси готовит обобщённый разбор записей за период через Claude. Ключ только на сервере, запросы через nginx по HTTPS, CORS по собственному origin, ограничение частоты, режим мока.
- Доступность. Телефоны экстренной помощи были набраны декоративным курсивом с контрастом 2,75 в тёмной теме — провал по WCAG. Переведены на прямой моноширинный шрифт с табличными цифрами и максимальным контрастом: читаются в остром состоянии и в любой теме. Остальной safety-контур пересобран тем же заходом, 16 правок, без единого изменения в логике.
- Качество данных. Выводы по дневнику раскрываются ступенчато по объёму записей — на малом объёме приложение честно сообщает, что картина ещё собирается, вместо обобщений.
- Доменная экспертиза. Формулировки онбординга, дисклеймеров и кризисных экранов вычитаны профильными специалистами: 17 замечаний, 16 внесено в тот же цикл.
- Статус. В проде на HTTPS, сервис разбора на том же домене.
Частые вопросы
Можно ли сделать веб-приложение без фреймворка?
Да, и для многих задач это правильный выбор: нет этапа сборки, нет зависимостей, которые ломаются при обновлении, первая отрисовка быстрее. Ограничение в другом — такой код нужно держать дисциплинированно, потому что ни типы, ни линтер по умолчанию не подстрахуют. На практике это компенсируется письменной фиксацией проверок и именованными точками отката.
Где хранить API-ключ, чтобы он не утёк во фронтенд?
Только на сервере. Фронтенд обращается к собственному эндпоинту, а серверный прокси уже подставляет ключ из переменных окружения и вызывает внешний API. Ключ в коде страницы, в сборке или в переменной с префиксом публичного окружения — это ключ, который уже утёк.
Что PWA даёт по сравнению с обычным сайтом?
Установку на домашний экран и запуск в полноэкранном режиме без магазина приложений: манифест, набор иконок и корректный режим отображения. Для пользователя приложение выглядит нативным, для разработки остаётся одной кодовой базой.
Достаточно ли проверить контраст текста на глаз?
Нет. Контраст — это числовое отношение яркостей, и на цветных подложках интуиция систематически ошибается. Проверка считается скриптом по всем парам «текст — фон», в светлой и тёмной темах, с отдельным порогом для крупного текста. Иначе провал обнаруживается уже у пользователя.
Почему тёмная тема — это не просто инверсия цветов?
При одинаковом формальном контрасте светлый текст на тёмном фоне выглядит тоньше и «расплывается». Нужна компенсация начертания и веса, а токены для текста на цветной подложке должны быть фиксированными — иначе «белый» при смене темы инвертируется в тёмный и текст пропадает на цветном фоне.
Расскажите о задаче
Ответим в течение одного рабочего дня, оценку пришлём за 1–2 дня. Бесплатно.