···180180181181 // Wait for user to complete OAuth flow, then retry
182182 fmt.Fprintf(os.Stderr, "Waiting for authentication")
183183- for i := 0; i < 60; i++ { // Wait up to 2 minutes
183183+ for range 60 { // Wait up to 2 minutes
184184 time.Sleep(2 * time.Second)
185185 fmt.Fprintf(os.Stderr, ".")
186186···765765 curParts := strings.Split(curV, ".")
766766767767 // Compare each part
768768- for i := 0; i < len(newParts) && i < len(curParts); i++ {
768768+ for i := range min(len(newParts), len(curParts)) {
769769 newNum := 0
770770 curNum := 0
771771 fmt.Sscanf(newParts[i], "%d", &newNum)
+4-2
pkg/appview/db/device_store.go
···365365}
366366367367// UpdateLastUsed updates the last used timestamp
368368-func (s *DeviceStore) UpdateLastUsed(secretHash string) error {
368368+func (s *DeviceStore) UpdateLastUsed(secretHash string) {
369369 _, err := s.db.Exec(`
370370 UPDATE devices
371371 SET last_used = ?
372372 WHERE secret_hash = ?
373373 `, time.Now(), secretHash)
374374375375- return err
375375+ if err != nil {
376376+ slog.Warn("Failed to update device last used timestamp", "component", "device_store", "error", err)
377377+ }
376378}
377379378380// CleanupExpired removes expired pending authorizations
+4-10
pkg/appview/db/device_store_test.go
···5656func TestGenerateUserCode(t *testing.T) {
5757 // Generate multiple codes to test
5858 codes := make(map[string]bool)
5959- for i := 0; i < 100; i++ {
5959+ for range 100 {
6060 code := generateUserCode()
61616262 // Test format: XXXX-XXXX
···372372 return
373373 }
374374 if !tt.wantErr {
375375- if device == nil {
376376- t.Error("Expected device, got nil")
377377- }
378375 if device.DID != "did:plc:alice123" {
379376 t.Errorf("DID = %v, want did:plc:alice123", device.DID)
380377 }
···399396 }
400397401398 // Create 3 devices
402402- for i := 0; i < 3; i++ {
399399+ for i := range 3 {
403400 pending, err := store.CreatePendingAuth("Device "+string(rune('A'+i)), "192.168.1.1", "Agent")
404401 if err != nil {
405402 t.Fatalf("CreatePendingAuth() error = %v", err)
···417414 }
418415419416 // Verify they're sorted by created_at DESC (newest first)
420420- for i := 0; i < len(devices)-1; i++ {
417417+ for i := range len(devices) - 1 {
421418 if devices[i].CreatedAt.Before(devices[i+1].CreatedAt) {
422419 t.Error("Devices should be sorted by created_at DESC")
423420 }
···521518 time.Sleep(10 * time.Millisecond)
522519523520 // Update last used
524524- err = store.UpdateLastUsed(device.SecretHash)
525525- if err != nil {
526526- t.Errorf("UpdateLastUsed() error = %v", err)
527527- }
521521+ store.UpdateLastUsed(device.SecretHash)
528522529523 // Verify it was updated
530524 device2, err := store.ValidateDeviceSecret(secret)
+6-8
pkg/appview/db/oauth_store.go
···213213}
214214215215// CleanupOldSessions removes sessions older than the specified duration
216216-func (s *OAuthStore) CleanupOldSessions(ctx context.Context, olderThan time.Duration) error {
216216+func (s *OAuthStore) CleanupOldSessions(ctx context.Context, olderThan time.Duration) {
217217 cutoff := time.Now().Add(-olderThan)
218218219219 result, err := s.db.ExecContext(ctx, `
···222222 `, cutoff)
223223224224 if err != nil {
225225- return fmt.Errorf("failed to cleanup old sessions: %w", err)
225225+ slog.Warn("Failed to cleanup old OAuth sessions", "component", "oauth_store", "error", err)
226226+ return
226227 }
227228228229 deleted, _ := result.RowsAffected()
229230 if deleted > 0 {
230231 slog.Info("Cleaned up old OAuth sessions", "count", deleted, "older_than", olderThan)
231232 }
232232-233233- return nil
234233}
235234236235// CleanupExpiredAuthRequests removes auth requests older than 10 minutes
237237-func (s *OAuthStore) CleanupExpiredAuthRequests(ctx context.Context) error {
236236+func (s *OAuthStore) CleanupExpiredAuthRequests(ctx context.Context) {
238237 cutoff := time.Now().Add(-10 * time.Minute)
239238240239 result, err := s.db.ExecContext(ctx, `
···243242 `, cutoff)
244243245244 if err != nil {
246246- return fmt.Errorf("failed to cleanup auth requests: %w", err)
245245+ slog.Warn("Failed to cleanup expired auth requests", "component", "oauth_store", "error", err)
246246+ return
247247 }
248248249249 deleted, _ := result.RowsAffected()
250250 if deleted > 0 {
251251 slog.Info("Cleaned up expired auth requests", "count", deleted)
252252 }
253253-254254- return nil
255253}
256254257255// InvalidateSessionsWithMismatchedScopes removes all sessions whose scopes don't match the desired scopes
+1-3
pkg/appview/db/oauth_store_test.go
···353353 }
354354355355 // Run cleanup (remove sessions older than 30 days)
356356- if err := store.CleanupOldSessions(ctx, 30*24*time.Hour); err != nil {
357357- t.Fatalf("Failed to cleanup old sessions: %v", err)
358358- }
356356+ store.CleanupOldSessions(ctx, 30*24*time.Hour)
359357360358 // Verify old session was deleted
361359 _, err = store.GetSession(ctx, did1, "old_session")
+2-2
pkg/appview/db/session_store_test.go
···252252253253 // Create multiple sessions for alice
254254 sessionIDs := make([]string, 3)
255255- for i := 0; i < 3; i++ {
255255+ for i := range 3 {
256256 id, err := store.Create(did, "alice.bsky.social", "https://pds.example.com", 1*time.Hour)
257257 if err != nil {
258258 t.Fatalf("Create() error = %v", err)
···516516517517 // Generate multiple session IDs
518518 ids := make(map[string]bool)
519519- for i := 0; i < 100; i++ {
519519+ for range 100 {
520520 id, err := store.Create("did:plc:alice123", "alice.bsky.social", "https://pds.example.com", 1*time.Hour)
521521 if err != nil {
522522 t.Fatalf("Create() error = %v", err)
···675675 }
676676677677 // Test 5: Process multiple deactivation events (idempotent)
678678- for i := 0; i < 3; i++ {
678678+ for i := range 3 {
679679 err = processor.ProcessAccount(context.Background(), testDID, false, "deactivated")
680680 if err != nil {
681681 t.Logf("Expected cache invalidation error on iteration %d: %v", i, err)
+1-2
pkg/appview/jetstream/worker.go
···128128129129 // Reset read deadline - we know connection is alive
130130 // Allow 90 seconds for next pong (3x ping interval)
131131- conn.SetReadDeadline(time.Now().Add(90 * time.Second))
132132- return nil
131131+ return conn.SetReadDeadline(time.Now().Add(90 * time.Second))
133132 })
134133135134 // Set initial read deadline
+2-2
pkg/appview/middleware/auth_test.go
···318318 // Pre-create all users and sessions before concurrent access
319319 // This ensures database is fully initialized before goroutines start
320320 sessionIDs := make([]string, 10)
321321- for i := 0; i < 10; i++ {
321321+ for i := range 10 {
322322 did := fmt.Sprintf("did:plc:user%d", i)
323323 handle := fmt.Sprintf("user%d.bsky.social", i)
324324···358358 var wg sync.WaitGroup
359359 var mu sync.Mutex // Protect results map
360360361361- for i := 0; i < 10; i++ {
361361+ for i := range 10 {
362362 wg.Add(1)
363363 go func(index int, sessionID string) {
364364 defer wg.Done()
+1-1
pkg/appview/middleware/registry.go
···555555556556 // Store HTTP method in context for routing decisions
557557 // This is used by routing_repository.go to distinguish pull (GET/HEAD) from push (PUT/POST)
558558- ctx = context.WithValue(ctx, "http.request.method", r.Method)
558558+ ctx = context.WithValue(ctx, storage.HTTPRequestMethod, r.Method)
559559560560 // Extract Authorization header
561561 authHeader := r.Header.Get("Authorization")
+14-13
pkg/appview/ogcard/card.go
···143143 defer face.Close()
144144145145 textWidth := font.MeasureString(face, text).Round()
146146- if align == AlignCenter {
146146+ switch align {
147147+ case AlignCenter:
147148 x -= float64(textWidth) / 2
148148- } else if align == AlignRight {
149149+ case AlignRight:
149150 x -= float64(textWidth)
150151 }
151152 }
···292293// DrawRoundedRect draws a filled rounded rectangle
293294func (c *Card) DrawRoundedRect(x, y, w, h, radius int, col color.Color) {
294295 // Draw main rectangle (without corners)
295295- for dy := radius; dy < h-radius; dy++ {
296296- for dx := 0; dx < w; dx++ {
297297- c.img.Set(x+dx, y+dy, col)
296296+ for dy := range h - 2*radius {
297297+ for dx := range w {
298298+ c.img.Set(x+dx, y+radius+dy, col)
298299 }
299300 }
300301 // Draw top and bottom strips (without corners)
301301- for dy := 0; dy < radius; dy++ {
302302- for dx := radius; dx < w-radius; dx++ {
303303- c.img.Set(x+dx, y+dy, col)
304304- c.img.Set(x+dx, y+h-1-dy, col)
302302+ for dy := range radius {
303303+ for dx := range w - 2*radius {
304304+ c.img.Set(x+radius+dx, y+dy, col)
305305+ c.img.Set(x+radius+dx, y+h-1-dy, col)
305306 }
306307 }
307308 // Draw rounded corners
308308- for dy := 0; dy < radius; dy++ {
309309- for dx := 0; dx < radius; dx++ {
309309+ for dy := range radius {
310310+ for dx := range radius {
310311 // Check if point is within circle
311312 cx := radius - dx - 1
312313 cy := radius - dy - 1
···388389 centerX := radius
389390 centerY := radius
390391391391- for y := 0; y < diameter; y++ {
392392- for x := 0; x < diameter; x++ {
392392+ for y := range diameter {
393393+ for x := range diameter {
393394 dx := x - centerX
394395 dy := y - centerY
395396 if dx*dx+dy*dy <= radius*radius {
+1
pkg/appview/readme/fetcher.go
···11+// Package readme provides fetching and rendering of README files from Git hosting platforms.
12package readme
2334import (
+1-1
pkg/appview/readme/fetcher_test.go
···301301}
302302303303func containsSubstringHelper(s, substr string) bool {
304304- for i := 0; i <= len(s)-len(substr); i++ {
304304+ for i := range len(s) - len(substr) + 1 {
305305 if s[i:i+len(substr)] == substr {
306306 return true
307307 }
+1-1
pkg/appview/storage/manifest_store.go
···7676 // Notify hold about manifest pull (for stats tracking)
7777 // Only count GET requests (actual downloads), not HEAD requests (existence checks)
7878 // Check HTTP method from context (distribution library stores it as "http.request.method")
7979- if method, ok := ctx.Value("http.request.method").(string); ok && method == "GET" {
7979+ if method, ok := ctx.Value(HTTPRequestMethod).(string); ok && method == "GET" {
8080 // Do this asynchronously to avoid blocking the response
8181 if s.ctx.ServiceToken != "" && s.ctx.Handle != "" {
8282 go func() {
+1-1
pkg/appview/storage/profile_test.go
···340340341341 // Make 5 concurrent GetProfile calls
342342 var wg sync.WaitGroup
343343- for i := 0; i < 5; i++ {
343343+ for range 5 {
344344 wg.Add(1)
345345 go func() {
346346 defer wg.Done()
+6-5
pkg/appview/storage/proxy_blob_store.go
···552552}
553553554554// abortMultipartUpload aborts a multipart upload via XRPC abortUpload endpoint
555555-func (p *ProxyBlobStore) abortMultipartUpload(ctx context.Context, digest, uploadID string) error {
555555+func (p *ProxyBlobStore) abortMultipartUpload(ctx context.Context, uploadID string) error {
556556 reqBody := map[string]any{
557557 "uploadId": uploadID,
558558 }
···760760 slog.Debug("Flushing final buffer", "component", "proxy_blob_store/Commit", "bytes", w.buffer.Len())
761761 if err := w.flushPart(); err != nil {
762762 // Try to abort multipart on error
763763- tempDigest := fmt.Sprintf("uploads/temp-%s", w.id)
764764- w.store.abortMultipartUpload(ctx, tempDigest, w.uploadID)
763763+ if err := w.store.abortMultipartUpload(ctx, w.uploadID); err != nil {
764764+ slog.Warn("Failed to abort multipart upload", "component", "proxy_blob_store/Cancel", "error", err)
765765+ // Continue anyway - we want to mark upload as cancelled
766766+ }
765767 return distribution.Descriptor{}, fmt.Errorf("failed to flush final part: %w", err)
766768 }
767769 }
···794796 globalUploadsMu.Unlock()
795797796798 // Abort multipart upload
797797- tempDigest := fmt.Sprintf("uploads/temp-%s", w.id)
798798- if err := w.store.abortMultipartUpload(ctx, tempDigest, w.uploadID); err != nil {
799799+ if err := w.store.abortMultipartUpload(ctx, w.uploadID); err != nil {
799800 slog.Warn("Failed to abort multipart upload", "component", "proxy_blob_store/Cancel", "error", err)
800801 // Continue anyway - we want to mark upload as cancelled
801802 }
···1111 "github.com/distribution/distribution/v3"
1212)
13131414+type contextKey string
1515+1616+const HTTPRequestMethod contextKey = "http.request.method"
1717+1418// RoutingRepository routes manifests to ATProto and blobs to external hold service
1519// The registry (AppView) is stateless and NEVER stores blobs locally
1620// NOTE: A fresh instance is created per-request (see middleware/registry.go)
···5559 // Push operations use the discovery-based hold DID from user's profile/default
5660 // This allows users to change their default hold and have new pushes go there
5761 isPull := false
5858- if method, ok := ctx.Value("http.request.method").(string); ok {
6262+ if method, ok := ctx.Value(HTTPRequestMethod).(string); ok {
5963 isPull = method == "GET" || method == "HEAD"
6064 }
6165
+5-5
pkg/appview/storage/routing_repository_test.go
···126126 }
127127 repo := NewRoutingRepository(nil, ctx)
128128129129- pullCtx := context.WithValue(context.Background(), "http.request.method", method)
129129+ pullCtx := context.WithValue(context.Background(), HTTPRequestMethod, method)
130130 blobStore := repo.Blobs(pullCtx)
131131132132 assert.NotNil(t, blobStore)
···164164 repo := NewRoutingRepository(nil, ctx)
165165166166 // Create context with push method
167167- pushCtx := context.WithValue(context.Background(), "http.request.method", tc.method)
167167+ pushCtx := context.WithValue(context.Background(), HTTPRequestMethod, tc.method)
168168 blobStore := repo.Blobs(pushCtx)
169169170170 assert.NotNil(t, blobStore)
···330330 wg.Wait()
331331332332 // Verify all stores are non-nil (due to race conditions, they may not all be the same instance)
333333- for i := 0; i < numGoroutines; i++ {
333333+ for i := range numGoroutines {
334334 assert.NotNil(t, manifestStores[i], "manifest store should not be nil")
335335 }
336336···351351 wg.Wait()
352352353353 // Verify all stores are non-nil (due to race conditions, they may not all be the same instance)
354354- for i := 0; i < numGoroutines; i++ {
354354+ for i := range numGoroutines {
355355 assert.NotNil(t, blobStores[i], "blob store should not be nil")
356356 }
357357···376376 repo := NewRoutingRepository(nil, ctx)
377377378378 // For pull (GET), database should take priority
379379- pullCtx := context.WithValue(context.Background(), "http.request.method", "GET")
379379+ pullCtx := context.WithValue(context.Background(), HTTPRequestMethod, "GET")
380380 blobStore := repo.Blobs(pullCtx)
381381382382 assert.NotNil(t, blobStore)
+2-2
pkg/atproto/directory_test.go
···3535 instances := make(chan any, numGoroutines)
36363737 // Launch many goroutines concurrently accessing GetDirectory
3838- for i := 0; i < numGoroutines; i++ {
3838+ for range numGoroutines {
3939 go func() {
4040 defer wg.Done()
4141 dir := GetDirectory()
···7373 t.Run("multiple calls in sequence", func(t *testing.T) {
7474 // Get directory multiple times in sequence
7575 dirs := make([]any, 10)
7676- for i := 0; i < 10; i++ {
7676+ for i := range 10 {
7777 dirs[i] = GetDirectory()
7878 }
7979
+1-1
pkg/auth/cache.go
···11-// Package token provides service token caching and management for AppView.
11+// Package auth provides service token caching and management for AppView.
22// Service tokens are JWTs issued by a user's PDS to authorize AppView to
33// act on their behalf when communicating with hold services. Tokens are
44// cached with automatic expiry parsing and 10-second safety margins.
-11
pkg/auth/hold_remote_test.go
···1414 "atcr.io/pkg/atproto"
1515)
16161717-func TestNewRemoteHoldAuthorizer(t *testing.T) {
1818- // Test with nil database (should still work)
1919- authorizer := NewRemoteHoldAuthorizer(nil, false)
2020- if authorizer == nil {
2121- t.Fatal("Expected non-nil authorizer")
2222- }
2323-2424- // Verify it implements the HoldAuthorizer interface
2525- var _ HoldAuthorizer = authorizer
2626-}
2727-2817func TestNewRemoteHoldAuthorizer_TestMode(t *testing.T) {
2918 // Test with testMode enabled
3019 authorizer := NewRemoteHoldAuthorizer(nil, true)
···11+// Package token provides JWT claims and token handling for registry authentication.
12package token
2334import (
+1-1
pkg/hold/pds/events_test.go
···150150 testCID, _ := cid.Decode("bafyreib2rxk3rkhh5ylyxj3x3gathxt3s32qvwj2lf3qg4kmzr6b7teqke")
151151152152 // Broadcast 5 events (exceeds maxHistory of 3)
153153- for i := 0; i < 5; i++ {
153153+ for range 5 {
154154 event := &RepoEvent{
155155 NewRoot: testCID,
156156 Rev: "test-rev",
+3-3
pkg/hold/pds/layer_test.go
···377377 }
378378379379 // Create layer records for owner
380380- for i := 0; i < 3; i++ {
380380+ for i := range 3 {
381381 record := atproto.NewLayerRecord(
382382 "sha256:owner"+string(rune('a'+i)),
383383 1024*1024*100, // 100MB each
···454454 addCrewMemberWithBerth(t, pds, crewDID, "writer", []string{"blob:write"}, "")
455455456456 // Create layer records for crew member
457457- for i := 0; i < 2; i++ {
457457+ for i := range 2 {
458458 record := atproto.NewLayerRecord(
459459 "sha256:crew"+string(rune('a'+i)),
460460 1024*1024*50, // 50MB each
···685685686686 // Create multiple layer records with same digest (should be deduplicated)
687687 digest := "sha256:duplicatelayer"
688688- for i := 0; i < 5; i++ {
688688+ for i := range 5 {
689689 record := atproto.NewLayerRecord(
690690 digest,
691691 1024*1024*100, // 100MB
+3-3
pkg/hold/pds/records_test.go
···322322 defer ri.Close()
323323324324 // Add 5 records
325325- for i := 0; i < 5; i++ {
325325+ for i := range 5 {
326326 rkey := string(rune('a' + i))
327327 if err := ri.IndexRecord("io.atcr.hold.crew", rkey, "cid-"+rkey); err != nil {
328328 t.Fatalf("IndexRecord() error = %v", err)
···473473 defer ri.Close()
474474475475 // Add records to two collections
476476- for i := 0; i < 3; i++ {
476476+ for i := range 3 {
477477 ri.IndexRecord("io.atcr.hold.crew", string(rune('a'+i)), "cid1")
478478 }
479479- for i := 0; i < 5; i++ {
479479+ for i := range 5 {
480480 ri.IndexRecord("io.atcr.hold.captain", string(rune('a'+i)), "cid2")
481481 }
482482
+1-2
pkg/hold/pds/server.go
···103103 // Uses same database as carstore for simplicity
104104 var recordsIndex *RecordsIndex
105105 if dbPath != ":memory:" {
106106- recordsDbPath := dbPath + "/db.sqlite3"
107107- recordsIndex, err = NewRecordsIndex(recordsDbPath)
106106+ recordsIndex, err = NewRecordsIndex(dbPath + "/db.sqlite3")
108107 if err != nil {
109108 return nil, fmt.Errorf("failed to create records index: %w", err)
110109 }
+1-1
pkg/hold/pds/status_test.go
···232232}
233233234234func findSubstring(s, substr string) bool {
235235- for i := 0; i <= len(s)-len(substr); i++ {
235235+ for i := range len(s) - len(substr) + 1 {
236236 if s[i:i+len(substr)] == substr {
237237 return true
238238 }
+4-4
pkg/hold/pds/xrpc_test.go
···609609610610 // Note: Bootstrap already added 1 crew member
611611 // Add 4 more for a total of 5
612612- for i := 0; i < 4; i++ {
612612+ for i := range 4 {
613613 _, err := handler.pds.AddCrewMember(ctx, "did:plc:member"+string(rune(i+'0')), "reader", []string{"blob:read"})
614614 if err != nil {
615615 t.Fatalf("Failed to add crew member: %v", err)
···673673 holdDID := "did:web:hold.example.com"
674674675675 // Add crew members
676676- for i := 0; i < 3; i++ {
676676+ for i := range 3 {
677677 _, err := handler.pds.AddCrewMember(ctx, "did:plc:member"+string(rune(i+'0')), "reader", []string{"blob:read"})
678678 if err != nil {
679679 t.Fatalf("Failed to add crew member: %v", err)
···888888 holdDID := "did:web:hold.example.com"
889889890890 // Add 4 more crew members for total of 5
891891- for i := 0; i < 4; i++ {
891891+ for i := range 4 {
892892 _, err := handler.pds.AddCrewMember(ctx, fmt.Sprintf("did:plc:member%d", i), "reader", []string{"blob:read"})
893893 if err != nil {
894894 t.Fatalf("Failed to add crew member: %v", err)
···968968 holdDID := "did:web:hold.example.com"
969969970970 // Add crew members
971971- for i := 0; i < 3; i++ {
971971+ for i := range 3 {
972972 _, err := handler.pds.AddCrewMember(ctx, fmt.Sprintf("did:plc:member%d", i), "reader", []string{"blob:read"})
973973 if err != nil {
974974 t.Fatalf("Failed to add crew member: %v", err)
+1
pkg/hold/quota/config.go
···11+// Package quota provides storage quota management for hold services.
12package quota
2334import (
+2-2
pkg/logging/logger_test.go
···366366 defer slog.SetDefault(originalLogger)
367367368368 b.ResetTimer()
369369- for i := 0; i < b.N; i++ {
369369+ for range b.N {
370370 InitLogger("info")
371371 }
372372}
···376376 defer slog.SetDefault(originalLogger)
377377378378 b.ResetTimer()
379379- for i := 0; i < b.N; i++ {
379379+ for range b.N {
380380 cleanup := SetupTestLogger()
381381 cleanup()
382382 }