feat: auth foundation, similar tools, costs, redundancy, anonymous voting
This commit is contained in:
@@ -241,6 +241,7 @@ export interface AuthUser {
|
||||
/** @nullable */
|
||||
preferredUsername?: string | null;
|
||||
role?: AuthUserRole;
|
||||
tier?: "free" | "premium" | "enterprise";
|
||||
isLocal?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export * from "./generated/api";
|
||||
export * from "./generated/api.schemas";
|
||||
export { setBaseUrl, setAuthTokenGetter } from "./custom-fetch";
|
||||
export { setBaseUrl, setAuthTokenGetter, customFetch } from "./custom-fetch";
|
||||
export type { AuthTokenGetter } from "./custom-fetch";
|
||||
|
||||
@@ -3,3 +3,5 @@ export * from "./ratings";
|
||||
export * from "./users";
|
||||
export * from "./audit-logs";
|
||||
export * from "./sessions";
|
||||
export * from "./tool-relations";
|
||||
export * from "./tool-costs";
|
||||
|
||||
@@ -10,6 +10,7 @@ export const ratingsTable = pgTable("ratings", {
|
||||
usability: integer("usability").notNull(),
|
||||
comment: text("comment"),
|
||||
reviewerName: text("reviewer_name"),
|
||||
voterToken: text("voter_token"),
|
||||
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { pgTable, text, serial, integer, numeric, timestamp } from "drizzle-orm/pg-core";
|
||||
import { toolsTable } from "./tools";
|
||||
import { usersTable } from "./users";
|
||||
|
||||
export const toolCostsTable = pgTable("tool_costs", {
|
||||
id: serial("id").primaryKey(),
|
||||
toolId: integer("tool_id").notNull().references(() => toolsTable.id, { onDelete: "cascade" }),
|
||||
licenseType: text("license_type", { enum: ["free", "subscription", "one_time", "usage_based"] }).notNull().default("free"),
|
||||
cost: numeric("cost", { precision: 10, scale: 2 }),
|
||||
currency: text("currency").default("EUR"),
|
||||
renewalDate: timestamp("renewal_date", { withTimezone: true }),
|
||||
notes: text("notes"),
|
||||
createdBy: integer("created_by").references(() => usersTable.id),
|
||||
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
import { pgTable, text, serial, integer, timestamp } from "drizzle-orm/pg-core";
|
||||
import { toolsTable } from "./tools";
|
||||
import { usersTable } from "./users";
|
||||
|
||||
export const toolRelationsTable = pgTable("tool_relations", {
|
||||
id: serial("id").primaryKey(),
|
||||
toolId: integer("tool_id").notNull().references(() => toolsTable.id, { onDelete: "cascade" }),
|
||||
relatedToolId: integer("related_tool_id").notNull().references(() => toolsTable.id, { onDelete: "cascade" }),
|
||||
relationType: text("relation_type", { enum: ["similar", "replaces", "superseded_by"] }).notNull().default("similar"),
|
||||
notes: text("notes"),
|
||||
createdBy: integer("created_by").references(() => usersTable.id),
|
||||
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
});
|
||||
@@ -5,9 +5,13 @@ import { z } from "zod/v4";
|
||||
export const usersTable = pgTable("users", {
|
||||
id: serial("id").primaryKey(),
|
||||
username: text("username").notNull().unique(),
|
||||
passwordHash: text("password_hash").notNull(),
|
||||
email: text("email"),
|
||||
role: text("role").notNull().default("user"),
|
||||
passwordHash: text("password_hash"),
|
||||
tier: text("tier").notNull().default("free"),
|
||||
authProvider: text("auth_provider").notNull().default("local"),
|
||||
authProviderId: text("auth_provider_id"),
|
||||
displayName: text("display_name"),
|
||||
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user