Implement complete API routes and mock authentication for full CMS functionality
- Add comprehensive nested route structure with proper authentication layers - Implement UpdateContent and ReorderCollectionItems handlers with repository pattern - Add automatic mock JWT token fetching for seamless development workflow - Restore content editing and collection reordering functionality broken after database refactoring - Provide production-ready authentication architecture with development convenience - Enable full CMS operations in browser with proper CRUD and bulk transaction support
This commit is contained in:
@@ -264,6 +264,54 @@ func (r *PostgreSQLRepository) CreateCollectionItemAtomic(ctx context.Context, s
|
||||
return nil, fmt.Errorf("CreateCollectionItemAtomic not yet implemented for PostgreSQL")
|
||||
}
|
||||
|
||||
// UpdateContent updates an existing content item
|
||||
func (r *PostgreSQLRepository) UpdateContent(ctx context.Context, siteID, contentID, htmlContent, lastEditedBy string) (*ContentItem, error) {
|
||||
content, err := r.queries.UpdateContent(ctx, postgresql.UpdateContentParams{
|
||||
HtmlContent: htmlContent,
|
||||
LastEditedBy: lastEditedBy,
|
||||
ID: contentID,
|
||||
SiteID: siteID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ContentItem{
|
||||
ID: content.ID,
|
||||
SiteID: content.SiteID,
|
||||
HTMLContent: content.HtmlContent,
|
||||
OriginalTemplate: FromNullString(content.OriginalTemplate),
|
||||
UpdatedAt: fmt.Sprintf("%d", content.UpdatedAt),
|
||||
LastEditedBy: content.LastEditedBy,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ReorderCollectionItems reorders collection items in bulk
|
||||
func (r *PostgreSQLRepository) ReorderCollectionItems(ctx context.Context, siteID, collectionID string, items []CollectionItemPosition, lastEditedBy string) error {
|
||||
// Use transaction for atomic bulk updates
|
||||
tx, err := r.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
qtx := r.queries.WithTx(tx)
|
||||
for _, item := range items {
|
||||
err = qtx.UpdateCollectionItemPosition(ctx, postgresql.UpdateCollectionItemPositionParams{
|
||||
ItemID: item.ItemID,
|
||||
CollectionID: collectionID,
|
||||
SiteID: siteID,
|
||||
Position: int32(item.Position),
|
||||
LastEditedBy: lastEditedBy,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update position for item %s: %w", item.ItemID, err)
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// WithTransaction executes a function within a database transaction
|
||||
func (r *PostgreSQLRepository) WithTransaction(ctx context.Context, fn func(ContentRepository) error) error {
|
||||
tx, err := r.db.BeginTx(ctx, nil)
|
||||
|
||||
@@ -11,6 +11,7 @@ type ContentRepository interface {
|
||||
GetBulkContent(ctx context.Context, siteID string, contentIDs []string) (map[string]ContentItem, error)
|
||||
GetAllContent(ctx context.Context, siteID string) (map[string]ContentItem, error)
|
||||
CreateContent(ctx context.Context, siteID, contentID, htmlContent, originalTemplate, lastEditedBy string) (*ContentItem, error)
|
||||
UpdateContent(ctx context.Context, siteID, contentID, htmlContent, lastEditedBy string) (*ContentItem, error)
|
||||
|
||||
// Collection operations
|
||||
GetCollection(ctx context.Context, siteID, collectionID string) (*CollectionItem, error)
|
||||
@@ -20,6 +21,7 @@ type ContentRepository interface {
|
||||
CreateCollectionTemplate(ctx context.Context, siteID, collectionID, name, htmlTemplate string, isDefault bool) (*CollectionTemplateItem, error)
|
||||
CreateCollectionItem(ctx context.Context, siteID, collectionID, itemID string, templateID int, htmlContent string, position int, lastEditedBy string) (*CollectionItemWithTemplate, error)
|
||||
CreateCollectionItemAtomic(ctx context.Context, siteID, collectionID string, templateID int, lastEditedBy string) (*CollectionItemWithTemplate, error)
|
||||
ReorderCollectionItems(ctx context.Context, siteID, collectionID string, items []CollectionItemPosition, lastEditedBy string) error
|
||||
|
||||
// Transaction support
|
||||
WithTransaction(ctx context.Context, fn func(ContentRepository) error) error
|
||||
@@ -77,6 +79,12 @@ type CollectionItemWithTemplate struct {
|
||||
IsDefault bool `json:"is_default"`
|
||||
}
|
||||
|
||||
// CollectionItemPosition represents item position for reordering
|
||||
type CollectionItemPosition struct {
|
||||
ItemID string `json:"itemId"`
|
||||
Position int `json:"position"`
|
||||
}
|
||||
|
||||
// Helper function to convert sql.NullString to string
|
||||
func getStringFromNullString(ns sql.NullString) string {
|
||||
if ns.Valid {
|
||||
|
||||
@@ -269,6 +269,54 @@ func (r *SQLiteRepository) CreateCollectionItemAtomic(ctx context.Context, siteI
|
||||
return nil, fmt.Errorf("CreateCollectionItemAtomic not yet implemented for SQLite")
|
||||
}
|
||||
|
||||
// UpdateContent updates an existing content item
|
||||
func (r *SQLiteRepository) UpdateContent(ctx context.Context, siteID, contentID, htmlContent, lastEditedBy string) (*ContentItem, error) {
|
||||
content, err := r.queries.UpdateContent(ctx, sqlite.UpdateContentParams{
|
||||
HtmlContent: htmlContent,
|
||||
LastEditedBy: lastEditedBy,
|
||||
ID: contentID,
|
||||
SiteID: siteID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ContentItem{
|
||||
ID: content.ID,
|
||||
SiteID: content.SiteID,
|
||||
HTMLContent: content.HtmlContent,
|
||||
OriginalTemplate: FromNullString(content.OriginalTemplate),
|
||||
UpdatedAt: fmt.Sprintf("%d", content.UpdatedAt),
|
||||
LastEditedBy: content.LastEditedBy,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ReorderCollectionItems reorders collection items in bulk
|
||||
func (r *SQLiteRepository) ReorderCollectionItems(ctx context.Context, siteID, collectionID string, items []CollectionItemPosition, lastEditedBy string) error {
|
||||
// Use transaction for atomic bulk updates
|
||||
tx, err := r.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
qtx := r.queries.WithTx(tx)
|
||||
for _, item := range items {
|
||||
err = qtx.UpdateCollectionItemPosition(ctx, sqlite.UpdateCollectionItemPositionParams{
|
||||
ItemID: item.ItemID,
|
||||
CollectionID: collectionID,
|
||||
SiteID: siteID,
|
||||
Position: int64(item.Position),
|
||||
LastEditedBy: lastEditedBy,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update position for item %s: %w", item.ItemID, err)
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// WithTransaction executes a function within a database transaction
|
||||
func (r *SQLiteRepository) WithTransaction(ctx context.Context, fn func(ContentRepository) error) error {
|
||||
tx, err := r.db.BeginTx(ctx, nil)
|
||||
|
||||
Reference in New Issue
Block a user