feat: complete production workflow migration
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
# Launcher provenance only
|
||||
|
||||
These launchers preserve the arguments and sequencing discovered during the
|
||||
read-only audit. Their project-root literals were replaced by the inert
|
||||
`GYXX_RUNTIME_ROOT` placeholder during migration.
|
||||
|
||||
Do not register or invoke these files as production entry points. Final tasks
|
||||
must call the native `gyxx-flow` CLI and its workflow registry.
|
||||
@@ -0,0 +1,35 @@
|
||||
@echo off
|
||||
REM Daily 23:00 sales-decline alert -- independent of 08:40 daily collect.
|
||||
REM
|
||||
REM Detection window: previous 9 days from today, split into 3 segments
|
||||
REM (strict decline: seg1 > seg2 > seg3 > 0).
|
||||
REM Data source: data/<plat>/<safe_name>_<date>/data.json (PG first, JSON fallback).
|
||||
REM Notify: POST Hermes analyzer chat completions, analyzer @ recipient by openid.
|
||||
REM Recipient: ou_7ad5fc8012e2f741afc5346e05ffd447.
|
||||
REM
|
||||
REM Independence rationale:
|
||||
REM - daily collect at 08:40 uses "yesterday" as window end (9d back: 5.31-6.8)
|
||||
REM - this job at 23:00 uses "today" (9d back: 6.1-6.9) to see the latest trend
|
||||
REM - even if daily collect fails, the alert still triggers
|
||||
REM
|
||||
REM Exit codes:
|
||||
REM 0 = 0 events, or successful POST
|
||||
REM 1 = detection logic failed
|
||||
REM 3 = Hermes POST failed (events still persisted)
|
||||
|
||||
setlocal
|
||||
cd /d %GYXX_RUNTIME_ROOT%
|
||||
|
||||
set "PY=%GYXX_RUNTIME_ROOT%\.venv\Scripts\python.exe"
|
||||
|
||||
if not exist data\logs mkdir data\logs
|
||||
|
||||
for /f %%i in ('powershell -NoProfile -Command "Get-Date -Format yyyy-MM-dd"') do set TODAY=%%i
|
||||
|
||||
echo [%TODAY% 23:00] === sales alert job start === >> data\logs\alerts.log
|
||||
|
||||
"%PY%" run_alerts_with_retry.py --end-date %TODAY% --openid ou_7ad5fc8012e2f741afc5346e05ffd447 >> data\logs\alerts.log 2>&1
|
||||
set RC=%ERRORLEVEL%
|
||||
|
||||
echo [%TODAY% 23:00] === sales alert job end (rc=%RC%) === >> data\logs\alerts.log
|
||||
exit /b %RC%
|
||||
@@ -0,0 +1,17 @@
|
||||
@echo off
|
||||
REM Daily 08:40 trigger -- collect (ERP + 3 platforms) + analyze (date-first summary)
|
||||
REM + export (data/ready_for_bitable/<date>/bitable_records.json)
|
||||
REM + insert (推飞书多维表格)
|
||||
REM Skips notify/decline (告警由 run_alerts.bat 23:00 跑; decline 暂未自动触发)
|
||||
REM Uses project venv Python to ensure scrapling/playwright are available
|
||||
REM 08:40 选在 JD/TM 当日数据已刷新、且赶在工作日开始前完成批跑
|
||||
|
||||
setlocal
|
||||
cd /d %GYXX_RUNTIME_ROOT%
|
||||
|
||||
set "PY=%GYXX_RUNTIME_ROOT%\.venv\Scripts\python.exe"
|
||||
|
||||
if not exist data\logs mkdir data\logs
|
||||
|
||||
"%PY%" orchestrate_daily_collection.py --stages collect,analyze,export,insert >> data\logs\daily_collect.log 2>&1
|
||||
exit /b %ERRORLEVEL%
|
||||
@@ -0,0 +1,38 @@
|
||||
@echo off
|
||||
REM run_daily_import.bat
|
||||
REM Triggered by Windows Task Scheduler daily at 19:00.
|
||||
REM Imports previous day's data via import_product_daily.py.
|
||||
REM Log goes to logs/daily_import_<timestamp>.log.
|
||||
REM Note: file is ASCII-only on purpose - cmd's default codepage 936 (GBK)
|
||||
REM misparses UTF-8 Chinese in REM/echo lines as commands.
|
||||
|
||||
setlocal EnableDelayedExpansion
|
||||
set "PROJECT_DIR=%GYXX_RUNTIME_ROOT%"
|
||||
set "PY=%PROJECT_DIR%\.venv\Scripts\python.exe"
|
||||
set "SCRIPT=%PROJECT_DIR%\import_product_daily.py"
|
||||
set "LOG_DIR=%PROJECT_DIR%\logs"
|
||||
|
||||
if not exist "%LOG_DIR%" mkdir "%LOG_DIR%"
|
||||
|
||||
REM yesterday's date (cmd has no date math, use PowerShell with usebackq to avoid quote conflict)
|
||||
for /f "usebackq" %%D in (`powershell -NoProfile -Command "(Get-Date).AddDays(-1).ToString('yyyy-MM-dd')"`) do set "YESTERDAY=%%D"
|
||||
|
||||
REM timestamp YYYYMMDD_HHMMSS
|
||||
set "STAMP=%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2%"
|
||||
set "STAMP=%STAMP: =0%"
|
||||
|
||||
set "LOG_FILE=%LOG_DIR%\daily_import_%STAMP%.log"
|
||||
|
||||
REM banner (ASCII only)
|
||||
echo [%date% %time:~0,8%] START daily import target_date=%YESTERDAY% log=%LOG_FILE%> "%LOG_FILE%"
|
||||
|
||||
cd /d "%PROJECT_DIR%"
|
||||
"%PY%" "%SCRIPT%" --date %YESTERDAY% >> "%LOG_FILE%" 2>&1
|
||||
set "EXIT_CODE=%ERRORLEVEL%"
|
||||
|
||||
echo [%date% %time:~0,8%] exit_code=%EXIT_CODE% >> "%LOG_FILE%"
|
||||
|
||||
REM keep 30 days of logs, delete older
|
||||
forfiles /p "%LOG_DIR%" /m "daily_import_*.log" /d -30 /c "cmd /c del @file" 2>nul
|
||||
|
||||
endlocal & exit /b %EXIT_CODE%
|
||||
@@ -0,0 +1,49 @@
|
||||
# run_daily_import.ps1
|
||||
# 每日 19:00 由 Windows Task Scheduler 触发。
|
||||
# 计算昨天的日期, 调 import_product_daily.py 入库, 日志落到 logs/。
|
||||
|
||||
$ErrorActionPreference = "Continue"
|
||||
$OutputEncoding = [System.Text.Encoding]::UTF8
|
||||
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'
|
||||
|
||||
$ProjectDir = $env:GYXX_RUNTIME_ROOT
|
||||
$LogDir = Join-Path $ProjectDir "logs"
|
||||
|
||||
if (-not (Test-Path $LogDir)) {
|
||||
New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
|
||||
}
|
||||
|
||||
$Stamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||||
$Yesterday = (Get-Date).AddDays(-1).ToString("yyyy-MM-dd")
|
||||
$LogFile = Join-Path $LogDir ("daily_import_" + $Stamp + ".log")
|
||||
|
||||
# 把 stdout/stderr 全部 >> 到日志 (用 cmd 重定向, 避免 PowerShell pipe 跟 Python 的编码冲突)
|
||||
@"
|
||||
[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] 启动每日导入 | 目标日期=$Yesterday | 日志=$LogFile
|
||||
"@ | Out-File -FilePath $LogFile -Encoding utf8 -Append
|
||||
|
||||
Set-Location $ProjectDir
|
||||
$Python = Join-Path $ProjectDir ".venv\Scripts\python.exe"
|
||||
$Script = Join-Path $ProjectDir "import_product_daily.py"
|
||||
|
||||
if (-not (Test-Path $Python)) {
|
||||
Add-Content -Path $LogFile -Value "[FATAL] 找不到 python: $Python" -Encoding utf8
|
||||
exit 2
|
||||
}
|
||||
if (-not (Test-Path $Script)) {
|
||||
Add-Content -Path $LogFile -Value "[FATAL] 找不到脚本: $Script" -Encoding utf8
|
||||
exit 2
|
||||
}
|
||||
|
||||
# 用 cmd 重定向 (2>&1 把 stderr 合并) - 兼容 Python 输出
|
||||
cmd /c "`"$Python`" `"$Script`" --date $Yesterday >> `"$LogFile`" 2>&1"
|
||||
$Exit = $LASTEXITCODE
|
||||
|
||||
Add-Content -Path $LogFile -Value "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] 退出码: $Exit" -Encoding utf8
|
||||
|
||||
# 保留 30 天日志, 删旧的
|
||||
Get-ChildItem -Path $LogDir -Filter "daily_import_*.log" |
|
||||
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-30) } |
|
||||
ForEach-Object { Remove-Item $_.FullName -Force }
|
||||
|
||||
exit $Exit
|
||||
@@ -0,0 +1,16 @@
|
||||
@echo off
|
||||
REM Daily 10:00 trigger -- 三平台人群画像并行采集 + 回填飞书表
|
||||
REM 天猫: collect_persona_to_bitable.py (达摩盘)
|
||||
REM 抖音: collect_dy_persona_to_bitable.py (罗盘成交人群)
|
||||
REM 京东: collect_jd_persona_to_bitable.py (商智人群画像)
|
||||
REM 三个脚本并行启动,各自独立写日志
|
||||
|
||||
setlocal
|
||||
cd /d %GYXX_RUNTIME_ROOT%
|
||||
|
||||
set "PY=%GYXX_RUNTIME_ROOT%\.venv\Scripts\python.exe"
|
||||
|
||||
if not exist data\logs mkdir data\logs
|
||||
|
||||
"%PY%" run_daily_persona.py >> data\logs\daily_persona_launcher.log 2>&1
|
||||
exit /b %ERRORLEVEL%
|
||||
@@ -0,0 +1,13 @@
|
||||
@echo off
|
||||
REM Runs independently every 3 days at 11:00. The analyzer defaults to yesterday
|
||||
REM as the window end, so each run covers the latest three complete calendar days.
|
||||
|
||||
setlocal
|
||||
cd /d %GYXX_RUNTIME_ROOT%
|
||||
|
||||
set "PY=%GYXX_RUNTIME_ROOT%\.venv\Scripts\python.exe"
|
||||
|
||||
if not exist data\logs mkdir data\logs
|
||||
|
||||
"%PY%" -u analyze_style_with_hermes.py --all-styles --days 3 --min-interval-days 3 --skip-existing >> data\logs\style_analysis_3d.log 2>&1
|
||||
exit /b %ERRORLEVEL%
|
||||
@@ -0,0 +1,12 @@
|
||||
@echo off
|
||||
REM Weekly JD main image pipeline. Keep this file ASCII-only for Task Scheduler.
|
||||
setlocal
|
||||
cd /d %GYXX_RUNTIME_ROOT%
|
||||
|
||||
set "PY=%GYXX_RUNTIME_ROOT%\.venv\Scripts\python.exe"
|
||||
set "PYTHONUNBUFFERED=1"
|
||||
|
||||
if not exist data\logs mkdir data\logs
|
||||
|
||||
"%PY%" -u run_weekly_jd_main_image.py --headless >> data\logs\weekly_jd_main_image.log 2>&1
|
||||
exit /b %ERRORLEVEL%
|
||||
@@ -0,0 +1,12 @@
|
||||
@echo off
|
||||
REM Weekly main image pipeline. Keep this file ASCII-only for Task Scheduler.
|
||||
setlocal
|
||||
cd /d %GYXX_RUNTIME_ROOT%
|
||||
|
||||
set "PY=%GYXX_RUNTIME_ROOT%\.venv\Scripts\python.exe"
|
||||
set "PYTHONUNBUFFERED=1"
|
||||
|
||||
if not exist data\logs mkdir data\logs
|
||||
|
||||
"%PY%" -u run_weekly_main_image.py --headless >> data\logs\weekly_main_image.log 2>&1
|
||||
exit /b %ERRORLEVEL%
|
||||
@@ -0,0 +1,14 @@
|
||||
@echo off
|
||||
REM Weekly Monday 10:00 -- collect TM/JD/DY market ranks, create Feishu docs,
|
||||
REM and archive each platform's latest document URL in PostgreSQL.
|
||||
|
||||
setlocal
|
||||
cd /d %GYXX_RUNTIME_ROOT%
|
||||
|
||||
set "PY=%GYXX_RUNTIME_ROOT%\.venv\Scripts\python.exe"
|
||||
set "PYTHONUNBUFFERED=1"
|
||||
|
||||
if not exist data\logs mkdir data\logs
|
||||
|
||||
"%PY%" orchestrate_market_rank_collection.py >> data\logs\market_rank_weekly.log 2>&1
|
||||
exit /b %ERRORLEVEL%
|
||||
Reference in New Issue
Block a user