feat: editor write path

This commit is contained in:
Florian Sylvain committed 2026-11-02 03:24:30 +01:00
1 parent d9158025d4
commit a0b3c58c52
88 files changed
+5738 -263

No files matched your search

@@ -2,6 +2,7 @@ package database
import (
entity "RenewCMS/internal/infrastructure/persistence/models"
"fmt"
"gorm.io/gorm"
)
@@ -9,7 +10,9 @@ import (
const (
articleStoriesMarker = "article_stories"
articleStoryLanguageIndex = "idx_articles_story_lang"
articleStoryLanguageIndexSQL = "CREATE UNIQUE INDEX idx_articles_story_lang ON articles (story_id, lang)"
articleStoryLanguageIndexSQL = "CREATE UNIQUE INDEX idx_articles_story_lang ON articles (story_id, lang, retired_id)"
articleStoryRetiredMarker = "article_story_language_retired"
articleRetiredIDsMarker = "article_retired_ids"
)
func BackfillArticleStories(db *gorm.DB) error {
@@ -35,9 +38,64 @@ func BackfillArticleStories(db *gorm.DB) error {
})
}
func BackfillRetiredArticles(db *gorm.DB) error {
return db.Transaction(func(tx *gorm.DB) error {
applied, err := markerApplied(tx, articleRetiredIDsMarker)
if err != nil || applied {
return err
}
if err := tx.Unscoped().Model(&entity.Article{}).Where("deleted_at IS NOT NULL AND retired_id = ?", 0).UpdateColumn("retired_id", gorm.Expr("id")).Error; err != nil {
return err
}
return applyMarker(tx, articleRetiredIDsMarker)
})
}
type duplicateStoryLanguage struct {
StoryID uint32
Lang string
RetiredID uint32
Versions int
}
func checkStoryLanguagesUnique(db *gorm.DB) error {
var duplicates []duplicateStoryLanguage
err := db.Unscoped().Model(&entity.Article{}).
Select("story_id, lang, retired_id, COUNT(*) AS versions").
Group("story_id, lang, retired_id").
Having("COUNT(*) > 1").
Order("story_id ASC, lang ASC").
Limit(1).
Scan(&duplicates).Error
if err != nil || len(duplicates) == 0 {
return err
}
first := duplicates[0]
return fmt.Errorf("cannot create the unique index %s: story %d holds %d versions in language %q; merge or delete the extra versions, then start again", articleStoryLanguageIndex, first.StoryID, first.Versions, first.Lang)
}
func ensureArticleStoryLanguageIndex(db *gorm.DB) error {
if db.Migrator().HasIndex(&entity.Article{}, articleStoryLanguageIndex) {
replaced, err := markerApplied(db, articleStoryRetiredMarker)
if err != nil {
return err
}
indexed := db.Migrator().HasIndex(&entity.Article{}, articleStoryLanguageIndex)
if replaced && indexed {
return nil
}
return db.Exec(articleStoryLanguageIndexSQL).Error
if indexed {
if err := db.Migrator().DropIndex(&entity.Article{}, articleStoryLanguageIndex); err != nil {
return err
}
}
if err := checkStoryLanguagesUnique(db); err != nil {
return err
}
if err := db.Exec(articleStoryLanguageIndexSQL).Error; err != nil {
return err
}
if replaced {
return nil
}
return applyMarker(db, articleStoryRetiredMarker)
}