feat: user relay management, blog naddr sync, and OG image update

Add UserRelay API and dashboard relays tab with NIP-65 import, store post
naddr for Nostr articles, and ship Prisma migrations for board tables,
user relays, and post metadata.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
bbe
2026-06-23 05:54:34 +02:00
co-authored by Cursor
parent 78271ea110
commit 3bdd01dedf
19 changed files with 896 additions and 132 deletions
+20 -1
View File
@@ -43,7 +43,15 @@ export const api = {
request<{ count: number; reactions: any[] }>(`/posts/${slug}/reactions`),
getPostReplies: (slug: string) =>
request<{ count: number; replies: any[] }>(`/posts/${slug}/replies`),
importPost: (data: { eventId?: string; naddr?: string }) =>
importPost: (data: {
nostrEventId: string;
naddr?: string;
title: string;
excerpt?: string;
authorPubkey: string;
publishedAt?: number;
tags?: string[];
}) =>
request<any>("/posts/import", { method: "POST", body: JSON.stringify(data) }),
updatePost: (id: string, data: any) =>
request<any>(`/posts/${id}`, { method: "PATCH", body: JSON.stringify(data) }),
@@ -116,6 +124,7 @@ export const api = {
request<void>(`/organizers/${id}`, { method: "DELETE" }),
// Relays
getPublicRelays: () => request<{ relays: string[] }>("/relays/public"),
getRelays: () => request<any[]>("/relays"),
addRelay: (data: { url: string; priority?: number }) =>
request<any>("/relays", { method: "POST", body: JSON.stringify(data) }),
@@ -126,6 +135,16 @@ export const api = {
testRelay: (id: string) =>
request<{ success: boolean }>(`/relays/${id}/test`, { method: "POST" }),
// User Relays
getUserRelays: () =>
request<any[]>("/user-relays"),
addUserRelay: (data: { url: string; read?: boolean; write?: boolean }) =>
request<any>("/user-relays", { method: "POST", body: JSON.stringify(data) }),
removeUserRelay: (id: string) =>
request<void>(`/user-relays/${id}`, { method: "DELETE" }),
importNip65Relays: () =>
request<{ imported: number; total?: number; message?: string }>("/user-relays/import-nip65", { method: "POST" }),
// Settings
getSettings: () => request<Record<string, string>>("/settings"),
getPublicSettings: () => request<Record<string, string>>("/settings/public"),