修復市場情報 writer CLI lazy import
All checks were successful
CD Pipeline / deploy (push) Successful in 1m22s

This commit is contained in:
OoO
2026-05-19 14:01:38 +08:00
parent 934366bdd3
commit d504ddac51
5 changed files with 54 additions and 6 deletions

View File

@@ -19,11 +19,11 @@ if str(REPO_ROOT) not in sys.path:
sys.path.insert(0, str(REPO_ROOT))
with contextlib.redirect_stdout(sys.stderr):
from services.market_intel import MarketIntelService # noqa: E402
from services.market_intel.candidate_queue_review_decision_writer_cli import ( # noqa: E402
APPROVAL_ENV_VAR,
build_candidate_queue_review_decision_writer_cli_plan,
)
from services.market_intel.phase import MARKET_INTEL_PHASE # noqa: E402
def parse_args(argv=None):
@@ -71,7 +71,6 @@ def _load_transaction_preview(path):
def main(argv=None):
args = parse_args(argv)
service = MarketIntelService()
plan = build_candidate_queue_review_decision_writer_cli_plan(
transaction_preview=_load_transaction_preview(args.transaction_json),
execute_requested=args.execute,
@@ -81,7 +80,7 @@ def main(argv=None):
backup_verified=args.backup_verified,
review_inventory_smoke_passed=args.review_inventory_smoke_passed,
)
plan["phase"] = service.phase
plan["phase"] = MARKET_INTEL_PHASE
print(json.dumps(plan, ensure_ascii=False, indent=2, sort_keys=True))
return int(plan.get("exit_code", 2))

View File

@@ -1,5 +1,17 @@
"""跨平台市場情報服務模組。"""
from services.market_intel.service import MarketIntelService, MarketIntelRuntimeStatus
__all__ = ["MarketIntelService", "MarketIntelRuntimeStatus"]
def __getattr__(name):
if name in __all__:
from services.market_intel.service import (
MarketIntelRuntimeStatus,
MarketIntelService,
)
return {
"MarketIntelService": MarketIntelService,
"MarketIntelRuntimeStatus": MarketIntelRuntimeStatus,
}[name]
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

View File

@@ -0,0 +1,3 @@
"""市場情報 rollout phase 單一來源。"""
MARKET_INTEL_PHASE = "phase_69_candidate_queue_review_decision_writer_cli"

View File

@@ -66,6 +66,7 @@ from services.market_intel.opportunity_scoring import (
)
from services.market_intel.platform_seed import build_platform_seed_rows
from services.market_intel.platform_seed_db_diff import build_platform_seed_db_diff_plan
from services.market_intel.phase import MARKET_INTEL_PHASE
from services.market_intel.scheduler_plan import build_scheduler_attach_plan
from services.market_intel.platform_seed_writer import (
build_platform_seed_writer_plan,
@@ -108,7 +109,7 @@ class MarketIntelRuntimeStatus:
class MarketIntelService:
"""市場情報入口服務,先集中 feature gate 與安全狀態。"""
phase = "phase_69_candidate_queue_review_decision_writer_cli"
phase = MARKET_INTEL_PHASE
def get_runtime_status(self) -> MarketIntelRuntimeStatus:
return MarketIntelRuntimeStatus(

View File

@@ -7698,3 +7698,36 @@ def test_candidate_queue_writer_cli_script_outputs_blocked_gate(tmp_path):
assert data["scheduler_attached"] is False
assert data["transaction_preview_summary"]["statement_count"] == 1
assert "execute_requested" in data["blocked_reasons"]
def test_review_decision_writer_cli_script_outputs_blocked_gate_without_login_env():
env = {
key: value
for key, value in os.environ.items()
if key not in {"LOGIN_PASSWORD", "SECRET_KEY"}
}
result = subprocess.run(
[sys.executable, "scripts/market_intel_review_decision_writer.py"],
capture_output=True,
check=False,
env=env,
text=True,
)
data = json.loads(result.stdout)
assert result.returncode == 0
assert data["mode"] == "candidate_queue_review_decision_writer_cli_blocked"
assert data["phase"] == "phase_69_candidate_queue_review_decision_writer_cli"
assert data["execute_requested"] is False
assert data["apply_real_write_requested"] is False
assert data["approval_token_present"] is False
assert data["writer_implementation_enabled"] is False
assert data["ready_for_real_write"] is False
assert data["api_executes_cli"] is False
assert data["api_reads_approval_token"] is False
assert data["database_connection_opened"] is False
assert data["database_write_executed"] is False
assert data["database_commit_executed"] is False
assert data["scheduler_attached"] is False
assert data["writes_executed"] is False
assert data["exit_code"] == 0