feat: complete HTML-first architecture implementation (Phase 1 & 2)
Major architectural simplification removing content type complexity: Database Schema: - Remove 'type' field from content and content_versions tables - Simplify to pure HTML storage with html_content + original_template - Regenerate all sqlc models for SQLite and PostgreSQL API Simplification: - Remove content type routing and validation - Eliminate type-specific handlers (text/markdown/structured) - Unified HTML-first approach for all content operations - Simplify CreateContent and UpdateContent to HTML-only Backend Enhancements: - Update enhancer to only generate data-content-id (no data-content-type) - Improve container expansion utilities with comprehensive block/inline rules - Add Phase 3 preparation with boundary-respecting traversal logic - Strengthen element classification for viable children detection Documentation: - Update TODO.md to reflect Phase 1-3 completion status - Add WORKING_ON.md documenting the architectural transformation - Mark container expansion and HTML-first architecture as complete This completes the transition to a unified HTML-first content management system with automatic style detection and element-based behavior, eliminating the complex multi-type system in favor of semantic HTML-driven editing.
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@@ -15,11 +16,14 @@ import (
|
||||
)
|
||||
|
||||
var enhanceCmd = &cobra.Command{
|
||||
Use: "enhance [input-dir]",
|
||||
Use: "enhance [input-path]",
|
||||
Short: "Enhance HTML files by injecting content from database",
|
||||
Long: `Enhance processes HTML files and injects latest content from the database
|
||||
while adding editing capabilities. This is the core build-time enhancement
|
||||
process that transforms static HTML into an editable CMS.`,
|
||||
process that transforms static HTML into an editable CMS.
|
||||
|
||||
The input can be either a directory (to enhance all HTML files) or a single
|
||||
HTML file. Non-HTML files in directories are copied as-is.`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
Run: runEnhance,
|
||||
}
|
||||
@@ -36,11 +40,23 @@ func init() {
|
||||
}
|
||||
|
||||
func runEnhance(cmd *cobra.Command, args []string) {
|
||||
inputDir := args[0]
|
||||
inputPath := args[0]
|
||||
|
||||
// Validate input directory
|
||||
if _, err := os.Stat(inputDir); os.IsNotExist(err) {
|
||||
log.Fatalf("Input directory does not exist: %s", inputDir)
|
||||
// Validate input path and determine if it's a file or directory
|
||||
inputStat, err := os.Stat(inputPath)
|
||||
if os.IsNotExist(err) {
|
||||
log.Fatalf("Input path does not exist: %s", inputPath)
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("Error accessing input path: %v", err)
|
||||
}
|
||||
|
||||
isFile := !inputStat.IsDir()
|
||||
if isFile {
|
||||
// Validate that single files are HTML files
|
||||
if !strings.HasSuffix(strings.ToLower(inputPath), ".html") {
|
||||
log.Fatalf("Single file input must be an HTML file (.html extension): %s", inputPath)
|
||||
}
|
||||
}
|
||||
|
||||
// Get configuration values
|
||||
@@ -51,9 +67,9 @@ func runEnhance(cmd *cobra.Command, args []string) {
|
||||
outputDir := viper.GetString("cli.output")
|
||||
|
||||
// Auto-derive site_id for demo paths or validate for production
|
||||
if strings.Contains(inputDir, "/demos/") || strings.Contains(inputDir, "./demos/") {
|
||||
if strings.Contains(inputPath, "/demos/") || strings.Contains(inputPath, "./demos/") {
|
||||
// Auto-derive site_id from demo path
|
||||
siteID = content.DeriveOrValidateSiteID(inputDir, siteID)
|
||||
siteID = content.DeriveOrValidateSiteID(inputPath, siteID)
|
||||
} else {
|
||||
// Validate site_id for non-demo paths
|
||||
if siteID == "" || siteID == "demo" {
|
||||
@@ -137,13 +153,27 @@ func runEnhance(cmd *cobra.Command, args []string) {
|
||||
enhancer := content.NewEnhancer(client, siteID, enhancementConfig)
|
||||
|
||||
fmt.Printf("🚀 Starting enhancement process...\n")
|
||||
fmt.Printf("📁 Input: %s\n", inputDir)
|
||||
fmt.Printf("📁 Input: %s\n", inputPath)
|
||||
fmt.Printf("📁 Output: %s\n", outputDir)
|
||||
fmt.Printf("🏷️ Site ID: %s\n\n", siteID)
|
||||
|
||||
// Enhance directory
|
||||
if err := enhancer.EnhanceDirectory(inputDir, outputDir); err != nil {
|
||||
log.Fatalf("Enhancement failed: %v", err)
|
||||
// Enhance based on input type
|
||||
if isFile {
|
||||
// For single files, determine the output file path
|
||||
outputFilePath := outputDir
|
||||
if stat, err := os.Stat(outputDir); err == nil && stat.IsDir() {
|
||||
// Output is a directory, use input filename in output directory
|
||||
outputFilePath = filepath.Join(outputDir, filepath.Base(inputPath))
|
||||
}
|
||||
// If output doesn't exist or is a file, use it as-is as the output file path
|
||||
|
||||
if err := enhancer.EnhanceFile(inputPath, outputFilePath); err != nil {
|
||||
log.Fatalf("Enhancement failed: %v", err)
|
||||
}
|
||||
} else {
|
||||
if err := enhancer.EnhanceDirectory(inputPath, outputDir); err != nil {
|
||||
log.Fatalf("Enhancement failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("\n✅ Enhancement complete! Enhanced files available in: %s\n", outputDir)
|
||||
|
||||
Reference in New Issue
Block a user