temp: auth-protected one-shot migration endpoint
This commit is contained in:
parent
12be105af4
commit
b7fb34fdde
1 changed files with 46 additions and 1 deletions
|
|
@ -1,16 +1,61 @@
|
|||
import { NextResponse } from "next/server";
|
||||
import { sql } from "@/db";
|
||||
import { requireFamily } from "@/lib/auth";
|
||||
|
||||
export async function GET() {
|
||||
const auth = await requireFamily();
|
||||
if (!auth.success) return NextResponse.json({ error: auth.error }, { status: auth.status });
|
||||
|
||||
try {
|
||||
const migrations = await sql.unsafe(
|
||||
`SELECT hash, created_at FROM __drizzle_migrations ORDER BY created_at DESC LIMIT 10`
|
||||
);
|
||||
const circleTables = await sql.unsafe(
|
||||
`SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND tablename LIKE 'circle%' ORDER BY tablename`
|
||||
`SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND (tablename LIKE 'circle%' OR tablename = 'post_reports') ORDER BY tablename`
|
||||
);
|
||||
return NextResponse.json({ migrations, circleTables });
|
||||
} catch (err: unknown) {
|
||||
return NextResponse.json({ error: err instanceof Error ? err.message : String(err) });
|
||||
}
|
||||
}
|
||||
|
||||
// One-shot: apply circles migration via the app DB connection (requires login)
|
||||
export async function POST(req: Request) {
|
||||
const auth = await requireFamily();
|
||||
if (!auth.success) return NextResponse.json({ error: auth.error }, { status: auth.status });
|
||||
|
||||
// Extra gate: require a confirmation header
|
||||
if (req.headers.get("x-run-migration") !== "yes") {
|
||||
return NextResponse.json({ error: "Missing confirmation header" }, { status: 400 });
|
||||
}
|
||||
|
||||
const steps = [
|
||||
`CREATE TABLE IF NOT EXISTS circles (id uuid PRIMARY KEY DEFAULT gen_random_uuid(), name text NOT NULL, created_by uuid NOT NULL REFERENCES families(id), created_at timestamptz NOT NULL DEFAULT now())`,
|
||||
`CREATE TABLE IF NOT EXISTS circle_members (circle_id uuid NOT NULL REFERENCES circles(id) ON DELETE CASCADE, family_id uuid NOT NULL REFERENCES families(id), role text NOT NULL DEFAULT 'member', joined_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY (circle_id, family_id))`,
|
||||
`CREATE TABLE IF NOT EXISTS circle_invites (id uuid PRIMARY KEY DEFAULT gen_random_uuid(), circle_id uuid NOT NULL REFERENCES circles(id) ON DELETE CASCADE, token text NOT NULL UNIQUE, created_by uuid NOT NULL REFERENCES families(id), expires_at timestamptz NOT NULL, consumed_at timestamptz, created_at timestamptz NOT NULL DEFAULT now())`,
|
||||
`CREATE TABLE IF NOT EXISTS circle_posts (id uuid PRIMARY KEY DEFAULT gen_random_uuid(), circle_id uuid NOT NULL REFERENCES circles(id) ON DELETE CASCADE, author_family_id uuid NOT NULL REFERENCES families(id), body text, image_key text, source_kind text, created_at timestamptz NOT NULL DEFAULT now())`,
|
||||
`CREATE TABLE IF NOT EXISTS circle_post_comments (id uuid PRIMARY KEY DEFAULT gen_random_uuid(), post_id uuid NOT NULL REFERENCES circle_posts(id) ON DELETE CASCADE, author_family_id uuid NOT NULL REFERENCES families(id), body text NOT NULL, created_at timestamptz NOT NULL DEFAULT now())`,
|
||||
`CREATE TABLE IF NOT EXISTS circle_post_reactions (post_id uuid NOT NULL REFERENCES circle_posts(id) ON DELETE CASCADE, family_id uuid NOT NULL REFERENCES families(id), emoji text NOT NULL, PRIMARY KEY (post_id, family_id, emoji))`,
|
||||
`CREATE TABLE IF NOT EXISTS post_reports (id uuid PRIMARY KEY DEFAULT gen_random_uuid(), post_id uuid NOT NULL REFERENCES circle_posts(id) ON DELETE CASCADE, reported_by uuid NOT NULL REFERENCES families(id), reason text, created_at timestamptz NOT NULL DEFAULT now())`,
|
||||
`CREATE INDEX IF NOT EXISTS circle_members_family_idx ON circle_members(family_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS circle_members_circle_idx ON circle_members(circle_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS circle_posts_circle_idx ON circle_posts(circle_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS circle_posts_author_idx ON circle_posts(author_family_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS circle_comments_post_idx ON circle_post_comments(post_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS circle_reactions_post_idx ON circle_post_reactions(post_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS circle_invites_token_idx ON circle_invites(token)`,
|
||||
];
|
||||
|
||||
const results: string[] = [];
|
||||
for (const step of steps) {
|
||||
try {
|
||||
await sql.unsafe(step);
|
||||
results.push(`OK: ${step.slice(0, 60)}`);
|
||||
} catch (err: unknown) {
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
results.push(`ERR: ${step.slice(0, 60)} → ${msg}`);
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json({ results });
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue