feat: add feedback system with modal, api endpoints, and stats tracking

This commit is contained in:
Riccardo Giorato
2026-04-16 22:02:03 +02:00
parent 200a4e2a29
commit 62f8a0ca35
8 changed files with 263 additions and 32 deletions
+16 -2
View File
@@ -1,6 +1,6 @@
import { db } from './db';
import { stories, pages, type Story, type Page } from './schema';
import { eq } from 'drizzle-orm';
import { stories, pages, feedback, type Story, type Page, type Feedback } from './schema';
import { and, eq, gte, isNotNull, sql } from 'drizzle-orm';
import { generateComicSlug } from './slug-generator';
export async function createStory(data: { title: string; description?: string; userId: string; style?: string; usesOwnApiKey?: boolean }): Promise<Story> {
@@ -149,4 +149,18 @@ export async function deletePage(pageId: string): Promise<void> {
export async function deleteStory(storyId: string): Promise<void> {
await db.delete(stories).where(eq(stories.id, storyId));
}
export async function createFeedback(data: { message: string; userId?: string }): Promise<Feedback> {
const [entry] = await db.insert(feedback).values(data).returning();
return entry;
}
export async function getPagesGeneratedLast24Hours(): Promise<number> {
const since = new Date(Date.now() - 24 * 60 * 60 * 1000);
const [row] = await db
.select({ count: sql<number>`count(*)::int` })
.from(pages)
.where(and(isNotNull(pages.generatedImageUrl), gte(pages.createdAt, since)));
return row?.count ?? 0;
}
+12 -1
View File
@@ -1,4 +1,4 @@
import { pgTable, text, integer, timestamp, uuid, jsonb, boolean } from 'drizzle-orm/pg-core';
import { pgTable, text, integer, timestamp, uuid, jsonb, boolean, serial } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';
// Stories table
@@ -38,7 +38,18 @@ export const pagesRelations = relations(pages, ({ one }) => ({
}),
}));
// Feedback table
export const feedback = pgTable('feedback', {
id: serial('id').primaryKey(),
message: text('message').notNull(),
userId: text('user_id'),
createdAt: timestamp('created_at').defaultNow().notNull(),
});
// Types
export type Feedback = typeof feedback.$inferSelect;
export type NewFeedback = typeof feedback.$inferInsert;
export type Story = typeof stories.$inferSelect;
export type NewStory = typeof stories.$inferInsert;