feat: 部署初版测试
Some checks failed
Extension Build & Release / build (push) Failing after 1m5s
Backend Deploy (Go + Docker) / deploy (push) Failing after 1m40s
Web Console Deploy (Vue 3 + Vite) / deploy (push) Has been cancelled

This commit is contained in:
zs
2026-03-02 21:25:21 +08:00
parent db3abb3174
commit 8cf6cb944b
97 changed files with 10250 additions and 209 deletions

View File

@@ -0,0 +1,74 @@
package repository
import (
"github.com/google/uuid"
"github.com/zs/InsightReply/internal/model"
"gorm.io/gorm"
)
type ReplyRepository struct {
db *gorm.DB
}
func NewReplyRepository(db *gorm.DB) *ReplyRepository {
return &ReplyRepository{db: db}
}
// CreateGeneratedReply logs an AI generated response when it is copied/used by the user
func (r *ReplyRepository) CreateGeneratedReply(reply *model.GeneratedReply) error {
return r.db.Create(reply).Error
}
// GetPendingPerformanceChecks returns copied replies that need their performance checked (e.g. older than 24h)
func (r *ReplyRepository) GetPendingPerformanceChecks() ([]model.GeneratedReply, error) {
var replies []model.GeneratedReply
// Complex: Fetch replies that are "copied", created more than 24 hours ago,
// and DO NOT already have a corresponding entry in reply_performance.
err := r.db.Table("generated_replies").
Select("generated_replies.*").
Joins("LEFT JOIN reply_performance rp ON rp.reply_id = generated_replies.id").
Where("generated_replies.status = ?", "copied").
Where("generated_replies.created_at < NOW() - INTERVAL '1 day'").
Where("rp.id IS NULL").
Find(&replies).Error
return replies, err
}
// SaveReplyPerformance persists the checked engagement scores of a generated reply
func (r *ReplyRepository) SaveReplyPerformance(perf *model.ReplyPerformance) error {
return r.db.Create(perf).Error
}
// UpsertDummyTweet acts as a safety hook to guarantee foreign key integrity exists before recording a reply onto an un-crawled Tweet.
func (r *ReplyRepository) UpsertDummyTweet(tweet *model.Tweet) error {
return r.db.Where("x_tweet_id = ?", tweet.XTweetID).FirstOrCreate(tweet).Error
}
// GetTweetXTweetID returns the string identifier string X uses, converting backwards from the postgres UUID
func (r *ReplyRepository) GetTweetXTweetID(tweetID uuid.UUID) (string, error) {
var tweet model.Tweet
err := r.db.Where("id = ?", tweetID).First(&tweet).Error
return tweet.XTweetID, err
}
// SaveStyleExtraction commits an AI-learned writing style profile against the user for future inference injection
func (r *ReplyRepository) SaveStyleExtraction(userID uuid.UUID, styleDesc string) error {
// user_style_profiles might not exist yet; use raw SQL or Gorm Upsert
return r.db.Exec(`
INSERT INTO user_style_profiles (user_id, tone_preference)
VALUES (?, ?)
ON CONFLICT (user_id)
DO UPDATE SET tone_preference = EXCLUDED.tone_preference, updated_at = NOW()
`, userID, styleDesc).Error
}
// GetGeneratedRepliesByUser retrieves all AI replies for a user to display in the History dashboard
func (r *ReplyRepository) GetGeneratedRepliesByUser(userID uuid.UUID) ([]model.GeneratedReply, error) {
var replies []model.GeneratedReply
// Preload the performance data if it exists. Preloading "Performance" requires GORM association.
// We'll just fetch replies and order by newest first.
err := r.db.Where("user_id = ?", userID).Order("created_at desc").Limit(100).Find(&replies).Error
return replies, err
}