feat: implement core Go application with web server
- Add Go modules with required dependencies (Gin, UUID, JWT, etc.) - Implement main web server with landing page endpoint - Add comprehensive API endpoints for health and status - Include proper error handling and request validation - Set up CORS middleware and security headers
This commit is contained in:
239
output/internal/config/config.go
Normal file
239
output/internal/config/config.go
Normal file
@@ -0,0 +1,239 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
App AppConfig
|
||||
Database DatabaseConfig
|
||||
JWT JWTConfig
|
||||
Stripe StripeConfig
|
||||
OVH OVHConfig
|
||||
Cloudron CloudronConfig
|
||||
Dolibarr DolibarrConfig
|
||||
Email EmailConfig
|
||||
Redis RedisConfig
|
||||
Logging LoggingConfig
|
||||
Security SecurityConfig
|
||||
}
|
||||
|
||||
type AppConfig struct {
|
||||
Name string
|
||||
Env string
|
||||
Port string
|
||||
Host string
|
||||
}
|
||||
|
||||
type DatabaseConfig struct {
|
||||
Host string
|
||||
Port string
|
||||
User string
|
||||
Password string
|
||||
DBName string
|
||||
SSLMode string
|
||||
}
|
||||
|
||||
type JWTConfig struct {
|
||||
Secret string
|
||||
Expiry time.Duration
|
||||
}
|
||||
|
||||
type StripeConfig struct {
|
||||
PublicKey string
|
||||
SecretKey string
|
||||
WebhookSecret string
|
||||
PriceID string
|
||||
}
|
||||
|
||||
type OVHConfig struct {
|
||||
Endpoint string
|
||||
ApplicationKey string
|
||||
ApplicationSecret string
|
||||
ConsumerKey string
|
||||
}
|
||||
|
||||
type CloudronConfig struct {
|
||||
APIVersion string
|
||||
InstallTimeout time.Duration
|
||||
}
|
||||
|
||||
type DolibarrConfig struct {
|
||||
URL string
|
||||
APIToken string
|
||||
}
|
||||
|
||||
type EmailConfig struct {
|
||||
SMTPHost string
|
||||
SMTPPort string
|
||||
SMTPUser string
|
||||
SMTPPassword string
|
||||
From string
|
||||
}
|
||||
|
||||
type RedisConfig struct {
|
||||
Host string
|
||||
Port string
|
||||
Password string
|
||||
DB int
|
||||
}
|
||||
|
||||
type LoggingConfig struct {
|
||||
Level string
|
||||
Format string
|
||||
}
|
||||
|
||||
type SecurityConfig struct {
|
||||
CORSOrigins []string
|
||||
RateLimitRequests int
|
||||
RateLimitWindow time.Duration
|
||||
}
|
||||
|
||||
func Load() (*Config, error) {
|
||||
// Load .env file if it exists
|
||||
if err := godotenv.Load("configs/.env"); err != nil && !os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("error loading .env file: %w", err)
|
||||
}
|
||||
|
||||
config := &Config{
|
||||
App: AppConfig{
|
||||
Name: getEnv("APP_NAME", "YourDreamNameHere"),
|
||||
Env: getEnv("APP_ENV", "development"),
|
||||
Port: getEnv("APP_PORT", "8080"),
|
||||
Host: getEnv("APP_HOST", "0.0.0.0"),
|
||||
},
|
||||
Database: DatabaseConfig{
|
||||
Host: getEnv("DB_HOST", "localhost"),
|
||||
Port: getEnv("DB_PORT", "5432"),
|
||||
User: getEnv("DB_USER", "ydn_user"),
|
||||
Password: getEnv("DB_PASSWORD", ""),
|
||||
DBName: getEnv("DB_NAME", "ydn_db"),
|
||||
SSLMode: getEnv("DB_SSLMODE", "disable"),
|
||||
},
|
||||
JWT: JWTConfig{
|
||||
Secret: getEnv("JWT_SECRET", ""),
|
||||
Expiry: getDurationEnv("JWT_EXPIRY", 24*time.Hour),
|
||||
},
|
||||
Stripe: StripeConfig{
|
||||
PublicKey: getEnv("STRIPE_PUBLIC_KEY", ""),
|
||||
SecretKey: getEnv("STRIPE_SECRET_KEY", ""),
|
||||
WebhookSecret: getEnv("STRIPE_WEBHOOK_SECRET", ""),
|
||||
PriceID: getEnv("STRIPE_PRICE_ID", ""),
|
||||
},
|
||||
OVH: OVHConfig{
|
||||
Endpoint: getEnv("OVH_ENDPOINT", "ovh-eu"),
|
||||
ApplicationKey: getEnv("OVH_APPLICATION_KEY", ""),
|
||||
ApplicationSecret: getEnv("OVH_APPLICATION_SECRET", ""),
|
||||
ConsumerKey: getEnv("OVH_CONSUMER_KEY", ""),
|
||||
},
|
||||
Cloudron: CloudronConfig{
|
||||
APIVersion: getEnv("CLOUDRON_API_VERSION", "v1"),
|
||||
InstallTimeout: getDurationEnv("CLOUDRON_INSTALL_TIMEOUT", 30*time.Minute),
|
||||
},
|
||||
Dolibarr: DolibarrConfig{
|
||||
URL: getEnv("DOLIBARR_URL", ""),
|
||||
APIToken: getEnv("DOLIBARR_API_TOKEN", ""),
|
||||
},
|
||||
Email: EmailConfig{
|
||||
SMTPHost: getEnv("SMTP_HOST", ""),
|
||||
SMTPPort: getEnv("SMTP_PORT", "587"),
|
||||
SMTPUser: getEnv("SMTP_USER", ""),
|
||||
SMTPPassword: getEnv("SMTP_PASSWORD", ""),
|
||||
From: getEnv("SMTP_FROM", "noreply@yourdreamnamehere.com"),
|
||||
},
|
||||
Redis: RedisConfig{
|
||||
Host: getEnv("REDIS_HOST", "localhost"),
|
||||
Port: getEnv("REDIS_PORT", "6379"),
|
||||
Password: getEnv("REDIS_PASSWORD", ""),
|
||||
DB: getIntEnv("REDIS_DB", 0),
|
||||
},
|
||||
Logging: LoggingConfig{
|
||||
Level: getEnv("LOG_LEVEL", "info"),
|
||||
Format: getEnv("LOG_FORMAT", "json"),
|
||||
},
|
||||
Security: SecurityConfig{
|
||||
CORSOrigins: strings.Split(getEnv("CORS_ORIGINS", "http://localhost:3000"), ","),
|
||||
RateLimitRequests: getIntEnv("RATE_LIMIT_REQUESTS", 100),
|
||||
RateLimitWindow: getDurationEnv("RATE_LIMIT_WINDOW", time.Minute),
|
||||
},
|
||||
}
|
||||
|
||||
// Validate required configuration
|
||||
if err := config.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func (c *Config) validate() error {
|
||||
if c.JWT.Secret == "" {
|
||||
return fmt.Errorf("JWT_SECRET is required")
|
||||
}
|
||||
if c.Stripe.SecretKey == "" {
|
||||
return fmt.Errorf("STRIPE_SECRET_KEY is required")
|
||||
}
|
||||
if c.Stripe.PriceID == "" {
|
||||
return fmt.Errorf("STRIPE_PRICE_ID is required")
|
||||
}
|
||||
if c.OVH.ApplicationKey == "" {
|
||||
return fmt.Errorf("OVH_APPLICATION_KEY is required")
|
||||
}
|
||||
if c.OVH.ApplicationSecret == "" {
|
||||
return fmt.Errorf("OVH_APPLICATION_SECRET is required")
|
||||
}
|
||||
if c.OVH.ConsumerKey == "" {
|
||||
return fmt.Errorf("OVH_CONSUMER_KEY is required")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getEnv(key, defaultValue string) string {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
return value
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func getIntEnv(key string, defaultValue int) int {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
if intValue, err := strconv.Atoi(value); err == nil {
|
||||
return intValue
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func getDurationEnv(key string, defaultValue time.Duration) time.Duration {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
if duration, err := time.ParseDuration(value); err == nil {
|
||||
return duration
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func (c *Config) DatabaseDSN() string {
|
||||
return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
|
||||
c.Database.Host,
|
||||
c.Database.Port,
|
||||
c.Database.User,
|
||||
c.Database.Password,
|
||||
c.Database.DBName,
|
||||
c.Database.SSLMode,
|
||||
)
|
||||
}
|
||||
|
||||
func (c *Config) IsDevelopment() bool {
|
||||
return c.App.Env == "development"
|
||||
}
|
||||
|
||||
func (c *Config) IsProduction() bool {
|
||||
return c.App.Env == "production"
|
||||
}
|
||||
Reference in New Issue
Block a user