Add repository guidelines and enhance documentation for project structure, build commands, coding standards, and testing practices. Introduce AGENTS.md for contributor guidance, update README.md to reference new guidelines, and improve configuration documentation for NATS modes. Update Makefile and Taskfile with clearer run commands and requirements for development and production modes. Add production deployment guide and improve logging configuration for better observability.

This commit is contained in:
windyboy
2025-11-17 16:25:23 +08:00
parent 67abd66fa3
commit 704c7b80f6
34 changed files with 2976 additions and 782 deletions
+35 -4
View File
@@ -10,6 +10,30 @@ import (
"go.uber.org/zap"
)
// sanitizePostgresURLForLogging creates a safe version of the connection string for logging
// by removing credentials and only showing host, port, and database
func sanitizePostgresURLForLogging(poolConfig *pgxpool.Config) string {
if poolConfig == nil || poolConfig.ConnConfig == nil {
return "postgres://***@***/***"
}
host := poolConfig.ConnConfig.Host
port := poolConfig.ConnConfig.Port
database := poolConfig.ConnConfig.Database
if host == "" {
host = "***"
}
if port == 0 {
port = 5432
}
if database == "" {
database = "***"
}
return fmt.Sprintf("postgres://***@%s:%d/%s", host, port, database)
}
// ProvideDB creates a PostgreSQL connection pool
func ProvideDB(cfg *config.Config, logger *zap.Logger) (*pgxpool.Pool, error) {
ctx := context.Background()
@@ -17,12 +41,15 @@ func ProvideDB(cfg *config.Config, logger *zap.Logger) (*pgxpool.Pool, error) {
poolConfig, err := pgxpool.ParseConfig(cfg.Postgres.URL)
if err != nil {
logger.Error("failed to parse postgres URL",
zap.String("url", cfg.Postgres.URL),
zap.String("host", "unknown"),
zap.Error(err),
)
return nil, fmt.Errorf("failed to parse postgres URL: %w", err)
}
// Extract safe connection info for logging
safeURL := sanitizePostgresURLForLogging(poolConfig)
poolConfig.MaxConns = int32(cfg.Postgres.MaxConns)
poolConfig.MinConns = int32(cfg.Postgres.MinConns)
poolConfig.MaxConnLifetime = time.Hour
@@ -31,7 +58,7 @@ func ProvideDB(cfg *config.Config, logger *zap.Logger) (*pgxpool.Pool, error) {
pool, err := pgxpool.NewWithConfig(ctx, poolConfig)
if err != nil {
logger.Error("failed to create connection pool",
zap.String("url", cfg.Postgres.URL),
zap.String("url", safeURL),
zap.Int32("max_conns", cfg.Postgres.MaxConns),
zap.Int32("min_conns", cfg.Postgres.MinConns),
zap.Error(err),
@@ -42,13 +69,17 @@ func ProvideDB(cfg *config.Config, logger *zap.Logger) (*pgxpool.Pool, error) {
// Test connection
if err := pool.Ping(ctx); err != nil {
logger.Error("failed to ping database",
zap.String("url", cfg.Postgres.URL),
zap.String("url", safeURL),
zap.Error(err),
)
return nil, fmt.Errorf("failed to ping database: %w", err)
}
// Log the connection pool
logger.Info("Connected to PostgreSQL", zap.Int32("max_conns", cfg.Postgres.MaxConns), zap.Int32("min_conns", cfg.Postgres.MinConns), zap.String("url", cfg.Postgres.URL))
logger.Info("Connected to PostgreSQL",
zap.String("url", safeURL),
zap.Int32("max_conns", cfg.Postgres.MaxConns),
zap.Int32("min_conns", cfg.Postgres.MinConns),
)
return pool, nil
}
+27
View File
@@ -0,0 +1,27 @@
package postgres
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/jackc/pgx/v5/pgxpool"
)
func TestPostgres(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Postgres Suite")
}
var _ = Describe("sanitizePostgresURLForLogging", func() {
It("returns a masked URL when config is empty", func() {
Expect(sanitizePostgresURLForLogging(nil)).To(Equal("postgres://***@***/***"))
})
It("returns a sanitized URL when fields are populated", func() {
cfg, err := pgxpool.ParseConfig("postgres://user:secret@db.local:6543/telegrams")
Expect(err).NotTo(HaveOccurred())
Expect(sanitizePostgresURLForLogging(cfg)).To(Equal("postgres://***@db.local:6543/telegrams"))
})
})