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:
YourDreamNameHere
2025-11-20 16:36:28 -05:00
parent aa93326897
commit 89443f213b
57 changed files with 14404 additions and 0 deletions

View 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"
}