refactor: implement unified binary architecture
🏗️ **Major Architecture Refactoring: Separate CLI + Server → Unified Binary** **Key Changes:** ✅ **Unified Binary**: Single 'insertr' binary with subcommands (enhance, serve) ✅ **Preserved Database Architecture**: Maintained sophisticated sqlc multi-DB setup ✅ **Smart Configuration**: Viper + YAML config with CLI flag precedence ✅ **Updated Build System**: Unified justfile, Air, and npm scripts **Command Structure:** - `insertr enhance [input-dir]` - Build-time content injection - `insertr serve` - HTTP API server (dev + production modes) - `insertr --config insertr.yaml` - YAML configuration support **Architecture Benefits:** - **Shared Database Layer**: Single source of truth for content models - **Flexible Workflows**: Local DB for dev, remote API for production - **Simple Deployment**: One binary for all use cases - **Better UX**: Consistent configuration across build and runtime **Preserved Features:** - Multi-database support (SQLite + PostgreSQL) - sqlc code generation and type safety - Version control system with rollback - Professional API endpoints - Content enhancement pipeline **Development Workflow:** - `just dev` - Full-stack development (API server + demo site) - `just serve` - API server only - `just enhance` - Build-time content injection - `air` - Hot reload unified binary **Migration:** Consolidated insertr-cli/ and insertr-server/ → unified root structure
This commit is contained in:
138
internal/content/mock.go
Normal file
138
internal/content/mock.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package content
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// MockClient implements ContentClient with mock data for development
|
||||
type MockClient struct {
|
||||
data map[string]ContentItem
|
||||
}
|
||||
|
||||
// NewMockClient creates a new mock content client with sample data
|
||||
func NewMockClient() *MockClient {
|
||||
// Generate realistic mock content based on actual generated IDs
|
||||
data := map[string]ContentItem{
|
||||
// Navigation (index.html has collision suffix)
|
||||
"navbar-logo-2b10ad": {
|
||||
ID: "navbar-logo-2b10ad",
|
||||
SiteID: "demo",
|
||||
Value: "Acme Consulting Solutions",
|
||||
Type: "text",
|
||||
UpdatedAt: time.Now().Format(time.RFC3339),
|
||||
},
|
||||
"navbar-logo-2b10ad-a44bad": {
|
||||
ID: "navbar-logo-2b10ad-a44bad",
|
||||
SiteID: "demo",
|
||||
Value: "Acme Business Advisors",
|
||||
Type: "text",
|
||||
UpdatedAt: time.Now().Format(time.RFC3339),
|
||||
},
|
||||
|
||||
// Hero Section - index.html (updated with actual IDs)
|
||||
"hero-title-7cfeea": {
|
||||
ID: "hero-title-7cfeea",
|
||||
SiteID: "demo",
|
||||
Value: "Transform Your Business with Strategic Expertise",
|
||||
Type: "text",
|
||||
UpdatedAt: time.Now().Format(time.RFC3339),
|
||||
},
|
||||
"hero-lead-e47475": {
|
||||
ID: "hero-lead-e47475",
|
||||
SiteID: "demo",
|
||||
Value: "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: "markdown",
|
||||
UpdatedAt: time.Now().Format(time.RFC3339),
|
||||
},
|
||||
"hero-link-76c620": {
|
||||
ID: "hero-link-76c620",
|
||||
SiteID: "demo",
|
||||
Value: "Schedule Free Consultation",
|
||||
Type: "link",
|
||||
UpdatedAt: time.Now().Format(time.RFC3339),
|
||||
},
|
||||
|
||||
// Hero Section - about.html
|
||||
"hero-title-c70343": {
|
||||
ID: "hero-title-c70343",
|
||||
SiteID: "demo",
|
||||
Value: "About Our Consulting Expertise",
|
||||
Type: "text",
|
||||
UpdatedAt: time.Now().Format(time.RFC3339),
|
||||
},
|
||||
"hero-lead-673026": {
|
||||
ID: "hero-lead-673026",
|
||||
SiteID: "demo",
|
||||
Value: "We're a team of **experienced consultants** dedicated to helping small businesses thrive in today's competitive marketplace through proven strategies.",
|
||||
Type: "markdown",
|
||||
UpdatedAt: time.Now().Format(time.RFC3339),
|
||||
},
|
||||
|
||||
// Services Section
|
||||
"services-subtitle-c8927c": {
|
||||
ID: "services-subtitle-c8927c",
|
||||
SiteID: "demo",
|
||||
Value: "Our Story",
|
||||
Type: "text",
|
||||
UpdatedAt: time.Now().Format(time.RFC3339),
|
||||
},
|
||||
"services-text-0d96da": {
|
||||
ID: "services-text-0d96da",
|
||||
SiteID: "demo",
|
||||
Value: "**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: "markdown",
|
||||
UpdatedAt: time.Now().Format(time.RFC3339),
|
||||
},
|
||||
|
||||
// Default fallback for any missing content
|
||||
"default": {
|
||||
ID: "default",
|
||||
SiteID: "demo",
|
||||
Value: "[Enhanced Content]",
|
||||
Type: "text",
|
||||
UpdatedAt: time.Now().Format(time.RFC3339),
|
||||
},
|
||||
}
|
||||
|
||||
return &MockClient{data: data}
|
||||
}
|
||||
|
||||
// GetContent fetches a single content item by ID
|
||||
func (m *MockClient) GetContent(siteID, contentID string) (*ContentItem, error) {
|
||||
if item, exists := m.data[contentID]; exists && item.SiteID == siteID {
|
||||
return &item, nil
|
||||
}
|
||||
|
||||
// Return nil for missing content - this will preserve original HTML content
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// GetBulkContent fetches multiple content items by IDs
|
||||
func (m *MockClient) GetBulkContent(siteID string, contentIDs []string) (map[string]ContentItem, error) {
|
||||
result := make(map[string]ContentItem)
|
||||
|
||||
for _, id := range contentIDs {
|
||||
item, err := m.GetContent(siteID, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if item != nil {
|
||||
result[id] = *item
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetAllContent fetches all content for a site
|
||||
func (m *MockClient) GetAllContent(siteID string) (map[string]ContentItem, error) {
|
||||
result := make(map[string]ContentItem)
|
||||
|
||||
for _, item := range m.data {
|
||||
if item.SiteID == siteID {
|
||||
result[item.ID] = item
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
Reference in New Issue
Block a user