pref: change the database type to SQLite
This commit is contained in:
@@ -149,10 +149,3 @@ OPERATING_ENV=production
|
||||
STORAGE_DIR=/public/uploads
|
||||
# 附件上传的最大大小
|
||||
MAX_UPLOAD_SIZE_MB=5
|
||||
|
||||
|
||||
POSTGRES_PASSWORD=p0stgr3s
|
||||
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
|
||||
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
|
||||
DATABASE_URL="postgresql://upage:${POSTGRES_PASSWORD}@localhost:5433/upage?schema=upage_schema"
|
||||
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -52,3 +52,5 @@ mock
|
||||
|
||||
# storage
|
||||
/public/uploads
|
||||
|
||||
/data/
|
||||
|
||||
95
Dockerfile
95
Dockerfile
@@ -1,78 +1,53 @@
|
||||
FROM node:20.18.0-alpine AS builder
|
||||
|
||||
# ---- build stage ----
|
||||
FROM node:20.18.0-alpine AS build
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk add --no-cache python3 make g++ bash
|
||||
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
|
||||
ENV HUSKY=0
|
||||
|
||||
RUN npm install -g pnpm && pnpm install
|
||||
# Use pnpm
|
||||
RUN corepack enable && corepack prepare pnpm@9.4.0 --activate
|
||||
|
||||
# Install deps efficiently
|
||||
COPY package.json pnpm-lock.yaml* ./
|
||||
RUN pnpm fetch
|
||||
|
||||
# Copy source and build
|
||||
COPY . .
|
||||
# install with dev deps (needed to build)
|
||||
RUN pnpm install --offline --frozen-lockfile
|
||||
|
||||
RUN NODE_OPTIONS="--max-old-space-size=4096" pnpm run build
|
||||
|
||||
FROM node:20.18.0-alpine AS deps
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk add --no-cache python3 make g++ bash
|
||||
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
|
||||
ENV HUSKY=0
|
||||
|
||||
RUN npm install -g pnpm && pnpm install --prod
|
||||
|
||||
COPY prisma ./prisma
|
||||
|
||||
# Generate prisma client
|
||||
RUN pnpm prisma generate
|
||||
|
||||
FROM node:20.18.0-alpine AS upage-ai-production
|
||||
# Build the Remix app (SSR + client)
|
||||
RUN NODE_OPTIONS=--max-old-space-size=4096 pnpm run build
|
||||
|
||||
# Keep only production deps for runtime
|
||||
RUN pnpm prune --prod --ignore-scripts
|
||||
|
||||
# ---- runtime stage ----
|
||||
FROM node:20.18.0-alpine AS runtime
|
||||
WORKDIR /app
|
||||
|
||||
RUN apk add --no-cache bash
|
||||
ENV NODE_ENV=production
|
||||
ENV LOGTO_ENABLE_DEV=false
|
||||
ENV PORT=3000
|
||||
ENV HOST=0.0.0.0
|
||||
|
||||
RUN npm install -g pnpm
|
||||
# Use pnpm
|
||||
RUN corepack enable && corepack prepare pnpm@9.4.0 --activate
|
||||
|
||||
ARG LOG_LEVEL=debug
|
||||
ARG PORT=3000
|
||||
ARG LLM_DEFAULT_PROVIDER
|
||||
ARG LLM_DEFAULT_MODEL
|
||||
ARG LLM_ENABLED_PROVIDERS
|
||||
ARG DEFAULT_NUM_CTX
|
||||
ARG OLLAMA_API_BASE_URL
|
||||
ARG TOGETHER_API_BASE_URL
|
||||
ARG LOGTO_ENDPOINT
|
||||
ARG LOGTO_APP_ID
|
||||
ARG LOGTO_BASE_URL
|
||||
# Install bash
|
||||
RUN apk add --no-cache bash \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV NODE_ENV=production \
|
||||
PORT=${PORT} \
|
||||
LOG_LEVEL=${LOG_LEVEL} \
|
||||
DEFAULT_NUM_CTX=${DEFAULT_NUM_CTX} \
|
||||
LLM_DEFAULT_PROVIDER=${LLM_DEFAULT_PROVIDER} \
|
||||
LLM_DEFAULT_MODEL=${LLM_DEFAULT_MODEL} \
|
||||
LLM_ENABLED_PROVIDERS=${LLM_ENABLED_PROVIDERS} \
|
||||
OLLAMA_API_BASE_URL=${OLLAMA_API_BASE_URL} \
|
||||
TOGETHER_API_BASE_URL=${TOGETHER_API_BASE_URL} \
|
||||
LOGTO_ENDPOINT=${LOGTO_ENDPOINT} \
|
||||
LOGTO_APP_ID=${LOGTO_APP_ID} \
|
||||
LOGTO_BASE_URL=${LOGTO_BASE_URL} \
|
||||
RUNNING_IN_DOCKER=true \
|
||||
STORAGE_DIR=/app/storage
|
||||
|
||||
COPY --from=builder /app/build ./build
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder /app/server.mjs ./
|
||||
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY --from=deps /app/prisma ./prisma
|
||||
|
||||
COPY package.json ./
|
||||
# Copy only what we need to run
|
||||
COPY --from=build /app/build /app/build
|
||||
COPY --from=build /app/node_modules /app/node_modules
|
||||
COPY --from=build /app/public ./public
|
||||
COPY --from=build /app/package.json /app/package.json
|
||||
COPY --from=build /app/server.mjs ./
|
||||
COPY --from=build /app/prisma ./prisma
|
||||
|
||||
COPY docker-entrypoint.sh /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
------------------------------
|
||||
|
||||
UPage 是一款基于人工智能的可视化网页构建平台,支持多种 AI 提供商集成,快速实现定制化网页。
|
||||
UPage 是一款基于人工智能的可视化网页构建平台,支持多种 AI 提供商集成,基于自然语言快速实现定制化网页。
|
||||
|
||||
------------------------------
|
||||
|
||||
@@ -30,7 +30,8 @@ docker run -d \
|
||||
-e OPENAI_LIKE_API_KEY=your-openai-like-api-key \
|
||||
-e LLM_DEFAULT_MODEL=your-default-model \
|
||||
-e LLM_MINOR_MODEL=your-minor-model \
|
||||
-v ./data:/app/data \
|
||||
-v ./logs:/app/logs \
|
||||
-v ./storage:/app/storage \
|
||||
ghcr.io/halo-dev/upage:latest
|
||||
ghcr.io/halo-dev/upage
|
||||
```
|
||||
|
||||
@@ -80,7 +80,7 @@ ${Object.entries(context)
|
||||
|
||||
return _streamText({
|
||||
model,
|
||||
tools,
|
||||
tools: tools(),
|
||||
system: systemPrompt,
|
||||
maxOutputTokens: maxTokens || MAX_TOKENS,
|
||||
messages: convertToModelMessages(messages),
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import type { Tool, ToolSet } from 'ai';
|
||||
import { serperTool } from './serper';
|
||||
import { weatherTool } from './weather';
|
||||
|
||||
export const tools = {
|
||||
serper: serperTool,
|
||||
weather: weatherTool,
|
||||
};
|
||||
export const tools: () => ToolSet = () => {
|
||||
const tools: Record<string, Tool> = {};
|
||||
|
||||
export { serperTool, weatherTool };
|
||||
if (process.env.SERPER_API_KEY) {
|
||||
tools.serper = serperTool;
|
||||
}
|
||||
|
||||
if (process.env.WEATHER_API_KEY) {
|
||||
tools.weather = weatherTool;
|
||||
}
|
||||
|
||||
return tools;
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { PrismaBetterSQLite3 } from '@prisma/adapter-better-sqlite3';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
// 创建PrismaClient实例
|
||||
@@ -7,13 +8,18 @@ declare global {
|
||||
var __db: PrismaClient | undefined;
|
||||
}
|
||||
|
||||
const adapter = new PrismaBetterSQLite3({
|
||||
url: 'file:data/upage.db',
|
||||
});
|
||||
|
||||
// 在开发环境中使用全局变量,避免热重载时创建多个实例
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
prisma = new PrismaClient();
|
||||
prisma = new PrismaClient({ adapter });
|
||||
} else {
|
||||
if (!global.__db) {
|
||||
global.__db = new PrismaClient({
|
||||
log: ['query', 'error', 'warn'],
|
||||
adapter,
|
||||
});
|
||||
}
|
||||
prisma = global.__db;
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
version: "3.9"
|
||||
services:
|
||||
upage:
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
image: upage-ai:dev
|
||||
image: upage-ai:production
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${PORT:-3000}:3000"
|
||||
environment:
|
||||
- OPERATING_ENV=${OPERATING_ENV:-production}
|
||||
- NODE_ENV=${NODE_ENV:-production}
|
||||
- DATABASE_URL=postgres://upage:${POSTGRES_PASSWORD}@postgres:5432/upage?schema=upage_schema
|
||||
- GROQ_API_KEY=${GROQ_API_KEY}
|
||||
- HuggingFace_API_KEY=${HuggingFace_API_KEY}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
@@ -48,23 +45,6 @@ services:
|
||||
- USAGE_LOG_FILE=true
|
||||
- STORAGE_DIR=/app/storage
|
||||
- MAX_UPLOAD_SIZE_MB=${MAX_UPLOAD_SIZE_MB:-5}
|
||||
networks:
|
||||
upage_network:
|
||||
postgres:
|
||||
image: postgres:17-alpine
|
||||
environment:
|
||||
POSTGRES_USER: upage
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
upage_network:
|
||||
|
||||
networks:
|
||||
upage_network:
|
||||
|
||||
volumes:
|
||||
upage-db:
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
version: "3.9"
|
||||
services:
|
||||
upage:
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
image: ghcr.io/halo-dev/upage:latest
|
||||
image: upage-ai:production
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${PORT:-3000}:3000"
|
||||
environment:
|
||||
- OPERATING_ENV=${OPERATING_ENV:-production}
|
||||
- NODE_ENV=${NODE_ENV:-production}
|
||||
- DATABASE_URL=postgres://upage:${POSTGRES_PASSWORD}@postgres:5432/upage?schema=upage_schema
|
||||
- GROQ_API_KEY=${GROQ_API_KEY}
|
||||
- HuggingFace_API_KEY=${HuggingFace_API_KEY}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
@@ -49,28 +45,9 @@ services:
|
||||
- USAGE_LOG_FILE=${USAGE_LOG_FILE:-true}
|
||||
- MAX_UPLOAD_SIZE_MB=${MAX_UPLOAD_SIZE_MB:-5}
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
- ./logs:/app/logs
|
||||
- ./storage:/app/storage
|
||||
networks:
|
||||
upage_network:
|
||||
postgres:
|
||||
image: postgres:17-alpine
|
||||
user: postgres
|
||||
environment:
|
||||
POSTGRES_USER: upage
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
volumes:
|
||||
- upage-db:/var/lib/postgresql/data
|
||||
networks:
|
||||
upage_network:
|
||||
|
||||
networks:
|
||||
upage_network:
|
||||
|
||||
volumes:
|
||||
upage-db:
|
||||
|
||||
@@ -1,131 +1,260 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
set -eo pipefail
|
||||
|
||||
echo "🚀 启动 UPage 应用..."
|
||||
SCRIPT_NAME=$(basename "$0")
|
||||
START_TIME=$(date +%s)
|
||||
MAX_DB_RETRIES=10
|
||||
DB_RETRY_INTERVAL=5
|
||||
TEMP_FILES=()
|
||||
|
||||
print_db_info() {
|
||||
if [ -z "$DATABASE_URL" ]; then
|
||||
echo "⚠️ 警告:DATABASE_URL 环境变量未设置!"
|
||||
return
|
||||
cleanup() {
|
||||
log_info "正在清理资源..."
|
||||
|
||||
for temp_file in "${TEMP_FILES[@]}"; do
|
||||
if [[ -f "$temp_file" ]]; then
|
||||
rm -f "$temp_file"
|
||||
log_debug "已删除临时文件: $temp_file"
|
||||
fi
|
||||
done
|
||||
|
||||
DB_USER=$(echo $DATABASE_URL | sed -n 's/.*:\/\/\([^:]*\):.*/\1/p')
|
||||
DB_HOST=$(echo $DATABASE_URL | sed -n 's/.*@\([^:]*\):.*/\1/p')
|
||||
DB_PORT=$(echo $DATABASE_URL | sed -n 's/.*:\([0-9]*\)\/.*/\1/p')
|
||||
DB_NAME=$(echo $DATABASE_URL | sed -n 's/.*\/\([^?]*\).*/\1/p')
|
||||
DB_SCHEMA=$(echo $DATABASE_URL | sed -n 's/.*schema=\([^&]*\).*/\1/p')
|
||||
|
||||
echo "📊 数据库连接信息:"
|
||||
echo " - 用户: $DB_USER"
|
||||
echo " - 主机: $DB_HOST"
|
||||
echo " - 端口: $DB_PORT"
|
||||
echo " - 数据库: $DB_NAME"
|
||||
echo " - Schema: $DB_SCHEMA"
|
||||
log_info "清理完成"
|
||||
}
|
||||
|
||||
echo "🖥️ 系统环境信息:"
|
||||
echo " - NODE_ENV: $NODE_ENV"
|
||||
echo " - 当前用户: $(whoami)"
|
||||
echo " - 工作目录: $(pwd)"
|
||||
handle_exit() {
|
||||
log_info "接收到退出信号,正在退出..."
|
||||
cleanup
|
||||
exit 0
|
||||
}
|
||||
|
||||
print_db_info
|
||||
trap handle_exit SIGTERM SIGINT
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "⏳ 等待数据库连接..."
|
||||
MAX_RETRIES=5
|
||||
RETRY_COUNT=0
|
||||
LOG_LEVEL_DEBUG=0
|
||||
LOG_LEVEL_INFO=1
|
||||
LOG_LEVEL_WARN=2
|
||||
LOG_LEVEL_ERROR=3
|
||||
CURRENT_LOG_LEVEL=${LOG_LEVEL_INFO}
|
||||
|
||||
ERROR_LOG=$(mktemp)
|
||||
if [[ "$LOG_LEVEL" == "debug" ]]; then
|
||||
CURRENT_LOG_LEVEL=${LOG_LEVEL_DEBUG}
|
||||
elif [[ "$LOG_LEVEL" == "info" ]]; then
|
||||
CURRENT_LOG_LEVEL=${LOG_LEVEL_INFO}
|
||||
elif [[ "$LOG_LEVEL" == "warn" ]]; then
|
||||
CURRENT_LOG_LEVEL=${LOG_LEVEL_WARN}
|
||||
elif [[ "$LOG_LEVEL" == "error" ]]; then
|
||||
CURRENT_LOG_LEVEL=${LOG_LEVEL_ERROR}
|
||||
fi
|
||||
|
||||
until pnpm prisma db push --accept-data-loss 2>$ERROR_LOG || pnpm prisma migrate deploy 2>$ERROR_LOG; do
|
||||
RETRY_COUNT=$((RETRY_COUNT + 1))
|
||||
|
||||
echo "❌ 数据库连接尝试 $RETRY_COUNT 失败,错误信息:"
|
||||
cat $ERROR_LOG
|
||||
|
||||
if [ $RETRY_COUNT -ge $MAX_RETRIES ]; then
|
||||
echo "❌ 数据库连接失败!已达到最大重试次数。"
|
||||
echo "🔍 最后一次错误详情:"
|
||||
cat $ERROR_LOG
|
||||
echo "🔍 尝试使用 pg_isready 检查数据库连接:"
|
||||
if command -v pg_isready >/dev/null 2>&1; then
|
||||
pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USER && echo "✅ 数据库可以连接" || echo "❌ 数据库无法连接"
|
||||
else
|
||||
echo "⚠️ pg_isready 命令不可用,无法进行连接测试"
|
||||
log_debug() {
|
||||
if [[ ${CURRENT_LOG_LEVEL} -le ${LOG_LEVEL_DEBUG} ]]; then
|
||||
echo "🔍 [$(date '+%Y-%m-%d %H:%M:%S')] [DEBUG] $*"
|
||||
fi
|
||||
}
|
||||
|
||||
log_info() {
|
||||
if [[ ${CURRENT_LOG_LEVEL} -le ${LOG_LEVEL_INFO} ]]; then
|
||||
echo "ℹ️ [$(date '+%Y-%m-%d %H:%M:%S')] [INFO] $*"
|
||||
fi
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
if [[ ${CURRENT_LOG_LEVEL} -le ${LOG_LEVEL_WARN} ]]; then
|
||||
echo "⚠️ [$(date '+%Y-%m-%d %H:%M:%S')] [WARN] $*"
|
||||
fi
|
||||
}
|
||||
|
||||
log_error() {
|
||||
if [[ ${CURRENT_LOG_LEVEL} -le ${LOG_LEVEL_ERROR} ]]; then
|
||||
echo "❌ [$(date '+%Y-%m-%d %H:%M:%S')] [ERROR] $*"
|
||||
fi
|
||||
}
|
||||
|
||||
log_success() {
|
||||
if [[ ${CURRENT_LOG_LEVEL} -le ${LOG_LEVEL_INFO} ]]; then
|
||||
echo "✅ [$(date '+%Y-%m-%d %H:%M:%S')] [SUCCESS] $*"
|
||||
fi
|
||||
}
|
||||
|
||||
# 创建安全的临时文件
|
||||
create_temp_file() {
|
||||
local temp_file
|
||||
temp_file=$(mktemp)
|
||||
TEMP_FILES+=("$temp_file")
|
||||
echo "$temp_file"
|
||||
}
|
||||
|
||||
safe_db_url() {
|
||||
# 直接返回固定的数据库路径
|
||||
echo "sqlite://data/upage.db"
|
||||
}
|
||||
|
||||
# 设置数据库信息
|
||||
extract_db_info() {
|
||||
DB_FILE="data/upage.db"
|
||||
return 0
|
||||
}
|
||||
|
||||
# 检查数据库连接
|
||||
check_db_connection() {
|
||||
log_info "检查 SQLite 数据库..."
|
||||
|
||||
if ! extract_db_info; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "SQLite 数据库文件路径: $DB_FILE"
|
||||
|
||||
# 如果数据库文件已存在,检查是否可读写
|
||||
if [[ -f "$DB_FILE" && ! -w "$DB_FILE" ]]; then
|
||||
log_error "SQLite 数据库文件存在但不可写: $DB_FILE"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 验证 Prisma 配置
|
||||
local output_file
|
||||
output_file=$(create_temp_file)
|
||||
|
||||
if pnpm prisma validate --schema=./prisma/schema.prisma > "$output_file" 2>&1; then
|
||||
log_success "Prisma 配置验证成功"
|
||||
else
|
||||
log_warn "Prisma 配置验证警告,但将继续执行:"
|
||||
cat "$output_file"
|
||||
fi
|
||||
|
||||
log_success "SQLite 数据库检查通过"
|
||||
return 0
|
||||
}
|
||||
|
||||
# 等待数据库就绪
|
||||
wait_for_db() {
|
||||
log_info "准备 SQLite 数据库..."
|
||||
|
||||
if check_db_connection; then
|
||||
log_success "SQLite 数据库就绪"
|
||||
return 0
|
||||
else
|
||||
log_error "SQLite 数据库检查失败"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 处理数据库迁移
|
||||
handle_db_migration() {
|
||||
log_info "处理数据库迁移..."
|
||||
|
||||
# 1. 尝试直接应用迁移
|
||||
local migrate_output
|
||||
migrate_output=$(create_temp_file)
|
||||
|
||||
log_info "尝试应用数据库迁移..."
|
||||
if pnpm prisma migrate deploy --schema=./prisma/schema.prisma > "$migrate_output" 2>&1; then
|
||||
log_success "数据库迁移成功应用"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if grep -q "P3005" "$migrate_output" || grep -q "数据库架构不为空" "$migrate_output"; then
|
||||
log_warn "检测到已存在的数据库结构,需要应用 baseline..."
|
||||
|
||||
local migration_dirs
|
||||
migration_dirs=$(find prisma/migrations -maxdepth 1 -type d | grep -v "^prisma/migrations$" | sort)
|
||||
|
||||
if [[ -z "$migration_dirs" ]]; then
|
||||
log_warn "未找到迁移,跳过 baseline 处理"
|
||||
else
|
||||
log_info "找到以下迁移:"
|
||||
|
||||
for migration_dir in $migration_dirs; do
|
||||
local migration_name
|
||||
migration_name=$(basename "$migration_dir")
|
||||
log_info " - $migration_name"
|
||||
|
||||
log_info "将迁移 $migration_name 标记为已应用..."
|
||||
local resolve_output
|
||||
resolve_output=$(create_temp_file)
|
||||
|
||||
if ! pnpm prisma migrate resolve --applied "$migration_name" > "$resolve_output" 2>&1; then
|
||||
log_warn "标记迁移 $migration_name 时出错:"
|
||||
cat "$resolve_output"
|
||||
fi
|
||||
done
|
||||
|
||||
log_success "Baseline 应用成功"
|
||||
|
||||
log_info "检查并应用新的迁移..."
|
||||
local deploy_output
|
||||
deploy_output=$(create_temp_file)
|
||||
|
||||
if ! pnpm prisma migrate deploy > "$deploy_output" 2>&1; then
|
||||
log_warn "应用新迁移时出错:"
|
||||
cat "$deploy_output"
|
||||
|
||||
log_info "尝试使用 db push 作为备选方案..."
|
||||
local push_output
|
||||
push_output=$(create_temp_file)
|
||||
|
||||
if ! pnpm prisma db push --accept-data-loss --skip-generate > "$push_output" 2>&1; then
|
||||
log_error "使用 db push 也失败了:"
|
||||
cat "$push_output"
|
||||
return 1
|
||||
else
|
||||
log_success "使用 db push 成功应用架构"
|
||||
fi
|
||||
else
|
||||
log_success "新迁移应用成功"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log_warn "迁移失败,错误信息:"
|
||||
cat "$migrate_output"
|
||||
|
||||
log_info "尝试使用 db push 作为备选方案..."
|
||||
local push_output
|
||||
push_output=$(create_temp_file)
|
||||
|
||||
if ! pnpm prisma db push --accept-data-loss --skip-generate > "$push_output" 2>&1; then
|
||||
log_error "使用 db push 也失败了:"
|
||||
cat "$push_output"
|
||||
return 1
|
||||
else
|
||||
log_success "使用 db push 成功应用架构"
|
||||
fi
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
main() {
|
||||
log_info "🚀 启动 UPage 应用..."
|
||||
|
||||
log_info "系统环境信息:"
|
||||
log_info " - NODE_ENV: $NODE_ENV"
|
||||
log_info " - 当前用户: $(whoami)"
|
||||
log_info " - 工作目录: $(pwd)"
|
||||
|
||||
if extract_db_info; then
|
||||
log_info "SQLite 数据库信息:"
|
||||
log_info " - 数据库文件: $DB_FILE"
|
||||
fi
|
||||
|
||||
if ! wait_for_db; then
|
||||
log_error "数据库连接失败,退出启动流程"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "⏳ 数据库尚未就绪,等待 5 秒后重试... (${RETRY_COUNT}/${MAX_RETRIES})"
|
||||
sleep 5
|
||||
done
|
||||
|
||||
rm -f $ERROR_LOG
|
||||
|
||||
echo "✅ 数据库连接成功"
|
||||
|
||||
echo "🔍 检查数据库迁移状态..."
|
||||
|
||||
MIGRATE_ERROR_LOG=$(mktemp)
|
||||
|
||||
if pnpm prisma migrate deploy 2>$MIGRATE_ERROR_LOG | grep -q "P3005"; then
|
||||
echo "📊 检测到已存在的数据库结构,需要应用baseline..."
|
||||
|
||||
echo "📑 获取所有迁移..."
|
||||
MIGRATION_DIRS=$(find prisma/migrations -maxdepth 1 -type d | grep -v "^prisma/migrations$" | sort)
|
||||
|
||||
if [ -z "$MIGRATION_DIRS" ]; then
|
||||
echo "⚠️ 未找到迁移,跳过baseline处理"
|
||||
else
|
||||
echo "🔄 找到以下迁移:"
|
||||
|
||||
for MIGRATION_DIR in $MIGRATION_DIRS; do
|
||||
MIGRATION_NAME=$(basename "$MIGRATION_DIR")
|
||||
echo " - $MIGRATION_NAME"
|
||||
|
||||
echo "🔖 将迁移 $MIGRATION_NAME 标记为已应用..."
|
||||
RESOLVE_ERROR_LOG=$(mktemp)
|
||||
if ! pnpm prisma migrate resolve --applied "$MIGRATION_NAME" 2>$RESOLVE_ERROR_LOG; then
|
||||
echo "⚠️ 标记迁移 $MIGRATION_NAME 时出错:"
|
||||
cat $RESOLVE_ERROR_LOG
|
||||
if ! handle_db_migration; then
|
||||
log_error "数据库迁移失败,退出启动流程"
|
||||
exit 1
|
||||
fi
|
||||
rm -f $RESOLVE_ERROR_LOG
|
||||
done
|
||||
|
||||
echo "✅ Baseline应用成功"
|
||||
local end_time
|
||||
end_time=$(date +%s)
|
||||
local duration=$((end_time - START_TIME))
|
||||
|
||||
echo "🔄 检查并应用新的迁移..."
|
||||
DEPLOY_ERROR_LOG=$(mktemp)
|
||||
if ! pnpm prisma migrate deploy 2>$DEPLOY_ERROR_LOG; then
|
||||
echo "⚠️ 应用新迁移时出错:"
|
||||
cat $DEPLOY_ERROR_LOG
|
||||
fi
|
||||
rm -f $DEPLOY_ERROR_LOG
|
||||
fi
|
||||
else
|
||||
if [ -s "$MIGRATE_ERROR_LOG" ]; then
|
||||
echo "⚠️ 数据库迁移过程中出现警告或错误:"
|
||||
cat $MIGRATE_ERROR_LOG
|
||||
else
|
||||
echo "🆕 数据库迁移已成功应用"
|
||||
fi
|
||||
fi
|
||||
log_success "初始化完成,耗时 ${duration} 秒"
|
||||
log_info "启动应用服务..."
|
||||
|
||||
rm -f $MIGRATE_ERROR_LOG
|
||||
log_info "执行命令: $*"
|
||||
exec "$@"
|
||||
}
|
||||
|
||||
echo "✅ 数据库迁移完成"
|
||||
|
||||
echo "🔧 生成 Prisma Client..."
|
||||
GENERATE_ERROR_LOG=$(mktemp)
|
||||
if ! pnpm prisma generate 2>$GENERATE_ERROR_LOG; then
|
||||
echo "⚠️ 生成 Prisma Client 时出错:"
|
||||
cat $GENERATE_ERROR_LOG
|
||||
else
|
||||
echo "✅ Prisma Client 生成完成"
|
||||
fi
|
||||
rm -f $GENERATE_ERROR_LOG
|
||||
|
||||
echo "🎉 启动应用服务..."
|
||||
|
||||
# 执行传入的命令
|
||||
echo "🚀 执行命令: $@"
|
||||
exec "$@"
|
||||
main "$@"
|
||||
|
||||
32
package.json
32
package.json
@@ -14,8 +14,9 @@
|
||||
"check:stage": "biome check --write --staged --no-errors-on-unmatched",
|
||||
"clean": "node scripts/clean.js",
|
||||
"setup": "prisma generate && prisma migrate deploy",
|
||||
"docker:build": "docker build -t upage-ai:dev -t upage-ai:latest --target upage-ai-production .",
|
||||
"docker:run": "docker compose -f docker-compose-dev.yaml up",
|
||||
"docker:build": "docker build -t upage-ai:production -t upage-ai:latest --target runtime .",
|
||||
"docker:dev:run": "docker compose -f docker-compose-dev.yaml up",
|
||||
"docker:prod:run": "docker compose -f docker-compose-prod.yaml up",
|
||||
"prepare": "husky || true",
|
||||
"test": "vitest --run",
|
||||
"test:watch": "vitest",
|
||||
@@ -41,6 +42,8 @@
|
||||
"@nanostores/react": "^1.0.0",
|
||||
"@octokit/rest": "^22.0.0",
|
||||
"@openrouter/ai-sdk-provider": "^1.2.0",
|
||||
"@prisma/adapter-better-sqlite3": "^6.16.2",
|
||||
"@prisma/client": "^6.16.2",
|
||||
"@radix-ui/react-checkbox": "^1.3.3",
|
||||
"@radix-ui/react-collapsible": "^1.1.12",
|
||||
"@radix-ui/react-context-menu": "^2.2.16",
|
||||
@@ -64,6 +67,7 @@
|
||||
"classnames": "^2.5.1",
|
||||
"compression": "^1.8.1",
|
||||
"cors": "^2.8.5",
|
||||
"cross-env": "^10.0.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"diff": "^8.0.2",
|
||||
"express": "^4.21.2",
|
||||
@@ -79,6 +83,8 @@
|
||||
"nanostores": "^1.0.1",
|
||||
"ollama-ai-provider-v2": "^1.3.1",
|
||||
"path-browserify": "^1.0.1",
|
||||
"prettier": "^3.6.2",
|
||||
"prisma": "^6.16.2",
|
||||
"qrcode": "1.5.1",
|
||||
"react": "^18.3.1",
|
||||
"react-chartjs-2": "^5.3.0",
|
||||
@@ -95,20 +101,19 @@
|
||||
"remix-utils": "^9.0.0",
|
||||
"shiki": "^3.13.0",
|
||||
"sonner": "^2.0.7",
|
||||
"unified": "^11.0.5",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"winston": "^3.17.0",
|
||||
"winston-daily-rotate-file": "^5.0.0",
|
||||
"zod": "^4.1.11",
|
||||
"unified": "^11.0.5",
|
||||
"prisma": "^6.16.2"
|
||||
"zod": "^4.1.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"dotenv": "^17.2.2",
|
||||
"@octokit/types": "^15.0.0",
|
||||
"@biomejs/biome": "2.2.4",
|
||||
"@iconify/json": "^2.2.387",
|
||||
"@iconify/types": "^2.0.0",
|
||||
"@prisma/client": "^6.16.2",
|
||||
"@octokit/types": "^15.0.0",
|
||||
"@remix-run/dev": "^2.17.1",
|
||||
"@remix-run/serve": "^2.17.1",
|
||||
"@testing-library/jest-dom": "^6.8.0",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@types/compression": "^1.8.1",
|
||||
@@ -118,24 +123,21 @@
|
||||
"@types/path-browserify": "^1.0.3",
|
||||
"@types/react": "^18.3.1",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"@unocss/reset": "^66.5.2",
|
||||
"@vitejs/plugin-react": "^5.0.3",
|
||||
"concurrently": "^9.2.1",
|
||||
"cross-env": "^10.0.0",
|
||||
"crypto-browserify": "^3.12.1",
|
||||
"dotenv": "^17.2.2",
|
||||
"fast-glob": "^3.3.3",
|
||||
"husky": "9.1.7",
|
||||
"node-fetch": "^3.3.2",
|
||||
"pnpm": "^10.17.1",
|
||||
"sass-embedded": "^1.93.1",
|
||||
"typescript": "^5.9.2",
|
||||
"unocss": "^66.5.2",
|
||||
"@unocss/reset": "^66.5.2",
|
||||
"vite": "^5.4.19",
|
||||
"vite-tsconfig-paths": "^5.1.4",
|
||||
"vitest": "^3.2.4",
|
||||
"@remix-run/dev": "^2.17.1",
|
||||
"@remix-run/serve": "^2.17.1",
|
||||
"node-fetch": "^3.3.2",
|
||||
"prettier": "^3.6.2"
|
||||
"vitest": "^3.2.4"
|
||||
},
|
||||
"packageManager": "pnpm@9.4.0",
|
||||
"engines": {
|
||||
|
||||
169
pnpm-lock.yaml
generated
169
pnpm-lock.yaml
generated
@@ -65,6 +65,12 @@ importers:
|
||||
'@openrouter/ai-sdk-provider':
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0(ai@5.0.49(zod@4.1.11))(zod@4.1.11)
|
||||
'@prisma/adapter-better-sqlite3':
|
||||
specifier: ^6.16.2
|
||||
version: 6.16.2
|
||||
'@prisma/client':
|
||||
specifier: ^6.16.2
|
||||
version: 6.16.2(prisma@6.16.2(typescript@5.9.2))(typescript@5.9.2)
|
||||
'@radix-ui/react-checkbox':
|
||||
specifier: ^1.3.3
|
||||
version: 1.3.3(@types/react-dom@18.3.7(@types/react@18.3.24))(@types/react@18.3.24)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -134,6 +140,9 @@ importers:
|
||||
cors:
|
||||
specifier: ^2.8.5
|
||||
version: 2.8.5
|
||||
cross-env:
|
||||
specifier: ^10.0.0
|
||||
version: 10.0.0
|
||||
date-fns:
|
||||
specifier: ^4.1.0
|
||||
version: 4.1.0
|
||||
@@ -179,6 +188,9 @@ importers:
|
||||
path-browserify:
|
||||
specifier: ^1.0.1
|
||||
version: 1.0.1
|
||||
prettier:
|
||||
specifier: ^3.6.2
|
||||
version: 3.6.2
|
||||
prisma:
|
||||
specifier: ^6.16.2
|
||||
version: 6.16.2(typescript@5.9.2)
|
||||
@@ -258,9 +270,6 @@ importers:
|
||||
'@octokit/types':
|
||||
specifier: ^15.0.0
|
||||
version: 15.0.0
|
||||
'@prisma/client':
|
||||
specifier: ^6.16.2
|
||||
version: 6.16.2(prisma@6.16.2(typescript@5.9.2))(typescript@5.9.2)
|
||||
'@remix-run/dev':
|
||||
specifier: ^2.17.1
|
||||
version: 2.17.1(@remix-run/react@2.17.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@remix-run/serve@2.17.1(typescript@5.9.2))(@types/node@22.15.21)(sass-embedded@1.93.1)(sass@1.93.1)(typescript@5.9.2)(vite@5.4.19(@types/node@22.15.21)(sass-embedded@1.93.1)(sass@1.93.1))
|
||||
@@ -303,9 +312,6 @@ importers:
|
||||
concurrently:
|
||||
specifier: ^9.2.1
|
||||
version: 9.2.1
|
||||
cross-env:
|
||||
specifier: ^10.0.0
|
||||
version: 10.0.0
|
||||
crypto-browserify:
|
||||
specifier: ^3.12.1
|
||||
version: 3.12.1
|
||||
@@ -324,9 +330,6 @@ importers:
|
||||
pnpm:
|
||||
specifier: ^10.17.1
|
||||
version: 10.17.1
|
||||
prettier:
|
||||
specifier: ^3.6.2
|
||||
version: 3.6.2
|
||||
sass-embedded:
|
||||
specifier: ^1.93.1
|
||||
version: 1.93.1
|
||||
@@ -1382,6 +1385,9 @@ packages:
|
||||
'@polka/url@1.0.0-next.29':
|
||||
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
|
||||
|
||||
'@prisma/adapter-better-sqlite3@6.16.2':
|
||||
resolution: {integrity: sha512-bCYiAveZAYZJTLsykJDZLXSpZ+0zu7KgoSl5VFlxR72S0WqCaImbtvFHxGDpwxhC9gO7skqZI7hQXDHSHDM0ig==}
|
||||
|
||||
'@prisma/client@6.16.2':
|
||||
resolution: {integrity: sha512-E00PxBcalMfYO/TWnXobBVUai6eW/g5OsifWQsQDzJYm7yaY+IRLo7ZLsaefi0QkTpxfuhFcQ/w180i6kX3iJw==}
|
||||
engines: {node: '>=18.18'}
|
||||
@@ -1400,6 +1406,9 @@ packages:
|
||||
'@prisma/debug@6.16.2':
|
||||
resolution: {integrity: sha512-bo4/gA/HVV6u8YK2uY6glhNsJ7r+k/i5iQ9ny/3q5bt9ijCj7WMPUwfTKPvtEgLP+/r26Z686ly11hhcLiQ8zA==}
|
||||
|
||||
'@prisma/driver-adapter-utils@6.16.2':
|
||||
resolution: {integrity: sha512-DMgfafnG0zPd+QoAQOC0Trn1xlb0fVAfQi2MpkpzSf641KiVkVPkJRXDSbcTbxGxO2HRdd0vI9U6LlesWad4XA==}
|
||||
|
||||
'@prisma/engines-version@6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43':
|
||||
resolution: {integrity: sha512-ThvlDaKIVrnrv97ujNFDYiQbeMQpLa0O86HFA2mNoip4mtFqM7U5GSz2ie1i2xByZtvPztJlNRgPsXGeM/kqAA==}
|
||||
|
||||
@@ -2612,10 +2621,16 @@ packages:
|
||||
before-after-hook@4.0.0:
|
||||
resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==}
|
||||
|
||||
better-sqlite3@11.10.0:
|
||||
resolution: {integrity: sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==}
|
||||
|
||||
binary-extensions@2.3.0:
|
||||
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
bindings@1.5.0:
|
||||
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
|
||||
|
||||
bl@4.1.0:
|
||||
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
|
||||
|
||||
@@ -3001,6 +3016,10 @@ packages:
|
||||
decode-named-character-reference@1.1.0:
|
||||
resolution: {integrity: sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==}
|
||||
|
||||
decompress-response@6.0.0:
|
||||
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
dedent@1.6.0:
|
||||
resolution: {integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==}
|
||||
peerDependencies:
|
||||
@@ -3013,6 +3032,10 @@ packages:
|
||||
resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
deep-extend@0.6.0:
|
||||
resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
deep-object-diff@1.1.9:
|
||||
resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==}
|
||||
|
||||
@@ -3061,6 +3084,10 @@ packages:
|
||||
engines: {node: '>=0.10'}
|
||||
hasBin: true
|
||||
|
||||
detect-libc@2.1.1:
|
||||
resolution: {integrity: sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
detect-node-es@1.1.0:
|
||||
resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
|
||||
|
||||
@@ -3261,6 +3288,10 @@ packages:
|
||||
resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
expand-template@2.0.3:
|
||||
resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
expect-type@1.2.1:
|
||||
resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
@@ -3333,6 +3364,9 @@ packages:
|
||||
resolution: {integrity: sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
file-uri-to-path@1.0.0:
|
||||
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
|
||||
|
||||
fill-range@7.1.1:
|
||||
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -3448,6 +3482,9 @@ packages:
|
||||
resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==}
|
||||
hasBin: true
|
||||
|
||||
github-from-package@0.0.0:
|
||||
resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
|
||||
|
||||
glob-parent@5.1.2:
|
||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||
engines: {node: '>= 6'}
|
||||
@@ -3628,6 +3665,9 @@ packages:
|
||||
inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
|
||||
ini@1.3.8:
|
||||
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
|
||||
|
||||
inline-style-parser@0.1.1:
|
||||
resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==}
|
||||
|
||||
@@ -4238,6 +4278,10 @@ packages:
|
||||
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
mimic-response@3.1.0:
|
||||
resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
min-indent@1.0.1:
|
||||
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -4337,6 +4381,9 @@ packages:
|
||||
resolution: {integrity: sha512-kNZ9xnoJYKg/AfxjrVL4SS0fKX++4awQReGqWnwTRHxeHGZ1FJFVgTqr/eMrNQdp0Tz7M7tG/TDaX8QfHDwVCw==}
|
||||
engines: {node: ^20.0.0 || >=22.0.0}
|
||||
|
||||
napi-build-utils@2.0.0:
|
||||
resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==}
|
||||
|
||||
negotiator@0.6.3:
|
||||
resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -4345,6 +4392,10 @@ packages:
|
||||
resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
node-abi@3.77.0:
|
||||
resolution: {integrity: sha512-DSmt0OEcLoK4i3NuscSbGjOf3bqiDEutejqENSplMSFA/gmB8mkED9G4pKWnPl7MDU4rSHebKPHeitpDfyH0cQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
node-addon-api@7.1.1:
|
||||
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
|
||||
|
||||
@@ -4686,6 +4737,11 @@ packages:
|
||||
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
prebuild-install@7.1.3:
|
||||
resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
prettier@2.8.8:
|
||||
resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
@@ -4807,6 +4863,10 @@ packages:
|
||||
rc9@2.1.2:
|
||||
resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
|
||||
|
||||
rc@1.2.8:
|
||||
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
|
||||
hasBin: true
|
||||
|
||||
react-chartjs-2@5.3.0:
|
||||
resolution: {integrity: sha512-UfZZFnDsERI3c3CZGxzvNJd02SHjaSJ8kgW1djn65H1KK8rehwTjyrRKOG3VTMG8wtHZ5rgAO5oTHtHi9GCCmw==}
|
||||
peerDependencies:
|
||||
@@ -5293,6 +5353,12 @@ packages:
|
||||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
simple-concat@1.0.1:
|
||||
resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
|
||||
|
||||
simple-get@4.0.1:
|
||||
resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
|
||||
|
||||
simple-swizzle@0.2.2:
|
||||
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
||||
|
||||
@@ -5407,6 +5473,10 @@ packages:
|
||||
resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-json-comments@2.0.1:
|
||||
resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
strip-literal@3.0.0:
|
||||
resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==}
|
||||
|
||||
@@ -5568,6 +5638,9 @@ packages:
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
tunnel-agent@0.6.0:
|
||||
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
|
||||
|
||||
turbo-stream@2.4.1:
|
||||
resolution: {integrity: sha512-v8kOJXpG3WoTN/+at8vK7erSzo6nW6CIaeOvNOkHQVDajfz1ZVeSxCbc6tOH4hrGZW7VUCV0TOXd8CPzYnYkrw==}
|
||||
|
||||
@@ -7136,6 +7209,11 @@ snapshots:
|
||||
|
||||
'@polka/url@1.0.0-next.29': {}
|
||||
|
||||
'@prisma/adapter-better-sqlite3@6.16.2':
|
||||
dependencies:
|
||||
'@prisma/driver-adapter-utils': 6.16.2
|
||||
better-sqlite3: 11.10.0
|
||||
|
||||
'@prisma/client@6.16.2(prisma@6.16.2(typescript@5.9.2))(typescript@5.9.2)':
|
||||
optionalDependencies:
|
||||
prisma: 6.16.2(typescript@5.9.2)
|
||||
@@ -7152,6 +7230,10 @@ snapshots:
|
||||
|
||||
'@prisma/debug@6.16.2': {}
|
||||
|
||||
'@prisma/driver-adapter-utils@6.16.2':
|
||||
dependencies:
|
||||
'@prisma/debug': 6.16.2
|
||||
|
||||
'@prisma/engines-version@6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43': {}
|
||||
|
||||
'@prisma/engines@6.16.2':
|
||||
@@ -8562,8 +8644,17 @@ snapshots:
|
||||
|
||||
before-after-hook@4.0.0: {}
|
||||
|
||||
better-sqlite3@11.10.0:
|
||||
dependencies:
|
||||
bindings: 1.5.0
|
||||
prebuild-install: 7.1.3
|
||||
|
||||
binary-extensions@2.3.0: {}
|
||||
|
||||
bindings@1.5.0:
|
||||
dependencies:
|
||||
file-uri-to-path: 1.0.0
|
||||
|
||||
bl@4.1.0:
|
||||
dependencies:
|
||||
buffer: 5.7.1
|
||||
@@ -9023,10 +9114,16 @@ snapshots:
|
||||
dependencies:
|
||||
character-entities: 2.0.2
|
||||
|
||||
decompress-response@6.0.0:
|
||||
dependencies:
|
||||
mimic-response: 3.1.0
|
||||
|
||||
dedent@1.6.0: {}
|
||||
|
||||
deep-eql@5.0.2: {}
|
||||
|
||||
deep-extend@0.6.0: {}
|
||||
|
||||
deep-object-diff@1.1.9: {}
|
||||
|
||||
deepmerge-ts@7.1.5: {}
|
||||
@@ -9063,6 +9160,8 @@ snapshots:
|
||||
detect-libc@1.0.3:
|
||||
optional: true
|
||||
|
||||
detect-libc@2.1.1: {}
|
||||
|
||||
detect-node-es@1.1.0: {}
|
||||
|
||||
devlop@1.1.0:
|
||||
@@ -9299,6 +9398,8 @@ snapshots:
|
||||
|
||||
exit-hook@2.2.1: {}
|
||||
|
||||
expand-template@2.0.3: {}
|
||||
|
||||
expect-type@1.2.1: {}
|
||||
|
||||
express-rate-limit@8.1.0(express@4.21.2):
|
||||
@@ -9404,6 +9505,8 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
file-uri-to-path@1.0.0: {}
|
||||
|
||||
fill-range@7.1.1:
|
||||
dependencies:
|
||||
to-regex-range: 5.0.1
|
||||
@@ -9522,6 +9625,8 @@ snapshots:
|
||||
nypm: 0.6.2
|
||||
pathe: 2.0.3
|
||||
|
||||
github-from-package@0.0.0: {}
|
||||
|
||||
glob-parent@5.1.2:
|
||||
dependencies:
|
||||
is-glob: 4.0.3
|
||||
@@ -9785,6 +9890,8 @@ snapshots:
|
||||
|
||||
inherits@2.0.4: {}
|
||||
|
||||
ini@1.3.8: {}
|
||||
|
||||
inline-style-parser@0.1.1: {}
|
||||
|
||||
inline-style-parser@0.2.4: {}
|
||||
@@ -10768,6 +10875,8 @@ snapshots:
|
||||
|
||||
mimic-fn@2.1.0: {}
|
||||
|
||||
mimic-response@3.1.0: {}
|
||||
|
||||
min-indent@1.0.1: {}
|
||||
|
||||
minimalistic-assert@1.0.1: {}
|
||||
@@ -10850,10 +10959,16 @@ snapshots:
|
||||
|
||||
nanostores@1.0.1: {}
|
||||
|
||||
napi-build-utils@2.0.0: {}
|
||||
|
||||
negotiator@0.6.3: {}
|
||||
|
||||
negotiator@0.6.4: {}
|
||||
|
||||
node-abi@3.77.0:
|
||||
dependencies:
|
||||
semver: 7.7.2
|
||||
|
||||
node-addon-api@7.1.1:
|
||||
optional: true
|
||||
|
||||
@@ -11201,6 +11316,21 @@ snapshots:
|
||||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
prebuild-install@7.1.3:
|
||||
dependencies:
|
||||
detect-libc: 2.1.1
|
||||
expand-template: 2.0.3
|
||||
github-from-package: 0.0.0
|
||||
minimist: 1.2.8
|
||||
mkdirp-classic: 0.5.3
|
||||
napi-build-utils: 2.0.0
|
||||
node-abi: 3.77.0
|
||||
pump: 3.0.2
|
||||
rc: 1.2.8
|
||||
simple-get: 4.0.1
|
||||
tar-fs: 2.1.4
|
||||
tunnel-agent: 0.6.0
|
||||
|
||||
prettier@2.8.8: {}
|
||||
|
||||
prettier@3.6.2: {}
|
||||
@@ -11327,6 +11457,13 @@ snapshots:
|
||||
defu: 6.1.4
|
||||
destr: 2.0.5
|
||||
|
||||
rc@1.2.8:
|
||||
dependencies:
|
||||
deep-extend: 0.6.0
|
||||
ini: 1.3.8
|
||||
minimist: 1.2.8
|
||||
strip-json-comments: 2.0.1
|
||||
|
||||
react-chartjs-2@5.3.0(chart.js@4.5.0)(react@18.3.1):
|
||||
dependencies:
|
||||
chart.js: 4.5.0
|
||||
@@ -11866,6 +12003,14 @@ snapshots:
|
||||
|
||||
signal-exit@4.1.0: {}
|
||||
|
||||
simple-concat@1.0.1: {}
|
||||
|
||||
simple-get@4.0.1:
|
||||
dependencies:
|
||||
decompress-response: 6.0.0
|
||||
once: 1.4.0
|
||||
simple-concat: 1.0.1
|
||||
|
||||
simple-swizzle@0.2.2:
|
||||
dependencies:
|
||||
is-arrayish: 0.3.2
|
||||
@@ -11974,6 +12119,8 @@ snapshots:
|
||||
dependencies:
|
||||
min-indent: 1.0.1
|
||||
|
||||
strip-json-comments@2.0.1: {}
|
||||
|
||||
strip-literal@3.0.0:
|
||||
dependencies:
|
||||
js-tokens: 9.0.1
|
||||
@@ -12131,6 +12278,10 @@ snapshots:
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
tunnel-agent@0.6.0:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
turbo-stream@2.4.1: {}
|
||||
|
||||
type-fest@4.41.0: {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "ChatUsage" (
|
||||
"id" TEXT NOT NULL,
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"userId" TEXT NOT NULL,
|
||||
"chatId" TEXT NOT NULL,
|
||||
"messageId" TEXT NOT NULL,
|
||||
@@ -9,35 +9,31 @@ CREATE TABLE "ChatUsage" (
|
||||
"cachedTokens" INTEGER NOT NULL DEFAULT 0,
|
||||
"reasoningTokens" INTEGER NOT NULL DEFAULT 0,
|
||||
"totalTokens" INTEGER NOT NULL DEFAULT 0,
|
||||
"calledAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"calledAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"status" TEXT NOT NULL,
|
||||
"modelName" TEXT,
|
||||
"prompt" TEXT,
|
||||
"metadata" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ChatUsage_pkey" PRIMARY KEY ("id")
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Chat" (
|
||||
"id" TEXT NOT NULL,
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"urlId" TEXT,
|
||||
"userId" TEXT NOT NULL,
|
||||
"description" TEXT,
|
||||
"timestamp" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"timestamp" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"version" INTEGER NOT NULL DEFAULT 1,
|
||||
"metadata" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Chat_pkey" PRIMARY KEY ("id")
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Message" (
|
||||
"id" TEXT NOT NULL,
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"chatId" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"role" TEXT NOT NULL,
|
||||
@@ -48,26 +44,24 @@ CREATE TABLE "Message" (
|
||||
"metadata" JSONB,
|
||||
"parts" JSONB,
|
||||
"version" INTEGER NOT NULL DEFAULT 1,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Message_pkey" PRIMARY KEY ("id")
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "Message_chatId_fkey" FOREIGN KEY ("chatId") REFERENCES "Chat" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Page" (
|
||||
"id" TEXT NOT NULL,
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"messageId" TEXT NOT NULL,
|
||||
"pages" JSONB NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Page_pkey" PRIMARY KEY ("id")
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "Page_messageId_fkey" FOREIGN KEY ("messageId") REFERENCES "Message" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Section" (
|
||||
"id" TEXT NOT NULL,
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"messageId" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL DEFAULT 'section',
|
||||
"action" TEXT NOT NULL DEFAULT 'add',
|
||||
@@ -77,15 +71,14 @@ CREATE TABLE "Section" (
|
||||
"domId" TEXT NOT NULL,
|
||||
"rootDomId" TEXT,
|
||||
"sort" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Section_pkey" PRIMARY KEY ("id")
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "Section_messageId_fkey" FOREIGN KEY ("messageId") REFERENCES "Message" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Deployment" (
|
||||
"id" TEXT NOT NULL,
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"userId" TEXT NOT NULL,
|
||||
"chatId" TEXT NOT NULL,
|
||||
"platform" TEXT NOT NULL,
|
||||
@@ -93,24 +86,21 @@ CREATE TABLE "Deployment" (
|
||||
"url" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL,
|
||||
"metadata" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Deployment_pkey" PRIMARY KEY ("id")
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "Deployment_chatId_fkey" FOREIGN KEY ("chatId") REFERENCES "Chat" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "UserSetting" (
|
||||
"id" TEXT NOT NULL,
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"userId" TEXT NOT NULL,
|
||||
"category" TEXT NOT NULL,
|
||||
"key" TEXT NOT NULL,
|
||||
"value" TEXT NOT NULL,
|
||||
"isSecret" BOOLEAN NOT NULL DEFAULT false,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "UserSetting_pkey" PRIMARY KEY ("id")
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
@@ -187,15 +177,3 @@ CREATE INDEX "UserSetting_isSecret_idx" ON "UserSetting"("isSecret");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "UserSetting_userId_category_key_key" ON "UserSetting"("userId", "category", "key");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Message" ADD CONSTRAINT "Message_chatId_fkey" FOREIGN KEY ("chatId") REFERENCES "Chat"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Page" ADD CONSTRAINT "Page_messageId_fkey" FOREIGN KEY ("messageId") REFERENCES "Message"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Section" ADD CONSTRAINT "Section_messageId_fkey" FOREIGN KEY ("messageId") REFERENCES "Message"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Deployment" ADD CONSTRAINT "Deployment_chatId_fkey" FOREIGN KEY ("chatId") REFERENCES "Chat"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -1,3 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "postgresql"
|
||||
provider = "sqlite"
|
||||
|
||||
@@ -3,8 +3,8 @@ generator client {
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
provider = "sqlite"
|
||||
url = "file:../data/upage.db"
|
||||
}
|
||||
|
||||
// 聊天使用记录,每个 message 对应多条。
|
||||
@@ -87,7 +87,7 @@ model Message {
|
||||
// 'user' 或 'assistant'
|
||||
role String
|
||||
// 消息内容
|
||||
content String @db.Text
|
||||
content String
|
||||
// 版本 ID
|
||||
revisionId String?
|
||||
// 注释
|
||||
@@ -147,7 +147,7 @@ model Section {
|
||||
// 页面名称
|
||||
pageName String @default("")
|
||||
// Section 内容 (HTML/CSS)
|
||||
content String @db.Text
|
||||
content String
|
||||
// DOM ID
|
||||
domId String
|
||||
// 根 DOM ID,用于标识父级容器
|
||||
@@ -209,7 +209,7 @@ model UserSetting {
|
||||
// 设置键名
|
||||
key String
|
||||
// 设置值
|
||||
value String @db.Text
|
||||
value String
|
||||
// 是否为敏感信息(如 API 密钥)
|
||||
isSecret Boolean @default(false)
|
||||
// 创建时间
|
||||
|
||||
Reference in New Issue
Block a user