120 lines
2.4 KiB
Bash
Executable File
120 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
# SQL 和缓存 key 组装 helper,供 remote acceptance 脚本复用。
|
||
|
||
sql_escape_literal() {
|
||
local value="$1"
|
||
local squote="'"
|
||
value=${value//$squote/$squote$squote}
|
||
printf '%s' "$value"
|
||
}
|
||
|
||
sql_literal() {
|
||
printf "'%s'" "$(sql_escape_literal "$1")"
|
||
}
|
||
|
||
build_top_up_user_balance_sql() {
|
||
local user_id="$1"
|
||
local min_balance="$2"
|
||
cat <<SQL
|
||
UPDATE users
|
||
SET balance = CASE WHEN balance < ${min_balance} THEN ${min_balance} ELSE balance END,
|
||
updated_at = now()
|
||
WHERE id = ${user_id};
|
||
SQL
|
||
}
|
||
|
||
build_bind_api_key_group_sql() {
|
||
local api_key="$1"
|
||
local group_id="$2"
|
||
cat <<SQL
|
||
UPDATE api_keys
|
||
SET group_id = ${group_id},
|
||
updated_at = now()
|
||
WHERE key = $(sql_literal "$api_key");
|
||
SQL
|
||
}
|
||
|
||
build_api_key_auth_cache_key() {
|
||
local api_key="$1"
|
||
local digest
|
||
digest="$(printf '%s' "$api_key" | sha256sum | awk '{print $1}')"
|
||
printf 'apikey:auth:%s' "$digest"
|
||
}
|
||
|
||
build_user_balance_cache_key() {
|
||
local user_id="$1"
|
||
printf 'billing:balance:%s' "$user_id"
|
||
}
|
||
|
||
build_subscription_billing_cache_key() {
|
||
local user_id="$1"
|
||
local group_id="$2"
|
||
printf 'billing:sub:%s:%s' "$user_id" "$group_id"
|
||
}
|
||
|
||
build_upsert_subscription_sql() {
|
||
local user_id="$1"
|
||
local group_id="$2"
|
||
local duration_days="$3"
|
||
local assigned_by="$4"
|
||
local notes="$5"
|
||
cat <<SQL
|
||
INSERT INTO user_subscriptions (
|
||
user_id,
|
||
group_id,
|
||
starts_at,
|
||
expires_at,
|
||
status,
|
||
assigned_by,
|
||
assigned_at,
|
||
notes,
|
||
created_at,
|
||
updated_at,
|
||
deleted_at
|
||
)
|
||
VALUES (
|
||
${user_id},
|
||
${group_id},
|
||
now(),
|
||
now() + interval '$(sql_escape_literal "$duration_days") days',
|
||
'active',
|
||
${assigned_by},
|
||
now(),
|
||
$(sql_literal "$notes"),
|
||
now(),
|
||
now(),
|
||
NULL
|
||
)
|
||
ON CONFLICT (user_id, group_id) WHERE deleted_at IS NULL
|
||
DO UPDATE SET
|
||
starts_at = EXCLUDED.starts_at,
|
||
expires_at = EXCLUDED.expires_at,
|
||
status = 'active',
|
||
assigned_by = EXCLUDED.assigned_by,
|
||
assigned_at = EXCLUDED.assigned_at,
|
||
notes = EXCLUDED.notes,
|
||
updated_at = now(),
|
||
deleted_at = NULL;
|
||
SQL
|
||
}
|
||
|
||
build_subscription_access_prep_sql() {
|
||
local user_id="$1"
|
||
local api_key="$2"
|
||
local group_id="$3"
|
||
local min_balance="$4"
|
||
local duration_days="$5"
|
||
local assigned_by="$6"
|
||
local notes="$7"
|
||
|
||
cat <<SQL
|
||
BEGIN;
|
||
$(build_top_up_user_balance_sql "$user_id" "$min_balance")
|
||
$(build_bind_api_key_group_sql "$api_key" "$group_id")
|
||
$(build_upsert_subscription_sql "$user_id" "$group_id" "$duration_days" "$assigned_by" "$notes")
|
||
COMMIT;
|
||
SQL
|
||
}
|