feat(ops): ECR-007 行为分析与 ECR-008 内容运营后台
ci / h5 (push) Canceled after 0s
ci / api (push) Canceled after 0s
ci / ess-docs (push) Canceled after 0s

落地埋点 ingest/数据看板、首页宫格 CMS 与测评上下架;含账号引导、问答流式与免责声明去重,以及 review P1 审计同事务修复。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-07 02:26:16 +08:00
co-authored by Cursor
parent 7e9023f0a8
commit 7ab9add5dd
132 changed files with 8276 additions and 491 deletions
+59
View File
@@ -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
}