feat: add redeem code affiliate rebate, batch concurrency API, and markdown page rendering
1. Redeem code affiliate rebate: balance-type redeem codes now trigger invite rebate for the inviter. Payment fulfillment uses context key to prevent double-rebate. 2. Batch concurrency update: new POST /admin/users/batch-concurrency endpoint supporting mode=set/add with all=true for all users. 3. Markdown page rendering: new GET /api/v1/pages/:slug API serves local .md files. Custom menu items with url="md:slug" render markdown with collapsible TOC sidebar, scroll spy, and copy buttons on code blocks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -737,6 +737,37 @@ func (r *userRepository) UpdateConcurrency(ctx context.Context, id int64, amount
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *userRepository) BatchSetConcurrency(ctx context.Context, userIDs []int64, value int) (int, error) {
|
||||
if len(userIDs) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
if value < 0 {
|
||||
value = 0
|
||||
}
|
||||
res, err := r.sql.ExecContext(ctx,
|
||||
"UPDATE users SET concurrency = $1, updated_at = NOW() WHERE id = ANY($2) AND deleted_at IS NULL",
|
||||
value, pq.Array(userIDs))
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("batch set concurrency: %w", err)
|
||||
}
|
||||
affected, _ := res.RowsAffected()
|
||||
return int(affected), nil
|
||||
}
|
||||
|
||||
func (r *userRepository) BatchAddConcurrency(ctx context.Context, userIDs []int64, delta int) (int, error) {
|
||||
if len(userIDs) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
res, err := r.sql.ExecContext(ctx,
|
||||
"UPDATE users SET concurrency = GREATEST(concurrency + $1, 0), updated_at = NOW() WHERE id = ANY($2) AND deleted_at IS NULL",
|
||||
delta, pq.Array(userIDs))
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("batch add concurrency: %w", err)
|
||||
}
|
||||
affected, _ := res.RowsAffected()
|
||||
return int(affected), nil
|
||||
}
|
||||
|
||||
func (r *userRepository) ExistsByEmail(ctx context.Context, email string) (bool, error) {
|
||||
return r.client.User.Query().Where(userEmailLookupPredicate(email)).Exist(ctx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user