turash/bugulma/backend/cmd/cli/internal/common.go
Damir Mukimov 000eab4740
Major repository reorganization and missing backend endpoints implementation
Repository Structure:
- Move files from cluttered root directory into organized structure
- Create archive/ for archived data and scraper results
- Create bugulma/ for the complete application (frontend + backend)
- Create data/ for sample datasets and reference materials
- Create docs/ for comprehensive documentation structure
- Create scripts/ for utility scripts and API tools

Backend Implementation:
- Implement 3 missing backend endpoints identified in gap analysis:
  * GET /api/v1/organizations/{id}/matching/direct - Direct symbiosis matches
  * GET /api/v1/users/me/organizations - User organizations
  * POST /api/v1/proposals/{id}/status - Update proposal status
- Add complete proposal domain model, repository, and service layers
- Create database migration for proposals table
- Fix CLI server command registration issue

API Documentation:
- Add comprehensive proposals.md API documentation
- Update README.md with Users and Proposals API sections
- Document all request/response formats, error codes, and business rules

Code Quality:
- Follow existing Go backend architecture patterns
- Add proper error handling and validation
- Match frontend expected response schemas
- Maintain clean separation of concerns (handler -> service -> repository)
2025-11-25 06:01:16 +01:00

83 lines
2.1 KiB
Go

package internal
import (
"context"
"fmt"
"log"
"bugulma/backend/pkg/config"
"github.com/joho/godotenv"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
// Config is an alias for config.Config to avoid import conflicts
type Config = config.Config
// LoadConfig loads configuration from environment variables and .env file
func LoadConfig(configPath string) (*Config, error) {
// Load .env file if it exists
if configPath != "" {
if err := godotenv.Load(configPath); err != nil {
log.Printf("Warning: Failed to load config file %s: %v", configPath, err)
}
} else {
// Try default .env file
if err := godotenv.Load(); err != nil {
log.Printf("Warning: .env file not found, using environment variables")
}
}
cfg := config.Load()
return cfg, nil
}
// ConnectPostgres establishes a PostgreSQL connection using the provided config
func ConnectPostgres(cfg *Config) (*gorm.DB, error) {
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s",
cfg.PostgresHost,
cfg.PostgresPort,
cfg.PostgresUser,
cfg.PostgresPassword,
cfg.PostgresDB,
cfg.PostgresSSLMode,
)
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
return nil, fmt.Errorf("failed to connect to PostgreSQL: %w", err)
}
return db, nil
}
// ConnectNeo4j establishes a Neo4j connection using the provided config
// Returns nil if Neo4j is disabled or connection fails
func ConnectNeo4j(cfg *Config) (neo4j.DriverWithContext, error) {
if !cfg.Neo4jEnabled {
return nil, nil
}
if cfg.Neo4jURI == "" {
return nil, fmt.Errorf("Neo4j URI not configured")
}
auth := neo4j.BasicAuth(cfg.Neo4jUsername, cfg.Neo4jPassword, "")
driver, err := neo4j.NewDriverWithContext(cfg.Neo4jURI, auth)
if err != nil {
return nil, fmt.Errorf("failed to create Neo4j driver: %w", err)
}
// Verify connectivity
ctx := context.Background()
if err := driver.VerifyConnectivity(ctx); err != nil {
driver.Close(ctx)
return nil, fmt.Errorf("failed to verify Neo4j connectivity: %w", err)
}
return driver, nil
}