feat: implement server-hosted static site enhancement with real-time content updates

- Add SiteManager for registering and managing static sites with file-based enhancement
- Implement EnhanceInPlace method for in-place file modification using database content
- Integrate automatic file enhancement triggers in UpdateContent API handler
- Add comprehensive site configuration support in insertr.yaml with auto-enhancement
- Extend serve command to automatically register and manage configured sites
- Add backup system for original files before enhancement
- Support multi-site hosting with individual auto-enhancement settings
- Update documentation for server-hosted enhancement workflow

This enables real-time content deployment where database content changes
immediately update static files without requiring rebuilds or redeployment.
The database remains the single source of truth while maintaining static
file performance benefits.
This commit is contained in:
2025-09-10 23:05:09 +02:00
parent 21ce92bf61
commit 8d92c6477b
9 changed files with 576 additions and 9 deletions

View File

@@ -5,6 +5,7 @@ import (
"database/sql"
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
"strings"
@@ -12,6 +13,7 @@ import (
"github.com/gorilla/mux"
"github.com/insertr/insertr/internal/auth"
"github.com/insertr/insertr/internal/content"
"github.com/insertr/insertr/internal/db"
"github.com/insertr/insertr/internal/db/postgresql"
"github.com/insertr/insertr/internal/db/sqlite"
@@ -21,6 +23,7 @@ import (
type ContentHandler struct {
database *db.Database
authService *auth.AuthService
siteManager *content.SiteManager
}
// NewContentHandler creates a new content handler
@@ -28,9 +31,15 @@ func NewContentHandler(database *db.Database, authService *auth.AuthService) *Co
return &ContentHandler{
database: database,
authService: authService,
siteManager: nil, // Will be set via SetSiteManager
}
}
// SetSiteManager sets the site manager for file enhancement
func (h *ContentHandler) SetSiteManager(siteManager *content.SiteManager) {
h.siteManager = siteManager
}
// GetContent handles GET /api/content/{id}
func (h *ContentHandler) GetContent(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
@@ -315,6 +324,17 @@ func (h *ContentHandler) UpdateContent(w http.ResponseWriter, r *http.Request) {
item := h.convertToAPIContent(upsertedContent)
// Trigger file enhancement if site is registered for auto-enhancement
if h.siteManager != nil && h.siteManager.IsAutoEnhanceEnabled(siteID) {
go func() {
if err := h.siteManager.EnhanceSite(siteID); err != nil {
log.Printf("⚠️ Failed to enhance site %s: %v", siteID, err)
} else {
log.Printf("✅ Enhanced files for site %s", siteID)
}
}()
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(item)
}