Merge origin/codex/xuxiake-mainline into codex/local-3001-integration (sync before art-flow raw view push)

This commit is contained in:
WuYongJie 2026-10-08 17:23:44 +08:00
commit 1ba16cbc6b
3 changed files with 114 additions and 0 deletions

View File

@ -0,0 +1,25 @@
-- 简尚「替换款管理」换货规则表(商品SABC打标「同款商品编码」依赖)。
-- 历史遗留:该表一直没进 migrations(本地用 db push 建过),正式环境用 migrate deploy 时缺失,
-- 导致同款商品编码全部为空。这里补上建表语句,生产/本地都可重复执行。
CREATE TABLE IF NOT EXISTS "SupplyChainProductArchiveReplacementRule" (
"id" TEXT NOT NULL,
"sourceId" INTEGER NOT NULL,
"sku" TEXT NOT NULL,
"replaceSku" TEXT NOT NULL DEFAULT '',
"replaceType" INTEGER NOT NULL DEFAULT 0,
"isSwapping" INTEGER NOT NULL DEFAULT 0,
"differentPoints" TEXT NOT NULL DEFAULT '',
"creator" TEXT NOT NULL DEFAULT '',
"sourceCreatedAt" TIMESTAMP(6),
"syncedAt" TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "SupplyChainProductArchiveReplacementRule_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX IF NOT EXISTS "SupplyChainProductArchiveReplacementRule_sourceId_key"
ON "SupplyChainProductArchiveReplacementRule" ("sourceId");
CREATE INDEX IF NOT EXISTS "SupplyChainProductArchiveReplacementRule_sku_idx"
ON "SupplyChainProductArchiveReplacementRule" ("sku");
CREATE INDEX IF NOT EXISTS "SupplyChainProductArchiveReplacementRule_replaceSku_idx"
ON "SupplyChainProductArchiveReplacementRule" ("replaceSku");

View File

@ -1095,6 +1095,24 @@ model SupplyChainProductArchiveDepartmentSnapshot {
@@index([generatedAt])
}
/// 简尚「替换款管理」换货规则:sku = 原编码(老),replaceSku = 替换编码(新)。
/// 商品SABC打标的「同款商品编码(业绩&费比合并计算)」与业绩合并都依赖这张表。
model SupplyChainProductArchiveReplacementRule {
id String @id
sourceId Int @unique
sku String
replaceSku String @default("")
replaceType Int @default(0)
isSwapping Int @default(0)
differentPoints String @default("")
creator String @default("")
sourceCreatedAt DateTime? @db.Timestamp(6)
syncedAt DateTime @default(now()) @db.Timestamp(6)
@@index([sku])
@@index([replaceSku])
}
model SupplyChainProductArchiveSource {
id String @id @default(cuid())
archiveId String

View File

@ -0,0 +1,71 @@
#!/usr/bin/env bash
set -euo pipefail
# Installs the daily sync timer for the JST replacement rules table
# (rpt.pm_replacementManage -> SupplyChainProductArchiveReplacementRule).
# The SABC same-product-code merge depends on this table being fresh,
# so the default schedule runs before the 09:00 SABC tag reconciliation.
BASE="${FURNITURE_PROD_BASE:-/opt/furniture-3d-system-prod}"
SERVICE_NAME="${PRODUCT_REPLACEMENT_RULE_SYNC_SERVICE_NAME:-furniture-product-replacement-rule-sync}"
APP_ROOT="$BASE/current/furniture-3d-system"
SHARED="$BASE/shared"
APP_ENV="$SHARED/.env"
SERVICE_FILE="/etc/systemd/system/$SERVICE_NAME.service"
TIMER_FILE="/etc/systemd/system/$SERVICE_NAME.timer"
SCHEDULE="${PRODUCT_REPLACEMENT_RULE_SYNC_SCHEDULE:-*-*-* 07:40:00 Asia/Shanghai}"
RANDOMIZED_DELAY_SEC="${PRODUCT_REPLACEMENT_RULE_SYNC_RANDOMIZED_DELAY_SEC:-5min}"
if [ "$(id -u)" -ne 0 ]; then
echo "This installer must run as root." >&2
exit 1
fi
if [ ! -d "$APP_ROOT" ]; then
echo "Missing app root: $APP_ROOT" >&2
exit 1
fi
if [ ! -f "$APP_ENV" ]; then
echo "Missing app env: $APP_ENV" >&2
exit 1
fi
if command -v systemd-analyze >/dev/null 2>&1; then
systemd-analyze calendar "$SCHEDULE" >/dev/null
fi
cat >"$SERVICE_FILE" <<EOF
[Unit]
Description=Sync JST replacement rules into SupplyChainProductArchiveReplacementRule
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
WorkingDirectory=$APP_ROOT
Environment=NODE_ENV=production
EnvironmentFile=$APP_ENV
ExecStart=/bin/bash -lc 'set -euo pipefail; cd "$APP_ROOT"; ./node_modules/.bin/tsx scripts/sync-product-replacement-rules.ts --apply --confirm=sync-product-replacement-rules'
TimeoutStartSec=1h
StandardOutput=journal
StandardError=journal
EOF
cat >"$TIMER_FILE" <<EOF
[Unit]
Description=Sync JST replacement rules once a day
[Timer]
OnCalendar=$SCHEDULE
Persistent=true
RandomizedDelaySec=$RANDOMIZED_DELAY_SEC
Unit=$SERVICE_NAME.service
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable --now "$SERVICE_NAME.timer"
systemctl list-timers --all "$SERVICE_NAME.timer" --no-pager