chore: baseline snapshot before moderation-strictness feature

Repo .git was damaged (refs/ missing, index truncated, object store near-empty).
Repaired via git init (rebuilt refs), stale index preserved as .git/index.corrupt-20260910.bak,
then full worktree committed as a rollback baseline.
This commit is contained in:
tamakyi
2026-09-10 10:56:27 +08:00
commit e3e59e7c69
296 changed files with 67458 additions and 0 deletions
+124
View File
@@ -0,0 +1,124 @@
-- ============================================================================
-- TamaBox 存量时间 +8h 漂移反向修正脚本(线上执行版)
-- 背景: 先前 timestamptz 迁移用 `AT TIME ZONE 'UTC'` 把存量"上海墙钟"误标为
-- UTC,导致全部存量时间绝对时刻 +8h(页面显示比真实本地时间晚 8 小时)。
-- 本脚本: 把当前值按 UTC 还原出原墙钟,再按 Asia/Shanghai 重新解释(净效果
-- -8h 绝对时刻,会话显示回到真实本地墙钟)。与会话时区无关。
-- 影响范围: nekobox.questions / users / censor_logs / upload_images 的
-- created_at / updated_at / deleted_at(12 列,全为 timestamptz)。
-- 安全: 全程无 DROP 业务对象;仅 CREATE SCHEMA/临时快照表 + ALTER TYPE。
-- 回滚方式见 PART 4(注释)。
-- 预期: PART 3 各项判读通过即成功;异常则执行 PART 4 回滚后贴回输出。
-- ============================================================================
-- PART 0: 核对当前状态 -------------------------------------------------------
-- 确认处于"错误状态"(时间列全为 timestamptz 且显示比真实晚 8h)。
-- 应输出 12 列 timestamptz; 3089 应显示 08:01:16(错误态) 而非 00:01:16。
SET TIME ZONE 'Asia/Shanghai';
SELECT 'PART 0: 当前状态核对(仅本次修正涉及的4表12列)' AS step;
SELECT table_name, column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'nekobox'
AND table_name IN ('questions','users','censor_logs','upload_images')
AND column_name IN ('created_at','updated_at','deleted_at')
ORDER BY table_name, column_name;
SELECT id, created_at AS now_display, (extract(epoch FROM created_at)*1000000000)::numeric(30,0) AS epoch_ns
FROM nekobox.questions WHERE id = 3089;
-- PART 1: 迁移前快照 ----------------------------------------------------------
CREATE SCHEMA IF NOT EXISTS diag_test;
DROP TABLE IF EXISTS diag_test.fix_before;
CREATE TABLE diag_test.fix_before(tbl text, col text, n bigint, s numeric);
DO $$
DECLARE r record;
BEGIN
FOR r IN
SELECT table_name tbl, column_name col
FROM information_schema.columns
WHERE table_schema='nekobox' AND data_type='timestamp with time zone'
AND column_name IN ('created_at','updated_at','deleted_at')
AND table_name IN ('questions','users','censor_logs','upload_images')
ORDER BY table_name, column_name
LOOP
EXECUTE format(
'INSERT INTO diag_test.fix_before SELECT %L, %L, count(%I), sum(extract(epoch FROM %I)*1000000000) FROM nekobox.%I',
r.tbl, r.col, r.col, r.col, r.tbl);
END LOOP;
END $$;
SELECT 'PART 1: 快照完成' AS step, count(*) AS cols FROM diag_test.fix_before;
-- PART 2: 反向修正 ------------------------------------------------------------
-- 核心: 原墙钟按 Asia/Shanghai 解释。净效果 = 绝对时刻 -8h, 会话显示回本地墙钟。
SELECT 'PART 2: 反向修正执行' AS step;
DO $$
DECLARE r record;
BEGIN
FOR r IN
SELECT table_name tbl, column_name col
FROM information_schema.columns
WHERE table_schema='nekobox' AND data_type='timestamp with time zone'
AND column_name IN ('created_at','updated_at','deleted_at')
AND table_name IN ('questions','users','censor_logs','upload_images')
ORDER BY table_name, column_name
LOOP
EXECUTE format(
'ALTER TABLE nekobox.%I ALTER COLUMN %I TYPE timestamptz USING (%I AT TIME ZONE ''UTC'' AT TIME ZONE ''Asia/Shanghai'')',
r.tbl, r.col, r.col);
END LOOP;
END $$;
SELECT '修正完成' AS step;
-- PART 3: 验收 -----------------------------------------------------------------
-- 3.1 关键行: 会话上海显示应回到真实本地墙钟(3089=00:01:16.678885+08, epoch 1788537676678885000)
DROP TABLE IF EXISTS diag_test.fix_after;
CREATE TABLE diag_test.fix_after(tbl text, col text, n bigint, s numeric);
DO $$
DECLARE r record;
BEGIN
FOR r IN
SELECT table_name tbl, column_name col
FROM information_schema.columns
WHERE table_schema='nekobox' AND data_type='timestamp with time zone'
AND column_name IN ('created_at','updated_at','deleted_at')
AND table_name IN ('questions','users','censor_logs','upload_images')
ORDER BY table_name, column_name
LOOP
EXECUTE format(
'INSERT INTO diag_test.fix_after SELECT %L, %L, count(%I), sum(extract(epoch FROM %I)*1000000000) FROM nekobox.%I',
r.tbl, r.col, r.col, r.col, r.tbl);
END LOOP;
END $$;
SELECT '3.1 修正后关键行(期望 3089=2026-09-05 00:01:16.678885+08 / epoch 1788537676678885000)' AS check_name;
SELECT id, created_at AS val_after, (extract(epoch FROM created_at)*1000000000)::numeric(30,0) AS epoch_ns
FROM nekobox.questions WHERE id IN (3089,3109,2411) ORDER BY id;
-- 3.2 keyset 翻页抽查(期望第2页 3088,2883..2411 共18条)
SELECT '3.2 keyset 第2页抽查' AS check_name;
SELECT q.id
FROM nekobox.questions q
WHERE q.user_id = 329 AND q.deleted_at IS NULL AND q.answer <> '' AND q.is_private = false
AND q.is_pinned = false
AND (q.created_at < TIMESTAMPTZ '2026-09-05 00:01:16.678885+08'
OR (q.created_at = TIMESTAMPTZ '2026-09-05 00:01:16.678885+08' AND q.id < 3089))
ORDER BY q.is_pinned DESC, q.created_at DESC, q.id DESC
LIMIT 20;
-- 3.3 全表差异留档(修正前后仅整体偏移, n 与结构不变; 供留档)
SELECT '3.3 修正前后列计数(应逐列一致)' AS check_name;
SELECT b.tbl, b.col, b.n AS n_before, a.n AS n_after
FROM diag_test.fix_before b JOIN diag_test.fix_after a USING (tbl,col)
WHERE b.n IS DISTINCT FROM a.n;
-- 3.4 列类型(仍应为 timestamptz, 残余 without=0)
SELECT '3.4 残余 timestamp without time zone(应0)' AS check_name;
SELECT count(*) AS remain_without
FROM information_schema.columns
WHERE table_schema='nekobox' AND data_type='timestamp without time zone'
AND column_name IN ('created_at','updated_at','deleted_at');
-- PART 4: 回滚(需要时才执行; 当前被注释) ---------------------------------------
-- 若修正后发现问题需回到"错误态"(UTC 基准):
-- 把 PART 2 的 USING 子句换成 (%I AT TIME ZONE 'Asia/Shanghai' AT TIME ZONE 'UTC')
-- 即: ALTER TABLE nekobox.xxx ALTER COLUMN c TYPE timestamptz
-- USING (c AT TIME ZONE 'Asia/Shanghai' AT TIME ZONE 'UTC');
-- 可先对比 diag_test.fix_before 快照确认还原。