From 9b550f4be24e5acad336157479e20510f7ec8aaf Mon Sep 17 00:00:00 2001 From: sittichok Ouamsiri Date: Mon, 15 Jun 2026 21:45:29 +0700 Subject: [PATCH] feat: .env.example --- .env.example | 34 ++++++++++++++++++++ backend/internal/adapter/rediscache/cache.go | 4 +-- backend/internal/config/config.go | 8 +++-- backend/internal/di/container.go | 2 +- 4 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..49a9d30 --- /dev/null +++ b/.env.example @@ -0,0 +1,34 @@ +# ── Storage ────────────────────────────────────────────────────────────────── +STORE=postgres +DATABASE_URL=postgres://snip:snip@localhost:5432/snip?sslmode=disable + +# ── Redis ───────────────────────────────────────────────────────────────────── +REDIS_ADDR=localhost:6379 +REDIS_PASSWORD= +REDIS_DB=0 +# Namespace prefix for all Redis keys — set this when sharing a Redis instance +# with other apps, e.g. REDIS_KEY_PREFIX=snip: → keys look like snip:code:abc +REDIS_KEY_PREFIX= + +# ── App ─────────────────────────────────────────────────────────────────────── +PUBLIC_URL=http://localhost:8080 +SHORT_DOMAIN=localhost:8080 +POST_LOGIN_REDIRECT=/dashboard +FRONTEND_DIST=./web + +# ── Security ────────────────────────────────────────────────────────────────── +SESSION_SECRET=change-me-in-production +COOKIE_SECURE=false + +# ── Google OAuth (optional) ─────────────────────────────────────────────────── +GOOGLE_CLIENT_ID= +GOOGLE_CLIENT_SECRET= + +# ── Generic OIDC (optional) ─────────────────────────────────────────────────── +OIDC_ISSUER= +OIDC_CLIENT_ID= +OIDC_CLIENT_SECRET= + +# ── Misc ────────────────────────────────────────────────────────────────────── +# How often buffered click counts are flushed to Postgres (seconds) +CLICK_FLUSH_SECONDS=10 diff --git a/backend/internal/adapter/rediscache/cache.go b/backend/internal/adapter/rediscache/cache.go index a189055..e18af6e 100644 --- a/backend/internal/adapter/rediscache/cache.go +++ b/backend/internal/adapter/rediscache/cache.go @@ -17,13 +17,13 @@ type Cache struct { prefix string } -func New(ctx context.Context, addr, password string, db int) (*Cache, error) { +func New(ctx context.Context, addr, password string, db int, keyPrefix string) (*Cache, error) { rdb := redis.NewClient(&redis.Options{Addr: addr, Password: password, DB: db}) if err := rdb.Ping(ctx).Err(); err != nil { _ = rdb.Close() return nil, err } - return &Cache{rdb: rdb, prefix: "code:"}, nil + return &Cache{rdb: rdb, prefix: keyPrefix + "code:"}, nil } func (c *Cache) key(code string) string { return c.prefix + code } diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index 1fb18be..f7545be 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -12,9 +12,10 @@ type Config struct { Store string DatabaseURL string - RedisAddr string - RedisPassword string - RedisDB int + RedisAddr string + RedisPassword string + RedisDB int + RedisKeyPrefix string // PublicURL is the externally reachable base (used to build OAuth callback // URLs). PostLoginRedirect is where users land after a successful login. @@ -76,6 +77,7 @@ func Load() Config { RedisAddr: env("REDIS_ADDR", "localhost:6379"), RedisPassword: env("REDIS_PASSWORD", ""), RedisDB: envInt("REDIS_DB", 0), + RedisKeyPrefix: env("REDIS_KEY_PREFIX", ""), PublicURL: env("PUBLIC_URL", "http://localhost:8080"), PostLoginRedirect: env("POST_LOGIN_REDIRECT", "/dashboard"), FrontendDist: env("FRONTEND_DIST", "./web"), diff --git a/backend/internal/di/container.go b/backend/internal/di/container.go index 04e20cd..4401ee0 100644 --- a/backend/internal/di/container.go +++ b/backend/internal/di/container.go @@ -56,7 +56,7 @@ func (c *Container) buildInfra(ctx context.Context) (*infra, error) { if err != nil { return nil, err } - cache, err := rediscache.New(ctx, c.cfg.RedisAddr, c.cfg.RedisPassword, c.cfg.RedisDB) + cache, err := rediscache.New(ctx, c.cfg.RedisAddr, c.cfg.RedisPassword, c.cfg.RedisDB, c.cfg.RedisKeyPrefix) if err != nil { pool.Close() return nil, err