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:
173
output/cmd/landing_main.go
Normal file
173
output/cmd/landing_main.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type LaunchRequest struct {
|
||||
Domain string `json:"domain" binding:"required"`
|
||||
Email string `json:"email" binding:"required,email"`
|
||||
CardNumber string `json:"cardNumber" binding:"required"`
|
||||
}
|
||||
|
||||
type LaunchResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
CustomerID string `json:"customer_id,omitempty"`
|
||||
Domain string `json:"domain,omitempty"`
|
||||
Provisioned bool `json:"provisioned,omitempty"`
|
||||
}
|
||||
|
||||
type HealthResponse struct {
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Set Gin mode
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
|
||||
r := gin.Default()
|
||||
|
||||
// Enable CORS for all origins
|
||||
r.Use(func(c *gin.Context) {
|
||||
c.Header("Access-Control-Allow-Origin", "*")
|
||||
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
||||
c.Header("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
|
||||
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
c.AbortWithStatus(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
})
|
||||
|
||||
// Serve landing page
|
||||
r.GET("/", func(c *gin.Context) {
|
||||
c.File("web/templates/landing.html")
|
||||
})
|
||||
|
||||
// Health check endpoint
|
||||
r.GET("/health", func(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, HealthResponse{
|
||||
Status: "ok",
|
||||
Message: "YourDreamNameHere API is running",
|
||||
Timestamp: time.Now(),
|
||||
Version: "1.0.0",
|
||||
})
|
||||
})
|
||||
|
||||
// API status endpoint
|
||||
r.GET("/api/status", func(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"status": "operational",
|
||||
"services": gin.H{
|
||||
"ovh": "connected",
|
||||
"stripe": "connected",
|
||||
"cloudron": "ready",
|
||||
"dolibarr": "connected",
|
||||
},
|
||||
"uptime": "0h 0m",
|
||||
})
|
||||
})
|
||||
|
||||
// Launch endpoint - handles the main business logic
|
||||
r.POST("/api/launch", func(c *gin.Context) {
|
||||
var req LaunchRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, LaunchResponse{
|
||||
Success: false,
|
||||
Message: fmt.Sprintf("Invalid request: %v", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate inputs
|
||||
if req.Domain == "" || req.Email == "" || req.CardNumber == "" {
|
||||
c.JSON(http.StatusBadRequest, LaunchResponse{
|
||||
Success: false,
|
||||
Message: "All fields are required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Generate customer ID
|
||||
customerID := uuid.New().String()
|
||||
|
||||
// Mock the provisioning process
|
||||
log.Printf("Starting provisioning for domain: %s, email: %s, customer: %s", req.Domain, req.Email, customerID)
|
||||
|
||||
// Simulate async processing
|
||||
go func() {
|
||||
// Mock domain registration
|
||||
time.Sleep(2 * time.Second)
|
||||
log.Printf("Domain %s registered for customer %s", req.Domain, customerID)
|
||||
|
||||
// Mock VPS provisioning
|
||||
time.Sleep(5 * time.Second)
|
||||
log.Printf("VPS provisioned for domain %s", req.Domain)
|
||||
|
||||
// Mock Cloudron installation
|
||||
time.Sleep(10 * time.Second)
|
||||
log.Printf("Cloudron installed for domain %s", req.Domain)
|
||||
|
||||
// Mock Dolibarr setup
|
||||
time.Sleep(3 * time.Second)
|
||||
log.Printf("Dolibarr configured for customer %s", customerID)
|
||||
|
||||
log.Printf("Provisioning completed for %s - customer %s", req.Domain, customerID)
|
||||
}()
|
||||
|
||||
// Return immediate response
|
||||
c.JSON(http.StatusOK, LaunchResponse{
|
||||
Success: true,
|
||||
Message: "Your hosting business is being provisioned! You'll receive an email when setup is complete.",
|
||||
CustomerID: customerID,
|
||||
Domain: req.Domain,
|
||||
Provisioned: false, // Will be true when async process completes
|
||||
})
|
||||
})
|
||||
|
||||
// Check provisioning status
|
||||
r.GET("/api/status/:customerID", func(c *gin.Context) {
|
||||
customerID := c.Param("customerID")
|
||||
|
||||
// Mock status check - in real implementation, check database
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"customer_id": customerID,
|
||||
"status": "provisioning",
|
||||
"progress": 25,
|
||||
"estimated_time": "15 minutes",
|
||||
"steps": []gin.H{
|
||||
{"name": "Domain Registration", "status": "completed"},
|
||||
{"name": "VPS Provisioning", "status": "in_progress"},
|
||||
{"name": "Cloudron Installation", "status": "pending"},
|
||||
{"name": "DNS Configuration", "status": "pending"},
|
||||
{"name": "Business Setup", "status": "pending"},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
// Static assets
|
||||
r.Static("/static", "./web/static")
|
||||
|
||||
// Start server
|
||||
port := "8080"
|
||||
log.Printf("🚀 YourDreamNameHere starting on port %s", port)
|
||||
log.Printf("📱 Landing page: http://localhost:%s", port)
|
||||
log.Printf("🔗 Health check: http://localhost:%s/health", port)
|
||||
log.Printf("📊 API status: http://localhost:%s/api/status", port)
|
||||
|
||||
if err := r.Run(":" + port); err != nil {
|
||||
log.Fatal("Failed to start server:", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user