···3939 registry_domains: []
4040# Web UI settings.
4141ui:
4242- # SQLite database for OAuth sessions, stars, pull counts, and device approvals.
4242+ # SQLite/libSQL database for OAuth sessions, stars, pull counts, and device approvals.
4343 database_path: /var/lib/atcr/ui.db
4444+ # Visual theme name (e.g. "seamark"). Empty uses default atcr.io branding.
4545+ theme: ""
4646+ # libSQL sync URL (libsql://...). Works with Turso cloud or self-hosted libsql-server. Leave empty for local-only SQLite.
4747+ libsql_sync_url: ""
4848+ # Auth token for libSQL sync. Required if libsql_sync_url is set.
4949+ libsql_auth_token: ""
5050+ # How often to sync with remote libSQL server. Default: 60s.
5151+ libsql_sync_interval: 1m0s
4452# Health check and cache settings.
4553health:
4654 # How long to cache hold health check results.
+4
config-hold.example.yaml
···8686 defaults:
8787 # Tier assigned to new crew members who don't have an explicit tier.
8888 new_crew_tier: deckhand
8989+# Vulnerability scanner settings. Empty disables scanning.
9090+scanner:
9191+ # Shared secret for scanner WebSocket auth. Empty disables scanning.
9292+ secret: ""
···410410 if err := json.Unmarshal(recordData, &starRecord); err != nil {
411411 return fmt.Errorf("failed to unmarshal star: %w", err)
412412 }
413413+414414+ // Ensure the starred repository's owner exists in the users table
415415+ // (the starrer is already ensured by ProcessRecord, but the owner
416416+ // may not have been processed yet during backfill or live events)
417417+ if err := p.EnsureUser(ctx, starRecord.Subject.DID); err != nil {
418418+ return fmt.Errorf("failed to ensure star subject user: %w", err)
419419+ }
420420+413421 // Upsert the star record (idempotent - won't duplicate)
414422 // The DID here is the starrer (user who starred)
415423 // The subject contains the owner DID and repository
+10
pkg/appview/jetstream/processor_test.go
···425425 database := setupTestDB(t)
426426 defer database.Close()
427427428428+ // Insert test users (starrer + owner) so EnsureUser finds them without network calls
429429+ for _, did := range []string{"did:plc:starrer123", "did:plc:owner123"} {
430430+ _, err := database.Exec(
431431+ `INSERT INTO users (did, handle, pds_endpoint, last_seen) VALUES (?, ?, ?, ?)`,
432432+ did, did+".test", "https://pds.example.com", time.Now())
433433+ if err != nil {
434434+ t.Fatalf("Failed to insert test user %s: %v", did, err)
435435+ }
436436+ }
437437+428438 p := NewProcessor(database, false, nil)
429439 ctx := context.Background()
430440