Публиковать album.created/updated/deleted и изменения состава фото в личный поток SSE, а также photo.created при загрузке, чтобы списки альбомов, счётчики и открытые страницы альбома обновлялись без перезагрузки. - members.Repository получил Audience (владелец + участники) для дешёвого веера - albums.Service рассылает события в личные потоки получателей, перечитывая альбом через GetByID и attachCover, чтобы payload совпадал с GET /api/albums - members.Service публикует при принятии инвайта, смене роли и исключении - photos.Service публикует photo.created при загрузке и album.updated при добавлении/копировании/перемещении/восстановлении/корзине/окончательном удалении - photos_count теперь считает фото вне корзины - web-клиент подписывается на /api/sse/me один раз на уровне layout'а (app) и применяет события к стору альбомов; страница альбома уходит при потере доступа
24 lines
979 B
Go
24 lines
979 B
Go
package members
|
|
|
|
import (
|
|
"context"
|
|
|
|
"galo/internal/models"
|
|
)
|
|
|
|
// Repository is the persistence contract for the members domain.
|
|
type Repository interface {
|
|
Role(ctx context.Context, albumID, userID string) (string, error)
|
|
List(ctx context.Context, albumID string) ([]models.AlbumMember, error)
|
|
// Audience returns the ids of every user the album is visible to: the owner
|
|
// plus all members. It resolves the set without joining users, so it stays
|
|
// cheap enough to call for every published album event.
|
|
Audience(ctx context.Context, albumID string) ([]string, error)
|
|
Add(ctx context.Context, albumID, userID, role string, invitedBy *string) error
|
|
UpdateRole(ctx context.Context, albumID, userID, role string) error
|
|
Remove(ctx context.Context, albumID, userID string) error
|
|
CreateInvite(ctx context.Context, inv *models.Invite) error
|
|
GetInviteByToken(ctx context.Context, token string) (*models.Invite, error)
|
|
IncrementUses(ctx context.Context, id string) error
|
|
}
|