Compare commits
34
Commits
f83deefa47
...
a1c267b0d4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1c267b0d4 | ||
|
|
836035f4cd | ||
|
|
b29be62747 | ||
|
|
a9dc632986 | ||
|
|
cc2677ce06 | ||
|
|
71dcf7e1b1 | ||
|
|
30bc489b5c | ||
|
|
4b19d1d929 | ||
|
|
921f3496ea | ||
|
|
7234b4b40a | ||
|
|
eef296942f | ||
|
|
e689e44923 | ||
|
|
fc23919a4e | ||
|
|
f34c8c3bae | ||
|
|
9f16db4286 | ||
|
|
fd029ad124 | ||
|
|
e963140bf9 | ||
|
|
533a05832e | ||
|
|
086f7aecf9 | ||
|
|
1edf57b75d | ||
|
|
4ce701e99a | ||
|
|
8813766aff | ||
|
|
aca8a05c0f | ||
|
|
9caaa303e5 | ||
|
|
a714013e3e | ||
|
|
1a695920ce | ||
|
|
025fcc3244 | ||
|
|
636e566657 | ||
|
|
040d560aff | ||
|
|
a4af607c41 | ||
|
|
a386660833 | ||
|
|
034c87f955 | ||
|
|
a4ab22588c | ||
|
|
61d3028909 |
@@ -9,3 +9,4 @@ src-tauri
|
||||
docs
|
||||
*.log
|
||||
readme
|
||||
deploy
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
# Windows 外壳构建模式 (npm run build:shell / vite build --mode shell)
|
||||
# 外壳内前端跑在 tauri://localhost, 没有同源后端, API 必须指向远端 Express。
|
||||
# 与 android 打包脚本 (scripts/wsl/build-apk.sh) 注入的值保持一致;
|
||||
# 进程环境变量优先级高于本文件, android 流程不受影响。
|
||||
#
|
||||
# 0.2.1 起正式域名: https://iboard.honor3.com (NPM 反代 -> baihu:3001, 受信证书)
|
||||
# PowerSync 同步端点默认同域 (NPM 把 /sync 反代到同步服务); 若改用独立子域,
|
||||
# 打包时用 VITE_POWERSYNC_URL=https://sync.example.com 覆盖即可。
|
||||
VITE_API_BASE=https://iboard.honor3.com
|
||||
VITE_POWERSYNC_URL=https://iboard.honor3.com
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
env:
|
||||
# 固定工具链版本, 便于 actions/cache 命中
|
||||
# Android 后端地址 (bake 进 APK); 与 scripts/wsl/build-apk.sh 保持一致
|
||||
VITE_API_BASE: http://bh.vps.honor3.com:3001
|
||||
VITE_API_BASE: https://iboard.honor3.com
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
# 关键: 显式固定 Android/OTA 后端地址, 覆盖 runner 环境里可能存在的
|
||||
# 其他 VITE_API_BASE 值。否则 OTA 包里的前端可能连错后端, 导致
|
||||
# "OTA 更新后登录失败/进不去内部"。与 android-build.yml 保持一致。
|
||||
VITE_API_BASE: http://bh.vps.honor3.com:3001
|
||||
VITE_API_BASE: https://iboard.honor3.com
|
||||
# OTA bundle 要求的最低原生二进制版本。
|
||||
# 与 package.json 的应用版本是**两个概念**: 前端 OTA 不碰原生层,
|
||||
# 现有 APK 仍是 0.1.0, 所以这里固定 0.1.0 (否则旧 APK 会被判定为不兼容而收不到更新)。
|
||||
@@ -112,38 +112,39 @@ jobs:
|
||||
- name: List images
|
||||
run: docker images
|
||||
|
||||
- name: Apply DB migrations
|
||||
# 数据库自动升级: 按 prisma/migrations/ 下的迁移顺序应用 (生产库由 master 部署时统一升级)
|
||||
# migrate deploy 幂等, 无新迁移时为 no-op
|
||||
# 位置关键: 在 "Remove old container" 之前 —— 建表/改表成功后才切换流量,
|
||||
# 迁移失败则整个 workflow 中断, 不会用新镜像顶掉仍在运行的旧容器
|
||||
env:
|
||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npx prisma migrate status || true
|
||||
npx prisma migrate deploy
|
||||
|
||||
- name: Remove old container
|
||||
run: docker rm -vf iboard || true
|
||||
|
||||
- name: Prune dangling images
|
||||
# 只清理本项目的悬空镜像 (旧 iboard:latest 被同名新镜像顶掉后变 dangling),
|
||||
# 不再用 `docker system prune --volumes` —— 那会清光宿主机 build cache,
|
||||
# 导致每次部署都全量重装 npm 依赖、重跑构建
|
||||
run: docker image prune -f
|
||||
|
||||
- name: Run container
|
||||
# DATABASE_URL 通过 gitea Actions secret 注入, 不进镜像层
|
||||
# OTA_PACKAGE_DIR 已在 Dockerfile 设为 /app/ota-package
|
||||
# 米家凭证 (auth.txt) 不进 git: 运维放宿主机 /app/iboard/cache, bind-mount 进容器 (MIHOME_CACHE_DIR=/app/cache)
|
||||
run: |
|
||||
docker run -d --name iboard -p 3001:3001 \
|
||||
-e DATABASE_URL="${{ secrets.DATABASE_URL }}" \
|
||||
-e JWT_SECRET="${{ secrets.JWT_SECRET }}" \
|
||||
-e MIHOME_CACHE_DIR=/app/cache \
|
||||
-v /app/iboard/cache:/app/cache \
|
||||
iboard:latest
|
||||
env:
|
||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||
JWT_SECRET: ${{ secrets.JWT_SECRET }}
|
||||
- name: Deploy 0.2.1 production stack
|
||||
# 0.2.1 起生产为单端口架构: app(3001 对外) + pg(内网) + powersync(内网),
|
||||
# 客户端同步经 app 的 /sync 反代进入同步服务 (无独立同步端口)。
|
||||
# 部署逻辑在服务器的 /app/iboard-prod/scripts/deploy/prod.sh (幂等), 这里只负责:
|
||||
# 1) 把刚构建好的镜像交给该脚本
|
||||
# 2) 未配置 PG 相关 secrets 或脚本缺失时跳过部署 (发布不失败, 仅提示)
|
||||
env:
|
||||
PG_PASSWORD: ${{ secrets.PG_PASSWORD }}
|
||||
PS_STORAGE_PASSWORD: ${{ secrets.PS_STORAGE_PASSWORD }}
|
||||
JWT_SECRET: ${{ secrets.JWT_SECRET }}
|
||||
POWERSYNC_JWT_SECRET: ${{ secrets.POWERSYNC_JWT_SECRET }}
|
||||
POWERSYNC_JWT_KEY_B64: ${{ secrets.POWERSYNC_JWT_KEY_B64 }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
HOST_DIR=/app/iboard-prod
|
||||
if [ -z "${PG_PASSWORD:-}" ]; then
|
||||
echo "::warning::未配置 PG_PASSWORD 等 secrets, 跳过自动部署 (镜像已构建完成)"
|
||||
echo "手工部署: ssh baihu 'bash $HOST_DIR/scripts/deploy/prod.sh'"
|
||||
exit 0
|
||||
fi
|
||||
if ! docker run --rm -v "$HOST_DIR:/w" alpine:3.20 test -f /w/scripts/deploy/prod.sh; then
|
||||
echo "::warning::$HOST_DIR/scripts/deploy/prod.sh 不存在, 跳过部署"
|
||||
exit 0
|
||||
fi
|
||||
docker run --rm \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v "$HOST_DIR:$HOST_DIR" \
|
||||
-w "$HOST_DIR" \
|
||||
-e PG_PASSWORD="$PG_PASSWORD" \
|
||||
-e PS_STORAGE_PASSWORD="$PS_STORAGE_PASSWORD" \
|
||||
-e JWT_SECRET="$JWT_SECRET" \
|
||||
-e POWERSYNC_JWT_SECRET="$POWERSYNC_JWT_SECRET" \
|
||||
-e POWERSYNC_JWT_KEY_B64="$POWERSYNC_JWT_KEY_B64" \
|
||||
-e PUBLIC_URL=https://iboard.honor3.com \
|
||||
-e ROOT="$HOST_DIR" \
|
||||
docker:27-cli sh -c 'apk add -q bash curl >/dev/null 2>&1; bash /app/iboard-prod/scripts/deploy/prod.sh'
|
||||
|
||||
+22
@@ -50,3 +50,25 @@ server/mihome/.cache/
|
||||
|
||||
# 鏈�湴 pnpm 瀹夎�浜х墿 (椤圭洰浣跨敤 package-lock.json)
|
||||
/.pnpm-store
|
||||
|
||||
# 0.2.1 楠岃瘉閮ㄧ讲: 鏈嶅姟鍣ㄦ湰鍦版暟鎹�嵎涓庡瘑閽� (缁濅笉鍏ュ簱)
|
||||
deploy/0.2.1/data/
|
||||
deploy/0.2.1/.env
|
||||
|
||||
# 构建/工具临时目录 (local)
|
||||
.esbuild-tmp/
|
||||
|
||||
|
||||
# Windows 打包产物 (本地生成, 不入库)
|
||||
/artifacts/
|
||||
|
||||
|
||||
# 生产部署密钥与数据卷
|
||||
/deploy/prod/.env
|
||||
/deploy/prod/data/
|
||||
|
||||
|
||||
# 本地临时脚本 (含口令, 不入库)
|
||||
scripts/_*.mjs
|
||||
.dsh-ops/
|
||||
|
||||
|
||||
+5
-5
@@ -50,9 +50,9 @@ WORKDIR /app
|
||||
# 阿里源加速
|
||||
RUN npm config set registry https://registry.npmmirror.com
|
||||
|
||||
# 只装运行时依赖
|
||||
# 只装运行时依赖 (better-sqlite3 是 @powersync/node 的 devOptional peer, 需同时 omit optional 才能跳过)
|
||||
COPY package*.json ./
|
||||
RUN --mount=type=cache,target=/root/.npm npm ci --omit=dev
|
||||
RUN --mount=type=cache,target=/root/.npm npm ci --omit=dev --omit=optional
|
||||
|
||||
# 拷贝构建产物
|
||||
COPY --from=builder /app/dist ./dist
|
||||
@@ -70,11 +70,11 @@ COPY ota-package ./ota-package
|
||||
ENV OTA_PACKAGE_DIR=/app/ota-package
|
||||
# OTA bundle 下载用的绝对 base (manifest.url 必须是绝对 URL, 插件不拼 base, 相对路径会导致下载 0% 失败)
|
||||
# 生产为 http 明文 (无 https), 客户端 tauri.conf.json 的 hotswap.require_https 已设为 false 放行 http
|
||||
ENV OTA_PUBLIC_BASE=http://bh.vps.honor3.com:3001
|
||||
ENV OTA_PUBLIC_BASE=https://iboard.honor3.com
|
||||
|
||||
# 健康检查
|
||||
# 健康检查 (端口跟随 PORT 环境变量, 0.2.1 部署为 13001)
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD wget -qO- http://127.0.0.1:3001/api/health || exit 1
|
||||
CMD wget -qO- http://127.0.0.1:${PORT:-3001}/api/health || exit 1
|
||||
|
||||
EXPOSE 3001
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# 复制为 .env (服务器上 chmod 600, 已 gitignore)。
|
||||
# POWERSYNC_JWT_KEY_B64 = base64url(POWERSYNC_JWT_SECRET 的 UTF-8 字节)
|
||||
# 生成: printf %s "$POWERSYNC_JWT_SECRET" | openssl base64 -A | tr '+/' '-_' | tr -d '='
|
||||
|
||||
PG_PASSWORD=change-me
|
||||
PS_STORAGE_PASSWORD=change-me
|
||||
JWT_SECRET_021=change-me
|
||||
POWERSYNC_JWT_SECRET=change-me
|
||||
POWERSYNC_JWT_KEY_B64=change-me
|
||||
POWERSYNC_URL=https://bh.vps.honor3.com:13443
|
||||
OTA_PUBLIC_BASE=http://bh.vps.honor3.com:13001
|
||||
@@ -0,0 +1,61 @@
|
||||
# 0.2.1 独立验证部署 (baihu /app/iboard-0.2.1)
|
||||
|
||||
与现网 `/app/iboard`(3001/宿主 MySQL) 完全隔离:本栈使用独立 PG 容器、端口 13443/13001/13002,不写原库。
|
||||
|
||||
**浏览器入口: `https://bh.vps.honor3.com:13443`**(自签证书,首次访问需在浏览器"高级→继续访问"接受一次;PowerSync 网页端必须运行在安全上下文,http://13001 入口仅供接口调试,任务模块会报 Navigator locks 错误)。
|
||||
正式启用需替换受信证书:把 `bh.pem/bh.key` 换成受信证书后 `docker compose restart tls-front`(例如 Let's Encrypt DNS-01,80/443 已被 gateway 占用无法 HTTP-01)。
|
||||
|
||||
## 栈
|
||||
|
||||
| 服务 | 说明 |
|
||||
| --- | --- |
|
||||
| `pg` | postgres:16-alpine,`wal_level=logical`(供 PowerSync 逻辑复制),数据在 `./data/pg`,**不对外暴露端口** |
|
||||
| `app` | 本仓库 Dockerfile 构建,13001 对外;启动时先 `prisma migrate deploy`;`DISABLE_CRON=1` 关闭定时任务 |
|
||||
| `powersync` | journeyapps/powersync-service,13002 对外;源库=pg,bucket storage=同实例 PG 的 powersync schema |
|
||||
|
||||
## 首次部署
|
||||
|
||||
```bash
|
||||
# 服务器上 (源码已上传到 /app/iboard-0.2.1)
|
||||
cd /app/iboard-0.2.1/deploy/0.2.1
|
||||
|
||||
# 1. 生成 .env (参照 .env.example; POWERSYNC_JWT_KEY_B64 由 secret 派生)
|
||||
umask 077
|
||||
PG_PASSWORD=$(openssl rand -hex 16)
|
||||
PS_STORAGE_PASSWORD=$(openssl rand -hex 16)
|
||||
JWT_SECRET_021=$(openssl rand -hex 32)
|
||||
POWERSYNC_JWT_SECRET=$(openssl rand -hex 32)
|
||||
POWERSYNC_JWT_KEY_B64=$(printf %s "$POWERSYNC_JWT_SECRET" | openssl base64 -A | tr '+/' '-_' | tr -d '=')
|
||||
cat > .env <<EOF
|
||||
PG_PASSWORD=$PG_PASSWORD
|
||||
PS_STORAGE_PASSWORD=$PS_STORAGE_PASSWORD
|
||||
JWT_SECRET_021=$JWT_SECRET_021
|
||||
POWERSYNC_JWT_SECRET=$POWERSYNC_JWT_SECRET
|
||||
POWERSYNC_JWT_KEY_B64=$POWERSYNC_JWT_KEY_B64
|
||||
POWERSYNC_URL=http://bh.vps.honor3.com:13002
|
||||
OTA_PUBLIC_BASE=http://bh.vps.honor3.com:13001
|
||||
EOF
|
||||
|
||||
# 2. 构建并启动
|
||||
docker compose build app
|
||||
docker compose up -d
|
||||
|
||||
# 3. 验证
|
||||
docker compose ps
|
||||
curl -s http://127.0.0.1:13001/api/health
|
||||
docker compose logs powersync --tail 50 # 应看到连接源库/建 publication/sync config 部署成功
|
||||
```
|
||||
|
||||
## 日常更新
|
||||
|
||||
```bash
|
||||
cd /app/iboard-0.2.1
|
||||
git archive 方式重新上传源码 tar 后解包覆盖 (data/.env 不受影响)
|
||||
cd deploy/0.2.1 && docker compose build app && docker compose up -d app
|
||||
```
|
||||
|
||||
## 注意
|
||||
|
||||
- `./data/pg` 为 0.2.1 独立数据卷;`./.env` 为密钥,两者均已 gitignore,更新源码时不会覆盖 `.env`(tar 解包不产生它)。
|
||||
- PowerSync 的 publication / replication slot 由 service 自动管理(账号 iboard021 为容器内 superuser)。
|
||||
- 同步规则改动:编辑 `powersync/sync-config.yaml` 后 `docker compose restart powersync`。
|
||||
@@ -0,0 +1,84 @@
|
||||
name: iboard-021
|
||||
|
||||
# 0.2.1 独立验证栈: PG (逻辑复制) + PowerSync + App, 与现网 /app/iboard 完全隔离
|
||||
# 见 docs/V0.2/离线编辑模块/0.2.1实施方案.md; 端口 13001 (app) / 13002 (powersync), PG 不对外
|
||||
|
||||
services:
|
||||
pg:
|
||||
image: postgres:16-alpine
|
||||
restart: unless-stopped
|
||||
command: ["postgres", "-c", "wal_level=logical"]
|
||||
environment:
|
||||
POSTGRES_USER: iboard021
|
||||
POSTGRES_PASSWORD: ${PG_PASSWORD:?PG_PASSWORD missing}
|
||||
POSTGRES_DB: iboard021
|
||||
# initdb 脚本用: 创建 powersync bucket storage 用户
|
||||
PS_STORAGE_PASSWORD: ${PS_STORAGE_PASSWORD:?PS_STORAGE_PASSWORD missing}
|
||||
volumes:
|
||||
- ./data/pg:/var/lib/postgresql/data
|
||||
- ./initdb:/docker-entrypoint-initdb.d:ro
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U iboard021 -d iboard021"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
|
||||
app:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: Dockerfile
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
pg:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
DATABASE_URL: postgresql://iboard021:${PG_PASSWORD}@pg:5432/iboard021
|
||||
PORT: "13001"
|
||||
JWT_SECRET: ${JWT_SECRET_021:?JWT_SECRET_021 missing}
|
||||
POWERSYNC_JWT_SECRET: ${POWERSYNC_JWT_SECRET:?POWERSYNC_JWT_SECRET missing}
|
||||
POWERSYNC_URL: ${POWERSYNC_URL:-http://bh.vps.honor3.com:13002}
|
||||
OTA_PUBLIC_BASE: ${OTA_PUBLIC_BASE:-http://bh.vps.honor3.com:13001}
|
||||
# 0.2.1 验证部署关闭定时任务 (新闻/油价/米家等), 避免重复外呼
|
||||
DISABLE_CRON: "1"
|
||||
command: ["sh", "-c", "npx prisma migrate deploy && node --experimental-strip-types --no-warnings server/index.js"]
|
||||
ports:
|
||||
- "13001:13001"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:13001/api/health || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 20s
|
||||
|
||||
# TLS 前置 (自签证书): PowerSync 网页端必须在安全上下文运行 (navigator.locks),
|
||||
# 因此浏览器入口统一走 https://bh.vps.honor3.com:13443 (证书接受一次即可, app+sync 同源同证书)
|
||||
tls-front:
|
||||
image: nginx:alpine
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- app
|
||||
- powersync
|
||||
volumes:
|
||||
- ./tls/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
- ./data/tls:/etc/nginx/certs:ro
|
||||
ports:
|
||||
- "13443:443"
|
||||
|
||||
powersync:
|
||||
image: journeyapps/powersync-service:latest
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
pg:
|
||||
condition: service_healthy
|
||||
command: ["start", "-r", "unified"]
|
||||
volumes:
|
||||
- ./powersync/service.yaml:/config/service.yaml:ro
|
||||
- ./powersync/sync-config.yaml:/config/sync-config.yaml:ro
|
||||
environment:
|
||||
POWERSYNC_CONFIG_PATH: /config/service.yaml
|
||||
# service.yaml 内 !env PS_* 引用 (整值替换; URI 在此组装)
|
||||
PS_SOURCE_URI: postgresql://iboard021:${PG_PASSWORD}@pg:5432/iboard021?sslmode=disable
|
||||
PS_STORAGE_URI: postgresql://powersync_storage:${PS_STORAGE_PASSWORD}@pg:5432/iboard021?sslmode=disable
|
||||
PS_JWT_KEY_B64: ${POWERSYNC_JWT_KEY_B64:?POWERSYNC_JWT_KEY_B64 missing}
|
||||
ports:
|
||||
- "13002:8080"
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
# 一次性 ETL: 清空 0.2.1 库 -> 从现网 MariaDB 只读快照导入
|
||||
# 现网连接串从 iboard 容器环境变量读取 (不回显), 源库仅 SELECT
|
||||
set -e
|
||||
cd /app/iboard-0.2.1/deploy/0.2.1
|
||||
SRC=$(docker inspect iboard --format '{{range .Config.Env}}{{println .}}{{end}}' | grep '^DATABASE_URL=' | cut -d= -f2-)
|
||||
[ -n "$SRC" ] || { echo '未取到现网 DATABASE_URL'; exit 1; }
|
||||
|
||||
echo '--- truncate 0.2.1 库 ---'
|
||||
docker compose exec -T pg psql -U iboard021 -d iboard021 -c "TRUNCATE TABLE \"User\",\"Project\",\"ProjectMember\",\"BoardColumn\",\"Task\",\"TaskMember\",\"TaskTag\",\"Habit\",\"CheckIn\",\"CheckList\",\"CheckListItem\",\"CheckListTemplate\",\"Article\",\"Strategy\",\"Indicator\",\"IndicatorPoint\",\"News\",\"Alert\",\"ServerNode\",\"ServerNodeHistory\",\"ServiceCheck\",\"Econ_SowInventory\",\"ScraperCache\",\"OilPriceHistory\",\"MihomeAccount\",\"MihomeHome\",\"MihomeDevice\",\"MihomeEnvSample\",\"MihomeEnvHour\" RESTART IDENTITY CASCADE;"
|
||||
|
||||
echo '--- etl run ---'
|
||||
docker compose exec -T -e SRC_DATABASE_URL="$SRC" app node scripts/etl-mariadb-to-pg.mjs
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
# 一次性初始化 (仅首次建库时执行): 创建 powersync bucket storage 专用用户
|
||||
# PG >= 14 允许源库与 bucket storage 同实例 (powersync schema 由 service 自建)
|
||||
set -e
|
||||
: "${PS_STORAGE_PASSWORD:?PS_STORAGE_PASSWORD missing}"
|
||||
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
||||
DO \$\$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'powersync_storage') THEN
|
||||
CREATE USER powersync_storage WITH PASSWORD '$PS_STORAGE_PASSWORD';
|
||||
END IF;
|
||||
END
|
||||
\$\$;
|
||||
GRANT CREATE ON DATABASE $POSTGRES_DB TO powersync_storage;
|
||||
EOSQL
|
||||
|
||||
echo "[initdb] powersync_storage user ready."
|
||||
@@ -0,0 +1,10 @@
|
||||
-- 一次性初始化: PowerSync 逻辑复制所需 publication (服务不自建, 见 PSYNC_S1141)
|
||||
-- 仅发布任务域 + User; 新增同步表时需 ALTER PUBLICATION powersync ADD TABLE ...
|
||||
CREATE PUBLICATION powersync FOR TABLE
|
||||
"Project",
|
||||
"ProjectMember",
|
||||
"BoardColumn",
|
||||
"Task",
|
||||
"TaskMember",
|
||||
"TaskTag",
|
||||
"User";
|
||||
@@ -0,0 +1,41 @@
|
||||
# PowerSync Service 主配置 (0.2.1 验证部署)
|
||||
# 参考: https://docs.powersync.com/configuration/powersync-service/self-hosted-instances
|
||||
# 注意: !env 是 YAML 整值标签, 只能整个值替换变量, 不能内嵌在 URI 字符串中;
|
||||
# 完整连接串由 docker-compose 以 PS_* 环境变量注入。
|
||||
|
||||
replication:
|
||||
connections:
|
||||
- type: postgresql
|
||||
# 源库: 本栈 pg 容器 (0.2.1 独立实例), 复制走 iboard021 账号
|
||||
uri: !env PS_SOURCE_URI
|
||||
sslmode: disable
|
||||
|
||||
# bucket storage: 同实例 PG (16 >= 14 允许同库不同 schema, service 自建 powersync schema)
|
||||
storage:
|
||||
type: postgresql
|
||||
uri: !env PS_STORAGE_URI
|
||||
sslmode: disable
|
||||
|
||||
port: 8080
|
||||
|
||||
sync_config:
|
||||
path: /config/sync-config.yaml
|
||||
|
||||
# 客户端鉴权: app 后端 /api/powersync/token 签发 HS256 JWT (aud=powersync)
|
||||
# oct 密钥 k = base64url(POWERSYNC_JWT_SECRET)
|
||||
client_auth:
|
||||
jwks:
|
||||
keys:
|
||||
- kty: oct
|
||||
k: !env PS_JWT_KEY_B64
|
||||
alg: HS256
|
||||
audience:
|
||||
- powersync
|
||||
|
||||
telemetry:
|
||||
disable_telemetry_sharing: true
|
||||
|
||||
system:
|
||||
logging:
|
||||
level: info
|
||||
format: text
|
||||
@@ -0,0 +1,25 @@
|
||||
# Sync Streams (edition 3): 任务模块 6 表 + User (展示用)
|
||||
# Sequential ID Mapping (见 docs/V0.2/离线编辑模块/0.2.1实施方案.md §3):
|
||||
# - 客户端主键 = uuid 列 (离线新建行同步回填后 id 稳定); int 自增 id 不下发
|
||||
# - 外键输出 uuid 镜像列, 别名回 projectId/columnId/parentId/taskId (客户端字段名不变)
|
||||
# - 引号保留 PG PascalCase 标识; 可见性按 ProjectMember 过滤
|
||||
|
||||
config:
|
||||
edition: 3
|
||||
|
||||
streams:
|
||||
iboard_users:
|
||||
auto_subscribe: true
|
||||
query: SELECT CAST("id" AS TEXT) AS "id", "name", "email" FROM "User"
|
||||
|
||||
iboard_task_data:
|
||||
auto_subscribe: true
|
||||
with:
|
||||
my_projects: SELECT "projectId" FROM "ProjectMember" WHERE CAST("userId" AS TEXT) = auth.user_id()
|
||||
queries:
|
||||
- SELECT "uuid" AS "id", "uuid", "code", "name", CAST("ownerId" AS TEXT) AS "ownerId", "isPersonal", "archived", "notes", "taskKinds", "icon", "autoArchive", "createdAt", "updatedAt" FROM "Project" WHERE "id" IN my_projects
|
||||
- SELECT "uuid" AS "id", "uuid", "projectUuid" AS "projectId", CAST("userId" AS TEXT) AS "userId", "permission", "createdAt" FROM "ProjectMember" WHERE "projectId" IN my_projects
|
||||
- SELECT "uuid" AS "id", "uuid", "projectUuid" AS "projectId", "name", "sortOrder", "boundStatus", "retention", "createdAt", "updatedAt" FROM "BoardColumn" WHERE "projectId" IN my_projects
|
||||
- SELECT "uuid" AS "id", "uuid", "projectUuid" AS "projectId", "columnUuid" AS "columnId", "parentUuid" AS "parentId", "title", "description", "kind", "markDate", "status", "doneAt", CAST("assigneeId" AS TEXT) AS "assigneeId", CAST("creatorId" AS TEXT) AS "creatorId", "extras", "sortOrder", "number", "archived", "archivedAt", "archiveSource", "createdAt", "updatedAt" FROM "Task" WHERE "projectId" IN my_projects
|
||||
- SELECT "uuid" AS "id", "uuid", "taskUuid" AS "taskId", CAST("userId" AS TEXT) AS "userId" FROM "TaskMember" WHERE "taskId" IN (SELECT "id" FROM "Task" WHERE "projectId" IN my_projects)
|
||||
- SELECT "uuid" AS "id", "uuid", "taskUuid" AS "taskId", "name" FROM "TaskTag" WHERE "taskId" IN (SELECT "id" FROM "Task" WHERE "projectId" IN my_projects)
|
||||
@@ -0,0 +1,37 @@
|
||||
# 0.2.1 TLS 前置: 单端口 13443, 按路径分流 (自签证书, 见 README)
|
||||
# PowerSync 页面必须在安全上下文运行 (navigator.locks 仅 HTTPS/localhost), 故 app 与 sync 统一走 TLS
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name bh.vps.honor3.com;
|
||||
|
||||
ssl_certificate /etc/nginx/certs/bh.pem;
|
||||
ssl_certificate_key /etc/nginx/certs/bh.key;
|
||||
|
||||
# PowerSync (HTTP 流式 + WebSocket 兜底)
|
||||
location /sync/ {
|
||||
proxy_pass http://powersync:8080;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection '';
|
||||
proxy_buffering off;
|
||||
proxy_read_timeout 3600s;
|
||||
}
|
||||
location /socket/ {
|
||||
proxy_pass http://powersync:8080;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 3600s;
|
||||
}
|
||||
location /health {
|
||||
proxy_pass http://powersync:8080;
|
||||
}
|
||||
|
||||
# 应用 (静态前端 + API)
|
||||
location / {
|
||||
proxy_pass http://app:13001;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# 生产环境变量 (deploy/prod/.env, 权限 600, 绝不入库)
|
||||
# POWERSYNC_JWT_KEY_B64 = base64url(POWERSYNC_JWT_SECRET 的 UTF-8 字节)
|
||||
# printf %s "$POWERSYNC_JWT_SECRET" | openssl base64 -A | tr '+/' '-_' | tr -d '='
|
||||
PG_PASSWORD=change-me
|
||||
PS_STORAGE_PASSWORD=change-me
|
||||
JWT_SECRET=change-me
|
||||
POWERSYNC_JWT_SECRET=change-me
|
||||
POWERSYNC_JWT_KEY_B64=change-me
|
||||
PUBLIC_URL=https://iboard.honor3.com
|
||||
@@ -0,0 +1,59 @@
|
||||
# iBoard 0.2.1 生产部署 (单端口, 无独立同步端口)
|
||||
|
||||
```
|
||||
pg (内网) ← app (3001 对外, /sync 反代) → powersync (内网)
|
||||
```
|
||||
|
||||
对外只有 **3001** 一个端口,域名 `https://iboard.honor3.com` 由 NPM 反代到这里;
|
||||
同步服务不再单独暴露端口(客户端拿到的 `POWERSYNC_URL` 是域名本身,请求经 app 的
|
||||
`/sync`、`/socket` 反代进入内网 powersync)。
|
||||
|
||||
## 首次部署顺序 (关键: publication 要在建表之后)
|
||||
|
||||
```bash
|
||||
# 0) 目录: /app/iboard-prod (源码已上传), 镜像 iboard:latest 已构建
|
||||
cd /app/iboard-prod/deploy/prod
|
||||
cp .env.example .env && chmod 600 .env # 填真实密钥
|
||||
mkdir -p data/pg data/cache
|
||||
|
||||
# 1) 先只起数据库
|
||||
docker compose --env-file .env up -d pg
|
||||
|
||||
# 2) 跑迁移建表 (一次性)
|
||||
docker run --rm --network iboard-prod_default \
|
||||
-e DATABASE_URL="postgresql://iboard:<PG_PASSWORD>@pg:5432/iboard" \
|
||||
iboard:latest npx prisma migrate deploy
|
||||
|
||||
# 3) 建逻辑复制 publication (表已存在)
|
||||
docker compose --env-file .env exec -T pg \
|
||||
psql -U iboard -d iboard -f /dev/stdin < sql/publication.sql
|
||||
|
||||
# 4) 起应用与同步服务
|
||||
docker compose --env-file .env up -d app powersync
|
||||
|
||||
# 5) 验证
|
||||
curl -s http://127.0.0.1:3001/api/health
|
||||
docker compose logs --tail 20 powersync # 应看到 replication 激活
|
||||
```
|
||||
|
||||
## 数据迁移 (从现网 MySQL 快照)
|
||||
|
||||
```bash
|
||||
# 只读源库; 目标必须是空库 (有数据会跳过, ETL_FORCE=1 强制)
|
||||
docker run --rm --network iboard-prod_default \
|
||||
-e DATABASE_URL="postgresql://iboard:<PG_PASSWORD>@pg:5432/iboard" \
|
||||
-e SRC_DATABASE_URL="mysql://<user>:<pass>@<host>:3306/iboard" \
|
||||
iboard:latest node scripts/etl-mariadb-to-pg.mjs
|
||||
```
|
||||
|
||||
迁移后需要重启 powersync 让它重新快照:
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env restart powersync
|
||||
```
|
||||
|
||||
## 版本与回滚
|
||||
|
||||
- 新版本: 构建新镜像 → `docker compose up -d app` (只重建 app, 数据卷不动)
|
||||
- 回滚: 用上一次的镜像标签重新 `up -d app`
|
||||
- 数据: `data/pg` 持久化; 变更前建议 `docker compose exec -T pg pg_dump -U iboard iboard > backup.sql`
|
||||
@@ -0,0 +1,80 @@
|
||||
name: iboard-prod
|
||||
|
||||
# iBoard 0.2.1 生产栈 (单端口对外)
|
||||
# - app : 3001 对外 (唯一入口), 内部把 /sync 反代到 powersync
|
||||
# - pg : PostgreSQL 16, 仅容器内网 (逻辑复制供同步服务消费)
|
||||
# - powersync : 同步服务, 仅容器内网 (不对外暴露端口)
|
||||
#
|
||||
# 与旧的生产方式区别: 不再依赖宿主 MySQL, 数据库与同步服务都在栈内;
|
||||
# 对外只有 3001 一个端口, 域名 https://iboard.honor3.com (NPM 反代) 即可。
|
||||
#
|
||||
# 用法 (baihu:/app/iboard-prod):
|
||||
# cp deploy/prod/.env.example deploy/prod/.env # 填密钥
|
||||
# docker compose --env-file deploy/prod/.env -f deploy/prod/docker-compose.yml up -d
|
||||
|
||||
services:
|
||||
pg:
|
||||
image: postgres:16-alpine
|
||||
restart: unless-stopped
|
||||
command: ["postgres", "-c", "wal_level=logical"]
|
||||
environment:
|
||||
POSTGRES_USER: iboard
|
||||
POSTGRES_PASSWORD: ${PG_PASSWORD:?PG_PASSWORD missing}
|
||||
POSTGRES_DB: iboard
|
||||
PS_STORAGE_PASSWORD: ${PS_STORAGE_PASSWORD:?PS_STORAGE_PASSWORD missing}
|
||||
volumes:
|
||||
- ./data/pg:/var/lib/postgresql/data
|
||||
- ./initdb:/docker-entrypoint-initdb.d:ro
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U iboard -d iboard"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 12
|
||||
|
||||
app:
|
||||
image: iboard:latest
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: Dockerfile
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
pg:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
DATABASE_URL: postgresql://iboard:${PG_PASSWORD}@pg:5432/iboard
|
||||
PORT: "3001"
|
||||
JWT_SECRET: ${JWT_SECRET:?JWT_SECRET missing}
|
||||
POWERSYNC_JWT_SECRET: ${POWERSYNC_JWT_SECRET:?POWERSYNC_JWT_SECRET missing}
|
||||
# 客户端拿到的同步地址 = 同域 (经由 app 的 /sync 反代)
|
||||
POWERSYNC_URL: ${PUBLIC_URL:-https://iboard.honor3.com}
|
||||
# app 内部转发同步请求到内网 powersync
|
||||
POWERSYNC_UPSTREAM: http://powersync:8080
|
||||
OTA_PUBLIC_BASE: ${PUBLIC_URL:-https://iboard.honor3.com}
|
||||
OTA_PACKAGE_DIR: /app/ota-package
|
||||
MIHOME_CACHE_DIR: /app/cache
|
||||
volumes:
|
||||
- ./data/cache:/app/cache
|
||||
ports:
|
||||
- "${HOST_PORT:-3001}:3001"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3001/api/health || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
start_period: 20s
|
||||
|
||||
powersync:
|
||||
image: journeyapps/powersync-service:latest
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
pg:
|
||||
condition: service_healthy
|
||||
command: ["start", "-r", "unified"]
|
||||
volumes:
|
||||
- ./powersync/service.yaml:/config/service.yaml:ro
|
||||
- ./powersync/sync-config.yaml:/config/sync-config.yaml:ro
|
||||
environment:
|
||||
POWERSYNC_CONFIG_PATH: /config/service.yaml
|
||||
PS_SOURCE_URI: postgresql://iboard:${PG_PASSWORD}@pg:5432/iboard?sslmode=disable
|
||||
PS_STORAGE_URI: postgresql://powersync_storage:${PS_STORAGE_PASSWORD}@pg:5432/iboard?sslmode=disable
|
||||
PS_JWT_KEY_B64: ${POWERSYNC_JWT_KEY_B64:?POWERSYNC_JWT_KEY_B64 missing}
|
||||
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
# 生产 PG 初始化: PowerSync bucket storage 专用用户
|
||||
set -e
|
||||
: "${PS_STORAGE_PASSWORD:?PS_STORAGE_PASSWORD missing}"
|
||||
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
||||
DO \$\$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'powersync_storage') THEN
|
||||
CREATE USER powersync_storage WITH PASSWORD '$PS_STORAGE_PASSWORD';
|
||||
END IF;
|
||||
END
|
||||
\$\$;
|
||||
GRANT CREATE ON DATABASE $POSTGRES_DB TO powersync_storage;
|
||||
EOSQL
|
||||
|
||||
echo '[initdb] powersync_storage ready.'
|
||||
@@ -0,0 +1,41 @@
|
||||
# PowerSync Service 主配置 (0.2.1 验证部署)
|
||||
# 参考: https://docs.powersync.com/configuration/powersync-service/self-hosted-instances
|
||||
# 注意: !env 是 YAML 整值标签, 只能整个值替换变量, 不能内嵌在 URI 字符串中;
|
||||
# 完整连接串由 docker-compose 以 PS_* 环境变量注入。
|
||||
|
||||
replication:
|
||||
connections:
|
||||
- type: postgresql
|
||||
# 源库: 本栈 pg 容器 (0.2.1 独立实例), 复制走 iboard021 账号
|
||||
uri: !env PS_SOURCE_URI
|
||||
sslmode: disable
|
||||
|
||||
# bucket storage: 同实例 PG (16 >= 14 允许同库不同 schema, service 自建 powersync schema)
|
||||
storage:
|
||||
type: postgresql
|
||||
uri: !env PS_STORAGE_URI
|
||||
sslmode: disable
|
||||
|
||||
port: 8080
|
||||
|
||||
sync_config:
|
||||
path: /config/sync-config.yaml
|
||||
|
||||
# 客户端鉴权: app 后端 /api/powersync/token 签发 HS256 JWT (aud=powersync)
|
||||
# oct 密钥 k = base64url(POWERSYNC_JWT_SECRET)
|
||||
client_auth:
|
||||
jwks:
|
||||
keys:
|
||||
- kty: oct
|
||||
k: !env PS_JWT_KEY_B64
|
||||
alg: HS256
|
||||
audience:
|
||||
- powersync
|
||||
|
||||
telemetry:
|
||||
disable_telemetry_sharing: true
|
||||
|
||||
system:
|
||||
logging:
|
||||
level: info
|
||||
format: text
|
||||
@@ -0,0 +1,25 @@
|
||||
# Sync Streams (edition 3): 任务模块 6 表 + User (展示用)
|
||||
# Sequential ID Mapping (见 docs/V0.2/离线编辑模块/0.2.1实施方案.md §3):
|
||||
# - 客户端主键 = uuid 列 (离线新建行同步回填后 id 稳定); int 自增 id 不下发
|
||||
# - 外键输出 uuid 镜像列, 别名回 projectId/columnId/parentId/taskId (客户端字段名不变)
|
||||
# - 引号保留 PG PascalCase 标识; 可见性按 ProjectMember 过滤
|
||||
|
||||
config:
|
||||
edition: 3
|
||||
|
||||
streams:
|
||||
iboard_users:
|
||||
auto_subscribe: true
|
||||
query: SELECT CAST("id" AS TEXT) AS "id", "name", "email" FROM "User"
|
||||
|
||||
iboard_task_data:
|
||||
auto_subscribe: true
|
||||
with:
|
||||
my_projects: SELECT "projectId" FROM "ProjectMember" WHERE CAST("userId" AS TEXT) = auth.user_id()
|
||||
queries:
|
||||
- SELECT "uuid" AS "id", "uuid", "code", "name", CAST("ownerId" AS TEXT) AS "ownerId", "isPersonal", "archived", "notes", "taskKinds", "icon", "autoArchive", "createdAt", "updatedAt" FROM "Project" WHERE "id" IN my_projects
|
||||
- SELECT "uuid" AS "id", "uuid", "projectUuid" AS "projectId", CAST("userId" AS TEXT) AS "userId", "permission", "createdAt" FROM "ProjectMember" WHERE "projectId" IN my_projects
|
||||
- SELECT "uuid" AS "id", "uuid", "projectUuid" AS "projectId", "name", "sortOrder", "boundStatus", "retention", "createdAt", "updatedAt" FROM "BoardColumn" WHERE "projectId" IN my_projects
|
||||
- SELECT "uuid" AS "id", "uuid", "projectUuid" AS "projectId", "columnUuid" AS "columnId", "parentUuid" AS "parentId", "title", "description", "kind", "markDate", "status", "doneAt", CAST("assigneeId" AS TEXT) AS "assigneeId", CAST("creatorId" AS TEXT) AS "creatorId", "extras", "sortOrder", "number", "archived", "archivedAt", "archiveSource", "createdAt", "updatedAt" FROM "Task" WHERE "projectId" IN my_projects
|
||||
- SELECT "uuid" AS "id", "uuid", "taskUuid" AS "taskId", CAST("userId" AS TEXT) AS "userId" FROM "TaskMember" WHERE "taskId" IN (SELECT "id" FROM "Task" WHERE "projectId" IN my_projects)
|
||||
- SELECT "uuid" AS "id", "uuid", "taskUuid" AS "taskId", "name" FROM "TaskTag" WHERE "taskId" IN (SELECT "id" FROM "Task" WHERE "projectId" IN my_projects)
|
||||
@@ -0,0 +1,11 @@
|
||||
-- 生产 PG: PowerSync 逻辑复制 publication
|
||||
-- 必须在 prisma migrate deploy 建表之后执行 (initdb 阶段表还不存在, 故不放 initdb 目录)。
|
||||
-- 幂等: 已存在则跳过。
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_publication WHERE pubname = 'powersync') THEN
|
||||
CREATE PUBLICATION powersync FOR TABLE
|
||||
"Project", "ProjectMember", "BoardColumn", "Task", "TaskMember", "TaskTag", "User";
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
@@ -0,0 +1,82 @@
|
||||
-- iBoard 0.2.1: 外键 uuid 镜像列触发器
|
||||
-- 由 0.2.1 验证库导出; 服务端写入时自动维护 projectUuid/columnUuid/parentUuid/taskUuid,
|
||||
-- 同步流据此把镜像列以 projectId/columnId/parentId/taskId 的别名下发给客户端。
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.func_boardcolumn_uuid_map()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
SELECT "uuid" INTO NEW."projectUuid" FROM "Project" WHERE "id" = NEW."projectId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'Project % 不存在', NEW."projectId"; END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$function$
|
||||
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.func_projectmember_uuid_map()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
SELECT "uuid" INTO NEW."projectUuid" FROM "Project" WHERE "id" = NEW."projectId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'Project % 不存在', NEW."projectId"; END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$function$
|
||||
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.func_task_uuid_map()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
SELECT "uuid" INTO NEW."projectUuid" FROM "Project" WHERE "id" = NEW."projectId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'Project % 不存在', NEW."projectId"; END IF;
|
||||
SELECT "uuid" INTO NEW."columnUuid" FROM "BoardColumn" WHERE "id" = NEW."columnId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'BoardColumn % 不存在', NEW."columnId"; END IF;
|
||||
IF NEW."parentId" IS NULL THEN
|
||||
NEW."parentUuid" := NULL;
|
||||
ELSE
|
||||
SELECT "uuid" INTO NEW."parentUuid" FROM "Task" WHERE "id" = NEW."parentId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'Task % 不存在', NEW."parentId"; END IF;
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$function$
|
||||
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.func_taskmember_uuid_map()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
SELECT "uuid" INTO NEW."taskUuid" FROM "Task" WHERE "id" = NEW."taskId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'Task % 不存在', NEW."taskId"; END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$function$
|
||||
|
||||
;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.func_tasktag_uuid_map()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
SELECT "uuid" INTO NEW."taskUuid" FROM "Task" WHERE "id" = NEW."taskId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'Task % 不存在', NEW."taskId"; END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$function$
|
||||
|
||||
;
|
||||
|
||||
CREATE TRIGGER trg_boardcolumn_uuid_map BEFORE INSERT OR UPDATE ON public."BoardColumn" FOR EACH ROW EXECUTE FUNCTION func_boardcolumn_uuid_map();
|
||||
CREATE TRIGGER trg_projectmember_uuid_map BEFORE INSERT OR UPDATE ON public."ProjectMember" FOR EACH ROW EXECUTE FUNCTION func_projectmember_uuid_map();
|
||||
CREATE TRIGGER trg_task_uuid_map BEFORE INSERT OR UPDATE ON public."Task" FOR EACH ROW EXECUTE FUNCTION func_task_uuid_map();
|
||||
CREATE TRIGGER trg_taskmember_uuid_map BEFORE INSERT OR UPDATE ON public."TaskMember" FOR EACH ROW EXECUTE FUNCTION func_taskmember_uuid_map();
|
||||
CREATE TRIGGER trg_tasktag_uuid_map BEFORE INSERT OR UPDATE ON public."TaskTag" FOR EACH ROW EXECUTE FUNCTION func_tasktag_uuid_map();
|
||||
+287
@@ -0,0 +1,287 @@
|
||||
# 0.2.1 发布任务 — 目标与现状
|
||||
|
||||
> 最后更新:2026-10-27 08:05
|
||||
> 分支:`dev-0.2`(已推送)
|
||||
> 状态:**生产已切换到 0.2.1 单端口架构并验证通过;剩余 "合 master 发布" 一步**
|
||||
|
||||
## 零、执行结果速览(2026-10-27 已完成)
|
||||
|
||||
| 项目 | 结果 |
|
||||
| --- | --- |
|
||||
| 生产地址 | `https://iboard.honor3.com` → baihu **3001**(NPM + 有效证书) |
|
||||
| 生产架构 | `iboard-prod-app-1`(3001 对外) + `iboard-prod-pg-1`(内网) + `iboard-prod-powersync-1`(内网) |
|
||||
| 端口 | **只剩 3001**;13001 / 13002 / 13443 全部下线 |
|
||||
| 数据迁移 | MySQL → PG 完成:Project 3、Task 25、BoardColumn 12、User 1、CheckIn 17、News 19、IndicatorPoint 245、Mihome 等全部迁入 |
|
||||
| 旧生产 | 容器 `iboard` 已 **stop(未删除)**,`docker start iboard` 可秒级回滚 |
|
||||
| 登录态 | `JWT_SECRET` 沿用 `iboard`,现有用户无需重新登录 |
|
||||
| 米家凭证 | `/app/iboard/cache` → `deploy/prod/data/cache`(`auth.txt` + `apizero/`) |
|
||||
| E2E 验证 | 在线:项目卡片 + `ADMIN-16`/`ADMIN-18` 编号;断网:徽标出现、任务页数据完整、无 fail fetch;恢复:徽标消失 |
|
||||
|
||||
### 迁移过程中踩到并修掉的坑
|
||||
|
||||
1. `prisma/migrations/` 是 **MySQL 语法**(反引号),PG 无法 `migrate deploy` → 改用 `prisma db push --accept-data-loss` 按 schema 建表。
|
||||
2. `db push` 首次因参数不被识别而输出帮助(表结构停在旧 schema,缺 `autoArchive`)→ 去掉错误参数重跑,列已补齐。
|
||||
3. 新库缺 **uuid 镜像触发器**(`projectUuid`/`columnUuid`/`parentUuid`/`taskUuid`)→ 从 0.2.1 验证库导出 5 个函数 + 5 个触发器,落库并入库 `deploy/prod/sql/uuid-triggers.sql`。
|
||||
4. bash 把 `$$` 展开成 PID 导致 TRUNCATE 脚本报错 → 改用 SQL 文件传入。
|
||||
5. baihu 上 `docker build` 缺 buildx → 改用 `docker compose build`。
|
||||
|
||||
---
|
||||
|
||||
## 一、任务目标(用户原始要求)
|
||||
|
||||
1. 域名 `iboard.honor3.com` 已指向 3000 端口、HTTPS 证书已配好 → 客户端全面切到该域名。
|
||||
2. **Windows 外壳 + 离线编辑功能正式合并到 `dev-0.2`**,完整版本号 **0.2.1**。
|
||||
3. 确保 **Android** 功能正常(通过 CI 编译验证,不在本地装 Android 工具链)。
|
||||
4. 确保 **CI/CD** 正常。
|
||||
5. Windows **本地打包正常**即可。
|
||||
6. `dev-0.2` 更新完成后 **通过 `master` 分支发布**。
|
||||
7. 追加要求:**不要再有 13002 这类独立端口**,所有版本合并成一套。
|
||||
|
||||
---
|
||||
|
||||
## 二、已完成
|
||||
|
||||
### 2.1 分支合并
|
||||
|
||||
| 内容 | 结果 |
|
||||
| --- | --- |
|
||||
| `dev-0.2.1`(离线编辑 + 项目编号 + PG/PowerSync)→ `dev-0.2` | 已合并 `e689e44` |
|
||||
| `dev-windows-0.1`(Windows 外壳:托盘/悬浮球/吸附/自启动)→ `dev-0.2` | 已按路径迁入 `eef2969` |
|
||||
| `dev-0.2` → `android-1.0`(触发 APK 构建) | 已合并 `4958359` |
|
||||
| 冲突处理 | `projects.js`/`tasks.js`/`api/task.js` 手工合并,**两边功能都保留**(`autoArchive` 归档 + `code` 编号) |
|
||||
| 归档功能补齐到本地库 | `src/api/task.js` 新增 `archive`/`unarchive`/`archivedList`;`schema.js` 加 `archived/archivedAt/archiveSource/autoArchive`;`sync-config.yaml` 与 upload 处理器同步 |
|
||||
| Prisma 客户端补齐 | dev-0.2 原来缺任务模块 6 个模型,已重新 generate `fc23919` |
|
||||
|
||||
### 2.2 版本与域名
|
||||
|
||||
- 版本统一 **0.2.1**:`package.json` / `src-tauri/tauri.conf.json` / `Cargo.toml` / `Cargo.lock`(`scripts/ci/check-version.mjs` 通过)
|
||||
- 域名切 `https://iboard.honor3.com`:
|
||||
- `src/api/client.js` 注释、`.env.shell`、`scripts/wsl/build-apk.sh`、`.gitea/workflows/android-build.yml`、`.gitea/workflows/docker-build.yml`、`Dockerfile`(`OTA_PUBLIC_BASE`)、`tauri.conf.json`(OTA endpoint + CSP)
|
||||
- 旧域名 `bh.vps.honor3.com:3001` 仅保留在 CSP 白名单里做滚动兼容
|
||||
|
||||
### 2.3 单端口架构(去掉 13002)
|
||||
|
||||
| 改动 | 位置 |
|
||||
| --- | --- |
|
||||
| Express 增加 `/sync`、`/socket` 同域反代到内网 powersync | `server/powersync-proxy.js` + `server/index.js`(挂在 `express.json()` 之前,支持长连接) |
|
||||
| 生产编排:app(3001 对外) + pg(内网) + powersync(内网) | `deploy/prod/docker-compose.yml` |
|
||||
| 生产部署脚本(幂等:迁移 → publication → 起栈 → 健康检查) | `scripts/deploy/prod.sh` |
|
||||
| PG 初始化(powersync_storage 用户) | `deploy/prod/initdb/01-powersync-storage.sh` |
|
||||
| 逻辑复制 publication(**建表后**执行) | `deploy/prod/sql/publication.sql` |
|
||||
| 部署文档 | `deploy/prod/README.md`、`.env.example` |
|
||||
| CI 部署段改为调用宿主脚本,未配 PG secrets 时自动跳过 | `.gitea/workflows/docker-build.yml` |
|
||||
|
||||
### 2.4 Windows 本地打包 — 通过 ✅
|
||||
|
||||
`npm run build:win` 全流程成功(本机需 Node 20.19+;已用便携 Node 20.18.1 之外的 Node 24 验证过 vite 构建):
|
||||
|
||||
| 产物 | 路径 | 大小 |
|
||||
| --- | --- | --- |
|
||||
| 安装包 | `artifacts/windows/iBoard_0.2.1_x64-setup.exe` | 6.9 MB |
|
||||
| 便携版 zip | `artifacts/windows/iBoard_0.2.1_x64-portable.zip` | 7.9 MB |
|
||||
|
||||
外壳能力(继承 dev-windows-0.1):托盘、悬浮球吸附、自动隐藏、单实例、自启动、窗口尺寸单值配置
|
||||
(`%APPDATA%\com.iboard.app\shell-config.json` 的 `window_width`,高度按 405:720 锁定推导)。
|
||||
|
||||
离线能力(继承 0.2.1):GET 响应本地缓存、同步凭证持久化(离线不清库)、左上角「离线」徽标。
|
||||
|
||||
### 2.5 Android CI — 通过 ✅
|
||||
|
||||
- 触发:`android-1.0` 分支 push(`4ded8e3`)
|
||||
- 结果:**16 个步骤全部 success**,`Build release APK` + `Publish APK to Gitea packages` 成功
|
||||
- 产物:`app-universal-release.apk`(20 MB),versionName = **0.2.1**
|
||||
已发布到 `http://git.honor3.com/api/packages/Fullstack/generic/iboard/1.0-4ded8e30/`
|
||||
- 首次失败原因:runner 宿主机(baihu)磁盘 **95%** → `No space left on device`;
|
||||
清理悬空镜像 + 构建缓存后释放 11.5 GB,重跑通过。**磁盘现已 60%(39 GB 可用)**
|
||||
|
||||
### 2.6 CI/CD 现状
|
||||
|
||||
| Workflow | 触发 | 状态 |
|
||||
| --- | --- | --- |
|
||||
| `docker-build.yml` | `master` push | 改造完成,未在 master 上验证(部署段会因缺 secrets 跳过) |
|
||||
| `android-build.yml` | `android-*` push | **已验证通过** |
|
||||
| `ota-build.yml` / `sync-registry.yml` | 参照原逻辑 | 未改动 |
|
||||
|
||||
---
|
||||
|
||||
## 三、当前卡点(生产切换未执行)
|
||||
|
||||
生产镜像 **已构建成功**:`iboard:latest` = `db6b27b851b8`(924 MB,2026-10-26 22:53)
|
||||
|
||||
baihu 上当前跑着两套:
|
||||
|
||||
| 容器 | 用途 | 端口 |
|
||||
| --- | --- | --- |
|
||||
| `iboard`(旧) | **现网生产**,MySQL(宿主 3306) | 3001 |
|
||||
| `iboard-021-app-1` 等 4 个 | 0.2.1 验证栈 | 13001 / 13002 / 13443 |
|
||||
| (未启动)`iboard-prod` | **新生产栈**(PG + PowerSync + app) | 3001(计划) |
|
||||
|
||||
`/app/iboard-prod` 已上传源码、`deploy/prod/.env` 已生成(6 个密钥,600 权限)。
|
||||
|
||||
**剩余步骤(约 4 步)**:
|
||||
|
||||
1. 起新栈(先用 `HOST_PORT=13011` 灰度,不动现网)
|
||||
2. 数据迁移:现网 MySQL → 新 PG(`scripts/etl-mariadb-to-pg.mjs`,只读源库)
|
||||
3. 验证:健康检查、登录、任务列表、离线编辑(断网后仍可读)、同步回流
|
||||
4. 切换:停 `iboard` 旧容器 → 新栈改绑 3001 → 域名 `iboard.honor3.com` 生效 → 下线验证栈(13001/13002/13443)
|
||||
|
||||
然后 `dev-0.2` → `master` 合并推送,触发 CI 发布。
|
||||
|
||||
---
|
||||
|
||||
## 四、需要确认的信息(阻塞项)
|
||||
|
||||
1. **Gitea Actions Secrets 是否要配 PG 密钥?**
|
||||
需配:`PG_PASSWORD`、`PS_STORAGE_PASSWORD`、`JWT_SECRET`、`POWERSYNC_JWT_SECRET`、`POWERSYNC_JWT_KEY_B64`。
|
||||
不配的话:master 的 CI 只构建镜像不部署,生产靠手工执行 `scripts/deploy/prod.sh`(当前默认路径)。
|
||||
|
||||
2. **生产数据迁移的时间窗口**:迁移需短暂停写(现网 MySQL 只读快照)。是否可以挑一个低峰时间、期间 (~10 分钟) 站点只读?
|
||||
|
||||
3. **现网 MySQL 里的米家凭证/缓存**:`/app/iboard/cache`(`auth.txt` 等)是否要一并搬到新栈的 `deploy/prod/data/cache`?
|
||||
|
||||
4. **用户密码**:迁移只搬数据,`JWT_SECRET` 若换新,所有人需重新登录;是否沿用现网 `JWT_SECRET`(`iboard`)以保持登录态?**建议换新**(当前值过弱)。
|
||||
|
||||
5. **域名端口说明**:`iboard.honor3.com` 实际反代到 baihu **3001**(NPM 配置:`114.134.187.170:3001`,SSL 强制)。
|
||||
你提到"已转向 3000 端口"——请确认指的是 `honor3.com` 根域(→ homepage)而非 `iboard` 子域,
|
||||
否则需要调整 NPM 的 forward_port。
|
||||
|
||||
---
|
||||
|
||||
## 五、关键路径与命令速查
|
||||
|
||||
```bash
|
||||
# 仓库
|
||||
C:\Users\Rabbit\Documents\workbetch\iboard # dev-0.2 主工作区
|
||||
C:\Users\Rabbit\Documents\workbetch\iboard-dev-0.2.1 # 研究分支 worktree
|
||||
C:\Users\Rabbit\Documents\workbetch\iboard-dev-windows # Windows 外壳 worktree
|
||||
|
||||
# 服务器
|
||||
ssh root@baihu # 生产 + CI runner(baihu 上跑 act_runner,注册名 baishe)
|
||||
ssh root@baishe # 反代(NPM)、Gitea、homepage
|
||||
|
||||
# 生产目录
|
||||
/app/iboard-prod/deploy/prod/{docker-compose.yml,.env,data/,powersync/,sql/,initdb/}
|
||||
|
||||
# 常用
|
||||
docker compose -f /app/iboard-prod/deploy/prod/docker-compose.yml --env-file /app/iboard-prod/deploy/prod/.env ps
|
||||
bash /app/iboard-prod/scripts/deploy/prod.sh
|
||||
curl -s https://iboard.honor3.com/api/health
|
||||
```
|
||||
|
||||
## 五之二、后续动作执行步骤(已确认方案,按序执行)
|
||||
|
||||
### 决策确认(2026-10-27)
|
||||
|
||||
| 项 | 决定 |
|
||||
| --- | --- |
|
||||
| PG 密钥 | **不进 Gitea Secrets**,直接写在服务器 `/app/iboard-prod/deploy/prod/.env`(600) |
|
||||
| 迁移时机 | 立即执行 |
|
||||
| 米家凭证 | 保留,`/app/iboard/cache` 搬到新栈 `deploy/prod/data/cache` |
|
||||
| `JWT_SECRET` | 沿用现网值(`iboard`),保持现有登录态 |
|
||||
| 域名 | `iboard.honor3.com` → baihu **3001**(NPM 已配好,SSL 强制) |
|
||||
|
||||
### 步骤 A:准备(不改动现网)
|
||||
|
||||
```bash
|
||||
# A1. 沿用现网 JWT_SECRET (其余密钥保持已生成的随机值)
|
||||
cd /app/iboard-prod/deploy/prod
|
||||
sed -i 's/^JWT_SECRET=.*/JWT_SECRET=iboard/' .env
|
||||
|
||||
# A2. 搬米家缓存 (auth.txt 等)
|
||||
mkdir -p data/cache
|
||||
rsync -a /app/iboard/cache/ data/cache/
|
||||
|
||||
# A3. 保留旧镜像用于回滚
|
||||
docker tag iboard:latest iboard:mysql-final # 需在重新构建前执行; 若已覆盖见"回滚预案"
|
||||
```
|
||||
|
||||
### 步骤 B:起灰度栈(不动现网 3001)
|
||||
|
||||
```bash
|
||||
cd /app/iboard-prod/deploy/prod
|
||||
HOST_PORT=13011 docker compose --project-name iboard-prod \
|
||||
--env-file .env -f docker-compose.yml up -d pg
|
||||
|
||||
# 迁移建表
|
||||
docker run --rm --network iboard-prod_default \
|
||||
-e DATABASE_URL="postgresql://iboard:$(grep ^PG_PASSWORD .env | cut -d= -f2)@pg:5432/iboard" \
|
||||
iboard:latest npx prisma migrate deploy
|
||||
|
||||
# 建 publication (必须在建表之后)
|
||||
docker compose --project-name iboard-prod --env-file .env -f docker-compose.yml exec -T pg \
|
||||
psql -U iboard -d iboard -v ON_ERROR_STOP=1 -f /dev/stdin < sql/publication.sql
|
||||
|
||||
# 起 app + powersync (只有 13011 对外)
|
||||
HOST_PORT=13011 docker compose --project-name iboard-prod \
|
||||
--env-file .env -f docker-compose.yml up -d app powersync
|
||||
|
||||
# 验收
|
||||
curl -s http://127.0.0.1:13011/api/health # {"ok":true,...}
|
||||
ss -tlnp | grep -E ':(13011|5432|8080)\b' # 只应看到 13011
|
||||
```
|
||||
|
||||
### 步骤 C:数据迁移(MySQL → PG)
|
||||
|
||||
```bash
|
||||
docker run --rm --network iboard-prod_default \
|
||||
-e DATABASE_URL="postgresql://iboard:<PG_PASSWORD>@pg:5432/iboard" \
|
||||
-e SRC_DATABASE_URL="mysql://root:<MYSQL_PASSWORD>@<host>:3306/iboard" \
|
||||
iboard:latest node scripts/etl-mariadb-to-pg.mjs
|
||||
|
||||
# 迁移后重启同步服务重建快照
|
||||
docker compose --project-name iboard-prod --env-file .env -f docker-compose.yml restart powersync
|
||||
```
|
||||
|
||||
**验收**:项目 3 个(ADMIN / IBOARD / P3F921)、任务 ~22 条、用户 1 个(admin@iboard.local);
|
||||
`docker compose logs powersync` 显示 replication 已激活且无报错。
|
||||
|
||||
### 步骤 D:功能验证(13011)
|
||||
|
||||
- 登录 `admin@iboard.local`
|
||||
- 任务页:项目卡片、任务编号(如 `ADMIN-16`)
|
||||
- **离线验证**:断网后列表仍可读、左上角出现「离线」徽标,恢复网络自动同步回流
|
||||
- 监控 / 宏观 / 打卡页有数据
|
||||
|
||||
### 步骤 E:切换生产
|
||||
|
||||
```bash
|
||||
# E1. 停旧容器 (MySQL 版)
|
||||
docker rm -vf iboard || true
|
||||
|
||||
# E2. 新栈改绑 3001
|
||||
cd /app/iboard-prod/deploy/prod
|
||||
HOST_PORT=3001 docker compose --project-name iboard-prod \
|
||||
--env-file .env -f docker-compose.yml up -d app
|
||||
curl -s https://iboard.honor3.com/api/health # 经 NPM + 证书
|
||||
|
||||
# E3. 下线 0.2.1 验证栈 (释放 13001/13002/13443)
|
||||
cd /app/iboard-0.2.1/deploy/0.2.1 && docker compose down
|
||||
```
|
||||
|
||||
**验收**:`https://iboard.honor3.com` 可登录、任务正常、离线可编辑;
|
||||
`ss -tlnp` 只剩 3001(外加仅供本机的 3306)。
|
||||
|
||||
### 步骤 F:发布
|
||||
|
||||
```bash
|
||||
git checkout master && git merge dev-0.2 --no-edit
|
||||
git push origin master # 触发 CI: 构建镜像 + OTA
|
||||
```
|
||||
|
||||
CI 未配 PG secrets → 只构建不部署;生产已由步骤 B~E 手工就绪。
|
||||
|
||||
### 回滚预案
|
||||
|
||||
| 场景 | 动作 |
|
||||
| --- | --- |
|
||||
| 新栈起不来 | 旧容器未停,现网不受影响,回步骤 B 排查 |
|
||||
| 迁移数据不对 | 清空 `deploy/prod/data/pg` 后重跑 ETL |
|
||||
| 切换后严重故障 | 用 `iboard:mysql-final` 旧镜像按原 MySQL 参数恢复 3001 |
|
||||
|
||||
## 六、已知遗留
|
||||
|
||||
- `dev-0.2.1` / `dev-windows-0.1` 两个 worktree 分支内容已全部并入 `dev-0.2`,可择机删除。
|
||||
- `tmp-offline-edit` 分支 = `1cd5b85`,历史遗留,可删。
|
||||
- 临时测试脚本 `scripts/_browser-test.mjs`、`scripts/_shell-offline-test.mjs` 含真实口令,**不要入库**。
|
||||
- 0.2.1 验证库里可能残留测试任务(`浏览器验证任务` / `IBOARD-8`),迁移后建议清理。
|
||||
- `node_modules` 曾在多种 Node 版本间切换,如遇 esbuild 权限报错,清 `node_modules` 重装即可。
|
||||
@@ -0,0 +1,108 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>设计稿 · 视图切换移入项目栏 (T-VW-02/03 调整)</title>
|
||||
<style>
|
||||
:root { --primary:#1677ff; --text:#333; --muted:#999; --border:#eee; }
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif; }
|
||||
body { background:#eceef1; padding: 24px; display:flex; gap:28px; flex-wrap:wrap; }
|
||||
.phone { width:375px; background:#f5f5f5; border-radius:18px; overflow:hidden; box-shadow:0 8px 30px rgba(0,0,0,.15); }
|
||||
.phone h3 { font-size:13px; color:#556; padding:10px 14px 0; font-weight:600; }
|
||||
.phone .cap { font-size:11px; color:#889; padding:2px 14px 10px; }
|
||||
.bar { display:flex; align-items:center; gap:8px; padding:10px 12px; background:#fff; border-bottom:1px solid #f0f0f0; }
|
||||
.pname { font-size:15px; font-weight:700; color:var(--text); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
|
||||
/* 紧凑分段切换: 高 26px, 内边距收窄, 选中项白底浮起 */
|
||||
.vseg { display:flex; background:#f2f3f5; border-radius:8px; padding:2px; flex-shrink:0; }
|
||||
.vseg div { font-size:12px; line-height:1; padding:5px 11px; border-radius:6px; color:var(--muted); cursor:pointer; white-space:nowrap; }
|
||||
.vseg div.on { background:#fff; color:var(--text); font-weight:600; box-shadow:0 1px 2px rgba(0,0,0,.08); }
|
||||
.mini { font-size:11px; color:var(--primary); background:#f0f5ff; border-radius:6px; padding:5px 8px; white-space:nowrap; flex-shrink:0; cursor:pointer; }
|
||||
.mini.solid { background:var(--primary); color:#fff; }
|
||||
.mini.ghost { background:#fff; border:1px solid #e3e6ea; color:#666; }
|
||||
.bar-note { font-size:10px; color:#b0b6bf; padding:6px 12px; background:#fafbfc; border-bottom:1px dashed #e5e8ec; }
|
||||
.demo-body { padding:12px; }
|
||||
.card { background:#fff; border-radius:9px; padding:10px 12px; margin-bottom:7px; font-size:13px; color:#444; box-shadow:0 1px 2px rgba(0,0,0,.04); display:flex; gap:8px; align-items:center; }
|
||||
.card .dot { width:8px; height:8px; border-radius:50%; background:#c9ced6; flex-shrink:0; }
|
||||
.cols { display:flex; gap:8px; }
|
||||
.col { flex:1; background:#fff; border-radius:9px; padding:8px; }
|
||||
.col b { font-size:11px; color:#556; }
|
||||
.col .ccard { background:#f6f7f9; border-radius:6px; font-size:11px; color:#555; padding:6px; margin-top:6px; }
|
||||
.anno { font-size:11px; color:#7a828e; padding:8px 14px 14px; line-height:1.7; background:#fafbfc; }
|
||||
.anno b { color:#43506b; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="phone">
|
||||
<h3>状态 1 · 列表视图(默认)</h3>
|
||||
<div class="cap">切换段控放在项目名右侧, 与名称同一行</div>
|
||||
<div class="bar">
|
||||
<div class="pname">我的看板项目</div>
|
||||
<div class="vseg"><div class="on">列表</div><div>看板</div></div>
|
||||
<div class="mini">已归档</div>
|
||||
<div class="mini ghost">管理</div>
|
||||
<div class="mini solid">+ 新增</div>
|
||||
</div>
|
||||
<div class="bar-note">「项目管理」按钮文案收窄为「管理」, 与「已归档」同为次级样式, 突出右侧主操作</div>
|
||||
<div class="demo-body">
|
||||
<div class="card"><span class="dot"></span>梳理 V0.2 归档需求</div>
|
||||
<div class="card"><span class="dot"></span>OTA 发布说明样式修复</div>
|
||||
<div class="card"><span class="dot"></span>看板列滚动条位置调整</div>
|
||||
</div>
|
||||
<div class="anno">
|
||||
<b>规格</b><br/>
|
||||
· 分段控件高 26px, 选中项白底浮起(复用现有 .seg 体系收窄版)<br/>
|
||||
· 项目名 flex:1 + 单行省略, 最短保留 4 字符<br/>
|
||||
· 段控始终紧贴名称右侧, 距离 8px
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="phone">
|
||||
<h3>状态 2 · 看板视图</h3>
|
||||
<div class="cap">点「看板」后段控选中项滑换, 其余布局不变</div>
|
||||
<div class="bar">
|
||||
<div class="pname">我的看板项目</div>
|
||||
<div class="vseg"><div>列表</div><div class="on">看板</div></div>
|
||||
<div class="mini">已归档</div>
|
||||
<div class="mini ghost">管理</div>
|
||||
<div class="mini solid">+ 新增</div>
|
||||
</div>
|
||||
<div class="demo-body">
|
||||
<div class="cols">
|
||||
<div class="col"><b>Plan · 2</b><div class="ccard">梳理归档需求</div><div class="ccard">OTA 说明修复</div></div>
|
||||
<div class="col"><b>Doing · 1</b><div class="ccard">滚动条调整</div></div>
|
||||
<div class="col"><b>Done · 1</b><div class="ccard">版本方案落地</div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="anno">
|
||||
<b>交互</b><br/>
|
||||
· 点按即切换并持久化(设备端记忆, T-VW-02/03 不变)<br/>
|
||||
· 切换不引发项目栏高度变化, 下方视图平滑重排<br/>
|
||||
· 长按/拖动手势不受影响(段控独立控件, 不在卡片上)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="phone">
|
||||
<h3>状态 3 · 长项目名</h3>
|
||||
<div class="cap">名称被压缩时单行省略, 段控与按钮永不换行/收缩</div>
|
||||
<div class="bar">
|
||||
<div class="pname">经济数据整理与策略研究-2026年第一季度重点项目</div>
|
||||
<div class="vseg"><div class="on">列表</div><div>看板</div></div>
|
||||
<div class="mini">已归档</div>
|
||||
<div class="mini ghost">管理</div>
|
||||
<div class="mini solid">+ 新增</div>
|
||||
</div>
|
||||
<div class="demo-body">
|
||||
<div class="card"><span class="dot"></span>完整项目名在详情/管理页仍可见</div>
|
||||
</div>
|
||||
<div class="anno">
|
||||
<b>宽度预算 (375px)</b><br/>
|
||||
· 左右内边距 24 + 段控 90 + 已归档 48 + 管理 42 + 新增 54 + 间距 32 ≈ 290<br/>
|
||||
· 名称可用 ≈ 85px(约 6 个汉字)起, 不足部分省略<br/>
|
||||
· 若仍嫌拥挤, 备选:「已归档」「管理」收进 ⋯ 溢出菜单(二期可选, 本稿未采用)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,103 @@
|
||||
# 0.2.1 实施方案:PostgreSQL 迁移 + 任务模块离线编辑 (PowerSync)
|
||||
|
||||
| 项 | 内容 |
|
||||
| --- | --- |
|
||||
| 分支 | `dev-0.2.1`(worktree `iboard-dev-0.2.1`,独立临时分支,与 master / dev-0.2 隔离) |
|
||||
| 日期 | 2026-10-25 |
|
||||
| 依据 | [PowerSync可行性研究报告](./PowerSync可行性研究报告.md),按其 5.2.2 路线执行 |
|
||||
| 目标 | 在现网应用与数据不受影响的前提下,验证任务模块离线编辑 + 联网后自动双向同步;数据库由 MariaDB 迁移至 PostgreSQL |
|
||||
|
||||
## 1. 已确认决策(2026-10-25 与需求方对齐)
|
||||
|
||||
| 决策点 | 结论 |
|
||||
| --- | --- |
|
||||
| 技术路线 | PowerSync 全链路(自部署 powersync-service) |
|
||||
| 离线范围 | 仅任务模块(Project / ProjectMember / BoardColumn / Task / TaskMember / TaskTag);打卡、清单本阶段不纳入;新闻/指标/监控等时序域仅做普通缓存 |
|
||||
| 客户端 | 先 Web / Windows 外壳(WebView2)跑通全链路;Android 真机后续验证 |
|
||||
| 编号 | 项目短前缀由用户自拟(2~8 位,全局唯一);任务号 = 项目内自增整数,展示 `前缀-序号`;编号由服务端统一分配,离线创建的任务在同步定号前显示临时标识 |
|
||||
| 初始数据 | 从现网 MariaDB 只读快照导出并转换导入新 PG;0.2.1 期间产生的新数据不回写现网 |
|
||||
| 端口 | Web/API 13001、PowerSync WebSocket 13002、PG 仅容器内网(调试绑 127.0.0.1:15432) |
|
||||
| 部署 | 源码上传 baihu `/app/iboard-0.2.1`,服务器上 `docker compose build`;不使用原 CI/CD |
|
||||
| 现网保护 | `/app/iboard`、宿主 3306 MySQL、3001 端口、原 CI/CD 一律不使用(快照导出仅 SELECT) |
|
||||
| 磁盘 | 允许在 baihu 执行 docker 悬空镜像/构建缓存的安全清理(磁盘仅剩 9.9G) |
|
||||
|
||||
## 2. 目标架构
|
||||
|
||||
```
|
||||
[Web / Tauri WebView2]
|
||||
React + @powersync/react
|
||||
本地 WASM SQLite (OPFS 持久化)
|
||||
│ 离线: 直接读写本地库; 写操作进入 upload queue
|
||||
│ 联网: 批量 POST 上行到 Express API (按 uuid 幂等 upsert)
|
||||
▼
|
||||
[iboard-0.2.1 Express :13001] ── Prisma (adapter-pg) ──┐
|
||||
+ /api/powersync/token (为登录用户签发同步 JWT) ▼
|
||||
[PostgreSQL 容器] (wal_level=logical)
|
||||
▲ 逻辑复制 (publication + replication slot)
|
||||
[powersync-service :13002] ── Sync Rules: 任务域 6 表 + User 只读引用, 按 ProjectMember 过滤
|
||||
```
|
||||
|
||||
- 写路径:客户端本地写 → upload queue → 上行 API → Prisma 写 PG → 逻辑复制捕获 → 广播各端;
|
||||
- 读路径:任务模块页面全部改读本地 SQLite(@powersync/react 响应式查询),其余页面维持 axios REST;
|
||||
- 认证:复用现有 jsonwebtoken 体系,新增 `/api/powersync/token` 签发 PowerSync 校验的 JWT。
|
||||
|
||||
## 3. 数据模型改造(原则:只增不改)
|
||||
|
||||
采用报告 3.2 中的「新增 uuid 列 + 应用层幂等 upsert」选项,不做全表主键 UUID 化:外键关系全部保留,存量数据迁移风险最小。
|
||||
|
||||
- 任务域 6 表各加 `uuid varchar(36) unique`(客户端创建时生成;存量行导入时回填);
|
||||
- `Project` 加 `code varchar(8) unique`(用户自拟短前缀;存量项目导入时回填自动码,后续可改);
|
||||
- `Task` 加 `number int`,`@@unique([projectId, number])`(服务端按项目 max+1 分配;离线创建的任务上行时定号,本地未定号行显示临时标识);
|
||||
- 主键仍为自增 Int,业务外键不动;客户端上行一律以 uuid 引用父子行,服务端解析为内部 id;
|
||||
- Prisma datasource: `mysql` → `postgresql`;本分支重建基线迁移(旧 MySQL 迁移文件移除,历史保留在 git)。
|
||||
|
||||
### 3.1 Sequential ID Mapping(落地时按官方模式补充)
|
||||
|
||||
按 PowerSync 官方 [Sequential ID Mapping](https://docs.powersync.com/client-sdks/advanced/sequential-id-mapping) 模式实施,解决"离线新建行同步回填后本地 id 变化"问题:
|
||||
|
||||
- 任务域 6 表再加**外键 uuid 镜像列**(`Task.projectUuid/columnUuid/parentUuid`、`BoardColumn.projectUuid`、`ProjectMember.projectUuid`、`TaskMember/TaskTag.taskUuid`),由 **PG 触发器**在写入时按 int 外键自动回填(迁移 `20261026010000_uuid_fk_mapping`),库级 NOT NULL;
|
||||
- Sync Streams 以 **`uuid` 作为客户端主键**(`SELECT "uuid" AS "id"`),镜像列别名输出回 `projectId/columnId/parentId/taskId` —— 客户端 schema 与页面代码**零改动**;
|
||||
- 服务端 upload 处理器按 uuid 解析父行(`findUnique({ where: { uuid } })`),解析后再写 int 外键 → 触发器回填镜像,两侧闭环一致;
|
||||
- 镜像列在 Prisma 模型中声明为可空(触发器保证库级非空),避免 create 校验拦截。
|
||||
|
||||
## 4. 同步与冲突
|
||||
|
||||
- Sync Rules 仅下发任务域 6 表 + `User`(展示名称/头像用),按 `ProjectMember.userId = auth.parameters.userId` 过滤项目可见性;时序/监控/米家等表不纳入;
|
||||
- 上行:`POST /api/powersync/upload` 批处理客户端 CRUD 操作,按 uuid 幂等 upsert,更新时以服务端时间戳做 LWW 仲裁;
|
||||
- 冲突:字段级 LWW 为主;`BoardColumn.sortOrder` / `Task.sortOrder` 由服务端重排仲裁;并发唯一冲突(项目前缀、看板列名)返回明确错误,客户端提示重试;
|
||||
- `Task.number` / `Project.code` 由服务端唯一分配,多端并发下天然无冲突。
|
||||
|
||||
## 5. 部署拓扑(baihu `/app/iboard-0.2.1`)
|
||||
|
||||
docker compose 三服务:
|
||||
|
||||
| 服务 | 镜像 | 端口 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `pg-021` | postgres:16-alpine | 仅容器内网 | `wal_level=logical`;数据卷 `./data/pg` |
|
||||
| `powersync-021` | powersync 官方镜像 | 13002 对外 | 连接 PG 逻辑复制 + WebSocket 下发 |
|
||||
| `app-021` | 本仓库 Dockerfile 构建 | 13001 对外 | `OTA_PUBLIC_BASE=http://bh.vps.honor3:13001` |
|
||||
|
||||
- 环境变量由 compose 注入:`DATABASE_URL`(指向 pg-021)、`JWT_SECRET`(0.2.1 独立新设)、`PORT=13001`;
|
||||
- 0.2.1 容器内 cron/米家调度预计无凭证或产生重复外呼,部署时以环境开关关闭(实现于 M4)。
|
||||
|
||||
## 6. 数据迁移(一次性)
|
||||
|
||||
1. 在 baihu 上用仓库自带 `mariadb` 驱动以只读 SQL 从宿主 MySQL(3306) 导出全表 JSON(仅 SELECT);
|
||||
2. 转换:回填 uuid / `Project.code`(按名称自动生成,可后改)/ `Task.number`(按项目内 createdAt 顺序);时间字段转 PG 时间戳;
|
||||
3. PG 侧先 `prisma migrate deploy` 建基线表,再执行 ETL 写入;
|
||||
4. 校验:逐表行数比对 + 抽样字段比对,输出核对报告。
|
||||
|
||||
## 7. 里程碑
|
||||
|
||||
1. **M1** schema/适配层切 PG(本提交):schema 字段、db.js 适配器、基线迁移重建、本地 `prisma generate` 通过;
|
||||
2. **M2** 服务端:powersync token 端点、upload 幂等上行端点、任务域路由幂等化与编号分配逻辑;
|
||||
3. **M3** 前端:任务模块数据层切 PowerSync(本地库 + useQuery + 上传队列),桌面端联调;
|
||||
4. **M4** compose 编排 + ETL 导数 + baihu 部署,端口/现网隔离验证;
|
||||
5. **M5** 离线-联网闭环验证(断网编辑 → 恢复自动同步 → 多端一致),Android 真机评估。
|
||||
|
||||
## 8. 开放问题 / 风险
|
||||
|
||||
- powersync-service 的元数据存储(bucket storage)对 MongoDB 的依赖需在部署阶段核实;若当前版本不支持用 PG 存元数据,则加一个 mongo 容器;
|
||||
- Android System WebView 的 OPFS/WASM SQLite 兼容性(M5 评估,先桌面);
|
||||
- 项目前缀全局唯一在多端并发下的冲突提示体验(上行返回结构化错误码);
|
||||
- 0.2.1 验证期数据与现网彻底隔离,不回迁;若验证后需并回主线,另行决策迁移口径。
|
||||
@@ -132,3 +132,33 @@ export type CheckListItem = Prisma.CheckListItemModel
|
||||
*
|
||||
*/
|
||||
export type CheckListTemplate = Prisma.CheckListTemplateModel
|
||||
/**
|
||||
* Model Project
|
||||
*
|
||||
*/
|
||||
export type Project = Prisma.ProjectModel
|
||||
/**
|
||||
* Model ProjectMember
|
||||
*
|
||||
*/
|
||||
export type ProjectMember = Prisma.ProjectMemberModel
|
||||
/**
|
||||
* Model BoardColumn
|
||||
*
|
||||
*/
|
||||
export type BoardColumn = Prisma.BoardColumnModel
|
||||
/**
|
||||
* Model Task
|
||||
*
|
||||
*/
|
||||
export type Task = Prisma.TaskModel
|
||||
/**
|
||||
* Model TaskMember
|
||||
*
|
||||
*/
|
||||
export type TaskMember = Prisma.TaskMemberModel
|
||||
/**
|
||||
* Model TaskTag
|
||||
*
|
||||
*/
|
||||
export type TaskTag = Prisma.TaskTagModel
|
||||
|
||||
@@ -156,3 +156,33 @@ export type CheckListItem = Prisma.CheckListItemModel
|
||||
*
|
||||
*/
|
||||
export type CheckListTemplate = Prisma.CheckListTemplateModel
|
||||
/**
|
||||
* Model Project
|
||||
*
|
||||
*/
|
||||
export type Project = Prisma.ProjectModel
|
||||
/**
|
||||
* Model ProjectMember
|
||||
*
|
||||
*/
|
||||
export type ProjectMember = Prisma.ProjectMemberModel
|
||||
/**
|
||||
* Model BoardColumn
|
||||
*
|
||||
*/
|
||||
export type BoardColumn = Prisma.BoardColumnModel
|
||||
/**
|
||||
* Model Task
|
||||
*
|
||||
*/
|
||||
export type Task = Prisma.TaskModel
|
||||
/**
|
||||
* Model TaskMember
|
||||
*
|
||||
*/
|
||||
export type TaskMember = Prisma.TaskMemberModel
|
||||
/**
|
||||
* Model TaskTag
|
||||
*
|
||||
*/
|
||||
export type TaskTag = Prisma.TaskTagModel
|
||||
|
||||
@@ -16,8 +16,8 @@ import type * as Prisma from "./internal/prismaNamespace.ts"
|
||||
|
||||
export type IntFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -27,8 +27,8 @@ export type IntFilter<$PrismaModel = never> = {
|
||||
|
||||
export type StringFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
in?: string[]
|
||||
notIn?: string[]
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -36,14 +36,14 @@ export type StringFilter<$PrismaModel = never> = {
|
||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
search?: string
|
||||
mode?: Prisma.QueryMode
|
||||
not?: Prisma.NestedStringFilter<$PrismaModel> | string
|
||||
}
|
||||
|
||||
export type DateTimeFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
in?: Date[] | string[]
|
||||
notIn?: Date[] | string[]
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -53,8 +53,8 @@ export type DateTimeFilter<$PrismaModel = never> = {
|
||||
|
||||
export type IntWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -69,8 +69,8 @@ export type IntWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type StringWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
in?: string[]
|
||||
notIn?: string[]
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -78,7 +78,7 @@ export type StringWithAggregatesFilter<$PrismaModel = never> = {
|
||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
search?: string
|
||||
mode?: Prisma.QueryMode
|
||||
not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedStringFilter<$PrismaModel>
|
||||
@@ -87,8 +87,8 @@ export type StringWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type DateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
in?: Date[] | string[]
|
||||
notIn?: Date[] | string[]
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -108,7 +108,7 @@ export type JsonFilter<$PrismaModel = never> =
|
||||
|
||||
export type JsonFilterBase<$PrismaModel = never> = {
|
||||
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||
path?: string
|
||||
path?: string[]
|
||||
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -116,10 +116,10 @@ export type JsonFilterBase<$PrismaModel = never> = {
|
||||
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
lt?: runtime.InputJsonValue
|
||||
lte?: runtime.InputJsonValue
|
||||
gt?: runtime.InputJsonValue
|
||||
gte?: runtime.InputJsonValue
|
||||
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ export type JsonWithAggregatesFilter<$PrismaModel = never> =
|
||||
|
||||
export type JsonWithAggregatesFilterBase<$PrismaModel = never> = {
|
||||
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||
path?: string
|
||||
path?: string[]
|
||||
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -140,10 +140,10 @@ export type JsonWithAggregatesFilterBase<$PrismaModel = never> = {
|
||||
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
lt?: runtime.InputJsonValue
|
||||
lte?: runtime.InputJsonValue
|
||||
gt?: runtime.InputJsonValue
|
||||
gte?: runtime.InputJsonValue
|
||||
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedJsonFilter<$PrismaModel>
|
||||
@@ -165,8 +165,8 @@ export type BoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type FloatFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
||||
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
@@ -176,8 +176,8 @@ export type FloatFilter<$PrismaModel = never> = {
|
||||
|
||||
export type FloatWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
||||
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
@@ -192,8 +192,8 @@ export type FloatWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type StringNullableFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||
in?: string[] | null
|
||||
notIn?: string[] | null
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -201,7 +201,7 @@ export type StringNullableFilter<$PrismaModel = never> = {
|
||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
search?: string
|
||||
mode?: Prisma.QueryMode
|
||||
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
|
||||
}
|
||||
|
||||
@@ -212,8 +212,8 @@ export type SortOrderInput = {
|
||||
|
||||
export type StringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||
in?: string[] | null
|
||||
notIn?: string[] | null
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -221,7 +221,7 @@ export type StringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
search?: string
|
||||
mode?: Prisma.QueryMode
|
||||
not?: Prisma.NestedStringNullableWithAggregatesFilter<$PrismaModel> | string | null
|
||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedStringNullableFilter<$PrismaModel>
|
||||
@@ -230,8 +230,8 @@ export type StringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type BigIntFilter<$PrismaModel = never> = {
|
||||
equals?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
in?: bigint[] | number[]
|
||||
notIn?: bigint[] | number[]
|
||||
in?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
||||
notIn?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
||||
lt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
lte?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
gt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
@@ -241,8 +241,8 @@ export type BigIntFilter<$PrismaModel = never> = {
|
||||
|
||||
export type BigIntWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
in?: bigint[] | number[]
|
||||
notIn?: bigint[] | number[]
|
||||
in?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
||||
notIn?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
||||
lt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
lte?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
gt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
@@ -264,7 +264,7 @@ export type JsonNullableFilter<$PrismaModel = never> =
|
||||
|
||||
export type JsonNullableFilterBase<$PrismaModel = never> = {
|
||||
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||
path?: string
|
||||
path?: string[]
|
||||
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -272,10 +272,10 @@ export type JsonNullableFilterBase<$PrismaModel = never> = {
|
||||
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
lt?: runtime.InputJsonValue
|
||||
lte?: runtime.InputJsonValue
|
||||
gt?: runtime.InputJsonValue
|
||||
gte?: runtime.InputJsonValue
|
||||
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ export type JsonNullableWithAggregatesFilter<$PrismaModel = never> =
|
||||
|
||||
export type JsonNullableWithAggregatesFilterBase<$PrismaModel = never> = {
|
||||
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||
path?: string
|
||||
path?: string[]
|
||||
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -296,10 +296,10 @@ export type JsonNullableWithAggregatesFilterBase<$PrismaModel = never> = {
|
||||
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
lt?: runtime.InputJsonValue
|
||||
lte?: runtime.InputJsonValue
|
||||
gt?: runtime.InputJsonValue
|
||||
gte?: runtime.InputJsonValue
|
||||
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedJsonNullableFilter<$PrismaModel>
|
||||
@@ -308,8 +308,8 @@ export type JsonNullableWithAggregatesFilterBase<$PrismaModel = never> = {
|
||||
|
||||
export type IntNullableFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -319,8 +319,8 @@ export type IntNullableFilter<$PrismaModel = never> = {
|
||||
|
||||
export type DateTimeNullableFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
||||
in?: Date[] | string[] | null
|
||||
notIn?: Date[] | string[] | null
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -330,8 +330,8 @@ export type DateTimeNullableFilter<$PrismaModel = never> = {
|
||||
|
||||
export type IntNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -346,8 +346,8 @@ export type IntNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type DateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
||||
in?: Date[] | string[] | null
|
||||
notIn?: Date[] | string[] | null
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -360,8 +360,8 @@ export type DateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type FloatNullableFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null
|
||||
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
@@ -371,8 +371,8 @@ export type FloatNullableFilter<$PrismaModel = never> = {
|
||||
|
||||
export type FloatNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null
|
||||
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
@@ -387,8 +387,8 @@ export type FloatNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedIntFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -398,8 +398,8 @@ export type NestedIntFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedStringFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
in?: string[]
|
||||
notIn?: string[]
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -407,14 +407,13 @@ export type NestedStringFilter<$PrismaModel = never> = {
|
||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
search?: string
|
||||
not?: Prisma.NestedStringFilter<$PrismaModel> | string
|
||||
}
|
||||
|
||||
export type NestedDateTimeFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
in?: Date[] | string[]
|
||||
notIn?: Date[] | string[]
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -424,8 +423,8 @@ export type NestedDateTimeFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedIntWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -440,8 +439,8 @@ export type NestedIntWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedFloatFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
||||
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
@@ -451,8 +450,8 @@ export type NestedFloatFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedStringWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
in?: string[]
|
||||
notIn?: string[]
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -460,7 +459,6 @@ export type NestedStringWithAggregatesFilter<$PrismaModel = never> = {
|
||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
search?: string
|
||||
not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedStringFilter<$PrismaModel>
|
||||
@@ -469,8 +467,8 @@ export type NestedStringWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedDateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
in?: Date[] | string[]
|
||||
notIn?: Date[] | string[]
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -490,7 +488,7 @@ export type NestedJsonFilter<$PrismaModel = never> =
|
||||
|
||||
export type NestedJsonFilterBase<$PrismaModel = never> = {
|
||||
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||
path?: string
|
||||
path?: string[]
|
||||
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -498,10 +496,10 @@ export type NestedJsonFilterBase<$PrismaModel = never> = {
|
||||
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
lt?: runtime.InputJsonValue
|
||||
lte?: runtime.InputJsonValue
|
||||
gt?: runtime.InputJsonValue
|
||||
gte?: runtime.InputJsonValue
|
||||
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||
}
|
||||
|
||||
@@ -520,8 +518,8 @@ export type NestedBoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedFloatWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
||||
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
@@ -536,8 +534,8 @@ export type NestedFloatWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedStringNullableFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||
in?: string[] | null
|
||||
notIn?: string[] | null
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -545,14 +543,13 @@ export type NestedStringNullableFilter<$PrismaModel = never> = {
|
||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
search?: string
|
||||
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
|
||||
}
|
||||
|
||||
export type NestedStringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||
in?: string[] | null
|
||||
notIn?: string[] | null
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -560,7 +557,6 @@ export type NestedStringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
search?: string
|
||||
not?: Prisma.NestedStringNullableWithAggregatesFilter<$PrismaModel> | string | null
|
||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedStringNullableFilter<$PrismaModel>
|
||||
@@ -569,8 +565,8 @@ export type NestedStringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedIntNullableFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -580,8 +576,8 @@ export type NestedIntNullableFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedBigIntFilter<$PrismaModel = never> = {
|
||||
equals?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
in?: bigint[] | number[]
|
||||
notIn?: bigint[] | number[]
|
||||
in?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
||||
notIn?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
||||
lt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
lte?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
gt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
@@ -591,8 +587,8 @@ export type NestedBigIntFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedBigIntWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
in?: bigint[] | number[]
|
||||
notIn?: bigint[] | number[]
|
||||
in?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
||||
notIn?: bigint[] | number[] | Prisma.ListBigIntFieldRefInput<$PrismaModel>
|
||||
lt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
lte?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
gt?: bigint | number | Prisma.BigIntFieldRefInput<$PrismaModel>
|
||||
@@ -614,7 +610,7 @@ export type NestedJsonNullableFilter<$PrismaModel = never> =
|
||||
|
||||
export type NestedJsonNullableFilterBase<$PrismaModel = never> = {
|
||||
equals?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||
path?: string
|
||||
path?: string[]
|
||||
mode?: Prisma.QueryMode | Prisma.EnumQueryModeFieldRefInput<$PrismaModel>
|
||||
string_contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
string_starts_with?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -622,17 +618,17 @@ export type NestedJsonNullableFilterBase<$PrismaModel = never> = {
|
||||
array_starts_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
array_ends_with?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
array_contains?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | null
|
||||
lt?: runtime.InputJsonValue
|
||||
lte?: runtime.InputJsonValue
|
||||
gt?: runtime.InputJsonValue
|
||||
gte?: runtime.InputJsonValue
|
||||
lt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
lte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
gt?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
gte?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel>
|
||||
not?: runtime.InputJsonValue | Prisma.JsonFieldRefInput<$PrismaModel> | Prisma.JsonNullValueFilter
|
||||
}
|
||||
|
||||
export type NestedDateTimeNullableFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
||||
in?: Date[] | string[] | null
|
||||
notIn?: Date[] | string[] | null
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -642,8 +638,8 @@ export type NestedDateTimeNullableFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedIntNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -658,8 +654,8 @@ export type NestedIntNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedFloatNullableFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null
|
||||
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
@@ -669,8 +665,8 @@ export type NestedFloatNullableFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedDateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
||||
in?: Date[] | string[] | null
|
||||
notIn?: Date[] | string[] | null
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -683,8 +679,8 @@ export type NestedDateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedFloatNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null
|
||||
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -73,7 +73,13 @@ export const ModelName = {
|
||||
CheckIn: 'CheckIn',
|
||||
CheckList: 'CheckList',
|
||||
CheckListItem: 'CheckListItem',
|
||||
CheckListTemplate: 'CheckListTemplate'
|
||||
CheckListTemplate: 'CheckListTemplate',
|
||||
Project: 'Project',
|
||||
ProjectMember: 'ProjectMember',
|
||||
BoardColumn: 'BoardColumn',
|
||||
Task: 'Task',
|
||||
TaskMember: 'TaskMember',
|
||||
TaskTag: 'TaskTag'
|
||||
} as const
|
||||
|
||||
export type ModelName = (typeof ModelName)[keyof typeof ModelName]
|
||||
@@ -443,6 +449,106 @@ export const CheckListTemplateScalarFieldEnum = {
|
||||
export type CheckListTemplateScalarFieldEnum = (typeof CheckListTemplateScalarFieldEnum)[keyof typeof CheckListTemplateScalarFieldEnum]
|
||||
|
||||
|
||||
export const ProjectScalarFieldEnum = {
|
||||
id: 'id',
|
||||
uuid: 'uuid',
|
||||
code: 'code',
|
||||
name: 'name',
|
||||
ownerId: 'ownerId',
|
||||
isPersonal: 'isPersonal',
|
||||
archived: 'archived',
|
||||
notes: 'notes',
|
||||
taskKinds: 'taskKinds',
|
||||
icon: 'icon',
|
||||
autoArchive: 'autoArchive',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
} as const
|
||||
|
||||
export type ProjectScalarFieldEnum = (typeof ProjectScalarFieldEnum)[keyof typeof ProjectScalarFieldEnum]
|
||||
|
||||
|
||||
export const ProjectMemberScalarFieldEnum = {
|
||||
id: 'id',
|
||||
uuid: 'uuid',
|
||||
projectUuid: 'projectUuid',
|
||||
projectId: 'projectId',
|
||||
userId: 'userId',
|
||||
permission: 'permission',
|
||||
createdAt: 'createdAt'
|
||||
} as const
|
||||
|
||||
export type ProjectMemberScalarFieldEnum = (typeof ProjectMemberScalarFieldEnum)[keyof typeof ProjectMemberScalarFieldEnum]
|
||||
|
||||
|
||||
export const BoardColumnScalarFieldEnum = {
|
||||
id: 'id',
|
||||
uuid: 'uuid',
|
||||
projectUuid: 'projectUuid',
|
||||
projectId: 'projectId',
|
||||
name: 'name',
|
||||
sortOrder: 'sortOrder',
|
||||
boundStatus: 'boundStatus',
|
||||
retention: 'retention',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
} as const
|
||||
|
||||
export type BoardColumnScalarFieldEnum = (typeof BoardColumnScalarFieldEnum)[keyof typeof BoardColumnScalarFieldEnum]
|
||||
|
||||
|
||||
export const TaskScalarFieldEnum = {
|
||||
id: 'id',
|
||||
uuid: 'uuid',
|
||||
projectUuid: 'projectUuid',
|
||||
columnUuid: 'columnUuid',
|
||||
parentUuid: 'parentUuid',
|
||||
projectId: 'projectId',
|
||||
columnId: 'columnId',
|
||||
parentId: 'parentId',
|
||||
title: 'title',
|
||||
description: 'description',
|
||||
kind: 'kind',
|
||||
markDate: 'markDate',
|
||||
status: 'status',
|
||||
doneAt: 'doneAt',
|
||||
assigneeId: 'assigneeId',
|
||||
creatorId: 'creatorId',
|
||||
extras: 'extras',
|
||||
sortOrder: 'sortOrder',
|
||||
archived: 'archived',
|
||||
archivedAt: 'archivedAt',
|
||||
archiveSource: 'archiveSource',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt',
|
||||
number: 'number'
|
||||
} as const
|
||||
|
||||
export type TaskScalarFieldEnum = (typeof TaskScalarFieldEnum)[keyof typeof TaskScalarFieldEnum]
|
||||
|
||||
|
||||
export const TaskMemberScalarFieldEnum = {
|
||||
id: 'id',
|
||||
uuid: 'uuid',
|
||||
taskUuid: 'taskUuid',
|
||||
taskId: 'taskId',
|
||||
userId: 'userId'
|
||||
} as const
|
||||
|
||||
export type TaskMemberScalarFieldEnum = (typeof TaskMemberScalarFieldEnum)[keyof typeof TaskMemberScalarFieldEnum]
|
||||
|
||||
|
||||
export const TaskTagScalarFieldEnum = {
|
||||
id: 'id',
|
||||
uuid: 'uuid',
|
||||
taskUuid: 'taskUuid',
|
||||
taskId: 'taskId',
|
||||
name: 'name'
|
||||
} as const
|
||||
|
||||
export type TaskTagScalarFieldEnum = (typeof TaskTagScalarFieldEnum)[keyof typeof TaskTagScalarFieldEnum]
|
||||
|
||||
|
||||
export const SortOrder = {
|
||||
asc: 'asc',
|
||||
desc: 'desc'
|
||||
@@ -466,23 +572,12 @@ export const NullableJsonNullValueInput = {
|
||||
export type NullableJsonNullValueInput = (typeof NullableJsonNullValueInput)[keyof typeof NullableJsonNullValueInput]
|
||||
|
||||
|
||||
export const UserOrderByRelevanceFieldEnum = {
|
||||
name: 'name',
|
||||
email: 'email',
|
||||
password: 'password'
|
||||
export const QueryMode = {
|
||||
default: 'default',
|
||||
insensitive: 'insensitive'
|
||||
} as const
|
||||
|
||||
export type UserOrderByRelevanceFieldEnum = (typeof UserOrderByRelevanceFieldEnum)[keyof typeof UserOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const ArticleOrderByRelevanceFieldEnum = {
|
||||
title: 'title',
|
||||
slug: 'slug',
|
||||
content: 'content',
|
||||
date: 'date'
|
||||
} as const
|
||||
|
||||
export type ArticleOrderByRelevanceFieldEnum = (typeof ArticleOrderByRelevanceFieldEnum)[keyof typeof ArticleOrderByRelevanceFieldEnum]
|
||||
export type QueryMode = (typeof QueryMode)[keyof typeof QueryMode]
|
||||
|
||||
|
||||
export const JsonNullValueFilter = {
|
||||
@@ -494,41 +589,6 @@ export const JsonNullValueFilter = {
|
||||
export type JsonNullValueFilter = (typeof JsonNullValueFilter)[keyof typeof JsonNullValueFilter]
|
||||
|
||||
|
||||
export const QueryMode = {
|
||||
default: 'default',
|
||||
insensitive: 'insensitive'
|
||||
} as const
|
||||
|
||||
export type QueryMode = (typeof QueryMode)[keyof typeof QueryMode]
|
||||
|
||||
|
||||
export const StrategyOrderByRelevanceFieldEnum = {
|
||||
name: 'name',
|
||||
description: 'description'
|
||||
} as const
|
||||
|
||||
export type StrategyOrderByRelevanceFieldEnum = (typeof StrategyOrderByRelevanceFieldEnum)[keyof typeof StrategyOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const IndicatorOrderByRelevanceFieldEnum = {
|
||||
name: 'name',
|
||||
groupName: 'groupName',
|
||||
title: 'title',
|
||||
unit: 'unit',
|
||||
source: 'source',
|
||||
frequency: 'frequency'
|
||||
} as const
|
||||
|
||||
export type IndicatorOrderByRelevanceFieldEnum = (typeof IndicatorOrderByRelevanceFieldEnum)[keyof typeof IndicatorOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const IndicatorPointOrderByRelevanceFieldEnum = {
|
||||
period: 'period'
|
||||
} as const
|
||||
|
||||
export type IndicatorPointOrderByRelevanceFieldEnum = (typeof IndicatorPointOrderByRelevanceFieldEnum)[keyof typeof IndicatorPointOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const NullsOrder = {
|
||||
first: 'first',
|
||||
last: 'last'
|
||||
@@ -536,158 +596,3 @@ export const NullsOrder = {
|
||||
|
||||
export type NullsOrder = (typeof NullsOrder)[keyof typeof NullsOrder]
|
||||
|
||||
|
||||
export const NewsOrderByRelevanceFieldEnum = {
|
||||
title: 'title',
|
||||
summary: 'summary',
|
||||
content: 'content',
|
||||
source: 'source',
|
||||
url: 'url'
|
||||
} as const
|
||||
|
||||
export type NewsOrderByRelevanceFieldEnum = (typeof NewsOrderByRelevanceFieldEnum)[keyof typeof NewsOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const AlertOrderByRelevanceFieldEnum = {
|
||||
indicatorName: 'indicatorName',
|
||||
period: 'period',
|
||||
sourceA: 'sourceA',
|
||||
sourceB: 'sourceB'
|
||||
} as const
|
||||
|
||||
export type AlertOrderByRelevanceFieldEnum = (typeof AlertOrderByRelevanceFieldEnum)[keyof typeof AlertOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const ServerNodeOrderByRelevanceFieldEnum = {
|
||||
uuid: 'uuid',
|
||||
name: 'name',
|
||||
cpuName: 'cpuName',
|
||||
os: 'os',
|
||||
region: 'region',
|
||||
status: 'status'
|
||||
} as const
|
||||
|
||||
export type ServerNodeOrderByRelevanceFieldEnum = (typeof ServerNodeOrderByRelevanceFieldEnum)[keyof typeof ServerNodeOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const ServerNodeHistoryOrderByRelevanceFieldEnum = {
|
||||
uuid: 'uuid'
|
||||
} as const
|
||||
|
||||
export type ServerNodeHistoryOrderByRelevanceFieldEnum = (typeof ServerNodeHistoryOrderByRelevanceFieldEnum)[keyof typeof ServerNodeHistoryOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const ServiceCheckOrderByRelevanceFieldEnum = {
|
||||
name: 'name',
|
||||
url: 'url',
|
||||
status: 'status',
|
||||
message: 'message'
|
||||
} as const
|
||||
|
||||
export type ServiceCheckOrderByRelevanceFieldEnum = (typeof ServiceCheckOrderByRelevanceFieldEnum)[keyof typeof ServiceCheckOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const Econ_SowInventoryOrderByRelevanceFieldEnum = {
|
||||
month: 'month'
|
||||
} as const
|
||||
|
||||
export type Econ_SowInventoryOrderByRelevanceFieldEnum = (typeof Econ_SowInventoryOrderByRelevanceFieldEnum)[keyof typeof Econ_SowInventoryOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const ScraperCacheOrderByRelevanceFieldEnum = {
|
||||
scraperName: 'scraperName',
|
||||
lastDataHash: 'lastDataHash'
|
||||
} as const
|
||||
|
||||
export type ScraperCacheOrderByRelevanceFieldEnum = (typeof ScraperCacheOrderByRelevanceFieldEnum)[keyof typeof ScraperCacheOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const OilPriceHistoryOrderByRelevanceFieldEnum = {
|
||||
province: 'province',
|
||||
fuel: 'fuel',
|
||||
source: 'source'
|
||||
} as const
|
||||
|
||||
export type OilPriceHistoryOrderByRelevanceFieldEnum = (typeof OilPriceHistoryOrderByRelevanceFieldEnum)[keyof typeof OilPriceHistoryOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const MihomeAccountOrderByRelevanceFieldEnum = {
|
||||
key: 'key',
|
||||
userId: 'userId',
|
||||
status: 'status',
|
||||
lastError: 'lastError'
|
||||
} as const
|
||||
|
||||
export type MihomeAccountOrderByRelevanceFieldEnum = (typeof MihomeAccountOrderByRelevanceFieldEnum)[keyof typeof MihomeAccountOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const MihomeHomeOrderByRelevanceFieldEnum = {
|
||||
homeId: 'homeId',
|
||||
name: 'name'
|
||||
} as const
|
||||
|
||||
export type MihomeHomeOrderByRelevanceFieldEnum = (typeof MihomeHomeOrderByRelevanceFieldEnum)[keyof typeof MihomeHomeOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const MihomeDeviceOrderByRelevanceFieldEnum = {
|
||||
did: 'did',
|
||||
homeId: 'homeId',
|
||||
model: 'model',
|
||||
name: 'name',
|
||||
alias: 'alias'
|
||||
} as const
|
||||
|
||||
export type MihomeDeviceOrderByRelevanceFieldEnum = (typeof MihomeDeviceOrderByRelevanceFieldEnum)[keyof typeof MihomeDeviceOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const MihomeEnvSampleOrderByRelevanceFieldEnum = {
|
||||
origin: 'origin'
|
||||
} as const
|
||||
|
||||
export type MihomeEnvSampleOrderByRelevanceFieldEnum = (typeof MihomeEnvSampleOrderByRelevanceFieldEnum)[keyof typeof MihomeEnvSampleOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const HabitOrderByRelevanceFieldEnum = {
|
||||
name: 'name',
|
||||
period: 'period',
|
||||
color: 'color',
|
||||
icon: 'icon',
|
||||
note: 'note'
|
||||
} as const
|
||||
|
||||
export type HabitOrderByRelevanceFieldEnum = (typeof HabitOrderByRelevanceFieldEnum)[keyof typeof HabitOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const CheckInOrderByRelevanceFieldEnum = {
|
||||
date: 'date',
|
||||
note: 'note',
|
||||
source: 'source'
|
||||
} as const
|
||||
|
||||
export type CheckInOrderByRelevanceFieldEnum = (typeof CheckInOrderByRelevanceFieldEnum)[keyof typeof CheckInOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const CheckListOrderByRelevanceFieldEnum = {
|
||||
title: 'title',
|
||||
scene: 'scene',
|
||||
note: 'note'
|
||||
} as const
|
||||
|
||||
export type CheckListOrderByRelevanceFieldEnum = (typeof CheckListOrderByRelevanceFieldEnum)[keyof typeof CheckListOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const CheckListItemOrderByRelevanceFieldEnum = {
|
||||
title: 'title',
|
||||
note: 'note'
|
||||
} as const
|
||||
|
||||
export type CheckListItemOrderByRelevanceFieldEnum = (typeof CheckListItemOrderByRelevanceFieldEnum)[keyof typeof CheckListItemOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const CheckListTemplateOrderByRelevanceFieldEnum = {
|
||||
name: 'name',
|
||||
scene: 'scene'
|
||||
} as const
|
||||
|
||||
export type CheckListTemplateOrderByRelevanceFieldEnum = (typeof CheckListTemplateOrderByRelevanceFieldEnum)[keyof typeof CheckListTemplateOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
@@ -31,4 +31,10 @@ export type * from './models/CheckIn.ts'
|
||||
export type * from './models/CheckList.ts'
|
||||
export type * from './models/CheckListItem.ts'
|
||||
export type * from './models/CheckListTemplate.ts'
|
||||
export type * from './models/Project.ts'
|
||||
export type * from './models/ProjectMember.ts'
|
||||
export type * from './models/BoardColumn.ts'
|
||||
export type * from './models/Task.ts'
|
||||
export type * from './models/TaskMember.ts'
|
||||
export type * from './models/TaskTag.ts'
|
||||
export type * from './commonInputTypes.ts'
|
||||
@@ -285,7 +285,6 @@ export type AlertOrderByWithRelationInput = {
|
||||
diff?: Prisma.SortOrder
|
||||
diffRatio?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
_relevance?: Prisma.AlertOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type AlertWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -426,12 +425,6 @@ export type AlertUncheckedUpdateManyInput = {
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type AlertOrderByRelevanceInput = {
|
||||
fields: Prisma.AlertOrderByRelevanceFieldEnum | Prisma.AlertOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type AlertCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
indicatorName?: Prisma.SortOrder
|
||||
@@ -502,7 +495,31 @@ export type AlertSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs =
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["alert"]>
|
||||
|
||||
export type AlertSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
indicatorName?: boolean
|
||||
period?: boolean
|
||||
valueA?: boolean
|
||||
valueB?: boolean
|
||||
sourceA?: boolean
|
||||
sourceB?: boolean
|
||||
diff?: boolean
|
||||
diffRatio?: boolean
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["alert"]>
|
||||
|
||||
export type AlertSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
indicatorName?: boolean
|
||||
period?: boolean
|
||||
valueA?: boolean
|
||||
valueB?: boolean
|
||||
sourceA?: boolean
|
||||
sourceB?: boolean
|
||||
diff?: boolean
|
||||
diffRatio?: boolean
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["alert"]>
|
||||
|
||||
export type AlertSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -650,6 +667,30 @@ export interface AlertDelegate<ExtArgs extends runtime.Types.Extensions.Internal
|
||||
*/
|
||||
createMany<T extends AlertCreateManyArgs>(args?: Prisma.SelectSubset<T, AlertCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many Alerts and returns the data saved in the database.
|
||||
* @param {AlertCreateManyAndReturnArgs} args - Arguments to create many Alerts.
|
||||
* @example
|
||||
* // Create many Alerts
|
||||
* const alert = await prisma.alert.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many Alerts and only return the `id`
|
||||
* const alertWithIdOnly = await prisma.alert.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends AlertCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, AlertCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$AlertPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a Alert.
|
||||
* @param {AlertDeleteArgs} args - Arguments to delete one Alert.
|
||||
@@ -714,6 +755,36 @@ export interface AlertDelegate<ExtArgs extends runtime.Types.Extensions.Internal
|
||||
*/
|
||||
updateMany<T extends AlertUpdateManyArgs>(args: Prisma.SelectSubset<T, AlertUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more Alerts and returns the data updated in the database.
|
||||
* @param {AlertUpdateManyAndReturnArgs} args - Arguments to update many Alerts.
|
||||
* @example
|
||||
* // Update many Alerts
|
||||
* const alert = await prisma.alert.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more Alerts and only return the `id`
|
||||
* const alertWithIdOnly = await prisma.alert.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends AlertUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, AlertUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$AlertPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one Alert.
|
||||
* @param {AlertUpsertArgs} args - Arguments to update or create a Alert.
|
||||
@@ -1125,6 +1196,25 @@ export type AlertCreateManyArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert createManyAndReturn
|
||||
*/
|
||||
export type AlertCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the Alert
|
||||
*/
|
||||
select?: Prisma.AlertSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the Alert
|
||||
*/
|
||||
omit?: Prisma.AlertOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many Alerts.
|
||||
*/
|
||||
data: Prisma.AlertCreateManyInput | Prisma.AlertCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert update
|
||||
*/
|
||||
@@ -1165,6 +1255,32 @@ export type AlertUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert updateManyAndReturn
|
||||
*/
|
||||
export type AlertUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the Alert
|
||||
*/
|
||||
select?: Prisma.AlertSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the Alert
|
||||
*/
|
||||
omit?: Prisma.AlertOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update Alerts.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.AlertUpdateManyMutationInput, Prisma.AlertUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which Alerts to update
|
||||
*/
|
||||
where?: Prisma.AlertWhereInput
|
||||
/**
|
||||
* Limit how many Alerts to update.
|
||||
*/
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert upsert
|
||||
*/
|
||||
|
||||
@@ -242,7 +242,6 @@ export type ArticleOrderByWithRelationInput = {
|
||||
date?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
_relevance?: Prisma.ArticleOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type ArticleWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -353,12 +352,6 @@ export type ArticleUncheckedUpdateManyInput = {
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type ArticleOrderByRelevanceInput = {
|
||||
fields: Prisma.ArticleOrderByRelevanceFieldEnum | Prisma.ArticleOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type ArticleCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
title?: Prisma.SortOrder
|
||||
@@ -409,7 +402,25 @@ export type ArticleSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["article"]>
|
||||
|
||||
export type ArticleSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
title?: boolean
|
||||
slug?: boolean
|
||||
content?: boolean
|
||||
date?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["article"]>
|
||||
|
||||
export type ArticleSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
title?: boolean
|
||||
slug?: boolean
|
||||
content?: boolean
|
||||
date?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["article"]>
|
||||
|
||||
export type ArticleSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -551,6 +562,30 @@ export interface ArticleDelegate<ExtArgs extends runtime.Types.Extensions.Intern
|
||||
*/
|
||||
createMany<T extends ArticleCreateManyArgs>(args?: Prisma.SelectSubset<T, ArticleCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many Articles and returns the data saved in the database.
|
||||
* @param {ArticleCreateManyAndReturnArgs} args - Arguments to create many Articles.
|
||||
* @example
|
||||
* // Create many Articles
|
||||
* const article = await prisma.article.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many Articles and only return the `id`
|
||||
* const articleWithIdOnly = await prisma.article.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends ArticleCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, ArticleCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ArticlePayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a Article.
|
||||
* @param {ArticleDeleteArgs} args - Arguments to delete one Article.
|
||||
@@ -615,6 +650,36 @@ export interface ArticleDelegate<ExtArgs extends runtime.Types.Extensions.Intern
|
||||
*/
|
||||
updateMany<T extends ArticleUpdateManyArgs>(args: Prisma.SelectSubset<T, ArticleUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more Articles and returns the data updated in the database.
|
||||
* @param {ArticleUpdateManyAndReturnArgs} args - Arguments to update many Articles.
|
||||
* @example
|
||||
* // Update many Articles
|
||||
* const article = await prisma.article.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more Articles and only return the `id`
|
||||
* const articleWithIdOnly = await prisma.article.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends ArticleUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, ArticleUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ArticlePayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one Article.
|
||||
* @param {ArticleUpsertArgs} args - Arguments to update or create a Article.
|
||||
@@ -1023,6 +1088,25 @@ export type ArticleCreateManyArgs<ExtArgs extends runtime.Types.Extensions.Inter
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Article createManyAndReturn
|
||||
*/
|
||||
export type ArticleCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the Article
|
||||
*/
|
||||
select?: Prisma.ArticleSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the Article
|
||||
*/
|
||||
omit?: Prisma.ArticleOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many Articles.
|
||||
*/
|
||||
data: Prisma.ArticleCreateManyInput | Prisma.ArticleCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Article update
|
||||
*/
|
||||
@@ -1063,6 +1147,32 @@ export type ArticleUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.Inter
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Article updateManyAndReturn
|
||||
*/
|
||||
export type ArticleUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the Article
|
||||
*/
|
||||
select?: Prisma.ArticleSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the Article
|
||||
*/
|
||||
omit?: Prisma.ArticleOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update Articles.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.ArticleUpdateManyMutationInput, Prisma.ArticleUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which Articles to update
|
||||
*/
|
||||
where?: Prisma.ArticleWhereInput
|
||||
/**
|
||||
* Limit how many Articles to update.
|
||||
*/
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Article upsert
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -267,7 +267,6 @@ export type CheckInOrderByWithRelationInput = {
|
||||
createdAt?: Prisma.SortOrder
|
||||
habit?: Prisma.HabitOrderByWithRelationInput
|
||||
user?: Prisma.UserOrderByWithRelationInput
|
||||
_relevance?: Prisma.CheckInOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type CheckInWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -399,12 +398,6 @@ export type CheckInOrderByRelationAggregateInput = {
|
||||
_count?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type CheckInOrderByRelevanceInput = {
|
||||
fields: Prisma.CheckInOrderByRelevanceFieldEnum | Prisma.CheckInOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type CheckInHabitIdDateSeqCompoundUniqueInput = {
|
||||
habitId: number
|
||||
date: string
|
||||
@@ -739,7 +732,31 @@ export type CheckInSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["checkIn"]>
|
||||
|
||||
export type CheckInSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
habitId?: boolean
|
||||
userId?: boolean
|
||||
date?: boolean
|
||||
seq?: boolean
|
||||
note?: boolean
|
||||
source?: boolean
|
||||
createdAt?: boolean
|
||||
habit?: boolean | Prisma.HabitDefaultArgs<ExtArgs>
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["checkIn"]>
|
||||
|
||||
export type CheckInSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
habitId?: boolean
|
||||
userId?: boolean
|
||||
date?: boolean
|
||||
seq?: boolean
|
||||
note?: boolean
|
||||
source?: boolean
|
||||
createdAt?: boolean
|
||||
habit?: boolean | Prisma.HabitDefaultArgs<ExtArgs>
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["checkIn"]>
|
||||
|
||||
export type CheckInSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -757,6 +774,14 @@ export type CheckInInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs
|
||||
habit?: boolean | Prisma.HabitDefaultArgs<ExtArgs>
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type CheckInIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
habit?: boolean | Prisma.HabitDefaultArgs<ExtArgs>
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type CheckInIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
habit?: boolean | Prisma.HabitDefaultArgs<ExtArgs>
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}
|
||||
|
||||
export type $CheckInPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "CheckIn"
|
||||
@@ -890,6 +915,30 @@ export interface CheckInDelegate<ExtArgs extends runtime.Types.Extensions.Intern
|
||||
*/
|
||||
createMany<T extends CheckInCreateManyArgs>(args?: Prisma.SelectSubset<T, CheckInCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many CheckIns and returns the data saved in the database.
|
||||
* @param {CheckInCreateManyAndReturnArgs} args - Arguments to create many CheckIns.
|
||||
* @example
|
||||
* // Create many CheckIns
|
||||
* const checkIn = await prisma.checkIn.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many CheckIns and only return the `id`
|
||||
* const checkInWithIdOnly = await prisma.checkIn.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends CheckInCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, CheckInCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$CheckInPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a CheckIn.
|
||||
* @param {CheckInDeleteArgs} args - Arguments to delete one CheckIn.
|
||||
@@ -954,6 +1003,36 @@ export interface CheckInDelegate<ExtArgs extends runtime.Types.Extensions.Intern
|
||||
*/
|
||||
updateMany<T extends CheckInUpdateManyArgs>(args: Prisma.SelectSubset<T, CheckInUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more CheckIns and returns the data updated in the database.
|
||||
* @param {CheckInUpdateManyAndReturnArgs} args - Arguments to update many CheckIns.
|
||||
* @example
|
||||
* // Update many CheckIns
|
||||
* const checkIn = await prisma.checkIn.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more CheckIns and only return the `id`
|
||||
* const checkInWithIdOnly = await prisma.checkIn.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends CheckInUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, CheckInUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$CheckInPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one CheckIn.
|
||||
* @param {CheckInUpsertArgs} args - Arguments to update or create a CheckIn.
|
||||
@@ -1389,6 +1468,29 @@ export type CheckInCreateManyArgs<ExtArgs extends runtime.Types.Extensions.Inter
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckIn createManyAndReturn
|
||||
*/
|
||||
export type CheckInCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the CheckIn
|
||||
*/
|
||||
select?: Prisma.CheckInSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the CheckIn
|
||||
*/
|
||||
omit?: Prisma.CheckInOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many CheckIns.
|
||||
*/
|
||||
data: Prisma.CheckInCreateManyInput | Prisma.CheckInCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.CheckInIncludeCreateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckIn update
|
||||
*/
|
||||
@@ -1433,6 +1535,36 @@ export type CheckInUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.Inter
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckIn updateManyAndReturn
|
||||
*/
|
||||
export type CheckInUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the CheckIn
|
||||
*/
|
||||
select?: Prisma.CheckInSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the CheckIn
|
||||
*/
|
||||
omit?: Prisma.CheckInOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update CheckIns.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.CheckInUpdateManyMutationInput, Prisma.CheckInUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which CheckIns to update
|
||||
*/
|
||||
where?: Prisma.CheckInWhereInput
|
||||
/**
|
||||
* Limit how many CheckIns to update.
|
||||
*/
|
||||
limit?: number
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.CheckInIncludeUpdateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckIn upsert
|
||||
*/
|
||||
|
||||
@@ -259,7 +259,6 @@ export type CheckListOrderByWithRelationInput = {
|
||||
updatedAt?: Prisma.SortOrder
|
||||
user?: Prisma.UserOrderByWithRelationInput
|
||||
items?: Prisma.CheckListItemOrderByRelationAggregateInput
|
||||
_relevance?: Prisma.CheckListOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type CheckListWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -395,12 +394,6 @@ export type CheckListOrderByRelationAggregateInput = {
|
||||
_count?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type CheckListOrderByRelevanceInput = {
|
||||
fields: Prisma.CheckListOrderByRelevanceFieldEnum | Prisma.CheckListOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type CheckListCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
userId?: Prisma.SortOrder
|
||||
@@ -710,7 +703,29 @@ export type CheckListSelect<ExtArgs extends runtime.Types.Extensions.InternalArg
|
||||
_count?: boolean | Prisma.CheckListCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["checkList"]>
|
||||
|
||||
export type CheckListSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
userId?: boolean
|
||||
title?: boolean
|
||||
scene?: boolean
|
||||
note?: boolean
|
||||
archived?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["checkList"]>
|
||||
|
||||
export type CheckListSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
userId?: boolean
|
||||
title?: boolean
|
||||
scene?: boolean
|
||||
note?: boolean
|
||||
archived?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["checkList"]>
|
||||
|
||||
export type CheckListSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -729,6 +744,12 @@ export type CheckListInclude<ExtArgs extends runtime.Types.Extensions.InternalAr
|
||||
items?: boolean | Prisma.CheckList$itemsArgs<ExtArgs>
|
||||
_count?: boolean | Prisma.CheckListCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type CheckListIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type CheckListIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}
|
||||
|
||||
export type $CheckListPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "CheckList"
|
||||
@@ -862,6 +883,30 @@ export interface CheckListDelegate<ExtArgs extends runtime.Types.Extensions.Inte
|
||||
*/
|
||||
createMany<T extends CheckListCreateManyArgs>(args?: Prisma.SelectSubset<T, CheckListCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many CheckLists and returns the data saved in the database.
|
||||
* @param {CheckListCreateManyAndReturnArgs} args - Arguments to create many CheckLists.
|
||||
* @example
|
||||
* // Create many CheckLists
|
||||
* const checkList = await prisma.checkList.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many CheckLists and only return the `id`
|
||||
* const checkListWithIdOnly = await prisma.checkList.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends CheckListCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, CheckListCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$CheckListPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a CheckList.
|
||||
* @param {CheckListDeleteArgs} args - Arguments to delete one CheckList.
|
||||
@@ -926,6 +971,36 @@ export interface CheckListDelegate<ExtArgs extends runtime.Types.Extensions.Inte
|
||||
*/
|
||||
updateMany<T extends CheckListUpdateManyArgs>(args: Prisma.SelectSubset<T, CheckListUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more CheckLists and returns the data updated in the database.
|
||||
* @param {CheckListUpdateManyAndReturnArgs} args - Arguments to update many CheckLists.
|
||||
* @example
|
||||
* // Update many CheckLists
|
||||
* const checkList = await prisma.checkList.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more CheckLists and only return the `id`
|
||||
* const checkListWithIdOnly = await prisma.checkList.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends CheckListUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, CheckListUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$CheckListPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one CheckList.
|
||||
* @param {CheckListUpsertArgs} args - Arguments to update or create a CheckList.
|
||||
@@ -1361,6 +1436,29 @@ export type CheckListCreateManyArgs<ExtArgs extends runtime.Types.Extensions.Int
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckList createManyAndReturn
|
||||
*/
|
||||
export type CheckListCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the CheckList
|
||||
*/
|
||||
select?: Prisma.CheckListSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the CheckList
|
||||
*/
|
||||
omit?: Prisma.CheckListOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many CheckLists.
|
||||
*/
|
||||
data: Prisma.CheckListCreateManyInput | Prisma.CheckListCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.CheckListIncludeCreateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckList update
|
||||
*/
|
||||
@@ -1405,6 +1503,36 @@ export type CheckListUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.Int
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckList updateManyAndReturn
|
||||
*/
|
||||
export type CheckListUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the CheckList
|
||||
*/
|
||||
select?: Prisma.CheckListSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the CheckList
|
||||
*/
|
||||
omit?: Prisma.CheckListOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update CheckLists.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.CheckListUpdateManyMutationInput, Prisma.CheckListUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which CheckLists to update
|
||||
*/
|
||||
where?: Prisma.CheckListWhereInput
|
||||
/**
|
||||
* Limit how many CheckLists to update.
|
||||
*/
|
||||
limit?: number
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.CheckListIncludeUpdateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckList upsert
|
||||
*/
|
||||
|
||||
@@ -270,7 +270,6 @@ export type CheckListItemOrderByWithRelationInput = {
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
list?: Prisma.CheckListOrderByWithRelationInput
|
||||
_relevance?: Prisma.CheckListItemOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type CheckListItemWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -411,12 +410,6 @@ export type CheckListItemOrderByRelationAggregateInput = {
|
||||
_count?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type CheckListItemOrderByRelevanceInput = {
|
||||
fields: Prisma.CheckListItemOrderByRelevanceFieldEnum | Prisma.CheckListItemOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type CheckListItemCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
listId?: Prisma.SortOrder
|
||||
@@ -627,7 +620,31 @@ export type CheckListItemSelect<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
list?: boolean | Prisma.CheckListDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["checkListItem"]>
|
||||
|
||||
export type CheckListItemSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
listId?: boolean
|
||||
title?: boolean
|
||||
note?: boolean
|
||||
done?: boolean
|
||||
doneAt?: boolean
|
||||
sortOrder?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
list?: boolean | Prisma.CheckListDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["checkListItem"]>
|
||||
|
||||
export type CheckListItemSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
listId?: boolean
|
||||
title?: boolean
|
||||
note?: boolean
|
||||
done?: boolean
|
||||
doneAt?: boolean
|
||||
sortOrder?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
list?: boolean | Prisma.CheckListDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["checkListItem"]>
|
||||
|
||||
export type CheckListItemSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -645,6 +662,12 @@ export type CheckListItemOmit<ExtArgs extends runtime.Types.Extensions.InternalA
|
||||
export type CheckListItemInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
list?: boolean | Prisma.CheckListDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type CheckListItemIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
list?: boolean | Prisma.CheckListDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type CheckListItemIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
list?: boolean | Prisma.CheckListDefaultArgs<ExtArgs>
|
||||
}
|
||||
|
||||
export type $CheckListItemPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "CheckListItem"
|
||||
@@ -778,6 +801,30 @@ export interface CheckListItemDelegate<ExtArgs extends runtime.Types.Extensions.
|
||||
*/
|
||||
createMany<T extends CheckListItemCreateManyArgs>(args?: Prisma.SelectSubset<T, CheckListItemCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many CheckListItems and returns the data saved in the database.
|
||||
* @param {CheckListItemCreateManyAndReturnArgs} args - Arguments to create many CheckListItems.
|
||||
* @example
|
||||
* // Create many CheckListItems
|
||||
* const checkListItem = await prisma.checkListItem.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many CheckListItems and only return the `id`
|
||||
* const checkListItemWithIdOnly = await prisma.checkListItem.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends CheckListItemCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, CheckListItemCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$CheckListItemPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a CheckListItem.
|
||||
* @param {CheckListItemDeleteArgs} args - Arguments to delete one CheckListItem.
|
||||
@@ -842,6 +889,36 @@ export interface CheckListItemDelegate<ExtArgs extends runtime.Types.Extensions.
|
||||
*/
|
||||
updateMany<T extends CheckListItemUpdateManyArgs>(args: Prisma.SelectSubset<T, CheckListItemUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more CheckListItems and returns the data updated in the database.
|
||||
* @param {CheckListItemUpdateManyAndReturnArgs} args - Arguments to update many CheckListItems.
|
||||
* @example
|
||||
* // Update many CheckListItems
|
||||
* const checkListItem = await prisma.checkListItem.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more CheckListItems and only return the `id`
|
||||
* const checkListItemWithIdOnly = await prisma.checkListItem.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends CheckListItemUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, CheckListItemUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$CheckListItemPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one CheckListItem.
|
||||
* @param {CheckListItemUpsertArgs} args - Arguments to update or create a CheckListItem.
|
||||
@@ -1277,6 +1354,29 @@ export type CheckListItemCreateManyArgs<ExtArgs extends runtime.Types.Extensions
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckListItem createManyAndReturn
|
||||
*/
|
||||
export type CheckListItemCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the CheckListItem
|
||||
*/
|
||||
select?: Prisma.CheckListItemSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the CheckListItem
|
||||
*/
|
||||
omit?: Prisma.CheckListItemOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many CheckListItems.
|
||||
*/
|
||||
data: Prisma.CheckListItemCreateManyInput | Prisma.CheckListItemCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.CheckListItemIncludeCreateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckListItem update
|
||||
*/
|
||||
@@ -1321,6 +1421,36 @@ export type CheckListItemUpdateManyArgs<ExtArgs extends runtime.Types.Extensions
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckListItem updateManyAndReturn
|
||||
*/
|
||||
export type CheckListItemUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the CheckListItem
|
||||
*/
|
||||
select?: Prisma.CheckListItemSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the CheckListItem
|
||||
*/
|
||||
omit?: Prisma.CheckListItemOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update CheckListItems.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.CheckListItemUpdateManyMutationInput, Prisma.CheckListItemUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which CheckListItems to update
|
||||
*/
|
||||
where?: Prisma.CheckListItemWhereInput
|
||||
/**
|
||||
* Limit how many CheckListItems to update.
|
||||
*/
|
||||
limit?: number
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.CheckListItemIncludeUpdateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckListItem upsert
|
||||
*/
|
||||
|
||||
@@ -253,7 +253,6 @@ export type CheckListTemplateOrderByWithRelationInput = {
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
user?: Prisma.UserOrderByWithRelationInput
|
||||
_relevance?: Prisma.CheckListTemplateOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type CheckListTemplateWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -384,12 +383,6 @@ export type CheckListTemplateOrderByRelationAggregateInput = {
|
||||
_count?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type CheckListTemplateOrderByRelevanceInput = {
|
||||
fields: Prisma.CheckListTemplateOrderByRelevanceFieldEnum | Prisma.CheckListTemplateOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type CheckListTemplateCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
userId?: Prisma.SortOrder
|
||||
@@ -585,7 +578,29 @@ export type CheckListTemplateSelect<ExtArgs extends runtime.Types.Extensions.Int
|
||||
user?: boolean | Prisma.CheckListTemplate$userArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["checkListTemplate"]>
|
||||
|
||||
export type CheckListTemplateSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
userId?: boolean
|
||||
name?: boolean
|
||||
scene?: boolean
|
||||
items?: boolean
|
||||
builtin?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
user?: boolean | Prisma.CheckListTemplate$userArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["checkListTemplate"]>
|
||||
|
||||
export type CheckListTemplateSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
userId?: boolean
|
||||
name?: boolean
|
||||
scene?: boolean
|
||||
items?: boolean
|
||||
builtin?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
user?: boolean | Prisma.CheckListTemplate$userArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["checkListTemplate"]>
|
||||
|
||||
export type CheckListTemplateSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -602,6 +617,12 @@ export type CheckListTemplateOmit<ExtArgs extends runtime.Types.Extensions.Inter
|
||||
export type CheckListTemplateInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
user?: boolean | Prisma.CheckListTemplate$userArgs<ExtArgs>
|
||||
}
|
||||
export type CheckListTemplateIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
user?: boolean | Prisma.CheckListTemplate$userArgs<ExtArgs>
|
||||
}
|
||||
export type CheckListTemplateIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
user?: boolean | Prisma.CheckListTemplate$userArgs<ExtArgs>
|
||||
}
|
||||
|
||||
export type $CheckListTemplatePayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "CheckListTemplate"
|
||||
@@ -734,6 +755,30 @@ export interface CheckListTemplateDelegate<ExtArgs extends runtime.Types.Extensi
|
||||
*/
|
||||
createMany<T extends CheckListTemplateCreateManyArgs>(args?: Prisma.SelectSubset<T, CheckListTemplateCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many CheckListTemplates and returns the data saved in the database.
|
||||
* @param {CheckListTemplateCreateManyAndReturnArgs} args - Arguments to create many CheckListTemplates.
|
||||
* @example
|
||||
* // Create many CheckListTemplates
|
||||
* const checkListTemplate = await prisma.checkListTemplate.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many CheckListTemplates and only return the `id`
|
||||
* const checkListTemplateWithIdOnly = await prisma.checkListTemplate.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends CheckListTemplateCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, CheckListTemplateCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$CheckListTemplatePayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a CheckListTemplate.
|
||||
* @param {CheckListTemplateDeleteArgs} args - Arguments to delete one CheckListTemplate.
|
||||
@@ -798,6 +843,36 @@ export interface CheckListTemplateDelegate<ExtArgs extends runtime.Types.Extensi
|
||||
*/
|
||||
updateMany<T extends CheckListTemplateUpdateManyArgs>(args: Prisma.SelectSubset<T, CheckListTemplateUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more CheckListTemplates and returns the data updated in the database.
|
||||
* @param {CheckListTemplateUpdateManyAndReturnArgs} args - Arguments to update many CheckListTemplates.
|
||||
* @example
|
||||
* // Update many CheckListTemplates
|
||||
* const checkListTemplate = await prisma.checkListTemplate.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more CheckListTemplates and only return the `id`
|
||||
* const checkListTemplateWithIdOnly = await prisma.checkListTemplate.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends CheckListTemplateUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, CheckListTemplateUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$CheckListTemplatePayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one CheckListTemplate.
|
||||
* @param {CheckListTemplateUpsertArgs} args - Arguments to update or create a CheckListTemplate.
|
||||
@@ -1232,6 +1307,29 @@ export type CheckListTemplateCreateManyArgs<ExtArgs extends runtime.Types.Extens
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckListTemplate createManyAndReturn
|
||||
*/
|
||||
export type CheckListTemplateCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the CheckListTemplate
|
||||
*/
|
||||
select?: Prisma.CheckListTemplateSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the CheckListTemplate
|
||||
*/
|
||||
omit?: Prisma.CheckListTemplateOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many CheckListTemplates.
|
||||
*/
|
||||
data: Prisma.CheckListTemplateCreateManyInput | Prisma.CheckListTemplateCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.CheckListTemplateIncludeCreateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckListTemplate update
|
||||
*/
|
||||
@@ -1276,6 +1374,36 @@ export type CheckListTemplateUpdateManyArgs<ExtArgs extends runtime.Types.Extens
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckListTemplate updateManyAndReturn
|
||||
*/
|
||||
export type CheckListTemplateUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the CheckListTemplate
|
||||
*/
|
||||
select?: Prisma.CheckListTemplateSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the CheckListTemplate
|
||||
*/
|
||||
omit?: Prisma.CheckListTemplateOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update CheckListTemplates.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.CheckListTemplateUpdateManyMutationInput, Prisma.CheckListTemplateUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which CheckListTemplates to update
|
||||
*/
|
||||
where?: Prisma.CheckListTemplateWhereInput
|
||||
/**
|
||||
* Limit how many CheckListTemplates to update.
|
||||
*/
|
||||
limit?: number
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.CheckListTemplateIncludeUpdateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* CheckListTemplate upsert
|
||||
*/
|
||||
|
||||
@@ -228,7 +228,6 @@ export type Econ_SowInventoryOrderByWithRelationInput = {
|
||||
inventory?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
_relevance?: Prisma.Econ_SowInventoryOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type Econ_SowInventoryWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -319,12 +318,6 @@ export type Econ_SowInventoryUncheckedUpdateManyInput = {
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type Econ_SowInventoryOrderByRelevanceInput = {
|
||||
fields: Prisma.Econ_SowInventoryOrderByRelevanceFieldEnum | Prisma.Econ_SowInventoryOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type Econ_SowInventoryCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
month?: Prisma.SortOrder
|
||||
@@ -369,7 +362,21 @@ export type Econ_SowInventorySelect<ExtArgs extends runtime.Types.Extensions.Int
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["econ_SowInventory"]>
|
||||
|
||||
export type Econ_SowInventorySelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
month?: boolean
|
||||
inventory?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["econ_SowInventory"]>
|
||||
|
||||
export type Econ_SowInventorySelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
month?: boolean
|
||||
inventory?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["econ_SowInventory"]>
|
||||
|
||||
export type Econ_SowInventorySelectScalar = {
|
||||
id?: boolean
|
||||
@@ -507,6 +514,30 @@ export interface Econ_SowInventoryDelegate<ExtArgs extends runtime.Types.Extensi
|
||||
*/
|
||||
createMany<T extends Econ_SowInventoryCreateManyArgs>(args?: Prisma.SelectSubset<T, Econ_SowInventoryCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many Econ_SowInventories and returns the data saved in the database.
|
||||
* @param {Econ_SowInventoryCreateManyAndReturnArgs} args - Arguments to create many Econ_SowInventories.
|
||||
* @example
|
||||
* // Create many Econ_SowInventories
|
||||
* const econ_SowInventory = await prisma.econ_SowInventory.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many Econ_SowInventories and only return the `id`
|
||||
* const econ_SowInventoryWithIdOnly = await prisma.econ_SowInventory.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends Econ_SowInventoryCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, Econ_SowInventoryCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$Econ_SowInventoryPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a Econ_SowInventory.
|
||||
* @param {Econ_SowInventoryDeleteArgs} args - Arguments to delete one Econ_SowInventory.
|
||||
@@ -571,6 +602,36 @@ export interface Econ_SowInventoryDelegate<ExtArgs extends runtime.Types.Extensi
|
||||
*/
|
||||
updateMany<T extends Econ_SowInventoryUpdateManyArgs>(args: Prisma.SelectSubset<T, Econ_SowInventoryUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more Econ_SowInventories and returns the data updated in the database.
|
||||
* @param {Econ_SowInventoryUpdateManyAndReturnArgs} args - Arguments to update many Econ_SowInventories.
|
||||
* @example
|
||||
* // Update many Econ_SowInventories
|
||||
* const econ_SowInventory = await prisma.econ_SowInventory.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more Econ_SowInventories and only return the `id`
|
||||
* const econ_SowInventoryWithIdOnly = await prisma.econ_SowInventory.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends Econ_SowInventoryUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, Econ_SowInventoryUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$Econ_SowInventoryPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one Econ_SowInventory.
|
||||
* @param {Econ_SowInventoryUpsertArgs} args - Arguments to update or create a Econ_SowInventory.
|
||||
@@ -977,6 +1038,25 @@ export type Econ_SowInventoryCreateManyArgs<ExtArgs extends runtime.Types.Extens
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Econ_SowInventory createManyAndReturn
|
||||
*/
|
||||
export type Econ_SowInventoryCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the Econ_SowInventory
|
||||
*/
|
||||
select?: Prisma.Econ_SowInventorySelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the Econ_SowInventory
|
||||
*/
|
||||
omit?: Prisma.Econ_SowInventoryOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many Econ_SowInventories.
|
||||
*/
|
||||
data: Prisma.Econ_SowInventoryCreateManyInput | Prisma.Econ_SowInventoryCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Econ_SowInventory update
|
||||
*/
|
||||
@@ -1017,6 +1097,32 @@ export type Econ_SowInventoryUpdateManyArgs<ExtArgs extends runtime.Types.Extens
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Econ_SowInventory updateManyAndReturn
|
||||
*/
|
||||
export type Econ_SowInventoryUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the Econ_SowInventory
|
||||
*/
|
||||
select?: Prisma.Econ_SowInventorySelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the Econ_SowInventory
|
||||
*/
|
||||
omit?: Prisma.Econ_SowInventoryOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update Econ_SowInventories.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.Econ_SowInventoryUpdateManyMutationInput, Prisma.Econ_SowInventoryUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which Econ_SowInventories to update
|
||||
*/
|
||||
where?: Prisma.Econ_SowInventoryWhereInput
|
||||
/**
|
||||
* Limit how many Econ_SowInventories to update.
|
||||
*/
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Econ_SowInventory upsert
|
||||
*/
|
||||
|
||||
@@ -303,7 +303,6 @@ export type HabitOrderByWithRelationInput = {
|
||||
updatedAt?: Prisma.SortOrder
|
||||
user?: Prisma.UserOrderByWithRelationInput
|
||||
records?: Prisma.CheckInOrderByRelationAggregateInput
|
||||
_relevance?: Prisma.HabitOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type HabitWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -479,12 +478,6 @@ export type HabitOrderByRelationAggregateInput = {
|
||||
_count?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type HabitOrderByRelevanceInput = {
|
||||
fields: Prisma.HabitOrderByRelevanceFieldEnum | Prisma.HabitOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type HabitCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
userId?: Prisma.SortOrder
|
||||
@@ -858,7 +851,37 @@ export type HabitSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs =
|
||||
_count?: boolean | Prisma.HabitCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["habit"]>
|
||||
|
||||
export type HabitSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
userId?: boolean
|
||||
name?: boolean
|
||||
period?: boolean
|
||||
target?: boolean
|
||||
color?: boolean
|
||||
icon?: boolean
|
||||
note?: boolean
|
||||
archived?: boolean
|
||||
sortOrder?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["habit"]>
|
||||
|
||||
export type HabitSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
userId?: boolean
|
||||
name?: boolean
|
||||
period?: boolean
|
||||
target?: boolean
|
||||
color?: boolean
|
||||
icon?: boolean
|
||||
note?: boolean
|
||||
archived?: boolean
|
||||
sortOrder?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["habit"]>
|
||||
|
||||
export type HabitSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -881,6 +904,12 @@ export type HabitInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs =
|
||||
records?: boolean | Prisma.Habit$recordsArgs<ExtArgs>
|
||||
_count?: boolean | Prisma.HabitCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type HabitIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type HabitIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
|
||||
}
|
||||
|
||||
export type $HabitPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "Habit"
|
||||
@@ -1018,6 +1047,30 @@ export interface HabitDelegate<ExtArgs extends runtime.Types.Extensions.Internal
|
||||
*/
|
||||
createMany<T extends HabitCreateManyArgs>(args?: Prisma.SelectSubset<T, HabitCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many Habits and returns the data saved in the database.
|
||||
* @param {HabitCreateManyAndReturnArgs} args - Arguments to create many Habits.
|
||||
* @example
|
||||
* // Create many Habits
|
||||
* const habit = await prisma.habit.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many Habits and only return the `id`
|
||||
* const habitWithIdOnly = await prisma.habit.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends HabitCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, HabitCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$HabitPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a Habit.
|
||||
* @param {HabitDeleteArgs} args - Arguments to delete one Habit.
|
||||
@@ -1082,6 +1135,36 @@ export interface HabitDelegate<ExtArgs extends runtime.Types.Extensions.Internal
|
||||
*/
|
||||
updateMany<T extends HabitUpdateManyArgs>(args: Prisma.SelectSubset<T, HabitUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more Habits and returns the data updated in the database.
|
||||
* @param {HabitUpdateManyAndReturnArgs} args - Arguments to update many Habits.
|
||||
* @example
|
||||
* // Update many Habits
|
||||
* const habit = await prisma.habit.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more Habits and only return the `id`
|
||||
* const habitWithIdOnly = await prisma.habit.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends HabitUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, HabitUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$HabitPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one Habit.
|
||||
* @param {HabitUpsertArgs} args - Arguments to update or create a Habit.
|
||||
@@ -1521,6 +1604,29 @@ export type HabitCreateManyArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Habit createManyAndReturn
|
||||
*/
|
||||
export type HabitCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the Habit
|
||||
*/
|
||||
select?: Prisma.HabitSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the Habit
|
||||
*/
|
||||
omit?: Prisma.HabitOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many Habits.
|
||||
*/
|
||||
data: Prisma.HabitCreateManyInput | Prisma.HabitCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.HabitIncludeCreateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Habit update
|
||||
*/
|
||||
@@ -1565,6 +1671,36 @@ export type HabitUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Habit updateManyAndReturn
|
||||
*/
|
||||
export type HabitUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the Habit
|
||||
*/
|
||||
select?: Prisma.HabitSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the Habit
|
||||
*/
|
||||
omit?: Prisma.HabitOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update Habits.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.HabitUpdateManyMutationInput, Prisma.HabitUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which Habits to update
|
||||
*/
|
||||
where?: Prisma.HabitWhereInput
|
||||
/**
|
||||
* Limit how many Habits to update.
|
||||
*/
|
||||
limit?: number
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.HabitIncludeUpdateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* Habit upsert
|
||||
*/
|
||||
|
||||
@@ -271,7 +271,6 @@ export type IndicatorOrderByWithRelationInput = {
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
points?: Prisma.IndicatorPointOrderByRelationAggregateInput
|
||||
_relevance?: Prisma.IndicatorOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type IndicatorWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -417,12 +416,6 @@ export type IndicatorUncheckedUpdateManyInput = {
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type IndicatorOrderByRelevanceInput = {
|
||||
fields: Prisma.IndicatorOrderByRelevanceFieldEnum | Prisma.IndicatorOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type IndicatorCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
name?: Prisma.SortOrder
|
||||
@@ -605,7 +598,31 @@ export type IndicatorSelect<ExtArgs extends runtime.Types.Extensions.InternalArg
|
||||
_count?: boolean | Prisma.IndicatorCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["indicator"]>
|
||||
|
||||
export type IndicatorSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
name?: boolean
|
||||
groupName?: boolean
|
||||
title?: boolean
|
||||
unit?: boolean
|
||||
source?: boolean
|
||||
frequency?: boolean
|
||||
hidden?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["indicator"]>
|
||||
|
||||
export type IndicatorSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
name?: boolean
|
||||
groupName?: boolean
|
||||
title?: boolean
|
||||
unit?: boolean
|
||||
source?: boolean
|
||||
frequency?: boolean
|
||||
hidden?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["indicator"]>
|
||||
|
||||
export type IndicatorSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -625,6 +642,8 @@ export type IndicatorInclude<ExtArgs extends runtime.Types.Extensions.InternalAr
|
||||
points?: boolean | Prisma.Indicator$pointsArgs<ExtArgs>
|
||||
_count?: boolean | Prisma.IndicatorCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type IndicatorIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {}
|
||||
export type IndicatorIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {}
|
||||
|
||||
export type $IndicatorPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "Indicator"
|
||||
@@ -759,6 +778,30 @@ export interface IndicatorDelegate<ExtArgs extends runtime.Types.Extensions.Inte
|
||||
*/
|
||||
createMany<T extends IndicatorCreateManyArgs>(args?: Prisma.SelectSubset<T, IndicatorCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many Indicators and returns the data saved in the database.
|
||||
* @param {IndicatorCreateManyAndReturnArgs} args - Arguments to create many Indicators.
|
||||
* @example
|
||||
* // Create many Indicators
|
||||
* const indicator = await prisma.indicator.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many Indicators and only return the `id`
|
||||
* const indicatorWithIdOnly = await prisma.indicator.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends IndicatorCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, IndicatorCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$IndicatorPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a Indicator.
|
||||
* @param {IndicatorDeleteArgs} args - Arguments to delete one Indicator.
|
||||
@@ -823,6 +866,36 @@ export interface IndicatorDelegate<ExtArgs extends runtime.Types.Extensions.Inte
|
||||
*/
|
||||
updateMany<T extends IndicatorUpdateManyArgs>(args: Prisma.SelectSubset<T, IndicatorUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more Indicators and returns the data updated in the database.
|
||||
* @param {IndicatorUpdateManyAndReturnArgs} args - Arguments to update many Indicators.
|
||||
* @example
|
||||
* // Update many Indicators
|
||||
* const indicator = await prisma.indicator.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more Indicators and only return the `id`
|
||||
* const indicatorWithIdOnly = await prisma.indicator.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends IndicatorUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, IndicatorUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$IndicatorPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one Indicator.
|
||||
* @param {IndicatorUpsertArgs} args - Arguments to update or create a Indicator.
|
||||
@@ -1259,6 +1332,25 @@ export type IndicatorCreateManyArgs<ExtArgs extends runtime.Types.Extensions.Int
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicator createManyAndReturn
|
||||
*/
|
||||
export type IndicatorCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the Indicator
|
||||
*/
|
||||
select?: Prisma.IndicatorSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the Indicator
|
||||
*/
|
||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many Indicators.
|
||||
*/
|
||||
data: Prisma.IndicatorCreateManyInput | Prisma.IndicatorCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicator update
|
||||
*/
|
||||
@@ -1303,6 +1395,32 @@ export type IndicatorUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.Int
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicator updateManyAndReturn
|
||||
*/
|
||||
export type IndicatorUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the Indicator
|
||||
*/
|
||||
select?: Prisma.IndicatorSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the Indicator
|
||||
*/
|
||||
omit?: Prisma.IndicatorOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update Indicators.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.IndicatorUpdateManyMutationInput, Prisma.IndicatorUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which Indicators to update
|
||||
*/
|
||||
where?: Prisma.IndicatorWhereInput
|
||||
/**
|
||||
* Limit how many Indicators to update.
|
||||
*/
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicator upsert
|
||||
*/
|
||||
|
||||
@@ -243,7 +243,6 @@ export type IndicatorPointOrderByWithRelationInput = {
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
indicator?: Prisma.IndicatorOrderByWithRelationInput
|
||||
_relevance?: Prisma.IndicatorPointOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type IndicatorPointWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -355,12 +354,6 @@ export type IndicatorPointOrderByRelationAggregateInput = {
|
||||
_count?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type IndicatorPointOrderByRelevanceInput = {
|
||||
fields: Prisma.IndicatorPointOrderByRelevanceFieldEnum | Prisma.IndicatorPointOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type IndicatorPointIndicatorIdPeriodCompoundUniqueInput = {
|
||||
indicatorId: number
|
||||
period: string
|
||||
@@ -551,7 +544,25 @@ export type IndicatorPointSelect<ExtArgs extends runtime.Types.Extensions.Intern
|
||||
indicator?: boolean | Prisma.IndicatorDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["indicatorPoint"]>
|
||||
|
||||
export type IndicatorPointSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
indicatorId?: boolean
|
||||
period?: boolean
|
||||
value?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
indicator?: boolean | Prisma.IndicatorDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["indicatorPoint"]>
|
||||
|
||||
export type IndicatorPointSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
indicatorId?: boolean
|
||||
period?: boolean
|
||||
value?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
indicator?: boolean | Prisma.IndicatorDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["indicatorPoint"]>
|
||||
|
||||
export type IndicatorPointSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -566,6 +577,12 @@ export type IndicatorPointOmit<ExtArgs extends runtime.Types.Extensions.Internal
|
||||
export type IndicatorPointInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
indicator?: boolean | Prisma.IndicatorDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type IndicatorPointIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
indicator?: boolean | Prisma.IndicatorDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type IndicatorPointIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
indicator?: boolean | Prisma.IndicatorDefaultArgs<ExtArgs>
|
||||
}
|
||||
|
||||
export type $IndicatorPointPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "IndicatorPoint"
|
||||
@@ -696,6 +713,30 @@ export interface IndicatorPointDelegate<ExtArgs extends runtime.Types.Extensions
|
||||
*/
|
||||
createMany<T extends IndicatorPointCreateManyArgs>(args?: Prisma.SelectSubset<T, IndicatorPointCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many IndicatorPoints and returns the data saved in the database.
|
||||
* @param {IndicatorPointCreateManyAndReturnArgs} args - Arguments to create many IndicatorPoints.
|
||||
* @example
|
||||
* // Create many IndicatorPoints
|
||||
* const indicatorPoint = await prisma.indicatorPoint.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many IndicatorPoints and only return the `id`
|
||||
* const indicatorPointWithIdOnly = await prisma.indicatorPoint.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends IndicatorPointCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, IndicatorPointCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$IndicatorPointPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a IndicatorPoint.
|
||||
* @param {IndicatorPointDeleteArgs} args - Arguments to delete one IndicatorPoint.
|
||||
@@ -760,6 +801,36 @@ export interface IndicatorPointDelegate<ExtArgs extends runtime.Types.Extensions
|
||||
*/
|
||||
updateMany<T extends IndicatorPointUpdateManyArgs>(args: Prisma.SelectSubset<T, IndicatorPointUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more IndicatorPoints and returns the data updated in the database.
|
||||
* @param {IndicatorPointUpdateManyAndReturnArgs} args - Arguments to update many IndicatorPoints.
|
||||
* @example
|
||||
* // Update many IndicatorPoints
|
||||
* const indicatorPoint = await prisma.indicatorPoint.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more IndicatorPoints and only return the `id`
|
||||
* const indicatorPointWithIdOnly = await prisma.indicatorPoint.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends IndicatorPointUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, IndicatorPointUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$IndicatorPointPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one IndicatorPoint.
|
||||
* @param {IndicatorPointUpsertArgs} args - Arguments to update or create a IndicatorPoint.
|
||||
@@ -1192,6 +1263,29 @@ export type IndicatorPointCreateManyArgs<ExtArgs extends runtime.Types.Extension
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* IndicatorPoint createManyAndReturn
|
||||
*/
|
||||
export type IndicatorPointCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the IndicatorPoint
|
||||
*/
|
||||
select?: Prisma.IndicatorPointSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the IndicatorPoint
|
||||
*/
|
||||
omit?: Prisma.IndicatorPointOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many IndicatorPoints.
|
||||
*/
|
||||
data: Prisma.IndicatorPointCreateManyInput | Prisma.IndicatorPointCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.IndicatorPointIncludeCreateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* IndicatorPoint update
|
||||
*/
|
||||
@@ -1236,6 +1330,36 @@ export type IndicatorPointUpdateManyArgs<ExtArgs extends runtime.Types.Extension
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* IndicatorPoint updateManyAndReturn
|
||||
*/
|
||||
export type IndicatorPointUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the IndicatorPoint
|
||||
*/
|
||||
select?: Prisma.IndicatorPointSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the IndicatorPoint
|
||||
*/
|
||||
omit?: Prisma.IndicatorPointOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update IndicatorPoints.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.IndicatorPointUpdateManyMutationInput, Prisma.IndicatorPointUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which IndicatorPoints to update
|
||||
*/
|
||||
where?: Prisma.IndicatorPointWhereInput
|
||||
/**
|
||||
* Limit how many IndicatorPoints to update.
|
||||
*/
|
||||
limit?: number
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.IndicatorPointIncludeUpdateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* IndicatorPoint upsert
|
||||
*/
|
||||
|
||||
@@ -233,7 +233,6 @@ export type MihomeAccountOrderByWithRelationInput = {
|
||||
status?: Prisma.SortOrder
|
||||
lastError?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
_relevance?: Prisma.MihomeAccountOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type MihomeAccountWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -334,12 +333,6 @@ export type MihomeAccountUncheckedUpdateManyInput = {
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type MihomeAccountOrderByRelevanceInput = {
|
||||
fields: Prisma.MihomeAccountOrderByRelevanceFieldEnum | Prisma.MihomeAccountOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type MihomeAccountCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
key?: Prisma.SortOrder
|
||||
@@ -386,7 +379,23 @@ export type MihomeAccountSelect<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["mihomeAccount"]>
|
||||
|
||||
export type MihomeAccountSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
key?: boolean
|
||||
userId?: boolean
|
||||
status?: boolean
|
||||
lastError?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["mihomeAccount"]>
|
||||
|
||||
export type MihomeAccountSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
key?: boolean
|
||||
userId?: boolean
|
||||
status?: boolean
|
||||
lastError?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["mihomeAccount"]>
|
||||
|
||||
export type MihomeAccountSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -526,6 +535,30 @@ export interface MihomeAccountDelegate<ExtArgs extends runtime.Types.Extensions.
|
||||
*/
|
||||
createMany<T extends MihomeAccountCreateManyArgs>(args?: Prisma.SelectSubset<T, MihomeAccountCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many MihomeAccounts and returns the data saved in the database.
|
||||
* @param {MihomeAccountCreateManyAndReturnArgs} args - Arguments to create many MihomeAccounts.
|
||||
* @example
|
||||
* // Create many MihomeAccounts
|
||||
* const mihomeAccount = await prisma.mihomeAccount.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many MihomeAccounts and only return the `id`
|
||||
* const mihomeAccountWithIdOnly = await prisma.mihomeAccount.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends MihomeAccountCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, MihomeAccountCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$MihomeAccountPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a MihomeAccount.
|
||||
* @param {MihomeAccountDeleteArgs} args - Arguments to delete one MihomeAccount.
|
||||
@@ -590,6 +623,36 @@ export interface MihomeAccountDelegate<ExtArgs extends runtime.Types.Extensions.
|
||||
*/
|
||||
updateMany<T extends MihomeAccountUpdateManyArgs>(args: Prisma.SelectSubset<T, MihomeAccountUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more MihomeAccounts and returns the data updated in the database.
|
||||
* @param {MihomeAccountUpdateManyAndReturnArgs} args - Arguments to update many MihomeAccounts.
|
||||
* @example
|
||||
* // Update many MihomeAccounts
|
||||
* const mihomeAccount = await prisma.mihomeAccount.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more MihomeAccounts and only return the `id`
|
||||
* const mihomeAccountWithIdOnly = await prisma.mihomeAccount.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends MihomeAccountUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, MihomeAccountUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$MihomeAccountPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one MihomeAccount.
|
||||
* @param {MihomeAccountUpsertArgs} args - Arguments to update or create a MihomeAccount.
|
||||
@@ -997,6 +1060,25 @@ export type MihomeAccountCreateManyArgs<ExtArgs extends runtime.Types.Extensions
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeAccount createManyAndReturn
|
||||
*/
|
||||
export type MihomeAccountCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the MihomeAccount
|
||||
*/
|
||||
select?: Prisma.MihomeAccountSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the MihomeAccount
|
||||
*/
|
||||
omit?: Prisma.MihomeAccountOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many MihomeAccounts.
|
||||
*/
|
||||
data: Prisma.MihomeAccountCreateManyInput | Prisma.MihomeAccountCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeAccount update
|
||||
*/
|
||||
@@ -1037,6 +1119,32 @@ export type MihomeAccountUpdateManyArgs<ExtArgs extends runtime.Types.Extensions
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeAccount updateManyAndReturn
|
||||
*/
|
||||
export type MihomeAccountUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the MihomeAccount
|
||||
*/
|
||||
select?: Prisma.MihomeAccountSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the MihomeAccount
|
||||
*/
|
||||
omit?: Prisma.MihomeAccountOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update MihomeAccounts.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.MihomeAccountUpdateManyMutationInput, Prisma.MihomeAccountUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which MihomeAccounts to update
|
||||
*/
|
||||
where?: Prisma.MihomeAccountWhereInput
|
||||
/**
|
||||
* Limit how many MihomeAccounts to update.
|
||||
*/
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeAccount upsert
|
||||
*/
|
||||
|
||||
@@ -366,7 +366,6 @@ export type MihomeDeviceOrderByWithRelationInput = {
|
||||
home?: Prisma.MihomeHomeOrderByWithRelationInput
|
||||
samples?: Prisma.MihomeEnvSampleOrderByRelationAggregateInput
|
||||
hours?: Prisma.MihomeEnvHourOrderByRelationAggregateInput
|
||||
_relevance?: Prisma.MihomeDeviceOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type MihomeDeviceWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -597,12 +596,6 @@ export type MihomeDeviceOrderByRelationAggregateInput = {
|
||||
_count?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type MihomeDeviceOrderByRelevanceInput = {
|
||||
fields: Prisma.MihomeDeviceOrderByRelevanceFieldEnum | Prisma.MihomeDeviceOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type MihomeDeviceCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
did?: Prisma.SortOrder
|
||||
@@ -1201,7 +1194,47 @@ export type MihomeDeviceSelect<ExtArgs extends runtime.Types.Extensions.Internal
|
||||
_count?: boolean | Prisma.MihomeDeviceCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["mihomeDevice"]>
|
||||
|
||||
export type MihomeDeviceSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
did?: boolean
|
||||
homeId?: boolean
|
||||
model?: boolean
|
||||
name?: boolean
|
||||
alias?: boolean
|
||||
tempSiid?: boolean
|
||||
tempPiid?: boolean
|
||||
humSiid?: boolean
|
||||
humPiid?: boolean
|
||||
battSiid?: boolean
|
||||
battPiid?: boolean
|
||||
battery?: boolean
|
||||
batteryAt?: boolean
|
||||
enabled?: boolean
|
||||
lastSyncAt?: boolean
|
||||
createdAt?: boolean
|
||||
home?: boolean | Prisma.MihomeHomeDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["mihomeDevice"]>
|
||||
|
||||
export type MihomeDeviceSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
did?: boolean
|
||||
homeId?: boolean
|
||||
model?: boolean
|
||||
name?: boolean
|
||||
alias?: boolean
|
||||
tempSiid?: boolean
|
||||
tempPiid?: boolean
|
||||
humSiid?: boolean
|
||||
humPiid?: boolean
|
||||
battSiid?: boolean
|
||||
battPiid?: boolean
|
||||
battery?: boolean
|
||||
batteryAt?: boolean
|
||||
enabled?: boolean
|
||||
lastSyncAt?: boolean
|
||||
createdAt?: boolean
|
||||
home?: boolean | Prisma.MihomeHomeDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["mihomeDevice"]>
|
||||
|
||||
export type MihomeDeviceSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -1230,6 +1263,12 @@ export type MihomeDeviceInclude<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
hours?: boolean | Prisma.MihomeDevice$hoursArgs<ExtArgs>
|
||||
_count?: boolean | Prisma.MihomeDeviceCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type MihomeDeviceIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
home?: boolean | Prisma.MihomeHomeDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type MihomeDeviceIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
home?: boolean | Prisma.MihomeHomeDefaultArgs<ExtArgs>
|
||||
}
|
||||
|
||||
export type $MihomeDevicePayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "MihomeDevice"
|
||||
@@ -1373,6 +1412,30 @@ export interface MihomeDeviceDelegate<ExtArgs extends runtime.Types.Extensions.I
|
||||
*/
|
||||
createMany<T extends MihomeDeviceCreateManyArgs>(args?: Prisma.SelectSubset<T, MihomeDeviceCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many MihomeDevices and returns the data saved in the database.
|
||||
* @param {MihomeDeviceCreateManyAndReturnArgs} args - Arguments to create many MihomeDevices.
|
||||
* @example
|
||||
* // Create many MihomeDevices
|
||||
* const mihomeDevice = await prisma.mihomeDevice.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many MihomeDevices and only return the `id`
|
||||
* const mihomeDeviceWithIdOnly = await prisma.mihomeDevice.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends MihomeDeviceCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, MihomeDeviceCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$MihomeDevicePayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a MihomeDevice.
|
||||
* @param {MihomeDeviceDeleteArgs} args - Arguments to delete one MihomeDevice.
|
||||
@@ -1437,6 +1500,36 @@ export interface MihomeDeviceDelegate<ExtArgs extends runtime.Types.Extensions.I
|
||||
*/
|
||||
updateMany<T extends MihomeDeviceUpdateManyArgs>(args: Prisma.SelectSubset<T, MihomeDeviceUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more MihomeDevices and returns the data updated in the database.
|
||||
* @param {MihomeDeviceUpdateManyAndReturnArgs} args - Arguments to update many MihomeDevices.
|
||||
* @example
|
||||
* // Update many MihomeDevices
|
||||
* const mihomeDevice = await prisma.mihomeDevice.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more MihomeDevices and only return the `id`
|
||||
* const mihomeDeviceWithIdOnly = await prisma.mihomeDevice.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends MihomeDeviceUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, MihomeDeviceUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$MihomeDevicePayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one MihomeDevice.
|
||||
* @param {MihomeDeviceUpsertArgs} args - Arguments to update or create a MihomeDevice.
|
||||
@@ -1882,6 +1975,29 @@ export type MihomeDeviceCreateManyArgs<ExtArgs extends runtime.Types.Extensions.
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeDevice createManyAndReturn
|
||||
*/
|
||||
export type MihomeDeviceCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the MihomeDevice
|
||||
*/
|
||||
select?: Prisma.MihomeDeviceSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the MihomeDevice
|
||||
*/
|
||||
omit?: Prisma.MihomeDeviceOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many MihomeDevices.
|
||||
*/
|
||||
data: Prisma.MihomeDeviceCreateManyInput | Prisma.MihomeDeviceCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.MihomeDeviceIncludeCreateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeDevice update
|
||||
*/
|
||||
@@ -1926,6 +2042,36 @@ export type MihomeDeviceUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeDevice updateManyAndReturn
|
||||
*/
|
||||
export type MihomeDeviceUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the MihomeDevice
|
||||
*/
|
||||
select?: Prisma.MihomeDeviceSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the MihomeDevice
|
||||
*/
|
||||
omit?: Prisma.MihomeDeviceOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update MihomeDevices.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.MihomeDeviceUpdateManyMutationInput, Prisma.MihomeDeviceUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which MihomeDevices to update
|
||||
*/
|
||||
where?: Prisma.MihomeDeviceWhereInput
|
||||
/**
|
||||
* Limit how many MihomeDevices to update.
|
||||
*/
|
||||
limit?: number
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.MihomeDeviceIncludeUpdateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeDevice upsert
|
||||
*/
|
||||
|
||||
@@ -566,7 +566,27 @@ export type MihomeEnvHourSelect<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
device?: boolean | Prisma.MihomeDeviceDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["mihomeEnvHour"]>
|
||||
|
||||
export type MihomeEnvHourSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
deviceId?: boolean
|
||||
hour?: boolean
|
||||
temperatureAvg?: boolean
|
||||
humidityAvg?: boolean
|
||||
raw?: boolean
|
||||
createdAt?: boolean
|
||||
device?: boolean | Prisma.MihomeDeviceDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["mihomeEnvHour"]>
|
||||
|
||||
export type MihomeEnvHourSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
deviceId?: boolean
|
||||
hour?: boolean
|
||||
temperatureAvg?: boolean
|
||||
humidityAvg?: boolean
|
||||
raw?: boolean
|
||||
createdAt?: boolean
|
||||
device?: boolean | Prisma.MihomeDeviceDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["mihomeEnvHour"]>
|
||||
|
||||
export type MihomeEnvHourSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -582,6 +602,12 @@ export type MihomeEnvHourOmit<ExtArgs extends runtime.Types.Extensions.InternalA
|
||||
export type MihomeEnvHourInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
device?: boolean | Prisma.MihomeDeviceDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type MihomeEnvHourIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
device?: boolean | Prisma.MihomeDeviceDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type MihomeEnvHourIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
device?: boolean | Prisma.MihomeDeviceDefaultArgs<ExtArgs>
|
||||
}
|
||||
|
||||
export type $MihomeEnvHourPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "MihomeEnvHour"
|
||||
@@ -713,6 +739,30 @@ export interface MihomeEnvHourDelegate<ExtArgs extends runtime.Types.Extensions.
|
||||
*/
|
||||
createMany<T extends MihomeEnvHourCreateManyArgs>(args?: Prisma.SelectSubset<T, MihomeEnvHourCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many MihomeEnvHours and returns the data saved in the database.
|
||||
* @param {MihomeEnvHourCreateManyAndReturnArgs} args - Arguments to create many MihomeEnvHours.
|
||||
* @example
|
||||
* // Create many MihomeEnvHours
|
||||
* const mihomeEnvHour = await prisma.mihomeEnvHour.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many MihomeEnvHours and only return the `id`
|
||||
* const mihomeEnvHourWithIdOnly = await prisma.mihomeEnvHour.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends MihomeEnvHourCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, MihomeEnvHourCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$MihomeEnvHourPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a MihomeEnvHour.
|
||||
* @param {MihomeEnvHourDeleteArgs} args - Arguments to delete one MihomeEnvHour.
|
||||
@@ -777,6 +827,36 @@ export interface MihomeEnvHourDelegate<ExtArgs extends runtime.Types.Extensions.
|
||||
*/
|
||||
updateMany<T extends MihomeEnvHourUpdateManyArgs>(args: Prisma.SelectSubset<T, MihomeEnvHourUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more MihomeEnvHours and returns the data updated in the database.
|
||||
* @param {MihomeEnvHourUpdateManyAndReturnArgs} args - Arguments to update many MihomeEnvHours.
|
||||
* @example
|
||||
* // Update many MihomeEnvHours
|
||||
* const mihomeEnvHour = await prisma.mihomeEnvHour.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more MihomeEnvHours and only return the `id`
|
||||
* const mihomeEnvHourWithIdOnly = await prisma.mihomeEnvHour.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends MihomeEnvHourUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, MihomeEnvHourUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$MihomeEnvHourPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one MihomeEnvHour.
|
||||
* @param {MihomeEnvHourUpsertArgs} args - Arguments to update or create a MihomeEnvHour.
|
||||
@@ -1210,6 +1290,29 @@ export type MihomeEnvHourCreateManyArgs<ExtArgs extends runtime.Types.Extensions
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeEnvHour createManyAndReturn
|
||||
*/
|
||||
export type MihomeEnvHourCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the MihomeEnvHour
|
||||
*/
|
||||
select?: Prisma.MihomeEnvHourSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the MihomeEnvHour
|
||||
*/
|
||||
omit?: Prisma.MihomeEnvHourOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many MihomeEnvHours.
|
||||
*/
|
||||
data: Prisma.MihomeEnvHourCreateManyInput | Prisma.MihomeEnvHourCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.MihomeEnvHourIncludeCreateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeEnvHour update
|
||||
*/
|
||||
@@ -1254,6 +1357,36 @@ export type MihomeEnvHourUpdateManyArgs<ExtArgs extends runtime.Types.Extensions
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeEnvHour updateManyAndReturn
|
||||
*/
|
||||
export type MihomeEnvHourUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the MihomeEnvHour
|
||||
*/
|
||||
select?: Prisma.MihomeEnvHourSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the MihomeEnvHour
|
||||
*/
|
||||
omit?: Prisma.MihomeEnvHourOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update MihomeEnvHours.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.MihomeEnvHourUpdateManyMutationInput, Prisma.MihomeEnvHourUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which MihomeEnvHours to update
|
||||
*/
|
||||
where?: Prisma.MihomeEnvHourWhereInput
|
||||
/**
|
||||
* Limit how many MihomeEnvHours to update.
|
||||
*/
|
||||
limit?: number
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.MihomeEnvHourIncludeUpdateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeEnvHour upsert
|
||||
*/
|
||||
|
||||
@@ -348,7 +348,6 @@ export type MihomeEnvSampleOrderByWithRelationInput = {
|
||||
raw?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
device?: Prisma.MihomeDeviceOrderByWithRelationInput
|
||||
_relevance?: Prisma.MihomeEnvSampleOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type MihomeEnvSampleWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -550,12 +549,6 @@ export type MihomeEnvSampleOrderByRelationAggregateInput = {
|
||||
_count?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type MihomeEnvSampleOrderByRelevanceInput = {
|
||||
fields: Prisma.MihomeEnvSampleOrderByRelevanceFieldEnum | Prisma.MihomeEnvSampleOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type MihomeEnvSampleDeviceIdDateCompoundUniqueInput = {
|
||||
deviceId: number
|
||||
date: Date | string
|
||||
@@ -857,7 +850,43 @@ export type MihomeEnvSampleSelect<ExtArgs extends runtime.Types.Extensions.Inter
|
||||
device?: boolean | Prisma.MihomeDeviceDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["mihomeEnvSample"]>
|
||||
|
||||
export type MihomeEnvSampleSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
deviceId?: boolean
|
||||
date?: boolean
|
||||
temperature?: boolean
|
||||
humidity?: boolean
|
||||
temperatureAvg?: boolean
|
||||
humidityAvg?: boolean
|
||||
temperatureMin?: boolean
|
||||
temperatureMax?: boolean
|
||||
humidityMin?: boolean
|
||||
humidityMax?: boolean
|
||||
origin?: boolean
|
||||
sampledAt?: boolean
|
||||
raw?: boolean
|
||||
createdAt?: boolean
|
||||
device?: boolean | Prisma.MihomeDeviceDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["mihomeEnvSample"]>
|
||||
|
||||
export type MihomeEnvSampleSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
deviceId?: boolean
|
||||
date?: boolean
|
||||
temperature?: boolean
|
||||
humidity?: boolean
|
||||
temperatureAvg?: boolean
|
||||
humidityAvg?: boolean
|
||||
temperatureMin?: boolean
|
||||
temperatureMax?: boolean
|
||||
humidityMin?: boolean
|
||||
humidityMax?: boolean
|
||||
origin?: boolean
|
||||
sampledAt?: boolean
|
||||
raw?: boolean
|
||||
createdAt?: boolean
|
||||
device?: boolean | Prisma.MihomeDeviceDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["mihomeEnvSample"]>
|
||||
|
||||
export type MihomeEnvSampleSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -881,6 +910,12 @@ export type MihomeEnvSampleOmit<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
export type MihomeEnvSampleInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
device?: boolean | Prisma.MihomeDeviceDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type MihomeEnvSampleIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
device?: boolean | Prisma.MihomeDeviceDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type MihomeEnvSampleIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
device?: boolean | Prisma.MihomeDeviceDefaultArgs<ExtArgs>
|
||||
}
|
||||
|
||||
export type $MihomeEnvSamplePayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "MihomeEnvSample"
|
||||
@@ -1020,6 +1055,30 @@ export interface MihomeEnvSampleDelegate<ExtArgs extends runtime.Types.Extension
|
||||
*/
|
||||
createMany<T extends MihomeEnvSampleCreateManyArgs>(args?: Prisma.SelectSubset<T, MihomeEnvSampleCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many MihomeEnvSamples and returns the data saved in the database.
|
||||
* @param {MihomeEnvSampleCreateManyAndReturnArgs} args - Arguments to create many MihomeEnvSamples.
|
||||
* @example
|
||||
* // Create many MihomeEnvSamples
|
||||
* const mihomeEnvSample = await prisma.mihomeEnvSample.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many MihomeEnvSamples and only return the `id`
|
||||
* const mihomeEnvSampleWithIdOnly = await prisma.mihomeEnvSample.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends MihomeEnvSampleCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, MihomeEnvSampleCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$MihomeEnvSamplePayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a MihomeEnvSample.
|
||||
* @param {MihomeEnvSampleDeleteArgs} args - Arguments to delete one MihomeEnvSample.
|
||||
@@ -1084,6 +1143,36 @@ export interface MihomeEnvSampleDelegate<ExtArgs extends runtime.Types.Extension
|
||||
*/
|
||||
updateMany<T extends MihomeEnvSampleUpdateManyArgs>(args: Prisma.SelectSubset<T, MihomeEnvSampleUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more MihomeEnvSamples and returns the data updated in the database.
|
||||
* @param {MihomeEnvSampleUpdateManyAndReturnArgs} args - Arguments to update many MihomeEnvSamples.
|
||||
* @example
|
||||
* // Update many MihomeEnvSamples
|
||||
* const mihomeEnvSample = await prisma.mihomeEnvSample.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more MihomeEnvSamples and only return the `id`
|
||||
* const mihomeEnvSampleWithIdOnly = await prisma.mihomeEnvSample.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends MihomeEnvSampleUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, MihomeEnvSampleUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$MihomeEnvSamplePayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one MihomeEnvSample.
|
||||
* @param {MihomeEnvSampleUpsertArgs} args - Arguments to update or create a MihomeEnvSample.
|
||||
@@ -1525,6 +1614,29 @@ export type MihomeEnvSampleCreateManyArgs<ExtArgs extends runtime.Types.Extensio
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeEnvSample createManyAndReturn
|
||||
*/
|
||||
export type MihomeEnvSampleCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the MihomeEnvSample
|
||||
*/
|
||||
select?: Prisma.MihomeEnvSampleSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the MihomeEnvSample
|
||||
*/
|
||||
omit?: Prisma.MihomeEnvSampleOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many MihomeEnvSamples.
|
||||
*/
|
||||
data: Prisma.MihomeEnvSampleCreateManyInput | Prisma.MihomeEnvSampleCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.MihomeEnvSampleIncludeCreateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeEnvSample update
|
||||
*/
|
||||
@@ -1569,6 +1681,36 @@ export type MihomeEnvSampleUpdateManyArgs<ExtArgs extends runtime.Types.Extensio
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeEnvSample updateManyAndReturn
|
||||
*/
|
||||
export type MihomeEnvSampleUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the MihomeEnvSample
|
||||
*/
|
||||
select?: Prisma.MihomeEnvSampleSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the MihomeEnvSample
|
||||
*/
|
||||
omit?: Prisma.MihomeEnvSampleOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update MihomeEnvSamples.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.MihomeEnvSampleUpdateManyMutationInput, Prisma.MihomeEnvSampleUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which MihomeEnvSamples to update
|
||||
*/
|
||||
where?: Prisma.MihomeEnvSampleWhereInput
|
||||
/**
|
||||
* Limit how many MihomeEnvSamples to update.
|
||||
*/
|
||||
limit?: number
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.MihomeEnvSampleIncludeUpdateManyAndReturn<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeEnvSample upsert
|
||||
*/
|
||||
|
||||
@@ -217,7 +217,6 @@ export type MihomeHomeOrderByWithRelationInput = {
|
||||
name?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
devices?: Prisma.MihomeDeviceOrderByRelationAggregateInput
|
||||
_relevance?: Prisma.MihomeHomeOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type MihomeHomeWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -303,12 +302,6 @@ export type MihomeHomeUncheckedUpdateManyInput = {
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type MihomeHomeOrderByRelevanceInput = {
|
||||
fields: Prisma.MihomeHomeOrderByRelevanceFieldEnum | Prisma.MihomeHomeOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type MihomeHomeCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
homeId?: Prisma.SortOrder
|
||||
@@ -439,7 +432,19 @@ export type MihomeHomeSelect<ExtArgs extends runtime.Types.Extensions.InternalAr
|
||||
_count?: boolean | Prisma.MihomeHomeCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["mihomeHome"]>
|
||||
|
||||
export type MihomeHomeSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
homeId?: boolean
|
||||
name?: boolean
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["mihomeHome"]>
|
||||
|
||||
export type MihomeHomeSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
homeId?: boolean
|
||||
name?: boolean
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["mihomeHome"]>
|
||||
|
||||
export type MihomeHomeSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -453,6 +458,8 @@ export type MihomeHomeInclude<ExtArgs extends runtime.Types.Extensions.InternalA
|
||||
devices?: boolean | Prisma.MihomeHome$devicesArgs<ExtArgs>
|
||||
_count?: boolean | Prisma.MihomeHomeCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}
|
||||
export type MihomeHomeIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {}
|
||||
export type MihomeHomeIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {}
|
||||
|
||||
export type $MihomeHomePayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "MihomeHome"
|
||||
@@ -581,6 +588,30 @@ export interface MihomeHomeDelegate<ExtArgs extends runtime.Types.Extensions.Int
|
||||
*/
|
||||
createMany<T extends MihomeHomeCreateManyArgs>(args?: Prisma.SelectSubset<T, MihomeHomeCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many MihomeHomes and returns the data saved in the database.
|
||||
* @param {MihomeHomeCreateManyAndReturnArgs} args - Arguments to create many MihomeHomes.
|
||||
* @example
|
||||
* // Create many MihomeHomes
|
||||
* const mihomeHome = await prisma.mihomeHome.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many MihomeHomes and only return the `id`
|
||||
* const mihomeHomeWithIdOnly = await prisma.mihomeHome.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends MihomeHomeCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, MihomeHomeCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$MihomeHomePayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a MihomeHome.
|
||||
* @param {MihomeHomeDeleteArgs} args - Arguments to delete one MihomeHome.
|
||||
@@ -645,6 +676,36 @@ export interface MihomeHomeDelegate<ExtArgs extends runtime.Types.Extensions.Int
|
||||
*/
|
||||
updateMany<T extends MihomeHomeUpdateManyArgs>(args: Prisma.SelectSubset<T, MihomeHomeUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more MihomeHomes and returns the data updated in the database.
|
||||
* @param {MihomeHomeUpdateManyAndReturnArgs} args - Arguments to update many MihomeHomes.
|
||||
* @example
|
||||
* // Update many MihomeHomes
|
||||
* const mihomeHome = await prisma.mihomeHome.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more MihomeHomes and only return the `id`
|
||||
* const mihomeHomeWithIdOnly = await prisma.mihomeHome.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends MihomeHomeUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, MihomeHomeUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$MihomeHomePayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one MihomeHome.
|
||||
* @param {MihomeHomeUpsertArgs} args - Arguments to update or create a MihomeHome.
|
||||
@@ -1075,6 +1136,25 @@ export type MihomeHomeCreateManyArgs<ExtArgs extends runtime.Types.Extensions.In
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeHome createManyAndReturn
|
||||
*/
|
||||
export type MihomeHomeCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the MihomeHome
|
||||
*/
|
||||
select?: Prisma.MihomeHomeSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the MihomeHome
|
||||
*/
|
||||
omit?: Prisma.MihomeHomeOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many MihomeHomes.
|
||||
*/
|
||||
data: Prisma.MihomeHomeCreateManyInput | Prisma.MihomeHomeCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeHome update
|
||||
*/
|
||||
@@ -1119,6 +1199,32 @@ export type MihomeHomeUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.In
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeHome updateManyAndReturn
|
||||
*/
|
||||
export type MihomeHomeUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the MihomeHome
|
||||
*/
|
||||
select?: Prisma.MihomeHomeSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the MihomeHome
|
||||
*/
|
||||
omit?: Prisma.MihomeHomeOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update MihomeHomes.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.MihomeHomeUpdateManyMutationInput, Prisma.MihomeHomeUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which MihomeHomes to update
|
||||
*/
|
||||
where?: Prisma.MihomeHomeWhereInput
|
||||
/**
|
||||
* Limit how many MihomeHomes to update.
|
||||
*/
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* MihomeHome upsert
|
||||
*/
|
||||
|
||||
@@ -264,7 +264,6 @@ export type NewsOrderByWithRelationInput = {
|
||||
publishedAt?: Prisma.SortOrder
|
||||
impactRank?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
_relevance?: Prisma.NewsOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type NewsWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -396,12 +395,6 @@ export type NewsUncheckedUpdateManyInput = {
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type NewsOrderByRelevanceInput = {
|
||||
fields: Prisma.NewsOrderByRelevanceFieldEnum | Prisma.NewsOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type NewsTitlePublishedAtCompoundUniqueInput = {
|
||||
title: string
|
||||
publishedAt: Date | string
|
||||
@@ -471,7 +464,29 @@ export type NewsSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = r
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["news"]>
|
||||
|
||||
export type NewsSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
title?: boolean
|
||||
summary?: boolean
|
||||
content?: boolean
|
||||
source?: boolean
|
||||
url?: boolean
|
||||
publishedAt?: boolean
|
||||
impactRank?: boolean
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["news"]>
|
||||
|
||||
export type NewsSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
title?: boolean
|
||||
summary?: boolean
|
||||
content?: boolean
|
||||
source?: boolean
|
||||
url?: boolean
|
||||
publishedAt?: boolean
|
||||
impactRank?: boolean
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["news"]>
|
||||
|
||||
export type NewsSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -617,6 +632,30 @@ export interface NewsDelegate<ExtArgs extends runtime.Types.Extensions.InternalA
|
||||
*/
|
||||
createMany<T extends NewsCreateManyArgs>(args?: Prisma.SelectSubset<T, NewsCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many News and returns the data saved in the database.
|
||||
* @param {NewsCreateManyAndReturnArgs} args - Arguments to create many News.
|
||||
* @example
|
||||
* // Create many News
|
||||
* const news = await prisma.news.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many News and only return the `id`
|
||||
* const newsWithIdOnly = await prisma.news.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends NewsCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, NewsCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$NewsPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a News.
|
||||
* @param {NewsDeleteArgs} args - Arguments to delete one News.
|
||||
@@ -681,6 +720,36 @@ export interface NewsDelegate<ExtArgs extends runtime.Types.Extensions.InternalA
|
||||
*/
|
||||
updateMany<T extends NewsUpdateManyArgs>(args: Prisma.SelectSubset<T, NewsUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more News and returns the data updated in the database.
|
||||
* @param {NewsUpdateManyAndReturnArgs} args - Arguments to update many News.
|
||||
* @example
|
||||
* // Update many News
|
||||
* const news = await prisma.news.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more News and only return the `id`
|
||||
* const newsWithIdOnly = await prisma.news.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends NewsUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, NewsUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$NewsPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one News.
|
||||
* @param {NewsUpsertArgs} args - Arguments to update or create a News.
|
||||
@@ -1091,6 +1160,25 @@ export type NewsCreateManyArgs<ExtArgs extends runtime.Types.Extensions.Internal
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* News createManyAndReturn
|
||||
*/
|
||||
export type NewsCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the News
|
||||
*/
|
||||
select?: Prisma.NewsSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the News
|
||||
*/
|
||||
omit?: Prisma.NewsOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many News.
|
||||
*/
|
||||
data: Prisma.NewsCreateManyInput | Prisma.NewsCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* News update
|
||||
*/
|
||||
@@ -1131,6 +1219,32 @@ export type NewsUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.Internal
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* News updateManyAndReturn
|
||||
*/
|
||||
export type NewsUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the News
|
||||
*/
|
||||
select?: Prisma.NewsSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the News
|
||||
*/
|
||||
omit?: Prisma.NewsOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update News.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.NewsUpdateManyMutationInput, Prisma.NewsUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which News to update
|
||||
*/
|
||||
where?: Prisma.NewsWhereInput
|
||||
/**
|
||||
* Limit how many News to update.
|
||||
*/
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* News upsert
|
||||
*/
|
||||
|
||||
@@ -246,7 +246,6 @@ export type OilPriceHistoryOrderByWithRelationInput = {
|
||||
price?: Prisma.SortOrder
|
||||
source?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
_relevance?: Prisma.OilPriceHistoryOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type OilPriceHistoryWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -358,12 +357,6 @@ export type OilPriceHistoryUncheckedUpdateManyInput = {
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type OilPriceHistoryOrderByRelevanceInput = {
|
||||
fields: Prisma.OilPriceHistoryOrderByRelevanceFieldEnum | Prisma.OilPriceHistoryOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type OilPriceHistoryDateProvinceFuelCompoundUniqueInput = {
|
||||
date: Date | string
|
||||
province: string
|
||||
@@ -422,7 +415,25 @@ export type OilPriceHistorySelect<ExtArgs extends runtime.Types.Extensions.Inter
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["oilPriceHistory"]>
|
||||
|
||||
export type OilPriceHistorySelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
date?: boolean
|
||||
province?: boolean
|
||||
fuel?: boolean
|
||||
price?: boolean
|
||||
source?: boolean
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["oilPriceHistory"]>
|
||||
|
||||
export type OilPriceHistorySelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
date?: boolean
|
||||
province?: boolean
|
||||
fuel?: boolean
|
||||
price?: boolean
|
||||
source?: boolean
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["oilPriceHistory"]>
|
||||
|
||||
export type OilPriceHistorySelectScalar = {
|
||||
id?: boolean
|
||||
@@ -564,6 +575,30 @@ export interface OilPriceHistoryDelegate<ExtArgs extends runtime.Types.Extension
|
||||
*/
|
||||
createMany<T extends OilPriceHistoryCreateManyArgs>(args?: Prisma.SelectSubset<T, OilPriceHistoryCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many OilPriceHistories and returns the data saved in the database.
|
||||
* @param {OilPriceHistoryCreateManyAndReturnArgs} args - Arguments to create many OilPriceHistories.
|
||||
* @example
|
||||
* // Create many OilPriceHistories
|
||||
* const oilPriceHistory = await prisma.oilPriceHistory.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many OilPriceHistories and only return the `id`
|
||||
* const oilPriceHistoryWithIdOnly = await prisma.oilPriceHistory.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends OilPriceHistoryCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, OilPriceHistoryCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$OilPriceHistoryPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a OilPriceHistory.
|
||||
* @param {OilPriceHistoryDeleteArgs} args - Arguments to delete one OilPriceHistory.
|
||||
@@ -628,6 +663,36 @@ export interface OilPriceHistoryDelegate<ExtArgs extends runtime.Types.Extension
|
||||
*/
|
||||
updateMany<T extends OilPriceHistoryUpdateManyArgs>(args: Prisma.SelectSubset<T, OilPriceHistoryUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more OilPriceHistories and returns the data updated in the database.
|
||||
* @param {OilPriceHistoryUpdateManyAndReturnArgs} args - Arguments to update many OilPriceHistories.
|
||||
* @example
|
||||
* // Update many OilPriceHistories
|
||||
* const oilPriceHistory = await prisma.oilPriceHistory.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more OilPriceHistories and only return the `id`
|
||||
* const oilPriceHistoryWithIdOnly = await prisma.oilPriceHistory.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends OilPriceHistoryUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, OilPriceHistoryUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$OilPriceHistoryPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one OilPriceHistory.
|
||||
* @param {OilPriceHistoryUpsertArgs} args - Arguments to update or create a OilPriceHistory.
|
||||
@@ -1036,6 +1101,25 @@ export type OilPriceHistoryCreateManyArgs<ExtArgs extends runtime.Types.Extensio
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* OilPriceHistory createManyAndReturn
|
||||
*/
|
||||
export type OilPriceHistoryCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the OilPriceHistory
|
||||
*/
|
||||
select?: Prisma.OilPriceHistorySelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the OilPriceHistory
|
||||
*/
|
||||
omit?: Prisma.OilPriceHistoryOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many OilPriceHistories.
|
||||
*/
|
||||
data: Prisma.OilPriceHistoryCreateManyInput | Prisma.OilPriceHistoryCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* OilPriceHistory update
|
||||
*/
|
||||
@@ -1076,6 +1160,32 @@ export type OilPriceHistoryUpdateManyArgs<ExtArgs extends runtime.Types.Extensio
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* OilPriceHistory updateManyAndReturn
|
||||
*/
|
||||
export type OilPriceHistoryUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the OilPriceHistory
|
||||
*/
|
||||
select?: Prisma.OilPriceHistorySelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the OilPriceHistory
|
||||
*/
|
||||
omit?: Prisma.OilPriceHistoryOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update OilPriceHistories.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.OilPriceHistoryUpdateManyMutationInput, Prisma.OilPriceHistoryUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which OilPriceHistories to update
|
||||
*/
|
||||
where?: Prisma.OilPriceHistoryWhereInput
|
||||
/**
|
||||
* Limit how many OilPriceHistories to update.
|
||||
*/
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* OilPriceHistory upsert
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -238,7 +238,6 @@ export type ScraperCacheOrderByWithRelationInput = {
|
||||
metadata?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
_relevance?: Prisma.ScraperCacheOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type ScraperCacheWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -349,12 +348,6 @@ export type ScraperCacheUncheckedUpdateManyInput = {
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type ScraperCacheOrderByRelevanceInput = {
|
||||
fields: Prisma.ScraperCacheOrderByRelevanceFieldEnum | Prisma.ScraperCacheOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type ScraperCacheCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
scraperName?: Prisma.SortOrder
|
||||
@@ -403,7 +396,25 @@ export type ScraperCacheSelect<ExtArgs extends runtime.Types.Extensions.Internal
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["scraperCache"]>
|
||||
|
||||
export type ScraperCacheSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
scraperName?: boolean
|
||||
lastDataHash?: boolean
|
||||
lastUpdateAt?: boolean
|
||||
metadata?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["scraperCache"]>
|
||||
|
||||
export type ScraperCacheSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
scraperName?: boolean
|
||||
lastDataHash?: boolean
|
||||
lastUpdateAt?: boolean
|
||||
metadata?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["scraperCache"]>
|
||||
|
||||
export type ScraperCacheSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -545,6 +556,30 @@ export interface ScraperCacheDelegate<ExtArgs extends runtime.Types.Extensions.I
|
||||
*/
|
||||
createMany<T extends ScraperCacheCreateManyArgs>(args?: Prisma.SelectSubset<T, ScraperCacheCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many ScraperCaches and returns the data saved in the database.
|
||||
* @param {ScraperCacheCreateManyAndReturnArgs} args - Arguments to create many ScraperCaches.
|
||||
* @example
|
||||
* // Create many ScraperCaches
|
||||
* const scraperCache = await prisma.scraperCache.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many ScraperCaches and only return the `id`
|
||||
* const scraperCacheWithIdOnly = await prisma.scraperCache.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends ScraperCacheCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, ScraperCacheCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ScraperCachePayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a ScraperCache.
|
||||
* @param {ScraperCacheDeleteArgs} args - Arguments to delete one ScraperCache.
|
||||
@@ -609,6 +644,36 @@ export interface ScraperCacheDelegate<ExtArgs extends runtime.Types.Extensions.I
|
||||
*/
|
||||
updateMany<T extends ScraperCacheUpdateManyArgs>(args: Prisma.SelectSubset<T, ScraperCacheUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more ScraperCaches and returns the data updated in the database.
|
||||
* @param {ScraperCacheUpdateManyAndReturnArgs} args - Arguments to update many ScraperCaches.
|
||||
* @example
|
||||
* // Update many ScraperCaches
|
||||
* const scraperCache = await prisma.scraperCache.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more ScraperCaches and only return the `id`
|
||||
* const scraperCacheWithIdOnly = await prisma.scraperCache.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends ScraperCacheUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, ScraperCacheUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ScraperCachePayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one ScraperCache.
|
||||
* @param {ScraperCacheUpsertArgs} args - Arguments to update or create a ScraperCache.
|
||||
@@ -1017,6 +1082,25 @@ export type ScraperCacheCreateManyArgs<ExtArgs extends runtime.Types.Extensions.
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* ScraperCache createManyAndReturn
|
||||
*/
|
||||
export type ScraperCacheCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the ScraperCache
|
||||
*/
|
||||
select?: Prisma.ScraperCacheSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the ScraperCache
|
||||
*/
|
||||
omit?: Prisma.ScraperCacheOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many ScraperCaches.
|
||||
*/
|
||||
data: Prisma.ScraperCacheCreateManyInput | Prisma.ScraperCacheCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* ScraperCache update
|
||||
*/
|
||||
@@ -1057,6 +1141,32 @@ export type ScraperCacheUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* ScraperCache updateManyAndReturn
|
||||
*/
|
||||
export type ScraperCacheUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the ScraperCache
|
||||
*/
|
||||
select?: Prisma.ScraperCacheSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the ScraperCache
|
||||
*/
|
||||
omit?: Prisma.ScraperCacheOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update ScraperCaches.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.ScraperCacheUpdateManyMutationInput, Prisma.ScraperCacheUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which ScraperCaches to update
|
||||
*/
|
||||
where?: Prisma.ScraperCacheWhereInput
|
||||
/**
|
||||
* Limit how many ScraperCaches to update.
|
||||
*/
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* ScraperCache upsert
|
||||
*/
|
||||
|
||||
@@ -464,7 +464,6 @@ export type ServerNodeOrderByWithRelationInput = {
|
||||
recordedAt?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
_relevance?: Prisma.ServerNodeOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type ServerNodeWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -755,12 +754,6 @@ export type ServerNodeUncheckedUpdateManyInput = {
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type ServerNodeOrderByRelevanceInput = {
|
||||
fields: Prisma.ServerNodeOrderByRelevanceFieldEnum | Prisma.ServerNodeOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type ServerNodeCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
uuid?: Prisma.SortOrder
|
||||
@@ -921,7 +914,61 @@ export type ServerNodeSelect<ExtArgs extends runtime.Types.Extensions.InternalAr
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["serverNode"]>
|
||||
|
||||
export type ServerNodeSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
uuid?: boolean
|
||||
name?: boolean
|
||||
cpuName?: boolean
|
||||
os?: boolean
|
||||
region?: boolean
|
||||
memTotal?: boolean
|
||||
diskTotal?: boolean
|
||||
cpuCores?: boolean
|
||||
cpuUsage?: boolean
|
||||
ramUsed?: boolean
|
||||
swapUsed?: boolean
|
||||
load1?: boolean
|
||||
load5?: boolean
|
||||
load15?: boolean
|
||||
diskUsed?: boolean
|
||||
netIn?: boolean
|
||||
netOut?: boolean
|
||||
uptime?: boolean
|
||||
process?: boolean
|
||||
connections?: boolean
|
||||
status?: boolean
|
||||
recordedAt?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["serverNode"]>
|
||||
|
||||
export type ServerNodeSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
uuid?: boolean
|
||||
name?: boolean
|
||||
cpuName?: boolean
|
||||
os?: boolean
|
||||
region?: boolean
|
||||
memTotal?: boolean
|
||||
diskTotal?: boolean
|
||||
cpuCores?: boolean
|
||||
cpuUsage?: boolean
|
||||
ramUsed?: boolean
|
||||
swapUsed?: boolean
|
||||
load1?: boolean
|
||||
load5?: boolean
|
||||
load15?: boolean
|
||||
diskUsed?: boolean
|
||||
netIn?: boolean
|
||||
netOut?: boolean
|
||||
uptime?: boolean
|
||||
process?: boolean
|
||||
connections?: boolean
|
||||
status?: boolean
|
||||
recordedAt?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["serverNode"]>
|
||||
|
||||
export type ServerNodeSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -1099,6 +1146,30 @@ export interface ServerNodeDelegate<ExtArgs extends runtime.Types.Extensions.Int
|
||||
*/
|
||||
createMany<T extends ServerNodeCreateManyArgs>(args?: Prisma.SelectSubset<T, ServerNodeCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many ServerNodes and returns the data saved in the database.
|
||||
* @param {ServerNodeCreateManyAndReturnArgs} args - Arguments to create many ServerNodes.
|
||||
* @example
|
||||
* // Create many ServerNodes
|
||||
* const serverNode = await prisma.serverNode.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many ServerNodes and only return the `id`
|
||||
* const serverNodeWithIdOnly = await prisma.serverNode.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends ServerNodeCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, ServerNodeCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ServerNodePayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a ServerNode.
|
||||
* @param {ServerNodeDeleteArgs} args - Arguments to delete one ServerNode.
|
||||
@@ -1163,6 +1234,36 @@ export interface ServerNodeDelegate<ExtArgs extends runtime.Types.Extensions.Int
|
||||
*/
|
||||
updateMany<T extends ServerNodeUpdateManyArgs>(args: Prisma.SelectSubset<T, ServerNodeUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more ServerNodes and returns the data updated in the database.
|
||||
* @param {ServerNodeUpdateManyAndReturnArgs} args - Arguments to update many ServerNodes.
|
||||
* @example
|
||||
* // Update many ServerNodes
|
||||
* const serverNode = await prisma.serverNode.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more ServerNodes and only return the `id`
|
||||
* const serverNodeWithIdOnly = await prisma.serverNode.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends ServerNodeUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, ServerNodeUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ServerNodePayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one ServerNode.
|
||||
* @param {ServerNodeUpsertArgs} args - Arguments to update or create a ServerNode.
|
||||
@@ -1589,6 +1690,25 @@ export type ServerNodeCreateManyArgs<ExtArgs extends runtime.Types.Extensions.In
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* ServerNode createManyAndReturn
|
||||
*/
|
||||
export type ServerNodeCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the ServerNode
|
||||
*/
|
||||
select?: Prisma.ServerNodeSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the ServerNode
|
||||
*/
|
||||
omit?: Prisma.ServerNodeOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many ServerNodes.
|
||||
*/
|
||||
data: Prisma.ServerNodeCreateManyInput | Prisma.ServerNodeCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* ServerNode update
|
||||
*/
|
||||
@@ -1629,6 +1749,32 @@ export type ServerNodeUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.In
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* ServerNode updateManyAndReturn
|
||||
*/
|
||||
export type ServerNodeUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the ServerNode
|
||||
*/
|
||||
select?: Prisma.ServerNodeSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the ServerNode
|
||||
*/
|
||||
omit?: Prisma.ServerNodeOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update ServerNodes.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.ServerNodeUpdateManyMutationInput, Prisma.ServerNodeUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which ServerNodes to update
|
||||
*/
|
||||
where?: Prisma.ServerNodeWhereInput
|
||||
/**
|
||||
* Limit how many ServerNodes to update.
|
||||
*/
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* ServerNode upsert
|
||||
*/
|
||||
|
||||
@@ -319,7 +319,6 @@ export type ServerNodeHistoryOrderByWithRelationInput = {
|
||||
process?: Prisma.SortOrder
|
||||
connections?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
_relevance?: Prisma.ServerNodeHistoryOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type ServerNodeHistoryWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -481,12 +480,6 @@ export type ServerNodeHistoryUncheckedUpdateManyInput = {
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type ServerNodeHistoryOrderByRelevanceInput = {
|
||||
fields: Prisma.ServerNodeHistoryOrderByRelevanceFieldEnum | Prisma.ServerNodeHistoryOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type ServerNodeHistoryUuidPeriodCompoundUniqueInput = {
|
||||
uuid: string
|
||||
period: Date | string
|
||||
@@ -578,7 +571,35 @@ export type ServerNodeHistorySelect<ExtArgs extends runtime.Types.Extensions.Int
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["serverNodeHistory"]>
|
||||
|
||||
export type ServerNodeHistorySelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
uuid?: boolean
|
||||
period?: boolean
|
||||
cpu?: boolean
|
||||
ram?: boolean
|
||||
load?: boolean
|
||||
disk?: boolean
|
||||
netIn?: boolean
|
||||
netOut?: boolean
|
||||
process?: boolean
|
||||
connections?: boolean
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["serverNodeHistory"]>
|
||||
|
||||
export type ServerNodeHistorySelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
uuid?: boolean
|
||||
period?: boolean
|
||||
cpu?: boolean
|
||||
ram?: boolean
|
||||
load?: boolean
|
||||
disk?: boolean
|
||||
netIn?: boolean
|
||||
netOut?: boolean
|
||||
process?: boolean
|
||||
connections?: boolean
|
||||
createdAt?: boolean
|
||||
}, ExtArgs["result"]["serverNodeHistory"]>
|
||||
|
||||
export type ServerNodeHistorySelectScalar = {
|
||||
id?: boolean
|
||||
@@ -730,6 +751,30 @@ export interface ServerNodeHistoryDelegate<ExtArgs extends runtime.Types.Extensi
|
||||
*/
|
||||
createMany<T extends ServerNodeHistoryCreateManyArgs>(args?: Prisma.SelectSubset<T, ServerNodeHistoryCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many ServerNodeHistories and returns the data saved in the database.
|
||||
* @param {ServerNodeHistoryCreateManyAndReturnArgs} args - Arguments to create many ServerNodeHistories.
|
||||
* @example
|
||||
* // Create many ServerNodeHistories
|
||||
* const serverNodeHistory = await prisma.serverNodeHistory.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many ServerNodeHistories and only return the `id`
|
||||
* const serverNodeHistoryWithIdOnly = await prisma.serverNodeHistory.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends ServerNodeHistoryCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, ServerNodeHistoryCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ServerNodeHistoryPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a ServerNodeHistory.
|
||||
* @param {ServerNodeHistoryDeleteArgs} args - Arguments to delete one ServerNodeHistory.
|
||||
@@ -794,6 +839,36 @@ export interface ServerNodeHistoryDelegate<ExtArgs extends runtime.Types.Extensi
|
||||
*/
|
||||
updateMany<T extends ServerNodeHistoryUpdateManyArgs>(args: Prisma.SelectSubset<T, ServerNodeHistoryUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more ServerNodeHistories and returns the data updated in the database.
|
||||
* @param {ServerNodeHistoryUpdateManyAndReturnArgs} args - Arguments to update many ServerNodeHistories.
|
||||
* @example
|
||||
* // Update many ServerNodeHistories
|
||||
* const serverNodeHistory = await prisma.serverNodeHistory.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more ServerNodeHistories and only return the `id`
|
||||
* const serverNodeHistoryWithIdOnly = await prisma.serverNodeHistory.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends ServerNodeHistoryUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, ServerNodeHistoryUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ServerNodeHistoryPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one ServerNodeHistory.
|
||||
* @param {ServerNodeHistoryUpsertArgs} args - Arguments to update or create a ServerNodeHistory.
|
||||
@@ -1207,6 +1282,25 @@ export type ServerNodeHistoryCreateManyArgs<ExtArgs extends runtime.Types.Extens
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* ServerNodeHistory createManyAndReturn
|
||||
*/
|
||||
export type ServerNodeHistoryCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the ServerNodeHistory
|
||||
*/
|
||||
select?: Prisma.ServerNodeHistorySelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the ServerNodeHistory
|
||||
*/
|
||||
omit?: Prisma.ServerNodeHistoryOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many ServerNodeHistories.
|
||||
*/
|
||||
data: Prisma.ServerNodeHistoryCreateManyInput | Prisma.ServerNodeHistoryCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* ServerNodeHistory update
|
||||
*/
|
||||
@@ -1247,6 +1341,32 @@ export type ServerNodeHistoryUpdateManyArgs<ExtArgs extends runtime.Types.Extens
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* ServerNodeHistory updateManyAndReturn
|
||||
*/
|
||||
export type ServerNodeHistoryUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the ServerNodeHistory
|
||||
*/
|
||||
select?: Prisma.ServerNodeHistorySelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the ServerNodeHistory
|
||||
*/
|
||||
omit?: Prisma.ServerNodeHistoryOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update ServerNodeHistories.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.ServerNodeHistoryUpdateManyMutationInput, Prisma.ServerNodeHistoryUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which ServerNodeHistories to update
|
||||
*/
|
||||
where?: Prisma.ServerNodeHistoryWhereInput
|
||||
/**
|
||||
* Limit how many ServerNodeHistories to update.
|
||||
*/
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* ServerNodeHistory upsert
|
||||
*/
|
||||
|
||||
@@ -264,7 +264,6 @@ export type ServiceCheckOrderByWithRelationInput = {
|
||||
lastCheckAt?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
_relevance?: Prisma.ServiceCheckOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type ServiceCheckWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -395,12 +394,6 @@ export type ServiceCheckUncheckedUpdateManyInput = {
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type ServiceCheckOrderByRelevanceInput = {
|
||||
fields: Prisma.ServiceCheckOrderByRelevanceFieldEnum | Prisma.ServiceCheckOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type ServiceCheckCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
name?: Prisma.SortOrder
|
||||
@@ -461,7 +454,29 @@ export type ServiceCheckSelect<ExtArgs extends runtime.Types.Extensions.Internal
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["serviceCheck"]>
|
||||
|
||||
export type ServiceCheckSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
name?: boolean
|
||||
url?: boolean
|
||||
status?: boolean
|
||||
latencyMs?: boolean
|
||||
message?: boolean
|
||||
lastCheckAt?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["serviceCheck"]>
|
||||
|
||||
export type ServiceCheckSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
name?: boolean
|
||||
url?: boolean
|
||||
status?: boolean
|
||||
latencyMs?: boolean
|
||||
message?: boolean
|
||||
lastCheckAt?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["serviceCheck"]>
|
||||
|
||||
export type ServiceCheckSelectScalar = {
|
||||
id?: boolean
|
||||
@@ -607,6 +622,30 @@ export interface ServiceCheckDelegate<ExtArgs extends runtime.Types.Extensions.I
|
||||
*/
|
||||
createMany<T extends ServiceCheckCreateManyArgs>(args?: Prisma.SelectSubset<T, ServiceCheckCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many ServiceChecks and returns the data saved in the database.
|
||||
* @param {ServiceCheckCreateManyAndReturnArgs} args - Arguments to create many ServiceChecks.
|
||||
* @example
|
||||
* // Create many ServiceChecks
|
||||
* const serviceCheck = await prisma.serviceCheck.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many ServiceChecks and only return the `id`
|
||||
* const serviceCheckWithIdOnly = await prisma.serviceCheck.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends ServiceCheckCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, ServiceCheckCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ServiceCheckPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a ServiceCheck.
|
||||
* @param {ServiceCheckDeleteArgs} args - Arguments to delete one ServiceCheck.
|
||||
@@ -671,6 +710,36 @@ export interface ServiceCheckDelegate<ExtArgs extends runtime.Types.Extensions.I
|
||||
*/
|
||||
updateMany<T extends ServiceCheckUpdateManyArgs>(args: Prisma.SelectSubset<T, ServiceCheckUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more ServiceChecks and returns the data updated in the database.
|
||||
* @param {ServiceCheckUpdateManyAndReturnArgs} args - Arguments to update many ServiceChecks.
|
||||
* @example
|
||||
* // Update many ServiceChecks
|
||||
* const serviceCheck = await prisma.serviceCheck.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more ServiceChecks and only return the `id`
|
||||
* const serviceCheckWithIdOnly = await prisma.serviceCheck.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends ServiceCheckUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, ServiceCheckUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$ServiceCheckPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one ServiceCheck.
|
||||
* @param {ServiceCheckUpsertArgs} args - Arguments to update or create a ServiceCheck.
|
||||
@@ -1081,6 +1150,25 @@ export type ServiceCheckCreateManyArgs<ExtArgs extends runtime.Types.Extensions.
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* ServiceCheck createManyAndReturn
|
||||
*/
|
||||
export type ServiceCheckCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the ServiceCheck
|
||||
*/
|
||||
select?: Prisma.ServiceCheckSelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the ServiceCheck
|
||||
*/
|
||||
omit?: Prisma.ServiceCheckOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many ServiceChecks.
|
||||
*/
|
||||
data: Prisma.ServiceCheckCreateManyInput | Prisma.ServiceCheckCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* ServiceCheck update
|
||||
*/
|
||||
@@ -1121,6 +1209,32 @@ export type ServiceCheckUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* ServiceCheck updateManyAndReturn
|
||||
*/
|
||||
export type ServiceCheckUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the ServiceCheck
|
||||
*/
|
||||
select?: Prisma.ServiceCheckSelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the ServiceCheck
|
||||
*/
|
||||
omit?: Prisma.ServiceCheckOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update ServiceChecks.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.ServiceCheckUpdateManyMutationInput, Prisma.ServiceCheckUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which ServiceChecks to update
|
||||
*/
|
||||
where?: Prisma.ServiceCheckWhereInput
|
||||
/**
|
||||
* Limit how many ServiceChecks to update.
|
||||
*/
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* ServiceCheck upsert
|
||||
*/
|
||||
|
||||
@@ -229,7 +229,6 @@ export type StrategyOrderByWithRelationInput = {
|
||||
data?: Prisma.SortOrder
|
||||
createdAt?: Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
_relevance?: Prisma.StrategyOrderByRelevanceInput
|
||||
}
|
||||
|
||||
export type StrategyWhereUniqueInput = Prisma.AtLeast<{
|
||||
@@ -330,12 +329,6 @@ export type StrategyUncheckedUpdateManyInput = {
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type StrategyOrderByRelevanceInput = {
|
||||
fields: Prisma.StrategyOrderByRelevanceFieldEnum | Prisma.StrategyOrderByRelevanceFieldEnum[]
|
||||
sort: Prisma.SortOrder
|
||||
search: string
|
||||
}
|
||||
|
||||
export type StrategyCountOrderByAggregateInput = {
|
||||
id?: Prisma.SortOrder
|
||||
name?: Prisma.SortOrder
|
||||
@@ -380,7 +373,23 @@ export type StrategySelect<ExtArgs extends runtime.Types.Extensions.InternalArgs
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["strategy"]>
|
||||
|
||||
export type StrategySelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
name?: boolean
|
||||
description?: boolean
|
||||
data?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["strategy"]>
|
||||
|
||||
export type StrategySelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
name?: boolean
|
||||
description?: boolean
|
||||
data?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}, ExtArgs["result"]["strategy"]>
|
||||
|
||||
export type StrategySelectScalar = {
|
||||
id?: boolean
|
||||
@@ -520,6 +529,30 @@ export interface StrategyDelegate<ExtArgs extends runtime.Types.Extensions.Inter
|
||||
*/
|
||||
createMany<T extends StrategyCreateManyArgs>(args?: Prisma.SelectSubset<T, StrategyCreateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Create many Strategies and returns the data saved in the database.
|
||||
* @param {StrategyCreateManyAndReturnArgs} args - Arguments to create many Strategies.
|
||||
* @example
|
||||
* // Create many Strategies
|
||||
* const strategy = await prisma.strategy.createManyAndReturn({
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Create many Strategies and only return the `id`
|
||||
* const strategyWithIdOnly = await prisma.strategy.createManyAndReturn({
|
||||
* select: { id: true },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
createManyAndReturn<T extends StrategyCreateManyAndReturnArgs>(args?: Prisma.SelectSubset<T, StrategyCreateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$StrategyPayload<ExtArgs>, T, "createManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Delete a Strategy.
|
||||
* @param {StrategyDeleteArgs} args - Arguments to delete one Strategy.
|
||||
@@ -584,6 +617,36 @@ export interface StrategyDelegate<ExtArgs extends runtime.Types.Extensions.Inter
|
||||
*/
|
||||
updateMany<T extends StrategyUpdateManyArgs>(args: Prisma.SelectSubset<T, StrategyUpdateManyArgs<ExtArgs>>): Prisma.PrismaPromise<Prisma.BatchPayload>
|
||||
|
||||
/**
|
||||
* Update zero or more Strategies and returns the data updated in the database.
|
||||
* @param {StrategyUpdateManyAndReturnArgs} args - Arguments to update many Strategies.
|
||||
* @example
|
||||
* // Update many Strategies
|
||||
* const strategy = await prisma.strategy.updateManyAndReturn({
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
*
|
||||
* // Update zero or more Strategies and only return the `id`
|
||||
* const strategyWithIdOnly = await prisma.strategy.updateManyAndReturn({
|
||||
* select: { id: true },
|
||||
* where: {
|
||||
* // ... provide filter here
|
||||
* },
|
||||
* data: [
|
||||
* // ... provide data here
|
||||
* ]
|
||||
* })
|
||||
* Note, that providing `undefined` is treated as the value not being there.
|
||||
* Read more here: https://pris.ly/d/null-undefined
|
||||
*
|
||||
*/
|
||||
updateManyAndReturn<T extends StrategyUpdateManyAndReturnArgs>(args: Prisma.SelectSubset<T, StrategyUpdateManyAndReturnArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$StrategyPayload<ExtArgs>, T, "updateManyAndReturn", GlobalOmitOptions>>
|
||||
|
||||
/**
|
||||
* Create or update one Strategy.
|
||||
* @param {StrategyUpsertArgs} args - Arguments to update or create a Strategy.
|
||||
@@ -991,6 +1054,25 @@ export type StrategyCreateManyArgs<ExtArgs extends runtime.Types.Extensions.Inte
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy createManyAndReturn
|
||||
*/
|
||||
export type StrategyCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the Strategy
|
||||
*/
|
||||
select?: Prisma.StrategySelectCreateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the Strategy
|
||||
*/
|
||||
omit?: Prisma.StrategyOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to create many Strategies.
|
||||
*/
|
||||
data: Prisma.StrategyCreateManyInput | Prisma.StrategyCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy update
|
||||
*/
|
||||
@@ -1031,6 +1113,32 @@ export type StrategyUpdateManyArgs<ExtArgs extends runtime.Types.Extensions.Inte
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy updateManyAndReturn
|
||||
*/
|
||||
export type StrategyUpdateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the Strategy
|
||||
*/
|
||||
select?: Prisma.StrategySelectUpdateManyAndReturn<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the Strategy
|
||||
*/
|
||||
omit?: Prisma.StrategyOmit<ExtArgs> | null
|
||||
/**
|
||||
* The data used to update Strategies.
|
||||
*/
|
||||
data: Prisma.XOR<Prisma.StrategyUpdateManyMutationInput, Prisma.StrategyUncheckedUpdateManyInput>
|
||||
/**
|
||||
* Filter which Strategies to update
|
||||
*/
|
||||
where?: Prisma.StrategyWhereInput
|
||||
/**
|
||||
* Limit how many Strategies to update.
|
||||
*/
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy upsert
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Generated
+340
-122
@@ -1,14 +1,17 @@
|
||||
{
|
||||
"name": "iboard",
|
||||
"version": "1.0.0",
|
||||
"version": "0.2.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "iboard",
|
||||
"version": "1.0.0",
|
||||
"version": "0.2.1",
|
||||
"dependencies": {
|
||||
"@prisma/adapter-mariadb": "^7.9.1",
|
||||
"@journeyapps/wa-sqlite": "^2.0.7",
|
||||
"@powersync/react": "^2.1.0",
|
||||
"@powersync/web": "^2.5.0",
|
||||
"@prisma/adapter-pg": "^7.9.1",
|
||||
"@prisma/client": "^7.7.0",
|
||||
"@zythum02/mijia-api": "^0.1.4",
|
||||
"antd-mobile": "^5.42.3",
|
||||
@@ -30,8 +33,8 @@
|
||||
"ws": "^8.21.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/api": "^2.0.0",
|
||||
"@tauri-apps/cli": "^2.0.0",
|
||||
"@tauri-apps/api": "^2.12.4",
|
||||
"@tauri-apps/cli": "^2.12.4",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"cheerio": "^1.2.0",
|
||||
"concurrently": "^9.0.0",
|
||||
@@ -1187,6 +1190,11 @@
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@journeyapps/wa-sqlite": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@journeyapps/wa-sqlite/-/wa-sqlite-2.0.8.tgz",
|
||||
"integrity": "sha512-WRXEms2515S/0DFSWzmlggHu9hSJomhugDUO17rWkL6VpokV/hfjIDLs954Egx/eqrk3WADmiOMzOc7MuJbznQ=="
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.13",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||
@@ -1615,64 +1623,91 @@
|
||||
"node": "^22.20 || ^24.12 || >=25"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/adapter-mariadb": {
|
||||
"version": "7.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/adapter-mariadb/-/adapter-mariadb-7.9.1.tgz",
|
||||
"integrity": "sha512-4aZUbIg2av7XFSQyM9cQeAp9YP9HiPr8H7ehe2rDo375IZXILEzQrNXZ/zLetgRQ2ojlaUl/brArFdOVS3n1xA==",
|
||||
"node_modules/@powersync/common": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@powersync/common/-/common-2.4.0.tgz",
|
||||
"integrity": "sha512-ngVogy+B8NQeI5l+0Es8qMxnGozUie8Q6R4+0/AHA3oBAhDG5UmeYw/LquTzZJSOPnCmvGgFSqovblV+JKzxKQ==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@powersync/react": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@powersync/react/-/react-2.1.0.tgz",
|
||||
"integrity": "sha512-ADIpakSLhstv0F9xrUIF+oCArFnAQPrcB9mNql6xH0Nup9EgBug38Ks+mv3yqbc33z60pBm9tuHs8uSIbkhuqg==",
|
||||
"license": "Apache-2.0",
|
||||
"peerDependencies": {
|
||||
"@powersync/common": "^2.4.0",
|
||||
"react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@powersync/shared-internals": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@powersync/shared-internals/-/shared-internals-1.4.0.tgz",
|
||||
"integrity": "sha512-OiqqDuW6tePW4Ed7C5IWutBKrtcqKuTMlVMQNwUZtKtqr7ZrqKlb+YP5l4niuz8mpqDYo3/HNU0dpc+3mneSBQ==",
|
||||
"license": "Apache-2.0",
|
||||
"peerDependencies": {
|
||||
"@powersync/common": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@powersync/web": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@powersync/web/-/web-2.5.0.tgz",
|
||||
"integrity": "sha512-/K2ZUjIdqvtFeoLfPetPcE+uioShBWzrTrOa8hpoZ7i62S8wgj47i+VPnKTXI7WQmXuxTGGZFUFnahinf6wjPg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/driver-adapter-utils": "7.9.1",
|
||||
"mariadb": "3.4.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/adapter-mariadb/node_modules/@types/node": {
|
||||
"version": "24.13.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz",
|
||||
"integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~7.18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/adapter-mariadb/node_modules/iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
"@journeyapps/wa-sqlite": "2.0.7",
|
||||
"@powersync/common": "2.4.0",
|
||||
"@powersync/shared-internals": "1.4.0",
|
||||
"comlink": "^4.4.2",
|
||||
"commander": "^12.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/adapter-mariadb/node_modules/lru-cache": {
|
||||
"version": "10.4.3",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@prisma/adapter-mariadb/node_modules/mariadb": {
|
||||
"version": "3.4.5",
|
||||
"resolved": "https://registry.npmjs.org/mariadb/-/mariadb-3.4.5.tgz",
|
||||
"integrity": "sha512-gThTYkhIS5rRqkVr+Y0cIdzr+GRqJ9sA2Q34e0yzmyhMCwyApf3OKAC1jnF23aSlIOqJuyaUFUcj7O1qZslmmQ==",
|
||||
"license": "LGPL-2.1-or-later",
|
||||
"dependencies": {
|
||||
"@types/geojson": "^7946.0.16",
|
||||
"@types/node": "^24.0.13",
|
||||
"denque": "^2.1.0",
|
||||
"iconv-lite": "^0.6.3",
|
||||
"lru-cache": "^10.4.3"
|
||||
"bin": {
|
||||
"powersync-web": "bin/powersync.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
"peerDependencies": {
|
||||
"@powersync/common": "^2.4.0",
|
||||
"@powersync/shared-internals": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/adapter-mariadb/node_modules/undici-types": {
|
||||
"version": "7.18.2",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
|
||||
"integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
|
||||
"license": "MIT"
|
||||
"node_modules/@powersync/web/node_modules/@journeyapps/wa-sqlite": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@journeyapps/wa-sqlite/-/wa-sqlite-2.0.7.tgz",
|
||||
"integrity": "sha512-mc6xUricl4QB2s8QTRGS+FofSr1cjwDtf6dPXAdMBuGWodjfEgkSJGDPWQ7zVqgc7hMfXYLT7WIfEBAxara8YA=="
|
||||
},
|
||||
"node_modules/@powersync/web/node_modules/commander": {
|
||||
"version": "12.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
|
||||
"integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/adapter-pg": {
|
||||
"version": "7.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/adapter-pg/-/adapter-pg-7.10.1.tgz",
|
||||
"integrity": "sha512-EP9ruPYHjKP80WZlb5qVaEXKgZjJieBFjAxcBtQnDAHD6+16UN4keVmBh6L/RUpuDQT2FQRbvKNgq5d4Ix+IkQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/driver-adapter-utils": "7.10.1",
|
||||
"@types/pg": "^8.16.0",
|
||||
"pg": "^8.16.3",
|
||||
"postgres-array": "3.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/adapter-pg/node_modules/@prisma/debug": {
|
||||
"version": "7.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-7.10.1.tgz",
|
||||
"integrity": "sha512-eFCAkGZ13D/qPg48JBlG5IWi9cSBBOC7oG3abDPcAkYioDWlIjh0YJJLK2J7qo5S+xWWD8I6egAN/8KbCaiMCA==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@prisma/adapter-pg/node_modules/@prisma/driver-adapter-utils": {
|
||||
"version": "7.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/driver-adapter-utils/-/driver-adapter-utils-7.10.1.tgz",
|
||||
"integrity": "sha512-DJ4c6xvVnm3s9ZUyql9nCUicADSqyvH+CjXRCM9L6m5zJxCNmebCElG6X4irICq3rosBwlX+S19Dxq/4IrZk3A==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/debug": "7.10.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/client": {
|
||||
"version": "7.7.0",
|
||||
@@ -1747,21 +1782,6 @@
|
||||
"zeptomatch": "2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/driver-adapter-utils": {
|
||||
"version": "7.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/driver-adapter-utils/-/driver-adapter-utils-7.9.1.tgz",
|
||||
"integrity": "sha512-vmHehG7nn/heW32DXXpp13DxxAxVVe6n250oEt3dOL2E/4bt3olktKZN0mzSuxMMronyMSkbeW2uCOn3F4g8RQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/debug": "7.9.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/driver-adapter-utils/node_modules/@prisma/debug": {
|
||||
"version": "7.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-7.9.1.tgz",
|
||||
"integrity": "sha512-/cpVZ4itxtcgB8GHBvZtcmuEjq+lWsLrRJxFMbwZrT1RIdtuKmUm7PPGo/wzfbYpBrk+9WmmBE8CHJw2rybKDQ==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@prisma/engines": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-7.7.0.tgz",
|
||||
@@ -2505,9 +2525,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tauri-apps/api": {
|
||||
"version": "2.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.11.1.tgz",
|
||||
"integrity": "sha512-M2FPuYND2m+wh5hfW9ZpSdxMPdEJovPBWwoHJmwUpysTYNHaOkVFN419m/K0LIgjb/7KU2vBgsUepJWugQCvAA==",
|
||||
"version": "2.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.12.4.tgz",
|
||||
"integrity": "sha512-pVmfis+4zT8H0Qhp3xPZx9Ju7kpzvA6rr/PSJPyuwfvucTQ8sVt61NYU9KMkK703UFlYadFmjKA4HhybOtN0gg==",
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@@ -2515,9 +2535,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.11.4.tgz",
|
||||
"integrity": "sha512-R8xGtMpwyetawSqm9kYOuMmEqkhUbvcUy8n0aNXIxollKBLESUu5f4Fx+64hgASYm1H+jSWq6jCW6zqTnH6hqQ==",
|
||||
"version": "2.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.12.4.tgz",
|
||||
"integrity": "sha512-JI9bHfudSRJikGOrjbXEm6RjzzvmKuLc+JixB1NE8hNzQkNlCCIC3pTES3uypkR9lxHrsbxzcnSwhI2IxBQphw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"bin": {
|
||||
@@ -2531,23 +2551,23 @@
|
||||
"url": "https://opencollective.com/tauri"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tauri-apps/cli-darwin-arm64": "2.11.4",
|
||||
"@tauri-apps/cli-darwin-x64": "2.11.4",
|
||||
"@tauri-apps/cli-linux-arm-gnueabihf": "2.11.4",
|
||||
"@tauri-apps/cli-linux-arm64-gnu": "2.11.4",
|
||||
"@tauri-apps/cli-linux-arm64-musl": "2.11.4",
|
||||
"@tauri-apps/cli-linux-riscv64-gnu": "2.11.4",
|
||||
"@tauri-apps/cli-linux-x64-gnu": "2.11.4",
|
||||
"@tauri-apps/cli-linux-x64-musl": "2.11.4",
|
||||
"@tauri-apps/cli-win32-arm64-msvc": "2.11.4",
|
||||
"@tauri-apps/cli-win32-ia32-msvc": "2.11.4",
|
||||
"@tauri-apps/cli-win32-x64-msvc": "2.11.4"
|
||||
"@tauri-apps/cli-darwin-arm64": "2.12.4",
|
||||
"@tauri-apps/cli-darwin-x64": "2.12.4",
|
||||
"@tauri-apps/cli-linux-arm-gnueabihf": "2.12.4",
|
||||
"@tauri-apps/cli-linux-arm64-gnu": "2.12.4",
|
||||
"@tauri-apps/cli-linux-arm64-musl": "2.12.4",
|
||||
"@tauri-apps/cli-linux-riscv64-gnu": "2.12.4",
|
||||
"@tauri-apps/cli-linux-x64-gnu": "2.12.4",
|
||||
"@tauri-apps/cli-linux-x64-musl": "2.12.4",
|
||||
"@tauri-apps/cli-win32-arm64-msvc": "2.12.4",
|
||||
"@tauri-apps/cli-win32-ia32-msvc": "2.12.4",
|
||||
"@tauri-apps/cli-win32-x64-msvc": "2.12.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-darwin-arm64": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.11.4.tgz",
|
||||
"integrity": "sha512-1ryOF3ZhpZ/nemHV5zVwBQBz9jDGKmKPvWPADOhc83ig0P4bMc2iER4NbC6r9sjeIZ6RVQ4g3RZIYvezhcl4TQ==",
|
||||
"version": "2.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.12.4.tgz",
|
||||
"integrity": "sha512-OxqKSckIkoJ6vX2AjifIJpTasFC0Hbdoo7gEiCmAjauABO3U8m2MRsLWe+QTiBwDx1mIrvgA+rvI7tvDnbnHVg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2562,9 +2582,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-darwin-x64": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.11.4.tgz",
|
||||
"integrity": "sha512-uFsGQAAfuyz1k/yGLmkWfkBlgKAqZfxqlHmLWx81QU27RJWfmbNHCIq8T8w1e+VClleIuZUjpHWfoE4E3DLo3A==",
|
||||
"version": "2.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.12.4.tgz",
|
||||
"integrity": "sha512-fz76/77wMMJOaaUN6n3CybRG0P/MTEjjqYk81mGPyhi9m6Ue5T+LWBnJP/AkPooNatBPI2vtulGqomyMJ44lCQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2579,9 +2599,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.11.4.tgz",
|
||||
"integrity": "sha512-IaHZn5CdBL21oUmjiVOS1ctw6Ip1O0pjp70FwOWmYz1myWe0SY96ZIj2FYf7pT0m8bI2h/hrs5ZbEXXh44/MkQ==",
|
||||
"version": "2.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.12.4.tgz",
|
||||
"integrity": "sha512-K0w8Bof6Lt8QKLAYhRy0yy36ZH5iA/35VuSOvnxyjvCUZ+A3JKsUTlALviH/sVgAlisaPzzmeJSH8XOn4Q2HBA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -2596,9 +2616,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.11.4.tgz",
|
||||
"integrity": "sha512-N41/ukTRVe6XSuUTESuFdGeOW2i7k62tK+6gHK5Kd5/q5RPvvi19GaWAVPPb9u95HSGmTChSolBfzynUsssFaA==",
|
||||
"version": "2.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.12.4.tgz",
|
||||
"integrity": "sha512-j5rOnjmRUwWrm1oosf0zBYl4D+fqydgUROFCk0hvKZxvbTT8SOERes0QB7rBV/XWNy+kM6pCKzb3oSm2sRglzg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2613,9 +2633,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.11.4.tgz",
|
||||
"integrity": "sha512-v277UnT/fB64xAfSroL5N3Km3tLmvATWqJJw/wRI+g6o+HkeD0slyE7gOhNs1MbjE41R7bQOTxMVoL3aomUJmw==",
|
||||
"version": "2.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.12.4.tgz",
|
||||
"integrity": "sha512-aOue3Fy6Jb7+oWcfAVUsVHfeTybSCt2CZoU06aO4jv4d2Ks/KnaTPwMAK3CLEduGOvBLY1lbBBrIyomqLLH5Sg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2630,9 +2650,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-riscv64-gnu": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.11.4.tgz",
|
||||
"integrity": "sha512-qqgNkQ2u1yZHxjhxsZaxUtRDW8dIqIYm33rx/mzwQv0SfY9x1B+iraj8vWeFiXjjSVVhEMepXSOts1TqPzvXNQ==",
|
||||
"version": "2.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.12.4.tgz",
|
||||
"integrity": "sha512-Fx6GShY/RvST+t6LMlTHAwd66+1tEaAAGrnU7cysVfaiRP1BKng5Vl6rVmO6rSLOA1Sp1dRzNYM4f0OWQGb7qA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@@ -2647,9 +2667,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.11.4.tgz",
|
||||
"integrity": "sha512-2VRNWl84FOH0m2giiDkO2h0QXlcMJeX+zJDpI5kDIQAx6s+geF3v48F4DXfJez4GS/FdoDGnPnw1C2iYGbQ7bQ==",
|
||||
"version": "2.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.12.4.tgz",
|
||||
"integrity": "sha512-tNzZSa79Z1nRpHxEpQ38lsAFpKlFlYvoXzjTV+lRRn/zSf3wrdUC3wnLcq2XEadchPu4ttK0zivhYzr+XGD19Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2664,9 +2684,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-linux-x64-musl": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.11.4.tgz",
|
||||
"integrity": "sha512-o9GyhYor/nc7xarmwDE3ka2szuW3uuZzXjHWh64Q8YX5AtSgxdQkFWzrY4O8KiGtVNvFBI14H3Q49Qj5TOIP/A==",
|
||||
"version": "2.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.12.4.tgz",
|
||||
"integrity": "sha512-jmZ1pr0xEqUhuEusWtt9Yt+GF6lCnGHUmIL+KIknpbjK/XQ2qkhDBhaxK/JMHM2A8dAacVXCxXJk2EXpwhQUfA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2681,9 +2701,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.11.4.tgz",
|
||||
"integrity": "sha512-ld5Ehb598m0VkYyylRPNeCFsBe/km0jxis6KgMpl3IGY6I/i1RwQXO05I1AsXUXO2WC6AvB/Lw4qTf/asiuEiQ==",
|
||||
"version": "2.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.12.4.tgz",
|
||||
"integrity": "sha512-fGo8pgEHZxdSYgZ/J98m1usJ7NHKmKbq7k6uT0x1rpOq6Bg2YVzzpaAblWk710f5LHYBJIL5QIFS5IrD+4gmTg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -2698,9 +2718,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.11.4.tgz",
|
||||
"integrity": "sha512-12Hxi0XX/H5VFxO/bGgHkFWhml9VMgEOu9CidjeCeTNQ1l6fpUlbiGgSP7CLI3PFtW9/FfbeHieZ+kyWK5H7CA==",
|
||||
"version": "2.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.12.4.tgz",
|
||||
"integrity": "sha512-ezl8sQIcjYsye3TUnTH5VcWmWzccZASlQm7hlZt0dYyj1XD0qpVW47u2xYVrIKui0F8uQv/7QGZixdWiClBsbg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -2715,9 +2735,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
|
||||
"version": "2.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.11.4.tgz",
|
||||
"integrity": "sha512-+vDiqBIU5dMISg/wNvX3sF+ZHfgJGJ5T0AcO+EHNXV9GGAG+P5fzodlDXD3QdKCRgZxMoCm5PPvj3BqLNjBthw==",
|
||||
"version": "2.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.12.4.tgz",
|
||||
"integrity": "sha512-DJhDeCqjLDNMWYFy7ZS8cfeAHX2RK0RbQMLiA3bMVVkXRDJ4NBYiHriGqsUhsr9iG41aTb+dJGkFPmPw1gWwVw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -2867,6 +2887,17 @@
|
||||
"undici-types": "~8.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/pg": {
|
||||
"version": "8.23.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.23.1.tgz",
|
||||
"integrity": "sha512-fKVHpikPdg4GKks3JuLEhvwSyvwzF23hnabPy6DD8ljVbC7+6J5dQzdv4arV6jqq57djnMgs1HKBxX4P8aBI3A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"pg-protocol": "*",
|
||||
"pg-types": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "19.2.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
|
||||
@@ -3193,6 +3224,21 @@
|
||||
"integrity": "sha512-YOf0VSj5nUPI27doTtXF+BBnsiRq3qY7avHqfIWnppxTLGyvkLq1QV2RTxkwoZwJ60ywLfZ0raFF4J/G886i7A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/better-sqlite3": {
|
||||
"version": "13.0.3",
|
||||
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-13.0.3.tgz",
|
||||
"integrity": "sha512-RbOBxmLBG8uvFUc15X9+9SFemKcQ0WBuISBVkpuiaUB2qblC8UWlHEjdWVoZ8AdhSwmoEgsiXKfopX0CQxaACQ==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"node-addon-api": "^8.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "1.20.6",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.6.tgz",
|
||||
@@ -3575,6 +3621,12 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/comlink": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/comlink/-/comlink-4.4.2.tgz",
|
||||
"integrity": "sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
|
||||
@@ -5362,6 +5414,17 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "8.9.2",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.9.2.tgz",
|
||||
"integrity": "sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^18 || ^20 || >= 21"
|
||||
}
|
||||
},
|
||||
"node_modules/node-cron": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz",
|
||||
@@ -5579,6 +5642,104 @@
|
||||
"integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pg": {
|
||||
"version": "8.23.1",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.23.1.tgz",
|
||||
"integrity": "sha512-aL96AHANtWjPLDOLqnhx+ngp9+UK7ETEU8VJrDCGvsSSi/mGLcWYsS6Herg7lmaBJe4uwrfqsa7gTEFaSizDoQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pg-connection-string": "^2.14.1",
|
||||
"pg-pool": "^3.14.0",
|
||||
"pg-protocol": "^1.16.1",
|
||||
"pg-types": "2.2.0",
|
||||
"pgpass": "1.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"pg-cloudflare": "^1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"pg-native": ">=3.0.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"pg-native": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pg-cloudflare": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.4.1.tgz",
|
||||
"integrity": "sha512-6PQbsFWZcp9EmJEwy5cGQ2La+AMWpP46lgbb8X+U/XsHIUweYDNCpeuKck5RxL2MdVFi7krbbEi5nX4Zh7JhrQ==",
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/pg-connection-string": {
|
||||
"version": "2.14.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.14.1.tgz",
|
||||
"integrity": "sha512-qR3kGNPBLpCNtz0evbKA0Y/MRFXwSSdT+pTJvYp/bXTcReZbvX1kzF0IyTc1QnxqF7AZbOeBhNL8R5mYQZV/MA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pg-int8": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
|
||||
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pg-pool": {
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.14.0.tgz",
|
||||
"integrity": "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"pg": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pg-protocol": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.16.1.tgz",
|
||||
"integrity": "sha512-p9VOFMiHB/ZbJATetbg+99PxssTVSQRnyuPSQ67mN1+1KBOjZaZ83ZQzltnxPhJwSsC3nwVjJ10DVJlerbFzLg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/pg-types": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
|
||||
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pg-int8": "1.0.1",
|
||||
"postgres-array": "~2.0.0",
|
||||
"postgres-bytea": "~1.0.0",
|
||||
"postgres-date": "~1.0.4",
|
||||
"postgres-interval": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/pg-types/node_modules/postgres-array": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
|
||||
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/pgpass": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
|
||||
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"split2": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
@@ -5619,6 +5780,45 @@
|
||||
"url": "https://github.com/sponsors/porsager"
|
||||
}
|
||||
},
|
||||
"node_modules/postgres-array": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.4.tgz",
|
||||
"integrity": "sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/postgres-bytea": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz",
|
||||
"integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postgres-date": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
|
||||
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postgres-interval": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
|
||||
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"xtend": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prisma": {
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/prisma/-/prisma-7.7.0.tgz",
|
||||
@@ -6470,6 +6670,15 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/split2": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
||||
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">= 10.x"
|
||||
}
|
||||
},
|
||||
"node_modules/sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
@@ -6938,6 +7147,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
|
||||
+10
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "iboard",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"tauri": "tauri",
|
||||
@@ -8,6 +8,9 @@
|
||||
"dev:server": "node --watch --experimental-strip-types --no-warnings server/index.js",
|
||||
"dev": "concurrently -n web,api -c blue,green \"npm run dev:web\" \"npm run dev:server\"",
|
||||
"build": "vite build",
|
||||
"build:shell": "vite build --mode shell",
|
||||
"build:win": "node scripts/build-windows.mjs",
|
||||
"build:win:debug": "node scripts/build-windows.mjs --debug",
|
||||
"build:ota": "node scripts/build-ota.mjs",
|
||||
"preview": "vite preview",
|
||||
"start": "node --experimental-strip-types --no-warnings server/index.js",
|
||||
@@ -30,7 +33,10 @@
|
||||
"publish": "bash scripts/wsl/build-apk.sh release"
|
||||
},
|
||||
"dependencies": {
|
||||
"@prisma/adapter-mariadb": "^7.9.1",
|
||||
"@journeyapps/wa-sqlite": "^2.0.7",
|
||||
"@powersync/react": "^2.1.0",
|
||||
"@powersync/web": "^2.5.0",
|
||||
"@prisma/adapter-pg": "^7.9.1",
|
||||
"@prisma/client": "^7.7.0",
|
||||
"@zythum02/mijia-api": "^0.1.4",
|
||||
"antd-mobile": "^5.42.3",
|
||||
@@ -52,8 +58,8 @@
|
||||
"ws": "^8.21.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/api": "^2.0.0",
|
||||
"@tauri-apps/cli": "^2.0.0",
|
||||
"@tauri-apps/api": "^2.12.4",
|
||||
"@tauri-apps/cli": "^2.12.4",
|
||||
"@vitejs/plugin-react": "^4.3.1",
|
||||
"cheerio": "^1.2.0",
|
||||
"concurrently": "^9.0.0",
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `User` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`email` VARCHAR(191) NOT NULL,
|
||||
`password` VARCHAR(191) NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `User_email_key`(`email`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Article` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`title` VARCHAR(191) NOT NULL,
|
||||
`slug` VARCHAR(191) NOT NULL,
|
||||
`content` VARCHAR(191) NOT NULL,
|
||||
`date` VARCHAR(191) NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Article_slug_key`(`slug`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Strategy` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`description` VARCHAR(191) NOT NULL,
|
||||
`data` JSON NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Indicator` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`groupName` VARCHAR(191) NOT NULL,
|
||||
`data` JSON NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `SowInventory` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`month` VARCHAR(191) NOT NULL,
|
||||
`inventory` INTEGER NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `SowInventory_month_key`(`month`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the `SowInventory` table. If the table is not empty, all the data it contains will be lost.
|
||||
|
||||
*/
|
||||
-- DropTable
|
||||
DROP TABLE `SowInventory`;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Econ_SowInventory` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`month` VARCHAR(191) NOT NULL,
|
||||
`inventory` INTEGER NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Econ_SowInventory_month_key`(`month`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
@@ -1,13 +0,0 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `ScraperCache` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`scraperName` VARCHAR(191) NOT NULL,
|
||||
`lastDataHash` VARCHAR(191) NULL,
|
||||
`lastUpdateAt` DATETIME(3) NOT NULL,
|
||||
`metadata` JSON NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `ScraperCache_scraperName_key`(`scraperName`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
@@ -1,5 +0,0 @@
|
||||
-- Add unique constraint on Strategy.name to enable idempotent upsert in seed script
|
||||
ALTER TABLE `Strategy` ADD UNIQUE INDEX `Strategy_name_key`(`name`);
|
||||
|
||||
-- Add unique constraint on Indicator.name to enable idempotent upsert in seed script
|
||||
ALTER TABLE `Indicator` ADD UNIQUE INDEX `Indicator_name_key`(`name`);
|
||||
@@ -1,24 +0,0 @@
|
||||
-- 经济指标: 明细数据拆到独立表, 兼容年/季/月/日频率
|
||||
-- 第一步: 建 IndicatorPoint 表 + Indicator 加元数据列 (data 列暂保留, 由迁移脚本搬运后删除)
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `IndicatorPoint` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`indicatorId` INTEGER NOT NULL,
|
||||
`period` VARCHAR(191) NOT NULL,
|
||||
`value` DOUBLE NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `IndicatorPoint_indicatorId_period_key`(`indicatorId`, `period`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AlterTable: 元数据列 (data JSON 拆出)
|
||||
ALTER TABLE `Indicator` ADD COLUMN `title` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
ADD COLUMN `unit` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
ADD COLUMN `source` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
ADD COLUMN `frequency` VARCHAR(191) NOT NULL DEFAULT 'month';
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `IndicatorPoint` ADD CONSTRAINT `IndicatorPoint_indicatorId_fkey` FOREIGN KEY (`indicatorId`) REFERENCES `Indicator`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -1,3 +0,0 @@
|
||||
-- 第二步: 明细数据已迁移到 IndicatorPoint, 删除 Indicator.data JSON 列
|
||||
-- AlterTable
|
||||
ALTER TABLE `Indicator` DROP COLUMN `data`;
|
||||
@@ -1,2 +0,0 @@
|
||||
-- 指标隐藏标记: 数据与获取脚本保留, 前端展示过滤 hidden=true
|
||||
ALTER TABLE `Indicator` ADD COLUMN `hidden` BOOLEAN NOT NULL DEFAULT false;
|
||||
@@ -1,32 +0,0 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `News` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`title` VARCHAR(191) NOT NULL,
|
||||
`summary` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`source` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`url` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`publishedAt` DATETIME(3) NOT NULL,
|
||||
`impactRank` INTEGER NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `News_title_publishedAt_key`(`title`, `publishedAt`),
|
||||
INDEX `News_publishedAt_idx`(`publishedAt`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Alert` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`indicatorName` VARCHAR(191) NOT NULL,
|
||||
`period` VARCHAR(191) NOT NULL,
|
||||
`valueA` DOUBLE NOT NULL,
|
||||
`valueB` DOUBLE NOT NULL,
|
||||
`sourceA` VARCHAR(191) NOT NULL,
|
||||
`sourceB` VARCHAR(191) NOT NULL,
|
||||
`diff` DOUBLE NOT NULL,
|
||||
`diffRatio` DOUBLE NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
INDEX `Alert_createdAt_idx`(`createdAt`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
@@ -1,68 +0,0 @@
|
||||
-- 服务器监控 + 服务健康检查
|
||||
-- CreateTable
|
||||
CREATE TABLE `ServerNode` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`uuid` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`cpuName` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`os` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`region` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`memTotal` BIGINT NOT NULL DEFAULT 0,
|
||||
`diskTotal` BIGINT NOT NULL DEFAULT 0,
|
||||
`cpuCores` INTEGER NOT NULL DEFAULT 0,
|
||||
`cpuUsage` DOUBLE NOT NULL DEFAULT 0,
|
||||
`ramUsed` BIGINT NOT NULL DEFAULT 0,
|
||||
`swapUsed` BIGINT NOT NULL DEFAULT 0,
|
||||
`load1` DOUBLE NOT NULL DEFAULT 0,
|
||||
`load5` DOUBLE NOT NULL DEFAULT 0,
|
||||
`load15` DOUBLE NOT NULL DEFAULT 0,
|
||||
`diskUsed` BIGINT NOT NULL DEFAULT 0,
|
||||
`netIn` BIGINT NOT NULL DEFAULT 0,
|
||||
`netOut` BIGINT NOT NULL DEFAULT 0,
|
||||
`uptime` BIGINT NOT NULL DEFAULT 0,
|
||||
`process` INTEGER NOT NULL DEFAULT 0,
|
||||
`connections` INTEGER NOT NULL DEFAULT 0,
|
||||
`status` VARCHAR(191) NOT NULL DEFAULT 'unknown',
|
||||
`recordedAt` DATETIME(3) NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `ServerNode_uuid_key`(`uuid`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `ServerNodeHistory` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`uuid` VARCHAR(191) NOT NULL,
|
||||
`period` DATETIME(3) NOT NULL,
|
||||
`cpu` DOUBLE NOT NULL DEFAULT 0,
|
||||
`ram` BIGINT NOT NULL DEFAULT 0,
|
||||
`load` DOUBLE NOT NULL DEFAULT 0,
|
||||
`disk` BIGINT NOT NULL DEFAULT 0,
|
||||
`netIn` BIGINT NOT NULL DEFAULT 0,
|
||||
`netOut` BIGINT NOT NULL DEFAULT 0,
|
||||
`process` INTEGER NOT NULL DEFAULT 0,
|
||||
`connections` INTEGER NOT NULL DEFAULT 0,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `ServerNodeHistory_uuid_period_key`(`uuid`, `period`),
|
||||
INDEX `ServerNodeHistory_uuid_period_idx`(`uuid`, `period`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `ServiceCheck` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`url` VARCHAR(191) NOT NULL,
|
||||
`status` VARCHAR(191) NOT NULL DEFAULT 'unknown',
|
||||
`latencyMs` INTEGER NOT NULL DEFAULT 0,
|
||||
`message` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`lastCheckAt` DATETIME(3) NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `ServiceCheck_name_key`(`name`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
@@ -1,2 +0,0 @@
|
||||
-- AlterTable (news.content 全文, 须在 news_and_alerts 建表之后执行)
|
||||
ALTER TABLE `News` ADD COLUMN `content` TEXT NULL;
|
||||
@@ -1,17 +0,0 @@
|
||||
-- 浙江省油价历史表
|
||||
-- - date: 调价日次日 (即数据实际抓取日, 便于按时间排序)
|
||||
-- - province + fuel: 浙江 / 92/95/0
|
||||
-- - unique (date, province, fuel): 防 cron 重复入库
|
||||
-- - DOUBLE 容纳 999.999 元/升
|
||||
CREATE TABLE OilPriceHistory (
|
||||
id INT NOT NULL AUTO_INCREMENT,
|
||||
date DATETIME(3) NOT NULL,
|
||||
province VARCHAR(191) NOT NULL,
|
||||
fuel VARCHAR(8) NOT NULL,
|
||||
price DOUBLE NOT NULL,
|
||||
source VARCHAR(191) NOT NULL DEFAULT 'apizero',
|
||||
createdAt DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE INDEX OilPriceHistory_date_province_fuel_key(date, province, fuel),
|
||||
INDEX OilPriceHistory_province_fuel_date_idx(province, fuel, date)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
@@ -1,95 +0,0 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `MihomeAccount` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`key` VARCHAR(191) NOT NULL DEFAULT 'default',
|
||||
`userId` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`status` VARCHAR(191) NOT NULL DEFAULT 'unknown',
|
||||
`lastError` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `MihomeAccount_key_key`(`key`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `MihomeHome` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`homeId` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `MihomeHome_homeId_key`(`homeId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `MihomeDevice` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`did` VARCHAR(191) NOT NULL,
|
||||
`homeId` VARCHAR(191) NOT NULL,
|
||||
`model` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`alias` VARCHAR(191) NULL,
|
||||
`tempSiid` INTEGER NOT NULL,
|
||||
`tempPiid` INTEGER NOT NULL,
|
||||
`humSiid` INTEGER NOT NULL,
|
||||
`humPiid` INTEGER NOT NULL,
|
||||
`battSiid` INTEGER NOT NULL,
|
||||
`battPiid` INTEGER NOT NULL,
|
||||
`battery` INTEGER NULL,
|
||||
`batteryAt` DATETIME(3) NULL,
|
||||
`enabled` BOOLEAN NOT NULL DEFAULT true,
|
||||
`lastSyncAt` DATETIME(3) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `MihomeDevice_did_key`(`did`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `MihomeEnvSample` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`deviceId` INTEGER NOT NULL,
|
||||
`date` DATETIME(3) NOT NULL,
|
||||
`temperature` DOUBLE NULL,
|
||||
`humidity` DOUBLE NULL,
|
||||
`temperatureAvg` DOUBLE NULL,
|
||||
`humidityAvg` DOUBLE NULL,
|
||||
`temperatureMin` DOUBLE NULL,
|
||||
`temperatureMax` DOUBLE NULL,
|
||||
`humidityMin` DOUBLE NULL,
|
||||
`humidityMax` DOUBLE NULL,
|
||||
`origin` VARCHAR(191) NOT NULL DEFAULT 'live',
|
||||
`sampledAt` DATETIME(3) NULL,
|
||||
`raw` JSON NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
INDEX `MihomeEnvSample_deviceId_date_idx`(`deviceId`, `date`),
|
||||
UNIQUE INDEX `MihomeEnvSample_deviceId_date_key`(`deviceId`, `date`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `MihomeEnvHour` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`deviceId` INTEGER NOT NULL,
|
||||
`hour` DATETIME(3) NOT NULL,
|
||||
`temperatureAvg` DOUBLE NULL,
|
||||
`humidityAvg` DOUBLE NULL,
|
||||
`raw` JSON NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
INDEX `MihomeEnvHour_deviceId_hour_idx`(`deviceId`, `hour`),
|
||||
UNIQUE INDEX `MihomeEnvHour_deviceId_hour_key`(`deviceId`, `hour`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `MihomeDevice` ADD CONSTRAINT `MihomeDevice_homeId_fkey` FOREIGN KEY (`homeId`) REFERENCES `MihomeHome`(`homeId`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `MihomeEnvSample` ADD CONSTRAINT `MihomeEnvSample_deviceId_fkey` FOREIGN KEY (`deviceId`) REFERENCES `MihomeDevice`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `MihomeEnvHour` ADD CONSTRAINT `MihomeEnvHour_deviceId_fkey` FOREIGN KEY (`deviceId`) REFERENCES `MihomeDevice`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `Habit` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`userId` INTEGER NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`period` VARCHAR(191) NOT NULL DEFAULT 'day',
|
||||
`target` INTEGER NOT NULL DEFAULT 1,
|
||||
`color` VARCHAR(191) NOT NULL DEFAULT '#1677ff',
|
||||
`icon` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`note` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`archived` BOOLEAN NOT NULL DEFAULT false,
|
||||
`sortOrder` INTEGER NOT NULL DEFAULT 0,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `Habit_userId_archived_sortOrder_idx`(`userId`, `archived`, `sortOrder`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `CheckIn` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`habitId` INTEGER NOT NULL,
|
||||
`userId` INTEGER NOT NULL,
|
||||
`date` VARCHAR(10) NOT NULL,
|
||||
`seq` INTEGER NOT NULL DEFAULT 1,
|
||||
`note` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`source` VARCHAR(191) NOT NULL DEFAULT 'user',
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `CheckIn_habitId_date_seq_key`(`habitId`, `date`, `seq`),
|
||||
INDEX `CheckIn_userId_date_idx`(`userId`, `date`),
|
||||
INDEX `CheckIn_habitId_date_idx`(`habitId`, `date`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `CheckList` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`userId` INTEGER NOT NULL,
|
||||
`title` VARCHAR(191) NOT NULL,
|
||||
`scene` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`note` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`archived` BOOLEAN NOT NULL DEFAULT false,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `CheckList_userId_archived_idx`(`userId`, `archived`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `CheckListItem` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`listId` INTEGER NOT NULL,
|
||||
`title` VARCHAR(191) NOT NULL,
|
||||
`note` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`done` BOOLEAN NOT NULL DEFAULT false,
|
||||
`doneAt` DATETIME(3) NULL,
|
||||
`sortOrder` INTEGER NOT NULL DEFAULT 0,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `CheckListItem_listId_sortOrder_idx`(`listId`, `sortOrder`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `CheckListTemplate` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`userId` INTEGER NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`scene` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
`items` JSON NOT NULL,
|
||||
`builtin` BOOLEAN NOT NULL DEFAULT false,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `CheckListTemplate_userId_builtin_idx`(`userId`, `builtin`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Habit` ADD CONSTRAINT `Habit_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `CheckIn` ADD CONSTRAINT `CheckIn_habitId_fkey` FOREIGN KEY (`habitId`) REFERENCES `Habit`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `CheckIn` ADD CONSTRAINT `CheckIn_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `CheckList` ADD CONSTRAINT `CheckList_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `CheckListItem` ADD CONSTRAINT `CheckListItem_listId_fkey` FOREIGN KEY (`listId`) REFERENCES `CheckList`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `CheckListTemplate` ADD CONSTRAINT `CheckListTemplate_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -1,126 +0,0 @@
|
||||
-- 任务模块 (V0.2): 项目 / 成员 / 看板列 / 任务 / 任务成员 / 标签
|
||||
-- 设计口径见 docs/V0.2/任务模块/任务模块数据库设计文档.md
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Project` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(50) NOT NULL,
|
||||
`ownerId` INTEGER NOT NULL,
|
||||
`isPersonal` BOOLEAN NOT NULL DEFAULT false,
|
||||
`archived` BOOLEAN NOT NULL DEFAULT false,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `Project_ownerId_idx`(`ownerId`),
|
||||
INDEX `Project_archived_idx`(`archived`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `ProjectMember` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`projectId` INTEGER NOT NULL,
|
||||
`userId` INTEGER NOT NULL,
|
||||
`permission` VARCHAR(191) NOT NULL DEFAULT 'member',
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
UNIQUE INDEX `ProjectMember_projectId_userId_key`(`projectId`, `userId`),
|
||||
INDEX `ProjectMember_userId_idx`(`userId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `BoardColumn` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`projectId` INTEGER NOT NULL,
|
||||
`name` VARCHAR(20) NOT NULL,
|
||||
`sortOrder` INTEGER NOT NULL DEFAULT 0,
|
||||
`boundStatus` VARCHAR(8) NULL,
|
||||
`retention` VARCHAR(8) NOT NULL DEFAULT 'forever',
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `BoardColumn_projectId_name_key`(`projectId`, `name`),
|
||||
INDEX `BoardColumn_projectId_sortOrder_idx`(`projectId`, `sortOrder`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Task` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`projectId` INTEGER NOT NULL,
|
||||
`columnId` INTEGER NOT NULL,
|
||||
`parentId` INTEGER NULL,
|
||||
`title` VARCHAR(200) NOT NULL,
|
||||
`description` TEXT NOT NULL,
|
||||
`status` VARCHAR(8) NOT NULL DEFAULT 'todo',
|
||||
`doneAt` DATETIME(3) NULL,
|
||||
`assigneeId` INTEGER NULL,
|
||||
`creatorId` INTEGER NOT NULL,
|
||||
`extras` JSON NOT NULL,
|
||||
`sortOrder` INTEGER NOT NULL DEFAULT 0,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
INDEX `Task_projectId_columnId_idx`(`projectId`, `columnId`),
|
||||
INDEX `Task_projectId_status_idx`(`projectId`, `status`),
|
||||
INDEX `Task_parentId_idx`(`parentId`),
|
||||
INDEX `Task_projectId_doneAt_idx`(`projectId`, `doneAt`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `TaskMember` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`taskId` INTEGER NOT NULL,
|
||||
`userId` INTEGER NOT NULL,
|
||||
|
||||
UNIQUE INDEX `TaskMember_taskId_userId_key`(`taskId`, `userId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `TaskTag` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`taskId` INTEGER NOT NULL,
|
||||
`name` VARCHAR(20) NOT NULL,
|
||||
|
||||
INDEX `TaskTag_taskId_idx`(`taskId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Project` ADD CONSTRAINT `Project_ownerId_fkey` FOREIGN KEY (`ownerId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `ProjectMember` ADD CONSTRAINT `ProjectMember_projectId_fkey` FOREIGN KEY (`projectId`) REFERENCES `Project`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `ProjectMember` ADD CONSTRAINT `ProjectMember_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `BoardColumn` ADD CONSTRAINT `BoardColumn_projectId_fkey` FOREIGN KEY (`projectId`) REFERENCES `Project`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Task` ADD CONSTRAINT `Task_projectId_fkey` FOREIGN KEY (`projectId`) REFERENCES `Project`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Task` ADD CONSTRAINT `Task_columnId_fkey` FOREIGN KEY (`columnId`) REFERENCES `BoardColumn`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Task` ADD CONSTRAINT `Task_parentId_fkey` FOREIGN KEY (`parentId`) REFERENCES `Task`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Task` ADD CONSTRAINT `Task_assigneeId_fkey` FOREIGN KEY (`assigneeId`) REFERENCES `User`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Task` ADD CONSTRAINT `Task_creatorId_fkey` FOREIGN KEY (`creatorId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `TaskMember` ADD CONSTRAINT `TaskMember_taskId_fkey` FOREIGN KEY (`taskId`) REFERENCES `Task`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `TaskMember` ADD CONSTRAINT `TaskMember_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `TaskTag` ADD CONSTRAINT `TaskTag_taskId_fkey` FOREIGN KEY (`taskId`) REFERENCES `Task`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -1,7 +0,0 @@
|
||||
-- 项目信息块 (T-PJ-13): Project 增加 notes JSON, 存 [{ title, content }] 任意多个长文本块
|
||||
-- 分三步保证存量行安全: 先可空加列 -> 回填 '[]' -> 收紧为 NOT NULL
|
||||
ALTER TABLE `Project` ADD COLUMN `notes` JSON NULL;
|
||||
|
||||
UPDATE `Project` SET `notes` = '[]' WHERE `notes` IS NULL;
|
||||
|
||||
ALTER TABLE `Project` MODIFY `notes` JSON NOT NULL;
|
||||
@@ -1,3 +0,0 @@
|
||||
-- 任务类型标签: 项目级自定义列表 + 任务上的类型
|
||||
ALTER TABLE `Project` ADD COLUMN `taskKinds` JSON NULL;
|
||||
ALTER TABLE `Task` ADD COLUMN `kind` VARCHAR(20) NULL;
|
||||
@@ -1,2 +0,0 @@
|
||||
-- 任务时间标记: 完整日期存储, 前端展示 MM-dd
|
||||
ALTER TABLE `Task` ADD COLUMN `markDate` DATETIME(3) NULL;
|
||||
@@ -1,2 +0,0 @@
|
||||
-- 项目图标: data URL (客户端裁剪 96x96 JPEG, 约 10-20KB)
|
||||
ALTER TABLE `Project` ADD COLUMN `icon` TEXT NULL;
|
||||
@@ -0,0 +1,655 @@
|
||||
-- CreateSchema
|
||||
CREATE SCHEMA IF NOT EXISTS "public";
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "User" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"password" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Article" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"slug" TEXT NOT NULL,
|
||||
"content" TEXT NOT NULL,
|
||||
"date" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Article_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Strategy" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"data" JSONB NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Strategy_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Indicator" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"groupName" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL DEFAULT '',
|
||||
"unit" TEXT NOT NULL DEFAULT '',
|
||||
"source" TEXT NOT NULL DEFAULT '',
|
||||
"frequency" TEXT NOT NULL DEFAULT 'month',
|
||||
"hidden" BOOLEAN NOT NULL DEFAULT false,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Indicator_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "IndicatorPoint" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"indicatorId" INTEGER NOT NULL,
|
||||
"period" TEXT NOT NULL,
|
||||
"value" DOUBLE PRECISION NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "IndicatorPoint_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "News" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"summary" TEXT NOT NULL DEFAULT '',
|
||||
"content" TEXT,
|
||||
"source" TEXT NOT NULL DEFAULT '',
|
||||
"url" TEXT NOT NULL DEFAULT '',
|
||||
"publishedAt" TIMESTAMP(3) NOT NULL,
|
||||
"impactRank" INTEGER NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "News_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Alert" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"indicatorName" TEXT NOT NULL,
|
||||
"period" TEXT NOT NULL,
|
||||
"valueA" DOUBLE PRECISION NOT NULL,
|
||||
"valueB" DOUBLE PRECISION NOT NULL,
|
||||
"sourceA" TEXT NOT NULL,
|
||||
"sourceB" TEXT NOT NULL,
|
||||
"diff" DOUBLE PRECISION NOT NULL,
|
||||
"diffRatio" DOUBLE PRECISION NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "Alert_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ServerNode" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"uuid" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"cpuName" TEXT NOT NULL DEFAULT '',
|
||||
"os" TEXT NOT NULL DEFAULT '',
|
||||
"region" TEXT NOT NULL DEFAULT '',
|
||||
"memTotal" BIGINT NOT NULL DEFAULT 0,
|
||||
"diskTotal" BIGINT NOT NULL DEFAULT 0,
|
||||
"cpuCores" INTEGER NOT NULL DEFAULT 0,
|
||||
"cpuUsage" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
"ramUsed" BIGINT NOT NULL DEFAULT 0,
|
||||
"swapUsed" BIGINT NOT NULL DEFAULT 0,
|
||||
"load1" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
"load5" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
"load15" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
"diskUsed" BIGINT NOT NULL DEFAULT 0,
|
||||
"netIn" BIGINT NOT NULL DEFAULT 0,
|
||||
"netOut" BIGINT NOT NULL DEFAULT 0,
|
||||
"uptime" BIGINT NOT NULL DEFAULT 0,
|
||||
"process" INTEGER NOT NULL DEFAULT 0,
|
||||
"connections" INTEGER NOT NULL DEFAULT 0,
|
||||
"status" TEXT NOT NULL DEFAULT 'unknown',
|
||||
"recordedAt" TIMESTAMP(3) NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ServerNode_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ServerNodeHistory" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"uuid" TEXT NOT NULL,
|
||||
"period" TIMESTAMP(3) NOT NULL,
|
||||
"cpu" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
"ram" BIGINT NOT NULL DEFAULT 0,
|
||||
"load" DOUBLE PRECISION NOT NULL DEFAULT 0,
|
||||
"disk" BIGINT NOT NULL DEFAULT 0,
|
||||
"netIn" BIGINT NOT NULL DEFAULT 0,
|
||||
"netOut" BIGINT NOT NULL DEFAULT 0,
|
||||
"process" INTEGER NOT NULL DEFAULT 0,
|
||||
"connections" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "ServerNodeHistory_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ServiceCheck" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"url" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'unknown',
|
||||
"latencyMs" INTEGER NOT NULL DEFAULT 0,
|
||||
"message" TEXT NOT NULL DEFAULT '',
|
||||
"lastCheckAt" TIMESTAMP(3) NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ServiceCheck_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Econ_SowInventory" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"month" TEXT NOT NULL,
|
||||
"inventory" INTEGER NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Econ_SowInventory_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ScraperCache" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"scraperName" TEXT NOT NULL,
|
||||
"lastDataHash" TEXT,
|
||||
"lastUpdateAt" TIMESTAMP(3) NOT NULL,
|
||||
"metadata" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "ScraperCache_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "OilPriceHistory" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"date" TIMESTAMP(3) NOT NULL,
|
||||
"province" TEXT NOT NULL,
|
||||
"fuel" TEXT NOT NULL,
|
||||
"price" DOUBLE PRECISION NOT NULL,
|
||||
"source" TEXT NOT NULL DEFAULT 'apizero',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "OilPriceHistory_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "MihomeAccount" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"key" TEXT NOT NULL DEFAULT 'default',
|
||||
"userId" TEXT NOT NULL DEFAULT '',
|
||||
"status" TEXT NOT NULL DEFAULT 'unknown',
|
||||
"lastError" TEXT NOT NULL DEFAULT '',
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "MihomeAccount_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "MihomeHome" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"homeId" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "MihomeHome_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "MihomeDevice" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"did" TEXT NOT NULL,
|
||||
"homeId" TEXT NOT NULL,
|
||||
"model" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"alias" TEXT,
|
||||
"tempSiid" INTEGER NOT NULL,
|
||||
"tempPiid" INTEGER NOT NULL,
|
||||
"humSiid" INTEGER NOT NULL,
|
||||
"humPiid" INTEGER NOT NULL,
|
||||
"battSiid" INTEGER NOT NULL,
|
||||
"battPiid" INTEGER NOT NULL,
|
||||
"battery" INTEGER,
|
||||
"batteryAt" TIMESTAMP(3),
|
||||
"enabled" BOOLEAN NOT NULL DEFAULT true,
|
||||
"lastSyncAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "MihomeDevice_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "MihomeEnvSample" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"deviceId" INTEGER NOT NULL,
|
||||
"date" TIMESTAMP(3) NOT NULL,
|
||||
"temperature" DOUBLE PRECISION,
|
||||
"humidity" DOUBLE PRECISION,
|
||||
"temperatureAvg" DOUBLE PRECISION,
|
||||
"humidityAvg" DOUBLE PRECISION,
|
||||
"temperatureMin" DOUBLE PRECISION,
|
||||
"temperatureMax" DOUBLE PRECISION,
|
||||
"humidityMin" DOUBLE PRECISION,
|
||||
"humidityMax" DOUBLE PRECISION,
|
||||
"origin" TEXT NOT NULL DEFAULT 'live',
|
||||
"sampledAt" TIMESTAMP(3),
|
||||
"raw" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "MihomeEnvSample_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "MihomeEnvHour" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"deviceId" INTEGER NOT NULL,
|
||||
"hour" TIMESTAMP(3) NOT NULL,
|
||||
"temperatureAvg" DOUBLE PRECISION,
|
||||
"humidityAvg" DOUBLE PRECISION,
|
||||
"raw" JSONB,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "MihomeEnvHour_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Habit" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"period" TEXT NOT NULL DEFAULT 'day',
|
||||
"target" INTEGER NOT NULL DEFAULT 1,
|
||||
"color" TEXT NOT NULL DEFAULT '#1677ff',
|
||||
"icon" TEXT NOT NULL DEFAULT '',
|
||||
"note" TEXT NOT NULL DEFAULT '',
|
||||
"archived" BOOLEAN NOT NULL DEFAULT false,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Habit_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CheckIn" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"habitId" INTEGER NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"date" VARCHAR(10) NOT NULL,
|
||||
"seq" INTEGER NOT NULL DEFAULT 1,
|
||||
"note" TEXT NOT NULL DEFAULT '',
|
||||
"source" TEXT NOT NULL DEFAULT 'user',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "CheckIn_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CheckList" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"scene" TEXT NOT NULL DEFAULT '',
|
||||
"note" TEXT NOT NULL DEFAULT '',
|
||||
"archived" BOOLEAN NOT NULL DEFAULT false,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "CheckList_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CheckListItem" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"listId" INTEGER NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"note" TEXT NOT NULL DEFAULT '',
|
||||
"done" BOOLEAN NOT NULL DEFAULT false,
|
||||
"doneAt" TIMESTAMP(3),
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "CheckListItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "CheckListTemplate" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"userId" INTEGER,
|
||||
"name" TEXT NOT NULL,
|
||||
"scene" TEXT NOT NULL DEFAULT '',
|
||||
"items" JSONB NOT NULL,
|
||||
"builtin" BOOLEAN NOT NULL DEFAULT false,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "CheckListTemplate_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Project" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"uuid" VARCHAR(36) NOT NULL,
|
||||
"code" VARCHAR(8) NOT NULL,
|
||||
"name" VARCHAR(50) NOT NULL,
|
||||
"ownerId" INTEGER NOT NULL,
|
||||
"isPersonal" BOOLEAN NOT NULL DEFAULT false,
|
||||
"archived" BOOLEAN NOT NULL DEFAULT false,
|
||||
"notes" JSONB NOT NULL DEFAULT '[]',
|
||||
"taskKinds" JSONB,
|
||||
"icon" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Project_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ProjectMember" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"uuid" VARCHAR(36) NOT NULL,
|
||||
"projectId" INTEGER NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
"permission" TEXT NOT NULL DEFAULT 'member',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "ProjectMember_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "BoardColumn" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"uuid" VARCHAR(36) NOT NULL,
|
||||
"projectId" INTEGER NOT NULL,
|
||||
"name" VARCHAR(20) NOT NULL,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
"boundStatus" VARCHAR(8),
|
||||
"retention" VARCHAR(8) NOT NULL DEFAULT 'forever',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "BoardColumn_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Task" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"uuid" VARCHAR(36) NOT NULL,
|
||||
"projectId" INTEGER NOT NULL,
|
||||
"columnId" INTEGER NOT NULL,
|
||||
"parentId" INTEGER,
|
||||
"title" VARCHAR(200) NOT NULL,
|
||||
"description" TEXT NOT NULL DEFAULT '',
|
||||
"kind" VARCHAR(20),
|
||||
"markDate" TIMESTAMP(3),
|
||||
"status" VARCHAR(8) NOT NULL DEFAULT 'todo',
|
||||
"doneAt" TIMESTAMP(3),
|
||||
"assigneeId" INTEGER,
|
||||
"creatorId" INTEGER NOT NULL,
|
||||
"extras" JSONB NOT NULL DEFAULT '[]',
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"number" INTEGER,
|
||||
|
||||
CONSTRAINT "Task_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "TaskMember" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"uuid" VARCHAR(36) NOT NULL,
|
||||
"taskId" INTEGER NOT NULL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
|
||||
CONSTRAINT "TaskMember_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "TaskTag" (
|
||||
"id" SERIAL NOT NULL,
|
||||
"uuid" VARCHAR(36) NOT NULL,
|
||||
"taskId" INTEGER NOT NULL,
|
||||
"name" VARCHAR(20) NOT NULL,
|
||||
|
||||
CONSTRAINT "TaskTag_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Article_slug_key" ON "Article"("slug");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Indicator_name_key" ON "Indicator"("name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "IndicatorPoint_indicatorId_period_key" ON "IndicatorPoint"("indicatorId", "period");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "News_publishedAt_idx" ON "News"("publishedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "News_title_publishedAt_key" ON "News"("title", "publishedAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Alert_createdAt_idx" ON "Alert"("createdAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ServerNode_uuid_key" ON "ServerNode"("uuid");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ServerNodeHistory_uuid_period_idx" ON "ServerNodeHistory"("uuid", "period");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ServerNodeHistory_uuid_period_key" ON "ServerNodeHistory"("uuid", "period");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ServiceCheck_name_key" ON "ServiceCheck"("name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Econ_SowInventory_month_key" ON "Econ_SowInventory"("month");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ScraperCache_scraperName_key" ON "ScraperCache"("scraperName");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "OilPriceHistory_province_fuel_date_idx" ON "OilPriceHistory"("province", "fuel", "date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "OilPriceHistory_date_province_fuel_key" ON "OilPriceHistory"("date", "province", "fuel");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "MihomeAccount_key_key" ON "MihomeAccount"("key");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "MihomeHome_homeId_key" ON "MihomeHome"("homeId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "MihomeDevice_did_key" ON "MihomeDevice"("did");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "MihomeEnvSample_deviceId_date_idx" ON "MihomeEnvSample"("deviceId", "date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "MihomeEnvSample_deviceId_date_key" ON "MihomeEnvSample"("deviceId", "date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "MihomeEnvHour_deviceId_hour_idx" ON "MihomeEnvHour"("deviceId", "hour");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "MihomeEnvHour_deviceId_hour_key" ON "MihomeEnvHour"("deviceId", "hour");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Habit_userId_archived_sortOrder_idx" ON "Habit"("userId", "archived", "sortOrder");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CheckIn_userId_date_idx" ON "CheckIn"("userId", "date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CheckIn_habitId_date_idx" ON "CheckIn"("habitId", "date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "CheckIn_habitId_date_seq_key" ON "CheckIn"("habitId", "date", "seq");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CheckList_userId_archived_idx" ON "CheckList"("userId", "archived");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CheckListItem_listId_sortOrder_idx" ON "CheckListItem"("listId", "sortOrder");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "CheckListTemplate_userId_builtin_idx" ON "CheckListTemplate"("userId", "builtin");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Project_uuid_key" ON "Project"("uuid");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Project_code_key" ON "Project"("code");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Project_ownerId_idx" ON "Project"("ownerId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Project_archived_idx" ON "Project"("archived");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ProjectMember_uuid_key" ON "ProjectMember"("uuid");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "ProjectMember_userId_idx" ON "ProjectMember"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "ProjectMember_projectId_userId_key" ON "ProjectMember"("projectId", "userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BoardColumn_uuid_key" ON "BoardColumn"("uuid");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "BoardColumn_projectId_sortOrder_idx" ON "BoardColumn"("projectId", "sortOrder");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "BoardColumn_projectId_name_key" ON "BoardColumn"("projectId", "name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Task_uuid_key" ON "Task"("uuid");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Task_projectId_columnId_idx" ON "Task"("projectId", "columnId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Task_projectId_status_idx" ON "Task"("projectId", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Task_parentId_idx" ON "Task"("parentId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Task_projectId_doneAt_idx" ON "Task"("projectId", "doneAt");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Task_projectId_number_key" ON "Task"("projectId", "number");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskMember_uuid_key" ON "TaskMember"("uuid");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskMember_taskId_userId_key" ON "TaskMember"("taskId", "userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "TaskTag_uuid_key" ON "TaskTag"("uuid");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "TaskTag_taskId_idx" ON "TaskTag"("taskId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "IndicatorPoint" ADD CONSTRAINT "IndicatorPoint_indicatorId_fkey" FOREIGN KEY ("indicatorId") REFERENCES "Indicator"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "MihomeDevice" ADD CONSTRAINT "MihomeDevice_homeId_fkey" FOREIGN KEY ("homeId") REFERENCES "MihomeHome"("homeId") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "MihomeEnvSample" ADD CONSTRAINT "MihomeEnvSample_deviceId_fkey" FOREIGN KEY ("deviceId") REFERENCES "MihomeDevice"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "MihomeEnvHour" ADD CONSTRAINT "MihomeEnvHour_deviceId_fkey" FOREIGN KEY ("deviceId") REFERENCES "MihomeDevice"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Habit" ADD CONSTRAINT "Habit_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CheckIn" ADD CONSTRAINT "CheckIn_habitId_fkey" FOREIGN KEY ("habitId") REFERENCES "Habit"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CheckIn" ADD CONSTRAINT "CheckIn_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CheckList" ADD CONSTRAINT "CheckList_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CheckListItem" ADD CONSTRAINT "CheckListItem_listId_fkey" FOREIGN KEY ("listId") REFERENCES "CheckList"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "CheckListTemplate" ADD CONSTRAINT "CheckListTemplate_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Project" ADD CONSTRAINT "Project_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ProjectMember" ADD CONSTRAINT "ProjectMember_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ProjectMember" ADD CONSTRAINT "ProjectMember_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "BoardColumn" ADD CONSTRAINT "BoardColumn_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Task" ADD CONSTRAINT "Task_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Task" ADD CONSTRAINT "Task_columnId_fkey" FOREIGN KEY ("columnId") REFERENCES "BoardColumn"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Task" ADD CONSTRAINT "Task_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Task"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Task" ADD CONSTRAINT "Task_assigneeId_fkey" FOREIGN KEY ("assigneeId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Task" ADD CONSTRAINT "Task_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "TaskMember" ADD CONSTRAINT "TaskMember_taskId_fkey" FOREIGN KEY ("taskId") REFERENCES "Task"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "TaskMember" ADD CONSTRAINT "TaskMember_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "TaskTag" ADD CONSTRAINT "TaskTag_taskId_fkey" FOREIGN KEY ("taskId") REFERENCES "Task"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,96 @@
|
||||
-- uuid 外键镜像 (PowerSync Sequential ID Mapping, 见 docs/V0.2/离线编辑模块/0.2.1实施方案.md §3)
|
||||
-- 目的: 同步流以 uuid 作为客户端主键 (离线新建行同步回填后本地 id 稳定不变),
|
||||
-- 外键列同步输出 uuid 镜像 (别名回 projectId/columnId/parentId/taskId), 客户端零改动。
|
||||
-- 镜像列由触发器维护: REST/Prisma 写 int 外键 -> 触发器回填 uuid; upload 端在应用层解析 uuid -> int。
|
||||
|
||||
-- 1) 加列 (先可空)
|
||||
ALTER TABLE "BoardColumn" ADD COLUMN "projectUuid" VARCHAR(36);
|
||||
ALTER TABLE "Task" ADD COLUMN "projectUuid" VARCHAR(36), ADD COLUMN "columnUuid" VARCHAR(36), ADD COLUMN "parentUuid" VARCHAR(36);
|
||||
ALTER TABLE "ProjectMember" ADD COLUMN "projectUuid" VARCHAR(36);
|
||||
ALTER TABLE "TaskMember" ADD COLUMN "taskUuid" VARCHAR(36);
|
||||
ALTER TABLE "TaskTag" ADD COLUMN "taskUuid" VARCHAR(36);
|
||||
|
||||
-- 2) 存量回填
|
||||
UPDATE "BoardColumn" c SET "projectUuid" = p."uuid" FROM "Project" p WHERE c."projectId" = p."id";
|
||||
UPDATE "Task" t SET "projectUuid" = p."uuid" FROM "Project" p WHERE t."projectId" = p."id";
|
||||
UPDATE "Task" t SET "columnUuid" = c."uuid" FROM "BoardColumn" c WHERE t."columnId" = c."id";
|
||||
UPDATE "Task" t SET "parentUuid" = pt."uuid" FROM "Task" pt WHERE t."parentId" = pt."id";
|
||||
UPDATE "ProjectMember" pm SET "projectUuid" = p."uuid" FROM "Project" p WHERE pm."projectId" = p."id";
|
||||
UPDATE "TaskMember" tm SET "taskUuid" = t."uuid" FROM "Task" t WHERE tm."taskId" = t."id";
|
||||
UPDATE "TaskTag" tt SET "taskUuid" = t."uuid" FROM "Task" t WHERE tt."taskId" = t."id";
|
||||
|
||||
-- 3) 非空约束
|
||||
ALTER TABLE "BoardColumn" ALTER COLUMN "projectUuid" SET NOT NULL;
|
||||
ALTER TABLE "Task" ALTER COLUMN "projectUuid" SET NOT NULL;
|
||||
ALTER TABLE "Task" ALTER COLUMN "columnUuid" SET NOT NULL;
|
||||
ALTER TABLE "ProjectMember" ALTER COLUMN "projectUuid" SET NOT NULL;
|
||||
ALTER TABLE "TaskMember" ALTER COLUMN "taskUuid" SET NOT NULL;
|
||||
ALTER TABLE "TaskTag" ALTER COLUMN "taskUuid" SET NOT NULL;
|
||||
|
||||
-- 4) 外键 (级联与 int 外键一致)
|
||||
ALTER TABLE "BoardColumn" ADD CONSTRAINT "BoardColumn_projectUuid_fkey" FOREIGN KEY ("projectUuid") REFERENCES "Project"("uuid") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "Task" ADD CONSTRAINT "Task_projectUuid_fkey" FOREIGN KEY ("projectUuid") REFERENCES "Project"("uuid") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "Task" ADD CONSTRAINT "Task_columnUuid_fkey" FOREIGN KEY ("columnUuid") REFERENCES "BoardColumn"("uuid") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "Task" ADD CONSTRAINT "Task_parentUuid_fkey" FOREIGN KEY ("parentUuid") REFERENCES "Task"("uuid") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ProjectMember" ADD CONSTRAINT "ProjectMember_projectUuid_fkey" FOREIGN KEY ("projectUuid") REFERENCES "Project"("uuid") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "TaskMember" ADD CONSTRAINT "TaskMember_taskUuid_fkey" FOREIGN KEY ("taskUuid") REFERENCES "Task"("uuid") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "TaskTag" ADD CONSTRAINT "TaskTag_taskUuid_fkey" FOREIGN KEY ("taskUuid") REFERENCES "Task"("uuid") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- 5) 触发器: 写入时按 int 外键回填 uuid 镜像
|
||||
CREATE OR REPLACE FUNCTION "func_projectmember_uuid_map"() RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
SELECT "uuid" INTO NEW."projectUuid" FROM "Project" WHERE "id" = NEW."projectId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'Project % 不存在', NEW."projectId"; END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER "trg_projectmember_uuid_map" BEFORE INSERT OR UPDATE ON "ProjectMember"
|
||||
FOR EACH ROW EXECUTE FUNCTION "func_projectmember_uuid_map"();
|
||||
|
||||
CREATE OR REPLACE FUNCTION "func_boardcolumn_uuid_map"() RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
SELECT "uuid" INTO NEW."projectUuid" FROM "Project" WHERE "id" = NEW."projectId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'Project % 不存在', NEW."projectId"; END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER "trg_boardcolumn_uuid_map" BEFORE INSERT OR UPDATE ON "BoardColumn"
|
||||
FOR EACH ROW EXECUTE FUNCTION "func_boardcolumn_uuid_map"();
|
||||
|
||||
CREATE OR REPLACE FUNCTION "func_task_uuid_map"() RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
SELECT "uuid" INTO NEW."projectUuid" FROM "Project" WHERE "id" = NEW."projectId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'Project % 不存在', NEW."projectId"; END IF;
|
||||
SELECT "uuid" INTO NEW."columnUuid" FROM "BoardColumn" WHERE "id" = NEW."columnId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'BoardColumn % 不存在', NEW."columnId"; END IF;
|
||||
IF NEW."parentId" IS NULL THEN
|
||||
NEW."parentUuid" := NULL;
|
||||
ELSE
|
||||
SELECT "uuid" INTO NEW."parentUuid" FROM "Task" WHERE "id" = NEW."parentId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'Task % 不存在', NEW."parentId"; END IF;
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER "trg_task_uuid_map" BEFORE INSERT OR UPDATE ON "Task"
|
||||
FOR EACH ROW EXECUTE FUNCTION "func_task_uuid_map"();
|
||||
|
||||
CREATE OR REPLACE FUNCTION "func_taskmember_uuid_map"() RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
SELECT "uuid" INTO NEW."taskUuid" FROM "Task" WHERE "id" = NEW."taskId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'Task % 不存在', NEW."taskId"; END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER "trg_taskmember_uuid_map" BEFORE INSERT OR UPDATE ON "TaskMember"
|
||||
FOR EACH ROW EXECUTE FUNCTION "func_taskmember_uuid_map"();
|
||||
|
||||
CREATE OR REPLACE FUNCTION "func_tasktag_uuid_map"() RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
SELECT "uuid" INTO NEW."taskUuid" FROM "Task" WHERE "id" = NEW."taskId";
|
||||
IF NOT FOUND THEN RAISE EXCEPTION 'Task % 不存在', NEW."taskId"; END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
CREATE TRIGGER "trg_tasktag_uuid_map" BEFORE INSERT OR UPDATE ON "TaskTag"
|
||||
FOR EACH ROW EXECUTE FUNCTION "func_tasktag_uuid_map"();
|
||||
@@ -1,3 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "mysql"
|
||||
provider = "postgresql"
|
||||
|
||||
+23
-6
@@ -9,7 +9,7 @@ generator client {
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "mysql"
|
||||
provider = "postgresql"
|
||||
}
|
||||
|
||||
model User {
|
||||
@@ -388,6 +388,8 @@ model CheckListTemplate {
|
||||
|
||||
model Project {
|
||||
id Int @id @default(autoincrement())
|
||||
uuid String @unique @db.VarChar(36) // 同步标识: 客户端生成 (0.2.1 离线编辑, 见 docs/V0.2/离线编辑模块)
|
||||
code String @unique @db.VarChar(8) // 项目短编号: 用户自拟 2~8 位前缀, 全局唯一, 服务端分配
|
||||
name String @db.VarChar(50)
|
||||
ownerId Int
|
||||
owner User @relation("ProjectOwner", fields: [ownerId], references: [id], onDelete: Cascade)
|
||||
@@ -409,8 +411,10 @@ model Project {
|
||||
}
|
||||
|
||||
model ProjectMember {
|
||||
id Int @id @default(autoincrement())
|
||||
projectId Int
|
||||
id Int @id @default(autoincrement())
|
||||
uuid String @unique @db.VarChar(36) // 同步标识: 客户端生成 (0.2.1 离线编辑)
|
||||
projectUuid String? @db.VarChar(36) // 外键 uuid 镜像 (触发器维护, 库级 NOT NULL)
|
||||
projectId Int
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
userId Int
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
@@ -423,6 +427,8 @@ model ProjectMember {
|
||||
|
||||
model BoardColumn {
|
||||
id Int @id @default(autoincrement())
|
||||
uuid String @unique @db.VarChar(36) // 同步标识: 客户端生成 (0.2.1 离线编辑)
|
||||
projectUuid String? @db.VarChar(36) // projectId 的 uuid 镜像 (触发器维护, 库级 NOT NULL; Prisma 侧可空以便触发器填充)
|
||||
projectId Int
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
name String @db.VarChar(20)
|
||||
@@ -440,6 +446,10 @@ model BoardColumn {
|
||||
|
||||
model Task {
|
||||
id Int @id @default(autoincrement())
|
||||
uuid String @unique @db.VarChar(36) // 同步标识: 客户端生成 (0.2.1 离线编辑)
|
||||
projectUuid String? @db.VarChar(36) // 外键 uuid 镜像 (触发器维护, 库级 NOT NULL)
|
||||
columnUuid String? @db.VarChar(36)
|
||||
parentUuid String? @db.VarChar(36)
|
||||
projectId Int
|
||||
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
||||
columnId Int
|
||||
@@ -471,6 +481,9 @@ model Task {
|
||||
members TaskMember[]
|
||||
tags TaskTag[]
|
||||
|
||||
number Int? // 项目内自增编号 (服务端分配, 展示为 `code-number`); 本地未定号的离线新建任务为空
|
||||
|
||||
@@unique([projectId, number])
|
||||
@@index([projectId, columnId])
|
||||
@@index([projectId, status])
|
||||
@@index([parentId])
|
||||
@@ -480,7 +493,9 @@ model Task {
|
||||
}
|
||||
|
||||
model TaskMember {
|
||||
id Int @id @default(autoincrement())
|
||||
id Int @id @default(autoincrement())
|
||||
uuid String @unique @db.VarChar(36) // 同步标识: 客户端生成 (0.2.1 离线编辑)
|
||||
taskUuid String? @db.VarChar(36) // 外键 uuid 镜像 (触发器维护, 库级 NOT NULL)
|
||||
taskId Int
|
||||
task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
||||
userId Int
|
||||
@@ -490,8 +505,10 @@ model TaskMember {
|
||||
}
|
||||
|
||||
model TaskTag {
|
||||
id Int @id @default(autoincrement())
|
||||
taskId Int
|
||||
id Int @id @default(autoincrement())
|
||||
uuid String @unique @db.VarChar(36) // 同步标识: 客户端生成 (0.2.1 离线编辑)
|
||||
taskUuid String? @db.VarChar(36) // 外键 uuid 镜像 (触发器维护, 库级 NOT NULL)
|
||||
taskId Int
|
||||
task Task @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
||||
name String @db.VarChar(20)
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<!-- 悬浮球 (W-SNP-02): 半圆形贴边图标, 圆弧朝屏幕内侧, 由 Rust 控制位置与主题 -->
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0; padding: 0; width: 100%; height: 100%;
|
||||
background: transparent; overflow: hidden; user-select: none;
|
||||
}
|
||||
#ball { position: fixed; inset: 0; cursor: pointer; transition: transform .12s ease; }
|
||||
/* 半圆: 直边贴屏幕边缘, 圆弧朝内 (四边方向) */
|
||||
.dock-left #ball { border-radius: 0 28px 28px 0; } /* 左缘 → 凸向右 */
|
||||
.dock-right #ball { border-radius: 28px 0 0 28px; } /* 右缘 → 凸向左 */
|
||||
.dock-top #ball { border-radius: 0 0 28px 28px; } /* 上缘 → 凸向下 */
|
||||
.dock-bottom #ball { border-radius: 28px 28px 0 0; } /* 下缘 → 凸向上 */
|
||||
/* 深浅色 (W-THE-01): 跟随系统应用模式 */
|
||||
.theme-light #ball { background: rgba(28, 28, 30, 0.92); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.35); }
|
||||
.theme-dark #ball { background: rgba(245, 245, 245, 0.95); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25); }
|
||||
#ball::after {
|
||||
content: ""; position: absolute; left: 50%; top: 50%;
|
||||
width: 8px; height: 8px; border-radius: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.theme-light #ball::after { background: rgba(255, 255, 255, 0.85); }
|
||||
.theme-dark #ball::after { background: rgba(30, 30, 30, 0.75); }
|
||||
#ball:hover { transform: scale(1.06); }
|
||||
</style>
|
||||
</head>
|
||||
<body class="dock-left theme-light">
|
||||
<div id="ball"></div>
|
||||
<script src="./dock.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,65 @@
|
||||
// 悬浮球交互 (W-SNP-04/05/12/13/14):
|
||||
// mouseenter/leave → hover 延时恢复 (Rust 侧计时 150ms)
|
||||
// 单击 (位移 ≤4px) → 立即恢复, 触屏点按等效
|
||||
// 拖动 → dock_drag_move 增量移动, 结束时按最近边停靠/换边/拖出
|
||||
const { invoke } = window.__TAURI__.core
|
||||
const ball = document.getElementById('ball')
|
||||
|
||||
let dragging = false
|
||||
let moved = 0
|
||||
let lastX = 0
|
||||
let lastY = 0
|
||||
|
||||
ball.addEventListener('mouseenter', () => invoke('dock_hover_start'))
|
||||
ball.addEventListener('mouseleave', () => invoke('dock_hover_end'))
|
||||
ball.addEventListener('contextmenu', (e) => e.preventDefault())
|
||||
|
||||
ball.addEventListener('pointerdown', (e) => {
|
||||
dragging = true
|
||||
moved = 0
|
||||
lastX = e.clientX
|
||||
lastY = e.clientY
|
||||
ball.setPointerCapture(e.pointerId)
|
||||
invoke('dock_drag_start')
|
||||
})
|
||||
|
||||
ball.addEventListener('pointermove', (e) => {
|
||||
if (!dragging) return
|
||||
const dx = e.clientX - lastX
|
||||
const dy = e.clientY - lastY
|
||||
if (dx === 0 && dy === 0) return
|
||||
lastX = e.clientX
|
||||
lastY = e.clientY
|
||||
moved += Math.abs(dx) + Math.abs(dy)
|
||||
if (moved > 4) {
|
||||
// clientX 为逻辑像素, 增量按 DPI 缩放换算成物理像素 (Rust 注入 __SCALE)
|
||||
const s = window.__SCALE || 1
|
||||
invoke('dock_drag_move', { dx: Math.round(dx * s), dy: Math.round(dy * s) })
|
||||
}
|
||||
})
|
||||
|
||||
ball.addEventListener('pointerup', (e) => {
|
||||
if (!dragging) return
|
||||
dragging = false
|
||||
try { ball.releasePointerCapture(e.pointerId) } catch { /* 已释放 */ }
|
||||
if (moved <= 4) {
|
||||
invoke('dock_click')
|
||||
} else {
|
||||
invoke('dock_drag_end')
|
||||
}
|
||||
})
|
||||
|
||||
ball.addEventListener('pointercancel', () => {
|
||||
dragging = false
|
||||
invoke('dock_drag_end')
|
||||
})
|
||||
|
||||
// Rust 在停靠/换边/主题变化时调用
|
||||
window.applyDock = (edge, theme) => {
|
||||
document.body.className = 'dock-' + edge + ' theme-' + theme
|
||||
}
|
||||
window.applyTheme = (theme) => {
|
||||
const edge = [...document.body.classList].find((c) => c.startsWith('dock-')) || 'dock-left'
|
||||
document.body.className = edge + ' theme-' + theme
|
||||
}
|
||||
window.__SCALE = 1
|
||||
@@ -0,0 +1,152 @@
|
||||
#!/usr/bin/env node
|
||||
// Windows 外壳一键构建 (开发用): 安装包 (NSIS) + 便携版 (portable zip)
|
||||
//
|
||||
// 用法:
|
||||
// npm run build:win # 完整流程
|
||||
// node scripts/build-windows.mjs --skip-check # 跳过版本一致性校验
|
||||
// node scripts/build-windows.mjs --debug # debug 构建 (快速验证, 产物带 -debug 后缀)
|
||||
//
|
||||
// 流程:
|
||||
// 1) 版本一致性校验 (scripts/ci/check-version.mjs, 外壳三件套)
|
||||
// 2) 前端构建 (build:shell, 注入 VITE_API_BASE 指向远端后端)
|
||||
// 3) tauri build --bundles nsis → 编译一次 release exe + NSIS 安装包
|
||||
// 4) 复用同一个 exe 组装便携版目录并压成 zip (不二次编译)
|
||||
//
|
||||
// 产物 (artifacts/windows/):
|
||||
// iBoard_<ver>_x64-setup.exe 安装包 (当前用户安装, 免管理员)
|
||||
// iBoard_<ver>_x64-portable.zip 便携版 (解压即用)
|
||||
// portable/ 便携版解压目录 (iBoard.exe + README.txt)
|
||||
//
|
||||
// 说明: 便携版不内置 WebView2 —— 目标机需 Win10 19041+ / Win11 (系统自带 WebView2 Runtime)。
|
||||
import { spawnSync } from 'node:child_process'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const args = process.argv.slice(2)
|
||||
const skipCheck = args.includes('--skip-check')
|
||||
const isDebug = args.includes('--debug')
|
||||
const profile = isDebug ? 'debug' : 'release'
|
||||
|
||||
const conf = JSON.parse(fs.readFileSync(path.join(root, 'src-tauri', 'tauri.conf.json'), 'utf8'))
|
||||
const version = String(conf.version || '0.0.0')
|
||||
const product = conf.productName || 'iBoard'
|
||||
const suffix = isDebug ? '-debug' : ''
|
||||
|
||||
const artifactsDir = path.join(root, 'artifacts', 'windows')
|
||||
const targetDir = path.join(root, 'src-tauri', 'target', profile)
|
||||
|
||||
function log(msg) {
|
||||
console.log(`\x1b[36m[build-win]\x1b[0m ${msg}`)
|
||||
}
|
||||
function fail(msg) {
|
||||
console.error(`\x1b[31m[build-win] 失败: ${msg}\x1b[0m`)
|
||||
process.exit(1)
|
||||
}
|
||||
function run(cmd, cmdArgs, opts = {}) {
|
||||
log(`$ ${cmd} ${cmdArgs.join(' ')}`)
|
||||
const res = spawnSync(cmd, cmdArgs, {
|
||||
cwd: root,
|
||||
stdio: 'inherit',
|
||||
shell: process.platform === 'win32',
|
||||
...opts,
|
||||
})
|
||||
if (res.status !== 0) fail(`${cmd} ${cmdArgs.join(' ')} 退出码 ${res.status}`)
|
||||
}
|
||||
|
||||
// ---------- 0. 前置检查 ----------
|
||||
if (process.platform !== 'win32') fail('本脚本仅支持 Windows')
|
||||
if (!fs.existsSync(path.join(root, 'node_modules'))) fail('缺少 node_modules, 请先运行 npm ci')
|
||||
|
||||
log(`项目 ${product} 外壳版本 ${version} (${profile})`)
|
||||
|
||||
// ---------- 1. 版本一致性 ----------
|
||||
if (!skipCheck) {
|
||||
log('校验版本一致性 (外壳 tauri.conf.json / Cargo.toml / Cargo.lock)')
|
||||
run('node', ['scripts/ci/check-version.mjs'], {
|
||||
env: { ...process.env, BRANCH: process.env.BRANCH || '' },
|
||||
})
|
||||
} else {
|
||||
log('跳过版本一致性校验 (--skip-check)')
|
||||
}
|
||||
|
||||
// ---------- 2. 前端构建 ----------
|
||||
log('构建前端 (build:shell, VITE_API_BASE 指向远端后端)')
|
||||
run('npm', ['run', 'build:shell'])
|
||||
|
||||
// ---------- 3. 安装包 (NSIS) ----------
|
||||
const tauriArgs = ['tauri', 'build']
|
||||
if (isDebug) tauriArgs.push('--debug')
|
||||
// 只出 NSIS: 避免 bundle.targets="all" 在 Windows 上拉 WiX 打 MSI
|
||||
tauriArgs.push('--bundles', 'nsis')
|
||||
log('编译外壳并生成 NSIS 安装包')
|
||||
run('npx', tauriArgs)
|
||||
|
||||
// ---------- 4. 便携版 ----------
|
||||
const exePath = path.join(targetDir, `iboard${suffix}.exe`)
|
||||
if (!fs.existsSync(exePath)) fail(`未找到构建产物 ${exePath}`)
|
||||
|
||||
fs.rmSync(artifactsDir, { recursive: true, force: true })
|
||||
fs.mkdirSync(artifactsDir, { recursive: true })
|
||||
|
||||
const portableDir = path.join(artifactsDir, 'portable')
|
||||
fs.mkdirSync(portableDir, { recursive: true })
|
||||
const portableExe = path.join(portableDir, `${product}.exe`)
|
||||
fs.copyFileSync(exePath, portableExe)
|
||||
|
||||
const readme = `${product} ${version} 便携版 (Windows x64)
|
||||
=================================================
|
||||
|
||||
免安装: 双击 ${product}.exe 即可运行。
|
||||
|
||||
系统要求
|
||||
- Windows 10 19041+ 或 Windows 11 (x64)
|
||||
- WebView2 Runtime: Win10/11 系统自带; 若提示缺失, 请安装
|
||||
https://developer.microsoft.com/microsoft-edge/webview2/
|
||||
|
||||
使用说明
|
||||
- 关闭窗口 = 隐藏到托盘, 不会退出; 退出请用托盘右键菜单「退出」。
|
||||
- 窗口贴屏幕边缘会自动收起为半圆悬浮球, 鼠标停留或单击唤回。
|
||||
- 托盘菜单可开关「开机启动」「边缘吸附」。
|
||||
- 配置保存在 %APPDATA%\\com.iboard.app\\shell-config.json (删除即恢复默认)。
|
||||
|
||||
注意: 便携版不写注册表、不装服务; 但若开启了「开机启动」, 会在
|
||||
HKCU\\...\\Run 写入自启动项, 关闭开关即可移除。
|
||||
`
|
||||
fs.writeFileSync(path.join(portableDir, 'README.txt'), readme, 'utf8')
|
||||
|
||||
const zipName = `${product}_${version}_x64-portable${suffix}.zip`
|
||||
const zipPath = path.join(artifactsDir, zipName)
|
||||
log('打包便携版 zip')
|
||||
const psZip = `Compress-Archive -Path '${portableDir}\\*' -DestinationPath '${zipPath}' -Force`
|
||||
const res = spawnSync('powershell', ['-NoProfile', '-NonInteractive', '-Command', psZip], {
|
||||
cwd: root,
|
||||
stdio: 'inherit',
|
||||
})
|
||||
if (res.status !== 0) fail('压缩便携版失败 (Compress-Archive)')
|
||||
|
||||
// ---------- 5. 汇总 ----------
|
||||
const setupExe = path.join(
|
||||
targetDir,
|
||||
'bundle',
|
||||
'nsis',
|
||||
`${product}_${version}_x64-setup${suffix}.exe`,
|
||||
)
|
||||
const outputs = []
|
||||
if (fs.existsSync(setupExe)) {
|
||||
const dest = path.join(artifactsDir, path.basename(setupExe))
|
||||
fs.copyFileSync(setupExe, dest)
|
||||
outputs.push(['安装包 (NSIS)', dest])
|
||||
} else {
|
||||
outputs.push(['安装包 (NSIS)', `未找到: ${setupExe}`])
|
||||
}
|
||||
outputs.push(['便携版 (zip)', zipPath])
|
||||
outputs.push(['便携版 (目录)', `${portableDir} (${fs.readdirSync(portableDir).length} 个文件)`])
|
||||
|
||||
log('构建完成:')
|
||||
for (const [label, p] of outputs) {
|
||||
const size = fs.existsSync(p) ? `${(fs.statSync(p).size / 1024 / 1024).toFixed(1)} MB` : ''
|
||||
console.log(` ${label.padEnd(14)} ${p}${size ? ' (' + size + ')' : ''}`)
|
||||
}
|
||||
process.exit(0)
|
||||
@@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
# 0.2.1 生产部署 (master 分支 CI 调用; 也可在服务器手工执行)
|
||||
#
|
||||
# 架构: app(3001 对外) + pg(内网) + powersync(内网), 见 deploy/prod/
|
||||
# 幂等: 迁移 -> publication -> 起栈; 任一环节失败则退出, 不切换流量
|
||||
#
|
||||
# 所需环境变量 (由 CI secrets 注入):
|
||||
# PG_PASSWORD, PS_STORAGE_PASSWORD, JWT_SECRET, POWERSYNC_JWT_SECRET,
|
||||
# POWERSYNC_JWT_KEY_B64, PUBLIC_URL(可选, 默认 https://iboard.honor3.com)
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="${ROOT:-/app/iboard-prod}"
|
||||
COMPOSE_FILE="$ROOT/deploy/prod/docker-compose.yml"
|
||||
ENV_FILE="$ROOT/deploy/prod/.env"
|
||||
PROJECT="iboard-prod"
|
||||
|
||||
log() { echo "[deploy] $*"; }
|
||||
die() { echo "[deploy][ERROR] $*" >&2; exit 1; }
|
||||
|
||||
for v in PG_PASSWORD PS_STORAGE_PASSWORD JWT_SECRET POWERSYNC_JWT_SECRET POWERSYNC_JWT_KEY_B64; do
|
||||
[ -n "${!v:-}" ] || die "缺少环境变量 $v (请在 Gitea Actions secrets 配置)"
|
||||
done
|
||||
[ -f "$COMPOSE_FILE" ] || die "找不到 $COMPOSE_FILE (源码需上传到 $ROOT)"
|
||||
|
||||
log "写入 $ENV_FILE"
|
||||
umask 077
|
||||
cat > "$ENV_FILE" <<EOF
|
||||
PG_PASSWORD=$PG_PASSWORD
|
||||
PS_STORAGE_PASSWORD=$PS_STORAGE_PASSWORD
|
||||
JWT_SECRET=$JWT_SECRET
|
||||
POWERSYNC_JWT_SECRET=$POWERSYNC_JWT_SECRET
|
||||
POWERSYNC_JWT_KEY_B64=$POWERSYNC_JWT_KEY_B64
|
||||
PUBLIC_URL=${PUBLIC_URL:-https://iboard.honor3.com}
|
||||
EOF
|
||||
|
||||
cd "$ROOT/deploy/prod"
|
||||
mkdir -p data/pg data/cache
|
||||
|
||||
log "启动数据库"
|
||||
docker compose --project-name "$PROJECT" --env-file "$ENV_FILE" -f "$COMPOSE_FILE" up -d pg
|
||||
|
||||
log "等待数据库就绪"
|
||||
for i in $(seq 1 30); do
|
||||
if docker compose --project-name "$PROJECT" --env-file "$ENV_FILE" -f "$COMPOSE_FILE" exec -T pg pg_isready -U iboard -d iboard >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
log "执行数据库迁移"
|
||||
docker run --rm --network "${PROJECT}_default" \
|
||||
-e DATABASE_URL="postgresql://iboard:${PG_PASSWORD}@pg:5432/iboard" \
|
||||
iboard:latest npx prisma migrate deploy
|
||||
|
||||
log "确保逻辑复制 publication 存在"
|
||||
docker compose --project-name "$PROJECT" --env-file "$ENV_FILE" -f "$COMPOSE_FILE" exec -T pg \
|
||||
psql -U iboard -d iboard -v ON_ERROR_STOP=1 -f /dev/stdin < sql/publication.sql
|
||||
|
||||
log "启动应用与同步服务"
|
||||
docker compose --project-name "$PROJECT" --env-file "$ENV_FILE" -f "$COMPOSE_FILE" up -d app powersync
|
||||
|
||||
log "等待健康检查"
|
||||
for i in $(seq 1 30); do
|
||||
if curl -fsS --max-time 3 http://127.0.0.1:3001/api/health >/dev/null 2>&1; then
|
||||
log "健康检查通过"
|
||||
exit 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
die "应用未通过健康检查, 请查看 docker compose logs"
|
||||
@@ -0,0 +1,201 @@
|
||||
// 一次性数据迁移: 现网 MariaDB 只读快照 -> 0.2.1 PostgreSQL
|
||||
// 运行 (在 app 容器内, 具备 mariadb 驱动与 PG 客户端):
|
||||
// SRC_DATABASE_URL=mysql://... node scripts/etl-mariadb-to-pg.mjs
|
||||
// 约束: 源库仅 SELECT; 目标库须为空 (Project 计数为 0), 除非 ETL_FORCE=1
|
||||
// 迁移内容见 docs/V0.2/离线编辑模块/0.2.1实施方案.md §6:
|
||||
// - 任务域 6 表回填 uuid; Project 回填短编号 code; Task 按项目内 (createdAt,id) 顺序回填 number
|
||||
// - 时序大表 (ServerNodeHistory/MihomeEnv*) 仅取最近 N 条
|
||||
// - 显式 id 插入后逐表 setval 校准序列
|
||||
import 'dotenv/config'
|
||||
import crypto from 'node:crypto'
|
||||
import mariadb from 'mariadb'
|
||||
import { PrismaPg } from '@prisma/adapter-pg'
|
||||
import { PrismaClient } from '../generated/prisma/client.ts'
|
||||
|
||||
// 顺序: 先父后子
|
||||
const TABLES = [
|
||||
['User', 'user'],
|
||||
['Project', 'project'],
|
||||
['ProjectMember', 'projectMember'],
|
||||
['BoardColumn', 'boardColumn'],
|
||||
['Habit', 'habit'],
|
||||
['CheckList', 'checkList'],
|
||||
['CheckListTemplate', 'checkListTemplate'],
|
||||
['CheckListItem', 'checkListItem'],
|
||||
['CheckIn', 'checkIn'],
|
||||
['Task', 'task'],
|
||||
['TaskMember', 'taskMember'],
|
||||
['TaskTag', 'taskTag'],
|
||||
['Article', 'article'],
|
||||
['Strategy', 'strategy'],
|
||||
['Indicator', 'indicator'],
|
||||
['IndicatorPoint', 'indicatorPoint'],
|
||||
['News', 'news'],
|
||||
['Alert', 'alert'],
|
||||
['ServerNode', 'serverNode'],
|
||||
['ServerNodeHistory', 'serverNodeHistory'],
|
||||
['ServiceCheck', 'serviceCheck'],
|
||||
['Econ_SowInventory', 'econ_SowInventory'],
|
||||
['ScraperCache', 'scraperCache'],
|
||||
['OilPriceHistory', 'oilPriceHistory'],
|
||||
['MihomeAccount', 'mihomeAccount'],
|
||||
['MihomeHome', 'mihomeHome'],
|
||||
['MihomeDevice', 'mihomeDevice'],
|
||||
['MihomeEnvSample', 'mihomeEnvSample'],
|
||||
['MihomeEnvHour', 'mihomeEnvHour'],
|
||||
]
|
||||
|
||||
const ROW_CAP = { ServerNodeHistory: 20000, MihomeEnvSample: 20000, MihomeEnvHour: 20000 }
|
||||
|
||||
const UUID_TABLES = new Set(['Project', 'ProjectMember', 'BoardColumn', 'Task', 'TaskMember', 'TaskTag'])
|
||||
|
||||
function parseUrl(url) {
|
||||
const u = new URL(url)
|
||||
return {
|
||||
host: u.hostname,
|
||||
port: Number(u.port) || 3306,
|
||||
user: decodeURIComponent(u.username),
|
||||
password: decodeURIComponent(u.password),
|
||||
database: u.pathname.replace(/^\//, ''),
|
||||
}
|
||||
}
|
||||
|
||||
function parseJson(v) {
|
||||
if (v === null || v === undefined || typeof v !== 'string') return v
|
||||
try { return JSON.parse(v) } catch { return v }
|
||||
}
|
||||
|
||||
function toBigInt(v) {
|
||||
if (v === null || v === undefined || typeof v === 'bigint') return v
|
||||
return BigInt(v)
|
||||
}
|
||||
|
||||
// MariaDB TINYINT(1) 返回 0/1, Prisma Boolean 需要 true/false
|
||||
function toBoolean(v) {
|
||||
if (v === null || v === undefined) return v
|
||||
return !!v
|
||||
}
|
||||
|
||||
function randCode(len) {
|
||||
return crypto.randomBytes(len * 2).toString('hex').toUpperCase().replace(/[^A-Z0-9]/g, '').padEnd(len, 'X').slice(0, len)
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const src = process.env.SRC_DATABASE_URL
|
||||
if (!src) throw new Error('SRC_DATABASE_URL 未配置')
|
||||
const cfg = parseUrl(src)
|
||||
|
||||
const conn = await mariadb.createConnection({
|
||||
host: cfg.host, port: cfg.port, user: cfg.user, password: cfg.password, database: cfg.database, connectTimeout: 8000,
|
||||
})
|
||||
console.log('[etl] 源库已连接 (只读):', `${cfg.host}:${cfg.port}/${cfg.database}`)
|
||||
|
||||
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL })
|
||||
const prisma = new PrismaClient({ adapter })
|
||||
|
||||
const existing = await prisma.project.count()
|
||||
if (existing > 0 && process.env.ETL_FORCE !== '1') {
|
||||
console.log(`[etl] 目标库已有 ${existing} 个项目, 跳过 (ETL_FORCE=1 可强制)`)
|
||||
await conn.end()
|
||||
return
|
||||
}
|
||||
|
||||
// 目标 PG 列清单 (类型感知转换 + 源库多余列丢弃): 现网库可能比本分支 schema 新
|
||||
const targetColumns = new Map()
|
||||
for (const [table] of TABLES) {
|
||||
const cols = await prisma.$queryRawUnsafe(
|
||||
`SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'public' AND table_name = $1`,
|
||||
table,
|
||||
)
|
||||
targetColumns.set(table, new Map(cols.map((c) => [c.column_name, c.data_type])))
|
||||
}
|
||||
|
||||
function adaptRow(table, r) {
|
||||
const cols = targetColumns.get(table)
|
||||
const out = {}
|
||||
for (const [name, dataType] of cols) {
|
||||
let v = r[name]
|
||||
if (v === undefined) v = null
|
||||
if (dataType === 'boolean') v = toBoolean(v)
|
||||
else if (dataType === 'bigint') v = toBigInt(v)
|
||||
else if (dataType === 'json' || dataType === 'jsonb') v = parseJson(v)
|
||||
out[name] = v
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Project.code 回填: 优先按名称推导字母, 冲突加随机尾缀
|
||||
const projectRows = await conn.query('SELECT * FROM `Project`')
|
||||
const usedCodes = new Set()
|
||||
for (const p of projectRows) {
|
||||
const letters = String(p.name || '').toUpperCase().replace(/[^A-Z0-9]/g, '')
|
||||
let cand = ''
|
||||
for (let i = 0; i < 30 && !cand; i++) {
|
||||
const base = i === 0
|
||||
? (letters.length >= 2 ? letters.slice(0, 8) : ('P' + String(p.id) + randCode(4)).slice(0, 8))
|
||||
: (letters.slice(0, 5) + randCode(3)).slice(0, 8)
|
||||
if (base.length >= 2 && !usedCodes.has(base)) cand = base
|
||||
}
|
||||
if (!cand) cand = randCode(6)
|
||||
usedCodes.add(cand)
|
||||
p.code = cand
|
||||
}
|
||||
|
||||
// Task.number 回填: 项目内按 (createdAt, id) 顺序 1..n
|
||||
const taskRows = (await conn.query('SELECT * FROM `Task`')).sort((a, b) => {
|
||||
if (a.projectId !== b.projectId) return a.projectId - b.projectId
|
||||
const ta = a.createdAt ? new Date(a.createdAt).getTime() : 0
|
||||
const tb = b.createdAt ? new Date(b.createdAt).getTime() : 0
|
||||
if (ta !== tb) return ta - tb
|
||||
return a.id - b.id
|
||||
})
|
||||
const taskNumber = new Map()
|
||||
for (const r of taskRows) {
|
||||
const key = String(r.projectId)
|
||||
const next = (taskNumber.get(key) || 0) + 1
|
||||
taskNumber.set(key, next)
|
||||
r.number = next
|
||||
}
|
||||
|
||||
const counts = {}
|
||||
for (const [table, model] of TABLES) {
|
||||
let rows
|
||||
if (table === 'Project') rows = projectRows
|
||||
else if (table === 'Task') rows = taskRows
|
||||
else {
|
||||
const cap = ROW_CAP[table]
|
||||
rows = await conn.query(cap ? `SELECT * FROM \`${table}\` ORDER BY id DESC LIMIT ${cap}` : `SELECT * FROM \`${table}\``)
|
||||
}
|
||||
if (rows.length) {
|
||||
const adapted = rows.map((r) => {
|
||||
if (UUID_TABLES.has(table)) r.uuid = crypto.randomUUID()
|
||||
return adaptRow(table, r)
|
||||
})
|
||||
const chunk = 500
|
||||
for (let i = 0; i < adapted.length; i += chunk) {
|
||||
await prisma[model].createMany({ data: adapted.slice(i, i + chunk) })
|
||||
}
|
||||
}
|
||||
counts[table] = rows.length
|
||||
console.log(`[etl] ${table}: ${rows.length}`)
|
||||
}
|
||||
|
||||
// 序列校准: 显式插入 id 后必须 setval, 否则新插入主键冲突
|
||||
for (const [table] of TABLES) {
|
||||
await prisma.$executeRawUnsafe(
|
||||
`SELECT setval(pg_get_serial_sequence('"${table}"', 'id'), COALESCE((SELECT MAX(id) FROM "${table}"), 0) + 1, false)`,
|
||||
)
|
||||
}
|
||||
|
||||
await conn.end()
|
||||
const summary = {
|
||||
users: await prisma.user.count(),
|
||||
projects: await prisma.project.count(),
|
||||
tasks: await prisma.task.count(),
|
||||
checkIns: await prisma.checkIn.count(),
|
||||
news: await prisma.news.count(),
|
||||
}
|
||||
console.log('[etl] 完成:', JSON.stringify(summary))
|
||||
}
|
||||
|
||||
main().catch((e) => { console.error('[etl] 失败:', e); process.exit(1) })
|
||||
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env node
|
||||
// 生成托盘深浅色单色图标 (W-THE-01):
|
||||
// src-tauri/icons/tray-light.png 深色字形 —— 浅色任务栏用
|
||||
// src-tauri/icons/tray-dark.png 白色字形 —— 深色任务栏用
|
||||
//
|
||||
// 做法: 不能只用 alpha 通道做剪影 —— 源图标是「深色圆角方块 + 白色 i」,
|
||||
// 整个方块都是不透明的, 只取 alpha 会得到一块纯色方块, i 字母细节全丢。
|
||||
// 这里按**亮度**映射, 保留字母结构:
|
||||
// 深色字形: alpha = (255-L)/255 → 方块保留深色, 白色 i 镂空透出任务栏
|
||||
// 浅色字形: alpha = max(L,40)/255 → i 白色高亮, 方块留一点淡淡衬底
|
||||
// 产物已提交进仓库, 仅图标变更时需要重跑: node scripts/gen-tray-icons.mjs
|
||||
import sharp from 'sharp'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import path from 'node:path'
|
||||
|
||||
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const src = path.join(root, 'src-tauri', 'icons', '128x128.png')
|
||||
const outDir = path.join(root, 'src-tauri', 'icons')
|
||||
|
||||
const targets = [
|
||||
{ file: 'tray-light.png', rgb: [31, 31, 31], mode: 'dark-glyph' }, // 深色字形 (浅色任务栏)
|
||||
{ file: 'tray-dark.png', rgb: [250, 250, 250], mode: 'light-glyph' }, // 白色字形 (深色任务栏)
|
||||
]
|
||||
|
||||
for (const t of targets) {
|
||||
const { data, info } = await sharp(src)
|
||||
.resize(32, 32, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } })
|
||||
.ensureAlpha()
|
||||
.raw()
|
||||
.toBuffer({ resolveWithObject: true })
|
||||
const out = Buffer.alloc(info.width * info.height * 4)
|
||||
for (let i = 0; i < info.width * info.height; i++) {
|
||||
const r = data[i * 4]
|
||||
const g = data[i * 4 + 1]
|
||||
const b = data[i * 4 + 2]
|
||||
const a = data[i * 4 + 3]
|
||||
const lumi = 0.2126 * r + 0.7152 * g + 0.0722 * b
|
||||
const alpha =
|
||||
t.mode === 'dark-glyph' ? (a * (255 - lumi)) / 255 : (a * Math.max(lumi, 40)) / 255
|
||||
out[i * 4] = t.rgb[0]
|
||||
out[i * 4 + 1] = t.rgb[1]
|
||||
out[i * 4 + 2] = t.rgb[2]
|
||||
out[i * 4 + 3] = Math.round(alpha)
|
||||
}
|
||||
await sharp(out, { raw: { width: info.width, height: info.height, channels: 4 } })
|
||||
.png()
|
||||
.toFile(path.join(outDir, t.file))
|
||||
console.log('generated', t.file)
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
// 0.2.1 闭环验证脚本 (Node 客户端): 同步下行 -> 本地离线写入 -> 上行 -> 服务端编号 -> 同步回填
|
||||
// 用法: node scripts/verify-powersync-client.mjs [BASE_URL] [EMAIL] [PASSWORD]
|
||||
// BASE_URL 默认 http://bh.vps.honor3.com:13001
|
||||
// 依赖 (dev-only, 不进服务端镜像; 运行前补装): npm install --no-save @powersync/node better-sqlite3
|
||||
// 流程:
|
||||
// 1. REST 登录 -> /api/powersync/token
|
||||
// 2. Node SDK 连接 PowerSync, 等待首次同步, 校验 ETL 数据 (项目/任务/编号)
|
||||
// 3. 本地新建一条验证任务 (number 为空, 模拟离线写入)
|
||||
// 4. 等待 upload 完成并同步回填 -> 本地行应获得服务端分配的 number
|
||||
// 5. 清理: 本地删除该任务 (上行级联删除), 恢复数据原状
|
||||
import 'dotenv/config'
|
||||
import crypto from 'node:crypto'
|
||||
import os from 'node:os'
|
||||
import path from 'node:path'
|
||||
import fs from 'node:fs'
|
||||
import { column, Schema, Table, PowerSyncDatabase, createConsoleLogger, LogLevels } from '@powersync/node'
|
||||
|
||||
const BASE = (process.argv[2] || 'http://bh.vps.honor3.com:13001').replace(/\/+$/, '')
|
||||
const EMAIL = process.argv[3] || 'admin@iboard.local'
|
||||
const PASSWORD = process.argv[4] || 'admin123'
|
||||
|
||||
const uuid = () => crypto.randomUUID()
|
||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms))
|
||||
|
||||
// 与 src/lib/powersync/schema.js 同构的最小 schema (验证只用到 Project/Task/TaskTag)
|
||||
const AppSchema = new Schema({
|
||||
Project: new Table({
|
||||
uuid: column.text, code: column.text, name: column.text, ownerId: column.text,
|
||||
isPersonal: column.integer, archived: column.integer, notes: column.text,
|
||||
taskKinds: column.text, icon: column.text, createdAt: column.text, updatedAt: column.text,
|
||||
}),
|
||||
Task: new Table({
|
||||
uuid: column.text, projectId: column.text, columnId: column.text, parentId: column.text,
|
||||
title: column.text, description: column.text, kind: column.text, markDate: column.text,
|
||||
status: column.text, doneAt: column.text, assigneeId: column.text, creatorId: column.text,
|
||||
extras: column.text, sortOrder: column.integer, number: column.integer,
|
||||
createdAt: column.text, updatedAt: column.text,
|
||||
}),
|
||||
TaskTag: new Table({ uuid: column.text, taskId: column.text, name: column.text }),
|
||||
TaskMember: new Table({ uuid: column.text, taskId: column.text, userId: column.text }),
|
||||
ProjectMember: new Table({ uuid: column.text, projectId: column.text, userId: column.text, permission: column.text, createdAt: column.text }),
|
||||
BoardColumn: new Table({
|
||||
uuid: column.text, projectId: column.text, name: column.text, sortOrder: column.integer,
|
||||
boundStatus: column.text, retention: column.text, createdAt: column.text, updatedAt: column.text,
|
||||
}),
|
||||
User: new Table({ name: column.text, email: column.text }),
|
||||
})
|
||||
|
||||
async function api(path, { method = 'GET', token, body } = {}) {
|
||||
const res = await fetch(BASE + '/api' + path, {
|
||||
method,
|
||||
headers: { 'Content-Type': 'application/json', ...(token ? { Authorization: 'Bearer ' + token } : {}) },
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
})
|
||||
const data = await res.json().catch(() => ({}))
|
||||
if (!res.ok) throw new Error(`${path} -> ${res.status}: ${data.error || '请求失败'}`)
|
||||
return data
|
||||
}
|
||||
|
||||
class Connector {
|
||||
constructor(appToken, endpoint) {
|
||||
// appToken: 应用 JWT (调业务 API 上行用); endpoint + sync JWT 由 fetchCredentials 提供
|
||||
this.appToken = appToken
|
||||
this.endpoint = endpoint
|
||||
}
|
||||
async fetchCredentials() {
|
||||
const cred = await api('/powersync/token', { method: 'POST', token: this.appToken })
|
||||
return { endpoint: cred.endpoint, token: cred.token }
|
||||
}
|
||||
async uploadData(database) {
|
||||
const batch = await database.getCrudBatch()
|
||||
if (!batch) return
|
||||
const ops = []
|
||||
for (let i = 0; i < batch.crud.length; i++) {
|
||||
const op = batch.crud[i]
|
||||
let data = op.opData || {}
|
||||
if (op.op !== 'DELETE') {
|
||||
const row = await database.getOptional(`SELECT * FROM "${op.table}" WHERE id = ?`, [op.id])
|
||||
if (row) data = row
|
||||
}
|
||||
ops.push({ id: String(i), table: op.table, op: op.op === 'DELETE' ? 'DELETE' : 'PUT', uuid: op.id, data })
|
||||
}
|
||||
const res = await fetch(BASE + '/api/powersync/upload', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + this.appToken },
|
||||
body: JSON.stringify({ ops }),
|
||||
})
|
||||
const out = await res.json().catch(() => ({}))
|
||||
if (!res.ok) throw new Error('upload failed: ' + JSON.stringify(out))
|
||||
const failed = (out.results || []).filter((r) => !r.ok)
|
||||
if (failed.length) console.log('[verify] upload 部分失败:', JSON.stringify(failed))
|
||||
await batch.complete()
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log(`[verify] BASE = ${BASE}`)
|
||||
const login = await api('/auth/login', { method: 'POST', body: { email: EMAIL, password: PASSWORD } })
|
||||
console.log('[verify] 1. 登录 OK, user:', login.user.email)
|
||||
const cred = await api('/powersync/token', { method: 'POST', token: login.token })
|
||||
if (!cred.endpoint) throw new Error('POWERSYNC_URL 未配置 (服务端 /powersync/token 返回空 endpoint)')
|
||||
console.log('[verify] 2. 同步凭证 OK, endpoint:', cred.endpoint)
|
||||
|
||||
const dbFile = path.join(os.tmpdir(), `iboard-verify-${Date.now()}.db`)
|
||||
const logger = createConsoleLogger({ minLevel: LogLevels.debug })
|
||||
const db = new PowerSyncDatabase({
|
||||
schema: AppSchema,
|
||||
database: { dbFilename: dbFile, databaseWorkerLogLevel: LogLevels.debug },
|
||||
sync: { logLevel: LogLevels.debug },
|
||||
logger,
|
||||
})
|
||||
db.registerListener({
|
||||
statusChanged: (s) => {
|
||||
const c = s?.dataFlowStatus || {}
|
||||
console.log(`[verify] sync status: connected=${s?.connected} connecting=${s?.connecting} err=${c.downloadError?.message || c.uploadError?.message || '-'}`)
|
||||
},
|
||||
})
|
||||
try {
|
||||
await db.connect(new Connector(login.token, cred.endpoint))
|
||||
console.log('[verify] connect() 已建立')
|
||||
} catch (e) {
|
||||
console.error('[verify] connect 失败:', e?.message)
|
||||
throw e
|
||||
}
|
||||
await Promise.race([
|
||||
db.waitForFirstSync(),
|
||||
sleep(45000).then(() => { throw new Error('waitForFirstSync 超时 (45s)') }),
|
||||
]).catch(async (e) => {
|
||||
console.log('[verify] waitForFirstSync 未完成, 轮询内部状态...')
|
||||
for (let i = 0; i < 10; i++) {
|
||||
await sleep(3000)
|
||||
const st = db.currentStatus
|
||||
const counts = {
|
||||
projects: (await db.getOptional('SELECT COUNT(*) AS n FROM Project'))?.n,
|
||||
tasks: (await db.getOptional('SELECT COUNT(*) AS n FROM Task'))?.n,
|
||||
}
|
||||
console.log(`[verify] poll#${i}:`, JSON.stringify({
|
||||
connected: st?.connected, connecting: st?.connecting, hasSynced: st?.hasSynced,
|
||||
lastSyncedAt: st?.lastSyncedAt, dl: st?.dataFlowStatus?.downloadError?.message,
|
||||
ul: st?.dataFlowStatus?.uploadError?.message, ...counts,
|
||||
}))
|
||||
if (st?.hasSynced && counts.projects > 0) {
|
||||
console.log('[verify] 轮询确认同步已完成')
|
||||
return
|
||||
}
|
||||
}
|
||||
throw e
|
||||
})
|
||||
console.log('[verify] 3. 首次同步完成')
|
||||
|
||||
const projects = await db.getAll('SELECT id, uuid, code, name FROM Project ORDER BY id')
|
||||
console.log(`[verify] 项目 ${projects.length} 个:`, projects.map((p) => `${p.code || '?'}(${p.name})`).join(', '))
|
||||
const tasks = await db.getAll('SELECT COUNT(*) AS n FROM Task')
|
||||
const numbered = await db.getAll('SELECT COUNT(*) AS n FROM Task WHERE number IS NOT NULL')
|
||||
console.log(`[verify] 任务 ${tasks[0].n} 条 (已有编号 ${numbered[0].n} 条)`)
|
||||
if (!projects.length || tasks[0].n === 0) throw new Error('同步数据为空, ETL 未生效?')
|
||||
|
||||
// 本地新建验证任务 (模拟离线写入: number 为空, 等服务端分配)
|
||||
const target = projects.find((p) => p.code) || projects[0]
|
||||
const firstCol = await db.get(`SELECT id, boundStatus FROM BoardColumn WHERE projectId = ? ORDER BY sortOrder, id LIMIT 1`, [target.id])
|
||||
const marker = `离线闭环验证-${Date.now()}`
|
||||
const newId = uuid()
|
||||
const ts = new Date().toISOString()
|
||||
await db.writeTransaction(async (tx) => {
|
||||
await tx.execute(
|
||||
`INSERT INTO Task (id, uuid, projectId, columnId, parentId, title, description, kind, markDate, status, doneAt, assigneeId, creatorId, extras, sortOrder, number, createdAt, updatedAt)
|
||||
VALUES (?, ?, ?, ?, NULL, ?, '', NULL, NULL, ?, NULL, NULL, ?, '[]', 0, NULL, ?, ?)`,
|
||||
[newId, newId, target.id, firstCol.id, marker, firstCol.boundStatus || 'todo', String(login.user.id), ts, ts],
|
||||
)
|
||||
})
|
||||
console.log(`[verify] 4. 本地写入任务 "${marker}" (number 为空), 等待上行 + 服务端定号 + 同步回填...`)
|
||||
|
||||
let syncedBack = null
|
||||
for (let i = 0; i < 30; i++) {
|
||||
await sleep(2000)
|
||||
const row = await db.getOptional('SELECT number, updatedAt FROM Task WHERE id = ?', [newId])
|
||||
const localCheck = await db.getOptional(`SELECT 1 AS x FROM ps_crud LIMIT 1`)
|
||||
if (!localCheck) {
|
||||
// 队列已清空 (上行完成); 等待下行回填 number
|
||||
if (row && row.number != null) { syncedBack = row; break }
|
||||
if (i > 10 && row && row.number == null) continue
|
||||
}
|
||||
}
|
||||
if (!syncedBack) throw new Error('超时: 未观测到服务端编号回填')
|
||||
console.log(`[verify] 5. 闭环 OK! 服务端分配编号: ${target.code}-${syncedBack.number} (项目 ${target.code})`)
|
||||
|
||||
// 直接从服务端核对 (REST 视角: REST 仍按 int id 寻址, 通过列表接口按 uuid 匹配)
|
||||
const plist = await api('/projects', { token: login.token })
|
||||
const pj = plist.items.find((p) => p.uuid === target.uuid)
|
||||
if (!pj) throw new Error('服务端确认失败: 项目列表中找不到目标项目')
|
||||
const tlist = await api(`/projects/${pj.id}/tasks`, { token: login.token })
|
||||
const hit = tlist.items.find((t) => t.uuid === newId)
|
||||
if (!hit || hit.number == null) throw new Error('服务端确认失败: 任务不存在或未定号')
|
||||
console.log(`[verify] 6. 服务端确认: number=${hit.number}, uuid=${hit.uuid.slice(0, 13)}...`)
|
||||
|
||||
// 清理验证数据 (本地删除 -> 上行删除)
|
||||
await db.execute('DELETE FROM Task WHERE id = ?', [newId])
|
||||
for (let i = 0; i < 15; i++) {
|
||||
await sleep(2000)
|
||||
const left = await db.getOptional('SELECT 1 AS x FROM ps_crud LIMIT 1')
|
||||
if (!left) break
|
||||
}
|
||||
const gone = await api(`/projects/${pj.id}/tasks`, { token: login.token })
|
||||
if (!gone.items.some((t) => t.uuid === newId)) console.log('[verify] 7. 验证任务已从服务端清除')
|
||||
else throw new Error('验证任务删除未同步到服务端')
|
||||
|
||||
db.close()
|
||||
try {
|
||||
fs.rmSync(dbFile, { force: true })
|
||||
fs.rmSync(dbFile + '-journal', { force: true })
|
||||
} catch { /* Windows 下可能被占用, 留在临时目录无害 */ }
|
||||
console.log('[verify] 全部通过: 下行同步 / 离线写入 / 上行幂等 / 服务端编号 / 回填 / 删除同步')
|
||||
}
|
||||
|
||||
main().catch((e) => {
|
||||
console.error('[verify] 失败:', e.message)
|
||||
process.exit(1)
|
||||
})
|
||||
+143
-143
@@ -1,143 +1,143 @@
|
||||
#!/usr/bin/env bash
|
||||
# iBoard Android APK 打包
|
||||
# 用法: bash scripts/wsl/build-apk.sh [debug|release]
|
||||
# release 模式自动构建 4 个 ABI 并出 universal APK
|
||||
set -euo pipefail
|
||||
|
||||
WIN_PROJECT='/mnt/d/workbench/iboard'
|
||||
cd "$WIN_PROJECT"
|
||||
|
||||
VARIANT="${1:-debug}"
|
||||
echo "构建变体: $VARIANT"
|
||||
|
||||
# 环境变量
|
||||
export ANDROID_HOME="${ANDROID_HOME:-$HOME/android-sdk}"
|
||||
export ANDROID_NDK_HOME="${ANDROID_NDK_HOME:-$ANDROID_HOME/ndk/27.2.12479018}"
|
||||
# 关键: 把 NDK toolchain bin 加进 PATH, .cargo/config.toml 里
|
||||
# linker = "aarch64-linux-android24-clang" 这种短名才能被解析到
|
||||
NDK_TOOLCHAIN_BIN="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin"
|
||||
if [ ! -d "$NDK_TOOLCHAIN_BIN" ]; then
|
||||
echo "ERROR: NDK toolchain bin 不存在: $NDK_TOOLCHAIN_BIN"
|
||||
echo "请确认 ANDROID_NDK_HOME 正确指向 NDK 27.2.x 目录"
|
||||
exit 1
|
||||
fi
|
||||
export PATH="$NDK_TOOLCHAIN_BIN:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$HOME/.cargo/bin:$PATH"
|
||||
|
||||
# 0. 首次需要 android 工程
|
||||
cd src-tauri
|
||||
if [ ! -d "gen/android" ]; then
|
||||
echo "=== 0. 初始化 Android 工程 (一次性) ==="
|
||||
npx tauri android init
|
||||
fi
|
||||
cd "$WIN_PROJECT"
|
||||
|
||||
# Android 后端地址, 写到前端 bundle 里 (覆盖默认的 /api 相对路径)
|
||||
export VITE_API_BASE="${VITE_API_BASE:-http://bh.vps.honor3.com:3001}"
|
||||
echo "VITE_API_BASE=$VITE_API_BASE"
|
||||
|
||||
# 1. 先构建前端, 让 Tauri android 工程能拿到 dist/
|
||||
echo "=== 1. 构建前端 ==="
|
||||
npm run build
|
||||
|
||||
# 1.5 拷贝 dist/ 到 Android 工程 assets/, 绕过 Tauri CLI 时这步要做
|
||||
# Tauri CLI 默认在 android build 前会干这事, 我们走直 gradle 要自己补上
|
||||
ANDROID_ASSETS="$WIN_PROJECT/src-tauri/gen/android/app/src/main/assets"
|
||||
mkdir -p "$ANDROID_ASSETS"
|
||||
# 清空旧的 (避免上次的残余)
|
||||
find "$ANDROID_ASSETS" -mindepth 1 -maxdepth 1 ! -name dexopt ! -name tauri.conf.json -exec rm -rf {} +
|
||||
cp -r dist/. "$ANDROID_ASSETS/"
|
||||
echo "前端 bundle 已拷贝到 $ANDROID_ASSETS"
|
||||
ls -la "$ANDROID_ASSETS" | head -10
|
||||
|
||||
# 2. 走不同路径
|
||||
cd src-tauri
|
||||
|
||||
# 全部 4 个 Android 架构的 rustBuild 任务 (Tauri 2 默认会编 4 个)
|
||||
RUST_BUILD_TASKS=(
|
||||
":app:rustBuildArm64Release"
|
||||
":app:rustBuildArmRelease"
|
||||
":app:rustBuildX86_64Release"
|
||||
":app:rustBuildX86Release"
|
||||
)
|
||||
SKIP_ARGS=()
|
||||
for t in "${RUST_BUILD_TASKS[@]}"; do SKIP_ARGS+=(-x "${t#:}"); done
|
||||
|
||||
# 4 个 Android 目标的 cargo target triple
|
||||
ANDROID_TARGETS=(
|
||||
"aarch64-linux-android"
|
||||
"armv7-linux-androideabi"
|
||||
"x86_64-linux-android"
|
||||
"i686-linux-android"
|
||||
)
|
||||
|
||||
if [ "$VARIANT" = "release" ]; then
|
||||
echo "[release] 手工 cargo 编 lib (4 个 ABI), gradle 只跑 packaging (跳过 rustBuild* 避免 --release 重复 bug)"
|
||||
|
||||
for target in "${ANDROID_TARGETS[@]}"; do
|
||||
echo " [cargo] build lib release for $target ..."
|
||||
cargo build \
|
||||
--target "$target" \
|
||||
--features custom-protocol \
|
||||
--lib \
|
||||
--release
|
||||
done
|
||||
|
||||
echo " [gradle] assembleRelease -x rustBuild* ..."
|
||||
cd gen/android
|
||||
./gradlew --no-daemon assembleRelease "${SKIP_ARGS[@]}"
|
||||
|
||||
APK_DIR="$WIN_PROJECT/src-tauri/gen/android/app/build/outputs/apk/universal/release"
|
||||
# Gradle 配了 signingConfig 就输出 app-universal-release.apk,
|
||||
# 否则输出 app-universal-release-unsigned.apk, 按文件名判断是否已签名
|
||||
SIGNED_APK="$APK_DIR/app-universal-release.apk"
|
||||
UNSIGNED_APK="$APK_DIR/app-universal-release-unsigned.apk"
|
||||
|
||||
if [ -f "$SIGNED_APK" ]; then
|
||||
APK_PATH="$SIGNED_APK"
|
||||
APK_STATUS="已签名"
|
||||
elif [ -f "$UNSIGNED_APK" ]; then
|
||||
APK_PATH="$UNSIGNED_APK"
|
||||
APK_STATUS="未签名"
|
||||
else
|
||||
APK_PATH=""
|
||||
APK_STATUS="未找到"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "=== 产物 ($APK_STATUS) ==="
|
||||
if [ -n "$APK_PATH" ]; then
|
||||
ls -lh "$APK_PATH"
|
||||
else
|
||||
ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)"
|
||||
fi
|
||||
|
||||
if [ "$APK_STATUS" = "已签名" ]; then
|
||||
echo
|
||||
echo "=== 安装到设备 ==="
|
||||
echo " adb install -r $APK_PATH"
|
||||
elif [ "$APK_STATUS" = "未签名" ]; then
|
||||
echo
|
||||
echo "=== Release 签名 (按需) ==="
|
||||
echo "1. 生成 keystore (一次性):"
|
||||
echo " keytool -genkey -v -keystore ~/iboard-release.keystore -alias iboard -keyalg RSA -keysize 2048 -validity 10000"
|
||||
echo "2. 在 ~/.gradle/gradle.properties 写:"
|
||||
echo " IBOARD_UPLOAD_STORE_FILE=/home/$(whoami)/iboard-release.keystore"
|
||||
echo " IBOARD_UPLOAD_KEY_ALIAS=iboard"
|
||||
echo " IBOARD_UPLOAD_STORE_PASSWORD=..."
|
||||
echo " IBOARD_UPLOAD_KEY_PASSWORD=..."
|
||||
echo "3. 重跑本脚本 (Gradle 读 gradle.properties 里的 IBOARD_UPLOAD_* 自动用 releaseSigning)"
|
||||
echo
|
||||
echo "=== 临时用 debug keystore 手动签 (仅测试) ==="
|
||||
echo " \$ANDROID_HOME/build-tools/*/apksigner sign --ks ~/.android/debug.keystore \"
|
||||
echo " --ks-pass pass:android --key-pass pass:android \"
|
||||
echo " $APK_PATH"
|
||||
fi
|
||||
else
|
||||
echo "[debug] Tauri CLI debug 路径 (不传 --release 不会触发 bug), 直接走"
|
||||
npx tauri android build --apk
|
||||
|
||||
APK_DIR="$WIN_PROJECT/src-tauri/target/debug/bundle/android/app/build/outputs/apk/debug"
|
||||
echo
|
||||
echo "=== 产物 ==="
|
||||
ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)"
|
||||
fi
|
||||
#!/usr/bin/env bash
|
||||
# iBoard Android APK 打包
|
||||
# 用法: bash scripts/wsl/build-apk.sh [debug|release]
|
||||
# release 模式自动构建 4 个 ABI 并出 universal APK
|
||||
set -euo pipefail
|
||||
|
||||
WIN_PROJECT='/mnt/d/workbench/iboard'
|
||||
cd "$WIN_PROJECT"
|
||||
|
||||
VARIANT="${1:-debug}"
|
||||
echo "构建变体: $VARIANT"
|
||||
|
||||
# 环境变量
|
||||
export ANDROID_HOME="${ANDROID_HOME:-$HOME/android-sdk}"
|
||||
export ANDROID_NDK_HOME="${ANDROID_NDK_HOME:-$ANDROID_HOME/ndk/27.2.12479018}"
|
||||
# 关键: 把 NDK toolchain bin 加进 PATH, .cargo/config.toml 里
|
||||
# linker = "aarch64-linux-android24-clang" 这种短名才能被解析到
|
||||
NDK_TOOLCHAIN_BIN="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin"
|
||||
if [ ! -d "$NDK_TOOLCHAIN_BIN" ]; then
|
||||
echo "ERROR: NDK toolchain bin 不存在: $NDK_TOOLCHAIN_BIN"
|
||||
echo "请确认 ANDROID_NDK_HOME 正确指向 NDK 27.2.x 目录"
|
||||
exit 1
|
||||
fi
|
||||
export PATH="$NDK_TOOLCHAIN_BIN:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$HOME/.cargo/bin:$PATH"
|
||||
|
||||
# 0. 首次需要 android 工程
|
||||
cd src-tauri
|
||||
if [ ! -d "gen/android" ]; then
|
||||
echo "=== 0. 初始化 Android 工程 (一次性) ==="
|
||||
npx tauri android init
|
||||
fi
|
||||
cd "$WIN_PROJECT"
|
||||
|
||||
# Android 后端地址, 写到前端 bundle 里 (覆盖默认的 /api 相对路径)
|
||||
export VITE_API_BASE="${VITE_API_BASE:-https://iboard.honor3.com}"
|
||||
echo "VITE_API_BASE=$VITE_API_BASE"
|
||||
|
||||
# 1. 先构建前端, 让 Tauri android 工程能拿到 dist/
|
||||
echo "=== 1. 构建前端 ==="
|
||||
npm run build
|
||||
|
||||
# 1.5 拷贝 dist/ 到 Android 工程 assets/, 绕过 Tauri CLI 时这步要做
|
||||
# Tauri CLI 默认在 android build 前会干这事, 我们走直 gradle 要自己补上
|
||||
ANDROID_ASSETS="$WIN_PROJECT/src-tauri/gen/android/app/src/main/assets"
|
||||
mkdir -p "$ANDROID_ASSETS"
|
||||
# 清空旧的 (避免上次的残余)
|
||||
find "$ANDROID_ASSETS" -mindepth 1 -maxdepth 1 ! -name dexopt ! -name tauri.conf.json -exec rm -rf {} +
|
||||
cp -r dist/. "$ANDROID_ASSETS/"
|
||||
echo "前端 bundle 已拷贝到 $ANDROID_ASSETS"
|
||||
ls -la "$ANDROID_ASSETS" | head -10
|
||||
|
||||
# 2. 走不同路径
|
||||
cd src-tauri
|
||||
|
||||
# 全部 4 个 Android 架构的 rustBuild 任务 (Tauri 2 默认会编 4 个)
|
||||
RUST_BUILD_TASKS=(
|
||||
":app:rustBuildArm64Release"
|
||||
":app:rustBuildArmRelease"
|
||||
":app:rustBuildX86_64Release"
|
||||
":app:rustBuildX86Release"
|
||||
)
|
||||
SKIP_ARGS=()
|
||||
for t in "${RUST_BUILD_TASKS[@]}"; do SKIP_ARGS+=(-x "${t#:}"); done
|
||||
|
||||
# 4 个 Android 目标的 cargo target triple
|
||||
ANDROID_TARGETS=(
|
||||
"aarch64-linux-android"
|
||||
"armv7-linux-androideabi"
|
||||
"x86_64-linux-android"
|
||||
"i686-linux-android"
|
||||
)
|
||||
|
||||
if [ "$VARIANT" = "release" ]; then
|
||||
echo "[release] 手工 cargo 编 lib (4 个 ABI), gradle 只跑 packaging (跳过 rustBuild* 避免 --release 重复 bug)"
|
||||
|
||||
for target in "${ANDROID_TARGETS[@]}"; do
|
||||
echo " [cargo] build lib release for $target ..."
|
||||
cargo build \
|
||||
--target "$target" \
|
||||
--features custom-protocol \
|
||||
--lib \
|
||||
--release
|
||||
done
|
||||
|
||||
echo " [gradle] assembleRelease -x rustBuild* ..."
|
||||
cd gen/android
|
||||
./gradlew --no-daemon assembleRelease "${SKIP_ARGS[@]}"
|
||||
|
||||
APK_DIR="$WIN_PROJECT/src-tauri/gen/android/app/build/outputs/apk/universal/release"
|
||||
# Gradle 配了 signingConfig 就输出 app-universal-release.apk,
|
||||
# 否则输出 app-universal-release-unsigned.apk, 按文件名判断是否已签名
|
||||
SIGNED_APK="$APK_DIR/app-universal-release.apk"
|
||||
UNSIGNED_APK="$APK_DIR/app-universal-release-unsigned.apk"
|
||||
|
||||
if [ -f "$SIGNED_APK" ]; then
|
||||
APK_PATH="$SIGNED_APK"
|
||||
APK_STATUS="已签名"
|
||||
elif [ -f "$UNSIGNED_APK" ]; then
|
||||
APK_PATH="$UNSIGNED_APK"
|
||||
APK_STATUS="未签名"
|
||||
else
|
||||
APK_PATH=""
|
||||
APK_STATUS="未找到"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "=== 产物 ($APK_STATUS) ==="
|
||||
if [ -n "$APK_PATH" ]; then
|
||||
ls -lh "$APK_PATH"
|
||||
else
|
||||
ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)"
|
||||
fi
|
||||
|
||||
if [ "$APK_STATUS" = "已签名" ]; then
|
||||
echo
|
||||
echo "=== 安装到设备 ==="
|
||||
echo " adb install -r $APK_PATH"
|
||||
elif [ "$APK_STATUS" = "未签名" ]; then
|
||||
echo
|
||||
echo "=== Release 签名 (按需) ==="
|
||||
echo "1. 生成 keystore (一次性):"
|
||||
echo " keytool -genkey -v -keystore ~/iboard-release.keystore -alias iboard -keyalg RSA -keysize 2048 -validity 10000"
|
||||
echo "2. 在 ~/.gradle/gradle.properties 写:"
|
||||
echo " IBOARD_UPLOAD_STORE_FILE=/home/$(whoami)/iboard-release.keystore"
|
||||
echo " IBOARD_UPLOAD_KEY_ALIAS=iboard"
|
||||
echo " IBOARD_UPLOAD_STORE_PASSWORD=..."
|
||||
echo " IBOARD_UPLOAD_KEY_PASSWORD=..."
|
||||
echo "3. 重跑本脚本 (Gradle 读 gradle.properties 里的 IBOARD_UPLOAD_* 自动用 releaseSigning)"
|
||||
echo
|
||||
echo "=== 临时用 debug keystore 手动签 (仅测试) ==="
|
||||
echo " \$ANDROID_HOME/build-tools/*/apksigner sign --ks ~/.android/debug.keystore \"
|
||||
echo " --ks-pass pass:android --key-pass pass:android \"
|
||||
echo " $APK_PATH"
|
||||
fi
|
||||
else
|
||||
echo "[debug] Tauri CLI debug 路径 (不传 --release 不会触发 bug), 直接走"
|
||||
npx tauri android build --apk
|
||||
|
||||
APK_DIR="$WIN_PROJECT/src-tauri/target/debug/bundle/android/app/build/outputs/apk/debug"
|
||||
echo
|
||||
echo "=== 产物 ==="
|
||||
ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)"
|
||||
fi
|
||||
|
||||
+4
-15
@@ -1,18 +1,7 @@
|
||||
// 服务端 Prisma 单例, 使用 mariadb 适配器
|
||||
// 服务端 Prisma 单例, 使用 pg 适配器 (0.2.1: 数据库迁移到 PostgreSQL)
|
||||
import 'dotenv/config'
|
||||
import { PrismaMariaDb } from '@prisma/adapter-mariadb'
|
||||
import { PrismaPg } from '@prisma/adapter-pg'
|
||||
import { PrismaClient } from '../generated/prisma/client.ts'
|
||||
|
||||
function parseDatabaseUrl(url) {
|
||||
const u = new URL(url)
|
||||
return {
|
||||
host: u.hostname,
|
||||
port: Number(u.port) || 3306,
|
||||
user: decodeURIComponent(u.username),
|
||||
password: decodeURIComponent(u.password),
|
||||
database: u.pathname.replace(/^\//, ''),
|
||||
}
|
||||
}
|
||||
|
||||
const adapter = new PrismaMariaDb(parseDatabaseUrl(process.env.DATABASE_URL))
|
||||
export const prisma = new PrismaClient({ adapter })
|
||||
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL })
|
||||
export const prisma = new PrismaClient({ adapter })
|
||||
|
||||
+12
-4
@@ -16,12 +16,16 @@ import checkinRouter from './routes/checkin.js'
|
||||
import checklistsRouter from './routes/checklists.js'
|
||||
import projectsRouter, { columnRouter } from './routes/projects.js'
|
||||
import tasksRouter from './routes/tasks.js'
|
||||
import powersyncRouter from './routes/powersync.js'
|
||||
import { powersyncProxy } from './powersync-proxy.js'
|
||||
|
||||
const PORT = Number(process.env.PORT) || 3001
|
||||
const DIST_DIR = path.join(process.cwd(), 'dist')
|
||||
const HAS_DIST = fs.existsSync(DIST_DIR)
|
||||
|
||||
const app = express()
|
||||
// 同步服务同域反代必须最先挂载 (流式长连接, 不能经过 json/cors 中间件)
|
||||
app.use(powersyncProxy())
|
||||
app.use(cors())
|
||||
app.use(express.json())
|
||||
|
||||
@@ -33,6 +37,8 @@ app.use('/api/auth', authRouter)
|
||||
// OTA 接口是公开的 (检查/下载更新不需要登录), 必须挂载在带 authRequired 的 router 之前,
|
||||
// 否则 /api/ota/* 请求会先进入 dataRouter 等并被 authRequired 以 401 拦截
|
||||
app.use('/api', otaRouter)
|
||||
// PowerSync: token 签发 + 离线上行队列 (自带 authRequired, 同样必须挂在带 authRequired 的业务 router 之前)
|
||||
app.use('/api/powersync', powersyncRouter)
|
||||
app.use('/api', dataRouter)
|
||||
app.use('/api', newsRouter)
|
||||
app.use('/api', alertsRouter)
|
||||
@@ -66,11 +72,13 @@ app.use((err, _req, res, _next) => {
|
||||
res.status(500).json({ error: err.message || '服务器内部错误' })
|
||||
})
|
||||
|
||||
// 启动定时任务: 每天凌晨 3 点拉取新闻
|
||||
import('./cron.js').catch((e) => console.error('[cron] 加载失败:', e.message))
|
||||
// 启动定时任务: 每天凌晨 3 点拉取新闻; 0.2.1 验证部署以 DISABLE_CRON=1 关闭 (避免重复外呼)
|
||||
if (process.env.DISABLE_CRON !== '1') {
|
||||
import('./cron.js').catch((e) => console.error('[cron] 加载失败:', e.message))
|
||||
|
||||
// 米家环境监控定时调度 (独立注册, 不与 cron.js 绑定, 见 server/mihome/scheduler.js)
|
||||
import('./mihome/scheduler.js').catch((e) => console.error('[cron] 米家调度注册失败:', e.message))
|
||||
// 米家环境监控定时调度 (独立注册, 不与 cron.js 绑定, 见 server/mihome/scheduler.js)
|
||||
import('./mihome/scheduler.js').catch((e) => console.error('[cron] 米家调度注册失败:', e.message))
|
||||
}
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`[iboard-api] listening on http://127.0.0.1:${PORT}`)
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// PowerSync 同域反代 (0.2.1): 把 /sync、/socket 转发到内网同步服务,
|
||||
// 对外只暴露应用本身一个端口 (无需单独的 powersync 端口)。
|
||||
// - 未配置 POWERSYNC_UPSTREAM 时直接跳过 (本地开发/无同步服务时行为不变)
|
||||
// - 必须挂在 express.json()/cors 之前: 同步走长连接流式响应, 不能被 body 解析打断
|
||||
import http from 'node:http'
|
||||
import https from 'node:https'
|
||||
|
||||
const PREFIXES = ['/sync', '/socket']
|
||||
|
||||
export function powersyncProxy() {
|
||||
const upstream = process.env.POWERSYNC_UPSTREAM
|
||||
if (!upstream) return (_req, _res, next) => next()
|
||||
|
||||
let target
|
||||
try {
|
||||
target = new URL(upstream)
|
||||
} catch {
|
||||
console.error('[powersync-proxy] POWERSYNC_UPSTREAM 非法:', upstream)
|
||||
return (_req, _res, next) => next()
|
||||
}
|
||||
const transport = target.protocol === 'https:' ? https : http
|
||||
const basePort = Number(target.port) || (target.protocol === 'https:' ? 443 : 80)
|
||||
console.log('[powersync-proxy] 同步请求转发到', target.origin)
|
||||
|
||||
return (req, res, next) => {
|
||||
if (!PREFIXES.some((p) => req.url === p || req.url.startsWith(p + '/') || req.url.startsWith(p + '?'))) {
|
||||
return next()
|
||||
}
|
||||
const headers = { ...req.headers, host: target.host }
|
||||
const upstreamReq = transport.request(
|
||||
{
|
||||
protocol: target.protocol,
|
||||
hostname: target.hostname,
|
||||
port: basePort,
|
||||
method: req.method,
|
||||
path: req.url,
|
||||
headers,
|
||||
},
|
||||
(upstreamRes) => {
|
||||
res.writeHead(upstreamRes.statusCode || 502, upstreamRes.headers)
|
||||
upstreamRes.pipe(res)
|
||||
},
|
||||
)
|
||||
upstreamReq.on('error', (e) => {
|
||||
console.error('[powersync-proxy] 转发失败:', e.message)
|
||||
if (!res.headersSent) res.writeHead(502, { 'content-type': 'text/plain' })
|
||||
res.end('powersync upstream error')
|
||||
})
|
||||
// 长连接: 客户端断开时同步断开上游
|
||||
req.on('aborted', () => upstreamReq.destroy())
|
||||
res.on('close', () => upstreamReq.destroy())
|
||||
req.pipe(upstreamReq)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
// PowerSync 接入: 同步 token 签发 + 客户端上传队列落地 (0.2.1, 见 docs/V0.2/离线编辑模块/0.2.1实施方案.md)
|
||||
// 下行由 powersync-service 经 PG 逻辑复制完成; 本文件只负责:
|
||||
// 1. /token 为已登录用户签发 powersync-service 接受的 JWT (aud=powersync, 独立密钥可选)
|
||||
// 2. /upload 批量落地客户端离线写操作, 按 uuid 幂等 upsert, 服务端统一分配编号
|
||||
import { Router } from 'express'
|
||||
import jwt from 'jsonwebtoken'
|
||||
import { prisma } from '../db.js'
|
||||
import { JWT_SECRET, authRequired } from '../middleware.js'
|
||||
import { genUuid, normProjectCode, allocProjectCode, withTaskNumber } from '../task-domain/identity.js'
|
||||
|
||||
const router = Router()
|
||||
|
||||
// ---------- 同步 token ----------
|
||||
router.post('/token', authRequired, async (req, res, next) => {
|
||||
try {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: req.user.sub },
|
||||
select: { id: true, name: true, email: true },
|
||||
})
|
||||
if (!user) return res.status(401).json({ error: '用户不存在' })
|
||||
const secret = process.env.POWERSYNC_JWT_SECRET || JWT_SECRET
|
||||
const token = jwt.sign(
|
||||
{ sub: String(user.id), aud: 'powersync', name: user.name, email: user.email },
|
||||
secret,
|
||||
{ expiresIn: '12h' },
|
||||
)
|
||||
res.json({ token, endpoint: process.env.POWERSYNC_URL || '' })
|
||||
} catch (e) { next(e) }
|
||||
})
|
||||
|
||||
// ---------- 上传队列 ----------
|
||||
// 契约: POST { ops: [{ id, table, op: 'PUT'|'DELETE', uuid, data }] }
|
||||
// table ∈ Project | BoardColumn | ProjectMember | Task | TaskMember | TaskTag
|
||||
// data 为客户端本地全量行 (列名与客户端 schema 一致); 外键列 (projectId/columnId/parentId/taskId)
|
||||
// 的值即父行的本地 id = uuid, 服务端据此解析为内部自增 id
|
||||
// 返回 { results: [{ id, ok, skipped?, error? }] }, 单条失败不影响同批其它 op
|
||||
const TABLES = ['Project', 'BoardColumn', 'ProjectMember', 'Task', 'TaskMember', 'TaskTag']
|
||||
const TABLE_RANK = Object.fromEntries(TABLES.map((t, i) => [t, i]))
|
||||
|
||||
const COLUMN_RETENTIONS = ['never', 'today', '3d', 'week', 'month', 'forever']
|
||||
const TASK_STATUSES = ['todo', 'doing', 'done']
|
||||
const AUTO_ARCHIVE_OPTIONS = ['3d', '1w', '1m', 'never']
|
||||
|
||||
function isoTime(v) {
|
||||
if (!v) return null
|
||||
const d = new Date(v)
|
||||
return Number.isNaN(d.getTime()) ? null : d
|
||||
}
|
||||
|
||||
// LWW: 服务端已有行不早于客户端数据 => 跳过本次覆盖
|
||||
function isStale(existing, data) {
|
||||
const t = isoTime(data?.updatedAt)
|
||||
if (!t) return false
|
||||
return existing.updatedAt && existing.updatedAt.getTime() >= t.getTime()
|
||||
}
|
||||
|
||||
function cleanExtras(v) {
|
||||
if (!Array.isArray(v)) return []
|
||||
return v.slice(0, 50).map((e) => ({
|
||||
label: String(e?.label ?? '').slice(0, 40),
|
||||
value: String(e?.value ?? ''),
|
||||
url: e?.url ? String(e.url) : '',
|
||||
}))
|
||||
}
|
||||
|
||||
function cleanNotes(v) {
|
||||
if (!Array.isArray(v)) return []
|
||||
return v.slice(0, 50).map((n) => ({
|
||||
title: String(n?.title ?? '').slice(0, 50),
|
||||
content: String(n?.content ?? '').slice(0, 20000),
|
||||
}))
|
||||
}
|
||||
|
||||
async function applyPut(op, ctx) {
|
||||
const { userId, assertMember } = ctx
|
||||
const { table, uuid } = op
|
||||
const d = op.data || {}
|
||||
if (!uuid) throw new Error('缺少 uuid')
|
||||
|
||||
if (table === 'Project') {
|
||||
const existing = await prisma.project.findUnique({ where: { uuid } })
|
||||
if (existing) {
|
||||
if (!(await assertMember(existing.id))) throw new Error('无项目权限')
|
||||
if (isStale(existing, d)) return { skipped: true }
|
||||
const data = {}
|
||||
if (d.name !== undefined) {
|
||||
const t = String(d.name).trim()
|
||||
if (!t || t.length > 20) throw new Error('项目名称非法')
|
||||
data.name = t
|
||||
}
|
||||
if (d.archived !== undefined) data.archived = !!d.archived
|
||||
if (d.notes !== undefined) data.notes = cleanNotes(d.notes)
|
||||
if (d.autoArchive !== undefined) {
|
||||
data.autoArchive = AUTO_ARCHIVE_OPTIONS.includes(d.autoArchive) ? d.autoArchive : 'never'
|
||||
}
|
||||
if (d.taskKinds !== undefined) {
|
||||
data.taskKinds = Array.isArray(d.taskKinds) ? d.taskKinds.map((k) => String(k).slice(0, 20)).filter(Boolean) : null
|
||||
}
|
||||
if (Object.keys(data).length) await prisma.project.update({ where: { uuid }, data })
|
||||
return {}
|
||||
}
|
||||
const name = String(d.name || '').trim()
|
||||
if (!name || name.length > 20) throw new Error('项目名称非法')
|
||||
const code = normProjectCode(d.code) || (await allocProjectCode(name))
|
||||
const row = await prisma.project.create({
|
||||
data: { uuid, code, name, ownerId: userId, isPersonal: !!d.isPersonal, archived: !!d.archived },
|
||||
})
|
||||
return { rowId: row.id, code: row.code }
|
||||
}
|
||||
|
||||
if (table === 'BoardColumn') {
|
||||
const existing = await prisma.boardColumn.findUnique({ where: { uuid } })
|
||||
if (existing) {
|
||||
if (!(await assertMember(existing.projectId))) throw new Error('无项目权限')
|
||||
if (isStale(existing, d)) return { skipped: true }
|
||||
const data = {}
|
||||
if (d.name !== undefined) {
|
||||
const t = String(d.name).trim()
|
||||
if (!t || t.length > 20) throw new Error('列名非法')
|
||||
data.name = t
|
||||
}
|
||||
if (d.sortOrder !== undefined) data.sortOrder = Number(d.sortOrder) || 0
|
||||
if (d.boundStatus !== undefined) data.boundStatus = TASK_STATUSES.includes(d.boundStatus) ? d.boundStatus : null
|
||||
if (d.retention !== undefined && COLUMN_RETENTIONS.includes(d.retention)) data.retention = d.retention
|
||||
if (Object.keys(data).length) await prisma.boardColumn.update({ where: { uuid }, data })
|
||||
return {}
|
||||
}
|
||||
const project = await prisma.project.findUnique({ where: { uuid: d.projectId } })
|
||||
if (!project || !(await assertMember(project.id))) throw new Error('项目不存在或无权限')
|
||||
const name = String(d.name || '').trim()
|
||||
if (!name || name.length > 20) throw new Error('列名非法')
|
||||
await prisma.boardColumn.create({
|
||||
data: {
|
||||
uuid,
|
||||
projectId: project.id,
|
||||
name,
|
||||
sortOrder: Number(d.sortOrder) || 0,
|
||||
boundStatus: TASK_STATUSES.includes(d.boundStatus) ? d.boundStatus : null,
|
||||
retention: COLUMN_RETENTIONS.includes(d.retention) ? d.retention : 'forever',
|
||||
},
|
||||
})
|
||||
return {}
|
||||
}
|
||||
|
||||
if (table === 'ProjectMember') {
|
||||
const existing = await prisma.projectMember.findUnique({ where: { uuid } })
|
||||
if (existing) {
|
||||
// 成员关系只增不改: 已存在即视为完成 (幂等)
|
||||
return { skipped: true }
|
||||
}
|
||||
const project = await prisma.project.findUnique({ where: { uuid: d.projectId } })
|
||||
if (!project || !(await assertMember(project.id))) throw new Error('项目不存在或无权限')
|
||||
const target = Number(d.userId)
|
||||
if (!target) throw new Error('userId 非法')
|
||||
const dup = await prisma.projectMember.findUnique({
|
||||
where: { projectId_userId: { projectId: project.id, userId: target } },
|
||||
})
|
||||
if (dup) return { skipped: true }
|
||||
await prisma.projectMember.create({
|
||||
data: { uuid, projectId: project.id, userId: target, permission: d.permission === 'admin' ? 'admin' : 'member' },
|
||||
})
|
||||
return {}
|
||||
}
|
||||
|
||||
if (table === 'Task') {
|
||||
const existing = await prisma.task.findUnique({ where: { uuid } })
|
||||
if (existing) {
|
||||
if (!(await assertMember(existing.projectId))) throw new Error('无项目权限')
|
||||
if (isStale(existing, d)) return { skipped: true }
|
||||
const data = {}
|
||||
if (d.title !== undefined) {
|
||||
const t = String(d.title).trim()
|
||||
if (!t || t.length > 30) throw new Error('任务标题非法')
|
||||
data.title = t
|
||||
}
|
||||
if (d.description !== undefined) data.description = String(d.description || '')
|
||||
if (d.kind !== undefined) data.kind = d.kind ? String(d.kind).trim().slice(0, 20) : null
|
||||
if (d.markDate !== undefined) {
|
||||
const m = isoTime(d.markDate)
|
||||
if (d.markDate && !m) throw new Error('时间标记非法')
|
||||
data.markDate = m
|
||||
}
|
||||
if (d.extras !== undefined) data.extras = cleanExtras(d.extras)
|
||||
if (d.sortOrder !== undefined) data.sortOrder = Number(d.sortOrder) || 0
|
||||
if (d.assigneeId !== undefined) data.assigneeId = d.assigneeId ? Number(d.assigneeId) : null
|
||||
if (d.doneAt !== undefined) data.doneAt = isoTime(d.doneAt)
|
||||
// 归档状态 (T-ARC): 客户端本地归档/恢复走这里
|
||||
if (d.archived !== undefined) data.archived = !!d.archived
|
||||
if (d.archivedAt !== undefined) data.archivedAt = isoTime(d.archivedAt)
|
||||
if (d.archiveSource !== undefined) {
|
||||
data.archiveSource = ['manual', 'auto'].includes(d.archiveSource) ? d.archiveSource : null
|
||||
}
|
||||
if (d.columnId !== undefined) {
|
||||
const col = await prisma.boardColumn.findUnique({ where: { uuid: d.columnId } })
|
||||
if (!col || col.projectId !== existing.projectId) throw new Error('看板列不存在')
|
||||
data.columnId = col.id
|
||||
}
|
||||
if (d.parentId !== undefined) {
|
||||
if (!d.parentId) {
|
||||
data.parentId = null
|
||||
} else {
|
||||
const parent = await prisma.task.findUnique({ where: { uuid: d.parentId } })
|
||||
if (!parent || parent.projectId !== existing.projectId) throw new Error('父任务不存在')
|
||||
if (parent.parentId) throw new Error('仅支持一级子任务')
|
||||
data.parentId = parent.id
|
||||
}
|
||||
}
|
||||
if (Object.keys(data).length) await prisma.task.update({ where: { uuid }, data })
|
||||
return {}
|
||||
}
|
||||
// 离线新建: 服务端解析父引用并分配项目内编号
|
||||
const project = await prisma.project.findUnique({ where: { uuid: d.projectId } })
|
||||
if (!project || !(await assertMember(project.id))) throw new Error('项目不存在或无权限')
|
||||
const title = String(d.title || '').trim()
|
||||
if (!title || title.length > 30) throw new Error('任务标题非法')
|
||||
let columnId = null
|
||||
if (d.columnId) {
|
||||
const col = await prisma.boardColumn.findUnique({ where: { uuid: d.columnId } })
|
||||
if (!col || col.projectId !== project.id) throw new Error('看板列不存在')
|
||||
columnId = col.id
|
||||
} else {
|
||||
const first = await prisma.boardColumn.findFirst({
|
||||
where: { projectId: project.id },
|
||||
orderBy: { sortOrder: 'asc' },
|
||||
})
|
||||
if (!first) throw new Error('项目没有可用的看板列')
|
||||
columnId = first.id
|
||||
}
|
||||
let parentId = null
|
||||
if (d.parentId) {
|
||||
const parent = await prisma.task.findUnique({ where: { uuid: d.parentId } })
|
||||
if (!parent || parent.projectId !== project.id) throw new Error('父任务不存在')
|
||||
if (parent.parentId) throw new Error('仅支持一级子任务')
|
||||
parentId = parent.id
|
||||
}
|
||||
const status = TASK_STATUSES.includes(d.status) ? d.status : 'todo'
|
||||
const base = {
|
||||
uuid,
|
||||
projectId: project.id,
|
||||
columnId,
|
||||
parentId,
|
||||
title,
|
||||
description: String(d.description || ''),
|
||||
kind: d.kind ? String(d.kind).trim().slice(0, 20) : null,
|
||||
markDate: isoTime(d.markDate),
|
||||
status,
|
||||
assigneeId: d.assigneeId ? Number(d.assigneeId) : null,
|
||||
creatorId: userId,
|
||||
extras: cleanExtras(d.extras),
|
||||
doneAt: status === 'done' ? (isoTime(d.doneAt) || new Date()) : null,
|
||||
sortOrder: Number(d.sortOrder) || 0,
|
||||
}
|
||||
const { value: row } = await withTaskNumber(project.id, (number) =>
|
||||
prisma.task.create({ data: { ...base, number } }),
|
||||
)
|
||||
return { rowId: row.id, number: row.number }
|
||||
}
|
||||
|
||||
if (table === 'TaskMember') {
|
||||
const existing = await prisma.taskMember.findUnique({ where: { uuid } })
|
||||
if (existing) return { skipped: true }
|
||||
const task = await prisma.task.findUnique({ where: { uuid: d.taskId } })
|
||||
if (!task || !(await assertMember(task.projectId))) throw new Error('任务不存在或无权限')
|
||||
const uid = Number(d.userId)
|
||||
if (!uid) throw new Error('userId 非法')
|
||||
const dup = await prisma.taskMember.findUnique({
|
||||
where: { taskId_userId: { taskId: task.id, userId: uid } },
|
||||
})
|
||||
if (dup) return { skipped: true }
|
||||
await prisma.taskMember.create({ data: { uuid, taskId: task.id, userId: uid } })
|
||||
return {}
|
||||
}
|
||||
|
||||
if (table === 'TaskTag') {
|
||||
const existing = await prisma.taskTag.findUnique({ where: { uuid } })
|
||||
if (existing) return { skipped: true }
|
||||
const task = await prisma.task.findUnique({ where: { uuid: d.taskId } })
|
||||
if (!task || !(await assertMember(task.projectId))) throw new Error('任务不存在或无权限')
|
||||
const name = String(d.name || '').trim().slice(0, 20)
|
||||
if (!name) throw new Error('标签名非法')
|
||||
const dup = await prisma.taskTag.findFirst({ where: { taskId: task.id, name } })
|
||||
if (dup) return { skipped: true }
|
||||
await prisma.taskTag.create({ data: { uuid, taskId: task.id, name } })
|
||||
return {}
|
||||
}
|
||||
|
||||
throw new Error('未知表: ' + table)
|
||||
}
|
||||
|
||||
async function applyDelete(op, ctx) {
|
||||
const { assertMember } = ctx
|
||||
const { table, uuid } = op
|
||||
if (!uuid) throw new Error('缺少 uuid')
|
||||
|
||||
if (table === 'Project') {
|
||||
const row = await prisma.project.findUnique({ where: { uuid }, select: { id: true, isPersonal: true } })
|
||||
if (!row) return { skipped: true }
|
||||
if (!(await assertMember(row.id))) throw new Error('无项目权限')
|
||||
if (row.isPersonal) throw new Error('个人默认项目不可删除')
|
||||
await prisma.project.delete({ where: { uuid } })
|
||||
return {}
|
||||
}
|
||||
if (table === 'BoardColumn') {
|
||||
const row = await prisma.boardColumn.findUnique({ where: { uuid } })
|
||||
if (!row) return { skipped: true }
|
||||
if (!(await assertMember(row.projectId))) throw new Error('无项目权限')
|
||||
await prisma.boardColumn.delete({ where: { uuid } })
|
||||
return {}
|
||||
}
|
||||
if (table === 'ProjectMember') {
|
||||
const row = await prisma.projectMember.findUnique({ where: { uuid } })
|
||||
if (!row) return { skipped: true }
|
||||
if (!(await assertMember(row.projectId))) throw new Error('无项目权限')
|
||||
await prisma.projectMember.delete({ where: { uuid } })
|
||||
return {}
|
||||
}
|
||||
if (table === 'Task') {
|
||||
const row = await prisma.task.findUnique({ where: { uuid } })
|
||||
if (!row) return { skipped: true }
|
||||
if (!(await assertMember(row.projectId))) throw new Error('无项目权限')
|
||||
await prisma.task.delete({ where: { uuid } })
|
||||
return {}
|
||||
}
|
||||
if (table === 'TaskMember') {
|
||||
const row = await prisma.taskMember.findUnique({ where: { uuid } })
|
||||
if (!row) return { skipped: true }
|
||||
const task = await prisma.task.findUnique({ where: { id: row.taskId }, select: { projectId: true } })
|
||||
if (!task || !(await assertMember(task.projectId))) throw new Error('无项目权限')
|
||||
await prisma.taskMember.delete({ where: { uuid } })
|
||||
return {}
|
||||
}
|
||||
if (table === 'TaskTag') {
|
||||
const row = await prisma.taskTag.findUnique({ where: { uuid } })
|
||||
if (!row) return { skipped: true }
|
||||
const task = await prisma.task.findUnique({ where: { id: row.taskId }, select: { projectId: true } })
|
||||
if (!task || !(await assertMember(task.projectId))) throw new Error('无项目权限')
|
||||
await prisma.taskTag.delete({ where: { uuid } })
|
||||
return {}
|
||||
}
|
||||
throw new Error('未知表: ' + table)
|
||||
}
|
||||
|
||||
router.post('/upload', authRequired, async (req, res, next) => {
|
||||
try {
|
||||
const userId = req.user.sub
|
||||
const ops = Array.isArray(req.body?.ops) ? req.body.ops : []
|
||||
if (!ops.length) return res.status(400).json({ error: 'ops 不能为空' })
|
||||
if (ops.length > 500) return res.status(400).json({ error: '单批 ops 过多 (上限 500)' })
|
||||
|
||||
const memberCache = new Map()
|
||||
const assertMember = async (projectId) => {
|
||||
if (!projectId) return false
|
||||
if (memberCache.has(projectId)) return memberCache.get(projectId)
|
||||
const ok = !!(await prisma.projectMember.findFirst({ where: { projectId, userId } }))
|
||||
memberCache.set(projectId, ok)
|
||||
return ok
|
||||
}
|
||||
const ctx = { userId, assertMember }
|
||||
|
||||
// 依赖顺序: 父表先落地 (Project → BoardColumn → ProjectMember → Task → TaskMember/TaskTag); 删除反向
|
||||
const rank = (o) => TABLE_RANK[o?.table] ?? 99
|
||||
const puts = ops.filter((o) => o && o.op !== 'DELETE').sort((a, b) => rank(a) - rank(b))
|
||||
const dels = ops.filter((o) => o && o.op === 'DELETE').sort((a, b) => rank(b) - rank(a))
|
||||
|
||||
const results = []
|
||||
for (const op of puts) {
|
||||
try {
|
||||
const extra = await applyPut(op, ctx)
|
||||
results.push({ id: op.id, ok: true, ...extra })
|
||||
} catch (e) {
|
||||
results.push({ id: op.id, ok: false, error: e.message })
|
||||
}
|
||||
}
|
||||
for (const op of dels) {
|
||||
try {
|
||||
const extra = await applyDelete(op, ctx)
|
||||
results.push({ id: op.id, ok: true, ...extra })
|
||||
} catch (e) {
|
||||
results.push({ id: op.id, ok: false, error: e.message })
|
||||
}
|
||||
}
|
||||
res.json({ results })
|
||||
} catch (e) { next(e) }
|
||||
})
|
||||
|
||||
export default router
|
||||
@@ -3,6 +3,7 @@ import { Router } from 'express'
|
||||
import { prisma } from '../db.js'
|
||||
import { authRequired } from '../middleware.js'
|
||||
import { loadProjectForUser, loadColumns, loadMemberIds } from '../task-domain/access.js'
|
||||
import { genUuid, withUuid, normProjectCode, allocProjectCode } from '../task-domain/identity.js'
|
||||
|
||||
const router = Router()
|
||||
router.use(authRequired)
|
||||
@@ -21,7 +22,7 @@ const MAX_NAME = 20
|
||||
/** 建 4 个默认列 */
|
||||
async function createDefaultColumns(projectId) {
|
||||
await prisma.boardColumn.createMany({
|
||||
data: DEFAULT_COLUMNS.map((c) => ({ ...c, projectId, retention: 'forever' })),
|
||||
data: withUuid(DEFAULT_COLUMNS.map((c) => ({ ...c, projectId, retention: 'forever' }))),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -32,7 +33,14 @@ export async function ensurePersonalProject(userId) {
|
||||
const user = await prisma.user.findUnique({ where: { id: userId }, select: { name: true } })
|
||||
const name = `${user?.name || '我'}的任务`
|
||||
const project = await prisma.project.create({
|
||||
data: { name, ownerId: userId, isPersonal: true, members: { create: { userId } } },
|
||||
data: {
|
||||
name,
|
||||
ownerId: userId,
|
||||
isPersonal: true,
|
||||
uuid: genUuid(),
|
||||
code: await allocProjectCode(name),
|
||||
members: { create: { uuid: genUuid(), userId } },
|
||||
},
|
||||
})
|
||||
await createDefaultColumns(project.id)
|
||||
return project
|
||||
@@ -58,6 +66,8 @@ export function normTaskKinds(v) {
|
||||
function projectSummary(p) {
|
||||
return {
|
||||
id: p.id,
|
||||
uuid: p.uuid,
|
||||
code: p.code,
|
||||
name: p.name,
|
||||
ownerId: p.ownerId,
|
||||
isPersonal: p.isPersonal,
|
||||
@@ -96,8 +106,27 @@ router.post('/', async (req, res, next) => {
|
||||
if (!name) return res.status(400).json({ error: '项目名称不能为空' })
|
||||
if (name.length > MAX_NAME) return res.status(400).json({ error: `项目名称不能超过 ${MAX_NAME} 字` })
|
||||
|
||||
// 项目短编号: 可由客户端自拟 (2~8 位字母数字, 全局唯一), 未提供时按名称自动分配
|
||||
let code
|
||||
const rawCode = req.body?.code
|
||||
if (rawCode !== undefined && rawCode !== null && String(rawCode).trim() !== '') {
|
||||
code = normProjectCode(rawCode)
|
||||
if (!code) return res.status(400).json({ error: '项目编号须为 2~8 位字母数字' })
|
||||
const dup = await prisma.project.findUnique({ where: { code } })
|
||||
if (dup) return res.status(409).json({ error: `项目编号 ${code} 已被占用` })
|
||||
} else {
|
||||
code = await allocProjectCode(name)
|
||||
}
|
||||
|
||||
const project = await prisma.project.create({
|
||||
data: { name, ownerId: userId, isPersonal: false, members: { create: { userId } } },
|
||||
data: {
|
||||
name,
|
||||
ownerId: userId,
|
||||
isPersonal: false,
|
||||
uuid: genUuid(),
|
||||
code,
|
||||
members: { create: { uuid: genUuid(), userId } },
|
||||
},
|
||||
})
|
||||
await createDefaultColumns(project.id)
|
||||
const full = await prisma.project.findUnique({
|
||||
@@ -139,7 +168,7 @@ router.put('/:id', async (req, res, next) => {
|
||||
const userId = req.user.sub
|
||||
const project = await loadProjectForUser(req.params.id, userId)
|
||||
if (!project) return res.status(404).json({ error: '项目不存在或无权限' })
|
||||
const { name, archived, notes, taskKinds, icon, autoArchive } = req.body || {}
|
||||
const { name, archived, notes, taskKinds, icon, autoArchive, code } = req.body || {}
|
||||
const data = {}
|
||||
if (name !== undefined) {
|
||||
const t = String(name).trim()
|
||||
@@ -147,6 +176,16 @@ router.put('/:id', async (req, res, next) => {
|
||||
if (t.length > MAX_NAME) return res.status(400).json({ error: `项目名称不能超过 ${MAX_NAME} 字` })
|
||||
data.name = t
|
||||
}
|
||||
// 项目短编号: 可修改 (2~8 位字母数字, 全局唯一)
|
||||
if (code !== undefined) {
|
||||
const c = normProjectCode(code)
|
||||
if (!c) return res.status(400).json({ error: '项目编号须为 2~8 位字母数字' })
|
||||
if (c !== project.code) {
|
||||
const dup = await prisma.project.findUnique({ where: { code: c } })
|
||||
if (dup) return res.status(409).json({ error: `项目编号 ${c} 已被占用` })
|
||||
data.code = c
|
||||
}
|
||||
}
|
||||
// 任务类型标签: 整体替换; 空数组回落默认
|
||||
if (taskKinds !== undefined) {
|
||||
if (!Array.isArray(taskKinds)) return res.status(400).json({ error: '任务类型格式非法' })
|
||||
@@ -215,7 +254,7 @@ router.post('/:id/members', async (req, res, next) => {
|
||||
})
|
||||
if (exist) return res.status(409).json({ error: '该用户已是项目成员' })
|
||||
|
||||
await prisma.projectMember.create({ data: { projectId: project.id, userId: target.id } })
|
||||
await prisma.projectMember.create({ data: { uuid: genUuid(), projectId: project.id, userId: target.id } })
|
||||
res.json({ ok: true, member: { userId: target.id, name: target.name } })
|
||||
} catch (e) { next(e) }
|
||||
})
|
||||
|
||||
+26
-23
@@ -9,6 +9,7 @@ import { resolveTaskWrite } from '../task-domain/resolveStatus.js'
|
||||
import { filterVisible } from '../task-domain/retention.js'
|
||||
import { copyTask } from '../task-domain/copyTask.js'
|
||||
import { runAutoArchiveForProject } from '../task-domain/archive.js'
|
||||
import { genUuid, withUuid, withTaskNumber } from '../task-domain/identity.js'
|
||||
|
||||
const router = Router()
|
||||
router.use(authRequired)
|
||||
@@ -184,28 +185,30 @@ router.post('/projects/:id/tasks', async (req, res, next) => {
|
||||
}
|
||||
|
||||
const firstCol = columns[0]
|
||||
const row = await prisma.task.create({
|
||||
data: {
|
||||
projectId: project.id,
|
||||
columnId: firstCol.id,
|
||||
parentId: pid,
|
||||
title: cleanTitle,
|
||||
description: String(description || ''),
|
||||
kind: kind ? String(kind).trim().slice(0, 20) : null,
|
||||
markDate: mark,
|
||||
status: firstCol.boundStatus || 'todo',
|
||||
assigneeId: finalAssignee,
|
||||
creatorId: userId,
|
||||
extras: [],
|
||||
members: {
|
||||
create: (Array.isArray(memberIds) ? memberIds : [])
|
||||
.map(Number).filter((id) => memberSet.has(id))
|
||||
.map((uid) => ({ userId: uid })),
|
||||
},
|
||||
tags: { create: (Array.isArray(tags) ? tags : []).filter(Boolean).map((n) => ({ name: String(n).slice(0, 20) })) },
|
||||
const taskData = {
|
||||
uuid: req.body?.uuid || genUuid(),
|
||||
projectId: project.id,
|
||||
columnId: firstCol.id,
|
||||
parentId: pid,
|
||||
title: cleanTitle,
|
||||
description: String(description || ''),
|
||||
kind: kind ? String(kind).trim().slice(0, 20) : null,
|
||||
markDate: mark,
|
||||
status: firstCol.boundStatus || 'todo',
|
||||
assigneeId: finalAssignee,
|
||||
creatorId: userId,
|
||||
extras: [],
|
||||
members: {
|
||||
create: withUuid((Array.isArray(memberIds) ? memberIds : [])
|
||||
.map(Number).filter((id) => memberSet.has(id))
|
||||
.map((uid) => ({ userId: uid }))),
|
||||
},
|
||||
include: TASK_INCLUDE,
|
||||
})
|
||||
tags: { create: withUuid((Array.isArray(tags) ? tags : []).filter(Boolean).map((n) => ({ name: String(n).slice(0, 20) }))) },
|
||||
}
|
||||
// 项目内自增编号 (展示 `code-number`): 服务端分配, 并发冲突时重取 max+1 重试
|
||||
const { value: row } = await withTaskNumber(project.id, (number) =>
|
||||
prisma.task.create({ data: { ...taskData, number }, include: TASK_INCLUDE }),
|
||||
)
|
||||
res.json({ item: shape(row) })
|
||||
} catch (e) { next(e) }
|
||||
})
|
||||
@@ -333,7 +336,7 @@ router.put('/tasks/:id', async (req, res, next) => {
|
||||
await prisma.taskMember.deleteMany({ where: { taskId: task.id } })
|
||||
if (ids.length) {
|
||||
await prisma.taskMember.createMany({
|
||||
data: ids.map((uid) => ({ taskId: task.id, userId: uid })),
|
||||
data: withUuid(ids.map((uid) => ({ taskId: task.id, userId: uid }))),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -341,7 +344,7 @@ router.put('/tasks/:id', async (req, res, next) => {
|
||||
await prisma.taskTag.deleteMany({ where: { taskId: task.id } })
|
||||
const names = body.tags.map((n) => String(n).trim()).filter(Boolean).slice(0, 10)
|
||||
if (names.length) {
|
||||
await prisma.taskTag.createMany({ data: names.map((name) => ({ taskId: task.id, name: name.slice(0, 20) })) })
|
||||
await prisma.taskTag.createMany({ data: withUuid(names.map((name) => ({ taskId: task.id, name: name.slice(0, 20) }))) })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user