feat: feedback form

This commit is contained in:
Henry
2025-01-29 12:09:40 +00:00
parent 0521ad5e87
commit 8addf952a9
10 changed files with 1929 additions and 14 deletions

View File

@@ -1,6 +1,7 @@
import { authRouter } from "./routers/auth";
import { boardRouter } from "./routers/board";
import { cardRouter } from "./routers/card";
import { feedbackRouter } from "./routers/feedback";
import { importRouter } from "./routers/import";
import { labelRouter } from "./routers/label";
import { listRouter } from "./routers/list";
@@ -13,6 +14,7 @@ export const appRouter = createTRPCRouter({
auth: authRouter,
board: boardRouter,
card: cardRouter,
feedback: feedbackRouter,
label: labelRouter,
list: listRouter,
member: memberRouter,

View File

@@ -0,0 +1,41 @@
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import * as feedbackRepo from "@kan/db/repository/feedback.repo";
import { createTRPCRouter, protectedProcedure } from "../trpc";
export const feedbackRouter = createTRPCRouter({
create: protectedProcedure
.meta({ enabled: false })
.input(
z.object({
feedback: z.string().min(1),
url: z.string().min(1),
}),
)
.output(z.object({ success: z.boolean() }))
.mutation(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const result = await feedbackRepo.create(ctx.adminDb, {
feedback: input.feedback,
createdBy: userId,
url: input.url,
});
if (!result?.id)
throw new TRPCError({
message: `Unable to create workspace`,
code: "INTERNAL_SERVER_ERROR",
});
return { success: true };
}),
});

View File

@@ -0,0 +1,15 @@
CREATE TABLE IF NOT EXISTS "feedback" (
"id" bigserial PRIMARY KEY NOT NULL,
"feedback" text NOT NULL,
"createdBy" uuid NOT NULL,
"createdAt" timestamp DEFAULT now() NOT NULL,
"updatedAt" timestamp,
"url" text NOT NULL,
"reviewed" boolean DEFAULT false NOT NULL
);
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "feedback" ADD CONSTRAINT "feedback_createdBy_user_id_fk" FOREIGN KEY ("createdBy") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

File diff suppressed because it is too large Load Diff

View File

@@ -43,6 +43,13 @@
"when": 1737130330536,
"tag": "0005_modern_gideon",
"breakpoints": true
},
{
"idx": 6,
"version": "7",
"when": 1738149668712,
"tag": "0006_spicy_mach_iv",
"breakpoints": true
}
]
}

View File

@@ -0,0 +1,25 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "@kan/db/types/database.types";
export const create = async (
db: SupabaseClient<Database>,
feedbackInput: {
feedback: string;
createdBy: string;
url: string;
},
) => {
const { data } = await db
.from("feedback")
.insert({
feedback: feedbackInput.feedback,
createdBy: feedbackInput.createdBy,
url: feedbackInput.url,
})
.select(`id`)
.limit(1)
.single();
return data;
};

View File

@@ -2,6 +2,7 @@ import { relations } from "drizzle-orm";
import {
bigint,
bigserial,
boolean,
index,
integer,
pgEnum,
@@ -465,3 +466,22 @@ export const slugs = pgTable("workspace_slugs", {
slug: varchar("slug", { length: 255 }).notNull().unique(),
type: slugTypeEnum("type").notNull(),
});
export const feedback = pgTable("feedback", {
id: bigserial("id", { mode: "number" }).primaryKey(),
feedback: text("feedback").notNull(),
createdBy: uuid("createdBy")
.notNull()
.references(() => users.id),
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt"),
url: text("url").notNull(),
reviewed: boolean("reviewed").default(false).notNull(),
});
export const feedbackRelations = relations(feedback, ({ one }) => ({
createdBy: one(users, {
fields: [feedback.createdBy],
references: [users.id],
}),
}));

View File

@@ -394,6 +394,44 @@ export type Database = {
},
]
}
feedback: {
Row: {
createdAt: string
createdBy: string
feedback: string
id: number
reviewed: boolean
updatedAt: string | null
url: string
}
Insert: {
createdAt?: string
createdBy: string
feedback: string
id?: number
reviewed?: boolean
updatedAt?: string | null
url: string
}
Update: {
createdAt?: string
createdBy?: string
feedback?: string
id?: number
reviewed?: boolean
updatedAt?: string | null
url?: string
}
Relationships: [
{
foreignKeyName: "feedback_createdBy_user_id_fk"
columns: ["createdBy"]
isOneToOne: false
referencedRelation: "user"
referencedColumns: ["id"]
},
]
}
import: {
Row: {
createdAt: string