Files
52b468bdee304e76b5480d6e57b…/database/schema/project.db.ts
NVWA Code Agent a20d191d92 design database
2026-01-05 06:19:05 +00:00

98 lines
3.6 KiB
TypeScript

import {
bigint, // BIGINT (大整数, -2^63 到 2^63-1)
bigserial, // BIGSERIAL (自增大整数, 1 到 2^63-1)
boolean, // BOOLEAN (布尔值)
char, // CHAR (定长字符串)
check, // 定义检查约束
date, // DATE (日期)
decimal, // DECIMAL/NUMERIC (精确数字, 指定 precision 和 scale)
doublePrecision, // DOUBLE PRECISION (双精度浮点数, 8字节)
foreignKey, // 定义外键
index, // 创建索引
integer, // INTEGER (整数, -2^31 到 2^31-1)
interval, // INTERVAL (时间间隔)
json, // JSON (JSON 数据)
jsonb, // JSONB (二进制 JSON, 推荐使用)
numeric, // NUMERIC (同 decimal)
pgEnum, // 定义枚举类型 (PostgreSQL ENUM)
pgMaterializedView, // 创建物化视图
pgPolicy, // 定义行级安全策略
pgRole, // 定义角色
pgSequence, // 创建序列
pgTable, // 定义表
pgTableCreator, // 创建自定义表名生成器的表定义函数
pgView, // 创建视图
primaryKey, // 定义主键
serial, // SERIAL (自增整数, 1 到 2^31-1)
text, // TEXT (变长字符串, 无长度限制)
time, // TIME (时间)
timestamp, // TIMESTAMP (日期时间, 无时区)
unique, // 定义唯一约束
uniqueIndex, // 创建唯一索引
uuid, // UUID (通用唯一标识符)
varchar, // VARCHAR (变长字符串, 指定长度)
} from "drizzle-orm/pg-core";
import { sql } from "drizzle-orm";
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,
});