Add project scaffolding with fx DI, SQLite migrations, and healthcheck
- go.mod with git.eeqj.de/sneak/chat module - internal packages: globals, logger, config, db, healthcheck, middleware, handlers, server - SQLite database with embedded migration system (schema_migrations tracking) - Migration 001: schema_migrations table - Migration 002: channels table - Config with chat-specific vars (MAX_HISTORY, SESSION_TIMEOUT, MAX_MESSAGE_SIZE, MOTD, SERVER_NAME, FEDERATION_KEY) - Healthcheck endpoint at /.well-known/healthcheck.json - Makefile, .gitignore - cmd/chatd/main.go entry point
This commit is contained in:
96
internal/config/config.go
Normal file
96
internal/config/config.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"git.eeqj.de/sneak/chat/internal/globals"
|
||||
"git.eeqj.de/sneak/chat/internal/logger"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/fx"
|
||||
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
)
|
||||
|
||||
type ConfigParams struct {
|
||||
fx.In
|
||||
Globals *globals.Globals
|
||||
Logger *logger.Logger
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
DBURL string
|
||||
Debug bool
|
||||
MaintenanceMode bool
|
||||
MetricsPassword string
|
||||
MetricsUsername string
|
||||
Port int
|
||||
SentryDSN string
|
||||
MaxHistory int
|
||||
SessionTimeout int
|
||||
MaxMessageSize int
|
||||
MOTD string
|
||||
ServerName string
|
||||
FederationKey string
|
||||
params *ConfigParams
|
||||
log *slog.Logger
|
||||
}
|
||||
|
||||
func New(lc fx.Lifecycle, params ConfigParams) (*Config, error) {
|
||||
log := params.Logger.Get()
|
||||
name := params.Globals.Appname
|
||||
|
||||
viper.SetConfigName(name)
|
||||
viper.SetConfigType("yaml")
|
||||
viper.AddConfigPath(fmt.Sprintf("/etc/%s", name))
|
||||
viper.AddConfigPath(fmt.Sprintf("$HOME/.config/%s", name))
|
||||
viper.AutomaticEnv()
|
||||
|
||||
viper.SetDefault("DEBUG", "false")
|
||||
viper.SetDefault("MAINTENANCE_MODE", "false")
|
||||
viper.SetDefault("PORT", "8080")
|
||||
viper.SetDefault("DBURL", "file:./data.db?_journal_mode=WAL")
|
||||
viper.SetDefault("SENTRY_DSN", "")
|
||||
viper.SetDefault("METRICS_USERNAME", "")
|
||||
viper.SetDefault("METRICS_PASSWORD", "")
|
||||
viper.SetDefault("MAX_HISTORY", "10000")
|
||||
viper.SetDefault("SESSION_TIMEOUT", "86400")
|
||||
viper.SetDefault("MAX_MESSAGE_SIZE", "4096")
|
||||
viper.SetDefault("MOTD", "")
|
||||
viper.SetDefault("SERVER_NAME", "")
|
||||
viper.SetDefault("FEDERATION_KEY", "")
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
||||
// Config file not found is OK
|
||||
} else {
|
||||
log.Error("config file malformed", "error", err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
s := &Config{
|
||||
DBURL: viper.GetString("DBURL"),
|
||||
Debug: viper.GetBool("DEBUG"),
|
||||
Port: viper.GetInt("PORT"),
|
||||
SentryDSN: viper.GetString("SENTRY_DSN"),
|
||||
MaintenanceMode: viper.GetBool("MAINTENANCE_MODE"),
|
||||
MetricsUsername: viper.GetString("METRICS_USERNAME"),
|
||||
MetricsPassword: viper.GetString("METRICS_PASSWORD"),
|
||||
MaxHistory: viper.GetInt("MAX_HISTORY"),
|
||||
SessionTimeout: viper.GetInt("SESSION_TIMEOUT"),
|
||||
MaxMessageSize: viper.GetInt("MAX_MESSAGE_SIZE"),
|
||||
MOTD: viper.GetString("MOTD"),
|
||||
ServerName: viper.GetString("SERVER_NAME"),
|
||||
FederationKey: viper.GetString("FEDERATION_KEY"),
|
||||
log: log,
|
||||
params: ¶ms,
|
||||
}
|
||||
|
||||
if s.Debug {
|
||||
params.Logger.EnableDebugLogging()
|
||||
s.log = params.Logger.Get()
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
Reference in New Issue
Block a user