Archived
1
0
This repository has been archived on 2025-11-29. You can view files and clone it, but cannot push or open issues or pull requests.
Files
app/README.md

146 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# p1ctos4ve
Проект в рамках дисциплины «Конструирование программного обеспечения»: сервис сохранения и организации медиа со внешних ресурсов
## Участники
- Железняков Марк Викторович - `5130904/30105`
- Михеев Егор Романович - `5130904/30105`
- Михальченко Владислав Сергеевич - `5130904/30105`
- Ботыгин Иван Алексеевич - `5130904/30105`
## Определение проблемы
Пользователи, сохраняющие большое количество медиафайлов (фотографий, видео, GIF) из разных источников (социальные сети, мессенджеры и другие специализированные платформы), сталкиваются с трудностями их систематизации и последующего поиска. Файлы скапливаются в беспорядке, отсутствует единая система тегов и категорий, что делает быстрый поиск нужного материала практически невозможным и требует значительных ручных усилий по организации. При этом всегда присутствует риск удаления материалов из первоисточника.
## Выработка требований
### Пользовательские истории
1. Как пользователь, я хочу добавлять медиафайлы (фото, видео, GIF) в свою библиотеку из различных источников (прямая загрузка, по ссылке, через интеграцию с Tenor/Pinterest), чтобы централизованно хранить все материалы.
2. Как пользователь, я хочу иметь мощную систему поиска по библиотеке с фильтрацией по типу файла, тегам, категориям и дате добавления, чтобы быстро находить конкретные материалы.
3. Как пользователь, я хочу иметь возможность просматривать свою медиатеку в удобном интерфейсе (галерея, список) с предпросмотром, чтобы легко ориентироваться в содержимом.
## Разработка архитектуры и детальное проектирование
### Оценка масштаба
> Оценка масштаба производится при условии нагрузки на сервис в размере 10 000 активных пользователей в сутки. При этом сервис подазумевает опцию селфхостинга, что может снизить требования к ресурсам центрального экземпляра (инстанса) сервиса.
#### Характер нагрузки
##### Соотношение R/W нагрузки
**30% на чтение и 70% на запись.** Обосновать это можно тем, что запись метаданных и загрузка файлов будет занимать большую долю операций в сервисе с пиками во время массовых импортов из Tenor/Pinterest. При этом чтение данных будет производится сильно реже
##### Трафик
Для входящего трафика предположим, что один пользователь в среднем будем генерировать 5 МБ данных. Так, 10 000 пользователей * 5 МБ = 50 ГБ/день.
##### Объемы дисковой системы
При начальном размере файла ~5 МБ и 10 загрузках на пользователя в день: 10 000 * 10 * 5 МБ = 500 ГБ/день. Поэтому может потребоваться дешевое S3-хранилище.
### Диаграммы C4 Model
#### Контекст
[[assets/c4-1context.jpg]]
#### Контейнеры
[[assets/c4-2containers.jpg]]
#### Компоненты
[[assets/c4-3components.jpg]]
### Контракты API
Краткая информация о методах API доступна в [assets/API.md](assets/API.md), а полная документация - в [Scalar](https://scalar.com/) на эндпоинте `/openapi`.
### Схема БД и оправдание с точки зрения нефункциональных требований
[[assets/db.png]]
#### Нефункциональные требования
##### Оптимизация индексов и связей
В схеме присутствуют индексы на полях, которые часто участвуют в поисковых запросах, например, `userId`, `visibility`, `shareUrl`, `tags`. Это повышает производительность выборок и операций поиска.
Наличие внешних ключей с каскадным удалением гарантирует целостность данных и упрощает управление связанными данными между таблицами.
##### Масштабируемость и расширяемость
Пользователи, сессии и аккаунты разделены по разным таблицам - это упрощает работу и интеграцию способов авторизации пользователей в сервисе.
##### Безопасность и уникальность данных
Схема предотвращает дублирование данных посредством использования уникальных индексов.
Например, на email и token в сессиях, shareUrl в сейвах.
### Схема масштабирования сервиса при росте нагрузки в 10 раз
Для возможности масштабирования можно использовать следующие подходы:
- Размещение бекенда за балансировщиком нагрузки (например, Nginx, Traefik или Caddy): трафик будет распределяться равномерно между двумя или более экземплярами API
- Репликация БД - основная база принимает запись, а одна или несколько реплик получают изменения по журналу (WAL) и обслуживают преимущественно чтение.
- Кеширование частозапрашиваемых данных через Redis: результаты чтения (например, списки, карточки по ID, агрегации, результаты поиска с популярными фильтрами) складываются в KV хранилище с некоторым TTL, что позволяет сократить время ответа на повторяющиеся запросы
## Кодирование и отладка
Для разработки сервиса был использован следующий набор технологий:
**Бекенд**
- *Bun* в качестве рантайма
- Бекенд-фреймворк *Elysia*
- *Drizzle ORM* для работы с базой данных *PostgreSQL*
- Фреймворк *Better Auth* для авторизации и аутентификаци пользователей
- *SeaweedFS* для хранения UGC
- *Redis* для кеширования частозапрашиваемых данных
**Фронтенд**
- Фреймворк и библиотеки *Expo* для реализации мобильного клиента сервиса
- *Tailwind* + *Nativewind* для стилизации
- Набор иконок *Lucide*
Для запуска в режиме разработки нужно:
**Бекенд**
- Установить зависимости: `bun i`
- В директории `apps/backend` заполнить файл `.env` на основе `.env.example`
- Прописать `bun dev` в директории бекенда или `bun backend:dev` в корне репозитория
**Фронтенд**
- В директории `apps/frontend` заполнить файл `.env` на основе `.env.example`
- Прописать `bun start` в директории фронтенда. Приложение можно отлаживать на мобильном устройстве через песочницу Expo Go.
## Unit-тестирование
В проекте есть тесты, проверяющие корректность работы отдельных элементов сервисов бекенда:
- `s3.service.test.ts` - проверяет корректность работы автоопределения типов медиа
- `saves.service.test.ts` - моковые тесты для проверки работы сервиса сейвов
- `scraper.service.test.ts` - тесты для проверки работы вычисления типов медиа на основе URL
Для запуска требуется прописать `bun run test:unit` из директории `apps/backend`.
## Интеграционное тестирование
Также реализованы e2e-тесты для проверки авторизации и сейвов.
Предварительно запустив бекенд, из директории бекенда нужно запустить `bun run test:e2e`.
## Сборка и запуск
Для запуска бекенда и его зависимостей на продакшене достаточно выполнить:
```
git clone https://git.inkling.su/p1ctos4ve/app p1ctos4ve
cd p1ctos4ve
chmod +x ./scripts/run.sh
./scripts/run.sh
```
Скрипт `run.sh`:
- Запустит PostgreSQL, SeaweedFS и Redis;
- Соберет образ бекенда в Docker-контейнер;
- Запустит unit и e2e-тесты;
- Поднимет сервер бекенда на `localhost:3000`
В дальнейшем для взаимодействия с API можно открыть Scalar на `localhost:3000/openapi` в браузере.