···333333 c.permissions
334334 FROM hold_captain_records h
335335 LEFT JOIN hold_crew_members c ON h.hold_did = c.hold_did AND c.member_did = ?1
336336- WHERE h.allow_all_crew = 1
336336+ WHERE (h.successor IS NULL OR h.successor = '')
337337+ AND (h.allow_all_crew = 1
337338 OR h.owner_did = ?1
338338- OR c.member_did IS NOT NULL
339339+ OR c.member_did IS NOT NULL)
339340 ORDER BY
340341 CASE
341342 WHEN h.owner_did = ?1 THEN 0
+26
pkg/appview/db/queries.go
···20222022 return UpdateManifestHoldDID(h.db, did, oldHoldDID, newHoldDID)
20232023}
2024202420252025+// GetDistinctManifestHoldDIDs returns all distinct hold DIDs referenced by a user's manifests.
20262026+func GetDistinctManifestHoldDIDs(db DBTX, did string) ([]string, error) {
20272027+ rows, err := db.Query(`
20282028+ SELECT DISTINCT hold_endpoint FROM manifests
20292029+ WHERE did = ? AND hold_endpoint != ''
20302030+ `, did)
20312031+ if err != nil {
20322032+ return nil, err
20332033+ }
20342034+ defer rows.Close()
20352035+ var holds []string
20362036+ for rows.Next() {
20372037+ var h string
20382038+ if err := rows.Scan(&h); err != nil {
20392039+ return nil, err
20402040+ }
20412041+ holds = append(holds, h)
20422042+ }
20432043+ return holds, rows.Err()
20442044+}
20452045+20462046+// GetDistinctManifestHoldDIDs wraps the package-level function.
20472047+func (h *HoldDIDDB) GetDistinctManifestHoldDIDs(did string) ([]string, error) {
20482048+ return GetDistinctManifestHoldDIDs(h.db, did)
20492049+}
20502050+20252051// IsManifestReferenced checks if a digest is a child of any manifest list for the user.
20262052// Implements storage.ManifestReferenceChecker.
20272053func (h *HoldDIDDB) IsManifestReferenced(did, digest string) (bool, error) {
···6666// EnsureUser resolves and upserts a user by DID
6767// Uses cache if enabled (Worker), queries DB if cache disabled (Backfill)
6868func (p *Processor) EnsureUser(ctx context.Context, did string) error {
6969- // Check cache first (if enabled)
6969+ // Check cache first (if enabled) — within a single backfill run,
7070+ // a user's identity won't change, so the cache hit is safe.
7071 if p.useCache && p.userCache != nil {
7172 if _, ok := p.userCache.cache[did]; ok {
7272- // User in cache - just update last seen timestamp
7373- return db.UpdateUserLastSeen(p.db, did)
7474- }
7575- } else if !p.useCache {
7676- // No cache - check if user already exists in DB
7777- existingUser, err := db.GetUserByDID(p.db, did)
7878- if err == nil && existingUser != nil {
7979- // User exists - just update last seen timestamp
8073 return db.UpdateUserLastSeen(p.db, did)
8174 }
8275 }
7676+ // No cache early-return: always re-resolve identity so stale handles
7777+ // (e.g., user changed handle between backfill runs) get corrected.
83788479 // Resolve DID to get handle and PDS endpoint
8580 resolvedDID, handle, pdsEndpoint, err := atproto.ResolveIdentity(ctx, did)