Skip to content

Commit 4f76e12

Browse files
committed
#build
1 parent e0b8685 commit 4f76e12

18 files changed

Lines changed: 96 additions & 708 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
alter table "public"."match_map_demos"
2+
drop column if exists "players";
3+
4+
drop function if exists public.clip_download_url(public.match_clips);
5+
6+
drop table if exists "public"."clip_render_jobs";
7+
drop table if exists "public"."match_clips";

hasura/migrations/default/1778300000000_create_clip_render_jobs_and_match_clips/up.sql renamed to hasura/migrations/default/1778300000000_clip_render_pipeline/up.sql

Lines changed: 56 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,23 @@
1-
-- match_clips: the durable record of a rendered clip.
2-
-- One row per successful render that the user chose to save to library.
3-
-- `download`-destination renders write a short-lived row only while the
4-
-- download URL is live and are reaped on the same window the file is.
51
create table if not exists "public"."match_clips" (
62
"id" uuid not null default gen_random_uuid(),
73
"user_steam_id" bigint not null,
84
"match_map_id" uuid not null,
95
"title" text,
10-
-- Wallclock duration of the rendered mp4. Filled by the pod after
11-
-- ffprobe; null while the upload is still in flight.
126
"duration_ms" integer,
13-
-- Final S3 location served via the same backblaze-proxy worker the
14-
-- demo files use. Null while the pod is still writing.
15-
"s3_url" text,
7+
"file" text,
168
"thumbnail_url" text,
17-
-- private | unlisted | match — only `private` is exposed by the v1
18-
-- editor; the column exists so phase-2 sharing flows don't need a
19-
-- migration. Default `private` so existing rows stay locked down.
209
"visibility" text not null default 'private',
10+
"target_steam_id" bigint,
2111
"created_at" timestamptz not null default now(),
2212
primary key ("id"),
2313
foreign key ("user_steam_id") references "public"."players" ("steam_id")
2414
on update cascade on delete cascade,
2515
foreign key ("match_map_id") references "public"."match_maps" ("id")
2616
on update cascade on delete cascade,
17+
foreign key ("target_steam_id") references "public"."players" ("steam_id")
18+
on update cascade on delete set null,
2719
constraint match_clips_visibility_chk
28-
check (visibility in ('private', 'unlisted', 'match'))
20+
check (visibility in ('private', 'unlisted', 'match', 'public'))
2921
);
3022

3123
create index if not exists "match_clips_user_steam_id_idx"
@@ -34,30 +26,23 @@ create index if not exists "match_clips_user_steam_id_idx"
3426
create index if not exists "match_clips_match_map_id_idx"
3527
on "public"."match_clips" ("match_map_id");
3628

37-
-- clip_render_jobs: ephemeral per-render record. The web subscribes to
38-
-- this row to drive the progress UI; the row is reaped once the clip
39-
-- is uploaded + match_clips row written (clip_id then points at it).
29+
create index if not exists "match_clips_target_steam_id_idx"
30+
on "public"."match_clips" ("target_steam_id");
31+
32+
create index if not exists "match_clips_public_created_at_idx"
33+
on "public"."match_clips" ("created_at" desc)
34+
where visibility = 'public';
35+
4036
create table if not exists "public"."clip_render_jobs" (
4137
"id" uuid not null default gen_random_uuid(),
4238
"user_steam_id" bigint not null,
4339
"match_map_id" uuid not null,
44-
-- Pod auth: the render pod posts back to /clip-renders/:id/status +
45-
-- /clip-renders/:id/upload with `x-origin-auth: <id>:<token>`. Same
46-
-- pattern as match_demo_sessions.session_token.
4740
"session_token" text not null,
4841
"k8s_job_name" text not null,
49-
-- The full ClipSpec sent by the editor (segments + overlays + audio
50-
-- + output). Stored as-is so a re-render later (or a debugging
51-
-- inspection) reproduces what was originally requested.
5242
"spec" jsonb not null,
53-
-- queued | rendering | uploading | done | error | cancelled
5443
"status" text not null default 'queued',
55-
-- 0..1 wallclock progress reported by the pod. Null while queued.
5644
"progress" numeric(4, 3),
5745
"error_message" text,
58-
-- Once the upload completes the pod creates a match_clips row and
59-
-- writes the id back here. The web subscription joins on this to
60-
-- show the final clip card.
6146
"clip_id" uuid,
6247
"status_history" jsonb not null default '[]'::jsonb,
6348
"last_status_at" timestamptz not null default now(),
@@ -75,15 +60,52 @@ create table if not exists "public"."clip_render_jobs" (
7560
check (progress is null or (progress >= 0 and progress <= 1))
7661
);
7762

78-
-- One in-flight job per user. Done/error/cancelled rows are excluded
79-
-- so the user can submit a new render once the previous finishes —
80-
-- this is the per-user concurrency cap referenced in the plan.
81-
create unique index if not exists "clip_render_jobs_one_in_flight_per_user"
82-
on "public"."clip_render_jobs" ("user_steam_id")
83-
where status in ('queued', 'rendering', 'uploading');
84-
8563
create index if not exists "clip_render_jobs_user_steam_id_idx"
8664
on "public"."clip_render_jobs" ("user_steam_id");
8765

8866
create index if not exists "clip_render_jobs_match_map_id_idx"
8967
on "public"."clip_render_jobs" ("match_map_id");
68+
69+
CREATE OR REPLACE FUNCTION public.clip_download_url(match_clips public.match_clips)
70+
RETURNS text
71+
LANGUAGE plpgsql STABLE
72+
AS $$
73+
DECLARE
74+
worker_url text;
75+
slug text;
76+
basename text;
77+
download_name text;
78+
BEGIN
79+
SELECT value INTO worker_url
80+
FROM settings
81+
WHERE name = 'cloudflare_worker_url';
82+
83+
IF worker_url IS NULL OR match_clips.file IS NULL THEN
84+
RETURN NULL;
85+
END IF;
86+
87+
slug := NULL;
88+
IF match_clips.title IS NOT NULL AND length(trim(match_clips.title)) > 0 THEN
89+
slug := regexp_replace(trim(match_clips.title), '[^a-zA-Z0-9_-]+', '-', 'g');
90+
slug := regexp_replace(slug, '^-+|-+$', '', 'g');
91+
IF length(slug) > 80 THEN
92+
slug := substring(slug from 1 for 80);
93+
END IF;
94+
IF length(slug) = 0 THEN
95+
slug := NULL;
96+
END IF;
97+
END IF;
98+
99+
basename := regexp_replace(match_clips.file, '^.*/', '');
100+
IF slug IS NOT NULL THEN
101+
download_name := slug || '.mp4';
102+
ELSE
103+
download_name := basename;
104+
END IF;
105+
106+
RETURN CONCAT(worker_url, '/', match_clips.file, '?name=', download_name);
107+
END;
108+
$$;
109+
110+
alter table "public"."match_map_demos"
111+
add column if not exists "players" jsonb null;

hasura/migrations/default/1778300000000_create_clip_render_jobs_and_match_clips/down.sql

Lines changed: 0 additions & 2 deletions
This file was deleted.

hasura/migrations/default/1778400000000_match_clips_file_and_download_url/down.sql

Lines changed: 0 additions & 19 deletions
This file was deleted.

hasura/migrations/default/1778400000000_match_clips_file_and_download_url/up.sql

Lines changed: 0 additions & 41 deletions
This file was deleted.

hasura/migrations/default/1778500000000_clip_download_url_path_style/down.sql

Lines changed: 0 additions & 19 deletions
This file was deleted.

hasura/migrations/default/1778500000000_clip_download_url_path_style/up.sql

Lines changed: 0 additions & 51 deletions
This file was deleted.

hasura/migrations/default/1778600000000_match_clips_target_and_public/down.sql

Lines changed: 0 additions & 18 deletions
This file was deleted.

hasura/migrations/default/1778600000000_match_clips_target_and_public/up.sql

Lines changed: 0 additions & 38 deletions
This file was deleted.

hasura/migrations/default/1778700000000_drop_clip_render_jobs_unique_in_flight/down.sql

Lines changed: 0 additions & 4 deletions
This file was deleted.

0 commit comments

Comments
 (0)