Live video on the AT Protocol

fix: address review feedback from iameli

- Remove impossible nil check after successful SyncBlueskyRepoCached
- Change livestream update to CREATE instead of PUT
- Set pushNotification=false for moderator-created livestream records

Addresses feedback from PR #787 (merged into this branch)

+21 -16
-4
pkg/atproto/sync.go
··· 429 429 if err != nil { 430 430 return fmt.Errorf("failed to sync bluesky repo: %w", err) 431 431 } 432 - if repo == nil { 433 - // someone we don't know about 434 - return nil 435 - } 436 432 log.Debug(ctx, "creating moderation delegation", "streamerDID", userDID, "moderatorDID", rec.Moderator) 437 433 438 434 permissionsJSON, err := json.Marshal(rec.Permissions)
+21 -12
pkg/spxrpc/place_stream_moderation.go
··· 271 271 return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to decode livestream record") 272 272 } 273 273 274 - // Update only the provided fields 274 + // Create new record (don't edit existing - old records serve as "chapter markers") 275 + // Copy fields from existing record and update title 275 276 if input.Title != nil { 276 277 livestream.Title = *input.Title 277 278 } 278 279 279 - // Update the record 280 - putInput := comatproto.RepoPutRecord_Input{ 280 + // Ensure notificationSettings.pushNotification is false for mods 281 + if livestream.NotificationSettings == nil { 282 + livestream.NotificationSettings = &streamplace.Livestream_NotificationSettings{} 283 + } 284 + pushNotificationFalse := false 285 + livestream.NotificationSettings.PushNotification = &pushNotificationFalse 286 + 287 + // Update createdAt to current time for new record 288 + livestream.CreatedAt = time.Now().UTC().Format(time.RFC3339) 289 + 290 + // Create new record instead of updating existing 291 + createInput := comatproto.RepoCreateRecord_Input{ 281 292 Collection: constants.PLACE_STREAM_LIVESTREAM, 282 293 Record: &lexutil.LexiconTypeDecoder{Val: livestream}, 283 - Rkey: rkey, 284 294 Repo: input.Streamer, 285 - SwapRecord: getOutput.Cid, 286 295 } 287 - putOutput := comatproto.RepoPutRecord_Output{} 296 + createOutput := comatproto.RepoCreateRecord_Output{} 288 297 289 - err = modCtx.StreamerClient.Do(ctx, xrpc.Procedure, "application/json", "com.atproto.repo.putRecord", map[string]any{}, putInput, &putOutput) 298 + err = modCtx.StreamerClient.Do(ctx, xrpc.Procedure, "application/json", "com.atproto.repo.createRecord", map[string]any{}, createInput, &createOutput) 290 299 if err != nil { 291 - log.Error(ctx, "failed to update livestream record", "err", err) 300 + log.Error(ctx, "failed to create livestream record", "err", err) 292 301 if auditErr := s.logAudit(ctx, input.Streamer, modCtx.ModeratorDID, "updateLivestream", input.LivestreamUri, "", "", false, err.Error()); auditErr != nil { 293 302 log.Error(ctx, "failed to create audit log", "error", auditErr) 294 303 } 295 - return nil, echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to update livestream: %v", err)) 304 + return nil, echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to create livestream: %v", err)) 296 305 } 297 306 298 307 // Log successful audit entry 299 - if err := s.logAudit(ctx, input.Streamer, modCtx.ModeratorDID, "updateLivestream", input.LivestreamUri, "", putOutput.Uri, true, ""); err != nil { 308 + if err := s.logAudit(ctx, input.Streamer, modCtx.ModeratorDID, "updateLivestream", input.LivestreamUri, "", createOutput.Uri, true, ""); err != nil { 300 309 log.Error(ctx, "failed to create audit log", "error", err) 301 310 } 302 311 303 312 return &streamplace.ModerationUpdateLivestream_Output{ 304 - Uri: putOutput.Uri, 305 - Cid: putOutput.Cid, 313 + Uri: createOutput.Uri, 314 + Cid: createOutput.Cid, 306 315 }, nil 307 316 } 308 317