45 lines
1.9 KiB
TypeScript
45 lines
1.9 KiB
TypeScript
import { pgTable, text, timestamp, integer } from "drizzle-orm/pg-core";
|
|
import { nostrIdentities } from "./nostr-identities";
|
|
|
|
// ── Status + reviewer types ───────────────────────────────────────────────────
|
|
|
|
export const QUEUE_STATUSES = ["pending", "approved", "rejected", "auto_approved", "flagged"] as const;
|
|
export type QueueStatus = (typeof QUEUE_STATUSES)[number];
|
|
|
|
export const QUEUE_REVIEWERS = ["timmy_ai", "admin"] as const;
|
|
export type QueueReviewer = (typeof QUEUE_REVIEWERS)[number];
|
|
|
|
// ── relay_event_queue ─────────────────────────────────────────────────────────
|
|
// Holds every event submitted by whitelisted (non-elite) accounts.
|
|
// Events wait here as "pending" until Timmy AI or an admin approves/rejects.
|
|
// On approval the API server injects the event into strfry via HTTP import.
|
|
// Elite accounts bypass this table entirely.
|
|
|
|
export const relayEventQueue = pgTable("relay_event_queue", {
|
|
eventId: text("event_id").primaryKey(),
|
|
|
|
pubkey: text("pubkey")
|
|
.notNull()
|
|
.references(() => nostrIdentities.pubkey, { onDelete: "cascade" }),
|
|
|
|
kind: integer("kind").notNull(),
|
|
|
|
// Full raw NIP-01 event JSON, stored as text so it can be forwarded to strfry
|
|
rawEvent: text("raw_event").notNull(),
|
|
|
|
status: text("status")
|
|
.$type<QueueStatus>()
|
|
.notNull()
|
|
.default("pending"),
|
|
|
|
// "timmy_ai" or "admin" — null until a decision is made
|
|
reviewedBy: text("reviewed_by").$type<QueueReviewer>(),
|
|
|
|
reviewReason: text("review_reason"),
|
|
|
|
createdAt: timestamp("created_at", { withTimezone: true }).defaultNow().notNull(),
|
|
decidedAt: timestamp("decided_at", { withTimezone: true }),
|
|
});
|
|
|
|
export type RelayEventQueueRow = typeof relayEventQueue.$inferSelect;
|