feat(realtime): доставлять клиентам события жизненного цикла альбома и изменения состава фото
Публиковать 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) и применяет события к стору альбомов; страница альбома уходит при потере доступа
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
package members_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"galo/internal/auth"
|
||||
"galo/internal/models"
|
||||
)
|
||||
|
||||
// Audience must resolve the owner plus every member from their own tables, and
|
||||
// must be empty for an album that does not exist.
|
||||
func TestAudience(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
st := newStack(t)
|
||||
owner := seedUser(t, st, "Owner")
|
||||
first := seedUser(t, st, "First")
|
||||
second := seedUser(t, st, "Second")
|
||||
|
||||
album := &models.Album{ID: auth.NewID(), OwnerID: owner, Title: "A"}
|
||||
if err := st.repos.Albums.Create(ctx, album); err != nil {
|
||||
t.Fatalf("create album: %v", err)
|
||||
}
|
||||
|
||||
assertAudience(t, st, album.ID, owner)
|
||||
|
||||
if err := st.repos.Members.Add(ctx, album.ID, first, "member", &owner); err != nil {
|
||||
t.Fatalf("add first: %v", err)
|
||||
}
|
||||
if err := st.repos.Members.Add(ctx, album.ID, second, "editor", &owner); err != nil {
|
||||
t.Fatalf("add second: %v", err)
|
||||
}
|
||||
assertAudience(t, st, album.ID, owner, first, second)
|
||||
|
||||
if err := st.repos.Members.Remove(ctx, album.ID, second); err != nil {
|
||||
t.Fatalf("remove second: %v", err)
|
||||
}
|
||||
assertAudience(t, st, album.ID, owner, first)
|
||||
|
||||
assertAudience(t, st, "missing-album")
|
||||
}
|
||||
Reference in New Issue
Block a user