back interdiff of round #1 and #0

refactor: move computed data code to function to simplify visuals #21

merged
opened by brookjeynes.dev targeting master from push-lokxzmtxxkxo
REVERTED
go.mod
··· 9 9 github.com/bluesky-social/indigo v0.0.0-20251003000214-3259b215110e 10 10 github.com/bluesky-social/jetstream v0.0.0-20250414024304-d17bd81a945e 11 11 github.com/carlmjohnson/versioninfo v0.22.5 12 - github.com/charmbracelet/log v0.4.2 13 12 github.com/go-chi/chi/v5 v5.2.1 14 13 github.com/gorilla/sessions v1.4.0 15 14 github.com/ipfs/go-cid v0.4.1 ··· 29 28 require ( 30 29 github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect 31 30 github.com/andybalholm/brotli v1.1.0 // indirect 32 - github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect 33 31 github.com/beorn7/perks v1.0.1 // indirect 34 32 github.com/cenkalti/backoff/v4 v4.3.0 // indirect 35 33 github.com/cespare/xxhash/v2 v2.3.0 // indirect 36 - github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect 37 - github.com/charmbracelet/lipgloss v1.1.0 // indirect 38 - github.com/charmbracelet/x/ansi v0.8.0 // indirect 39 - github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect 40 - github.com/charmbracelet/x/term v0.2.1 // indirect 41 34 github.com/cli/browser v1.3.0 // indirect 42 35 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect 43 36 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect 44 37 github.com/fatih/color v1.16.0 // indirect 45 38 github.com/felixge/httpsnoop v1.0.4 // indirect 46 39 github.com/fsnotify/fsnotify v1.7.0 // indirect 47 - github.com/go-logfmt/logfmt v0.6.0 // indirect 48 40 github.com/go-logr/logr v1.4.2 // indirect 49 41 github.com/go-logr/stdr v1.2.2 // indirect 50 42 github.com/goccy/go-json v0.10.2 // indirect ··· 77 69 github.com/lestrrat-go/httprc v1.0.4 // indirect 78 70 github.com/lestrrat-go/iter v1.0.2 // indirect 79 71 github.com/lestrrat-go/option v1.0.1 // indirect 80 - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect 81 72 github.com/mattn/go-colorable v0.1.13 // indirect 82 73 github.com/mattn/go-isatty v0.0.20 // indirect 83 - github.com/mattn/go-runewidth v0.0.16 // indirect 84 74 github.com/minio/sha256-simd v1.0.1 // indirect 85 75 github.com/mr-tron/base58 v1.2.0 // indirect 86 - github.com/muesli/termenv v0.16.0 // indirect 87 76 github.com/multiformats/go-base32 v0.1.0 // indirect 88 77 github.com/multiformats/go-base36 v0.2.0 // indirect 89 78 github.com/multiformats/go-multibase v0.2.0 // indirect ··· 96 85 github.com/prometheus/client_model v0.6.1 // indirect 97 86 github.com/prometheus/common v0.54.0 // indirect 98 87 github.com/prometheus/procfs v0.15.1 // indirect 99 - github.com/rivo/uniseg v0.4.7 // indirect 100 88 github.com/segmentio/asm v1.2.0 // indirect 101 89 github.com/spaolacci/murmur3 v1.1.0 // indirect 102 - github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect 103 90 gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect 104 91 gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect 105 92 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect ··· 110 97 go.uber.org/multierr v1.11.0 // indirect 111 98 go.uber.org/zap v1.26.0 // indirect 112 99 golang.org/x/crypto v0.40.0 // indirect 113 - golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect 114 100 golang.org/x/mod v0.26.0 // indirect 115 101 golang.org/x/sys v0.34.0 // indirect 116 102 golang.org/x/time v0.8.0 // indirect
REVERTED
go.sum
··· 5 5 github.com/a-h/templ v0.3.898/go.mod h1:oLBbZVQ6//Q6zpvSMPTuBK0F3qOtBdFBcGRspcT+VNQ= 6 6 github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= 7 7 github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= 8 - github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= 9 - github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= 10 8 github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 11 9 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 12 10 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= ··· 24 22 github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= 25 23 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= 26 24 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 27 - github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= 28 - github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= 29 - github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= 30 - github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= 31 - github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig= 32 - github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw= 33 - github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE= 34 - github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q= 35 - github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= 36 - github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= 37 - github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= 38 - github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= 39 25 github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo= 40 26 github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk= 41 27 github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= ··· 56 42 github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= 57 43 github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8= 58 44 github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= 59 - github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= 60 - github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= 61 45 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 62 46 github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= 63 47 github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= ··· 164 148 github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= 165 149 github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= 166 150 github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= 167 - github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= 168 - github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= 169 151 github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 170 152 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 171 153 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 172 154 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 173 155 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 174 156 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 175 - github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= 176 - github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 177 157 github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= 178 158 github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= 179 159 github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= 180 160 github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= 181 161 github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= 182 162 github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= 183 - github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= 184 - github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= 185 163 github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= 186 164 github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= 187 165 github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= ··· 218 196 github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= 219 197 github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE= 220 198 github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= 221 - github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 222 - github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= 223 - github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 224 199 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 225 200 github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= 226 201 github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= ··· 256 231 github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= 257 232 github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e h1:28X54ciEwwUxyHn9yrZfl5ojgF4CBNLWX7LR0rvBkf4= 258 233 github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= 259 - github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= 260 - github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= 261 234 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 262 235 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 263 236 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
REVERTED
internal/server/log/log.go
··· 4 4 "context" 5 5 "log/slog" 6 6 "os" 7 - 8 - "github.com/charmbracelet/log" 9 7 ) 10 8 9 + // NewHandler sets up a new slog.Handler with the service name as an attribute 11 10 func NewHandler(name string) slog.Handler { 11 + handler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{}) 12 + 13 + var attrs []slog.Attr 14 + attrs = append(attrs, slog.Attr{Key: "service", Value: slog.StringValue(name)}) 15 + handler.WithAttrs(attrs) 16 + return handler 12 - return log.NewWithOptions(os.Stderr, log.Options{ 13 - ReportTimestamp: true, 14 - Prefix: name, 15 - Level: log.DebugLevel, 16 - }) 17 17 } 18 18 19 19 func New(name string) *slog.Logger { ··· 45 45 46 46 return slog.Default() 47 47 } 48 - 49 - // Sublogger derives a new logger from an existing one by appending a suffix to 50 - // its prefix. 51 - func SubLogger(base *slog.Logger, suffix string) *slog.Logger { 52 - // Try to get the underlying charmbracelet logger. 53 - if cl, ok := base.Handler().(*log.Logger); ok { 54 - prefix := cl.GetPrefix() 55 - if prefix != "" { 56 - prefix = prefix + "/" + suffix 57 - } else { 58 - prefix = suffix 59 - } 60 - return slog.New(NewHandler(prefix)) 61 - } 62 - 63 - // Fallback to no known handler type. 64 - return slog.New(NewHandler(suffix)) 65 - }
REVERTED
internal/db/db.go
··· 4 4 "context" 5 5 "database/sql" 6 6 "fmt" 7 - "log/slog" 8 7 "strings" 9 8 10 9 _ "github.com/mattn/go-sqlite3" ··· 12 11 13 12 type DB struct { 14 13 *sql.DB 15 - logger *slog.Logger 16 14 } 17 15 18 16 type Execer interface { ··· 26 24 PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) 27 25 } 28 26 27 + func Make(dbPath string) (*DB, error) { 29 - func Make(ctx context.Context, dbPath string, logger *slog.Logger) (*DB, error) { 30 28 opts := []string{ 31 29 "_foreign_keys=1", 32 30 "_journal_mode=WAL", ··· 39 37 return nil, fmt.Errorf("failed to open db: %w", err) 40 38 } 41 39 40 + ctx := context.Background() 41 + 42 42 conn, err := db.Conn(ctx) 43 43 if err != nil { 44 44 return nil, err ··· 231 231 return nil, fmt.Errorf("failed to execute db create statement: %w", err) 232 232 } 233 233 234 + return &DB{db}, nil 234 - return &DB{ 235 - db, 236 - logger, 237 - }, nil 238 235 }
REVERTED
internal/server/handlers/study-session.go
··· 3 3 import ( 4 4 "errors" 5 5 "fmt" 6 + "log" 6 7 "net/http" 7 8 "strconv" 8 9 "time" ··· 116 117 } 117 118 118 119 func (h *Handler) HandleStudySessionFeed(w http.ResponseWriter, r *http.Request) { 119 - l := h.Logger.With("handler", "HandleStudySessionFeed") 120 - 121 120 isFriends, err := strconv.ParseBool(r.URL.Query().Get("friends")) 122 121 if err != nil { 122 + log.Println("failed to parse friends value:", err) 123 - l.Error("failed to parse friends value", "err", err) 124 123 isFriends = false 125 124 } 126 125 ··· 130 129 } 131 130 page, err := strconv.ParseInt(pageStr, 10, 64) 132 131 if err != nil { 132 + log.Println("failed to parse page value:", err) 133 - l.Error("failed to parse page value", "err", err) 134 133 page = 1 135 134 } 136 135 if page == 0 { ··· 149 148 if !isFriends { 150 149 feed, err = db.GetStudySessionFeed(h.Db, pageSize+1, int(offset)) 151 150 if err != nil { 151 + log.Println("failed to get global feed:", err) 152 - l.Error("failed to get global feed", "err", err) 153 152 htmx.HxError(w, http.StatusInternalServerError, "Failed to get global study session feed, try again later.") 154 153 return 155 154 } 156 155 err = h.GetBskyProfileHydratedSessionFeed(feed) 157 156 if err != nil { 157 + log.Println("failed to hydrate bsky profiles:", err) 158 - l.Error("failed to hydrate bsky profiles", "err", err) 159 158 htmx.HxError(w, http.StatusInternalServerError, "Failed to get global study session feed, try again later.") 160 159 return 161 160 } 162 161 } else { 163 162 if fetchUserError != nil { 163 + log.Println("failed to get logged-in user:", err) 164 - l.Error("failed to get logged-in user", "err", err) 165 164 htmx.HxRedirect(w, "/login") 166 165 return 167 166 } 168 167 169 168 feed, err = db.GetFriendsStudySessionFeed(h.Db, user.Did, pageSize+1, int(offset)) 170 169 if err != nil { 170 + log.Println("failed to get global feed:", err) 171 - l.Error("failed to get global feed", "err", err) 172 171 htmx.HxError(w, http.StatusInternalServerError, "Failed to get global study session feed, try again later.") 173 172 return 174 173 } 175 174 err = h.GetBskyProfileHydratedSessionFeed(feed) 176 175 if err != nil { 176 + log.Println("failed to hydrate bsky profiles:", err) 177 - l.Error("failed to hydrate bsky profiles", "err", err) 178 177 htmx.HxError(w, http.StatusInternalServerError, "Failed to get global study session feed, try again later.") 179 178 return 180 179 } ··· 182 181 183 182 feed, err = ApplyPendingChanges(h, w, r, feed, PendingStudySessionCreation, PendingStudySessionUpdates, PendingStudySessionDeletion) 184 183 if err != nil { 184 + log.Printf("failed to save yoten-session after processing pending changes: %v", err) 185 - l.Error("failed to save yoten-session after processing pending changes", "err", err) 186 185 } 187 186 188 187 nextPage := 0 ··· 201 200 } 202 201 203 202 func (h *Handler) HandleEditStudySessionPage(w http.ResponseWriter, r *http.Request) { 204 - l := h.Logger.With("handler", "HandleEditStudySessionPage") 205 - 206 203 client, err := h.Oauth.AuthorizedClient(r) 207 204 if err != nil { 205 + log.Println("failed to get authorized client:", err) 208 - l.Error("failed to get authorized client", "err", err) 209 206 htmx.HxRedirect(w, "/login") 210 207 return 211 208 } 212 209 213 210 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 214 211 if err != nil { 212 + log.Println("failed to get logged-in user:", err) 215 - l.Error("failed to get logged-in user", "err", err) 216 213 htmx.HxRedirect(w, "/login") 217 214 return 218 215 } ··· 220 217 rkey := chi.URLParam(r, "rkey") 221 218 studySession, err := db.GetStudySessionByRkey(h.Db, user.Did, rkey) 222 219 if err != nil { 220 + log.Println("failed to get study session from db:", err) 223 - l.Error("failed to get study session from db", "err", err) 224 221 htmx.HxError(w, http.StatusInternalServerError, "Failed to update study session, try again later.") 225 222 return 226 223 } 227 224 228 225 if user.Did != studySession.Did { 226 + log.Printf("user '%s' does not own record '%s'", user.Did, studySession.Rkey) 229 - l.Error("user does not own record", "did", user.Did, "sessionDid", studySession.Did) 230 227 htmx.HxError(w, http.StatusUnauthorized, "You do not have permissions to edit this study session.") 231 228 return 232 229 } ··· 235 232 case http.MethodGet: 236 233 userDefinedActivities, err := db.GetActivitiesByDid(h.Db, user.Did) 237 234 if err != nil { 235 + log.Println("failed to get user-defined activities:", err) 238 - l.Error("failed to get user-defined activities", "err", err) 239 236 } 240 237 241 238 resources, err := db.GetResourcesByDid(h.Db, user.Did) 242 239 if err != nil { 240 + log.Println("failed to get user-defined resources:", err) 243 - l.Error("failed to get user-defined resources", "err", err) 244 241 } 245 242 246 243 preDefinedActivities, err := db.GetPredefinedActivities(h.Db) 247 244 if err != nil { 245 + log.Println("failed to get pre-defined activities:", err) 248 - l.Error("failed to get pre-defined activities", "err", err) 249 246 } 250 247 251 248 currentResource := studySession.Resource ··· 270 267 271 268 languages, err := db.GetProfileLanguages(h.Db, user.Did) 272 269 if err != nil { 270 + log.Println("failed to fetch profile languages:", err) 273 - l.Error("failed to fetch profile languages", "err", err) 274 271 } 275 272 276 273 views.EditStudySessionPage(views.EditStudySessionPageParams{ ··· 283 280 case http.MethodPost: 284 281 updatedStudySession, err := h.parseStudySessionForm(r) 285 282 if err != nil { 283 + log.Println("invalid study session form:", err) 286 - l.Error("invalid study session form", "err", err) 287 284 htmx.HxError(w, http.StatusBadRequest, "Failed to update study session, ensure all data is valid.") 288 285 return 289 286 } ··· 292 289 updatedStudySession.CreatedAt = studySession.CreatedAt 293 290 294 291 if err := db.ValidateStudySession(updatedStudySession); err != nil { 292 + log.Println("invalid study session:", err) 295 - l.Error("invalid study session", "err", err) 296 293 switch { 297 294 case errors.Is(err, db.ErrSessionDescriptionTooLong): 298 295 htmx.HxError(w, http.StatusBadRequest, "Study session description cannot be more than 256 characters.") ··· 361 358 SwapRecord: cid, 362 359 }) 363 360 if err != nil { 361 + log.Println("failed to update study session record:", err) 364 - l.Error("failed to update study session record", "err", err) 365 362 htmx.HxError(w, http.StatusInternalServerError, "Failed to update study session, try again later.") 366 363 return 367 364 } 368 365 369 366 err = SavePendingUpdate(h, w, r, PendingStudySessionUpdates, updatedStudySession) 370 367 if err != nil { 368 + log.Printf("failed to save yoten-session to add pending study session updates: %v", err) 371 - l.Error("failed to save yoten-session to add pending study session updates", "err", err) 372 369 } 373 370 374 371 if !h.Config.Core.Dev { ··· 380 377 Set("rkey", rkey), 381 378 }) 382 379 if err != nil { 380 + log.Println("failed to enqueue posthog event:", err) 383 - l.Error("failed to enqueue posthog event", "err", err) 384 381 } 385 382 } 386 383 ··· 389 386 } 390 387 391 388 func (h *Handler) HandleNewStudySessionPage(w http.ResponseWriter, r *http.Request) { 392 - l := h.Logger.With("handler", "HandleNewStudySessionPage") 393 - 394 389 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 395 390 if err != nil { 391 + log.Println("failed to get logged-in user:", err) 396 - l.Error("failed to get logged-in user", "err", err) 397 392 htmx.HxRedirect(w, "/login") 398 393 return 399 394 } 400 395 401 396 client, err := h.Oauth.AuthorizedClient(r) 402 397 if err != nil { 398 + log.Println("failed to get authorized client:", err) 403 - l.Error("failed to get authorized client", "err", err) 404 399 htmx.HxRedirect(w, "/login") 405 400 return 406 401 } ··· 409 404 case http.MethodGet: 410 405 profile, err := db.GetProfile(h.Db, user.Did) 411 406 if err != nil { 407 + log.Printf("failed to find %s in db: %s", user.Did, err) 412 - l.Error("failed to find user in db", "did", user.Did, "err", err) 413 408 htmx.HxError(w, http.StatusNotFound, "Failed to find user.") 414 409 return 415 410 } 416 411 417 412 userDefinedActivities, err := db.GetActivitiesByDid(h.Db, user.Did) 418 413 if err != nil { 414 + log.Println("failed to get user-defined activities:", err) 419 - l.Error("failed to get user-defined activities", "err", err) 420 415 } 421 416 preDefinedActivities, err := db.GetPredefinedActivities(h.Db) 422 417 if err != nil { 418 + log.Println("failed to get pre-defined activities:", err) 423 - l.Error("failed to get pre-defined activities", "err", err) 424 419 } 425 420 activeActivities := utils.Filter(userDefinedActivities, func(activity db.Activity) bool { 426 421 return activity.Status != db.Deleted ··· 429 424 430 425 resources, err := db.GetResourcesByDid(h.Db, user.Did) 431 426 if err != nil { 427 + log.Println("failed to get user-defined resources:", err) 432 - l.Error("failed to get user-defined resources", "err", err) 433 428 } 434 429 activeResources := utils.Filter(resources, func(resource db.Resource) bool { 435 430 return resource.Status != db.Deleted ··· 445 440 case http.MethodPost: 446 441 newStudySession, err := h.parseStudySessionForm(r) 447 442 if err != nil { 443 + log.Println("invalid study session form:", err) 448 - l.Error("invalid study session form", "err", err) 449 444 htmx.HxError(w, http.StatusBadRequest, "Failed to update study session, ensure all data is valid.") 450 445 return 451 446 } ··· 464 459 } 465 460 466 461 if err := db.ValidateStudySession(newStudySession); err != nil { 462 + log.Println("invalid study session:", err) 467 - l.Error("invalid study session", "err", err) 468 463 switch { 469 464 case errors.Is(err, db.ErrSessionDescriptionTooLong): 470 465 htmx.HxError(w, http.StatusBadRequest, "Study session description cannot be more than 256 characters.") ··· 526 521 }, 527 522 }) 528 523 if err != nil { 524 + log.Println("failed to create study session record:", err) 529 - l.Error("failed to create study session record", "err", err) 530 525 htmx.HxError(w, http.StatusInternalServerError, "Failed to create study session, try again later.") 531 526 return 532 527 } 533 528 534 529 err = SavePendingCreate(h, w, r, PendingStudySessionCreation, newStudySession) 535 530 if err != nil { 531 + log.Printf("failed to save yoten-session to add pending study session creation: %v", err) 536 - l.Error("failed to save yoten-session to add pending study session creation", "err", err) 537 532 } 538 533 539 534 if !h.Config.Core.Dev { ··· 550 545 Set("date_is_today", newStudySession.Date.Truncate(24*time.Hour).Equal(time.Now().UTC().In(loc).Truncate(24*time.Hour))), 551 546 }) 552 547 if err != nil { 548 + log.Println("failed to enqueue posthog event:", err) 553 - l.Error("failed to enqueue posthog event", "err", err) 554 549 } 555 550 } 556 551 ··· 559 554 } 560 555 561 556 func (h *Handler) HandleDeleteStudySession(w http.ResponseWriter, r *http.Request) { 562 - l := h.Logger.With("handler", "HandleDeleteStudySession") 563 - 564 557 user := h.Oauth.GetUser(r) 565 558 if user == nil { 559 + log.Println("failed to get logged-in user") 566 - l.Error("failed to get logged-in user") 567 560 htmx.HxRedirect(w, "/login") 568 561 return 569 562 } 570 563 571 564 client, err := h.Oauth.AuthorizedClient(r) 572 565 if err != nil { 566 + log.Println("failed to get authorized client:", err) 573 - l.Error("failed to get authorized client", "err", err) 574 567 htmx.HxError(w, http.StatusUnauthorized, "Failed to delete study session, try again later.") 575 568 return 576 569 } ··· 579 572 case http.MethodDelete: 580 573 err := r.ParseForm() 581 574 if err != nil { 575 + log.Println("failed to parse study session delete form:", err) 582 - l.Error("failed to parse study session delete form", "err", err) 583 576 htmx.HxError(w, http.StatusBadRequest, "Failed to delete study session, try again later.") 584 577 return 585 578 } ··· 587 580 rkey := chi.URLParam(r, "rkey") 588 581 studySession, err := db.GetStudySessionByRkey(h.Db, user.Did, rkey) 589 582 if err != nil { 583 + log.Println("failed to get study session from db:", err) 590 - l.Error("failed to get study session from db", "err", err) 591 584 htmx.HxError(w, http.StatusInternalServerError, "Failed to delete study session, try again later.") 592 585 return 593 586 } 594 587 595 588 if user.Did != studySession.Did { 589 + log.Println("failed to delete study session: user does not own record") 596 - l.Error("user does not own record", "did", user.Did, "sessionDid", studySession.Did) 597 590 htmx.HxError(w, http.StatusUnauthorized, "Failed to delete study session, try again later.") 598 591 return 599 592 } ··· 604 597 Rkey: rkey, 605 598 }) 606 599 if err != nil { 600 + log.Println("failed to delete study session from PDS:", err) 607 - l.Error("failed to delete study session from PDS", "err", err) 608 601 htmx.HxError(w, http.StatusInternalServerError, "Failed to delete study session, try again later.") 609 602 return 610 603 } 611 604 612 605 err = SavePendingDelete(h, w, r, PendingStudySessionDeletion, studySession) 613 606 if err != nil { 607 + log.Printf("failed to save yoten-session to add pending study session deletion: %v", err) 614 - l.Error("failed to save yoten-session to add pending study session deletion", "err", err) 615 608 } 616 609 617 610 if !h.Config.Core.Dev { ··· 624 617 Set("session_age_seconds", time.Since(studySession.CreatedAt).Seconds()), 625 618 }) 626 619 if err != nil { 620 + log.Println("failed to enqueue posthog event:", err) 627 - l.Error("failed to enqueue posthog event", "err", err) 628 621 } 629 622 } 630 623 ··· 651 644 } 652 645 653 646 func (h *Handler) HandleStudySessionPage(w http.ResponseWriter, r *http.Request) { 654 - l := h.Logger.With("handler", "HandleStudySessionPage") 655 - 656 647 user, _ := bsky.GetUserWithBskyProfile(h.Oauth, r) 657 648 didOrHandle := chi.URLParam(r, "user") 658 649 if didOrHandle == "" { ··· 670 661 671 662 studySession, err := db.GetStudySessionByRkey(h.Db, ident.DID.String(), rkey) 672 663 if err != nil { 664 + log.Println("failed to retrieve study session:", err) 673 - l.Error("failed to retrieve study session", "err", err) 674 665 htmx.HxError(w, http.StatusInternalServerError, "Failed to retrieve study session, try again later.") 675 666 return 676 667 } 677 668 678 669 bskyProfile, err := bsky.GetBskyProfile(ident.DID.String()) 679 670 if err != nil { 671 + log.Println("failed to retrieve bsky profile for study session:", err) 680 - l.Error("failed to retrieve bsky profile for study session", "err", err) 681 672 htmx.HxError(w, http.StatusInternalServerError, "Failed to retrieve bsky profile, try again later.") 682 673 return 683 674 } 684 675 685 676 profile, err := db.GetProfile(h.Db, ident.DID.String()) 686 677 if err != nil { 678 + log.Println("failed to retrieve profile for study session:", err) 687 - l.Error("failed to retrieve profile for study session", "err", err) 688 679 htmx.HxError(w, http.StatusInternalServerError, "Failed to retrieve profile, try again later.") 689 680 return 690 681 } ··· 707 698 } 708 699 709 700 func (h *Handler) HandleStudySessionPageCommentFeed(w http.ResponseWriter, r *http.Request) { 710 - l := h.Logger.With("handler", "HandleStudySessionPageCommentFeed") 711 - 712 701 user, _ := bsky.GetUserWithBskyProfile(h.Oauth, r) 713 702 714 703 didOrHandle := chi.URLParam(r, "user") ··· 732 721 } 733 722 page, err := strconv.ParseInt(pageStr, 10, 64) 734 723 if err != nil { 724 + log.Println("failed to parse page value:", err) 735 - l.Error("failed to parse page value", "err", err) 736 725 page = 1 737 726 } 738 727 if page == 0 { ··· 744 733 745 734 commentFeed, err := db.GetCommentsForSession(h.Db, studySessionUri.String(), pageSize+1, int(offset)) 746 735 if err != nil { 736 + log.Println("failed to get comment feed:", err) 747 - l.Error("failed to get comment feed", "err", err) 748 737 htmx.HxError(w, http.StatusInternalServerError, "Failed to get comment feed, try again later.") 749 738 return 750 739 } ··· 780 769 781 770 populatedCommentFeed, err := h.BuildCommentFeed(finalFeed) 782 771 if err != nil { 772 + log.Println("failed to populate comment feed:", err) 783 - l.Error("failed to populate comment feed", "err", err) 784 773 htmx.HxError(w, http.StatusInternalServerError, "Failed to get comment feed, try again later.") 785 774 return 786 775 }
REVERTED
internal/server/handlers/resource.go
··· 3 3 import ( 4 4 "errors" 5 5 "fmt" 6 + "log" 6 7 "net/http" 7 8 "time" 8 9 ··· 62 63 } 63 64 64 65 func (h *Handler) HandleNewResourcePage(w http.ResponseWriter, r *http.Request) { 65 - l := h.Logger.With("handler", "HandleNewResourcePage") 66 - 67 66 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 68 67 if err != nil { 68 + log.Println("failed to get logged-in user:", err) 69 - l.Error("failed to get logged-in user", "err", err) 70 69 htmx.HxRedirect(w, "/login") 71 70 return 72 71 } ··· 80 79 case http.MethodPost: 81 80 client, err := h.Oauth.AuthorizedClient(r) 82 81 if err != nil { 82 + log.Println("failed to get authorized client:", err) 83 - l.Error("failed to get authorized client", "err", err) 84 83 htmx.HxRedirect(w, "/login") 85 84 return 86 85 } 87 86 88 87 newResource, err := parseResourceForm(r) 89 88 if err != nil { 89 + log.Println("invalid resource form:", err) 90 - l.Error("invalid resource form", "err", err) 91 90 htmx.HxError(w, http.StatusBadRequest, "Failed to create resource, ensure all fields contain valid data.") 92 91 return 93 92 } ··· 96 95 newResource.CreatedAt = time.Now().UTC() 97 96 98 97 if err := db.ValidateResource(newResource); err != nil { 98 + log.Println("invalid resource definition:", err) 99 - l.Error("invalid resource definition", "err", err) 100 99 switch { 101 100 case errors.Is(err, db.ErrResourceTitleEmpty): 102 101 htmx.HxError(w, http.StatusBadRequest, "Resource must have a title.") ··· 119 118 if newResource.Link != nil { 120 119 linkCheckResult := google.CheckResourceLinkSafety(*newResource.Link) 121 120 if linkCheckResult.Err != nil { 121 + log.Println("invalid resource definition:", linkCheckResult.Err) 122 - l.Error("invalid resource definition", "err", linkCheckResult.Err) 123 122 switch { 124 123 case errors.Is(linkCheckResult.Err, google.ErrResourceLinkSketchy): 125 124 if !h.Config.Core.Dev { ··· 187 186 }, 188 187 }) 189 188 if err != nil { 189 + log.Println("failed to create resource record:", err) 190 - l.Error("failed to create resource record", "err", err) 191 190 htmx.HxError(w, http.StatusInternalServerError, "Failed to create resource, try again later.") 192 191 return 193 192 } 194 193 195 194 err = SavePendingCreate(h, w, r, PendingResourceCreation, newResource) 196 195 if err != nil { 196 + log.Printf("failed to save yoten-session to add pending resource creation: %v", err) 197 - l.Error("failed to save yoten-session to add pending resource creation", "err", err) 198 197 } 199 198 200 199 if !h.Config.Core.Dev { ··· 210 209 Set("link_provided", newResource.Link != nil), 211 210 }) 212 211 if err != nil { 212 + log.Println("failed to enqueue posthog event:", err) 213 - l.Error("failed to enqueue posthog event", "err", err) 214 213 } 215 214 } 216 215 ··· 219 218 } 220 219 221 220 func (h *Handler) HandleDeleteResource(w http.ResponseWriter, r *http.Request) { 222 - l := h.Logger.With("handler", "HandleDeleteResource") 223 - 224 221 user := h.Oauth.GetUser(r) 225 222 if user == nil { 223 + log.Println("failed to get logged-in user") 226 - l.Error("failed to get logged-in user") 227 224 htmx.HxRedirect(w, "/login") 228 225 return 229 226 } 230 227 client, err := h.Oauth.AuthorizedClient(r) 231 228 if err != nil { 229 + log.Println("failed to get authorized client:", err) 232 - l.Error("failed to get authorized client", "err", err) 233 230 htmx.HxError(w, http.StatusUnauthorized, "Failed to delete resource, try again later.") 234 231 return 235 232 } ··· 239 236 rkey := chi.URLParam(r, "rkey") 240 237 resource, err := db.GetResourceByRkey(h.Db, user.Did, rkey) 241 238 if err != nil { 239 + log.Println("failed to get resource from db:", err) 242 - l.Error("failed to get resource from db", "err", err) 243 240 htmx.HxError(w, http.StatusInternalServerError, "Failed to delete resource, try again later.") 244 241 return 245 242 } 246 243 247 244 if user.Did != resource.Did { 245 + log.Printf("user '%s' does not own record '%s'", user.Did, rkey) 248 - l.Error("user does not own record", "did", user.Did, "resourceDid", resource.Did) 249 246 htmx.HxError(w, http.StatusUnauthorized, "You do not have permissions to delete this resource.") 250 247 return 251 248 } ··· 256 253 Rkey: resource.Rkey, 257 254 }) 258 255 if err != nil { 256 + log.Println("failed to delete resource from PDS:", err) 259 - l.Error("failed to delete resource from PDS", "err", err) 260 257 htmx.HxError(w, http.StatusInternalServerError, "Failed to delete resource, try again later.") 261 258 return 262 259 } 263 260 264 261 err = SavePendingDelete(h, w, r, PendingResourceDeletion, resource) 265 262 if err != nil { 263 + log.Printf("failed to save yoten-session to add pending resource deletion: %v", err) 266 - l.Error("failed to save yoten-session to add pending resource deletion", "err", err) 267 264 } 268 265 269 266 if !h.Config.Core.Dev { ··· 275 272 Set("resource_type", resource.Type), 276 273 }) 277 274 if err != nil { 275 + log.Println("failed to enqueue posthog event:", err) 278 - l.Error("failed to enqueue posthog event", "err", err) 279 276 } 280 277 } 281 278 ··· 284 281 } 285 282 286 283 func (h *Handler) HandleEditResourcePage(w http.ResponseWriter, r *http.Request) { 287 - l := h.Logger.With("handler", "HandleEditResourcePage") 288 - 289 284 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 290 285 if err != nil { 286 + log.Println("failed to get logged-in user:", err) 291 - l.Error("failed to get logged-in user", "err", err) 292 287 htmx.HxRedirect(w, "/login") 293 288 return 294 289 } ··· 296 291 rkey := chi.URLParam(r, "rkey") 297 292 resource, err := db.GetResourceByRkey(h.Db, user.Did, rkey) 298 293 if err != nil { 294 + log.Println("failed to get resource from db:", err) 299 - l.Error("failed to get resource from db", "err", err) 300 295 htmx.HxError(w, http.StatusInternalServerError, "Failed to update resource, try again later.") 301 296 return 302 297 } 303 298 304 299 if user.Did != resource.Did { 300 + log.Printf("user '%s' does not own record '%s'", user.Did, rkey) 305 - l.Error("user does not own record", "did", user.Did, "resourceDid", resource.Did) 306 301 htmx.HxError(w, http.StatusUnauthorized, "You do not have permissions to edit this resource.") 307 302 return 308 303 } ··· 317 312 case http.MethodPost: 318 313 client, err := h.Oauth.AuthorizedClient(r) 319 314 if err != nil { 315 + log.Println("failed to get authorized client:", err) 320 - l.Error("failed to get authorized client", "err", err) 321 316 htmx.HxRedirect(w, "/login") 322 317 return 323 318 } 324 319 325 320 updatedResource, err := parseResourceForm(r) 326 321 if err != nil { 322 + log.Println("invalid resource form:", err) 327 - l.Error("invalid resource form", "err", err) 328 323 htmx.HxError(w, http.StatusBadRequest, "Failed to create resource, ensure all fields contain valid data.") 329 324 return 330 325 } ··· 333 328 updatedResource.CreatedAt = resource.CreatedAt 334 329 335 330 if err := db.ValidateResource(updatedResource); err != nil { 331 + log.Println("invalid resource definition:", err) 336 - l.Error("invalid resource definition", "err", err) 337 332 switch { 338 333 case errors.Is(err, db.ErrResourceTitleEmpty): 339 334 htmx.HxError(w, http.StatusBadRequest, "Resource must have a title.") ··· 357 352 if updatedResource.Link != nil && (resource.Link == nil || *updatedResource.Link != *resource.Link) { 358 353 linkCheckResult := google.CheckResourceLinkSafety(*updatedResource.Link) 359 354 if linkCheckResult.Err != nil { 355 + log.Println("invalid resource definition:", linkCheckResult.Err) 360 - l.Error("invalid resource link", "link", resource.Link, "threatType", linkCheckResult.ThreatType, "err", linkCheckResult.Err) 361 356 switch { 362 357 case errors.Is(linkCheckResult.Err, google.ErrResourceLinkSketchy): 363 358 if !h.Config.Core.Dev { ··· 432 427 SwapRecord: cid, 433 428 }) 434 429 if err != nil { 430 + log.Println("failed to update resource record:", err) 435 - l.Error("failed to update resource record", "err", err) 436 431 htmx.HxError(w, http.StatusInternalServerError, "Failed to update resource, try again later.") 437 432 return 438 433 } 439 434 440 435 err = SavePendingUpdate(h, w, r, PendingResourceUpdates, updatedResource) 441 436 if err != nil { 437 + log.Printf("failed to save yoten-session to add pending resource updates: %v", err) 442 - l.Error("failed to save yoten-session to add pending resource updates", "err", err) 443 438 } 444 439 445 440 if !h.Config.Core.Dev { ··· 455 450 Set("link_provided", updatedResource.Link != nil), 456 451 }) 457 452 if err != nil { 453 + log.Println("failed to enqueue posthog event:", err) 458 - l.Error("failed to enqueue posthog event", "err", err) 459 454 } 460 455 } 461 456
REVERTED
internal/server/handlers/comment.go
··· 1 1 package handlers 2 2 3 3 import ( 4 + "log" 4 5 "net/http" 5 6 "strings" 6 7 "time" ··· 22 23 ) 23 24 24 25 func (h *Handler) HandleNewComment(w http.ResponseWriter, r *http.Request) { 25 - l := h.Logger.With("handler", "HandleNewComment") 26 - 27 26 client, err := h.Oauth.AuthorizedClient(r) 28 27 if err != nil { 28 + log.Println("failed to get authorized client:", err) 29 - l.Error("failed to get authorized client", "err", err) 30 29 htmx.HxRedirect(w, "/login") 31 30 return 32 31 } 33 32 34 33 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 35 34 if err != nil { 35 + log.Println("failed to get logged-in user:", err) 36 - l.Error("failed to get logged-in user", "err", err) 37 36 htmx.HxRedirect(w, "/login") 38 37 return 39 38 } 40 39 41 40 profile, err := db.GetProfile(h.Db, user.Did) 42 41 if err != nil { 42 + log.Println("failed to get logged-in user:", err) 43 - l.Error("failed to get logged-in user", "err", err) 44 43 htmx.HxRedirect(w, "/login") 45 44 return 46 45 } 47 46 48 47 err = r.ParseForm() 49 48 if err != nil { 49 + log.Println("invalid comment form:", err) 50 - l.Error("invalid comment form", "err", err) 51 50 htmx.HxError(w, http.StatusBadRequest, "Unable to process comment, please try again later.") 52 51 return 53 52 } 54 53 55 54 commentBody := r.FormValue("comment") 56 55 if len(strings.TrimSpace(commentBody)) == 0 { 56 + log.Println("invalid comment form: missing comment body") 57 - l.Error("invalid comment form: missing comment body") 58 57 htmx.HxError(w, http.StatusBadRequest, "Comment cannot be empty.") 59 58 return 60 59 } 61 60 62 61 studySessionUri := r.FormValue("study_session_uri") 63 62 if len(studySessionUri) == 0 { 63 + log.Println("invalid comment form: missing study session Uri") 64 - l.Error("invalid comment form: missing study session Uri") 65 64 htmx.HxError(w, http.StatusBadRequest, "Unable to create comment, please try again later.") 66 65 return 67 66 } ··· 101 100 }, 102 101 }) 103 102 if err != nil { 103 + log.Println("failed to create comment record:", err) 104 - l.Error("failed to create comment record", "err", err) 105 104 htmx.HxError(w, http.StatusInternalServerError, "Failed to create comment, try again later.") 106 105 return 107 106 } ··· 122 121 123 122 err = h.Posthog.Enqueue(event) 124 123 if err != nil { 124 + log.Println("failed to enqueue posthog event:", err) 125 - l.Error("failed to enqueue posthog event", "err", err) 126 125 } 127 126 } 128 127 ··· 154 153 } 155 154 156 155 func (h *Handler) HandleDeleteComment(w http.ResponseWriter, r *http.Request) { 157 - l := h.Logger.With("handler", "HandleDeleteComment") 158 - 159 156 user := h.Oauth.GetUser(r) 160 157 if user == nil { 158 + log.Println("failed to get logged-in user") 161 - l.Error("failed to get logged-in user") 162 159 htmx.HxRedirect(w, "/login") 163 160 return 164 161 } 165 162 client, err := h.Oauth.AuthorizedClient(r) 166 163 if err != nil { 164 + log.Println("failed to get authorized client:", err) 167 - l.Error("failed to get authorized client", "err", err) 168 165 htmx.HxRedirect(w, "/login") 169 166 return 170 167 } ··· 174 171 rkey := chi.URLParam(r, "rkey") 175 172 comment, err := db.GetCommentByRkey(h.Db, user.Did, rkey) 176 173 if err != nil { 174 + log.Println("failed to get comment from db:", err) 177 - l.Error("failed to get comment from db", "err", err) 178 175 htmx.HxError(w, http.StatusInternalServerError, "Failed to delete comment, try again later.") 179 176 return 180 177 } 181 178 182 179 if user.Did != comment.Did { 180 + log.Printf("user '%s' does not own record '%s'", user.Did, rkey) 183 - l.Error("user does not own record", "did", user.Did, "commentDid", comment.Did) 184 181 htmx.HxError(w, http.StatusUnauthorized, "You do not have permissions to delete this comment.") 185 182 return 186 183 } ··· 191 188 Rkey: comment.Rkey, 192 189 }) 193 190 if err != nil { 191 + log.Println("failed to delete comment from PDS:", err) 194 - l.Error("failed to delete comment from PDS", "err", err) 195 192 htmx.HxError(w, http.StatusInternalServerError, "Failed to delete comment, try again later.") 196 193 return 197 194 } ··· 212 209 213 210 err = h.Posthog.Enqueue(event) 214 211 if err != nil { 212 + log.Println("failed to enqueue posthog event:", err) 215 - l.Error("failed to enqueue posthog event", "err", err) 216 213 } 217 214 } 218 215 ··· 221 218 } 222 219 223 220 func (h *Handler) HandleEditCommentPage(w http.ResponseWriter, r *http.Request) { 224 - l := h.Logger.With("handler", "HandleEditCommentPage") 225 - 226 221 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 227 222 if err != nil { 223 + log.Println("failed to get logged-in user:", err) 228 - l.Error("failed to get logged-in user", "err", err) 229 224 htmx.HxRedirect(w, "/login") 230 225 return 231 226 } ··· 233 228 rkey := chi.URLParam(r, "rkey") 234 229 comment, err := db.GetCommentByRkey(h.Db, user.Did, rkey) 235 230 if err != nil { 231 + log.Println("failed to get comment from db:", err) 236 - l.Error("failed to get comment from db", "err", err) 237 232 htmx.HxError(w, http.StatusInternalServerError, "Failed to update comment, try again later.") 238 233 return 239 234 } 240 235 241 236 if user.Did != comment.Did { 237 + log.Printf("user '%s' does not own record '%s'", user.Did, rkey) 242 - l.Error("user does not own record", "did", user.Did, "commentDid", comment.Did) 243 238 htmx.HxError(w, http.StatusUnauthorized, "You do not have permissions to edit this comment.") 244 239 return 245 240 } ··· 250 245 case http.MethodPost: 251 246 client, err := h.Oauth.AuthorizedClient(r) 252 247 if err != nil { 248 + log.Println("failed to get authorized client:", err) 253 - l.Error("failed to get authorized client", "err", err) 254 249 htmx.HxRedirect(w, "/login") 255 250 return 256 251 } 257 252 258 253 err = r.ParseForm() 259 254 if err != nil { 255 + log.Println("invalid comment form:", err) 260 - l.Error("invalid comment form", "err", err) 261 256 htmx.HxError(w, http.StatusBadRequest, "Unable to process comment, please try again later.") 262 257 return 263 258 } 264 259 265 260 commentBody := r.FormValue("comment") 266 261 if len(strings.TrimSpace(commentBody)) == 0 { 262 + log.Println("invalid comment form: missing comment body") 267 - l.Error("invalid comment form: missing comment body") 268 263 htmx.HxError(w, http.StatusBadRequest, "Comment cannot be empty.") 269 264 return 270 265 } ··· 308 303 SwapRecord: cid, 309 304 }) 310 305 if err != nil { 306 + log.Println("failed to update study session record:", err) 311 - l.Error("failed to update study session record", "err", err) 312 307 htmx.HxError(w, http.StatusInternalServerError, "Failed to update comment, try again later.") 313 308 return 314 309 } ··· 329 324 330 325 err = h.Posthog.Enqueue(event) 331 326 if err != nil { 327 + log.Println("failed to enqueue posthog event:", err) 332 - l.Error("failed to enqueue posthog event", "err", err) 333 328 } 334 329 } 335 330 ··· 392 387 } 393 388 394 389 func (h *Handler) HandleReply(w http.ResponseWriter, r *http.Request) { 395 - l := h.Logger.With("handler", "HandleReply") 396 - 397 390 user := h.Oauth.GetUser(r) 398 391 if user == nil { 392 + log.Println("failed to get logged-in user") 399 - l.Error("failed to get logged-in user") 400 393 htmx.HxRedirect(w, "/login") 401 394 return 402 395 } ··· 404 397 studySessionUri := r.URL.Query().Get("root") 405 398 parentCommentUri := r.URL.Query().Get("parent") 406 399 if len(studySessionUri) == 0 || len(parentCommentUri) == 0 { 400 + log.Println("invalid reply form: study session uri or parent comment uri is empty") 407 - l.Error("invalid reply form: study session uri or parent comment uri is empty") 408 401 htmx.HxError(w, http.StatusBadRequest, "Unable to process comment, please try again later.") 409 402 return 410 403 } ··· 416 409 } 417 410 418 411 func (h *Handler) HandleCancelCommentEdit(w http.ResponseWriter, r *http.Request) { 419 - l := h.Logger.With("handler", "HandleCancelCommentEdit") 420 - 421 412 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 422 413 if err != nil { 414 + log.Println("failed to get logged-in user:", err) 423 - l.Error("failed to get logged-in user", "err", err) 424 415 htmx.HxRedirect(w, "/login") 425 416 return 426 417 } ··· 428 419 rkey := chi.URLParam(r, "rkey") 429 420 comment, err := db.GetCommentByRkey(h.Db, user.Did, rkey) 430 421 if err != nil { 422 + log.Println("failed to get comment from db:", err) 431 - l.Error("failed to get comment from db", "err", err) 432 423 htmx.HxError(w, http.StatusInternalServerError, "Failed to update comment, try again later.") 433 424 return 434 425 }
REVERTED
internal/server/handlers/follow.go
··· 1 1 package handlers 2 2 3 3 import ( 4 + "log" 4 5 "net/http" 5 6 "time" 6 7 ··· 19 20 ) 20 21 21 22 func (h *Handler) HandleFollow(w http.ResponseWriter, r *http.Request) { 22 - l := h.Logger.With("handler", "HandleFollow") 23 - 24 23 client, err := h.Oauth.AuthorizedClient(r) 25 24 if err != nil { 25 + log.Println("failed to get authorized client:", err) 26 - l.Error("failed to get authorized client", "err", err) 27 26 htmx.HxRedirect(w, "/login") 28 27 return 29 28 } 30 29 31 30 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 32 31 if err != nil { 32 + log.Println("failed to get logged-in user:", err) 33 - l.Error("failed to get logged-in user", "err", err) 34 33 htmx.HxRedirect(w, "/login") 35 34 return 36 35 } ··· 43 42 44 43 subjectIdent, err := h.IdResolver.ResolveIdent(r.Context(), subject) 45 44 if err != nil { 45 + log.Println("failed to follow, invalid did:", err) 46 - l.Error("failed to follow, invalid did", "err", err) 47 46 htmx.HxError(w, http.StatusBadRequest, "Failed to follow profile, try again later.") 48 47 return 49 48 } 50 49 51 50 if user.Did == subjectIdent.DID.String() { 51 + log.Println("failed to follow, cannot follow yourself") 52 - l.Error("failed to follow, cannot follow yourself") 53 52 htmx.HxError(w, http.StatusBadRequest, "You cannot follow yourself.") 54 53 return 55 54 } ··· 69 68 }}, 70 69 }) 71 70 if err != nil { 71 + log.Println("failed to create follow record:", err) 72 - l.Error("failed to create follow record", "err", err) 73 72 htmx.HxError(w, http.StatusInternalServerError, "Failed to follow profile, try again later.") 74 73 return 75 74 } ··· 85 84 Set("is_mutual_follow", followStatus == db.IsMutual), 86 85 }) 87 86 if err != nil { 87 + log.Println("failed to enqueue posthog event:", err) 88 - l.Error("failed to enqueue posthog event", "err", err) 89 88 } 90 89 } 91 90 ··· 96 95 case http.MethodDelete: 97 96 follow, err := db.GetFollow(h.Db, user.Did, subjectIdent.DID.String()) 98 97 if err != nil { 98 + log.Println("failed to get follow relationship:", err) 99 - l.Error("failed to get follow relationship", "err", err) 100 99 htmx.HxError(w, http.StatusInternalServerError, "Failed to unfollow profile, try again later.") 101 100 return 102 101 } ··· 107 106 Rkey: follow.Rkey, 108 107 }) 109 108 if err != nil { 109 + log.Println("failed to delete follow record:", err) 110 - l.Error("failed to delete follow record", "err", err) 111 110 htmx.HxError(w, http.StatusInternalServerError, "Failed to unfollow profile, try again later.") 112 111 return 113 112 } ··· 120 119 Set("subject_did", subjectIdent.DID.String()), 121 120 }) 122 121 if err != nil { 122 + log.Println("failed to enqueue posthog event:", err) 123 - l.Error("failed to enqueue posthog event", "err", err) 124 123 } 125 124 } 126 125
REVERTED
internal/server/handlers/activity.go
··· 3 3 import ( 4 4 "errors" 5 5 "fmt" 6 + "log" 6 7 "net/http" 7 8 "time" 8 9 ··· 54 55 } 55 56 56 57 func (h *Handler) HandleNewActivityPage(w http.ResponseWriter, r *http.Request) { 57 - l := h.Logger.With("handler", "HandleNewActivityPage") 58 - 59 58 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 60 59 if err != nil { 60 + log.Println("failed to get logged-in user:", err) 61 - l.Error("failed to get logged-in user", "err", err) 62 61 htmx.HxRedirect(w, "/login") 63 62 return 64 63 } ··· 72 71 case http.MethodPost: 73 72 client, err := h.Oauth.AuthorizedClient(r) 74 73 if err != nil { 74 + log.Println("failed to get authorized client:", err) 75 - l.Error("failed to get authorized client", "err", err) 76 75 htmx.HxRedirect(w, "/login") 77 76 return 78 77 } 79 78 80 79 newActivity, err := parseActivityForm(r) 81 80 if err != nil { 81 + log.Println("invalid activity form:", err) 82 - l.Error("invalid activity form", "err", err) 83 82 htmx.HxError(w, http.StatusBadRequest, "Failed to create activity, ensure all fields contain valid data.") 84 83 return 85 84 } ··· 88 87 newActivity.CreatedAt = time.Now().UTC() 89 88 90 89 if err := db.ValidateActivity(newActivity); err != nil { 90 + log.Println("invalid activity def:", err) 91 - l.Error("invalid activity def", "err", err) 92 91 switch { 93 92 case errors.Is(err, db.ErrActivityNameEmpty): 94 93 htmx.HxError(w, http.StatusBadRequest, "Activity must have a name.") ··· 124 123 }, 125 124 }) 126 125 if err != nil { 126 + log.Println("failed to create activity record:", err) 127 - l.Error("failed to create activity record", "err", err) 128 127 htmx.HxError(w, http.StatusInternalServerError, "Failed to create activity, try again later.") 129 128 return 130 129 } 131 130 132 131 err = SavePendingCreate(h, w, r, PendingActivityCreation, newActivity) 133 132 if err != nil { 133 + log.Printf("failed to save yoten-session to add pending activity creation: %v", err) 134 - l.Error("failed to save yoten-session to add pending activity creation", "err", err) 135 134 } 136 135 137 136 if !h.Config.Core.Dev { ··· 146 145 Set("category_count", len(categoriesString)), 147 146 }) 148 147 if err != nil { 148 + log.Println("failed to enqueue posthog event:", err) 149 - l.Error("failed to enqueue posthog event", "err", err) 150 149 } 151 150 } 152 151 ··· 155 154 } 156 155 157 156 func (h *Handler) HandleDeleteActivity(w http.ResponseWriter, r *http.Request) { 158 - l := h.Logger.With("handler", "HandleDeleteActivity") 159 - 160 157 user := h.Oauth.GetUser(r) 161 158 if user == nil { 159 + log.Println("failed to get logged-in user") 162 - l.Error("failed to get logged-in user") 163 160 htmx.HxRedirect(w, "/login") 164 161 return 165 162 } 166 163 client, err := h.Oauth.AuthorizedClient(r) 167 164 if err != nil { 165 + log.Println("failed to get authorized client:", err) 168 - l.Error("failed to get authorized client", "err", err) 169 166 htmx.HxError(w, http.StatusUnauthorized, "Failed to delete activity, try again later.") 170 167 return 171 168 } ··· 175 172 rkey := chi.URLParam(r, "rkey") 176 173 activity, err := db.GetActivityByRkey(h.Db, user.Did, rkey) 177 174 if err != nil { 175 + log.Println("failed to get activity from db:", err) 178 - l.Error("failed to get activity from db", "err", err) 179 176 htmx.HxError(w, http.StatusInternalServerError, "Failed to delete activity, try again later.") 180 177 return 181 178 } 182 179 183 180 if user.Did != activity.Did { 181 + log.Printf("user '%s' does not own record '%s'", user.Did, rkey) 184 - l.Error("user does not own record", "did", user.Did, "activityDid", activity.Did) 185 182 htmx.HxError(w, http.StatusUnauthorized, "You do not have permissions to edit this activity.") 186 183 return 187 184 } ··· 192 189 Rkey: activity.Rkey, 193 190 }) 194 191 if err != nil { 192 + log.Println("failed to delete activity from PDS:", err) 195 - l.Error("failed to delete activity from PDS", "err", err) 196 193 htmx.HxError(w, http.StatusInternalServerError, "Failed to delete activity, try again later.") 197 194 return 198 195 } 199 196 200 197 err = SavePendingDelete(h, w, r, PendingActivityDeletion, activity) 201 198 if err != nil { 199 + log.Printf("failed to save yoten-session to add pending activity deletion: %v", err) 202 - l.Error("failed to save yoten-session to add pending activity deletion", "err", err) 203 200 } 204 201 205 202 if !h.Config.Core.Dev { ··· 210 207 Set("activity_id", activity.ID), 211 208 }) 212 209 if err != nil { 210 + log.Println("failed to enqueue posthog event:", err) 213 - l.Error("failed to enqueue posthog event", "err", err) 214 211 } 215 212 } 216 213 ··· 219 216 } 220 217 221 218 func (h *Handler) HandleEditActivityPage(w http.ResponseWriter, r *http.Request) { 222 - l := h.Logger.With("handler", "HandleEditActivityPage") 223 - 224 219 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 225 220 if err != nil { 221 + log.Println("failed to get logged-in user:", err) 226 - l.Error("failed to get logged-in user", "err", err) 227 222 htmx.HxRedirect(w, "/login") 228 223 return 229 224 } ··· 231 226 rkey := chi.URLParam(r, "rkey") 232 227 activity, err := db.GetActivityByRkey(h.Db, user.Did, rkey) 233 228 if err != nil { 229 + log.Println("failed to get activity from db:", err) 234 - l.Error("failed to get activity from db", "err", err) 235 230 htmx.HxError(w, http.StatusInternalServerError, "Failed to update activity, try again later.") 236 231 return 237 232 } 238 233 239 234 if user.Did != activity.Did { 235 + log.Printf("user '%s' does not own record '%s'", user.Did, rkey) 240 - l.Error("user does not own record", "did", user.Did, "activityDid", activity.Did) 241 236 htmx.HxError(w, http.StatusUnauthorized, "You do not have permissions to edit this activity.") 242 237 return 243 238 } ··· 252 247 case http.MethodPost: 253 248 client, err := h.Oauth.AuthorizedClient(r) 254 249 if err != nil { 250 + log.Println("failed to get authorized client:", err) 255 - l.Error("failed to get authorized client", "err", err) 256 251 htmx.HxRedirect(w, "/login") 257 252 return 258 253 } 259 254 260 255 updatedActivity, err := parseActivityForm(r) 261 256 if err != nil { 257 + log.Println("invalid activity form:", err) 262 - l.Error("invalid activity form", "err", err) 263 258 htmx.HxError(w, http.StatusBadRequest, "Failed to create activity, ensure all fields contain valid data.") 264 259 return 265 260 } ··· 268 263 updatedActivity.CreatedAt = activity.CreatedAt 269 264 270 265 if err := db.ValidateActivity(updatedActivity); err != nil { 266 + log.Println("invalid activity def:", err) 271 - l.Error("invalid activity def", "err", err) 272 267 switch { 273 268 case errors.Is(err, db.ErrActivityNameEmpty): 274 269 htmx.HxError(w, http.StatusBadRequest, "Activity must have a name.") ··· 311 306 SwapRecord: cid, 312 307 }) 313 308 if err != nil { 309 + log.Println("failed to update study session record:", err) 314 - l.Error("failed to update study session record", "err", err) 315 310 htmx.HxError(w, http.StatusInternalServerError, "Failed to update activity, try again later.") 316 311 return 317 312 } 318 313 319 314 err = SavePendingUpdate(h, w, r, PendingActivityUpdates, updatedActivity) 320 315 if err != nil { 316 + log.Printf("failed to save yoten-session to add pending activity updates: %v", err) 321 - l.Error("failed to save yoten-session to add pending activity updates", "err", err) 322 317 } 323 318 324 319 if !h.Config.Core.Dev { ··· 333 328 Set("category_count", len(categoriesString)), 334 329 }) 335 330 if err != nil { 331 + log.Println("failed to enqueue posthog event:", err) 336 - l.Error("failed to enqueue posthog event", "err", err) 337 332 } 338 333 } 339 334
REVERTED
internal/server/handlers/notification.go
··· 1 1 package handlers 2 2 3 3 import ( 4 + "log" 4 5 "net/http" 5 6 "strconv" 6 7 ··· 11 12 ) 12 13 13 14 func (h *Handler) HandleNotificationFeed(w http.ResponseWriter, r *http.Request) { 14 - l := h.Logger.With("handler", "HandleNotificationFeed") 15 - 16 15 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 17 16 if err != nil { 17 + log.Println("failed to get logged-in user:", err) 18 - l.Error("failed to get logged-in user", "err", err) 19 18 htmx.HxRedirect(w, "/login") 20 19 return 21 20 } ··· 26 25 } 27 26 page, err := strconv.ParseInt(pageStr, 10, 64) 28 27 if err != nil { 28 + log.Println("failed to parse page value:", err) 29 - l.Error("failed to parse page value", "err", err) 30 29 page = 1 31 30 } 32 31 if page == 0 { ··· 40 39 case http.MethodGet: 41 40 notifications, err := db.GetNotificationsByDid(h.Db, user.Did, pageSize+1, int(offset)) 42 41 if err != nil { 42 + log.Println("failed to retrieve notifications:", err) 43 - l.Error("failed to retrieve notifications", "err", err) 44 43 htmx.HxError(w, http.StatusInternalServerError, "Failed to get notifications, try again later.") 45 44 return 46 45 } 47 46 48 47 hydratedNotifications, err := h.getBskyProfileHydratedNotificationFeed(notifications) 49 48 if err != nil { 49 + log.Println("failed to hydrate notifications with bsky profile:", err) 50 - l.Error("failed to hydrate notifications with bsky profile", "err", err) 51 50 htmx.HxError(w, http.StatusInternalServerError, "Failed to get notifications, try again later.") 52 51 return 53 52 } ··· 67 66 } 68 67 69 68 func (h *Handler) HandleNotificationMarkAllRead(w http.ResponseWriter, r *http.Request) { 70 - l := h.Logger.With("handler", "HandleNotificationMarkAllRead") 71 - 72 69 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 73 70 if err != nil { 71 + log.Println("failed to get logged-in user:", err) 74 - l.Error("failed to get logged-in user", "err", err) 75 72 htmx.HxRedirect(w, "/login") 76 73 return 77 74 } 78 75 79 76 err = db.MarkAllNotificationsAsRead(h.Db, user.Did) 80 77 if err != nil { 78 + log.Println("failed to mark all notifications:", err) 81 - l.Error("failed to mark all notifications", "err", err) 82 79 htmx.HxError(w, http.StatusInternalServerError, "Failed to mark all notifications as read, try again later.") 83 80 return 84 81 }
REVERTED
internal/server/handlers/reaction.go
··· 1 1 package handlers 2 2 3 3 import ( 4 + "log" 4 5 "net/http" 5 6 "slices" 6 7 "strconv" ··· 20 21 ) 21 22 22 23 func (h *Handler) HandleReaction(w http.ResponseWriter, r *http.Request) { 23 - l := h.Logger.With("handler", "HandleReaction") 24 - 25 24 client, err := h.Oauth.AuthorizedClient(r) 26 25 if err != nil { 26 + log.Println("failed to get authorized client:", err) 27 - l.Error("failed to get authorized client", "err", err) 28 27 htmx.HxRedirect(w, "/login") 29 28 return 30 29 } 31 30 32 31 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 33 32 if err != nil { 33 + log.Println("failed to get logged-in user:", err) 34 - l.Error("failed to get logged-in user", "err", err) 35 34 htmx.HxRedirect(w, "/login") 36 35 return 37 36 } ··· 54 53 } 55 54 56 55 if user.Did == session.Did { 56 + log.Println("failed to react to study session, cannot react to your own study session") 57 - l.Error("failed to react to study session, cannot react to your own study session") 58 57 htmx.HxError(w, http.StatusBadRequest, "You cannot react to your own study sessions.") 59 58 return 60 59 } ··· 74 73 75 74 reaction, err := db.ReactionFromString(db.ReactionType(reactionId).String()) 76 75 if err != nil { 76 + log.Printf("failed to get reaction types: %v", err) 77 - l.Error("failed to get reaction types", "err", err) 78 77 htmx.HxError(w, http.StatusInternalServerError, "Failed to get global study session feed, try again later.") 79 78 return 80 79 } 81 80 82 81 reactionEvents, err := db.GetReactionsForSession(h.Db, subjectDid, subjectRkey) 83 82 if err != nil { 83 + log.Println("failed to get reactions for study session from db:", err) 84 - l.Error("failed to get reactions for study session from db", "err", err) 85 84 htmx.HxError(w, http.StatusInternalServerError, "Failed to get global study session feed, try again later.") 86 85 return 87 86 } ··· 90 89 case http.MethodPost: 91 90 reactionEvent, err := db.GetReactionEvent(h.Db, user.Did, session, reaction.ID) 92 91 if err != nil { 92 + log.Println("failed to get reaction event from db:", err) 93 - l.Error("failed to get reaction event from db", "err", err) 94 93 htmx.HxError(w, http.StatusInternalServerError, "Failed to add reaction, try again later.") 95 94 return 96 95 } 97 96 if reactionEvent != nil { 97 + log.Println("failed to add reaction, user already reacted") 98 - l.Error("failed to add reaction, user already reacted") 99 98 htmx.HxError(w, http.StatusBadRequest, "You cannot react multiple times with the same reaction.") 100 99 return 101 100 } ··· 114 113 }}, 115 114 }) 116 115 if err != nil { 116 + log.Println("failed to create reaction record:", err) 117 - l.Error("failed to create reaction record", "err", err) 118 117 htmx.HxError(w, http.StatusInternalServerError, "Failed to add reaction, try again later.") 119 118 return 120 119 } ··· 129 128 Set("session_rkey", subjectRkey), 130 129 }) 131 130 if err != nil { 131 + log.Println("failed to enqueue posthog event:", err) 132 - l.Error("failed to enqueue posthog event", "err", err) 133 132 } 134 133 } 135 134 ··· 154 153 case http.MethodDelete: 155 154 reactionEvent, err := db.GetReactionEvent(h.Db, user.Did, session, reaction.ID) 156 155 if err != nil { 156 + log.Println("failed to get reaction event from db:", err) 157 - l.Error("failed to get reaction event from db", "err", err) 158 157 htmx.HxError(w, http.StatusInternalServerError, "Failed to remove reaction, try again later.") 159 158 return 160 159 } ··· 165 164 Rkey: reactionEvent.Rkey, 166 165 }) 167 166 if err != nil { 167 + log.Println("failed to delete reaction record:", err) 168 - l.Error("failed to delete reaction record", "err", err) 169 168 htmx.HxError(w, http.StatusInternalServerError, "Failed to remove reaction, try again later.") 170 169 return 171 170 } ··· 180 179 Set("session_rkey", subjectRkey), 181 180 }) 182 181 if err != nil { 182 + log.Println("failed to enqueue posthog event:", err) 183 - l.Error("failed to enqueue posthog event", "err", err) 184 183 } 185 184 } 186 185 ··· 189 188 }) 190 189 191 190 partials.NewReactions(partials.NewReactionsProps{ 191 + User: user, 192 + SessionRkey: subjectRkey, 193 + SessionDid: subjectDid, 194 + // Reactions: reactions, 192 - User: user, 193 - SessionRkey: subjectRkey, 194 - SessionDid: subjectDid, 195 195 ReactionEvents: reactionEvents, 196 196 }).Render(r.Context(), w) 197 197 }
REVERTED
internal/server/handlers/stats.go
··· 1 1 package handlers 2 2 3 3 import ( 4 + "log" 4 5 "net/http" 5 6 6 7 "yoten.app/internal/clients/bsky" ··· 11 12 ) 12 13 13 14 func (h *Handler) HandleTimePerGraphs(w http.ResponseWriter, r *http.Request) { 14 - l := h.Logger.With("handler", "HandleTimePerGraphs") 15 - 16 15 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 17 16 if err != nil { 17 + log.Println("failed to get logged-in user:", err) 18 - l.Error("failed to get logged-in user", "err", err) 19 18 htmx.HxRedirect(w, "/login") 20 19 return 21 20 } ··· 25 24 26 25 chartData, err := db.GetTimePerData(h.Db, user.Did, period) 27 26 if err != nil { 27 + log.Println("failed to get time per chart data:", err) 28 - l.Error("failed to get time per chart data", "err", err) 29 28 chartData = db.ChartsData{ 30 29 ActivityData: []db.ChartData{}, 31 30 CategoryData: []db.ChartData{}, ··· 39 38 } 40 39 41 40 func (h *Handler) HandleStatsPage(w http.ResponseWriter, r *http.Request) { 42 - l := h.Logger.With("handler", "HandleStatsPage") 43 - 44 41 user, err := bsky.GetUserWithBskyProfile(h.Oauth, r) 45 42 if err != nil { 43 + log.Println("failed to get logged-in user:", err) 46 - l.Error("failed to get logged-in user", "err", err) 47 44 htmx.HxRedirect(w, "/login") 48 45 return 49 46 } 50 47 51 48 totalStudyTime, err := db.GetTotalStudyTime(h.Db, user.Did) 52 49 if err != nil { 50 + log.Println("failed to get total study time:", err) 53 - l.Error("failed to get total study time", "err", err) 54 51 } 55 52 56 53 totalStudySessions, err := db.GetTotalStudySessions(h.Db, user.Did) 57 54 if err != nil { 55 + log.Println("failed to get total study study sessions:", err) 58 - l.Error("failed to get total study study sessions", "err", err) 59 56 } 60 57 61 58 totalActiveDays, err := db.GetTotalActiveDays(h.Db, user.Did) 62 59 if err != nil { 60 + log.Println("failed to get total active days:", err) 63 - l.Error("failed to get total active days", "err", err) 64 61 } 65 62 66 63 streak, err := db.GetCurrentStreak(h.Db, user.Did) 67 64 if err != nil { 65 + log.Println("failed to get streak:", err) 68 - l.Error("failed to get streak", "err", err) 69 66 } 70 67 71 68 heatmap, err := db.GetHeatmapData(h.Db, user.Did) 72 69 if err != nil { 70 + log.Println("failed to get heatmap data:", err) 73 - l.Error("failed to get heatmap data", "err", err) 74 71 } 75 72 76 73 inputOutputPercentage, err := db.GetInputOutputPercentage(h.Db, user.Did) 77 74 if err != nil { 75 + log.Println("failed to get input vs output data:", err) 78 - l.Error("failed to get input vs output data", "err", err) 79 76 } 80 77 81 78 languageSummary, err := db.GetLanguageSummary(h.Db, user.Did) 82 79 if err != nil { 80 + log.Println("failed to get language time summary:", err) 83 - l.Error("failed to get language time summary", "err", err) 84 81 } 85 82 languageChartSegments := db.ConvertToDonutChartSegments(languageSummary) 86 83
REVERTED
internal/consumer/ingester.go
··· 4 4 "context" 5 5 "encoding/json" 6 6 "fmt" 7 + "log" 7 - "log/slog" 8 8 "strings" 9 9 "time" 10 10 ··· 20 20 type Ingester struct { 21 21 Db db.DbWrapper 22 22 Config *config.Config 23 - Logger *slog.Logger 24 23 } 25 24 26 25 type processFunc func(ctx context.Context, e *models.Event) error ··· 36 35 } 37 36 }() 38 37 39 - l := i.Logger.With("kind", e.Kind) 40 38 switch e.Kind { 41 39 case models.EventKindCommit: 42 40 switch e.Commit.Collection { 43 41 case yoten.ActorProfileNSID: 44 - l = l.With("handler", "ingestProfile") 45 42 err = i.ingestProfile(e) 46 43 case yoten.FeedSessionNSID: 47 - l = l.With("handler", "ingestStudySession") 48 44 err = i.ingestStudySession(e) 49 45 case yoten.ActivityDefNSID: 50 - l = l.With("handler", "ingestActivityDef") 51 46 err = i.ingestActivityDef(e) 52 47 case yoten.FeedResourceNSID: 53 - l = l.With("handler", "ingestResource") 54 48 err = i.ingestResource(e) 55 49 case yoten.GraphFollowNSID: 56 - l = l.With("handler", "ingestFollow") 57 50 err = i.ingestFollow(e) 58 51 case yoten.FeedReactionNSID: 59 - l = l.With("handler", "ingestReaction") 60 52 err = i.ingestReaction(e) 61 53 case yoten.FeedCommentNSID: 62 - l = l.With("handler", "ingestComment") 63 54 err = i.ingestComment(e) 64 55 } 65 - l = i.Logger.With("nsid", e.Commit.Collection) 66 56 } 67 57 if err != nil { 58 + log.Printf("failed to ingest event for collection %s: %v", e.Commit.Collection, err) 68 - l.Error("failed to ingest event", "err", err) 69 59 } 70 60 71 61 return nil ··· 139 129 return fmt.Errorf("failed to start transaction: %w", err) 140 130 } 141 131 132 + log.Printf("upserting profile '%s' from pds request", profile.Did) 142 - i.Logger.Debug("upserting profile from pds request") 143 133 err = db.UpsertProfile(tx, &profile) 144 134 if err != nil { 145 135 tx.Rollback() ··· 170 160 171 161 date, err := time.Parse(time.RFC3339, record.Date) 172 162 if err != nil { 163 + log.Printf("invalid record: %s", err) 173 - i.Logger.Error("invalid record", "err", err) 174 164 return err 175 165 } 176 166 ··· 237 227 return fmt.Errorf("failed to start transaction: %w", err) 238 228 } 239 229 230 + log.Println("upserting study session from pds request") 240 - i.Logger.Debug("upserting study session from pds request") 241 231 err = db.UpsertStudySession(tx, &studySession, e.Commit.RKey) 242 232 if err != nil { 243 233 tx.Rollback() ··· 262 252 return fmt.Errorf("failed to start transaction: %w", err) 263 253 } 264 254 255 + log.Println("deleting study session from pds request") 265 - i.Logger.Debug("deleting study session from pds request") 266 256 err = db.DeleteStudySessionByRkey(tx, did, e.Commit.RKey) 267 257 if err != nil { 268 258 tx.Rollback() ··· 354 344 return fmt.Errorf("failed to start transaction: %w", err) 355 345 } 356 346 347 + log.Println("upserting activity def from pds request") 357 - i.Logger.Debug("upserting activity def from pds request") 358 348 err = db.UpsertActivityDef(tx, &activityDef, e.Commit.RKey) 359 349 if err != nil { 360 350 tx.Rollback() ··· 362 352 } 363 353 return tx.Commit() 364 354 case models.CommitOperationDelete: 355 + log.Println("deleting activity def from pds request") 365 - i.Logger.Debug("deleting activity def from pds request") 366 356 err = db.DeleteActivityDefByRkey(i.Db, did, e.Commit.RKey) 367 357 } 368 358 if err != nil { ··· 397 387 398 388 subjectDid := record.Subject 399 389 390 + log.Println("upserting follow from pds request") 400 - i.Logger.Debug("upserting follow from pds request") 401 391 err = db.AddFollow(tx, did, subjectDid, e.Commit.RKey) 402 392 if err != nil { 403 393 tx.Rollback() ··· 407 397 subjectUri := fmt.Sprintf("at://%s/%s/%s", did, yoten.GraphFollowNSID, e.Commit.RKey) 408 398 err = db.CreateNotification(tx, subjectDid, did, subjectUri, db.NotificationTypeFollow) 409 399 if err != nil { 400 + log.Println("failed to create notification record:", err) 410 - i.Logger.Error("failed to create notification record", "err", err) 411 401 } 412 402 413 403 return tx.Commit() 414 404 case models.CommitOperationDelete: 405 + log.Println("deleting follow from pds request") 415 - i.Logger.Debug("deleting follow from pds request") 416 406 err = db.DeleteFollowByRkey(i.Db, did, e.Commit.RKey) 417 407 } 418 408 if err != nil { ··· 475 465 CreatedAt: createdAt, 476 466 } 477 467 468 + log.Println("upserting reaction from pds request") 478 - i.Logger.Debug("upserting reaction from pds request") 479 469 err = db.UpsertReaction(i.Db, reactionEvent) 480 470 if err != nil { 481 471 tx.Rollback() ··· 484 474 485 475 err = db.CreateNotification(tx, subjectDid.String(), did, subject.String(), db.NotificationTypeReaction) 486 476 if err != nil { 477 + log.Println("failed to create notification record:", err) 487 - i.Logger.Error("failed to create notification record", "err", err) 488 478 } 489 479 490 480 return tx.Commit() 491 481 case models.CommitOperationDelete: 482 + log.Println("deleting reaction from pds request") 492 - i.Logger.Debug("deleting reaction from pds request") 493 483 err = db.DeleteReactionByRkey(i.Db, did, e.Commit.RKey) 494 484 } 495 485 if err != nil { ··· 556 546 return fmt.Errorf("invalid resource: %w", err) 557 547 } 558 548 549 + log.Println("upserting resource from pds request") 559 - i.Logger.Debug("upserting resource from pds request") 560 550 err = db.UpsertResource(i.Db, resource, resource.Rkey) 561 551 if err != nil { 562 552 tx.Rollback() ··· 564 554 } 565 555 return tx.Commit() 566 556 case models.CommitOperationDelete: 557 + log.Println("deleting resource from pds request") 567 - i.Logger.Debug("deleting resource from pds request") 568 558 err = db.DeleteResourceByRkey(i.Db, did, e.Commit.RKey) 569 559 } 570 560 if err != nil { ··· 636 626 CreatedAt: createdAt, 637 627 } 638 628 629 + log.Println("upserting comment from pds request") 639 - i.Logger.Debug("upserting comment from pds request") 640 630 err = db.UpsertComment(i.Db, comment) 641 631 if err != nil { 642 632 tx.Rollback() ··· 647 637 if subjectDid.String() != did { 648 638 err = db.CreateNotification(tx, subjectDid.String(), did, subjectUri.String(), db.NotificationTypeComment) 649 639 if err != nil { 640 + log.Println("failed to create notification record:", err) 650 - i.Logger.Error("failed to create notification record", "err", err) 651 641 } 652 642 } 653 643 ··· 655 645 if comment.ParentCommentUri != nil && comment.ParentCommentUri.Authority().String() != did { 656 646 err = db.CreateNotification(tx, comment.ParentCommentUri.Authority().String(), did, parentCommentUri.String(), db.NotificationTypeReply) 657 647 if err != nil { 648 + log.Println("failed to create notification record:", err) 658 - i.Logger.Error("failed to create notification record", "err", err) 659 649 } 660 650 } 661 651 662 652 return tx.Commit() 663 653 case models.CommitOperationDelete: 654 + log.Println("deleting comment from pds request") 664 - i.Logger.Debug("deleting comment from pds request") 665 655 err = db.DeleteCommentByRkey(i.Db, did, e.Commit.RKey) 666 656 } 667 657 if err != nil {
REVERTED
internal/server/handlers/router.go
··· 7 7 "github.com/go-chi/chi/v5" 8 8 9 9 "yoten.app/internal/server" 10 - "yoten.app/internal/server/log" 11 10 "yoten.app/internal/server/middleware" 12 11 "yoten.app/internal/server/views" 13 12 ) ··· 26 25 h.Oauth, 27 26 h.Db, 28 27 h.IdResolver, 29 - log.SubLogger(h.Logger, "middleware"), 30 28 ) 31 29 32 30 router.HandleFunc("/*", func(w http.ResponseWriter, r *http.Request) {
REVERTED
internal/server/middleware/middleware.go
··· 3 3 import ( 4 4 "context" 5 5 "fmt" 6 + "log" 6 - "log/slog" 7 7 "net/http" 8 8 "net/url" 9 9 "slices" ··· 25 25 oauth *oauth.OAuth 26 26 db *db.DB 27 27 idResolver *atproto.Resolver 28 - logger *slog.Logger 29 28 } 30 29 30 + func New(oauth *oauth.OAuth, db *db.DB, idResolver *atproto.Resolver) Middleware { 31 - func New(oauth *oauth.OAuth, db *db.DB, idResolver *atproto.Resolver, logger *slog.Logger) Middleware { 32 31 return Middleware{ 33 32 oauth: oauth, 34 33 db: db, 35 34 idResolver: idResolver, 36 - logger: logger, 37 35 } 38 36 } 39 37 40 38 type middlewareFunc func(http.Handler) http.Handler 41 39 42 40 func AuthMiddleware(o *oauth.OAuth) middlewareFunc { 43 - l := o.Logger.With("middleware", "AuthMiddleware") 44 - 45 41 return func(next http.Handler) http.Handler { 46 42 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 47 43 returnURL := "/" ··· 63 59 64 60 sess, err := o.ResumeSession(r) 65 61 if err != nil { 62 + log.Println("failed to resume session, redirecting...", "err", err, "url", r.URL.String()) 66 - l.Error("failed to resume session, redirecting...", "err", err, "url", r.URL.String()) 67 63 redirectFunc(w, r) 68 64 return 69 65 } 70 66 71 67 if sess == nil { 68 + log.Printf("session is nil, redirecting...") 72 - l.Warn("session is nil, redirecting...") 73 69 redirectFunc(w, r) 74 70 return 75 71 } ··· 80 76 } 81 77 82 78 func (mw Middleware) ResolveIdent() middlewareFunc { 83 - l := mw.logger.With("middleware", "ResolveIdent") 84 79 excluded := []string{"favicon.ico"} 85 80 86 81 return func(next http.Handler) http.Handler { ··· 95 90 96 91 id, err := mw.idResolver.ResolveIdent(r.Context(), didOrHandle) 97 92 if err != nil { 93 + log.Println("failed to resolve did/handle:", err) 98 - l.Error("failed to resolve did/handle", "err", err) 99 94 w.WriteHeader(http.StatusNotFound) 100 95 views.NotFoundPage(views.NotFoundPageParams{}).Render(r.Context(), w) 101 96 return ··· 109 104 } 110 105 111 106 func (mw Middleware) LoadUnreadNotificationCount() middlewareFunc { 112 - l := mw.logger.With("middleware", "LoadUnreadNotificationCount") 113 - 114 107 return func(next http.Handler) http.Handler { 115 108 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 116 109 user := mw.oauth.GetUser(r) ··· 121 114 122 115 count, err := db.GetUnreadNotificationCount(mw.db, user.Did) 123 116 if err != nil { 117 + log.Println("failed to get notification count:", err) 124 - l.Error("failed to get notification count", "err", err) 125 118 } 126 119 127 120 ctx := context.WithValue(r.Context(), UnreadNotificationCountCtxKey, count)
ERROR
internal/server/handlers/login.go

Failed to calculate interdiff for this file.

NEW
internal/server/app.go
··· 63 63 64 64 idResolver := atproto.DefaultResolver() 65 65 66 - oauth, err := oauth.New(config, posthog, log.SubLogger(logger, "oauth")) 66 + oauth, err := oauth.New(config, posthog, idResolver, log.SubLogger(logger, "oauth")) 67 67 if err != nil { 68 68 return nil, fmt.Errorf("failed to start oauth handler: %w", err) 69 69 }
NEW
internal/server/handlers/profile.go
··· 130 130 }) 131 131 132 132 if err := g.Wait(); err != nil { 133 - l.Error("failed to fetch critical profile data for", "did", profileDid, "err", err) 133 + l.Error("failed to fetch critical profile data", "did", profileDid, "err", err) 134 134 htmx.HxError(w, http.StatusInternalServerError, "Failed to fetch profile data, try again later.") 135 135 return 136 136 }
NEW
internal/server/oauth/handler.go
··· 1 1 package oauth 2 2 3 3 import ( 4 + "context" 4 5 "encoding/json" 6 + "fmt" 5 7 "net/http" 8 + "time" 6 9 10 + comatproto "github.com/bluesky-social/indigo/api/atproto" 11 + lexutil "github.com/bluesky-social/indigo/lex/util" 7 12 "github.com/go-chi/chi/v5" 8 13 "github.com/lestrrat-go/jwx/v2/jwk" 9 14 "github.com/posthog/posthog-go" 10 15 16 + "yoten.app/api/yoten" 11 17 ph "yoten.app/internal/clients/posthog" 18 + "yoten.app/internal/db" 19 + "yoten.app/internal/server/htmx" 12 20 ) 13 21 14 22 func (o *OAuth) Router() http.Handler { ··· 63 71 } 64 72 65 73 func (o *OAuth) callback(w http.ResponseWriter, r *http.Request) { 74 + l := o.Logger.With("handler", "callback") 66 75 ctx := r.Context() 67 76 68 77 sessData, err := o.ClientApp.ProcessCallback(ctx, r.URL.Query()) ··· 73 82 } 74 83 75 84 if err := o.SaveSession(w, r, sessData); err != nil { 76 - o.Logger.Error("failed to save session", "err", err) 85 + l.Error("failed to save session", "err", err) 77 86 http.Error(w, err.Error(), http.StatusInternalServerError) 78 87 return 79 88 } 80 89 81 - if !o.Config.Core.Dev { 82 - err = o.Posthog.Enqueue(posthog.Capture{ 83 - DistinctId: sessData.AccountDID.String(), 84 - Event: ph.UserSignInSuccessEvent, 90 + did := sessData.AccountDID.String() 91 + resolved, err := o.IdResolver.ResolveIdent(context.Background(), did) 92 + if err != nil { 93 + l.Error("failed to resolve handle", "handle", resolved.Handle.String(), "err", err) 94 + htmx.HxError(w, http.StatusBadRequest, fmt.Sprintf("'%s' is an invalid handle", resolved.Handle.String())) 95 + return 96 + } 97 + 98 + client, err := o.AuthorizedClient(r) 99 + if err != nil { 100 + l.Error("failed to get authorized client", "err", err) 101 + http.Error(w, err.Error(), http.StatusInternalServerError) 102 + return 103 + } 104 + 105 + ex, _ := comatproto.RepoGetRecord(r.Context(), client, "", yoten.ActorProfileNSID, did, "self") 106 + var cid *string 107 + if ex != nil { 108 + cid = ex.Cid 109 + } 110 + 111 + // This should only occur once per account 112 + if ex == nil { 113 + createdAt := time.Now().Format(time.RFC3339) 114 + atresp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 115 + Collection: yoten.ActorProfileNSID, 116 + Repo: did, 117 + Rkey: "self", 118 + Record: &lexutil.LexiconTypeDecoder{ 119 + Val: &yoten.ActorProfile{ 120 + DisplayName: resolved.Handle.String(), 121 + Description: db.ToPtr(""), 122 + Languages: make([]string, 0), 123 + Location: db.ToPtr(""), 124 + CreatedAt: createdAt, 125 + }}, 126 + 127 + SwapRecord: cid, 85 128 }) 86 129 if err != nil { 87 - o.Logger.Error("failed to enqueue posthog event", "err", err) 130 + l.Error("failed to create profile record", "err", err) 131 + htmx.HxError(w, http.StatusInternalServerError, "Failed to announce profile creation, try again later") 132 + return 133 + } 134 + 135 + l.Debug("created profile record", "uri", atresp.Uri) 136 + 137 + if !o.Config.Core.Dev { 138 + err = o.Posthog.Enqueue(posthog.Capture{ 139 + DistinctId: sessData.AccountDID.String(), 140 + Event: ph.UserSignInSuccessEvent, 141 + }) 142 + if err != nil { 143 + l.Error("failed to enqueue posthog event", "err", err) 144 + } 145 + 146 + properties := posthog.NewProperties(). 147 + Set("display_name", resolved.Handle.String()). 148 + Set("language_count", 0). 149 + Set("$set_once", posthog.NewProperties(). 150 + Set("initial_did", did). 151 + Set("initial_handle", resolved.Handle.String()). 152 + Set("created_at", createdAt), 153 + ) 154 + 155 + err = o.Posthog.Enqueue(posthog.Identify{ 156 + DistinctId: did, 157 + Properties: properties, 158 + }) 159 + if err != nil { 160 + l.Error("failed to enqueue posthog identify event", "err", err) 161 + } 162 + 163 + err = o.Posthog.Enqueue(posthog.Capture{ 164 + DistinctId: did, 165 + Event: ph.ProfileRecordCreatedEvent, 166 + }) 167 + if err != nil { 168 + l.Error("failed to enqueue posthog event", "err", err) 169 + } 88 170 } 89 171 } 90 172
NEW
internal/server/oauth/oauth.go
··· 15 15 "github.com/gorilla/sessions" 16 16 "github.com/posthog/posthog-go" 17 17 18 + "yoten.app/internal/atproto" 18 19 "yoten.app/internal/server/config" 19 20 "yoten.app/internal/types" 20 21 ) ··· 26 27 JwksUri string 27 28 Posthog posthog.Client 28 29 Logger *slog.Logger 30 + IdResolver *atproto.Resolver 29 31 } 30 32 31 - func New(config *config.Config, ph posthog.Client, logger *slog.Logger) (*OAuth, error) { 33 + func New(config *config.Config, ph posthog.Client, idResolver *atproto.Resolver, logger *slog.Logger) (*OAuth, error) { 32 34 var oauthConfig oauth.ClientConfig 33 35 var clientUri string 34 36 ··· 58 60 SessionStore: sessStore, 59 61 JwksUri: jwksUri, 60 62 Posthog: ph, 63 + IdResolver: idResolver, 61 64 Logger: logger, 62 65 }, nil 63 66