Add account based multiplayer hosting and bug report retention
This commit is contained in:
@@ -3,6 +3,7 @@ import { z } from "zod";
|
||||
import { admin, required } from "@/lib/supabase";
|
||||
import { verifySupportWebhook } from "@/lib/support-signature";
|
||||
import { supportCommand } from "@/shared/bug-reports";
|
||||
import { reconcileBugStatus, scheduleBugCleanup } from "@/lib/bug-lifecycle";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export async function POST(request: NextRequest) {
|
||||
@@ -59,6 +60,17 @@ export async function POST(request: NextRequest) {
|
||||
.safeParse(decoded);
|
||||
if (!payload.success) return new NextResponse(null, { status: 400 });
|
||||
const event = payload.data;
|
||||
if (event.type === "Issue" && ["create", "update"].includes(event.action)) {
|
||||
try {
|
||||
await reconcileBugStatus(event.data.id, true);
|
||||
return NextResponse.json({ ok: true });
|
||||
} catch {
|
||||
return NextResponse.json(
|
||||
{ error: "Support status delivery failed" },
|
||||
{ status: 503 },
|
||||
);
|
||||
}
|
||||
}
|
||||
// Only explicit new staff comments are public. Internal comments and user echoes stay private.
|
||||
if (
|
||||
event.action !== "create" ||
|
||||
@@ -71,6 +83,16 @@ export async function POST(request: NextRequest) {
|
||||
const command = supportCommand(event.data.body ?? "");
|
||||
if (!command) return NextResponse.json({ ok: true });
|
||||
try {
|
||||
if (command.kind === "close") {
|
||||
required(
|
||||
await admin().rpc("receive_bug_close", {
|
||||
p_report: event.data.issueId,
|
||||
p_external: event.data.id,
|
||||
}),
|
||||
);
|
||||
await scheduleBugCleanup(event.data.issueId);
|
||||
return NextResponse.json({ ok: true });
|
||||
}
|
||||
required(
|
||||
await admin().rpc("receive_bug_reply", {
|
||||
p_report: event.data.issueId,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { getI18n } from "@/lib/i18n";
|
||||
import { Header, Footer } from "@/components/Shell";
|
||||
import { DraftEditor } from "@/components/DraftEditor";
|
||||
import { user } from "@/lib/supabase";
|
||||
import { accountProfile } from "@/lib/profile";
|
||||
import { redirect } from "next/navigation";
|
||||
export default async function Draft({
|
||||
params,
|
||||
@@ -10,15 +11,17 @@ export default async function Draft({
|
||||
}) {
|
||||
const { t } = await getI18n();
|
||||
const { id } = await params;
|
||||
if (!(await user()))
|
||||
const account = await user();
|
||||
if (!account)
|
||||
redirect(`/log-in?next=${encodeURIComponent("/dashboard/" + id)}`);
|
||||
const profile = await accountProfile(account);
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<main className="section page-content">
|
||||
<span className="eyebrow">{t("YOUR WORLD · YOUR LOCATIONS")}</span>
|
||||
<h1>{t("Map workshop")}</h1>
|
||||
<DraftEditor id={id} />
|
||||
<DraftEditor id={id} hostName={profile.display_name} />
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
|
||||
@@ -8,6 +8,7 @@ import { getMap } from "@/lib/catalog";
|
||||
import { ContributionInstructions } from "@/components/ContributionInstructions";
|
||||
import { ReportContent } from "@/components/ReportContent";
|
||||
import { user } from "@/lib/supabase";
|
||||
import { accountProfile } from "@/lib/profile";
|
||||
import { ExportMap } from "@/components/MapTransfer";
|
||||
export default async function ServerPage({
|
||||
params,
|
||||
@@ -19,6 +20,7 @@ export default async function ServerPage({
|
||||
const map = await getMap(id);
|
||||
if (!map) notFound();
|
||||
const account = await user();
|
||||
const profile = account ? await accountProfile(account) : null;
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
@@ -63,7 +65,7 @@ export default async function ServerPage({
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<StartGame datasetId={id} />
|
||||
<StartGame datasetId={id} hostName={profile?.display_name ?? null} />
|
||||
</div>
|
||||
{map.allow_contributions && (
|
||||
<ContributionInstructions
|
||||
|
||||
Reference in New Issue
Block a user