gohorsejobs/backend/cmd/manual_migrate/main.go
Tiago Yamamoto 841b1d780c feat: Email System, Avatar Upload, Email Templates UI, and Public Job Posting
- Backend: Email producer (LavinMQ), EmailService interface
- Backend: CRUD API for email_templates and email_settings
- Backend: avatar_url field in users table + UpdateMyProfile support
- Backend: StorageService for pre-signed URLs
- NestJS: Email consumer with Nodemailer and Handlebars
- Frontend: Email Templates admin pages (list/edit)
- Frontend: Updated profileApi.uploadAvatar with pre-signed URL flow
- Frontend: New /post-job public page (company registration + job creation wizard)
- Migrations: 027_create_email_system.sql, 028_add_avatar_url_to_users.sql
2025-12-26 12:21:34 -03:00

105 lines
2.5 KiB
Go

package main
import (
"database/sql"
"fmt"
"log"
"os"
"strings"
"github.com/joho/godotenv"
_ "github.com/lib/pq"
)
func main() {
pwd, _ := os.Getwd()
log.Printf("Current Working Directory: %s", pwd)
if err := godotenv.Load(".env"); err != nil {
// Try loading from parent if not in root
if err := godotenv.Load("../.env"); err != nil {
log.Println("No .env file found")
}
}
dbURL := os.Getenv("DATABASE_URL")
if dbURL == "" {
host := os.Getenv("DB_HOST")
port := os.Getenv("DB_PORT")
user := os.Getenv("DB_USER")
pass := os.Getenv("DB_PASSWORD")
name := os.Getenv("DB_NAME")
ssl := os.Getenv("DB_SSLMODE")
if host != "" {
dbURL = fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=%s", user, pass, host, port, name, ssl)
} else {
// Last resort
dbURL = "postgres://postgres:postgres@localhost:5432/gohorsejobs?sslmode=disable"
}
}
db, err := sql.Open("postgres", dbURL)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// List of migrations to run (in order)
migrations := []string{
"024_create_external_services_credentials.sql",
"025_create_chat_tables.sql",
"026_create_system_settings.sql",
"027_create_email_system.sql",
"028_add_avatar_url_to_users.sql",
}
for _, migFile := range migrations {
log.Printf("Processing migration: %s", migFile)
// Try multiple paths
paths := []string{
"migrations/" + migFile,
"backend/migrations/" + migFile,
"../migrations/" + migFile,
"/home/yamamoto/lab/gohorsejobs/backend/migrations/" + migFile,
}
var content []byte
var readErr error
for _, p := range paths {
content, readErr = os.ReadFile(p)
if readErr == nil {
log.Printf("Found migration at: %s", p)
break
}
}
if content == nil {
log.Fatalf("Could not find migration file %s. Last error: %v", migFile, readErr)
}
statements := strings.Split(string(content), ";")
for _, stmt := range statements {
trimmed := strings.TrimSpace(stmt)
if trimmed == "" {
continue
}
log.Printf("Executing: %s", trimmed)
_, err = db.Exec(trimmed)
if err != nil {
if strings.Contains(err.Error(), "already exists") {
log.Printf("Warning (ignored): %v", err)
} else {
log.Printf("FAILED executing: %s\nError: %v", trimmed, err)
// Verify if we should stop. For now, continue best effort or fail?
// Use fatal for critical schema errors not "already exists"
log.Fatal(err)
}
}
}
log.Printf("Migration %s applied successfully", migFile)
}
fmt.Println("All requested migrations applied.")
}