package repository import ( "context" "github.com/geo-platform/tenant-api/internal/tenant/repository/generated" "github.com/jackc/pgx/v5" ) type CreateArticleInput struct { TenantID int64 SourceType string TemplateID *int64 KolPromptID *int64 } type CreateArticleVersionInput struct { ArticleID int64 VersionNo int Title string HTMLContent string MarkdownContent string WordCount int SourceLabel string } type ArticleRepository interface { CreateArticle(ctx context.Context, input CreateArticleInput) (int64, error) CreateArticleVersion(ctx context.Context, input CreateArticleVersionInput) (int64, error) UpdateArticleCurrentVersion(ctx context.Context, articleID, tenantID, versionID int64) error UpdateArticleGenerateStatus(ctx context.Context, articleID, tenantID int64, status string) error } type articleRepository struct { db generated.DBTX q generated.Querier } func NewArticleRepository(db generated.DBTX) ArticleRepository { return &articleRepository{db: db, q: newQuerier(db)} } func (r *articleRepository) CreateArticle(ctx context.Context, input CreateArticleInput) (int64, error) { return r.q.CreateArticle(ctx, generated.CreateArticleParams{ TenantID: input.TenantID, SourceType: input.SourceType, TemplateID: pgInt8(input.TemplateID), KolPromptID: pgInt8(input.KolPromptID), }) } func (r *articleRepository) CreateArticleVersion(ctx context.Context, input CreateArticleVersionInput) (int64, error) { previous, err := loadLatestArticleVersionContent(ctx, r.db, input.ArticleID) if err != nil { return 0, err } storedHTML, storedMarkdown := buildArticleVersionDiffStorage(*previous, ArticleVersionContent{ HTMLContent: stringPtr(input.HTMLContent), MarkdownContent: stringPtr(input.MarkdownContent), }) var versionID int64 err = r.db.QueryRow(ctx, ` INSERT INTO article_versions ( article_id, version_no, title, html_content, markdown_content, word_count, source_label ) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id `, input.ArticleID, input.VersionNo, pgText(&input.Title), pgText(storedHTML), pgText(storedMarkdown), input.WordCount, pgText(&input.SourceLabel), ).Scan(&versionID) if err != nil { return 0, err } return versionID, nil } func (r *articleRepository) UpdateArticleCurrentVersion(ctx context.Context, articleID, tenantID, versionID int64) error { tag, err := r.db.Exec(ctx, ` UPDATE articles SET current_version_id = $1, updated_at = NOW() WHERE id = $2 AND tenant_id = $3 AND deleted_at IS NULL `, pgInt8(&versionID), articleID, tenantID) if err != nil { return err } if tag.RowsAffected() == 0 { return pgx.ErrNoRows } return nil } func (r *articleRepository) UpdateArticleGenerateStatus(ctx context.Context, articleID, tenantID int64, status string) error { tag, err := r.db.Exec(ctx, ` UPDATE articles SET generate_status = $1, updated_at = NOW() WHERE id = $2 AND tenant_id = $3 AND deleted_at IS NULL `, status, articleID, tenantID) if err != nil { return err } if tag.RowsAffected() == 0 { return pgx.ErrNoRows } return nil }