feat: scaffold relay client auth workspace

This commit is contained in:
L
2026-02-23 23:18:56 +00:00
parent b4942e4ab1
commit 050dbc792a
18 changed files with 3724 additions and 0 deletions

67
db/schema.sql Normal file
View File

@@ -0,0 +1,67 @@
-- PostgreSQL schema scaffold for dvv tunnel SaaS platform.
create extension if not exists pgcrypto;
create table if not exists users (
id uuid primary key default gen_random_uuid(),
email text unique not null,
password_hash text,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now()
);
create table if not exists plans (
id text primary key,
name text not null,
max_tunnels integer not null,
custom_subdomain boolean not null default false,
idle_timeout_seconds integer,
bandwidth_cap_kbps integer,
priority_routing boolean not null default false,
created_at timestamptz not null default now()
);
create table if not exists subscriptions (
id uuid primary key default gen_random_uuid(),
user_id uuid not null references users(id) on delete cascade,
plan_id text not null references plans(id),
provider text not null default 'stripe',
provider_customer_id text,
provider_subscription_id text,
status text not null,
current_period_end timestamptz,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now()
);
create index if not exists subscriptions_user_id_idx on subscriptions(user_id);
create table if not exists tunnels (
id uuid primary key default gen_random_uuid(),
user_id uuid not null references users(id) on delete cascade,
region text not null check (region in ('eu', 'us', 'asia')),
subdomain text not null,
custom_domain boolean not null default false,
active boolean not null default true,
created_at timestamptz not null default now(),
updated_at timestamptz not null default now(),
unique (region, subdomain)
);
create index if not exists tunnels_user_id_idx on tunnels(user_id);
create table if not exists usage_rollups_hourly (
user_id uuid not null references users(id) on delete cascade,
hour_bucket timestamptz not null,
bytes_in bigint not null default 0,
bytes_out bigint not null default 0,
player_connections integer not null default 0,
primary key (user_id, hour_bucket)
);
insert into plans (id, name, max_tunnels, custom_subdomain, idle_timeout_seconds, bandwidth_cap_kbps, priority_routing)
values
('free', 'Free', 1, false, 900, 512, false),
('pro', 'Pro', 5, true, null, 8192, true),
('team', 'Team', 25, true, null, null, true)
on conflict (id) do nothing;