Add user authentication and video upload capabilities
Implement user registration, login, and logout endpoints with session management. Integrate Multer for video file uploads and extend the schema for user, video upload, category, and tag management. Replit-Commit-Author: Agent Replit-Commit-Session-Id: d7424866-83d1-4486-a212-ac12b4c7becf Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/d7424866-83d1-4486-a212-ac12b4c7becf/WCZ9oGO
This commit is contained in:
+99
-3
@@ -1,10 +1,10 @@
|
||||
import { sql } from "drizzle-orm";
|
||||
import { pgTable, text, varchar, integer, timestamp, boolean } from "drizzle-orm/pg-core";
|
||||
import { pgTable, text, varchar, integer, timestamp, boolean, real } from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
export const videos = pgTable("videos", {
|
||||
id: varchar("id").primaryKey(),
|
||||
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
||||
title: text("title").notNull(),
|
||||
description: text("description").default("").notNull(),
|
||||
thumbnailUrl: text("thumbnail_url").notNull(),
|
||||
@@ -17,10 +17,71 @@ export const videos = pgTable("videos", {
|
||||
category: text("category").default("").notNull(),
|
||||
tags: text("tags").array().default([]).notNull(),
|
||||
isPublic: boolean("is_public").default(true).notNull(),
|
||||
uploadStatus: text("upload_status").default("pending").notNull(), // pending, processing, completed, failed
|
||||
originalFileName: text("original_file_name"),
|
||||
fileSize: integer("file_size"), // in bytes
|
||||
bitrate: integer("bitrate"), // in kbps
|
||||
resolution: text("resolution"), // e.g., "1920x1080"
|
||||
format: text("format"), // e.g., "mp4", "avi", "mov"
|
||||
encoding: text("encoding"), // e.g., "h264", "h265"
|
||||
createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
|
||||
updatedAt: timestamp("updated_at").notNull().default(sql`CURRENT_TIMESTAMP`),
|
||||
});
|
||||
|
||||
// User table for authentication and video ownership
|
||||
export const users = pgTable("users", {
|
||||
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
||||
username: varchar("username", { length: 50 }).notNull().unique(),
|
||||
email: varchar("email", { length: 255 }).notNull().unique(),
|
||||
password: varchar("password", { length: 255 }).notNull(),
|
||||
firstName: varchar("first_name", { length: 100 }),
|
||||
lastName: varchar("last_name", { length: 100 }),
|
||||
profileImageUrl: text("profile_image_url"),
|
||||
isAdmin: boolean("is_admin").default(false).notNull(),
|
||||
createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
|
||||
updatedAt: timestamp("updated_at").notNull().default(sql`CURRENT_TIMESTAMP`),
|
||||
});
|
||||
|
||||
// Video uploads table for tracking upload progress
|
||||
export const videoUploads = pgTable("video_uploads", {
|
||||
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
||||
userId: varchar("user_id").notNull().references(() => users.id),
|
||||
videoId: varchar("video_id").references(() => videos.id),
|
||||
originalFileName: text("original_file_name").notNull(),
|
||||
fileSize: integer("file_size").notNull(),
|
||||
mimeType: text("mime_type").notNull(),
|
||||
uploadStatus: text("upload_status").default("uploading").notNull(), // uploading, processing, completed, failed
|
||||
uploadProgress: real("upload_progress").default(0).notNull(), // 0-1
|
||||
errorMessage: text("error_message"),
|
||||
uploadUrl: text("upload_url"), // presigned URL for upload
|
||||
createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
|
||||
updatedAt: timestamp("updated_at").notNull().default(sql`CURRENT_TIMESTAMP`),
|
||||
});
|
||||
|
||||
// Categories table for better organization
|
||||
export const categories = pgTable("categories", {
|
||||
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
||||
name: text("name").notNull().unique(),
|
||||
description: text("description"),
|
||||
color: varchar("color", { length: 7 }).default("#000000").notNull(), // hex color
|
||||
createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
|
||||
});
|
||||
|
||||
// Tags table for better organization
|
||||
export const tags = pgTable("tags", {
|
||||
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
||||
name: text("name").notNull().unique(),
|
||||
useCount: integer("use_count").default(0).notNull(),
|
||||
createdAt: timestamp("created_at").notNull().default(sql`CURRENT_TIMESTAMP`),
|
||||
});
|
||||
|
||||
// Video tags junction table
|
||||
export const videoTags = pgTable("video_tags", {
|
||||
videoId: varchar("video_id").notNull().references(() => videos.id, { onDelete: "cascade" }),
|
||||
tagId: varchar("tag_id").notNull().references(() => tags.id, { onDelete: "cascade" }),
|
||||
});
|
||||
|
||||
// Schemas for form validation and API
|
||||
export const insertVideoSchema = createInsertSchema(videos).omit({
|
||||
id: true,
|
||||
createdAt: true,
|
||||
@@ -33,6 +94,41 @@ export const updateVideoSchema = createInsertSchema(videos).omit({
|
||||
updatedAt: true,
|
||||
}).partial();
|
||||
|
||||
export const insertUserSchema = createInsertSchema(users).omit({
|
||||
id: true,
|
||||
createdAt: true,
|
||||
updatedAt: true,
|
||||
});
|
||||
|
||||
export const insertVideoUploadSchema = createInsertSchema(videoUploads).omit({
|
||||
id: true,
|
||||
createdAt: true,
|
||||
updatedAt: true,
|
||||
});
|
||||
|
||||
export const insertCategorySchema = createInsertSchema(categories).omit({
|
||||
id: true,
|
||||
createdAt: true,
|
||||
});
|
||||
|
||||
export const insertTagSchema = createInsertSchema(tags).omit({
|
||||
id: true,
|
||||
createdAt: true,
|
||||
});
|
||||
|
||||
// Type exports
|
||||
export type Video = typeof videos.$inferSelect;
|
||||
export type InsertVideo = z.infer<typeof insertVideoSchema>;
|
||||
export type UpdateVideo = z.infer<typeof updateVideoSchema>;
|
||||
export type Video = typeof videos.$inferSelect;
|
||||
|
||||
export type User = typeof users.$inferSelect;
|
||||
export type InsertUser = z.infer<typeof insertUserSchema>;
|
||||
|
||||
export type VideoUpload = typeof videoUploads.$inferSelect;
|
||||
export type InsertVideoUpload = z.infer<typeof insertVideoUploadSchema>;
|
||||
|
||||
export type Category = typeof categories.$inferSelect;
|
||||
export type InsertCategory = z.infer<typeof insertCategorySchema>;
|
||||
|
||||
export type Tag = typeof tags.$inferSelect;
|
||||
export type InsertTag = z.infer<typeof insertTagSchema>;
|
||||
|
||||
Reference in New Issue
Block a user