design database
This commit is contained in:
@@ -36,3 +36,62 @@ import {
|
|||||||
import { sql } from "drizzle-orm";
|
import { sql } from "drizzle-orm";
|
||||||
|
|
||||||
import { id, createdAt, updatedAt } from "../common";
|
import { id, createdAt, updatedAt } from "../common";
|
||||||
|
import { user } from "./auth.db";
|
||||||
|
|
||||||
|
// Enums
|
||||||
|
const difficultyEnum = pgEnum('difficulty', ['easy', 'medium', 'hard']);
|
||||||
|
const levelTypeEnum = pgEnum('level_type', ['drag_drop', 'puzzle']);
|
||||||
|
const progressStatusEnum = pgEnum('progress_status', ['not_started', 'in_progress', 'completed']);
|
||||||
|
const rewardTypeEnum = pgEnum('reward_type', ['badge', 'points', 'certificate']);
|
||||||
|
|
||||||
|
// Tables
|
||||||
|
export const levels = pgTable("levels", {
|
||||||
|
id,
|
||||||
|
title: varchar("title", { length: 255 }).notNull(),
|
||||||
|
description: text("description"),
|
||||||
|
difficulty: difficultyEnum("difficulty").notNull(),
|
||||||
|
type: levelTypeEnum("type").notNull(),
|
||||||
|
content: jsonb("content"), // JSON data for puzzle/blocks
|
||||||
|
order: integer("order").notNull(),
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const userProgress = pgTable("user_progress", {
|
||||||
|
id,
|
||||||
|
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
||||||
|
levelId: integer("level_id").notNull().references(() => levels.id, { onDelete: "cascade" }),
|
||||||
|
status: progressStatusEnum("status").notNull().default('not_started'),
|
||||||
|
progress: integer("progress").notNull().default(0), // 0-100
|
||||||
|
completedAt: timestamp("completed_at"),
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const rewards = pgTable("rewards", {
|
||||||
|
id,
|
||||||
|
name: varchar("name", { length: 255 }).notNull(),
|
||||||
|
type: rewardTypeEnum("type").notNull(),
|
||||||
|
value: integer("value"), // e.g., points value
|
||||||
|
description: text("description"),
|
||||||
|
iconUrl: varchar("icon_url", { length: 255 }),
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const userRewards = pgTable("user_rewards", {
|
||||||
|
id,
|
||||||
|
userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
||||||
|
rewardId: integer("reward_id").notNull().references(() => rewards.id, { onDelete: "cascade" }),
|
||||||
|
earnedAt: timestamp("earned_at").defaultNow().notNull(),
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const parentChild = pgTable("parent_child", {
|
||||||
|
id,
|
||||||
|
parentId: text("parent_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
||||||
|
childId: text("child_id").notNull().references(() => user.id, { onDelete: "cascade" }),
|
||||||
|
createdAt,
|
||||||
|
updatedAt,
|
||||||
|
});
|
||||||
|
|||||||
16957
pnpm-lock.yaml
generated
16957
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user