···928928 logger.info('Fetching archive_upload records ready for processing...')
929929930930 const ready = await sql`
931931- SELECT au.id, au.account_id, a.username, au.archive_at
932932- FROM public.archive_upload au left join all_account a on au.account_id=a.account_id
931931+ SELECT au.id, au.account_id, au.username, au.archive_at
932932+ FROM public.archive_upload au
933933 WHERE upload_phase IN ('ready_for_commit')
934934 ORDER BY archive_at ASC
935935 `
···11+-- Add username column to archive_upload table to store the handle at time of upload
22+-- This prevents issues when users change their handle after uploading archives
33+44+ALTER TABLE "public"."archive_upload"
55+ADD COLUMN "username" text;
66+77+-- Add a comment to explain the purpose
88+COMMENT ON COLUMN "public"."archive_upload"."username" IS 'Username/handle at the time of archive upload - used to locate archive files in storage';
99+1010+-- Populate username column in existing archive_upload records
1111+-- This migration updates existing records to have the username from all_account table
1212+1313+UPDATE "public"."archive_upload"
1414+SET "username" = "all_account"."username"
1515+FROM "public"."all_account"
1616+WHERE "archive_upload"."account_id" = "all_account"."account_id"
1717+ AND "archive_upload"."username" IS NULL;
···11+CREATE INDEX IF NOT EXISTS idx_archive_upload_username ON public.archive_upload USING btree (username);
22+33+CREATE INDEX IF NOT EXISTS idx_tweets_account_created ON public.tweets USING btree (account_id, created_at);
+4-9
supabase/schemas/020_tables.sql
···5454 "upload_likes" boolean DEFAULT true,
5555 "start_date" "date",
5656 "end_date" "date",
5757- "upload_phase" "public"."upload_phase_enum" DEFAULT 'uploading'::"public"."upload_phase_enum"
5757+ "upload_phase" "public"."upload_phase_enum" DEFAULT 'uploading'::"public"."upload_phase_enum",
5858+ "username" "text"
5859);
5960ALTER TABLE "public"."archive_upload" OWNER TO "postgres";
6061···218219 quoted_tweet_id TEXT NOT NULL,
219220220221 -- Composite primary key
221221- PRIMARY KEY (tweet_id, quoted_tweet_id),
222222-223223- -- Foreign key constraints
224224- CONSTRAINT fk_quote_tweets_tweet_id FOREIGN KEY (tweet_id) REFERENCES public.tweets (tweet_id) ON DELETE CASCADE
222222+ PRIMARY KEY (tweet_id, quoted_tweet_id)
225223);
226224227225ALTER TABLE "public"."quote_tweets" OWNER TO "postgres";
228226229227CREATE TABLE IF NOT EXISTS public.retweets (
230228 tweet_id TEXT NOT NULL PRIMARY KEY,
231231- retweeted_tweet_id TEXT NULL,
232232-233233- CONSTRAINT fk_retweets_tweet_id FOREIGN KEY (tweet_id) REFERENCES public.tweets (tweet_id) ON DELETE CASCADE,
234234- CONSTRAINT fk_retweets_retweeted_tweet_id FOREIGN KEY (retweeted_tweet_id) REFERENCES public.tweets (tweet_id) ON DELETE SET NULL
229229+ retweeted_tweet_id TEXT NULL
235230);
236231237232ALTER TABLE "public"."retweets" OWNER TO "postgres";
+2
supabase/schemas/030_indexes.sql
···5566-- public.archive_upload
77CREATE INDEX "idx_archive_upload_account_id" ON "public"."archive_upload" USING "btree" ("account_id");
88+CREATE INDEX "idx_archive_upload_username" ON "public"."archive_upload" USING "btree" ("username");
89910-- public.conversations
1011CREATE INDEX "idx_conversation_id" ON "public"."conversations" USING "btree" ("conversation_id");
···5859CREATE INDEX "text_fts" ON "public"."tweets" USING "gin" ("fts");
5960CREATE INDEX "tweets_account_id_favorite_idx" ON "public"."tweets" USING "btree" ("account_id", "favorite_count" DESC);
6061CREATE INDEX "tweets_account_id_retweet_idx" ON "public"."tweets" USING "btree" ("account_id", "retweet_count" DESC);
6262+CREATE INDEX "idx_tweets_account_created" ON public.tweets (account_id, created_at);
61636264-- public.user_mentions
6365CREATE INDEX "idx_user_mentions_mentioned_user_id" ON "public"."user_mentions" USING "btree" ("mentioned_user_id");
-10
supabase/schemas/040_views.sql
···2233-- public.account moved to 032_views_prereq.sql
4455--- public.quote_tweets
66-CREATE OR REPLACE VIEW "public"."quote_tweets" AS
77- SELECT "t"."tweet_id",
88- "substring"("tu"."expanded_url", 'status/([0-9]+)'::"text") AS "quoted_tweet_id",
99- "substring"("tu"."expanded_url", 'https?://(?:www\\.)?twitter\\.com/([^/]+)/status/'::"text") AS "quoted_tweet_username"
1010- FROM ("public"."tweet_urls" "tu"
1111- JOIN "public"."tweets" "t" ON (("tu"."tweet_id" = "t"."tweet_id")))
1212- WHERE (("tu"."expanded_url" ~~ 'https://twitter.com/%/status/%'::"text") OR ("tu"."expanded_url" ~~ 'https://x.com/%/status/%'::"text"));
1313-ALTER TABLE "public"."quote_tweets" OWNER TO "postgres";
1414-155-- public.enriched_tweets
166CREATE OR REPLACE VIEW "public"."enriched_tweets" AS
177 SELECT "t"."tweet_id",
+13
supabase/schemas/050_constraints.sql
···177177 ADD CONSTRAINT "optin_username_key" UNIQUE ("username");
178178ALTER TABLE ONLY "public"."optin"
179179 ADD CONSTRAINT "optin_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id") ON DELETE CASCADE;
180180+181181+182182+-- public.quote_tweets foreign keys
183183+ALTER TABLE ONLY "public"."quote_tweets"
184184+ ADD CONSTRAINT "fk_quote_tweets_tweet_id" FOREIGN KEY ("tweet_id") REFERENCES "public"."tweets"("tweet_id") ON DELETE CASCADE;
185185+ALTER TABLE ONLY "public"."quote_tweets"
186186+ ADD CONSTRAINT "fk_quote_tweets_quoted_tweet_id" FOREIGN KEY ("quoted_tweet_id") REFERENCES "public"."tweets"("tweet_id") ON DELETE CASCADE;
187187+188188+-- public.retweets foreign keys
189189+ALTER TABLE ONLY "public"."retweets"
190190+ ADD CONSTRAINT "fk_retweets_tweet_id" FOREIGN KEY ("tweet_id") REFERENCES "public"."tweets"("tweet_id") ON DELETE CASCADE;
191191+ALTER TABLE ONLY "public"."retweets"
192192+ ADD CONSTRAINT "fk_retweets_retweeted_tweet_id" FOREIGN KEY ("retweeted_tweet_id") REFERENCES "public"."tweets"("tweet_id") ON DELETE SET NULL;
+3-2
supabase/schemas/070_functions.sql
···934934DECLARE
935935 v_archive_upload_id BIGINT;
936936 v_account_id TEXT;
937937+ v_username TEXT;
937938 v_archive_at TIMESTAMP WITH TIME ZONE;
938939 v_keep_private BOOLEAN;
939940 v_upload_likes BOOLEAN;
···974975 v_phase_start := clock_timestamp();
975976 RAISE NOTICE 'Phase 2: Getting archive upload data';
976977 -- Get the archive upload that's ready for commit
977977- SELECT id, archive_at, keep_private, upload_likes, start_date, end_date
978978- INTO v_archive_upload_id, v_archive_at, v_keep_private, v_upload_likes, v_start_date, v_end_date
978978+ SELECT id, archive_at, keep_private, upload_likes, start_date, end_date, username
979979+ INTO v_archive_upload_id, v_archive_at, v_keep_private, v_upload_likes, v_start_date, v_end_date, v_username
979980 FROM public.archive_upload
980981 WHERE account_id = v_account_id
981982 AND upload_phase = 'ready_for_commit'
+6-2
supabase/schemas/prod.sql
···3434DECLARE
3535 v_archive_upload_id BIGINT;
3636 v_account_id TEXT;
3737+ v_username TEXT;
3738 v_archive_at TIMESTAMP WITH TIME ZONE;
3839 v_keep_private BOOLEAN;
3940 v_upload_likes BOOLEAN;
···7172 RAISE NOTICE 'Phase 2: Getting archive upload data';
7273 -- 2. Get the latest archive upload data from temp.archive_upload
7374 EXECUTE format('
7474- SELECT archive_at, keep_private, upload_likes, start_date, end_date
7575+ SELECT archive_at, keep_private, upload_likes, start_date, end_date, username
7576 FROM temp.archive_upload_%s
7677 ORDER BY archive_at DESC
7778 LIMIT 1
7878- ', p_suffix) INTO v_archive_at, v_keep_private, v_upload_likes, v_start_date, v_end_date;
7979+ ', p_suffix) INTO v_archive_at, v_keep_private, v_upload_likes, v_start_date, v_end_date, v_username;
79808081 RAISE NOTICE 'Phase 3: Inserting archive upload data';
8182 -- 3. Insert or update archive_upload and get the ID
8283 INSERT INTO public.archive_upload (
8384 account_id,
8585+ username,
8486 archive_at,
8587 created_at,
8688 keep_private,
···9193 )
9294 VALUES (
9395 v_account_id,
9696+ v_username,
9497 v_archive_at,
9598 CURRENT_TIMESTAMP,
9699 v_keep_private,
···102105 ON CONFLICT (account_id, archive_at)
103106 DO UPDATE SET
104107 account_id = EXCLUDED.account_id,
108108+ username = EXCLUDED.username,
105109 created_at = CURRENT_TIMESTAMP,
106110 keep_private = EXCLUDED.keep_private,
107111 upload_likes = EXCLUDED.upload_likes,