` tags get direct URL+text editor, `` tags get rich text with formatting
+- **Container transformation**: Syntactic sugar working per CLASSES.md specification
+- **Simplified frontend**: No runtime container expansion - backend handles transformation
+- **Zero breaking changes**: User-facing functionality maintained while simplifying backend
+
+### š **System Now Works As**:
+```javascript
+// Single path for ALL .insertr elements
+class StyleAwareEditor {
+ async initialize() {
+ // 1. Always extract HTML with preservation
+ this.originalContent = this.htmlEngine.extractForEditing(this.element);
+
+ // 2. Always detect styles from nested elements
+ this.detectedStyles = this.styleEngine.detectStyles(this.element);
+
+ // 3. Element-based UX routing
+ if (this.isMultiPropertyElement()) {
+ this.createDirectEditor(); // URL+text for links
+ } else {
+ this.createRichEditor(); // Rich text with styles
+ }
+ }
+}
+```
+
+**Confidence Level**: High - All changes successfully implemented and tested. Server starts correctly, builds complete successfully.
diff --git a/cmd/enhance.go b/cmd/enhance.go
index f566049..8b9f3ab 100644
--- a/cmd/enhance.go
+++ b/cmd/enhance.go
@@ -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)
diff --git a/internal/api/handlers.go b/internal/api/handlers.go
index 5789ecd..76f4289 100644
--- a/internal/api/handlers.go
+++ b/internal/api/handlers.go
@@ -314,14 +314,7 @@ func (h *ContentHandler) CreateContent(w http.ResponseWriter, r *http.Request) {
}
}
- // Determine content type: use provided type, fallback to existing type, default to "text"
- contentType := req.Type
- if contentType == "" && contentExists {
- contentType = h.getContentType(existingContent)
- }
- if contentType == "" {
- contentType = "text" // default type for new content
- }
+ // HTML-first approach: no content type needed
var content interface{}
var err error
@@ -333,7 +326,6 @@ func (h *ContentHandler) CreateContent(w http.ResponseWriter, r *http.Request) {
SiteID: siteID,
HtmlContent: req.HTMLContent,
OriginalTemplate: toNullString(req.OriginalTemplate),
- Type: contentType,
LastEditedBy: userID,
})
case "postgresql":
@@ -342,7 +334,6 @@ func (h *ContentHandler) CreateContent(w http.ResponseWriter, r *http.Request) {
SiteID: siteID,
HtmlContent: req.HTMLContent,
OriginalTemplate: toNullString(req.OriginalTemplate),
- Type: contentType,
LastEditedBy: userID,
})
default:
@@ -447,7 +438,6 @@ func (h *ContentHandler) UpdateContent(w http.ResponseWriter, r *http.Request) {
case "sqlite3":
updatedContent, err = h.database.GetSQLiteQueries().UpdateContent(context.Background(), sqlite.UpdateContentParams{
HtmlContent: req.HTMLContent,
- Type: h.getContentType(existingContent),
LastEditedBy: userID,
ID: contentID,
SiteID: siteID,
@@ -455,7 +445,6 @@ func (h *ContentHandler) UpdateContent(w http.ResponseWriter, r *http.Request) {
case "postgresql":
updatedContent, err = h.database.GetPostgreSQLQueries().UpdateContent(context.Background(), postgresql.UpdateContentParams{
HtmlContent: req.HTMLContent,
- Type: h.getContentType(existingContent),
LastEditedBy: userID,
ID: contentID,
SiteID: siteID,
@@ -664,7 +653,6 @@ func (h *ContentHandler) RollbackContent(w http.ResponseWriter, r *http.Request)
sqliteVersion := targetVersion.(sqlite.ContentVersion)
updatedContent, err = h.database.GetSQLiteQueries().UpdateContent(context.Background(), sqlite.UpdateContentParams{
HtmlContent: sqliteVersion.HtmlContent,
- Type: sqliteVersion.Type,
LastEditedBy: userID,
ID: contentID,
SiteID: siteID,
@@ -673,7 +661,6 @@ func (h *ContentHandler) RollbackContent(w http.ResponseWriter, r *http.Request)
pgVersion := targetVersion.(postgresql.ContentVersion)
updatedContent, err = h.database.GetPostgreSQLQueries().UpdateContent(context.Background(), postgresql.UpdateContentParams{
HtmlContent: pgVersion.HtmlContent,
- Type: pgVersion.Type,
LastEditedBy: userID,
ID: contentID,
SiteID: siteID,
@@ -704,7 +691,6 @@ func (h *ContentHandler) convertToAPIContent(content interface{}) ContentItem {
SiteID: c.SiteID,
HTMLContent: c.HtmlContent,
OriginalTemplate: fromNullString(c.OriginalTemplate),
- Type: c.Type,
CreatedAt: time.Unix(c.CreatedAt, 0),
UpdatedAt: time.Unix(c.UpdatedAt, 0),
LastEditedBy: c.LastEditedBy,
@@ -716,7 +702,6 @@ func (h *ContentHandler) convertToAPIContent(content interface{}) ContentItem {
SiteID: c.SiteID,
HTMLContent: c.HtmlContent,
OriginalTemplate: fromNullString(c.OriginalTemplate),
- Type: c.Type,
CreatedAt: time.Unix(c.CreatedAt, 0),
UpdatedAt: time.Unix(c.UpdatedAt, 0),
LastEditedBy: c.LastEditedBy,
@@ -757,7 +742,6 @@ func (h *ContentHandler) convertToAPIVersionList(versionList interface{}) []Cont
SiteID: version.SiteID,
HTMLContent: version.HtmlContent,
OriginalTemplate: fromNullString(version.OriginalTemplate),
- Type: version.Type,
CreatedAt: time.Unix(version.CreatedAt, 0),
CreatedBy: version.CreatedBy,
}
@@ -773,7 +757,6 @@ func (h *ContentHandler) convertToAPIVersionList(versionList interface{}) []Cont
SiteID: version.SiteID,
HTMLContent: version.HtmlContent,
OriginalTemplate: fromNullString(version.OriginalTemplate),
- Type: version.Type,
CreatedAt: time.Unix(version.CreatedAt, 0),
CreatedBy: version.CreatedBy,
}
@@ -792,7 +775,6 @@ func (h *ContentHandler) createContentVersion(content interface{}) error {
SiteID: c.SiteID,
HtmlContent: c.HtmlContent,
OriginalTemplate: c.OriginalTemplate,
- Type: c.Type,
CreatedBy: c.LastEditedBy,
})
case "postgresql":
@@ -802,23 +784,12 @@ func (h *ContentHandler) createContentVersion(content interface{}) error {
SiteID: c.SiteID,
HtmlContent: c.HtmlContent,
OriginalTemplate: c.OriginalTemplate,
- Type: c.Type,
CreatedBy: c.LastEditedBy,
})
}
return fmt.Errorf("unsupported database type")
}
-func (h *ContentHandler) getContentType(content interface{}) string {
- switch h.database.GetDBType() {
- case "sqlite3":
- return content.(sqlite.Content).Type
- case "postgresql":
- return content.(postgresql.Content).Type
- }
- return ""
-}
-
func (h *ContentHandler) versionMatches(version interface{}, contentID, siteID string) bool {
switch h.database.GetDBType() {
case "sqlite3":
diff --git a/internal/api/models.go b/internal/api/models.go
index 043a356..2e94b37 100644
--- a/internal/api/models.go
+++ b/internal/api/models.go
@@ -8,7 +8,6 @@ type ContentItem struct {
SiteID string `json:"site_id"`
HTMLContent string `json:"html_content"`
OriginalTemplate string `json:"original_template"`
- Type string `json:"type"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
LastEditedBy string `json:"last_edited_by"`
@@ -20,7 +19,6 @@ type ContentVersion struct {
SiteID string `json:"site_id"`
HTMLContent string `json:"html_content"`
OriginalTemplate string `json:"original_template"`
- Type string `json:"type"`
CreatedAt time.Time `json:"created_at"`
CreatedBy string `json:"created_by"`
}
@@ -48,7 +46,6 @@ type CreateContentRequest struct {
FilePath string `json:"file_path"` // File path for consistent ID generation
HTMLContent string `json:"html_content"` // HTML content value
OriginalTemplate string `json:"original_template"` // Original template markup
- Type string `json:"type"` // Content type
SiteID string `json:"site_id,omitempty"` // Site identifier
CreatedBy string `json:"created_by,omitempty"` // User who created the content
}
diff --git a/internal/content/client.go b/internal/content/client.go
index a4b48c5..5907f54 100644
--- a/internal/content/client.go
+++ b/internal/content/client.go
@@ -166,7 +166,7 @@ func (c *HTTPClient) GetAllContent(siteID string) (map[string]engine.ContentItem
}
// CreateContent creates a new content item via HTTP API
-func (c *HTTPClient) CreateContent(siteID, contentID, htmlContent, originalTemplate, contentType, lastEditedBy string) (*engine.ContentItem, error) {
+func (c *HTTPClient) CreateContent(siteID, contentID, htmlContent, originalTemplate, lastEditedBy string) (*engine.ContentItem, error) {
// For now, HTTPClient CreateContent is not implemented for enhancer use
// This would typically be used in API-driven enhancement scenarios
return nil, fmt.Errorf("CreateContent not implemented for HTTPClient - use DatabaseClient for enhancement")
diff --git a/internal/content/database.go b/internal/content/database.go
index 5015870..7c55462 100644
--- a/internal/content/database.go
+++ b/internal/content/database.go
@@ -144,7 +144,6 @@ func (d *DatabaseClient) convertToContentItem(content interface{}) engine.Conten
SiteID: c.SiteID,
HTMLContent: c.HtmlContent,
OriginalTemplate: getStringFromNullString(c.OriginalTemplate),
- Type: c.Type,
UpdatedAt: time.Unix(c.UpdatedAt, 0).Format(time.RFC3339),
}
case "postgresql":
@@ -154,7 +153,6 @@ func (d *DatabaseClient) convertToContentItem(content interface{}) engine.Conten
SiteID: c.SiteID,
HTMLContent: c.HtmlContent,
OriginalTemplate: getStringFromNullString(c.OriginalTemplate),
- Type: c.Type,
UpdatedAt: time.Unix(c.UpdatedAt, 0).Format(time.RFC3339),
}
}
@@ -182,8 +180,8 @@ func (d *DatabaseClient) convertToContentItemList(contentList interface{}) []eng
return []engine.ContentItem{} // Should never happen
}
-// CreateContent creates a new content item
-func (c *DatabaseClient) CreateContent(siteID, contentID, htmlContent, originalTemplate, contentType, lastEditedBy string) (*engine.ContentItem, error) {
+// CreateContent creates a new content item
+func (c *DatabaseClient) CreateContent(siteID, contentID, htmlContent, originalTemplate, lastEditedBy string) (*engine.ContentItem, error) {
switch c.db.GetDBType() {
case "sqlite3":
content, err := c.db.GetSQLiteQueries().CreateContent(context.Background(), sqlite.CreateContentParams{
@@ -191,7 +189,6 @@ func (c *DatabaseClient) CreateContent(siteID, contentID, htmlContent, originalT
SiteID: siteID,
HtmlContent: htmlContent,
OriginalTemplate: toNullString(originalTemplate),
- Type: contentType,
LastEditedBy: lastEditedBy,
})
if err != nil {
@@ -202,7 +199,6 @@ func (c *DatabaseClient) CreateContent(siteID, contentID, htmlContent, originalT
SiteID: content.SiteID,
HTMLContent: content.HtmlContent,
OriginalTemplate: getStringFromNullString(content.OriginalTemplate),
- Type: content.Type,
LastEditedBy: content.LastEditedBy,
}, nil
@@ -212,7 +208,6 @@ func (c *DatabaseClient) CreateContent(siteID, contentID, htmlContent, originalT
SiteID: siteID,
HtmlContent: htmlContent,
OriginalTemplate: toNullString(originalTemplate),
- Type: contentType,
LastEditedBy: lastEditedBy,
})
if err != nil {
@@ -223,7 +218,6 @@ func (c *DatabaseClient) CreateContent(siteID, contentID, htmlContent, originalT
SiteID: content.SiteID,
HTMLContent: content.HtmlContent,
OriginalTemplate: getStringFromNullString(content.OriginalTemplate),
- Type: content.Type,
LastEditedBy: content.LastEditedBy,
}, nil
diff --git a/internal/content/mock.go b/internal/content/mock.go
index 5fb0ebe..4bb41b0 100644
--- a/internal/content/mock.go
+++ b/internal/content/mock.go
@@ -20,15 +20,15 @@ func NewMockClient() *MockClient {
ID: "navbar-logo-2b10ad",
SiteID: "demo",
HTMLContent: "Acme Consulting Solutions",
- Type: "text",
- UpdatedAt: time.Now().Format(time.RFC3339),
+
+ UpdatedAt: time.Now().Format(time.RFC3339),
},
"navbar-logo-2b10ad-a44bad": {
ID: "navbar-logo-2b10ad-a44bad",
SiteID: "demo",
HTMLContent: "Acme Business Advisors",
- Type: "text",
- UpdatedAt: time.Now().Format(time.RFC3339),
+
+ UpdatedAt: time.Now().Format(time.RFC3339),
},
// Hero Section - index.html (updated with actual IDs)
@@ -36,22 +36,22 @@ func NewMockClient() *MockClient {
ID: "hero-title-7cfeea",
SiteID: "demo",
HTMLContent: "Transform Your Business with Strategic Expertise",
- Type: "text",
- UpdatedAt: time.Now().Format(time.RFC3339),
+
+ UpdatedAt: time.Now().Format(time.RFC3339),
},
"hero-lead-e47475": {
ID: "hero-lead-e47475",
SiteID: "demo",
HTMLContent: "We help ambitious businesses grow through strategic planning, process optimization, and digital transformation. Our team brings 20+ years of experience to accelerate your success.",
- Type: "text",
- UpdatedAt: time.Now().Format(time.RFC3339),
+
+ UpdatedAt: time.Now().Format(time.RFC3339),
},
"hero-link-76c620": {
ID: "hero-link-76c620",
SiteID: "demo",
HTMLContent: "Schedule Free Consultation",
- Type: "link",
- UpdatedAt: time.Now().Format(time.RFC3339),
+
+ UpdatedAt: time.Now().Format(time.RFC3339),
},
// Hero Section - about.html
@@ -59,15 +59,15 @@ func NewMockClient() *MockClient {
ID: "hero-title-c70343",
SiteID: "demo",
HTMLContent: "About Our Consulting Expertise",
- Type: "text",
- UpdatedAt: time.Now().Format(time.RFC3339),
+
+ UpdatedAt: time.Now().Format(time.RFC3339),
},
"hero-lead-673026": {
ID: "hero-lead-673026",
SiteID: "demo",
HTMLContent: "We're a team of experienced consultants dedicated to helping small businesses thrive in today's competitive marketplace through proven strategies.",
- Type: "text",
- UpdatedAt: time.Now().Format(time.RFC3339),
+
+ UpdatedAt: time.Now().Format(time.RFC3339),
},
// Services Section
@@ -75,15 +75,15 @@ func NewMockClient() *MockClient {
ID: "services-subtitle-c8927c",
SiteID: "demo",
HTMLContent: "Our Story",
- Type: "text",
- UpdatedAt: time.Now().Format(time.RFC3339),
+
+ UpdatedAt: time.Now().Format(time.RFC3339),
},
"services-text-0d96da": {
ID: "services-text-0d96da",
SiteID: "demo",
HTMLContent: "Founded in 2020, Acme Consulting emerged from a simple observation: small businesses needed access to the same high-quality strategic advice that large corporations receive, but in a format that was accessible, affordable, and actionable.",
- Type: "text",
- UpdatedAt: time.Now().Format(time.RFC3339),
+
+ UpdatedAt: time.Now().Format(time.RFC3339),
},
// Default fallback for any missing content
@@ -91,8 +91,8 @@ func NewMockClient() *MockClient {
ID: "default",
SiteID: "demo",
HTMLContent: "[Enhanced Content]",
- Type: "text",
- UpdatedAt: time.Now().Format(time.RFC3339),
+
+ UpdatedAt: time.Now().Format(time.RFC3339),
},
}
@@ -140,20 +140,19 @@ func (m *MockClient) GetAllContent(siteID string) (map[string]engine.ContentItem
}
// CreateContent creates a new mock content item
-func (m *MockClient) CreateContent(siteID, contentID, htmlContent, originalTemplate, contentType, lastEditedBy string) (*engine.ContentItem, error) {
+func (m *MockClient) CreateContent(siteID, contentID, htmlContent, originalTemplate, lastEditedBy string) (*engine.ContentItem, error) {
// For mock client, just create and store the item
item := engine.ContentItem{
ID: contentID,
SiteID: siteID,
HTMLContent: htmlContent,
OriginalTemplate: originalTemplate,
- Type: contentType,
UpdatedAt: time.Now().Format(time.RFC3339),
LastEditedBy: lastEditedBy,
}
-
+
// Store in mock data
m.data[contentID] = item
-
+
return &item, nil
}
diff --git a/internal/db/postgresql/content.sql.go b/internal/db/postgresql/content.sql.go
index 76e6e99..12bf81d 100644
--- a/internal/db/postgresql/content.sql.go
+++ b/internal/db/postgresql/content.sql.go
@@ -12,9 +12,9 @@ import (
)
const createContent = `-- name: CreateContent :one
-INSERT INTO content (id, site_id, html_content, original_template, type, last_edited_by)
-VALUES ($1, $2, $3, $4, $5, $6)
-RETURNING id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+INSERT INTO content (id, site_id, html_content, original_template, last_edited_by)
+VALUES ($1, $2, $3, $4, $5)
+RETURNING id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
`
type CreateContentParams struct {
@@ -22,7 +22,6 @@ type CreateContentParams struct {
SiteID string `json:"site_id"`
HtmlContent string `json:"html_content"`
OriginalTemplate sql.NullString `json:"original_template"`
- Type string `json:"type"`
LastEditedBy string `json:"last_edited_by"`
}
@@ -32,7 +31,6 @@ func (q *Queries) CreateContent(ctx context.Context, arg CreateContentParams) (C
arg.SiteID,
arg.HtmlContent,
arg.OriginalTemplate,
- arg.Type,
arg.LastEditedBy,
)
var i Content
@@ -41,7 +39,6 @@ func (q *Queries) CreateContent(ctx context.Context, arg CreateContentParams) (C
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.UpdatedAt,
&i.LastEditedBy,
@@ -75,7 +72,7 @@ func (q *Queries) DeleteContent(ctx context.Context, arg DeleteContentParams) er
}
const getAllContent = `-- name: GetAllContent :many
-SELECT id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+SELECT id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
FROM content
WHERE site_id = $1
ORDER BY updated_at DESC
@@ -95,7 +92,6 @@ func (q *Queries) GetAllContent(ctx context.Context, siteID string) ([]Content,
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.UpdatedAt,
&i.LastEditedBy,
@@ -114,7 +110,7 @@ func (q *Queries) GetAllContent(ctx context.Context, siteID string) ([]Content,
}
const getBulkContent = `-- name: GetBulkContent :many
-SELECT id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+SELECT id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
FROM content
WHERE site_id = $1 AND id IN ($2)
`
@@ -149,7 +145,6 @@ func (q *Queries) GetBulkContent(ctx context.Context, arg GetBulkContentParams)
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.UpdatedAt,
&i.LastEditedBy,
@@ -168,7 +163,7 @@ func (q *Queries) GetBulkContent(ctx context.Context, arg GetBulkContentParams)
}
const getContent = `-- name: GetContent :one
-SELECT id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+SELECT id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
FROM content
WHERE id = $1 AND site_id = $2
`
@@ -186,7 +181,6 @@ func (q *Queries) GetContent(ctx context.Context, arg GetContentParams) (Content
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.UpdatedAt,
&i.LastEditedBy,
@@ -196,14 +190,13 @@ func (q *Queries) GetContent(ctx context.Context, arg GetContentParams) (Content
const updateContent = `-- name: UpdateContent :one
UPDATE content
-SET html_content = $1, type = $2, last_edited_by = $3
-WHERE id = $4 AND site_id = $5
-RETURNING id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+SET html_content = $1, last_edited_by = $2
+WHERE id = $3 AND site_id = $4
+RETURNING id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
`
type UpdateContentParams struct {
HtmlContent string `json:"html_content"`
- Type string `json:"type"`
LastEditedBy string `json:"last_edited_by"`
ID string `json:"id"`
SiteID string `json:"site_id"`
@@ -212,7 +205,6 @@ type UpdateContentParams struct {
func (q *Queries) UpdateContent(ctx context.Context, arg UpdateContentParams) (Content, error) {
row := q.db.QueryRowContext(ctx, updateContent,
arg.HtmlContent,
- arg.Type,
arg.LastEditedBy,
arg.ID,
arg.SiteID,
@@ -223,7 +215,6 @@ func (q *Queries) UpdateContent(ctx context.Context, arg UpdateContentParams) (C
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.UpdatedAt,
&i.LastEditedBy,
@@ -232,13 +223,12 @@ func (q *Queries) UpdateContent(ctx context.Context, arg UpdateContentParams) (C
}
const upsertContent = `-- name: UpsertContent :one
-INSERT INTO content (id, site_id, html_content, original_template, type, last_edited_by)
-VALUES ($1, $2, $3, $4, $5, $6)
+INSERT INTO content (id, site_id, html_content, original_template, last_edited_by)
+VALUES ($1, $2, $3, $4, $5)
ON CONFLICT(id, site_id) DO UPDATE SET
html_content = EXCLUDED.html_content,
- type = EXCLUDED.type,
last_edited_by = EXCLUDED.last_edited_by
-RETURNING id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+RETURNING id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
`
type UpsertContentParams struct {
@@ -246,7 +236,6 @@ type UpsertContentParams struct {
SiteID string `json:"site_id"`
HtmlContent string `json:"html_content"`
OriginalTemplate sql.NullString `json:"original_template"`
- Type string `json:"type"`
LastEditedBy string `json:"last_edited_by"`
}
@@ -256,7 +245,6 @@ func (q *Queries) UpsertContent(ctx context.Context, arg UpsertContentParams) (C
arg.SiteID,
arg.HtmlContent,
arg.OriginalTemplate,
- arg.Type,
arg.LastEditedBy,
)
var i Content
@@ -265,7 +253,6 @@ func (q *Queries) UpsertContent(ctx context.Context, arg UpsertContentParams) (C
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.UpdatedAt,
&i.LastEditedBy,
diff --git a/internal/db/postgresql/models.go b/internal/db/postgresql/models.go
index 61be412..57722de 100644
--- a/internal/db/postgresql/models.go
+++ b/internal/db/postgresql/models.go
@@ -13,7 +13,6 @@ type Content struct {
SiteID string `json:"site_id"`
HtmlContent string `json:"html_content"`
OriginalTemplate sql.NullString `json:"original_template"`
- Type string `json:"type"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
LastEditedBy string `json:"last_edited_by"`
@@ -25,7 +24,6 @@ type ContentVersion struct {
SiteID string `json:"site_id"`
HtmlContent string `json:"html_content"`
OriginalTemplate sql.NullString `json:"original_template"`
- Type string `json:"type"`
CreatedAt int64 `json:"created_at"`
CreatedBy string `json:"created_by"`
}
diff --git a/internal/db/postgresql/schema.sql b/internal/db/postgresql/schema.sql
index 0e0b4ea..d1799d9 100644
--- a/internal/db/postgresql/schema.sql
+++ b/internal/db/postgresql/schema.sql
@@ -5,7 +5,6 @@ CREATE TABLE content (
site_id TEXT NOT NULL,
html_content TEXT NOT NULL,
original_template TEXT,
- type TEXT NOT NULL,
created_at BIGINT DEFAULT EXTRACT(EPOCH FROM NOW()) NOT NULL,
updated_at BIGINT DEFAULT EXTRACT(EPOCH FROM NOW()) NOT NULL,
last_edited_by TEXT DEFAULT 'system' NOT NULL,
@@ -19,7 +18,6 @@ CREATE TABLE content_versions (
site_id TEXT NOT NULL,
html_content TEXT NOT NULL,
original_template TEXT,
- type TEXT NOT NULL,
created_at BIGINT DEFAULT EXTRACT(EPOCH FROM NOW()) NOT NULL,
created_by TEXT DEFAULT 'system' NOT NULL
);
diff --git a/internal/db/postgresql/setup.sql b/internal/db/postgresql/setup.sql
index 4d8ef51..db1792b 100644
--- a/internal/db/postgresql/setup.sql
+++ b/internal/db/postgresql/setup.sql
@@ -4,7 +4,6 @@ CREATE TABLE IF NOT EXISTS content (
site_id TEXT NOT NULL,
html_content TEXT NOT NULL,
original_template TEXT,
- type TEXT NOT NULL CHECK (type IN ('text', 'link')),
created_at BIGINT DEFAULT (EXTRACT(EPOCH FROM NOW())) NOT NULL,
updated_at BIGINT DEFAULT (EXTRACT(EPOCH FROM NOW())) NOT NULL,
last_edited_by TEXT DEFAULT 'system' NOT NULL,
@@ -18,7 +17,6 @@ CREATE TABLE IF NOT EXISTS content_versions (
site_id TEXT NOT NULL,
html_content TEXT NOT NULL,
original_template TEXT,
- type TEXT NOT NULL,
created_at BIGINT DEFAULT (EXTRACT(EPOCH FROM NOW())) NOT NULL,
created_by TEXT DEFAULT 'system' NOT NULL
);
diff --git a/internal/db/postgresql/setup.sql.go b/internal/db/postgresql/setup.sql.go
index 0a100e4..f8efe47 100644
--- a/internal/db/postgresql/setup.sql.go
+++ b/internal/db/postgresql/setup.sql.go
@@ -57,7 +57,6 @@ CREATE TABLE IF NOT EXISTS content (
site_id TEXT NOT NULL,
html_content TEXT NOT NULL,
original_template TEXT,
- type TEXT NOT NULL CHECK (type IN ('text', 'link')),
created_at BIGINT DEFAULT (EXTRACT(EPOCH FROM NOW())) NOT NULL,
updated_at BIGINT DEFAULT (EXTRACT(EPOCH FROM NOW())) NOT NULL,
last_edited_by TEXT DEFAULT 'system' NOT NULL,
@@ -77,7 +76,6 @@ CREATE TABLE IF NOT EXISTS content_versions (
site_id TEXT NOT NULL,
html_content TEXT NOT NULL,
original_template TEXT,
- type TEXT NOT NULL,
created_at BIGINT DEFAULT (EXTRACT(EPOCH FROM NOW())) NOT NULL,
created_by TEXT DEFAULT 'system' NOT NULL
)
diff --git a/internal/db/postgresql/versions.sql.go b/internal/db/postgresql/versions.sql.go
index 9d9939e..bdf51c0 100644
--- a/internal/db/postgresql/versions.sql.go
+++ b/internal/db/postgresql/versions.sql.go
@@ -11,8 +11,8 @@ import (
)
const createContentVersion = `-- name: CreateContentVersion :exec
-INSERT INTO content_versions (content_id, site_id, html_content, original_template, type, created_by)
-VALUES ($1, $2, $3, $4, $5, $6)
+INSERT INTO content_versions (content_id, site_id, html_content, original_template, created_by)
+VALUES ($1, $2, $3, $4, $5)
`
type CreateContentVersionParams struct {
@@ -20,7 +20,6 @@ type CreateContentVersionParams struct {
SiteID string `json:"site_id"`
HtmlContent string `json:"html_content"`
OriginalTemplate sql.NullString `json:"original_template"`
- Type string `json:"type"`
CreatedBy string `json:"created_by"`
}
@@ -30,7 +29,6 @@ func (q *Queries) CreateContentVersion(ctx context.Context, arg CreateContentVer
arg.SiteID,
arg.HtmlContent,
arg.OriginalTemplate,
- arg.Type,
arg.CreatedBy,
)
return err
@@ -53,7 +51,7 @@ func (q *Queries) DeleteOldVersions(ctx context.Context, arg DeleteOldVersionsPa
const getAllVersionsForSite = `-- name: GetAllVersionsForSite :many
SELECT
- cv.version_id, cv.content_id, cv.site_id, cv.html_content, cv.original_template, cv.type, cv.created_at, cv.created_by,
+ cv.version_id, cv.content_id, cv.site_id, cv.html_content, cv.original_template, cv.created_at, cv.created_by,
c.html_content as current_html_content
FROM content_versions cv
LEFT JOIN content c ON cv.content_id = c.id AND cv.site_id = c.site_id
@@ -73,7 +71,6 @@ type GetAllVersionsForSiteRow struct {
SiteID string `json:"site_id"`
HtmlContent string `json:"html_content"`
OriginalTemplate sql.NullString `json:"original_template"`
- Type string `json:"type"`
CreatedAt int64 `json:"created_at"`
CreatedBy string `json:"created_by"`
CurrentHtmlContent sql.NullString `json:"current_html_content"`
@@ -94,7 +91,6 @@ func (q *Queries) GetAllVersionsForSite(ctx context.Context, arg GetAllVersionsF
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.CreatedBy,
&i.CurrentHtmlContent,
@@ -113,7 +109,7 @@ func (q *Queries) GetAllVersionsForSite(ctx context.Context, arg GetAllVersionsF
}
const getContentVersion = `-- name: GetContentVersion :one
-SELECT version_id, content_id, site_id, html_content, original_template, type, created_at, created_by
+SELECT version_id, content_id, site_id, html_content, original_template, created_at, created_by
FROM content_versions
WHERE version_id = $1
`
@@ -127,7 +123,6 @@ func (q *Queries) GetContentVersion(ctx context.Context, versionID int32) (Conte
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.CreatedBy,
)
@@ -135,7 +130,7 @@ func (q *Queries) GetContentVersion(ctx context.Context, versionID int32) (Conte
}
const getContentVersionHistory = `-- name: GetContentVersionHistory :many
-SELECT version_id, content_id, site_id, html_content, original_template, type, created_at, created_by
+SELECT version_id, content_id, site_id, html_content, original_template, created_at, created_by
FROM content_versions
WHERE content_id = $1 AND site_id = $2
ORDER BY created_at DESC
@@ -163,7 +158,6 @@ func (q *Queries) GetContentVersionHistory(ctx context.Context, arg GetContentVe
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.CreatedBy,
); err != nil {
diff --git a/internal/db/queries/content.sql b/internal/db/queries/content.sql
index f25a98e..6c955f9 100644
--- a/internal/db/queries/content.sql
+++ b/internal/db/queries/content.sql
@@ -1,38 +1,37 @@
-- name: GetContent :one
-SELECT id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+SELECT id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
FROM content
WHERE id = sqlc.arg(id) AND site_id = sqlc.arg(site_id);
-- name: GetAllContent :many
-SELECT id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+SELECT id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
FROM content
WHERE site_id = sqlc.arg(site_id)
ORDER BY updated_at DESC;
-- name: GetBulkContent :many
-SELECT id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+SELECT id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
FROM content
WHERE site_id = sqlc.arg(site_id) AND id IN (sqlc.slice('ids'));
-- name: CreateContent :one
-INSERT INTO content (id, site_id, html_content, original_template, type, last_edited_by)
-VALUES (sqlc.arg(id), sqlc.arg(site_id), sqlc.arg(html_content), sqlc.arg(original_template), sqlc.arg(type), sqlc.arg(last_edited_by))
-RETURNING id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by;
+INSERT INTO content (id, site_id, html_content, original_template, last_edited_by)
+VALUES (sqlc.arg(id), sqlc.arg(site_id), sqlc.arg(html_content), sqlc.arg(original_template), sqlc.arg(last_edited_by))
+RETURNING id, site_id, html_content, original_template, created_at, updated_at, last_edited_by;
-- name: UpdateContent :one
UPDATE content
-SET html_content = sqlc.arg(html_content), type = sqlc.arg(type), last_edited_by = sqlc.arg(last_edited_by)
+SET html_content = sqlc.arg(html_content), last_edited_by = sqlc.arg(last_edited_by)
WHERE id = sqlc.arg(id) AND site_id = sqlc.arg(site_id)
-RETURNING id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by;
+RETURNING id, site_id, html_content, original_template, created_at, updated_at, last_edited_by;
-- name: UpsertContent :one
-INSERT INTO content (id, site_id, html_content, original_template, type, last_edited_by)
-VALUES (sqlc.arg(id), sqlc.arg(site_id), sqlc.arg(html_content), sqlc.arg(original_template), sqlc.arg(type), sqlc.arg(last_edited_by))
+INSERT INTO content (id, site_id, html_content, original_template, last_edited_by)
+VALUES (sqlc.arg(id), sqlc.arg(site_id), sqlc.arg(html_content), sqlc.arg(original_template), sqlc.arg(last_edited_by))
ON CONFLICT(id, site_id) DO UPDATE SET
html_content = EXCLUDED.html_content,
- type = EXCLUDED.type,
last_edited_by = EXCLUDED.last_edited_by
-RETURNING id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by;
+RETURNING id, site_id, html_content, original_template, created_at, updated_at, last_edited_by;
-- name: DeleteContent :exec
DELETE FROM content
diff --git a/internal/db/queries/versions.sql b/internal/db/queries/versions.sql
index 2d756ba..0bebfa5 100644
--- a/internal/db/queries/versions.sql
+++ b/internal/db/queries/versions.sql
@@ -1,22 +1,22 @@
-- name: CreateContentVersion :exec
-INSERT INTO content_versions (content_id, site_id, html_content, original_template, type, created_by)
-VALUES (sqlc.arg(content_id), sqlc.arg(site_id), sqlc.arg(html_content), sqlc.arg(original_template), sqlc.arg(type), sqlc.arg(created_by));
+INSERT INTO content_versions (content_id, site_id, html_content, original_template, created_by)
+VALUES (sqlc.arg(content_id), sqlc.arg(site_id), sqlc.arg(html_content), sqlc.arg(original_template), sqlc.arg(created_by));
-- name: GetContentVersionHistory :many
-SELECT version_id, content_id, site_id, html_content, original_template, type, created_at, created_by
+SELECT version_id, content_id, site_id, html_content, original_template, created_at, created_by
FROM content_versions
WHERE content_id = sqlc.arg(content_id) AND site_id = sqlc.arg(site_id)
ORDER BY created_at DESC
LIMIT sqlc.arg(limit_count);
-- name: GetContentVersion :one
-SELECT version_id, content_id, site_id, html_content, original_template, type, created_at, created_by
+SELECT version_id, content_id, site_id, html_content, original_template, created_at, created_by
FROM content_versions
WHERE version_id = sqlc.arg(version_id);
-- name: GetAllVersionsForSite :many
SELECT
- cv.version_id, cv.content_id, cv.site_id, cv.html_content, cv.original_template, cv.type, cv.created_at, cv.created_by,
+ cv.version_id, cv.content_id, cv.site_id, cv.html_content, cv.original_template, cv.created_at, cv.created_by,
c.html_content as current_html_content
FROM content_versions cv
LEFT JOIN content c ON cv.content_id = c.id AND cv.site_id = c.site_id
diff --git a/internal/db/sqlite/content.sql.go b/internal/db/sqlite/content.sql.go
index 95f2c4b..a715913 100644
--- a/internal/db/sqlite/content.sql.go
+++ b/internal/db/sqlite/content.sql.go
@@ -12,9 +12,9 @@ import (
)
const createContent = `-- name: CreateContent :one
-INSERT INTO content (id, site_id, html_content, original_template, type, last_edited_by)
-VALUES (?1, ?2, ?3, ?4, ?5, ?6)
-RETURNING id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+INSERT INTO content (id, site_id, html_content, original_template, last_edited_by)
+VALUES (?1, ?2, ?3, ?4, ?5)
+RETURNING id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
`
type CreateContentParams struct {
@@ -22,7 +22,6 @@ type CreateContentParams struct {
SiteID string `json:"site_id"`
HtmlContent string `json:"html_content"`
OriginalTemplate sql.NullString `json:"original_template"`
- Type string `json:"type"`
LastEditedBy string `json:"last_edited_by"`
}
@@ -32,7 +31,6 @@ func (q *Queries) CreateContent(ctx context.Context, arg CreateContentParams) (C
arg.SiteID,
arg.HtmlContent,
arg.OriginalTemplate,
- arg.Type,
arg.LastEditedBy,
)
var i Content
@@ -41,7 +39,6 @@ func (q *Queries) CreateContent(ctx context.Context, arg CreateContentParams) (C
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.UpdatedAt,
&i.LastEditedBy,
@@ -75,7 +72,7 @@ func (q *Queries) DeleteContent(ctx context.Context, arg DeleteContentParams) er
}
const getAllContent = `-- name: GetAllContent :many
-SELECT id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+SELECT id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
FROM content
WHERE site_id = ?1
ORDER BY updated_at DESC
@@ -95,7 +92,6 @@ func (q *Queries) GetAllContent(ctx context.Context, siteID string) ([]Content,
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.UpdatedAt,
&i.LastEditedBy,
@@ -114,7 +110,7 @@ func (q *Queries) GetAllContent(ctx context.Context, siteID string) ([]Content,
}
const getBulkContent = `-- name: GetBulkContent :many
-SELECT id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+SELECT id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
FROM content
WHERE site_id = ?1 AND id IN (/*SLICE:ids*/?)
`
@@ -149,7 +145,6 @@ func (q *Queries) GetBulkContent(ctx context.Context, arg GetBulkContentParams)
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.UpdatedAt,
&i.LastEditedBy,
@@ -168,7 +163,7 @@ func (q *Queries) GetBulkContent(ctx context.Context, arg GetBulkContentParams)
}
const getContent = `-- name: GetContent :one
-SELECT id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+SELECT id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
FROM content
WHERE id = ?1 AND site_id = ?2
`
@@ -186,7 +181,6 @@ func (q *Queries) GetContent(ctx context.Context, arg GetContentParams) (Content
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.UpdatedAt,
&i.LastEditedBy,
@@ -196,14 +190,13 @@ func (q *Queries) GetContent(ctx context.Context, arg GetContentParams) (Content
const updateContent = `-- name: UpdateContent :one
UPDATE content
-SET html_content = ?1, type = ?2, last_edited_by = ?3
-WHERE id = ?4 AND site_id = ?5
-RETURNING id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+SET html_content = ?1, last_edited_by = ?2
+WHERE id = ?3 AND site_id = ?4
+RETURNING id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
`
type UpdateContentParams struct {
HtmlContent string `json:"html_content"`
- Type string `json:"type"`
LastEditedBy string `json:"last_edited_by"`
ID string `json:"id"`
SiteID string `json:"site_id"`
@@ -212,7 +205,6 @@ type UpdateContentParams struct {
func (q *Queries) UpdateContent(ctx context.Context, arg UpdateContentParams) (Content, error) {
row := q.db.QueryRowContext(ctx, updateContent,
arg.HtmlContent,
- arg.Type,
arg.LastEditedBy,
arg.ID,
arg.SiteID,
@@ -223,7 +215,6 @@ func (q *Queries) UpdateContent(ctx context.Context, arg UpdateContentParams) (C
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.UpdatedAt,
&i.LastEditedBy,
@@ -232,13 +223,12 @@ func (q *Queries) UpdateContent(ctx context.Context, arg UpdateContentParams) (C
}
const upsertContent = `-- name: UpsertContent :one
-INSERT INTO content (id, site_id, html_content, original_template, type, last_edited_by)
-VALUES (?1, ?2, ?3, ?4, ?5, ?6)
+INSERT INTO content (id, site_id, html_content, original_template, last_edited_by)
+VALUES (?1, ?2, ?3, ?4, ?5)
ON CONFLICT(id, site_id) DO UPDATE SET
html_content = EXCLUDED.html_content,
- type = EXCLUDED.type,
last_edited_by = EXCLUDED.last_edited_by
-RETURNING id, site_id, html_content, original_template, type, created_at, updated_at, last_edited_by
+RETURNING id, site_id, html_content, original_template, created_at, updated_at, last_edited_by
`
type UpsertContentParams struct {
@@ -246,7 +236,6 @@ type UpsertContentParams struct {
SiteID string `json:"site_id"`
HtmlContent string `json:"html_content"`
OriginalTemplate sql.NullString `json:"original_template"`
- Type string `json:"type"`
LastEditedBy string `json:"last_edited_by"`
}
@@ -256,7 +245,6 @@ func (q *Queries) UpsertContent(ctx context.Context, arg UpsertContentParams) (C
arg.SiteID,
arg.HtmlContent,
arg.OriginalTemplate,
- arg.Type,
arg.LastEditedBy,
)
var i Content
@@ -265,7 +253,6 @@ func (q *Queries) UpsertContent(ctx context.Context, arg UpsertContentParams) (C
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.UpdatedAt,
&i.LastEditedBy,
diff --git a/internal/db/sqlite/models.go b/internal/db/sqlite/models.go
index 48abaf0..afdfd08 100644
--- a/internal/db/sqlite/models.go
+++ b/internal/db/sqlite/models.go
@@ -13,7 +13,6 @@ type Content struct {
SiteID string `json:"site_id"`
HtmlContent string `json:"html_content"`
OriginalTemplate sql.NullString `json:"original_template"`
- Type string `json:"type"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
LastEditedBy string `json:"last_edited_by"`
@@ -25,7 +24,6 @@ type ContentVersion struct {
SiteID string `json:"site_id"`
HtmlContent string `json:"html_content"`
OriginalTemplate sql.NullString `json:"original_template"`
- Type string `json:"type"`
CreatedAt int64 `json:"created_at"`
CreatedBy string `json:"created_by"`
}
diff --git a/internal/db/sqlite/schema.sql b/internal/db/sqlite/schema.sql
index 0e545ea..f8a91f5 100644
--- a/internal/db/sqlite/schema.sql
+++ b/internal/db/sqlite/schema.sql
@@ -5,7 +5,6 @@ CREATE TABLE content (
site_id TEXT NOT NULL,
html_content TEXT NOT NULL,
original_template TEXT,
- type TEXT NOT NULL,
created_at INTEGER DEFAULT (strftime('%s', 'now')) NOT NULL,
updated_at INTEGER DEFAULT (strftime('%s', 'now')) NOT NULL,
last_edited_by TEXT DEFAULT 'system' NOT NULL,
@@ -19,7 +18,6 @@ CREATE TABLE content_versions (
site_id TEXT NOT NULL,
html_content TEXT NOT NULL,
original_template TEXT,
- type TEXT NOT NULL,
created_at INTEGER DEFAULT (strftime('%s', 'now')) NOT NULL,
created_by TEXT DEFAULT 'system' NOT NULL
);
diff --git a/internal/db/sqlite/setup.sql b/internal/db/sqlite/setup.sql
index c31c9eb..df2a13c 100644
--- a/internal/db/sqlite/setup.sql
+++ b/internal/db/sqlite/setup.sql
@@ -4,7 +4,6 @@ CREATE TABLE IF NOT EXISTS content (
site_id TEXT NOT NULL,
html_content TEXT NOT NULL,
original_template TEXT,
- type TEXT NOT NULL CHECK (type IN ('text', 'link')),
created_at INTEGER DEFAULT (strftime('%s', 'now')) NOT NULL,
updated_at INTEGER DEFAULT (strftime('%s', 'now')) NOT NULL,
last_edited_by TEXT DEFAULT 'system' NOT NULL,
@@ -18,7 +17,6 @@ CREATE TABLE IF NOT EXISTS content_versions (
site_id TEXT NOT NULL,
html_content TEXT NOT NULL,
original_template TEXT,
- type TEXT NOT NULL,
created_at INTEGER DEFAULT (strftime('%s', 'now')) NOT NULL,
created_by TEXT DEFAULT 'system' NOT NULL
);
diff --git a/internal/db/sqlite/setup.sql.go b/internal/db/sqlite/setup.sql.go
index 7d9c107..20df7d7 100644
--- a/internal/db/sqlite/setup.sql.go
+++ b/internal/db/sqlite/setup.sql.go
@@ -15,7 +15,6 @@ CREATE TABLE IF NOT EXISTS content (
site_id TEXT NOT NULL,
html_content TEXT NOT NULL,
original_template TEXT,
- type TEXT NOT NULL CHECK (type IN ('text', 'link')),
created_at INTEGER DEFAULT (strftime('%s', 'now')) NOT NULL,
updated_at INTEGER DEFAULT (strftime('%s', 'now')) NOT NULL,
last_edited_by TEXT DEFAULT 'system' NOT NULL,
@@ -35,7 +34,6 @@ CREATE TABLE IF NOT EXISTS content_versions (
site_id TEXT NOT NULL,
html_content TEXT NOT NULL,
original_template TEXT,
- type TEXT NOT NULL,
created_at INTEGER DEFAULT (strftime('%s', 'now')) NOT NULL,
created_by TEXT DEFAULT 'system' NOT NULL
)
diff --git a/internal/db/sqlite/versions.sql.go b/internal/db/sqlite/versions.sql.go
index 17c7f8d..a6f9c1a 100644
--- a/internal/db/sqlite/versions.sql.go
+++ b/internal/db/sqlite/versions.sql.go
@@ -11,8 +11,8 @@ import (
)
const createContentVersion = `-- name: CreateContentVersion :exec
-INSERT INTO content_versions (content_id, site_id, html_content, original_template, type, created_by)
-VALUES (?1, ?2, ?3, ?4, ?5, ?6)
+INSERT INTO content_versions (content_id, site_id, html_content, original_template, created_by)
+VALUES (?1, ?2, ?3, ?4, ?5)
`
type CreateContentVersionParams struct {
@@ -20,7 +20,6 @@ type CreateContentVersionParams struct {
SiteID string `json:"site_id"`
HtmlContent string `json:"html_content"`
OriginalTemplate sql.NullString `json:"original_template"`
- Type string `json:"type"`
CreatedBy string `json:"created_by"`
}
@@ -30,7 +29,6 @@ func (q *Queries) CreateContentVersion(ctx context.Context, arg CreateContentVer
arg.SiteID,
arg.HtmlContent,
arg.OriginalTemplate,
- arg.Type,
arg.CreatedBy,
)
return err
@@ -53,7 +51,7 @@ func (q *Queries) DeleteOldVersions(ctx context.Context, arg DeleteOldVersionsPa
const getAllVersionsForSite = `-- name: GetAllVersionsForSite :many
SELECT
- cv.version_id, cv.content_id, cv.site_id, cv.html_content, cv.original_template, cv.type, cv.created_at, cv.created_by,
+ cv.version_id, cv.content_id, cv.site_id, cv.html_content, cv.original_template, cv.created_at, cv.created_by,
c.html_content as current_html_content
FROM content_versions cv
LEFT JOIN content c ON cv.content_id = c.id AND cv.site_id = c.site_id
@@ -73,7 +71,6 @@ type GetAllVersionsForSiteRow struct {
SiteID string `json:"site_id"`
HtmlContent string `json:"html_content"`
OriginalTemplate sql.NullString `json:"original_template"`
- Type string `json:"type"`
CreatedAt int64 `json:"created_at"`
CreatedBy string `json:"created_by"`
CurrentHtmlContent sql.NullString `json:"current_html_content"`
@@ -94,7 +91,6 @@ func (q *Queries) GetAllVersionsForSite(ctx context.Context, arg GetAllVersionsF
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.CreatedBy,
&i.CurrentHtmlContent,
@@ -113,7 +109,7 @@ func (q *Queries) GetAllVersionsForSite(ctx context.Context, arg GetAllVersionsF
}
const getContentVersion = `-- name: GetContentVersion :one
-SELECT version_id, content_id, site_id, html_content, original_template, type, created_at, created_by
+SELECT version_id, content_id, site_id, html_content, original_template, created_at, created_by
FROM content_versions
WHERE version_id = ?1
`
@@ -127,7 +123,6 @@ func (q *Queries) GetContentVersion(ctx context.Context, versionID int64) (Conte
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.CreatedBy,
)
@@ -135,7 +130,7 @@ func (q *Queries) GetContentVersion(ctx context.Context, versionID int64) (Conte
}
const getContentVersionHistory = `-- name: GetContentVersionHistory :many
-SELECT version_id, content_id, site_id, html_content, original_template, type, created_at, created_by
+SELECT version_id, content_id, site_id, html_content, original_template, created_at, created_by
FROM content_versions
WHERE content_id = ?1 AND site_id = ?2
ORDER BY created_at DESC
@@ -163,7 +158,6 @@ func (q *Queries) GetContentVersionHistory(ctx context.Context, arg GetContentVe
&i.SiteID,
&i.HtmlContent,
&i.OriginalTemplate,
- &i.Type,
&i.CreatedAt,
&i.CreatedBy,
); err != nil {
diff --git a/internal/engine/database_client.go b/internal/engine/database_client.go
index e5f37f5..cb6cde3 100644
--- a/internal/engine/database_client.go
+++ b/internal/engine/database_client.go
@@ -46,7 +46,6 @@ func (c *DatabaseClient) GetContent(siteID, contentID string) (*ContentItem, err
SiteID: content.SiteID,
HTMLContent: content.HtmlContent,
OriginalTemplate: getStringFromNullString(content.OriginalTemplate),
- Type: content.Type,
LastEditedBy: content.LastEditedBy,
}, nil
@@ -63,7 +62,6 @@ func (c *DatabaseClient) GetContent(siteID, contentID string) (*ContentItem, err
SiteID: content.SiteID,
HTMLContent: content.HtmlContent,
OriginalTemplate: getStringFromNullString(content.OriginalTemplate),
- Type: content.Type,
LastEditedBy: content.LastEditedBy,
}, nil
@@ -91,7 +89,6 @@ func (c *DatabaseClient) GetBulkContent(siteID string, contentIDs []string) (map
SiteID: content.SiteID,
HTMLContent: content.HtmlContent,
OriginalTemplate: getStringFromNullString(content.OriginalTemplate),
- Type: content.Type,
LastEditedBy: content.LastEditedBy,
}
}
@@ -113,7 +110,6 @@ func (c *DatabaseClient) GetBulkContent(siteID string, contentIDs []string) (map
SiteID: content.SiteID,
HTMLContent: content.HtmlContent,
OriginalTemplate: getStringFromNullString(content.OriginalTemplate),
- Type: content.Type,
LastEditedBy: content.LastEditedBy,
}
}
@@ -140,7 +136,6 @@ func (c *DatabaseClient) GetAllContent(siteID string) (map[string]ContentItem, e
SiteID: content.SiteID,
HTMLContent: content.HtmlContent,
OriginalTemplate: getStringFromNullString(content.OriginalTemplate),
- Type: content.Type,
LastEditedBy: content.LastEditedBy,
}
}
@@ -159,7 +154,6 @@ func (c *DatabaseClient) GetAllContent(siteID string) (map[string]ContentItem, e
SiteID: content.SiteID,
HTMLContent: content.HtmlContent,
OriginalTemplate: getStringFromNullString(content.OriginalTemplate),
- Type: content.Type,
LastEditedBy: content.LastEditedBy,
}
}
@@ -171,7 +165,7 @@ func (c *DatabaseClient) GetAllContent(siteID string) (map[string]ContentItem, e
}
// CreateContent creates a new content item
-func (c *DatabaseClient) CreateContent(siteID, contentID, htmlContent, originalTemplate, contentType, lastEditedBy string) (*ContentItem, error) {
+func (c *DatabaseClient) CreateContent(siteID, contentID, htmlContent, originalTemplate, lastEditedBy string) (*ContentItem, error) {
switch c.database.GetDBType() {
case "sqlite3":
content, err := c.database.GetSQLiteQueries().CreateContent(context.Background(), sqlite.CreateContentParams{
@@ -179,7 +173,6 @@ func (c *DatabaseClient) CreateContent(siteID, contentID, htmlContent, originalT
SiteID: siteID,
HtmlContent: htmlContent,
OriginalTemplate: toNullString(originalTemplate),
- Type: contentType,
LastEditedBy: lastEditedBy,
})
if err != nil {
@@ -190,7 +183,6 @@ func (c *DatabaseClient) CreateContent(siteID, contentID, htmlContent, originalT
SiteID: content.SiteID,
HTMLContent: content.HtmlContent,
OriginalTemplate: getStringFromNullString(content.OriginalTemplate),
- Type: content.Type,
LastEditedBy: content.LastEditedBy,
}, nil
@@ -200,7 +192,6 @@ func (c *DatabaseClient) CreateContent(siteID, contentID, htmlContent, originalT
SiteID: siteID,
HtmlContent: htmlContent,
OriginalTemplate: toNullString(originalTemplate),
- Type: contentType,
LastEditedBy: lastEditedBy,
})
if err != nil {
@@ -211,7 +202,6 @@ func (c *DatabaseClient) CreateContent(siteID, contentID, htmlContent, originalT
SiteID: content.SiteID,
HTMLContent: content.HtmlContent,
OriginalTemplate: getStringFromNullString(content.OriginalTemplate),
- Type: content.Type,
LastEditedBy: content.LastEditedBy,
}, nil
@@ -220,7 +210,7 @@ func (c *DatabaseClient) CreateContent(siteID, contentID, htmlContent, originalT
}
}
-// Helper function to convert string to sql.NullString
+// Helper function to convert string to sql.NullString
func toNullString(s string) sql.NullString {
if s == "" {
return sql.NullString{Valid: false}
diff --git a/internal/engine/types.go b/internal/engine/types.go
index e1ed683..3cff90f 100644
--- a/internal/engine/types.go
+++ b/internal/engine/types.go
@@ -35,7 +35,6 @@ type ContentResult struct {
type ProcessedElement struct {
Node *html.Node // HTML node
ID string // Generated content ID
- Type string // Content type (text, link)
Content string // Injected content (if any)
Generated bool // Whether ID was generated (vs existing)
Tag string // Element tag name
@@ -48,7 +47,7 @@ type ContentClient interface {
GetContent(siteID, contentID string) (*ContentItem, error)
GetBulkContent(siteID string, contentIDs []string) (map[string]ContentItem, error)
GetAllContent(siteID string) (map[string]ContentItem, error)
- CreateContent(siteID, contentID, htmlContent, originalTemplate, contentType, lastEditedBy string) (*ContentItem, error)
+ CreateContent(siteID, contentID, htmlContent, originalTemplate, lastEditedBy string) (*ContentItem, error)
}
// ContentItem represents a piece of content from the database
@@ -57,7 +56,6 @@ type ContentItem struct {
SiteID string `json:"site_id"`
HTMLContent string `json:"html_content"`
OriginalTemplate string `json:"original_template"`
- Type string `json:"type"`
UpdatedAt string `json:"updated_at"`
LastEditedBy string `json:"last_edited_by,omitempty"`
}
diff --git a/internal/engine/utils.go b/internal/engine/utils.go
index e52d877..f8d156f 100644
--- a/internal/engine/utils.go
+++ b/internal/engine/utils.go
@@ -179,40 +179,149 @@ func isContainer(node *html.Node) bool {
"main": true,
"aside": true,
"nav": true,
+ "ul": true, // Phase 3: Lists are containers
+ "ol": true,
}
return containerTags[node.Data]
}
-// findViableChildren finds all child elements that are viable for editing
+// findViableChildren finds all descendant elements that should get .insertr class
+// Phase 3: Recursive traversal with block/inline classification and boundary respect
func findViableChildren(node *html.Node) []*html.Node {
var viable []*html.Node
+ traverseForViableElements(node, &viable)
+ return viable
+}
+// traverseForViableElements recursively traverses all descendants, stopping at .insertr boundaries
+func traverseForViableElements(node *html.Node, viable *[]*html.Node) {
for child := node.FirstChild; child != nil; child = child.NextSibling {
- // Skip whitespace-only text nodes
- if child.Type == html.TextNode {
- if strings.TrimSpace(child.Data) == "" {
- continue
- }
- }
-
// Only consider element nodes
if child.Type != html.ElementNode {
continue
}
- // Skip self-closing elements for now
- if isSelfClosing(child) {
+ // BOUNDARY: Stop if element already has .insertr class
+ if hasInsertrClass(child) {
continue
}
- // Check if element has editable content (improved logic)
- if hasEditableContent(child) {
- viable = append(viable, child)
+ // Skip deferred complex elements (tables, forms)
+ if isDeferredElement(child) {
+ continue
}
+
+ // Determine if this element should get .insertr
+ if shouldGetInsertrClass(child) {
+ *viable = append(*viable, child)
+ // Don't traverse children - they're handled by this element's expansion
+ continue
+ }
+
+ // Continue traversing if this is just a container
+ traverseForViableElements(child, viable)
+ }
+}
+
+// Phase 3: Block vs Inline element classification
+func isBlockElement(node *html.Node) bool {
+ blockTags := map[string]bool{
+ // Content blocks
+ "h1": true, "h2": true, "h3": true, "h4": true, "h5": true, "h6": true,
+ "p": true, "div": true, "article": true, "section": true, "nav": true,
+ "header": true, "footer": true, "main": true, "aside": true,
+ // Lists
+ "ul": true, "ol": true, "li": true,
+ // Interactive (when at block level)
+ "button": true, "a": true, "img": true, "video": true, "audio": true,
}
- return viable
+ return blockTags[node.Data]
+}
+
+// isInlineElement checks if element is inline formatting (never gets .insertr)
+func isInlineElement(node *html.Node) bool {
+ inlineTags := map[string]bool{
+ "strong": true, "b": true, "em": true, "i": true, "span": true,
+ "code": true, "small": true, "sub": true, "sup": true, "br": true,
+ "mark": true, "kbd": true,
+ }
+
+ return inlineTags[node.Data]
+}
+
+// isContextSensitive checks if element can be block or inline (a, button)
+func isContextSensitive(node *html.Node) bool {
+ contextTags := map[string]bool{
+ "a": true,
+ "button": true,
+ }
+
+ return contextTags[node.Data]
+}
+
+// isInBlockContext determines if context-sensitive element should be treated as block
+func isInBlockContext(node *html.Node) bool {
+ parent := node.Parent
+ if parent == nil || parent.Type != html.ElementNode {
+ return true
+ }
+
+ // If parent is a content element, this is inline formatting
+ contentElements := map[string]bool{
+ "p": true, "h1": true, "h2": true, "h3": true, "h4": true, "h5": true, "h6": true,
+ "li": true, "td": true, "th": true,
+ }
+
+ return !contentElements[parent.Data]
+}
+
+// shouldGetInsertrClass determines if element should receive .insertr class
+func shouldGetInsertrClass(node *html.Node) bool {
+ // Always block elements get .insertr
+ if isBlockElement(node) && !isContextSensitive(node) {
+ return true
+ }
+
+ // Context-sensitive elements depend on parent context
+ if isContextSensitive(node) {
+ return isInBlockContext(node)
+ }
+
+ // Inline elements never get .insertr
+ if isInlineElement(node) {
+ return false
+ }
+
+ // Self-closing elements - only img gets .insertr when block-level
+ if isSelfClosing(node) {
+ return node.Data == "img" && isInBlockContext(node)
+ }
+
+ return false
+}
+
+// isDeferredElement checks for complex elements that need separate planning
+func isDeferredElement(node *html.Node) bool {
+ deferredTags := map[string]bool{
+ "table": true, "tr": true, "td": true, "th": true,
+ "thead": true, "tbody": true, "tfoot": true,
+ "form": true, "input": true, "textarea": true, "select": true, "option": true,
+ }
+
+ return deferredTags[node.Data]
+}
+
+// hasInsertrClass checks if node has class="insertr"
+func hasInsertrClass(node *html.Node) bool {
+ classes := GetClasses(node)
+ for _, class := range classes {
+ if class == "insertr" {
+ return true
+ }
+ }
+ return false
}
// findViableChildrenLegacy uses the old text-only logic for backwards compatibility