@gadmin2n/schematics 0.0.87 → 0.0.89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/application/files/gadmin2-game-angle-demo/.dockerignore +16 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile.codegen +40 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile.server +76 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile.web +53 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/Jenkinsfile +219 -33
- package/dist/lib/application/files/gadmin2-game-angle-demo/compose-ctl.sh +250 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/workflow.prisma +4 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/dev/postgres/init.sql +12 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/docker-compose.md +170 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/docker-compose.yml +254 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +8 -7
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/lib/page-helpers.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/prismaModels.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/agenda.seed.ts +39 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/audit.seed.ts +40 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/bootstrap.ts +56 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/canvas.seed.ts +39 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/{scripts/sync-data-mngt-pages.ts → seed/data-mngt.seed.ts} +36 -20
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/game.seed.ts +44 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +30 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permission.seed.ts +130 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-event-trigger.ts +60 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow-node-types.ts +11 -25
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/workflow.seed.ts +108 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/main.ts +1 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/agendaJob/agendaJob.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/audit/audit.service.spec.ts +41 -57
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/game/game.service.spec.ts +309 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.service.spec.ts +315 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/pageResource/pageResource.service.spec.ts +312 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/resource/resource.service.spec.ts +317 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.service.spec.ts +309 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/rolePages/rolePages.service.spec.ts +299 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/roleResource/roleResource.service.spec.ts +307 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.controller.spec.ts +31 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/user/user.service.spec.ts +309 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/dsl-validate.util.spec.ts +205 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/dsl-validate.util.ts +116 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.spec.ts +158 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/temporal.service.ts +110 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/webhook-signature.util.spec.ts +79 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/webhook-signature.util.ts +54 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.controller.ts +34 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.spec.ts +457 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflow/workflow.service.ts +241 -4
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.controller.spec.ts +34 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowEventOutbox/workflowEventOutbox.service.spec.ts +24 -30
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.controller.spec.ts +34 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeInstance/workflowNodeInstance.service.spec.ts +36 -36
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.controller.spec.ts +34 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/workflowNodeType/workflowNodeType.service.spec.ts +48 -24
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/README.md +312 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/TODO.md +152 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/.dockerignore +12 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/Dockerfile +79 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/GRACEFUL-DEPLOYMENT.md +270 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/index.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/activities/reporting.ts +23 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/index.ts +70 -5
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/outbox-poller.ts +246 -90
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/tests/cron-trigger-workflow.test.ts +20 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/worker/src/workflows/dsl-workflow.ts +96 -8
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/nginx.conf +74 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/ElementInspector.tsx +18 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/promptGenerator.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/form.tsx +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +3 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +3 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/plugins/devShellPlugin.ts +4 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasEditPage.tsx +9 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +156 -139
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx +14 -2
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx +62 -0
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/PublishModal.tsx +4 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasApi.ts +18 -27
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasDefaults.ts +32 -11
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/demos.ts +48 -61
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas-page/index.tsx +3 -6
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/components/DslView.tsx +16 -16
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/editor.tsx +28 -35
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/instance-detail.tsx +34 -3
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/show.tsx +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/workflow/types.ts +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/antd.css +6 -0
- package/package.json +1 -1
- package/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile +0 -63
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/sync-resources.ts +0 -100
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permissions.ts +0 -302
- package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas.controller.spec.ts +0 -20
- package/dist/lib/application/files/gadmin2-game-angle-demo/temporal/sql/create-event-trigger.sql +0 -87
- /package/dist/lib/application/files/gadmin2-game-angle-demo/{GRACEFUL-DEPLOYMENT.md → server/GRACEFUL-DEPLOYMENT.md} +0 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# compose-ctl.sh — gadmin 本地全栈 docker-compose 控制脚本
|
|
3
|
+
#
|
|
4
|
+
# 用法见 `./compose-ctl.sh -h`
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
cd "$(dirname "$0")"
|
|
8
|
+
|
|
9
|
+
# ─── 项目命名(pod / 镜像 prefix 都用这个) ─────────────────────
|
|
10
|
+
# PROJECT_NAME 默认取项目目录的 basename,例如本项目为 "gadmin-test"。
|
|
11
|
+
# - 镜像: <PROJECT_NAME>-{codegen,web,nest-server,temporal-worker}:local
|
|
12
|
+
# - pod : <PROJECT_NAME>-pod (仅 podman-compose 有 pod 概念)
|
|
13
|
+
# 通过 export COMPOSE_PROJECT_NAME 让 docker-compose.yml 中的
|
|
14
|
+
# ${COMPOSE_PROJECT_NAME} 变量插值到正确的值。
|
|
15
|
+
PROJECT_NAME="$(basename "$(pwd)")"
|
|
16
|
+
export COMPOSE_PROJECT_NAME="$PROJECT_NAME"
|
|
17
|
+
POD_NAME="${PROJECT_NAME}-pod"
|
|
18
|
+
CODEGEN_IMAGE="${PROJECT_NAME}-codegen:local"
|
|
19
|
+
|
|
20
|
+
# ─── 最低推荐版本(低于会打 warning 但仍尝试执行) ──────────────
|
|
21
|
+
MIN_DOCKER="20.10"
|
|
22
|
+
MIN_DOCKER_COMPOSE_V2="2.0.0"
|
|
23
|
+
MIN_DOCKER_COMPOSE_V1="1.29.0"
|
|
24
|
+
MIN_PODMAN="4.0.0"
|
|
25
|
+
MIN_PODMAN_COMPOSE="1.0.7"
|
|
26
|
+
|
|
27
|
+
# 从命令输出中抽取第一个 X.Y(.Z) 形式的版本号
|
|
28
|
+
extract_semver() {
|
|
29
|
+
printf '%s' "$1" | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n1
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# version_lt "1.0.6" "1.0.7" → 0 (true) 当 $1 < $2
|
|
33
|
+
version_lt() {
|
|
34
|
+
[ "$1" = "$2" ] && return 1
|
|
35
|
+
[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
warn_if_old() {
|
|
39
|
+
local name="$1" actual="$2" minimum="$3"
|
|
40
|
+
if [ -z "$actual" ]; then
|
|
41
|
+
echo "[compose-ctl] WARN: 无法检测 $name 版本(最低推荐 $minimum)" >&2
|
|
42
|
+
return
|
|
43
|
+
fi
|
|
44
|
+
if version_lt "$actual" "$minimum"; then
|
|
45
|
+
echo "[compose-ctl] WARN: $name $actual < 最低推荐 $minimum" >&2
|
|
46
|
+
echo "[compose-ctl] 可能症状:profiles 不生效 / service_completed_successfully 被忽略 /" >&2
|
|
47
|
+
echo "[compose-ctl] depends_on 顺序错乱 / 多阶段构建失败。建议升级。" >&2
|
|
48
|
+
fi
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# ─── 运行时探测 ─────────────────────────────────────────────────
|
|
52
|
+
# shell alias (alias docker=podman) 不会传到 bash 脚本里,所以这里要自己找。
|
|
53
|
+
# DOCKER_CLI / COMPOSE_CLI 用数组以支持 "docker compose" 这种带空格的命令。
|
|
54
|
+
DOCKER_CLI=()
|
|
55
|
+
COMPOSE_CLI=()
|
|
56
|
+
DOCKER_VER=""
|
|
57
|
+
COMPOSE_VER=""
|
|
58
|
+
COMPOSE_KIND="" # 用于挑选最低推荐版本
|
|
59
|
+
|
|
60
|
+
detect_runtime() {
|
|
61
|
+
if command -v docker >/dev/null 2>&1; then
|
|
62
|
+
DOCKER_CLI=(docker)
|
|
63
|
+
DOCKER_VER=$(extract_semver "$(docker --version 2>/dev/null)")
|
|
64
|
+
if docker compose version >/dev/null 2>&1; then
|
|
65
|
+
COMPOSE_CLI=(docker compose)
|
|
66
|
+
COMPOSE_VER=$(extract_semver "$(docker compose version 2>/dev/null)")
|
|
67
|
+
COMPOSE_KIND="docker-compose-v2"
|
|
68
|
+
elif command -v docker-compose >/dev/null 2>&1; then
|
|
69
|
+
COMPOSE_CLI=(docker-compose)
|
|
70
|
+
COMPOSE_VER=$(extract_semver "$(docker-compose --version 2>/dev/null)")
|
|
71
|
+
# v2 standalone 的版本号也是 2.x,v1 是 1.x
|
|
72
|
+
case "$COMPOSE_VER" in
|
|
73
|
+
2.*) COMPOSE_KIND="docker-compose-v2" ;;
|
|
74
|
+
*) COMPOSE_KIND="docker-compose-v1" ;;
|
|
75
|
+
esac
|
|
76
|
+
fi
|
|
77
|
+
elif command -v podman >/dev/null 2>&1; then
|
|
78
|
+
DOCKER_CLI=(podman)
|
|
79
|
+
DOCKER_VER=$(extract_semver "$(podman --version 2>/dev/null)")
|
|
80
|
+
if command -v podman-compose >/dev/null 2>&1; then
|
|
81
|
+
COMPOSE_CLI=(podman-compose)
|
|
82
|
+
COMPOSE_VER=$(extract_semver "$(podman-compose --version 2>/dev/null | head -n1)")
|
|
83
|
+
COMPOSE_KIND="podman-compose"
|
|
84
|
+
elif command -v docker-compose >/dev/null 2>&1; then
|
|
85
|
+
COMPOSE_CLI=(docker-compose)
|
|
86
|
+
COMPOSE_VER=$(extract_semver "$(docker-compose --version 2>/dev/null)")
|
|
87
|
+
case "$COMPOSE_VER" in
|
|
88
|
+
2.*) COMPOSE_KIND="docker-compose-v2" ;;
|
|
89
|
+
*) COMPOSE_KIND="docker-compose-v1" ;;
|
|
90
|
+
esac
|
|
91
|
+
fi
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
if [ ${#DOCKER_CLI[@]} -eq 0 ]; then
|
|
95
|
+
echo "ERROR: 未找到 docker 或 podman" >&2
|
|
96
|
+
echo "提示:alias docker=podman 不会传到 bash 脚本,需要真实安装 docker 或 podman 二进制" >&2
|
|
97
|
+
exit 127
|
|
98
|
+
fi
|
|
99
|
+
if [ ${#COMPOSE_CLI[@]} -eq 0 ]; then
|
|
100
|
+
echo "ERROR: 找到了 ${DOCKER_CLI[*]} 但没找到 compose 命令" >&2
|
|
101
|
+
echo "提示:装 docker-compose 或 podman-compose" >&2
|
|
102
|
+
exit 127
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
echo "[compose-ctl] runtime: ${DOCKER_CLI[*]} ${DOCKER_VER:-?} | compose: ${COMPOSE_CLI[*]} ${COMPOSE_VER:-?}"
|
|
106
|
+
|
|
107
|
+
# podman-compose 1.0.7+ 支持 --in-pod=NAME,让所有服务跑在同一个自定义命名 pod 里。
|
|
108
|
+
# docker-compose 没有 pod 概念,跳过。
|
|
109
|
+
COMPOSE_GLOBAL_ARGS=()
|
|
110
|
+
if [ "$COMPOSE_KIND" = "podman-compose" ]; then
|
|
111
|
+
COMPOSE_GLOBAL_ARGS+=(--in-pod="$POD_NAME")
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
# 版本检查(只 warn 不 fail)
|
|
115
|
+
case "${DOCKER_CLI[0]}" in
|
|
116
|
+
docker) warn_if_old "docker" "$DOCKER_VER" "$MIN_DOCKER" ;;
|
|
117
|
+
podman) warn_if_old "podman" "$DOCKER_VER" "$MIN_PODMAN" ;;
|
|
118
|
+
esac
|
|
119
|
+
case "$COMPOSE_KIND" in
|
|
120
|
+
docker-compose-v2) warn_if_old "docker compose" "$COMPOSE_VER" "$MIN_DOCKER_COMPOSE_V2" ;;
|
|
121
|
+
docker-compose-v1) warn_if_old "docker-compose" "$COMPOSE_VER" "$MIN_DOCKER_COMPOSE_V1" ;;
|
|
122
|
+
podman-compose) warn_if_old "podman-compose" "$COMPOSE_VER" "$MIN_PODMAN_COMPOSE" ;;
|
|
123
|
+
esac
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
print_help() {
|
|
127
|
+
cat <<'EOF'
|
|
128
|
+
compose-ctl.sh — gadmin-test 本地全栈 docker-compose 控制脚本
|
|
129
|
+
|
|
130
|
+
用法:
|
|
131
|
+
./compose-ctl.sh [up] 起服务(默认)。codegen 镜像不存在才构建,否则跳过。
|
|
132
|
+
./compose-ctl.sh --rebuild 强制重建 codegen 后起服务。
|
|
133
|
+
config/ui/** 或 config/prisma/** 改动后用。
|
|
134
|
+
./compose-ctl.sh --reset 清数据卷 + 重建 codegen + 起服务(核武器)。
|
|
135
|
+
业务数据、temporal 历史全部清空,回到种子数据状态。
|
|
136
|
+
./compose-ctl.sh --down 停服务(保留数据)。
|
|
137
|
+
./compose-ctl.sh -h, --help 显示本帮助。
|
|
138
|
+
|
|
139
|
+
运行时:
|
|
140
|
+
脚本会自动探测 docker / podman,自动选择 compose 命令。
|
|
141
|
+
优先级: docker compose > docker-compose > podman-compose
|
|
142
|
+
|
|
143
|
+
最低推荐版本(低于会打 warning,不阻断执行):
|
|
144
|
+
docker >= 20.10
|
|
145
|
+
docker compose v2 >= 2.0 (插件形式 / 独立 v2 二进制)
|
|
146
|
+
docker-compose v1 >= 1.29 (legacy)
|
|
147
|
+
podman >= 4.0
|
|
148
|
+
podman-compose >= 1.0.7
|
|
149
|
+
|
|
150
|
+
示例:
|
|
151
|
+
首次拉代码后: ./compose-ctl.sh
|
|
152
|
+
改了 prisma: ./compose-ctl.sh --rebuild
|
|
153
|
+
数据库脏了: ./compose-ctl.sh --reset
|
|
154
|
+
下班关掉: ./compose-ctl.sh --down
|
|
155
|
+
EOF
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
print_post_up_guide() {
|
|
159
|
+
cat <<'EOF'
|
|
160
|
+
|
|
161
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
162
|
+
服务已启动 ✓ 首次启动需等 30~60s 让 temporal-server 完成 schema 初始化
|
|
163
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
164
|
+
|
|
165
|
+
访问入口:
|
|
166
|
+
Web 前端 http://localhost:3000
|
|
167
|
+
Server API http://localhost:8000 (健康检查 /health/live)
|
|
168
|
+
Temporal Web UI http://localhost:8080
|
|
169
|
+
Temporal gRPC localhost:7233 (worker / @temporalio/client)
|
|
170
|
+
PostgreSQL localhost:5432 (用户 kavenma / 密码 kavenma)
|
|
171
|
+
|
|
172
|
+
库划分 (PG 内):
|
|
173
|
+
gadmin_demo 业务库 (server + worker, Prisma 管理)
|
|
174
|
+
temporal Temporal 元数据库
|
|
175
|
+
temporal_visibility Temporal Visibility 库 (PG-only)
|
|
176
|
+
|
|
177
|
+
常用命令:
|
|
178
|
+
查看所有服务状态 docker compose ps
|
|
179
|
+
跟某个服务日志 docker compose logs -f <service>
|
|
180
|
+
(service: postgres / temporal-server / temporal-ui /
|
|
181
|
+
temporal-worker / server / server-init / web)
|
|
182
|
+
跟全部日志 docker compose logs -f
|
|
183
|
+
重启某服务 docker compose restart <service>
|
|
184
|
+
进容器排查 docker compose exec <service> sh
|
|
185
|
+
|
|
186
|
+
停止 / 重置:
|
|
187
|
+
停服务 (保留数据) ./compose-ctl.sh --down
|
|
188
|
+
config 改了重建 ./compose-ctl.sh --rebuild
|
|
189
|
+
清空数据回到种子状态 ./compose-ctl.sh --reset
|
|
190
|
+
|
|
191
|
+
提示:
|
|
192
|
+
· 前端开发请用 cd web && yarn dev (本 compose 的 web 是 nginx 静态镜像,无热更新)
|
|
193
|
+
· server-init 是一次性容器,跑完 push:db + seed 后退出 (Exited 0) 是正常的
|
|
194
|
+
EOF
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
build_codegen() {
|
|
198
|
+
echo "[compose-ctl] building codegen image ($CODEGEN_IMAGE) ..."
|
|
199
|
+
"${COMPOSE_CLI[@]}" "${COMPOSE_GLOBAL_ARGS[@]}" --profile codegen build codegen
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
up_services() {
|
|
203
|
+
echo "[compose-ctl] starting services (project=$PROJECT_NAME, pod=$POD_NAME) ..."
|
|
204
|
+
"${COMPOSE_CLI[@]}" "${COMPOSE_GLOBAL_ARGS[@]}" up -d --build
|
|
205
|
+
print_post_up_guide
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
# ─── main ──────────────────────────────────────────────────────
|
|
209
|
+
# 帮助命令不需要运行时,先处理
|
|
210
|
+
case "${1:-up}" in
|
|
211
|
+
-h|--help)
|
|
212
|
+
print_help
|
|
213
|
+
exit 0
|
|
214
|
+
;;
|
|
215
|
+
esac
|
|
216
|
+
|
|
217
|
+
detect_runtime
|
|
218
|
+
|
|
219
|
+
case "${1:-up}" in
|
|
220
|
+
up)
|
|
221
|
+
if "${DOCKER_CLI[@]}" image inspect "$CODEGEN_IMAGE" >/dev/null 2>&1; then
|
|
222
|
+
echo "[compose-ctl] codegen image exists, skip build (use --rebuild to force)"
|
|
223
|
+
else
|
|
224
|
+
build_codegen
|
|
225
|
+
fi
|
|
226
|
+
up_services
|
|
227
|
+
;;
|
|
228
|
+
--rebuild|-r)
|
|
229
|
+
build_codegen
|
|
230
|
+
# podman-compose 1.x 不会因镜像 ID 变化自动重建容器(docker-compose v2 会)。
|
|
231
|
+
# --rebuild 既然是为"改了配置/Dockerfile/代码"准备的,强制 recreate 才能让新镜像生效。
|
|
232
|
+
echo "[compose-ctl] (rebuild) force-recreating containers ..."
|
|
233
|
+
"${COMPOSE_CLI[@]}" "${COMPOSE_GLOBAL_ARGS[@]}" up -d --build --force-recreate
|
|
234
|
+
print_post_up_guide
|
|
235
|
+
;;
|
|
236
|
+
--reset)
|
|
237
|
+
"${COMPOSE_CLI[@]}" "${COMPOSE_GLOBAL_ARGS[@]}" down -v
|
|
238
|
+
build_codegen
|
|
239
|
+
up_services
|
|
240
|
+
;;
|
|
241
|
+
--down)
|
|
242
|
+
"${COMPOSE_CLI[@]}" "${COMPOSE_GLOBAL_ARGS[@]}" down
|
|
243
|
+
;;
|
|
244
|
+
*)
|
|
245
|
+
echo "unknown option: $1" >&2
|
|
246
|
+
echo "" >&2
|
|
247
|
+
print_help >&2
|
|
248
|
+
exit 1
|
|
249
|
+
;;
|
|
250
|
+
esac
|
|
@@ -76,6 +76,7 @@ model WorkflowInstance {
|
|
|
76
76
|
context Json?
|
|
77
77
|
result Json?
|
|
78
78
|
temporalRunId String? @db.VarChar(128) @map("temporal_run_id") // Temporal workflow run ID
|
|
79
|
+
sourceOutboxId BigInt? @map("source_outbox_id") // 触发本实例的 outbox 行 id;与 workflowId 组合后唯一,用于 outbox-poller 的幂等 upsert,避免崩溃恢复时产生重复 instance 行
|
|
79
80
|
startedAt DateTime? @map("started_at")
|
|
80
81
|
finishedAt DateTime? @map("finished_at")
|
|
81
82
|
creator String @default("") @db.VarChar(128) @map("creator")
|
|
@@ -85,6 +86,7 @@ model WorkflowInstance {
|
|
|
85
86
|
workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade)
|
|
86
87
|
nodeExecutions WorkflowNodeExecution[]
|
|
87
88
|
|
|
89
|
+
@@unique([workflowId, sourceOutboxId], map: "uk_wi_workflow_outbox") // 一个 outbox 事件对一个 workflow 至多一条 instance(NULL 不参与唯一性,正常 execute / cron / webhook 不受影响)
|
|
88
90
|
@@index([workflowId], map: "idx_wi_workflow_id")
|
|
89
91
|
@@index([status], map: "idx_wi_status")
|
|
90
92
|
@@map("t_workflow_instance")
|
|
@@ -166,6 +168,7 @@ model WorkflowEventOutbox {
|
|
|
166
168
|
retryCount Int @default(0) @map("retry_count") // 处理失败重试次数
|
|
167
169
|
lastError String? @db.Text @map("last_error") // 最近一次失败的错误信息
|
|
168
170
|
|
|
169
|
-
|
|
171
|
+
// 注意:未处理事件的部分索引 idx_outbox_unprocessed 由 seed/workflow-event-trigger.ts 维护
|
|
172
|
+
// (Prisma schema 不支持 WHERE 子句的 partial index)
|
|
170
173
|
@@map("t_workflow_event_outbox")
|
|
171
174
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- Bootstrap databases on first postgres container start.
|
|
2
|
+
-- Runs once: only when the named volume `pgdata` is empty.
|
|
3
|
+
-- Reset with `docker compose down -v` to re-run.
|
|
4
|
+
--
|
|
5
|
+
-- Three databases created here:
|
|
6
|
+
-- gadmin_demo -> server + worker business data (Prisma)
|
|
7
|
+
-- temporal -> Temporal Server default schema (auto-setup populates tables)
|
|
8
|
+
-- temporal_visibility -> Temporal Server visibility schema (PG-only, no ES locally)
|
|
9
|
+
|
|
10
|
+
CREATE DATABASE gadmin_demo;
|
|
11
|
+
CREATE DATABASE temporal;
|
|
12
|
+
CREATE DATABASE temporal_visibility;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# 本地联调环境(docker-compose)
|
|
2
|
+
|
|
3
|
+
一行命令起一整套服务用于本地集成验证:PostgreSQL + Temporal Server + Temporal Web UI + NestJS Server + Temporal Worker + Web 前端。
|
|
4
|
+
|
|
5
|
+
> 生产部署走 K8s(参考 `docs/temporal-server-argocd.md`)。本环境**只**用于本地联调与端到端集成验证。
|
|
6
|
+
|
|
7
|
+
## 启动 / 停止
|
|
8
|
+
|
|
9
|
+
**推荐:用 `./compose-ctl.sh` 一键起,不用记 codegen 那一步。**
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# 起所有服务(codegen 镜像不存在才构建,否则跳过)
|
|
13
|
+
./compose-ctl.sh
|
|
14
|
+
|
|
15
|
+
# 改了 config/ui/** 或 config/prisma/** 后,强制重建 codegen
|
|
16
|
+
./compose-ctl.sh --rebuild
|
|
17
|
+
|
|
18
|
+
# 完全重置:清数据卷 + 重建 codegen + 起服务(首启会重新初始化 schema/seed)
|
|
19
|
+
./compose-ctl.sh --reset
|
|
20
|
+
|
|
21
|
+
# 停服务(保留数据)
|
|
22
|
+
./compose-ctl.sh --down
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
如果想用原生 `docker compose` 命令(脚本就是这两步的封装):
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# 起所有服务(后台)
|
|
29
|
+
docker compose up -d
|
|
30
|
+
|
|
31
|
+
# 跟日志(按 Ctrl+C 退出,服务继续运行)
|
|
32
|
+
docker compose logs -f
|
|
33
|
+
|
|
34
|
+
# 停服务(保留数据)
|
|
35
|
+
docker compose down
|
|
36
|
+
|
|
37
|
+
# 完全重置(连数据卷一起删,下次首启会重新初始化 schema)
|
|
38
|
+
docker compose down -v
|
|
39
|
+
|
|
40
|
+
# 重建某个镜像(改了 Dockerfile / 源码后)
|
|
41
|
+
docker compose build server
|
|
42
|
+
docker compose up -d server
|
|
43
|
+
|
|
44
|
+
# 改了 config/ui/** 或 config/prisma/** 后,必须先 rebuild codegen 中间镜像
|
|
45
|
+
docker compose --profile codegen build codegen
|
|
46
|
+
docker compose build server web # 让 server/web 拉到新的生成代码
|
|
47
|
+
docker compose up -d server web
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 访问入口
|
|
51
|
+
|
|
52
|
+
| 服务 | 地址 | 说明 |
|
|
53
|
+
|------|------|------|
|
|
54
|
+
| Web 前端 | http://localhost:3000 | 生产 nginx 镜像,**不支持热更新** |
|
|
55
|
+
| Server API | http://localhost:8000 | NestJS,健康检查 `/health/live` |
|
|
56
|
+
| Temporal Web UI | http://localhost:8080 | Workflow 可视化 |
|
|
57
|
+
| Temporal gRPC | `localhost:7233` | Worker / `@temporalio/client` 连这里 |
|
|
58
|
+
| PostgreSQL | `localhost:5432` | 用户 `kavenma` / 密码 `kavenma` |
|
|
59
|
+
|
|
60
|
+
库划分:
|
|
61
|
+
|
|
62
|
+
- `gadmin_demo` —— 业务库(server + worker 共用,Prisma 管理)
|
|
63
|
+
- `temporal` —— Temporal 元数据库(auto-setup 自动建表)
|
|
64
|
+
- `temporal_visibility` —— Temporal Visibility 库(PG-only,本地不开 ES)
|
|
65
|
+
|
|
66
|
+
## 与 `temporal/docker-compose.yml` 的区别
|
|
67
|
+
|
|
68
|
+
| 文件 | 内容 | 用途 |
|
|
69
|
+
|------|------|------|
|
|
70
|
+
| `docker-compose.yml`(本目录) | **完整**栈:PG + Temporal + Server + Worker + Web | 端到端集成验证 |
|
|
71
|
+
| `temporal/docker-compose.yml` | 只有 Temporal Server + UI(连 host PG) | 只想跑 Temporal、复用本机 PG 时使用 |
|
|
72
|
+
|
|
73
|
+
两个文件互不干扰,可单独使用。
|
|
74
|
+
|
|
75
|
+
## 前端开发态:不要用本 compose
|
|
76
|
+
|
|
77
|
+
本 compose 里的 `web` service 是 `nginx + 编译后静态文件`,改前端代码不会热更新。日常前端开发请:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
cd web
|
|
81
|
+
yarn dev # Vite dev server,端口 5173,自带 HMR
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
让 Vite dev server 反代到本 compose 起的 `server`(http://localhost:8000)。
|
|
85
|
+
|
|
86
|
+
后端开发同理:可以选择只起 `postgres` + `temporal-server` 这两个外部依赖:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
docker compose up -d postgres temporal-server temporal-ui
|
|
90
|
+
cd server && yarn start:dev
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 启动顺序(depends_on + healthcheck)
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
postgres (healthy: pg_isready)
|
|
97
|
+
├─> server-init (一次性容器:prisma db push + seed → exit 0)
|
|
98
|
+
│ ├─> server (启动 API)
|
|
99
|
+
│ └─> temporal-worker (并需 temporal-server healthy)
|
|
100
|
+
└─> temporal-server (healthy: temporal operator cluster health)
|
|
101
|
+
├─> temporal-ui
|
|
102
|
+
└─> temporal-worker
|
|
103
|
+
server (started)
|
|
104
|
+
└─> web
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
首次启动 Temporal 需要跑 schema 初始化(约 30~60s),期间 `temporal-server` 会处于 `starting`,依赖它的 worker 会等待。
|
|
108
|
+
|
|
109
|
+
`server-init` 跑完 `prisma db push` + `seed` 就退出,`docker compose ps` 里它显示 `Exited (0)` 是正常的,不是故障 —— 见"常见问题"。
|
|
110
|
+
|
|
111
|
+
## 常见问题
|
|
112
|
+
|
|
113
|
+
### 端口冲突
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# 看占用:
|
|
117
|
+
lsof -iTCP:3000 -sTCP:LISTEN
|
|
118
|
+
lsof -iTCP:5432 -sTCP:LISTEN
|
|
119
|
+
lsof -iTCP:7233 -sTCP:LISTEN
|
|
120
|
+
lsof -iTCP:8000 -sTCP:LISTEN
|
|
121
|
+
lsof -iTCP:8080 -sTCP:LISTEN
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
如本机已有 PG 在 5432,可临时把 `docker-compose.yml` 里 postgres 的 ports 改成 `"5433:5432"`,并把 server / worker 的 `DATABASE_URL` host 改回 `postgres`(容器内通信不变,宿主机端口不影响 docker 网络)。
|
|
125
|
+
|
|
126
|
+
### `server-init` 显示 `Exited (0)` 是 bug 吗?
|
|
127
|
+
|
|
128
|
+
**不是。** `server-init` 是一次性容器,启动后跑 `prisma db push` 同步业务表结构,再跑 `seed` 灌默认数据,跑完就退出 ——`docker compose ps` 里看到状态 `Exited (0)` 即代表初始化成功。`server` / `temporal-worker` 在 `depends_on` 里声明了 `condition: service_completed_successfully` 等它跑完。
|
|
129
|
+
|
|
130
|
+
> ⚠️ **podman-compose 1.x 注意**:实测对 `service_completed_successfully` 的支持不完整,`up -d` 时不会真的等 init 退出就启动 server/worker。NestJS 启动时不立即查表所以一般没问题,但严格的串行保证没了。真 docker-compose v2 没这问题。
|
|
131
|
+
|
|
132
|
+
要看它做了什么:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
docker compose logs server-init
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
如果状态是 `Exited (1)` 或更高,说明 push:db 或 seed 失败了,server / worker 不会启动。看日志排错后用 `docker compose up -d server-init` 重跑(幂等)。
|
|
139
|
+
|
|
140
|
+
### Temporal schema 初始化失败
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
docker compose logs temporal-server | grep -i schema
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
最常见原因是 PG 没就绪 server 就启动了。`docker compose down -v` 重置后再 `up -d` 通常解决。
|
|
147
|
+
|
|
148
|
+
### Server 启动后访问 401 / Cookie 失效
|
|
149
|
+
|
|
150
|
+
server 镜像里 `TAIHU_*` 用的是 `server/.env` 默认值,对应太湖测试账号。如需走真实账号,先 `docker compose down`,把对应变量加到 shell 环境(或新建项目根 `.env` 文件,compose 会自动读取)后重启。
|
|
151
|
+
|
|
152
|
+
### 重置数据库(清空所有业务数据)
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
./compose-ctl.sh --reset
|
|
156
|
+
# 等 temporal-server 重新做 schema setup(看日志 `temporal-server` 里出现 "Temporal server started")
|
|
157
|
+
# server-init 会自动重跑 push:db + seed,业务库回到种子数据状态
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## 用到的镜像
|
|
161
|
+
|
|
162
|
+
| 镜像 | 版本 | 来源 |
|
|
163
|
+
|------|------|------|
|
|
164
|
+
| `postgres` | 15-alpine | docker hub 官方 |
|
|
165
|
+
| `temporalio/auto-setup` | 1.29.6.1 | Docker Hub 上 auto-setup 当前最新(生产 Server 是 1.31.0,auto-setup tag 通常滞后;schema 兼容) |
|
|
166
|
+
| `temporalio/ui` | latest | 仅 UI,跨版本兼容性好 |
|
|
167
|
+
| `gadmin2-codegen:local` | 本地 build | `Dockerfile.codegen`,仅做 `gadmin2 g prisma`,被 server/web 镜像通过 `FROM ${CODEGEN_IMAGE}` 引用;同时被 `server-init` 直接复用其全量依赖 |
|
|
168
|
+
| `gadmin-server` | 本地 build | `Dockerfile.server`,build context = 项目根,依赖 codegen 镜像 |
|
|
169
|
+
| `gadmin-temporal-worker` | 本地 build | `temporal/worker/Dockerfile` |
|
|
170
|
+
| `gadmin-web` | 本地 build | `Dockerfile.web`,nginx 静态镜像,依赖 codegen 镜像 |
|