videofolxtv/shared/schema.ts
sebastjanartic e02d52998a Enable users to manage video playlists and mark favorite content
Adds new user, playlist, and favorites management API endpoints and React components.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 50814a1e-92e4-4968-856f-7bc7eedf5e8f
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/50814a1e-92e4-4968-856f-7bc7eedf5e8f/hISDNbZ
2025-08-04 20:04:23 +00:00

144 lines
5.1 KiB
TypeScript

import { sql } from "drizzle-orm";
import { pgTable, text, varchar, integer, timestamp, boolean, primaryKey, uuid } from "drizzle-orm/pg-core";
import { relations } from "drizzle-orm";
import { createInsertSchema } from "drizzle-zod";
import { z } from "zod";
export const videos = pgTable("videos", {
id: varchar("id").primaryKey(),
title: text("title").notNull(),
description: text("description"),
thumbnailUrl: text("thumbnail_url").notNull(),
videoUrl: text("video_url").notNull(),
duration: integer("duration").notNull(), // in seconds
views: integer("views").notNull().default(0),
category: text("category"),
createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
});
export const insertVideoSchema = createInsertSchema(videos).omit({
id: true,
createdAt: true,
});
export type InsertVideo = z.infer<typeof insertVideoSchema>;
export type Video = typeof videos.$inferSelect;
// Users table for authentication and user management
export const users = pgTable("users", {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
username: varchar("username", { length: 50 }).notNull().unique(),
email: varchar("email", { length: 255 }).notNull().unique(),
passwordHash: varchar("password_hash", { length: 255 }).notNull(),
firstName: varchar("first_name", { length: 100 }),
lastName: varchar("last_name", { length: 100 }),
avatar: text("avatar"),
isActive: boolean("is_active").notNull().default(true),
createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
updatedAt: timestamp("updated_at").notNull().default(sql`CURRENT_TIMESTAMP`),
});
export const insertUserSchema = createInsertSchema(users).omit({
id: true,
createdAt: true,
updatedAt: true,
});
export type InsertUser = z.infer<typeof insertUserSchema>;
export type User = typeof users.$inferSelect;
// Playlists table
export const playlists = pgTable("playlists", {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
name: varchar("name", { length: 255 }).notNull(),
description: text("description"),
isPublic: boolean("is_public").notNull().default(false),
thumbnailUrl: text("thumbnail_url"),
createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
updatedAt: timestamp("updated_at").notNull().default(sql`CURRENT_TIMESTAMP`),
});
export const insertPlaylistSchema = createInsertSchema(playlists).omit({
id: true,
createdAt: true,
updatedAt: true,
});
export type InsertPlaylist = z.infer<typeof insertPlaylistSchema>;
export type Playlist = typeof playlists.$inferSelect;
// Playlist videos junction table
export const playlistVideos = pgTable("playlist_videos", {
playlistId: uuid("playlist_id").notNull().references(() => playlists.id, { onDelete: "cascade" }),
videoId: varchar("video_id").notNull().references(() => videos.id, { onDelete: "cascade" }),
position: integer("position").notNull().default(0),
addedAt: timestamp("added_at").notNull().default(sql`CURRENT_TIMESTAMP`),
}, (table) => ({
pk: primaryKey({ columns: [table.playlistId, table.videoId] }),
}));
export const insertPlaylistVideoSchema = createInsertSchema(playlistVideos).omit({
addedAt: true,
});
export type InsertPlaylistVideo = z.infer<typeof insertPlaylistVideoSchema>;
export type PlaylistVideo = typeof playlistVideos.$inferSelect;
// User favorites table
export const userFavorites = pgTable("user_favorites", {
userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
videoId: varchar("video_id").notNull().references(() => videos.id, { onDelete: "cascade" }),
createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
}, (table) => ({
pk: primaryKey({ columns: [table.userId, table.videoId] }),
}));
export const insertUserFavoriteSchema = createInsertSchema(userFavorites).omit({
createdAt: true,
});
export type InsertUserFavorite = z.infer<typeof insertUserFavoriteSchema>;
export type UserFavorite = typeof userFavorites.$inferSelect;
// Relations
export const usersRelations = relations(users, ({ many }) => ({
playlists: many(playlists),
favorites: many(userFavorites),
}));
export const playlistsRelations = relations(playlists, ({ one, many }) => ({
user: one(users, {
fields: [playlists.userId],
references: [users.id],
}),
playlistVideos: many(playlistVideos),
}));
export const videosRelations = relations(videos, ({ many }) => ({
playlistVideos: many(playlistVideos),
userFavorites: many(userFavorites),
}));
export const playlistVideosRelations = relations(playlistVideos, ({ one }) => ({
playlist: one(playlists, {
fields: [playlistVideos.playlistId],
references: [playlists.id],
}),
video: one(videos, {
fields: [playlistVideos.videoId],
references: [videos.id],
}),
}));
export const userFavoritesRelations = relations(userFavorites, ({ one }) => ({
user: one(users, {
fields: [userFavorites.userId],
references: [users.id],
}),
video: one(videos, {
fields: [userFavorites.videoId],
references: [videos.id],
}),
}));