feat(ops): ECR-007 行为分析与 ECR-008 内容运营后台
落地埋点 ingest/数据看板、首页宫格 CMS 与测评上下架;含账号引导、问答流式与免责声明去重,以及 review P1 审计同事务修复。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -102,3 +102,62 @@ func (r *AskRepo) ConsumeMembershipQuota(ctx context.Context, userID uuid.UUID)
|
||||
}
|
||||
return true, left, nil
|
||||
}
|
||||
|
||||
// GetAskPaidQuota returns purchased ask pack remaining.
|
||||
func (r *AskRepo) GetAskPaidQuota(ctx context.Context, userID uuid.UUID) (int, error) {
|
||||
var n int
|
||||
err := r.Pool.QueryRow(ctx, `
|
||||
SELECT ask_paid_quota_left FROM users WHERE id=$1 AND deleted_at IS NULL`, userID,
|
||||
).Scan(&n)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return 0, nil
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
// AddAskPaidQuota increments purchased ask pack remaining.
|
||||
func (r *AskRepo) AddAskPaidQuota(ctx context.Context, userID uuid.UUID, delta int) (int, error) {
|
||||
if delta <= 0 {
|
||||
return 0, errors.New("delta must be positive")
|
||||
}
|
||||
var n int
|
||||
err := r.Pool.QueryRow(ctx, `
|
||||
UPDATE users SET ask_paid_quota_left = ask_paid_quota_left + $2, updated_at=now()
|
||||
WHERE id=$1 AND deleted_at IS NULL
|
||||
RETURNING ask_paid_quota_left`, userID, delta,
|
||||
).Scan(&n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// ConsumeAskPaidQuota decrements purchased ask pack remaining.
|
||||
func (r *AskRepo) ConsumeAskPaidQuota(ctx context.Context, userID uuid.UUID) (ok bool, left int, err error) {
|
||||
err = r.Pool.QueryRow(ctx, `
|
||||
UPDATE users SET ask_paid_quota_left = ask_paid_quota_left - 1, updated_at=now()
|
||||
WHERE id=$1 AND deleted_at IS NULL AND ask_paid_quota_left > 0
|
||||
RETURNING ask_paid_quota_left`, userID,
|
||||
).Scan(&left)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return false, 0, nil
|
||||
}
|
||||
if err != nil {
|
||||
return false, 0, err
|
||||
}
|
||||
return true, left, nil
|
||||
}
|
||||
|
||||
// SoftDeleteThread marks a thread and its messages deleted for the owner.
|
||||
func (r *AskRepo) SoftDeleteThread(ctx context.Context, userID, threadID uuid.UUID) error {
|
||||
ct, err := r.Pool.Exec(ctx, `
|
||||
UPDATE ask_threads SET deleted_at=now(), updated_at=now()
|
||||
WHERE id=$1 AND user_id=$2 AND deleted_at IS NULL`, threadID, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ct.RowsAffected() == 0 {
|
||||
return errors.New("thread not found")
|
||||
}
|
||||
_, err = r.Pool.Exec(ctx, `
|
||||
UPDATE ask_messages SET deleted_at=now()
|
||||
WHERE thread_id=$1 AND deleted_at IS NULL`, threadID)
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user