Перейти к содержанию

Социальные функции

Обзор функциональности

Обзор

Социальный слой приложения включает три ключевых механизма: 1. Шеринг образов — генерация уникальной ссылки для ��ередачи образа другому пользователю 2. Получение обр��зов — просмотр и claim (забирание) образа по ссылке 3. Лента — персонализированная бесконечная лента AI-сгенерированных образов

Страницы модуля

Страница Маршрут Защищённый Назначение
SharePage /share/:outfitId да Создание ссылки / сторис-картинки
ShareRecipientPage /share/view/:token нет Просмотр и забирание расшаренного образа
FeedPage /feed да Персонализированная лента образов

Sequence diagram: шеринг образа

sequenceDiagram
    participant U as Отправитель
    participant Share as SharePage
    participant API as outfitsApi
    participant Clip as Clipboard

    U->>Share: Открывает /share/:outfitId
    Share->>API: GET /outfits/:id
    API-->>Share: Outfit (обложка, название)

    alt Скопировать ссылку
        U->>Share: Нажимает "Скопировать ссылку"
        Share->>API: POST /outfits/:id/share { format: 'link' }
        API-->>Share: { url: '/share/view/:token', format: 'link' }
        Share->>Clip: navigator.clipboard.writeText(url)
        Share-->>U: message.success('Ссылка скопирована')
    else Сторис
        U->>Share: Нажи��ает "Сторис"
        Share->>Share: generateOutfitStoryJpeg({ outfitImageSrc })
        Share->>Share: openStoryBlobInNewTab(blob, title)
        Share-->>U: "Сохраните фото и выложите в сторис"
    end

Диаграмма

Sequence diagram: получение образа

sequenceDiagram
    participant R as Получатель
    participant Page as ShareRecipientPage
    participant API as shareApi
    participant Auth as authStore

    R->>Page: Открывает /share/view/:token
    Page->>API: GET /share/:token
    API-->>Page: Outfit (обложка, название, состав)

    alt Авторизован
        R->>Page: Нажимает "Забрать образ"
        Page->>API: POST /share/:token
        API-->>Page: Outfit (создан в коллекции получателя)
        Page->>R: navigate('/')  message.success
    else Не авторизован
        R->>Page: Нажимает "Забрать образ"
        Page->>R: navigate('/login?redirect=/share/view/:token')
        Note over R, Auth: После логина — редирект обратно
        R->>Page: Возврат на страницу
        R->>Page: Нажимает "Забрать образ"
        Page->>API: POST /share/:token
    end

Диаграмма

Sequence diagram: бесконечная лента

sequenceDiagram
    participant U as Пользователь
    participant Feed as FeedPage
    participant API as feedApi
    participant Cache as feedSessionCache

    U->>Feed: Открывает /feed
    Feed->>Cache: readFeedSessionCache(queryKey)
    Cache-->>Feed: Кешированные данные (если есть)

    Feed->>API: GET /feed?limit=20
    API-->>Feed: { outfits[], next_offset }
    Feed->>Cache: writeFeedSessionCache(queryKey, data)
    Feed-->>U: Рендер карточек (snap-scroll)

    loop Бесконечный скролл
        U->>Feed: Скроллит вниз
        Feed->>Feed: IntersectionObserver (sentinel)
        Feed->>API: GET /feed?limit=20&cursor=:offset
        API-->>Feed: { outfits[], next_offset }
        Feed-->>U: Новые карточки
    end

    U->>Feed: Нажимает "Сохранить" на карточке
    Feed->>API: POST /outfits (материализация виртуального образа)
    Feed->>API: POST /outfits/:id/save
    Feed-->>U: "Образ сохранён"

Диаграмма

API-модули

// shareApi (frontend/src/api/share.ts)
shareApi.getByToken(token)       // GET /share/:token — просмотр расшаренного образа
shareApi.claim(token)            // POST /share/:token — забрать образ себе
shareApi.getMySharedOutfits()    // GET /users/me/shared-outfits
shareApi.revoke(token)           // DELETE /share/:token

// feedApi (frontend/src/api/feed.ts)
feedApi.list(params)             // GET /feed — лента с cursor-пагинацией

Навигация