Files
backend_fiesta/main.go
Suriya fab06bb33e Bridge global catalogue DB to per-store product catalogue
Adds a separate CatalogueDB (pgvector) connection alongside the main
nearledb, plus a new catalogue module (repository/service/controller/
routes) to browse it by brand, category, and keyword, with brand
optional so the whole ~237-product catalogue can be browsed unfiltered.

Adds the actual bridge: importing a catalogue product snapshots it into
the tenant's own products table (keyed on brand+catalogueid, since a
catalogue row's bare id is only unique within its own brand table),
then links it via the existing productlocations upsert. Re-importing
tops up stock and refreshes price instead of duplicating. Also adds an
imported-refs endpoint so the frontend can badge already-imported items
without diffing full product lists, and wires the new AWS S3 image
store used to resolve catalogue product photos.

Bumps Go/Docker to 1.24 for the AWS SDK dependency this needs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 17:34:20 +05:30

98 lines
1.7 KiB
Go

package main
import (
"fmt"
"log"
"nearle/db"
"nearle/facade"
"nearle/models"
"nearle/routes"
"os"
"os/signal"
"strings"
"syscall"
"time"
_ "time/tzdata"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/joho/godotenv"
"gorm.io/gorm"
)
func init() {
godotenv.Load()
}
func main() {
app := fiber.New()
app.Use(cors.New(cors.Config{
AllowHeaders: "Origin,Content-Type,Accept,Content-Length,Accept-Language,Accept-Encoding,Connection,Access-Control-Allow-Origin",
AllowOrigins: "*",
AllowCredentials: true,
AllowMethods: "GET,POST,HEAD,PUT,DELETE,PATCH,OPTIONS",
}))
fmt.Println("🌐 Connecting to databases...")
db.Connect()
fmt.Println("✅ Database connections established!")
// Ensure schema is updated
db.DB.AutoMigrate(&models.StockRequest{})
f := facade.NewFacade(db.DB, db.CatalogueDB)
routes.RegisterRoutes(app, f)
// Start server
go func() {
if err := app.Listen(":1122"); err != nil {
log.Fatal("Server failed to start:", err)
}
}()
gracefulShutdown()
}
func selectDBMiddleware(c *fiber.Ctx) error {
path := c.Path()
result := strings.Split(path, "/")
var flavour string
if len(result) > 1 {
flavour = result[1]
}
var currentDB *gorm.DB
switch flavour {
case "dev", "live":
currentDB = db.DB
}
if currentDB != nil {
c.Locals("DB", currentDB)
}
return c.Next()
}
func gracefulShutdown() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
<-c
fmt.Println("\nShutting down gracefully...")
// Normally: close db.DB_DEV and db.DB_LIVE
// Example:
// closeDB(db.DB_DEV)
// closeDB(db.DB_LIVE)
time.Sleep(2 * time.Second)
fmt.Println("Shutdown complete.")
os.Exit(0)
}