Refactor database layer to eliminate type switching and simplify architecture
- Replace type switching with clean repository pattern using sqlc-generated code - Move ContentRepository interface and domain models to db package - Create separate SQLiteRepository and PostgreSQLRepository implementations - Remove unnecessary RepositoryAdapter and ContentClient interface duplication - Update all clients (HTTP, Mock) to implement db.ContentRepository directly - Add context.Context parameters to all repository methods (Go best practice) - Eliminate duplicate domain models and type conversions - Remove type aliases - use db package types directly throughout codebase - Update engine, content managers, and API handlers to use repositories directly Benefits: - Zero runtime type switching overhead - Single source of truth for domain models - Clean package boundaries and separation of concerns - Standard Go interface patterns with context support - Easier testing with mockable repository interface - Maintainable: adding new database types requires no changes to existing code
This commit is contained in:
@@ -1,21 +1,22 @@
|
||||
package content
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/insertr/insertr/internal/engine"
|
||||
"github.com/insertr/insertr/internal/db"
|
||||
)
|
||||
|
||||
// MockClient implements ContentClient with mock data for development
|
||||
type MockClient struct {
|
||||
data map[string]engine.ContentItem
|
||||
data map[string]db.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]engine.ContentItem{
|
||||
data := map[string]db.ContentItem{
|
||||
// Navigation (index.html has collision suffix)
|
||||
"navbar-logo-2b10ad": {
|
||||
ID: "navbar-logo-2b10ad",
|
||||
@@ -101,7 +102,7 @@ func NewMockClient() *MockClient {
|
||||
}
|
||||
|
||||
// GetContent fetches a single content item by ID
|
||||
func (m *MockClient) GetContent(siteID, contentID string) (*engine.ContentItem, error) {
|
||||
func (m *MockClient) GetContent(ctx context.Context, siteID, contentID string) (*db.ContentItem, error) {
|
||||
if item, exists := m.data[contentID]; exists && item.SiteID == siteID {
|
||||
return &item, nil
|
||||
}
|
||||
@@ -111,11 +112,11 @@ func (m *MockClient) GetContent(siteID, contentID string) (*engine.ContentItem,
|
||||
}
|
||||
|
||||
// GetBulkContent fetches multiple content items by IDs
|
||||
func (m *MockClient) GetBulkContent(siteID string, contentIDs []string) (map[string]engine.ContentItem, error) {
|
||||
result := make(map[string]engine.ContentItem)
|
||||
func (m *MockClient) GetBulkContent(ctx context.Context, siteID string, contentIDs []string) (map[string]db.ContentItem, error) {
|
||||
result := make(map[string]db.ContentItem)
|
||||
|
||||
for _, id := range contentIDs {
|
||||
item, err := m.GetContent(siteID, id)
|
||||
item, err := m.GetContent(ctx, siteID, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -128,8 +129,8 @@ func (m *MockClient) GetBulkContent(siteID string, contentIDs []string) (map[str
|
||||
}
|
||||
|
||||
// GetAllContent fetches all content for a site
|
||||
func (m *MockClient) GetAllContent(siteID string) (map[string]engine.ContentItem, error) {
|
||||
result := make(map[string]engine.ContentItem)
|
||||
func (m *MockClient) GetAllContent(ctx context.Context, siteID string) (map[string]db.ContentItem, error) {
|
||||
result := make(map[string]db.ContentItem)
|
||||
|
||||
for _, item := range m.data {
|
||||
if item.SiteID == siteID {
|
||||
@@ -141,9 +142,9 @@ 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, lastEditedBy string) (*engine.ContentItem, error) {
|
||||
func (m *MockClient) CreateContent(ctx context.Context, siteID, contentID, htmlContent, originalTemplate, lastEditedBy string) (*db.ContentItem, error) {
|
||||
// For mock client, just create and store the item
|
||||
item := engine.ContentItem{
|
||||
item := db.ContentItem{
|
||||
ID: contentID,
|
||||
SiteID: siteID,
|
||||
HTMLContent: htmlContent,
|
||||
@@ -159,30 +160,35 @@ func (m *MockClient) CreateContent(siteID, contentID, htmlContent, originalTempl
|
||||
}
|
||||
|
||||
// Collection method stubs - TODO: Implement these for mock testing
|
||||
func (m *MockClient) GetCollection(siteID, collectionID string) (*engine.CollectionItem, error) {
|
||||
func (m *MockClient) GetCollection(ctx context.Context, siteID, collectionID string) (*db.CollectionItem, error) {
|
||||
return nil, fmt.Errorf("collection operations not implemented in MockClient")
|
||||
}
|
||||
|
||||
func (m *MockClient) CreateCollection(siteID, collectionID, containerHTML, lastEditedBy string) (*engine.CollectionItem, error) {
|
||||
func (m *MockClient) CreateCollection(ctx context.Context, siteID, collectionID, containerHTML, lastEditedBy string) (*db.CollectionItem, error) {
|
||||
return nil, fmt.Errorf("collection operations not implemented in MockClient")
|
||||
}
|
||||
|
||||
func (m *MockClient) GetCollectionItems(siteID, collectionID string) ([]engine.CollectionItemWithTemplate, error) {
|
||||
func (m *MockClient) GetCollectionItems(ctx context.Context, siteID, collectionID string) ([]db.CollectionItemWithTemplate, error) {
|
||||
return nil, fmt.Errorf("collection operations not implemented in MockClient")
|
||||
}
|
||||
|
||||
func (m *MockClient) CreateCollectionTemplate(siteID, collectionID, name, htmlTemplate string, isDefault bool) (*engine.CollectionTemplateItem, error) {
|
||||
func (m *MockClient) CreateCollectionTemplate(ctx context.Context, siteID, collectionID, name, htmlTemplate string, isDefault bool) (*db.CollectionTemplateItem, error) {
|
||||
return nil, fmt.Errorf("collection operations not implemented in MockClient")
|
||||
}
|
||||
|
||||
func (m *MockClient) GetCollectionTemplates(siteID, collectionID string) ([]engine.CollectionTemplateItem, error) {
|
||||
func (m *MockClient) GetCollectionTemplates(ctx context.Context, siteID, collectionID string) ([]db.CollectionTemplateItem, error) {
|
||||
return nil, fmt.Errorf("collection operations not implemented in MockClient")
|
||||
}
|
||||
|
||||
func (m *MockClient) CreateCollectionItem(siteID, collectionID, itemID string, templateID int, htmlContent string, position int, lastEditedBy string) (*engine.CollectionItemWithTemplate, error) {
|
||||
func (m *MockClient) CreateCollectionItem(ctx context.Context, siteID, collectionID, itemID string, templateID int, htmlContent string, position int, lastEditedBy string) (*db.CollectionItemWithTemplate, error) {
|
||||
return nil, fmt.Errorf("collection operations not implemented in MockClient")
|
||||
}
|
||||
|
||||
func (m *MockClient) CreateCollectionItemAtomic(siteID, collectionID string, templateID int, lastEditedBy string) (*engine.CollectionItemWithTemplate, error) {
|
||||
func (m *MockClient) CreateCollectionItemAtomic(ctx context.Context, siteID, collectionID string, templateID int, lastEditedBy string) (*db.CollectionItemWithTemplate, error) {
|
||||
return nil, fmt.Errorf("collection operations not implemented in MockClient")
|
||||
}
|
||||
|
||||
// WithTransaction executes a function within a transaction (not supported for mock client)
|
||||
func (m *MockClient) WithTransaction(ctx context.Context, fn func(db.ContentRepository) error) error {
|
||||
return fmt.Errorf("transactions not supported for mock client")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user