feat: implement unified content engine to eliminate ID generation inconsistencies

- Create internal/engine module as single source of truth for content processing
- Consolidate 4 separate ID generation systems into one unified engine
- Update API handlers to use engine for consistent server-side ID generation
- Remove frontend client-side ID generation, delegate to server engine
- Ensure identical HTML markup + file path produces identical content IDs
- Resolve content persistence failures caused by ID fragmentation between manual editing and enhancement processes
This commit is contained in:
2025-09-16 15:04:27 +02:00
parent c1bc28d107
commit 84c90f428d
12 changed files with 1426 additions and 267 deletions

59
internal/engine/types.go Normal file
View File

@@ -0,0 +1,59 @@
package engine
import (
"golang.org/x/net/html"
)
// ProcessMode defines how the engine should process content
type ProcessMode int
const (
// Enhancement mode: Parse + Generate IDs + Inject content + Add editor assets
Enhancement ProcessMode = iota
// IDGeneration mode: Parse + Generate IDs only (for API)
IDGeneration
// ContentInjection mode: Parse + Generate IDs + Inject content only
ContentInjection
)
// ContentInput represents input to the content engine
type ContentInput struct {
HTML []byte // Raw HTML or markup
FilePath string // File context (e.g., "index.html")
SiteID string // Site identifier
Mode ProcessMode // Processing mode
}
// ContentResult represents the result of content processing
type ContentResult struct {
Document *html.Node // Processed HTML document
Elements []ProcessedElement // All processed elements
GeneratedIDs map[string]string // Map of element positions to generated IDs
}
// ProcessedElement represents an element that has been processed
type ProcessedElement struct {
Node *html.Node // HTML node
ID string // Generated content ID
Type string // Content type (text, markdown, link)
Content string // Injected content (if any)
Generated bool // Whether ID was generated (vs existing)
Tag string // Element tag name
Classes []string // Element CSS classes
}
// ContentClient interface for accessing content data
// This will be implemented by database clients
type ContentClient interface {
GetContent(siteID, contentID string) (*ContentItem, error)
GetBulkContent(siteID string, contentIDs []string) ([]*ContentItem, error)
}
// ContentItem represents a piece of content from the database
type ContentItem struct {
ID string
SiteID string
Value string
Type string
LastEditedBy string
}