Как я в 15 лет написал российскую социальную сеть с нуля — и что из этого вышло

от автора

Меня зовут Арсений, мне 15 лет. У меня 99 пользователей, более 100 SQL‑миграций и приложение на Android и Windows. И, что не менее важно, — команда единомышленников и поддержка тех, кто верил в проект с самого начала.

агора.com (https://агора.com)

агора.com (https://агора.com)

Почему я вообще за это взялся

Всё началось с простого любопытства: а смогу ли я создать что‑то подобное с нуля? Социальная сеть казалась одной из самых сложных задач для программиста: realtime‑функционал, авторизация, модерация, шифрование, мобильное приложение… Я решил проверить себя — и взялся за дело.

наш учитель по информатике в школе

наш учитель по информатике в школе

Огромную роль сыграла поддержка друзей и знакомых: многие из них сразу заинтересовались идеей, стали первыми тестерами и давали обратную связь на каждом этапе. Отдельный вклад внесли те, кто помогал со стилями и UX — их взгляд сделал интерфейс гораздо приятнее и удобнее.

А ещё у меня есть наставник в программировании — именно он помог сделать первые шаги в разработке. Благодаря его поддержке и советам мы смогли реализовать первый пиксель‑батл — и этим опередили второй ивент в соцсети ИТД блогера Nowkie. Этот опыт дал мощный толчок и вдохновил на создание собственной платформы.

тот самый пиксель батл

тот самый пиксель батл

Стек технологий

Я не выбирал архитектуру на основе каких‑то глубоких теоретических выкладок — взял то, что смог понять и что не требовало вложений на старте:

  • React 18 + TypeScript + Vite — фронтенд. Использовал CSS Modules без UI‑библиотек, всё стилизовал вручную (огромная благодарность тем, кто помог с визуальной частью!).

  • Supabase self‑hosted (PostgreSQL + realtime + auth + storage) — поднял на VDS за 999 рублей в месяц.

  • Cloudflare Workers — для фоновых задач: импорта Telegram‑каналов, push‑уведомлений и платёжного webhook.

  • Capacitor — чтобы собрать Android‑приложение из того же React‑кода.

  • Electron — для десктопного приложения под Windows.

При этом я обошёлся без Next.js и бэкенда на Node.js: вся бизнес‑логика реализована в PostgreSQL через RPC‑функции и RLS‑политики.

Что получилось в итоге

Когда начинаешь делать соцсеть, кажется, что всё просто: посты, лайки, профили — что тут сложного? Но спустя полгода разработки список функций разрастается так, что ты словно проваливаешься в кроличью нору.

Сейчас в проекте есть:

Контент:

  • посты с текстом, фото, видео и голосовыми сообщениями;

  • Stories;

  • комментарии с вложенностью;

  • репосты с цитатой;

  • хэштеги;

  • треды.

Общение:

  • личные сообщения с E2E‑шифрованием (ECDH P‑256 + AES‑GCM);

  • групповые чаты с голосовыми сообщениями, файлами и реакциями;

  • Telegram‑каналы с импортом.

Безопасность и модерация:

  • трёхступенчатая очередь модерации;

  • автомодерация NSFW‑контента через TensorFlow/NSFWJS прямо в браузере;

  • фильтр мата;

  • система предупреждений;

  • бан на уровне RLS (не фронтенда);

  • аудит‑лог всех действий;

  • блокировки пользователей.

Монетизация:

  • подписка «Агора+» через YooKassa;

  • совместные подписки (split‑cost);

  • реферальная система: 15 приглашённых друзей дают месяц премиума;

  • трекер личных подписок (Netflix, Spotify и т. д.).

Соответствие 152‑ФЗ:

  • EXIF‑стриппинг при загрузке любого фото;

  • данные хранятся только на российской инфраструктуре;

  • приватность профиля;

  • E2E‑шифрование в личных сообщениях: сервер не видит содержимое.

Приложения:

  • Android (Capacitor) — с биометрией, нативными хаптиками и камерой;

  • Windows (Electron) — с трей‑иконкой, splash‑screen и автообновлением.

Про 100+ SQL‑миграций: уроки на ошибках

Это не хвастовство, а скорее признание: каждая миграция — либо новая функция, либо исправление того, что сломалось после предыдущей. Вот несколько примеров, которые научили меня думать наперёд:

  1. Миграция 33 (security_fixes). Обнаружил, что RLS на таблице сообщений позволяет прочитать чужую переписку, если знаешь ID разговора. Фикс занял два часа, но чувство тревоги осталось.

  2. Миграция 40 (ban_rls_server_side). Раньше проверка бана выполнялась на фронтенде. Это означало, что любой мог открыть DevTools, удалить проверку и писать заблокированным пользователям. После исправления PostgreSQL отклоняет запросы забаненного пользователя на уровне БД — до React дело вообще не доходит.

  3. Миграция 95 (feed_rpc). Лента загружалась через 5 последовательных запросов, что на медленном соединении давало задержку 3–4 секунды. Переписал в одну RPC‑функцию — время загрузки сократилось до менее 400 мс. Но по пути столкнулся с ошибкой 42702: column "post_id" is ambiguous. В PL/pgSQL имя параметра функции конфликтовало с именем колонки в подзапросе — такое не гуглится с первого раза.

Друзья и знакомые, которые тестировали проект, помогли выявить многие из этих проблем на ранних стадиях — их замечания и отчёты о багах сэкономили мне кучу времени.

E2E‑шифрование: задача, которую я не ожидал осилить

Сначала ECDH казался мне чем‑то непостижимым. Но задача была чёткой: сервер не должен иметь доступа к содержимому личных сообщений.

Итоговая схема:

  1. При регистрации генерируется пара ключей ECDH P‑256.

  2. Приватный ключ шифруется паролем пользователя через PBKDF2 → AES‑GCM и хранится в БД в зашифрованном виде. Так ключ доступен с любого устройства, но сервер его не знает.

  3. Каждое сообщение шифруется с использованием общего секрета ECDH + AES‑GCM с уникальным IV.

  4. В БД хранится строка вида E2E:base64ciphertext — сервер видит только это.

Всё это реализуется через WebCrypto API прямо в браузере, без сторонних библиотек.

NSFW‑фильтрация без сервера

Нейросеть для определения неприемлемого контента работает прямо в браузере пользователя через TensorFlow.js + NSFWJS. Картинка проверяется до загрузки на сервер — так сервер вообще не получает NSFW‑контент.

Это решает сразу три проблемы:

  • снижает нагрузку на сервер;

  • устраняет задержку модерации;

  • минимизирует юридические риски.

Что оказалось самым сложным

Не алгоритмы и не шифрование. Самое трудное — это:

  • Realtime‑функционал. Уведомления, статус «онлайн», индикатор «печатает…», новые сообщения — всё это должно работать одновременно, без утечек памяти и зависших WebSocket‑соединений.

  • RLS в PostgreSQL. Row Level Security — мощная штука, но одна неправильная политика может привести либо к утечке данных, либо к неработоспособности запросов. У меня было и то и другое.

  • Мобильная клавиатура на Android. Звучит смешно, но настройка adjustResize vs adjustPan отняла у меня несколько часов. Клавиатура перекрывала поле ввода, и это не фиксилось одной строчкой кода.

  • Работа в одиночку. Когда фича не работает в 23:00 и ты один — не у кого спросить совета. Тут меня выручали друзья и наставник: они подбадривали, помогали искать решения и тестировали каждую новую версию.

Цифры

  • 99 зарегистрированных пользователей (многие из них — мои знакомые и их друзья);

  • более 100 SQL‑миграций;

  • около 15 000 строк кода на TypeScript;

  • 1 основной разработчик + неоценимая помощь друзей по стилям, UX и тестированию;

  • 0 рублей на рекламу (рост — только за счёт сарафанного радио и поддержки окружения).

Что дальше

Проект жив и развивается. Сейчас я работаю над:

  • публикацией в Google Play;

  • улучшением онбординговой воронки: люди заходят, не понимают, что делать, и уходят.

Огромное спасибо:

  • моему наставнику — за первые шаги в программировании и вдохновение на создание пиксель‑батла, который стал отправной точкой;

  • друзьям и знакомым — за помощь со стилями, UX, тестированием и честной обратной связью;

  • всем, кто поддерживал проект с самого начала и верил в него.

Если вам интересно попробовать — заходите на агора.com.

А если вы школьник и думаете: «Это слишком сложно для меня», — нет. Просто начните. Первую версию я написал за три недели, не зная TypeScript. Всё остальное пришло по ходу работы — и, конечно, с поддержкой тех, кто рядом.

ссылка на оригинал статьи https://habr.com/ru/articles/1028768/