Введение
Репозиторий Antosha122/test-oren-it — это реализация сервиса для анонимных обращений за психологической, юридической и конфликтологической помощью. Проект написан на Go и разворачивается через Docker Compose, поднимая два веб-интерфейса: публичный для заявителей и закрытый для сотрудников. В этой статье разберём, как устроена архитектура, какие технические решения применены и что делает проект интересным с инженерной точки зрения.
Что представляет собой проект
Сервис решает задачу безопасного и анонимного взаимодействия между человеком, которому нужна помощь, и специалистом (психологом, юристом, конфликтологом). Заявитель не регистрируется и не оставляет контактов — доступ к обращению осуществляется исключительно по трек-номеру. Сотрудники работают через отдельный порт и авторизуются по логину и паролю.
Приложение собирается в один бинарник на Go, внутри которого через go:embed вшит одностраничный веб-интерфейс без внешних зависимостей. База данных — PostgreSQL 16. Всё поднимается одной командой docker compose up -d --build.
Архитектура
Код организован по слоям, что упрощает навигацию и сопровождение:
cmd/server— точка входа.internal/config— конфигурация через переменные окружения.internal/db— подключение к БД, миграции и начальные данные (сиды).internal/domain— бизнес-логика: статусы обращений, генерация трек-номеров, эвристика выявления кризисных ситуаций.internal/store— все SQL-запросы.internal/httpapi— REST-обработчики, маршрутизация, аутентификация и проекции данных для каждой роли.
Такое разделение позволяет тестировать доменную логику отдельно от HTTP-слоя и хранилища.
Функциональность
Интерфейс заявителя (порт 8080)
Заявитель может:
- подать обращение, выбрав категорию или описав проблему свободно;
- ответить на уточняющие вопросы (необязательно);
- приложить до 5 файлов по 10 МБ с автоматическим удалением EXIF и геолокации;
- получить трек-номер формата
ОТК-X7KD-R9MF-Q3HP(12 значимых символов из алфавита без похожих букв и цифр); - войти по трек-номеру в чат, который обновляется автоматически (поллинг каждые 5 секунд);
- оценить результат: «помогло» или «не помогло» (в последнем случае обращение возвращается оператору).
Тон общения адаптируется под тип заявителя: со школьником — на «ты», с родителем или педагогом — на «вы».
Интерфейс сотрудников (порт 8081)
Роли и возможности:
- Оператор — видит очередь новых обращений, назначает эксперта (с подсказкой системы), меняет приоритет и категорию, отклоняет, завершает, закрывает без ответа, возвращает на доработку. Доступна аналитика только по своим действиям.
- Эксперт (психолог, юрист, конфликтолог) — работает только с назначенными ему обращениями: берёт в работу, задаёт уточняющие вопросы, готовит рекомендации, запрашивает передачу другому специалисту или подключает соисполнителей. Ведёт внутренние заметки, недоступные заявителю.
- Администратор — управляет пользователями, категориями, правилами маршрутизации, просматривает жалобы, выгружает CSV. Может менять статус, приоритет и исполнителя любого обращения, но обязан указать причину, и всё фиксируется в журнале. При этом админ не видит переписку и заметки и не может закрывать обращения.
API
Публичные эндпоинты включают проверку здоровья (/api/health), список категорий, уточняющие вопросы, создание обращения и вход по трек-номеру. Для сотрудников предусмотрены отдельные ветки: /api/operator/..., /api/expert/..., /api/admin/..., а также общие для всех сотрудников эндпоинты аналитики, экспорта и смены пароля.
Безопасность и приватность
Проект с самого начала проектировался с упором на анонимность:
- Заявитель не регистрируется и не оставляет контактов.
- Трек-номера и сессионные токены хранятся в базе только в виде SHA-256-хешей — при утечке БД восстановить доступ к обращениям невозможно.
- Пароли сотрудников хешируются через bcrypt.
- Каждая роль видит только необходимый минимум данных.
- Вложения обезличиваются: исходные имена файлов заменяются на
attachment.bin, тип проверяется по фактическому содержимому (whitelist MIME), при отдаче ставится заголовокX-Content-Type-Options: nosniff. - Действуют rate limit: создание обращений — не более 5 с одного IP в час, попытки входа по трек-номеру — 20 в час, логин сотрудников — 10 в минуту.
- Сессии живут 2 часа (настраивается через
SESSION_TTL_MIN).
На все ответы ставятся заголовки Content-Security-Policy, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy: no-referrer; при COOKIE_SECURE=1 добавляется Strict-Transport-Security.
Отдельно стоит отметить, что трек-номер выдаётся ровно один раз и не хранится в открытом виде. Если пользователь его потерял, обращение становится недоступным — это сознательная жертва ради анонимности.
Технологии
- Язык: Go.
- База данных: PostgreSQL 16.
- Контейнеризация: Docker, Docker Compose.
- Веб-интерфейс: встроен в бинарник через
go:embed, без внешних зависимостей. - Аутентификация: bcrypt для паролей, SHA-256 для трек-номеров и сессионных токенов.
- Обновление данных: поллинг каждые 5 секунд.
Запуск
Для запуска достаточно склонировать репозиторий, скопировать .env.example в .env и выполнить docker compose up -d --build. Через минуту поднимутся два контейнера: PostgreSQL и приложение на Go. Миграции и создание начальных данных (категории, тестовые пользователи) выполняются автоматически при первом запуске, если база пуста.
Проверить работоспособность можно командой curl http://localhost:8080/api/healthok`. — в ответ должно прийти
Демо-учётные записи: operator, psychologist1, psychologist2, lawyer1, conflictolog1, admin. Пароль по умолчанию — otklik-demo-2026 (можно переопределить через SEED_DEFAULT_PWD).
Заключение
test-oren-it — это пример аккуратно спроектированного сервиса, где безопасность и анонимность являются не дополнительной функцией, а основой архитектуры. Разделение портов для заявителей и сотрудников, хеширование трек-номеров, обезличивание вложений и строгие rate limit — всё это говорит о зрелом подходе к защите данных. Код разделён на слои, что упрощает поддержку и тестирование. Проект может быть интересен как референс для разработчиков, которые строят системы с повышенными требованиями к приватности.