Merge GitHub upstream into Gitea primary
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
create table if not exists public.admin_users (
|
||||
user_id uuid primary key references auth.users(id) on delete cascade,
|
||||
created_at timestamptz not null default now(),
|
||||
created_by uuid not null references auth.users(id),
|
||||
revoked_at timestamptz,
|
||||
revoked_by uuid references auth.users(id)
|
||||
);
|
||||
|
||||
alter table public.admin_users enable row level security;
|
||||
revoke all on table public.admin_users from anon, authenticated;
|
||||
grant select, insert, update on table public.admin_users to service_role;
|
||||
|
||||
alter table public.credit_transactions drop constraint if exists credit_transactions_transaction_type_check;
|
||||
alter table public.credit_transactions add constraint credit_transactions_transaction_type_check
|
||||
check (transaction_type in ('redeem', 'reserve', 'refund', 'payment'));
|
||||
alter table public.credit_transactions drop constraint if exists credit_transactions_amount_check;
|
||||
alter table public.credit_transactions add constraint credit_transactions_amount_check
|
||||
check ((transaction_type = 'reserve' and amount < 0) or (transaction_type in ('redeem', 'refund', 'payment') and amount > 0));
|
||||
|
||||
create table if not exists public.payment_packages (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
name text not null check (char_length(name) between 1 and 80),
|
||||
description text not null default '' check (char_length(description) <= 500),
|
||||
price_cents integer not null check (price_cents > 0),
|
||||
credits integer not null check (credits > 0),
|
||||
sort_order integer not null default 0,
|
||||
enabled boolean not null default true,
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now(),
|
||||
created_by uuid references auth.users(id) on delete set null
|
||||
);
|
||||
|
||||
create table if not exists public.payment_orders (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
order_no text not null unique check (char_length(order_no) between 16 and 100),
|
||||
user_id uuid not null references auth.users(id) on delete cascade,
|
||||
package_id uuid not null references public.payment_packages(id) on delete restrict,
|
||||
money_cents integer not null check (money_cents > 0),
|
||||
credits integer not null check (credits > 0),
|
||||
status text not null default 'pending' check (status in ('pending', 'paid', 'failed', 'expired')),
|
||||
epay_trade_no text,
|
||||
raw_notify_payload_hash text,
|
||||
paid_at timestamptz,
|
||||
created_at timestamptz not null default now()
|
||||
);
|
||||
|
||||
create unique index if not exists payment_orders_trade_no_idx on public.payment_orders(epay_trade_no) where epay_trade_no is not null;
|
||||
create index if not exists payment_orders_user_created_idx on public.payment_orders(user_id, created_at desc);
|
||||
create index if not exists payment_orders_created_status_idx on public.payment_orders(created_at desc, status);
|
||||
|
||||
alter table public.payment_packages enable row level security;
|
||||
alter table public.payment_orders enable row level security;
|
||||
revoke all on public.payment_packages, public.payment_orders from anon, authenticated;
|
||||
grant select on public.payment_orders to authenticated;
|
||||
drop policy if exists payment_orders_select_own on public.payment_orders;
|
||||
create policy payment_orders_select_own on public.payment_orders for select to authenticated using ((select auth.uid()) = user_id);
|
||||
grant all on public.payment_packages, public.payment_orders to service_role;
|
||||
|
||||
create or replace function public.settle_epay_order(p_order_no text, p_trade_no text, p_money_cents integer, p_payload_hash text)
|
||||
returns table (success boolean, status text, credits integer)
|
||||
language plpgsql security definer set search_path = public, pg_temp
|
||||
as $$
|
||||
declare v_order public.payment_orders%rowtype; v_balance integer;
|
||||
begin
|
||||
select * into v_order from public.payment_orders where order_no = btrim(p_order_no) for update;
|
||||
if not found or v_order.money_cents <> p_money_cents then return query select false, 'invalid'::text, null::integer; return; end if;
|
||||
if v_order.status = 'paid' then return query select true, 'paid'::text, v_order.credits; return; end if;
|
||||
select credits into v_balance from public.profiles where id = v_order.user_id for update;
|
||||
if not found then return query select false, 'profile_missing'::text, null::integer; return; end if;
|
||||
update public.profiles set credits = credits + v_order.credits, updated_at = now() where id = v_order.user_id returning credits into v_balance;
|
||||
insert into public.credit_transactions(user_id, transaction_type, amount, balance_after, request_id)
|
||||
values (v_order.user_id, 'payment', v_order.credits, v_balance, v_order.order_no)
|
||||
on conflict (user_id, transaction_type, request_id) do nothing;
|
||||
update public.payment_orders set status='paid', epay_trade_no=p_trade_no, raw_notify_payload_hash=p_payload_hash, paid_at=now() where id=v_order.id;
|
||||
return query select true, 'paid'::text, v_order.credits;
|
||||
end;
|
||||
$$;
|
||||
revoke all on function public.settle_epay_order(text, text, integer, text) from public, anon, authenticated;
|
||||
grant execute on function public.settle_epay_order(text, text, integer, text) to service_role;
|
||||
|
||||
create or replace function public.get_payment_order_stats(p_from timestamptz default null, p_to timestamptz default null)
|
||||
returns table (total_orders bigint, paid_orders bigint, pending_orders bigint, failed_expired_orders bigint, paid_amount_cents bigint, granted_credits bigint)
|
||||
language sql security definer set search_path = public, pg_temp
|
||||
as $$
|
||||
select
|
||||
count(*)::bigint,
|
||||
count(*) filter (where status = 'paid')::bigint,
|
||||
count(*) filter (where status = 'pending')::bigint,
|
||||
count(*) filter (where status in ('failed', 'expired'))::bigint,
|
||||
coalesce(sum(money_cents) filter (where status = 'paid'), 0)::bigint,
|
||||
coalesce(sum(credits) filter (where status = 'paid'), 0)::bigint
|
||||
from public.payment_orders
|
||||
where (p_from is null or created_at >= p_from)
|
||||
and (p_to is null or created_at <= p_to);
|
||||
$$;
|
||||
revoke all on function public.get_payment_order_stats(timestamptz, timestamptz) from public, anon, authenticated;
|
||||
grant execute on function public.get_payment_order_stats(timestamptz, timestamptz) to service_role;
|
||||
|
||||
create table if not exists public.epay_settings (
|
||||
id boolean primary key default true check (id),
|
||||
gateway_url text not null,
|
||||
pid text not null,
|
||||
encrypted_key text not null,
|
||||
notify_url text not null,
|
||||
return_url text not null,
|
||||
site_name text not null,
|
||||
chat_enabled boolean not null default false,
|
||||
updated_by uuid not null,
|
||||
updated_at timestamptz not null default clock_timestamp()
|
||||
);
|
||||
|
||||
alter table public.epay_settings enable row level security;
|
||||
revoke all on table public.epay_settings from public, anon, authenticated, service_role;
|
||||
grant select on table public.epay_settings to service_role;
|
||||
|
||||
alter table audit.admin_audit_logs
|
||||
drop constraint if exists admin_audit_logs_action_check,
|
||||
drop constraint if exists admin_audit_logs_target_type_check;
|
||||
alter table audit.admin_audit_logs
|
||||
add constraint admin_audit_logs_action_check check (
|
||||
action in ('redemption_code.create', 'redemption_code.update', 'redemption_code.revoke', 'epay_settings.update')
|
||||
),
|
||||
add constraint admin_audit_logs_target_type_check check (
|
||||
target_type in ('redemption_code', 'epay_settings')
|
||||
);
|
||||
|
||||
create or replace function public.admin_save_epay_settings(
|
||||
p_actor_user_id uuid,
|
||||
p_actor_email text,
|
||||
p_actor_role text,
|
||||
p_request_id text,
|
||||
p_gateway_url text,
|
||||
p_pid text,
|
||||
p_encrypted_key text,
|
||||
p_notify_url text,
|
||||
p_return_url text,
|
||||
p_site_name text,
|
||||
p_chat_enabled boolean,
|
||||
p_key_changed boolean
|
||||
)
|
||||
returns public.epay_settings
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = ''
|
||||
as $$
|
||||
declare
|
||||
v_email text;
|
||||
v_before public.epay_settings;
|
||||
v_after public.epay_settings;
|
||||
v_target_id constant uuid := '00000000-0000-0000-0000-000000000001';
|
||||
begin
|
||||
v_email := public.admin_verified_actor_email(p_actor_user_id, p_actor_email, p_actor_role);
|
||||
|
||||
select * into v_before from public.epay_settings where id = true for update;
|
||||
|
||||
insert into public.epay_settings (
|
||||
id, gateway_url, pid, encrypted_key, notify_url, return_url,
|
||||
site_name, chat_enabled, updated_by, updated_at
|
||||
) values (
|
||||
true, p_gateway_url, p_pid, p_encrypted_key, p_notify_url, p_return_url,
|
||||
p_site_name, p_chat_enabled, p_actor_user_id, clock_timestamp()
|
||||
)
|
||||
on conflict (id) do update set
|
||||
gateway_url = excluded.gateway_url,
|
||||
pid = excluded.pid,
|
||||
encrypted_key = excluded.encrypted_key,
|
||||
notify_url = excluded.notify_url,
|
||||
return_url = excluded.return_url,
|
||||
site_name = excluded.site_name,
|
||||
chat_enabled = excluded.chat_enabled,
|
||||
updated_by = excluded.updated_by,
|
||||
updated_at = excluded.updated_at
|
||||
returning * into v_after;
|
||||
|
||||
insert into audit.admin_audit_logs (
|
||||
actor_user_id, actor_email, actor_role, action, target_type,
|
||||
target_id, before_value, after_value, request_id
|
||||
) values (
|
||||
p_actor_user_id, v_email, p_actor_role, 'epay_settings.update', 'epay_settings',
|
||||
v_target_id,
|
||||
case when v_before.id is null then null else jsonb_build_object(
|
||||
'gatewayUrl', v_before.gateway_url,
|
||||
'pid', v_before.pid,
|
||||
'notifyUrl', v_before.notify_url,
|
||||
'returnUrl', v_before.return_url,
|
||||
'siteName', v_before.site_name,
|
||||
'chatEnabled', v_before.chat_enabled,
|
||||
'keyConfigured', true,
|
||||
'keyChanged', false
|
||||
) end,
|
||||
jsonb_build_object(
|
||||
'gatewayUrl', v_after.gateway_url,
|
||||
'pid', v_after.pid,
|
||||
'notifyUrl', v_after.notify_url,
|
||||
'returnUrl', v_after.return_url,
|
||||
'siteName', v_after.site_name,
|
||||
'chatEnabled', v_after.chat_enabled,
|
||||
'keyConfigured', true,
|
||||
'keyChanged', p_key_changed
|
||||
),
|
||||
p_request_id
|
||||
);
|
||||
|
||||
return v_after;
|
||||
end;
|
||||
$$;
|
||||
|
||||
revoke all on function public.admin_save_epay_settings(uuid, text, text, text, text, text, text, text, text, text, boolean, boolean)
|
||||
from public, anon, authenticated;
|
||||
grant execute on function public.admin_save_epay_settings(uuid, text, text, text, text, text, text, text, text, text, boolean, boolean)
|
||||
to service_role;
|
||||
|
||||
do $$
|
||||
begin
|
||||
if exists (select 1 from pg_roles where rolname = 'admin_runtime') then
|
||||
grant select, insert, update on table public.payment_packages to admin_runtime;
|
||||
grant select on table public.payment_orders to admin_runtime;
|
||||
grant select on table public.epay_settings to admin_runtime;
|
||||
grant execute on function public.admin_save_epay_settings(
|
||||
uuid, text, text, text, text, text, text, text, text, text, boolean, boolean
|
||||
) to admin_runtime;
|
||||
|
||||
drop policy if exists payment_packages_admin_select on public.payment_packages;
|
||||
create policy payment_packages_admin_select on public.payment_packages
|
||||
for select to admin_runtime using (true);
|
||||
|
||||
drop policy if exists payment_packages_admin_insert on public.payment_packages;
|
||||
create policy payment_packages_admin_insert on public.payment_packages
|
||||
for insert to admin_runtime with check (true);
|
||||
|
||||
drop policy if exists payment_packages_admin_update on public.payment_packages;
|
||||
create policy payment_packages_admin_update on public.payment_packages
|
||||
for update to admin_runtime using (true) with check (true);
|
||||
|
||||
drop policy if exists payment_orders_admin_select on public.payment_orders;
|
||||
create policy payment_orders_admin_select on public.payment_orders
|
||||
for select to admin_runtime using (true);
|
||||
|
||||
drop policy if exists epay_settings_admin_read on public.epay_settings;
|
||||
create policy epay_settings_admin_read on public.epay_settings
|
||||
for select to admin_runtime using (id = true);
|
||||
end if;
|
||||
end;
|
||||
$$;
|
||||
+3
-7
@@ -1,14 +1,12 @@
|
||||
begin;
|
||||
|
||||
alter table public.birth_time_rectification_v4_turns
|
||||
add column model_id text
|
||||
add column if not exists model_id text
|
||||
check (model_id is null or length(btrim(model_id)) between 1 and 120);
|
||||
|
||||
drop function public.submit_birth_time_rectification_v4_answer(
|
||||
drop function if exists public.submit_birth_time_rectification_v4_answer(
|
||||
uuid, uuid, uuid, bigint, uuid, uuid, text, uuid, text, text, uuid, timestamptz
|
||||
);
|
||||
|
||||
create function public.submit_birth_time_rectification_v4_answer(
|
||||
create or replace function public.submit_birth_time_rectification_v4_answer(
|
||||
p_user_id uuid, p_case_id uuid, p_action_id uuid, p_expected_version bigint,
|
||||
p_turn_id uuid, p_question_id uuid, p_question_domain text, p_question_target_event_id uuid, p_question text,
|
||||
p_answer text, p_model_id text, p_job_id uuid, p_now timestamptz
|
||||
@@ -54,5 +52,3 @@ revoke all on function public.submit_birth_time_rectification_v4_answer(
|
||||
grant execute on function public.submit_birth_time_rectification_v4_answer(
|
||||
uuid, uuid, uuid, bigint, uuid, uuid, text, uuid, text, text, text, uuid, timestamptz
|
||||
) to service_role;
|
||||
|
||||
commit;
|
||||
Reference in New Issue
Block a user