Go backend with Gin, pgx, Valkey (go-valkey), and PostGIS. Domains: - Market search with PostGIS geo-queries (ST_DWithin, ST_Distance), German full-text search (tsvector + ILIKE fallback for compound words), date range filtering, pagination, and slug-based detail endpoint - Auth with email+password (bcrypt), JWT access tokens (15min), session tokens (30d, dual Valkey+Postgres storage), OAuth (Google/GitHub/Facebook), magic links, and TOTP 2FA - User profile with CRUD, soft-delete (30d grace), and restore Infrastructure: - 6 database migrations (users, sessions, oauth_accounts, magic_links, markets with PostGIS+FTS, totp_secrets) - Middleware: recovery, request ID, structured logging (slog), CORS, per-IP rate limiting, JWT auth - Seed data: 10 medieval markets across DACH region - Docker Compose (PostGIS 17 + Valkey 8), multi-stage Dockerfile, Woodpecker CI pipeline, Kubernetes manifests - Justfile, golangci-lint config, env example
38 lines
745 B
Go
38 lines
745 B
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
|
|
"github.com/valkey-io/valkey-go"
|
|
|
|
"marktvogt.de/backend/internal/config"
|
|
)
|
|
|
|
func NewValkey(cfg config.ValkeyConfig) (valkey.Client, error) {
|
|
opts := valkey.ClientOption{
|
|
InitAddress: []string{cfg.Addr},
|
|
}
|
|
if cfg.Password != "" {
|
|
opts.Password = cfg.Password
|
|
}
|
|
if cfg.DB > 0 {
|
|
opts.SelectDB = cfg.DB
|
|
}
|
|
|
|
client, err := valkey.NewClient(opts)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("creating valkey client: %w", err)
|
|
}
|
|
|
|
ctx := context.Background()
|
|
if err := client.Do(ctx, client.B().Ping().Build()).Error(); err != nil {
|
|
client.Close()
|
|
return nil, fmt.Errorf("pinging valkey: %w", err)
|
|
}
|
|
|
|
slog.Info("connected to valkey", "addr", cfg.Addr)
|
|
return client, nil
|
|
}
|