From 7713cfeb9e2efa38a286bd8d50b931a01a204e22 Mon Sep 17 00:00:00 2001 From: XuJiacheng Date: Tue, 24 Mar 2026 08:34:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20G5=20=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E8=A1=A8=E5=90=8C=E6=AD=A5=E5=BC=80=E5=85=B3=EF=BC=8C?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=85=B3=E9=97=AD=E5=86=99=E5=85=A5=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=B9=B6=E6=9B=B4=E6=96=B0=E7=9B=B8=E5=85=B3=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=92=8C=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bls-onoffline-backend/.env | 4 ++++ bls-onoffline-backend/.env.example | 4 ++++ .../proposal.md | 13 ++++++++++++ .../specs/onoffline/spec.md | 14 +++++++++++++ .../tasks.md | 11 ++++++++++ .../openspec/specs/onoffline/spec.md | 13 ++++++++++++ bls-onoffline-backend/src/config/config.js | 7 +++++++ bls-onoffline-backend/src/index.js | 20 +++++++++++++------ 8 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 bls-onoffline-backend/openspec/changes/archive/2026-03-18-add-g5-room-status-sync-toggle/proposal.md create mode 100644 bls-onoffline-backend/openspec/changes/archive/2026-03-18-add-g5-room-status-sync-toggle/specs/onoffline/spec.md create mode 100644 bls-onoffline-backend/openspec/changes/archive/2026-03-18-add-g5-room-status-sync-toggle/tasks.md diff --git a/bls-onoffline-backend/.env b/bls-onoffline-backend/.env index 889fe71..78d14f4 100644 --- a/bls-onoffline-backend/.env +++ b/bls-onoffline-backend/.env @@ -49,3 +49,7 @@ REDIS_PASSWORD= REDIS_DB=15 REDIS_CONNECT_TIMEOUT_MS=5000 REDIS_PROJECT_NAME=bls-onoffline + +# G5 room_status.moment sync +# false: do not write room_status.room_status_moment_g5 +G5_ROOM_STATUS_MOMENT_SYNC_ENABLED=false diff --git a/bls-onoffline-backend/.env.example b/bls-onoffline-backend/.env.example index d716cb7..7ef71bc 100644 --- a/bls-onoffline-backend/.env.example +++ b/bls-onoffline-backend/.env.example @@ -29,3 +29,7 @@ REDIS_PASSWORD= REDIS_DB=0 REDIS_PROJECT_NAME=bls-onoffline REDIS_API_BASE_URL=http://localhost:3001 + +# G5 room_status.moment sync +# false: do not write room_status.room_status_moment_g5 +G5_ROOM_STATUS_MOMENT_SYNC_ENABLED=false diff --git a/bls-onoffline-backend/openspec/changes/archive/2026-03-18-add-g5-room-status-sync-toggle/proposal.md b/bls-onoffline-backend/openspec/changes/archive/2026-03-18-add-g5-room-status-sync-toggle/proposal.md new file mode 100644 index 0000000..90dd378 --- /dev/null +++ b/bls-onoffline-backend/openspec/changes/archive/2026-03-18-add-g5-room-status-sync-toggle/proposal.md @@ -0,0 +1,13 @@ +# Change: add g5 room status sync toggle + +## Why +当前 G5 `room_status.room_status_moment_g5` 同步是默认启用的,但新的运行要求需要默认关闭,避免未经确认就写入状态表。 + +## What Changes +- 新增一个环境变量开关,控制是否同步写入 G5 `room_status.room_status_moment_g5`。 +- 默认值为 `false`,即不写入该表。 +- 当开关开启时,保留现有按 `hotel_id + room_id` upsert 更新 `ip` 的行为。 + +## Impact +- Affected specs: `openspec/specs/onoffline/spec.md` +- Affected code: `src/config/config.js`, `src/index.js`, `.env`, `.env.example` diff --git a/bls-onoffline-backend/openspec/changes/archive/2026-03-18-add-g5-room-status-sync-toggle/specs/onoffline/spec.md b/bls-onoffline-backend/openspec/changes/archive/2026-03-18-add-g5-room-status-sync-toggle/specs/onoffline/spec.md new file mode 100644 index 0000000..82b156d --- /dev/null +++ b/bls-onoffline-backend/openspec/changes/archive/2026-03-18-add-g5-room-status-sync-toggle/specs/onoffline/spec.md @@ -0,0 +1,14 @@ +## ADDED Requirements + +### Requirement: G5 状态表同步开关 +系统 SHALL 提供一个环境变量开关,用于控制是否向 G5 状态表 `room_status.room_status_moment_g5` 写入数据;该开关默认值 SHALL 为 `false`。 + +#### Scenario: 默认关闭 +- **GIVEN** 未设置 G5 状态表同步开关 +- **WHEN** 服务启动并处理 Kafka 消息 +- **THEN** 系统不向 `room_status.room_status_moment_g5` 写入数据 + +#### Scenario: 显式开启 +- **GIVEN** G5 状态表同步开关被设置为 `true` +- **WHEN** 服务处理 Kafka 消息 +- **THEN** 系统恢复向 `room_status.room_status_moment_g5` 写入数据 diff --git a/bls-onoffline-backend/openspec/changes/archive/2026-03-18-add-g5-room-status-sync-toggle/tasks.md b/bls-onoffline-backend/openspec/changes/archive/2026-03-18-add-g5-room-status-sync-toggle/tasks.md new file mode 100644 index 0000000..69b76d4 --- /dev/null +++ b/bls-onoffline-backend/openspec/changes/archive/2026-03-18-add-g5-room-status-sync-toggle/tasks.md @@ -0,0 +1,11 @@ +## 1. Implementation +- [x] 1.1 Add a config flag for G5 room_status synchronization. +- [x] 1.2 Disable `room_status.room_status_moment_g5` writes by default. +- [x] 1.3 Keep the existing upsert behavior when the flag is enabled. +- [x] 1.4 Update environment samples to set the flag to `false`. + +## 2. Validation +- [x] 2.1 Run `npm run lint`. +- [x] 2.2 Run `npm run test`. +- [x] 2.3 Run `npm run build`. +- [x] 2.4 Run `openspec validate add-g5-room-status-sync-toggle --strict`. diff --git a/bls-onoffline-backend/openspec/specs/onoffline/spec.md b/bls-onoffline-backend/openspec/specs/onoffline/spec.md index 31c6ffd..eac982f 100644 --- a/bls-onoffline-backend/openspec/specs/onoffline/spec.md +++ b/bls-onoffline-backend/openspec/specs/onoffline/spec.md @@ -106,3 +106,16 @@ - **WHEN** 服务处理该错误 - **THEN** 服务记录错误并按既有错误处理机制处理,不在运行时执行分区创建 +### Requirement: G5 状态表同步开关 +系统 SHALL 提供一个环境变量开关,用于控制是否向 G5 状态表 `room_status.room_status_moment_g5` 写入数据;该开关默认值 SHALL 为 `false`。 + +#### Scenario: 默认关闭 +- **GIVEN** 未设置 G5 状态表同步开关 +- **WHEN** 服务启动并处理 Kafka 消息 +- **THEN** 系统不向 `room_status.room_status_moment_g5` 写入数据 + +#### Scenario: 显式开启 +- **GIVEN** G5 状态表同步开关被设置为 `true` +- **WHEN** 服务处理 Kafka 消息 +- **THEN** 系统恢复向 `room_status.room_status_moment_g5` 写入数据 + diff --git a/bls-onoffline-backend/src/config/config.js b/bls-onoffline-backend/src/config/config.js index 1669d9f..6569d8c 100644 --- a/bls-onoffline-backend/src/config/config.js +++ b/bls-onoffline-backend/src/config/config.js @@ -13,6 +13,12 @@ const parseList = (value) => .map((item) => item.trim()) .filter(Boolean); +const parseBoolean = (value, defaultValue) => { + if (value === undefined || value === null || value === '') return defaultValue; + if (typeof value === 'boolean') return value; + return value === 'true' || value === '1'; +}; + export const config = { env: process.env.NODE_ENV || 'development', port: parseNumber(process.env.PORT, 3001), @@ -51,6 +57,7 @@ export const config = { }, g5db: { enabled: !!process.env.POSTGRES_HOST_G5, + roomStatusMomentSyncEnabled: parseBoolean(process.env.G5_ROOM_STATUS_MOMENT_SYNC_ENABLED, false), host: process.env.POSTGRES_HOST_G5, port: parseNumber(process.env.POSTGRES_PORT_G5, 5434), user: process.env.POSTGRES_USER_G5, diff --git a/bls-onoffline-backend/src/index.js b/bls-onoffline-backend/src/index.js index ee87906..14b7ff7 100644 --- a/bls-onoffline-backend/src/index.js +++ b/bls-onoffline-backend/src/index.js @@ -21,6 +21,10 @@ const bootstrap = async () => { database: config.db.database, schema: config.db.schema }, + g5db: { + enabled: config.g5db.enabled, + roomStatusMomentSyncEnabled: config.g5db.roomStatusMomentSyncEnabled + }, kafka: { brokers: config.kafka.brokers, topic: config.kafka.topic, @@ -183,9 +187,11 @@ const bootstrap = async () => { promises.push(g5DbManager.insertRows({ schema: config.g5db.schema, table: config.g5db.table, rows }).catch(e => { logger.error('G5 Database insert failed but non-blocking', { error: e.message }); })); - promises.push(g5DbManager.upsertRoomStatusMomentIp(rows).catch(e => { - logger.error('G5 room_status_moment_g5 upsert failed but non-blocking', { error: e.message }); - })); + if (config.g5db.roomStatusMomentSyncEnabled) { + promises.push(g5DbManager.upsertRoomStatusMomentIp(rows).catch(e => { + logger.error('G5 room_status_moment_g5 upsert failed but non-blocking', { error: e.message }); + })); + } } await Promise.all(promises); @@ -216,9 +222,11 @@ const bootstrap = async () => { promises.push(g5DbManager.insertRows({ schema: config.g5db.schema, table: config.g5db.table, rows }).catch(e => { logger.error('G5 Database insert failed in insertOnce', { error: e.message }); })); - promises.push(g5DbManager.upsertRoomStatusMomentIp(rows).catch(e => { - logger.error('G5 room_status_moment_g5 upsert failed in insertOnce', { error: e.message }); - })); + if (config.g5db.roomStatusMomentSyncEnabled) { + promises.push(g5DbManager.upsertRoomStatusMomentIp(rows).catch(e => { + logger.error('G5 room_status_moment_g5 upsert failed in insertOnce', { error: e.message }); + })); + } } await Promise.all(promises); metricCollector.increment('db_insert_count', 1);