mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-19 18:41:24 +02:00
Replaces the NestJS mana-notify service with a Go implementation. Features: 4 notification channels (email/SMTP, Expo push, Matrix, webhook), goroutine worker pool with retry/backoff (replaces BullMQ), Go template engine (replaces Handlebars), PostgreSQL with auto-migrations (5 tables), user preferences with quiet hours, idempotency via externalId, batch sending, scheduled delivery, JWT + service key auth. 22 API endpoints, 1:1 compatible. Binary: 21 MB. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
62 lines
1.1 KiB
Go
62 lines
1.1 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
type DB struct {
|
|
Pool *pgxpool.Pool
|
|
}
|
|
|
|
func New(ctx context.Context, databaseURL string) (*DB, error) {
|
|
cfg, err := pgxpool.ParseConfig(databaseURL)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("parse database url: %w", err)
|
|
}
|
|
|
|
cfg.MaxConns = 20
|
|
cfg.MinConns = 2
|
|
cfg.MaxConnLifetime = 30 * time.Minute
|
|
cfg.MaxConnIdleTime = 5 * time.Minute
|
|
|
|
pool, err := pgxpool.NewWithConfig(ctx, cfg)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("connect to database: %w", err)
|
|
}
|
|
|
|
if err := pool.Ping(ctx); err != nil {
|
|
pool.Close()
|
|
return nil, fmt.Errorf("ping database: %w", err)
|
|
}
|
|
|
|
slog.Info("database connected", "url", redactURL(databaseURL))
|
|
|
|
db := &DB{Pool: pool}
|
|
if err := db.migrate(ctx); err != nil {
|
|
pool.Close()
|
|
return nil, fmt.Errorf("run migrations: %w", err)
|
|
}
|
|
|
|
return db, nil
|
|
}
|
|
|
|
func (d *DB) Close() {
|
|
d.Pool.Close()
|
|
}
|
|
|
|
func (d *DB) HealthCheck(ctx context.Context) error {
|
|
return d.Pool.Ping(ctx)
|
|
}
|
|
|
|
func redactURL(url string) string {
|
|
// Hide password from logs
|
|
if idx := len(url); idx > 30 {
|
|
return url[:30] + "..."
|
|
}
|
|
return url
|
|
}
|