Skip to content

07Rinat07/social-network

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

59 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Solid Social Network SPA URALSK + IPTV/Radio

SPA-социальная сеть на Laravel + Vue с realtime-чатами, медиа-лентой, интернет-радио, IPTV и административным кабинетом.

Автор проекта: Rinat Sarmuldin
Email: ura07srr@gmail.com

IPTV/Radio: используются открытые источники. Ответственность за соблюдение прав на конкретные потоки лежит на пользователе/владельце инстанса.

Содержание

О проекте

Solid Social объединяет классический social feed и realtime-взаимодействие с мультимедийными сценариями:

  • социальные публикации с медиа, комментариями, репостами и лайками;
  • realtime-чаты с presence-статусами и typing-индикаторами;
  • радио и IPTV-плеер (direct/proxy/transcode/relay режимы);
  • админ-панель для модерации, настройки и аналитического дашборда;
  • lifetime text error log для серверных, клиентских и analytics failure ошибок с просмотром и экспортом из админки;
  • серверный heartbeat-трекинг пользовательской активности по модулям;
  • клиентский event-трекинг для видео, upload-failure, радио и IPTV;
  • мультиязычный интерфейс RU/EN с SEO URL (/ru/..., /en/...).

Ключевая функциональность

Социальная часть

  • Регистрация, вход, подтверждение email.
  • Профиль пользователя, подписки, лента подписок.
  • Посты, комментарии, лайки, репосты, просмотры.
  • Список комментариев к посту заново запрашивается с сервера при каждом открытии, поэтому новые комментарии и удаления видны разным пользователям без hard refresh.
  • Если у поста уже есть комментарии, но они свернуты, карточка показывает отдельную заметную плашку Показать комментарии, чтобы не пропустить обсуждение.
  • Загрузка изображений и видео через отдельные API-эндпоинты.
  • Поддержка форматов пост-медиа: jpg/jpeg/png/webp/gif/mp4/webm/mov/m4v/avi/mkv, размер файла до 200 MB.
  • В личном кабинете отображаются очередь загрузки, общий и покомпонентный прогресс, статусы и ошибки по каждому файлу.

Realtime и чаты

  • Личные и общие диалоги.
  • Presence: кто онлайн на сайте и в конкретном чате.
  • Typing indicator через whisper.
  • Статусы настроения с настройкой видимости (для всех или скрытие от выбранных участников).
  • Архивирование/восстановление чатов, реакции, вложения.
  • Удаление сообщений/вложений автором и администратором (через API), синхронизация между страницей чатов и виджетом.
  • Транспорт realtime: Laravel Reverb + pusher protocol.

IPTV

  • Импорт плейлиста по URL (m3u/m3u8) и пользовательские сидеры.
  • Фильтрация каналов по имени/группе, избранное, recent.
  • Режимы воспроизведения:
    • Direct (прямой поток),
    • Proxy (серверный прокси для обхода CORS),
    • Compatibility/Transcode (FFmpeg HLS-подготовка),
    • Relay (ретрансляция с минимальной обработкой).
  • Автоочистка и остановка серверных сессий при уходе со страницы.

Радио

  • Поиск станций через Radio Browser API.
  • Встроенные подборки станций по категориям с проверкой доступности потоков.
  • Карусели подборок и избранного с режимами Авто/Вручную, скоростью автодвижения и темами Прозрачнее/Контрастнее.
  • Блок "Сейчас играет" со статусом воспроизведения, временем сессии и метаданными станции.
  • Синхронизация воспроизведения между страницей радио и виджетом, включая корректный LIVE-таймер сессии.
  • Компактный адаптивный режим: на телефонах блок "Сейчас играет" сжат, найденные станции по умолчанию свернуты, а счетчики/чипы и служебные badge усилены по контрасту.
  • Избранные станции пользователя с мини-контролом текущего трека (play/pause/seek для не-live потоков).
  • Одноразовая команда распределения избранного админов всем не-админам: php artisan radio:distribute-admin-favorites (--dry-run для проверки).

Главная страница и контент

  • Медиа-карусель.
  • Компактная карусель авторов с поиском по имени и никнейму.
  • Глобальная кнопка В начало на длинных экранах разделов с адаптивным положением для планшетов и телефонов.
  • Виджет времени и погоды для городов (Нью-Йорк, Москва, Минск, Астана, Анкара, Уральск).
  • Источник погоды: Open-Meteo через серверный запрос.
  • В админке редактирование контента главной отдельно для RU и EN.

Админ-аналитика и heartbeat

  • Админ-дашборд с KPI, графиками подписок/активности и выбором периода date_from/date_to (в рамках выбранного года).
  • Отдельные аналитические секции по удержанию и stickiness, эффективности контента, чатам, медиа/видео, радио, IPTV и ошибкам/модерации.
  • Cohort-retention по месяцам регистрации, top posts/authors, reply-time по direct chat, mode split для IPTV и failure rate по transport/media.
  • Сравнение предпочтений пользователей по social/chats/radio/iptv.
  • Выгрузка фактической аналитики за выбранный диапазон в Excel (.xls) и JSON (скачивание на локальный компьютер/смартфон через браузер).
  • Excel-выгрузка теперь включает блоки Summary, Retention, Retention Cohorts, Content, Top Posts, Top Authors, Chats, Media, Radio, IPTV, Errors / Moderation, а также пользовательскую сводку за период.
  • Серверный endpoint heartbeat: POST /api/activity/heartbeat (auth + verified).
  • Серверный endpoint client analytics: POST /api/analytics/events (auth + verified).
  • Публичный endpoint client runtime log: POST /api/client-errors с записью runtime/promise/vue/http ошибок в lifetime text log.
  • В админке есть preview на dashboard и отдельная вкладка журнала ошибок с поиском, фильтром по типу, пагинацией, filtered export и скачиванием полного .log.
  • История журнала не теряется после ротации: старые файлы архивируются, при необходимости сжимаются в .gz, а поиск/фильтр/экспорт читают и активный лог, и архивы.
  • Агрегация активности в таблицы:
    • user_activity_sessions (сессии пользователя по feature),
    • user_activity_daily_stats (дневная агрегированная статистика),
    • analytics_events (клиентские события радио/IPTV/видео/upload-failure).
  • Для дашборда автоматически выбирается модель аналитики:
    • actions (fallback по действиям),
    • time_minutes (если доступны heartbeat-данные за период).

Мультиязычность и SEO

  • Локализованные роуты: /ru/... и /en/....
  • Автоматический редирект на язык, если префикс не указан.
  • Хранение выбранного языка в localStorage (solid-social:locale).
  • Поддержка runtime-перевода legacy-строк.

Скриншоты интерфейса

Актуальная галерея интерфейса. Нажмите на изображение, чтобы открыть полный размер.

Главная страница Solid Social
Главная / лента
Страница чатов Solid Social
Чаты
Радио Solid Social
Радио
IPTV с воспроизводимым каналом
IPTV
Кабинет пользователя Solid Social
Кабинет пользователя
Админка: раздел настроек
Админ-панель
Скриншоты открываются в новой вкладке — вернуться можно, просто закрыв её.

Каталог со скриншотами: docs/screenshots/.

Карта модулей

Модуль Назначение Точка входа
Auth + профиль Регистрация, вход, подтверждение email, кабинет routes/web.php, routes/api.php
Feed / posts Публикации, лайки, комментарии, репосты, discover app/Http/Controllers/PostController.php
Realtime chat Диалоги, presence, typing, вложения, архивы app/Http/Controllers/ChatController.php, routes/channels.php
IPTV Загрузка плейлистов, proxy/transcode/relay сессии app/Http/Controllers/IptvController.php, app/Services/Iptv*
Radio Поиск, подборки, воспроизведение, избранное и их распределение app/Http/Controllers/RadioController.php, app/Console/Commands/DistributeAdminRadioFavorites.php
Админка Модерация пользователей/контента/обращений, настройки сайта /api/admin/*, app/Http/Controllers/AdminController.php
Аналитика активности Heartbeat + client analytics events, дашборд и Excel/JSON export app/Http/Controllers/ActivityHeartbeatController.php, app/Http/Controllers/AnalyticsEventController.php, app/Services/AdminDashboardService.php, app/Services/AdminDashboardExportService.php
Диагностика ошибок Lifetime log сайта, preview/search/filter/export/download, archive rotation app/Http/Controllers/SiteErrorLogController.php, app/Services/SiteErrorLogService.php, resources/js/utils/siteErrorReporter.js
Контент главной RU/EN контент, world overview (время/погода) app/Http/Controllers/SiteSettingController.php, app/Services/WorldOverviewService.php
i18n + SEO RU/EN маршруты, runtime перевод, SEO мета resources/js/router/index.js, resources/js/i18n

Архитектура

Схема компонентов

flowchart LR
    U[Browser / Vue SPA] -->|HTTP API + Cookie Session + CSRF| N[Nginx]
    U -->|WebSocket (Pusher protocol)| R[Laravel Reverb :6001]
    N --> A[Laravel API / PHP-FPM]
    A --> DB[(MySQL 8.4)]
    A --> F[FFmpeg]
    A --> WM[Open-Meteo API]
    A --> RB[Radio Browser API]
    A <--> R
Loading

Слои приложения

  • Frontend (Vue 3 SPA):
    • роутер: resources/js/router/index.js
    • представления: resources/js/views
    • i18n: resources/js/i18n
  • Backend (Laravel 13):
    • HTTP API: routes/api.php
    • web/shell: routes/web.php
    • broadcast channels: routes/channels.php
    • бизнес-логика: app/Services
    • валидация/безопасность: app/Rules, app/Http/Middleware
  • Realtime: Laravel Reverb (сервис websocket в Docker).
  • Storage/DB: MySQL + файловое хранилище storage.

Методика аналитики

Методика аналитики описана прямо в README, Swagger/OpenAPI и проектном отчете без отдельного markdown-файла.

Что зафиксировано:

  • точные таблицы-источники и endpoint-источники;
  • формулы всех KPI и блоков summary, dashboard, retention, content, chats, media, radio, iptv, errors_and_moderation;
  • логика fallback между heartbeat-метриками и action-based расчётом;
  • правила DAU/WAU/MAU, stickiness, cohort retention, engagement per post, failure rate, mode split;
  • команды для ручной проверки цифр через php artisan tinker.

Короткая карта:

  • GET /api/admin/summary считает прямые COUNT(*) из БД.
  • GET /api/admin/dashboard строит единый payload через app/Services/AdminDashboardService.php.
  • GET /api/admin/dashboard/export экспортирует тот же payload через app/Services/AdminDashboardExportService.php, поэтому экран и Excel/JSON должны совпадать.
  • Heartbeat хранится в user_activity_sessions и user_activity_daily_stats.
  • Client analytics events для media/radio/IPTV/video хранятся в analytics_events.

Важно:

  • при наличии heartbeat-данных дашборд переключается на time_minutes;
  • без heartbeat включается fallback по действиям;
  • transport/media/video блоки зависят от реально отправленных analytics_events;
  • demo/seed-данные могут смещать пики по месяцам и retention-картины.

Ключевые директории

app/
  Http/
  Services/
  Events/
  Rules/
resources/js/
  views/
  components/
  router/
  i18n/
routes/
tests/Feature/
docker/

Безопасность

Аутентификация и доступ

  • Laravel Sanctum в stateful-cookie режиме (EnsureFrontendRequestsAreStateful).
  • Основные API сгруппированы под auth:sanctum + verified (подтвержденный email).
  • Админские маршруты защищены middleware admin (EnsureUserIsAdmin).
  • Broadcast-каналы имеют явную авторизацию в routes/channels.php.

CSRF / Cookies / CORS

  • CSRF защита включена для web-запросов.
  • XSRF cookie name вынесен в env (XSRF_COOKIE), чтобы не конфликтовать между local и Docker.
  • Сессионный cookie name тоже разделен (SESSION_COOKIE).
  • CORS ограничен списком CORS_ALLOWED_ORIGINS, credentials включены.

Валидация входных данных

  • Запросы покрыты FormRequest/валидацией.
  • Правило NoUnsafeMarkup блокирует:
    • HTML-теги,
    • encoded-теги (&lt;...&gt;),
    • javascript: / vbscript: / inline handlers,
    • скрытые управляющие символы.
  • Для IPTV URL действует фильтрация:
    • только http/https,
    • блок private/reserved IP и localhost.
  • Upload-валидация пост-медиа опирается на серверный MIME/Fileinfo; клиентский MIME используется только как fallback для контейнеров вроде mkv, которые браузер может отправлять как application/octet-stream.
  • Файлы, замаскированные под видео, но распознанные сервером как не-media (application/pdf и т.п.), отклоняются до сохранения.

Ограничение нагрузки

  • API throttling настроен по маршрутам:
    • авторизованные API-запросы: throttle:600,1;
    • публичные site/home-content и site/world-overview: throttle:240,1;
  • feedback anti-spam: throttle:20,1;
  • public client error log: throttle:30,1 на POST /api/client-errors;
  • media (post-images, avatars): throttle:600,1;
  • IPTV segment/playlist delivery (public relay/proxy/transcode): throttle:1200,1.
  • Отправка email verification notification: throttle:6,1.
  • Heartbeat endpoint: throttle:120,1 на POST /api/activity/heartbeat.
  • Client analytics endpoint: throttle:240,1 на POST /api/analytics/events.
  • IPTV сессии ограничены по количеству и TTL (proxy/transcode).

Технологический стек

  • Backend: PHP ^8.5 (Docker: PHP 8.5 FPM), Laravel 13, Sanctum 4, Reverb 1.10, L5 Swagger 11.
  • Frontend: Node 24, Vue 3.5, Vue Router 5, Axios, Vite 8, Laravel Vite Plugin 3, Tailwind CSS 4.
  • Media/Streaming: HLS.js, DASH.js, MPEGTS.js, Plyr, FFmpeg.
  • Database: MySQL (Docker: mysql:8.4).
  • Infra: Docker Compose (Nginx 1.28 + PHP-FPM + Reverb + MySQL + Node profiles).

Быстрый старт

1) Локальный режим (без Docker)

  1. Проверьте локальные версии:
    • PHP 8.5 (.php-version)
    • Node 24 (.nvmrc)
    • npm использует проектный cache из .npmrc, чтобы не зависеть от прав на глобальный cache Windows/OSPanel.
  2. Установите зависимости:
    • composer install
    • npm ci
  3. Создайте .env из примера:
    • Linux/macOS: cp .env.example .env
    • PowerShell: Copy-Item .env.example .env
    • CMD: copy .env.example .env
  4. Настройте подключение к БД в .env.
  5. Выполните инициализацию:
    • php artisan key:generate
    • php artisan migrate --seed (включая демо-контент: пользователи, посты, комментарии, лайки, изображения)
    • php artisan storage:link
  6. Запустите процессы:
    • php artisan serve
    • npm run dev
    • php artisan reverb:start --host=0.0.0.0 --port=6001
  7. Откройте http://127.0.0.1:8000.

2) Docker режим

  1. Запуск:
    • Обязательно создайте отдельный Docker env из шаблона .env.docker.example:
      • Linux/macOS: cp .env.docker.example .env.docker
      • PowerShell: Copy-Item .env.docker.example .env.docker -Force
      • CMD: copy .env.docker.example .env.docker
    • Не копируйте локальный .env в .env.docker: для Docker здесь нужны DB_HOST=db и переменные инициализации MySQL (MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD, MYSQL_ROOT_PASSWORD).
    • docker compose up -d --build
    • Если порты заняты, задайте forward-порты перед запуском (PowerShell): $env:WEB_FORWARD_PORT=8081; $env:DB_FORWARD_PORT=3308; $env:VITE_FORWARD_PORT=5174; $env:REVERB_FORWARD_PORT=6002; docker compose up -d --build
  2. Проверка:
    • docker compose ps
    • docker compose top websocket
  3. Откройте http://localhost:8080.

В Docker:

  • миграции запускаются автоматически (RUN_MIGRATIONS=1);
  • при пустой БД (например после docker compose down -v) сиды запускаются автоматически (RUN_SEEDERS_ON_EMPTY_DB=1);
  • если нужны реальные demo-фото в seed-постах, включите DEMO_SEED_USE_REMOTE_IMAGES=1 в .env.docker и затем повторно запустите docker compose exec --user=www-data app php artisan db:seed --class=DemoSocialContentSeeder --force;
  • ffmpeg уже установлен в образе app;
  • отдельный websocket сервис поднимает Reverb на 6001.
  • Node-сервисы используют кастомный образ docker/node/Dockerfile на базе node:24-alpine с git/openssh-client, чтобы npm ci воспроизводимо ставил GitHub-зависимость mpegts.js.
  • Docker-шаблон использует CACHE_DRIVER=file, чтобы websocket/Reverb не зависел от таблицы cache и доступности MySQL при старте.
  • при первом запуске зависимости (composer/npm) могут ставиться несколько минут, это нормально.
  • frontend-build это одноразовый сервис сборки ассетов, поэтому состояние Exited (0) для него нормально;
  • runtime-директории Laravel (bootstrap/cache, storage/framework/*) вынесены в named volumes, чтобы уменьшить лаги на Windows/macOS/Linux bind-mount.

Полезные Docker команды

  • Миграции вручную: docker compose exec --user=www-data app php artisan migrate --seed
  • Сиды: docker compose exec --user=www-data app php artisan db:seed
  • Демо-наполнение соцконтентом: docker compose exec --user=www-data app php artisan db:seed --class=DemoSocialContentSeeder
  • Наполнение IPTV каналов: docker compose exec --user=www-data app php artisan db:seed --class=IptvSeedSeeder
  • Проверка раздачи радио-избранного админа: docker compose exec --user=www-data app php artisan radio:distribute-admin-favorites --dry-run
  • Тесты (без пересборки): docker compose --profile test run --rm --no-build test
  • Тесты (с пересборкой test image): docker compose --profile test run --rm --build test
  • Логи: docker compose logs --tail=100 app
  • Остановка: docker compose down

Docker порты и БД

  • App: http://localhost:8080 (переменная WEB_FORWARD_PORT)
  • Vite dev (profile dev): http://localhost:5173 (переменная VITE_FORWARD_PORT)
  • Reverb websocket: ws://localhost:6001 (переменная REVERB_FORWARD_PORT)
  • MySQL с хоста: 127.0.0.1:3307 (переменная DB_FORWARD_PORT)
  • MySQL внутри сети Docker: db:3306

Переменные окружения

Важно

  • Локальный режим: используйте .env (из .env.example).
  • Docker режим: сервисы используют ${DOCKER_ENV_FILE}; рекомендуемый рабочий файл .env.docker, шаблон .env.docker.example.
  • Не смешивайте local и docker cookies/домены в одном браузерном контексте.
  • Если меняете cache backend для Docker на database или redis, он должен быть доступен и app, и websocket; для database также нужны таблицы cache/cache_locks.

Ключевые env-переменные

  • Приложение: APP_ENV, APP_DEBUG, APP_URL
  • База: DB_CONNECTION, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD
  • Инициализация MySQL в Docker: MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD, MYSQL_ROOT_PASSWORD
  • Безопасность/сессия: SANCTUM_STATEFUL_DOMAINS, CORS_ALLOWED_ORIGINS, SESSION_COOKIE, XSRF_COOKIE, VITE_XSRF_COOKIE_NAME
  • Realtime: REVERB_*, VITE_REVERB_*
  • IPTV: IPTV_FFMPEG_BIN
  • Radio API: RADIO_BROWSER_BASE_URL
  • Lifetime error log: SITE_ERROR_LOG_PATH, SITE_ERROR_LOG_ARCHIVE_PATH, SITE_ERROR_LOG_ROTATE_MAX_BYTES, SITE_ERROR_LOG_ROTATE_MAX_AGE_DAYS, SITE_ERROR_LOG_ARCHIVE_COMPRESS
  • Docker Compose (host only): WEB_FORWARD_PORT, DB_FORWARD_PORT, VITE_FORWARD_PORT, REVERB_FORWARD_PORT, APP_HEALTHCHECK_START_PERIOD, RUN_MIGRATIONS, RUN_SEEDERS_ON_EMPTY_DB, DEMO_SEED_USE_REMOTE_IMAGES
  • Docker env selector: DOCKER_ENV_FILE (например .env.docker)

Тестирование

Локально:

  • Все тесты: php artisan test
  • Feature suite: php artisan test --testsuite=Feature
  • Rate limit и anti-spam: php artisan test tests/Feature/ApiRateLimitFeatureTest.php
  • Login lockout/retry-after: php artisan test tests/Feature/LoginThrottleFeatureTest.php
  • Медиа (доступ, fallback, cache-bust query): php artisan test tests/Feature/MediaPostFeatureTest.php
  • Heartbeat трекинг: php artisan test tests/Feature/ActivityHeartbeatFeatureTest.php
  • Дашборд/экспорт админ-аналитики: php artisan test tests/Feature/AdminAndChatFeatureTest.php
  • Lifetime error log, фильтры, export и archive rotation: php artisan test tests/Feature/SiteErrorLogFeatureTest.php
  • Сид демо-контента: php artisan test tests/Feature/DemoSocialContentSeederFeatureTest.php
  • IPTV: php artisan test tests/Feature/IptvFeatureTest.php
  • IPTV Админка (Сидеры): php artisan test tests/Feature/AdminIptvSeedFeatureTest.php
  • Чаты и realtime: php artisan test tests/Feature/ChatFeatureTest.php
  • Broadcast channels: php artisan test tests/Feature/BroadcastChannelsFeatureTest.php
  • Swagger/OpenAPI: php artisan test tests/Feature/SwaggerDocumentationFeatureTest.php
  • Админка: php artisan test tests/Feature/AdminPanelFeatureTest.php, php artisan test tests/Feature/AdminAndChatFeatureTest.php
  • JS unit-тесты helper-логики (radio, iptv, avatar search, section top button): npm run test:js
  • Фронт-билд: npm run build

В Docker:

  • Все тесты (одноразовый test-контейнер): docker compose --profile test run --rm --no-build test
  • Все тесты (в запущенном app-контейнере): docker compose exec --user=www-data app php artisan test
  • Feature suite: docker compose exec --user=www-data app php artisan test --testsuite=Feature
  • Конкретный файл тестов: docker compose exec --user=www-data app php artisan test tests/Feature/ChatFeatureTest.php
  • Фронт-билд: docker compose run --rm frontend-build

Изоляция тестового окружения:

  • Bootstrap тестов (tests/CreatesApplication.php) принудительно выставляет testing-env (sqlite :memory:, CACHE_DRIVER=array, SESSION_DRIVER=array, BROADCAST_DRIVER=log) до загрузки приложения.
  • Для каждого процесса формируется TEST_TOKEN, а cache/storage paths переносятся в отдельный temp-каталог.
  • Это устраняет конфликты и падения тестов из-за смешивания cache/storage между запуском от root и www-data в Docker.

Рекомендуемый pre-commit check:

  • php artisan test
  • npm run test:js
  • npm run build

Контрольный набор перед релизом:

  • docker compose run --rm test
  • docker compose run --rm --no-deps --entrypoint npm node run test:js
  • docker compose run --rm --no-deps frontend-build

Проверка зависимостей:

  • npm outdated — контроль устаревших проектных пакетов.
  • npm audit — должен завершаться без уязвимостей.
  • composer audit — должен завершаться без security advisories; abandoned-зависимости удалены после миграции Swagger/OpenAPI с PHPDoc на PHP attributes.

Ручной smoke-check интерфейса перед релизом:

  • длинные секции и кнопки В начало на desktop/tablet/mobile;
  • радио: карусели, счетчики, контрастные плашки, режимы Прозрачнее/Контрастнее, компактный mobile-блок Сейчас играет;
  • чаты и виджеты: кнопки удаления, контраст текста/статусов и адаптивные списки.

API ориентиры

Публичные

  • POST /api/feedback
  • POST /api/client-errors
  • GET /api/site/home-content
  • GET /api/site/world-overview?locale=ru|en

Авторизованные + verified

  • Пользователи и профиль:
    • GET /api/users, GET /api/users/{user}/posts, GET /api/users/following_posts
    • POST /api/users/profile, POST /api/users/{user}/toggle_following
  • Посты и медиа:
    • POST /api/post_media, GET /api/media/post-images/{postImage}
    • GET /api/posts, POST /api/posts, GET /api/posts/discover, GET /api/posts/carousel
    • POST /api/posts/{post}/view, GET /api/posts/{post}/comment, POST /api/posts/{post}/comment, DELETE /api/posts/{post}/comments/{comment}
  • Чаты:
    • GET /api/chats, GET /api/chats/unread-summary, GET /api/chats/users
    • POST /api/chats/direct/{user}, GET /api/chats/{conversation}, POST /api/chats/{conversation}/read
    • GET /api/chats/{conversation}/messages, POST /api/chats/{conversation}/messages
    • POST /api/chats/{conversation}/messages/{message}/reactions
    • DELETE /api/chats/{conversation}/messages/{message}
    • DELETE /api/chats/{conversation}/messages/{message}/attachments/{attachment}
    • GET /api/chats/settings, PATCH /api/chats/settings
    • GET /api/chats/archives, POST /api/chats/archives, GET /api/chats/archives/{archive}/download, POST /api/chats/archives/{archive}/restore
    • PATCH /api/chats/{conversation}/mood-status
  • Радио: GET /api/radio/stations, GET /api/radio/stream, GET /api/radio/favorites, POST /api/radio/favorites, DELETE /api/radio/favorites/{stationUuid}
  • IPTV библиотека и импорт: POST /api/iptv/playlist/fetch, GET /api/iptv/saved, POST /api/iptv/saved/playlists, PATCH /api/iptv/saved/playlists/{playlistId}, DELETE /api/iptv/saved/playlists/{playlistId}, POST /api/iptv/saved/channels, PATCH /api/iptv/saved/channels/{channelId}, DELETE /api/iptv/saved/channels/{channelId}
  • IPTV возможности: GET /api/iptv/transcode/capabilities
  • POST /api/iptv/proxy/start, DELETE /api/iptv/proxy/{session}
  • POST /api/iptv/transcode/start, DELETE /api/iptv/transcode/{session}
  • POST /api/iptv/relay/start, DELETE /api/iptv/relay/{session}
  • Activity tracking: POST /api/activity/heartbeat, POST /api/analytics/events

Админские (/api/admin/*)

  • Пользователи, посты, комментарии, обращения, диалоги, блокировки, настройки сайта.
  • Дашборд аналитики:
    • GET /api/admin/summary
    • GET /api/admin/dashboard?year=YYYY&date_from=YYYY-MM-DD&date_to=YYYY-MM-DD
  • GET /api/admin/dashboard/export?format=xls|json&locale=ru|en&year=YYYY&date_from=YYYY-MM-DD&date_to=YYYY-MM-DD
  • Диагностика lifetime error log:
    • GET /api/admin/error-log
    • GET /api/admin/error-log/entries?search=...&type=all|server_exception|client_error|analytics_failure&page=1&per_page=20
    • GET /api/admin/error-log/export?search=...&type=...
    • GET /api/admin/error-log/download
  • Экспорт запускается из админки и возвращает поток файла (Content-Disposition) для прямого скачивания.
  • JSON/XLS payload синхронизирован с блоками retention, content, chats, media, radio, iptv, errors_and_moderation.
  • Lifetime error log работает как отдельный operational diagnostics контур: хранит подробные сырые записи за весь срок жизни сайта, умеет искать по активному логу и архивам и не зависит от периодного dashboard payload.
  • JSON/XLS payload строится из heartbeat, client analytics events, users/posts/comments/media/chats/radio/IPTV/error-log данных и покрывается feature-тестами.

Swagger / OpenAPI

  • Swagger UI: GET /api/documentation
  • Docs route для JSON, который использует Swagger UI: GET /docs?api-docs.json
  • Сгенерированный JSON-файл на диске: storage/api-docs/api-docs.json
  • Генерация документации: php artisan l5-swagger:generate
  • Базовая спецификация на PHP attributes: app/OpenApi/OpenApiSpec.php
  • Актуальная версия спецификации: 1.5.0
  • Спецификация синхронизирована с ключевыми маршрутами site config, users, posts, post_media, radio favorites, chat settings/archives/mood-status, IPTV library/playback sessions, activity heartbeat, client analytics events, client error logging, admin summary/analytics/export, admin diagnostics error-log.
  • Для блока админ-аналитики Swagger синхронизирован с маршрутами dashboard/export и проверяется SwaggerDocumentationFeatureTest.
  • На L5 Swagger 11 спецификация переведена на OpenApi\Attributes; abandoned-пакет doctrine/annotations больше не нужен.
  • Генерация и доступность Swagger UI дополнительно проверяются тестом tests/Feature/SwaggerDocumentationFeatureTest.php.

Тестовые аккаунты

Доступны после php artisan db:seed:

  • admin@example.com / password
  • user1@example.com / password
  • user2@example.com / password
  • user3@example.com / password
  • user4@example.com / password
  • user5@example.com / password
  • demo01@example.com ... demo18@example.com / password

DemoSocialContentSeeder дополнительно создаёт демо-посты, комментарии, лайки, подписки и placeholder-изображения. По умолчанию изображения генерируются локально (без зависимости от интернета). Если нужны внешние фото из loremflickr.com, включите DEMO_SEED_USE_REMOTE_IMAGES=1. Если seed-посты уже были созданы с локальными SVG-плейсхолдерами, повторный запуск DemoSocialContentSeeder при DEMO_SEED_USE_REMOTE_IMAGES=1 заменит их на реальные загруженные изображения.

Частые проблемы

SQLSTATE[HY000] [2002] Connection refused

  • Проверьте DB_HOST/DB_PORT в активном env-файле.
  • Из контейнеров Docker MySQL доступен как db:3306.
  • С хоста Windows/MySQL доступен как 127.0.0.1:3307.

Access denied

  • Проверьте DB_USERNAME/DB_PASSWORD и пользователя в MySQL.

Container social-network-db-1 is unhealthy

  • Самая частая причина: Docker запущен с неправильным .env.docker или без MYSQL_ROOT_PASSWORD.
  • Пересоздайте docker-env из шаблона:
    • PowerShell: Copy-Item .env.docker.example .env.docker -Force
  • Проверьте, что в .env.docker есть:
    • DB_HOST=db
    • MYSQL_DATABASE=...
    • MYSQL_USER=...
    • MYSQL_PASSWORD=...
    • MYSQL_ROOT_PASSWORD=...
  • После исправления env перезапустите стек:
    • docker compose down -v
    • docker compose up -d --build

ports are not available / bind ... already in use

  • Порт уже занят другим приложением.
  • Запустите Docker с другими host-портами через переменные: WEB_FORWARD_PORT, DB_FORWARD_PORT, VITE_FORWARD_PORT, REVERB_FORWARD_PORT.

После docker compose down -v пропали демо-данные

  • Это ожидаемо: флаг -v удаляет том MySQL (db_data), база пересоздаётся с нуля.
  • В текущей конфигурации контейнер app сам запускает db:seed, если таблица users пустая (RUN_SEEDERS_ON_EMPTY_DB=1).
  • Если вы отключили авто-сидирование, запустите вручную:
    • docker compose exec --user=www-data app php artisan db:seed --force

В ленте видно fallback-картинку вместо фото

  • Частая причина: прерванный запрос изображения (например 499 при смене маршрута), а не отсутствие файла или интернета.
  • Маршруты media (post-images, avatars) используют отдельный лимит throttle:600,1.
  • Во фронтенде добавлен автоповтор загрузки изображения перед fallback (cache-bust query ?_img_retry=...).
  • Если вы обновили код, но эффект не появился, очистите кэш:
    • docker compose exec --user=www-data app php artisan optimize:clear
    • Ctrl+F5 в браузере

Видео не загружается в новый пост

  • Поддерживаются mp4, webm, mov, m4v, avi, mkv и изображения jpg/jpeg/png/webp/gif.
  • Лимит одного файла: 200 MB.
  • В личном кабинете показываются статус и текст ошибки по каждому файлу; если загрузка отклонена, причина видна под формой.
  • Для mkv загрузка и скачивание поддерживаются, но встроенное воспроизведение в браузере зависит от кодеков конкретного файла.
  • В production проверьте, что Nginx/reverse proxy разрешает тело запроса не меньше 200M, иначе запрос будет отклонен до Laravel.

No services to build при docker compose --profile test run ...

  • Это warning от Docker Compose, а не ошибка тестов.
  • Используйте:
    • без пересборки: docker compose --profile test run --rm --no-build test
    • с пересборкой: docker compose --profile test run --rm --build test

500 /login + fopen(...storage/framework/cache/data/..): No such file or directory

  • Причина: artisan запускался в контейнере от root, и часть cache-папок создавалась с правами, недоступными для www-data.
  • Профилактика: запускайте artisan в Docker так: docker compose exec --user=www-data app php artisan ...
  • Если уже сломалось:
    • docker compose exec app sh -lc "chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache && find /var/www/html/storage /var/www/html/bootstrap/cache -type d -exec chmod 775 {} \\; && find /var/www/html/storage /var/www/html/bootstrap/cache -type f -exec chmod 664 {} \\;"
    • docker compose exec --user=www-data app php artisan optimize:clear

FilesystemIterator::__construct(...storage/framework/testing/disks/...): Permission denied в тестах

  • Причина: тестовые storage-пути были созданы от другого пользователя (обычно root), после чего запуск от www-data не может очистить директории.
  • Профилактика: запускайте тесты в Docker от www-data и не смешивайте docker compose exec app ... и docker compose exec --user=www-data app ....
  • Если уже сломалось:
    • docker compose exec app sh -lc "rm -rf /var/www/html/storage/framework/testing/disks && mkdir -p /var/www/html/storage/framework/testing/disks && chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache && chmod -R ug+rwX /var/www/html/storage /var/www/html/bootstrap/cache"
    • docker compose exec --user=www-data app php artisan test

A temporary file could not be opened to write the process output (Windows/OSPanel)

  • Причина: PHP/Symfony Process не может писать lock-файлы во временную директорию по умолчанию (C:/OSPanel/temp/...).
  • Решение: запускать тесты с локальным writable temp-каталогом проекта:
    • PowerShell:
      • $tempPath = Join-Path (Get-Location) 'storage\\framework\\testing-runtime\\tmp'
      • New-Item -ItemType Directory -Force -Path $tempPath | Out-Null
      • php -d sys_temp_dir="$tempPath" artisan test

Пустая страница / сломанный фронт

  • Локально: запущен ли npm run dev.
  • Docker: пересоберите фронт docker compose run --rm frontend-build.
  • Сделайте Ctrl+F5.

Контейнер frontend-build в Exited (0)

  • Это нормально: сервис делает npm run build и завершается после успешной сборки.
  • Проверяйте именно долгоживущие сервисы: app, web, websocket, db.
  • Если после простоя сайт отвечает медленно, смотрите docker compose ps и docker compose logs --tail=100 app web db websocket, а не статус frontend-build.

502 Bad Gateway в Docker

  • Короткий 502 во время ручного docker compose up -d --force-recreate app возможен, пока php-fpm поднимается заново.
  • Постоянный 502 уже не должен быть связан со stale upstream IP: web резолвит app через Docker DNS во время работы.
  • Если 502 не исчезает после того, как app стал healthy, проверьте:
    • docker compose ps
    • docker compose logs --tail=100 app web
    • docker compose exec --user=www-data app php artisan optimize:clear

403 на /api/broadcasting/auth

  • Убедитесь, что пользователь авторизован.
  • Проверьте домен/порт (APP_URL) и фактический URL браузера.
  • Проверьте, что Reverb запущен.

CSRF token mismatch

  • Очистите cookie и обновите страницу (Ctrl+F5).
  • Убедитесь, что не смешаны окружения:
    • local: XSRF_COOKIE=social_network_local_xsrf
    • Docker: XSRF_COOKIE=social_network_docker_xsrf
  • После переключения режимов выполните logout и удалите старые cookies.

Битая аватарка или файлы из /storage (локально)

  • Исправление:
    • php -r "if (is_link('public/storage')) unlink('public/storage');"
    • php artisan storage:link

Деплой в production

Подробный production-гайд (Ubuntu + Nginx + PHP-FPM + Supervisor):
DEPLOY.md

Лицензия и права использования

  • © 2026 Rinat Sarmuldin. All rights reserved.
  • Репозиторий распространяется по проприетарной лицензии: LICENSE.
  • Без письменного разрешения автора запрещены:
    • использование в production и коммерческих проектах;
    • копирование, изменение, распространение и создание производных работ.
  • Для получения прав на использование свяжитесь с автором: ura07srr@gmail.com.

About

Solid Social Network SPA URALSK + IPTV/Radio ==> SPA-социальная сеть на Laravel + Vue с чатами, realtime, медиа-контентом и админ-панелью.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors