From 4d9452bb75364ea24affdae2c6fb06a6b59143ab Mon Sep 17 00:00:00 2001 From: Evan Jarrett Date: Sat, 7 Feb 2026 23:28:42 -0600 Subject: [PATCH] update configs, fix foreign key issues --- config-appview.example.yaml | 10 +++++++++- config-hold.example.yaml | 4 ++++ deploy/upcloud/configs/appview.yaml.tmpl | 15 +++++++++++++++ deploy/upcloud/configs/cloudinit.sh.tmpl | 4 ++-- deploy/upcloud/configs/hold.yaml.tmpl | 15 +++++++++++++++ pkg/appview/jetstream/processor.go | 8 ++++++++ pkg/appview/jetstream/processor_test.go | 10 ++++++++++ 7 files changed, 63 insertions(+), 3 deletions(-) diff --git a/config-appview.example.yaml b/config-appview.example.yaml index 97c4b2a..b7cc175 100644 --- a/config-appview.example.yaml +++ b/config-appview.example.yaml @@ -39,8 +39,16 @@ server: registry_domains: [] # Web UI settings. ui: - # SQLite database for OAuth sessions, stars, pull counts, and device approvals. + # SQLite/libSQL database for OAuth sessions, stars, pull counts, and device approvals. database_path: /var/lib/atcr/ui.db + # Visual theme name (e.g. "seamark"). Empty uses default atcr.io branding. + theme: "" + # libSQL sync URL (libsql://...). Works with Turso cloud or self-hosted libsql-server. Leave empty for local-only SQLite. + libsql_sync_url: "" + # Auth token for libSQL sync. Required if libsql_sync_url is set. + libsql_auth_token: "" + # How often to sync with remote libSQL server. Default: 60s. + libsql_sync_interval: 1m0s # Health check and cache settings. health: # How long to cache hold health check results. diff --git a/config-hold.example.yaml b/config-hold.example.yaml index a134327..ed95ca9 100644 --- a/config-hold.example.yaml +++ b/config-hold.example.yaml @@ -86,3 +86,7 @@ quota: defaults: # Tier assigned to new crew members who don't have an explicit tier. new_crew_tier: deckhand +# Vulnerability scanner settings. Empty disables scanning. +scanner: + # Shared secret for scanner WebSocket auth. Empty disables scanning. + secret: "" diff --git a/deploy/upcloud/configs/appview.yaml.tmpl b/deploy/upcloud/configs/appview.yaml.tmpl index 2d04ac6..825d628 100644 --- a/deploy/upcloud/configs/appview.yaml.tmpl +++ b/deploy/upcloud/configs/appview.yaml.tmpl @@ -1,5 +1,12 @@ version: "0.1" log_level: info +log_shipper: + backend: "" + url: "" + batch_size: 100 + flush_interval: 5s + username: "" + password: "" server: addr: :5000 base_url: "https://seamark.dev" @@ -13,6 +20,12 @@ server: ui: database_path: "{{.BasePath}}/ui.db" theme: seamark + libsql_sync_url: "" + libsql_auth_token: "" + libsql_sync_interval: 1m0s +health: + cache_ttl: 15m0s + check_interval: 15m0s jetstream: url: wss://jetstream2.us-west.bsky.network/subscribe backfill_enabled: true @@ -20,6 +33,8 @@ jetstream: auth: key_path: "{{.BasePath}}/auth/private-key.pem" cert_path: "{{.BasePath}}/auth/private-key.crt" +credential_helper: + tangled_repo: "" legal: company_name: Seamark jurisdiction: State of Texas, United States diff --git a/deploy/upcloud/configs/cloudinit.sh.tmpl b/deploy/upcloud/configs/cloudinit.sh.tmpl index f21ace2..058aef8 100644 --- a/deploy/upcloud/configs/cloudinit.sh.tmpl +++ b/deploy/upcloud/configs/cloudinit.sh.tmpl @@ -43,8 +43,8 @@ fi npm ci go generate ./... CGO_ENABLED=1 go build \ - -ldflags="-s -w -linkmode external -extldflags '-static'" \ - -tags sqlite_omit_load_extension -trimpath \ + -ldflags="-s -w" \ + -trimpath \ -o bin/{{.BinaryName}} ./cmd/{{.BuildCmd}} # Service user & data dirs diff --git a/deploy/upcloud/configs/hold.yaml.tmpl b/deploy/upcloud/configs/hold.yaml.tmpl index a28e26f..816c9e7 100644 --- a/deploy/upcloud/configs/hold.yaml.tmpl +++ b/deploy/upcloud/configs/hold.yaml.tmpl @@ -1,5 +1,12 @@ version: "0.1" log_level: info +log_shipper: + backend: "" + url: "" + batch_size: 100 + flush_interval: 5s + username: "" + password: "" storage: access_key: "{{.S3AccessKey}}" secret_key: "{{.S3SecretKey}}" @@ -10,12 +17,18 @@ server: addr: :8080 public_url: "https://{{.HoldDomain}}" public: false + relay_endpoint: "" + read_timeout: 5m0s + write_timeout: 5m0s registration: owner_did: "did:plc:pddp4xt5lgnv2qsegbzzs4xg" allow_all_crew: true + profile_avatar_url: https://imgs.blue/evan.jarrett.net/1TpTOdtS60GdJWBYEqtK22y688jajbQ9a5kbYRFtwuqrkBAE enable_bluesky_posts: false + region: "" database: path: "{{.BasePath}}" + key_path: "" admin: enabled: true quota: @@ -28,3 +41,5 @@ quota: quota: 100GB defaults: new_crew_tier: deckhand +scanner: + secret: "" diff --git a/pkg/appview/jetstream/processor.go b/pkg/appview/jetstream/processor.go index 488b5f7..d491d63 100644 --- a/pkg/appview/jetstream/processor.go +++ b/pkg/appview/jetstream/processor.go @@ -410,6 +410,14 @@ func (p *Processor) ProcessStar(ctx context.Context, did string, recordData []by if err := json.Unmarshal(recordData, &starRecord); err != nil { return fmt.Errorf("failed to unmarshal star: %w", err) } + + // Ensure the starred repository's owner exists in the users table + // (the starrer is already ensured by ProcessRecord, but the owner + // may not have been processed yet during backfill or live events) + if err := p.EnsureUser(ctx, starRecord.Subject.DID); err != nil { + return fmt.Errorf("failed to ensure star subject user: %w", err) + } + // Upsert the star record (idempotent - won't duplicate) // The DID here is the starrer (user who starred) // The subject contains the owner DID and repository diff --git a/pkg/appview/jetstream/processor_test.go b/pkg/appview/jetstream/processor_test.go index a847e25..4949f43 100644 --- a/pkg/appview/jetstream/processor_test.go +++ b/pkg/appview/jetstream/processor_test.go @@ -425,6 +425,16 @@ func TestProcessStar(t *testing.T) { database := setupTestDB(t) defer database.Close() + // Insert test users (starrer + owner) so EnsureUser finds them without network calls + for _, did := range []string{"did:plc:starrer123", "did:plc:owner123"} { + _, err := database.Exec( + `INSERT INTO users (did, handle, pds_endpoint, last_seen) VALUES (?, ?, ?, ?)`, + did, did+".test", "https://pds.example.com", time.Now()) + if err != nil { + t.Fatalf("Failed to insert test user %s: %v", did, err) + } + } + p := NewProcessor(database, false, nil) ctx := context.Background()