プロジェクト

全般

プロフィール

機能 #10519

未完了

[VEND-V2-06] 競合3社診断ジョブ・レート制限・コスト制御

Redmine Admin さんが12日前に追加. 10日前に更新.

ステータス:
進行中
優先度:
通常
担当者:
-
開始日:
2026-07-27
期日:
進捗率:

0%

予定工数:
自動実行:
from_agent:
to_agent:
lock_required:
context_json:
session_id:
priority_custom:
start_time:
end_time:
execution_time:
acceptance_criteria:
assigned_role:
human_gate:
gate_type:
chain_root_id:
wave_id:

説明

親: #10516
依存: #10518 検索API資格情報

目的

対象1社+競合3社の診断を同期HTTPで長時間実行せず、版付きジョブとして安全に処理する。

要件

  • 競合候補検索とAIO診断を非同期ジョブ化
  • 1ジョブ最大3競合、同一domain重複排除
  • IP/session単位レート制限、同一URL再利用、結果キャッシュ
  • LLM呼出数・検索API呼出数・実行時間の上限
  • status: queued/running/completed/partial/failed
  • 個別競合失敗でもpartial結果を返す
  • SSRF、redirect再検証、prompt injection対策を全URLへ適用
  • worker concurrencyを制限
  • API key、raw HTML、検索provider内部情報を公開しない
  • 比較時は同じrubric versionを固定
  • 旧rubric結果を混在させない
  • 検索日時、検索語、provider、候補順位、除外理由を保存

表示

  • 検索条件に基づく比較対象と明記
  • 市場順位・シェア・業界トップとは表現しない
  • 会社名/公式URL/総合点/6軸差分
  • 競合共通対策、自社のみ未対応、自社優位

完了条件

  • 負荷・コスト上限試験
  • ジョブ再開/失敗/partial試験
  • E2Eとセキュリティレビュー
  • 運用監視・停止スイッチ

Redmine Admin さんが12日前に更新

  • ステータス新規 から 進行中 に変更

着手。検索API資格情報なしで実装可能な基盤を先行する。競合比較ジョブ、最大3社、同一rubric固定、レート制限、URL重複排除、結果キャッシュ、partial failure、停止スイッチを実装する。検索候補取得はprovider interfaceとして分離し、資格情報接続後に統合する。

Redmine Admin さんが12日前に更新

フェーズ1を本番反映。

実装:

  • disabled-by-default /v2/competitor-jobs POST/GET基盤
  • competitor_jobs / competitor_job_itemsテーブル・indexを冪等作成
  • target診断はschema2.4/rubric2026.5、利用者入力の業種+エリア必須
  • 手動競合URL 1〜3件、URL正規化、対象/競合同士の同一registrable domainを拒否
  • 生IP非保存。HMAC-SHA256 requester hashのみ保存
  • DBベース rate limit: requester 3件/時、target 2件/時
  • target/rubric/sorted URL集合のcompleted/partialを24時間cache
  • public responseからrequester hash/cache key/internal情報を除外
  • feature flag falseまたは32文字未満secretで503

検証:

  • Node20 backend全36件合格
  • DB integrity ok、V1/V2保持
  • 公開POSTはfeature_unavailable 503(機能停止状態)
  • API healthy
  • source commit 1deaa41
  • image be0180cfff5b
  • backup /root/backup/website-vending-machine/20260727-1315-10519-phase1

未完:

  • FIFO runner、診断再利用、partial/all-fail、再起動回復
  • 検索API接続
    機能は有効化していない。

Redmine Admin さんが12日前に更新

進捗: 2026-07-27 JST #10519 phase1本番反映。disabled-by-default競合ジョブAPI、competitor_jobs/items、IP HMAC、1h rate limit requester3/target2、24h cache、manual competitor URLs max3、registrable domain重複排除、schema2.4/rubric2026.5固定対象検証。Node20 backend36/36、DB integrity、公開503 disabled、API healthy。source 1deaa41、image be0180cfff5b、backup 20260727-1315-10519-phase1。次はFIFO runner、診断再利用、partial/all-fail、restart recovery。全体進捗55%。

Redmine Admin さんが11日前に更新

フェーズ2を本番反映。

実装:

  • process-wide concurrency 1
  • FIFO処理。同一秒作成時はDB rowidで挿入順を保証
  • 競合URLを逐次診断
  • target site_contextを完全一致で再利用
  • 同一URL/rubric/site_contextの正常診断を24時間再利用
  • completed / partial / failed集約
  • 個別エラーをinvalid_url/not_crawlable/robots_blocked/timeout/diagnosis_failedへ限定
  • 内部例外文を公開・保存しない
  • rubric不一致時は診断を実行せずfailed
  • 起動時runningをqueuedへ戻す
  • feature disabled時は再キューのみで実行しない
  • target欠損時もGET public shapeを維持

検証:

  • Node20 backend全45件合格
  • independent review approve
  • site_context完全一致引き継ぎ試験
  • FIFO競合試験で同時刻順序バグを検出・修正
  • DB integrity ok、running job 0
  • 公開APIはfeature_unavailable 503のまま
  • API healthy、ログ異常なし
  • source 0607b97
  • image 91d3eb2f42eb
  • backup /root/backup/website-vending-machine/20260728-0718-10519-phase2

残作業:

  • 有効化前のsecret設定と限定E2E
  • 検索API接続 #10518
  • 自動候補取得と比較UI #10516

Redmine Admin さんが11日前に更新

進捗: 2026-07-28 JST #10519 phase2本番反映。競合ジョブFIFO単一並列、逐次診断、target site_context完全継承、同一URL/rubric/context正常診断24h再利用、completed/partial/failed、generic error only、rubric mismatch fail-fast、running->queued再起動回復、disabled時非実行。FIFO同時刻バグをrowid tie-breakで修正。Node20 backend45/45、review approve、DB integrity、public503 disabled、API healthy。source 0607b97、image 91d3eb2f42eb、backup 20260728-0718-10519-phase2。全体進捗60%。

Redmine Admin さんが10日前に更新

Node 22移行とAPIセキュリティ強化を本番反映しました。

実施内容:

  • Node 22.22.0 / npm 10へ移行
  • node:22.22.0-bookworm-slimへ変更
  • better-sqlite3 11.3.0互換性確認
  • CSP / nosniff / frame-ancestors / Referrer-Policy / Permissions-Policy
  • CORS完全一致、Origin/Referer検証、application/json強制によるCSRF/XSRF対策
  • XSS、CRLF、NUL、ディレクトリトラバーサル、二重エンコード、危険スキーム対策
  • SSRF、DNS解決後検証、リダイレクト再検証
  • 競合検索結果・検索語のサニタイズ
  • プロンプトインジェクション境界と16KB制限
  • 外部API/内部例外の固定エラーコード化
  • インメモリレート制限

検証:

  • Backend 59/59 PASS
  • Frontend 31/31 PASS
  • 合計90/90 PASS
  • 本番DBコピー integrity_check=ok、既存テーブル8
  • 本番コンテナ healthy、Node v22.22.0
  • 公開health HTTP 200
  • evil Origin 403
  • text/plain POST 415
  • 正規OPTIONS 204
  • 競合検索は機能フラグOFFのため503を維持

コミット: 87d4759, a6522c5, d5d403a, cd90a63, 1cf1340
master: 73cef94

Redmine Admin さんが10日前に更新

進捗: 2026-07-29 Node 22移行とAPIセキュリティ強化を本番反映。Backend 59/59、Frontend 31/31、合計90/90 PASS。本番DBコピー integrity_check=ok、既存テーブル8。vend01-apiはNode v22.22.0でhealthy。公開経路でhealth 200、evil Origin 403、非JSON POST 415、正規OPTIONS 204、競合検索は機能フラグOFFで503維持。master 73cef94。バックアップ: /root/backups/vend01-node22-security-20260729-065459。

Redmine Admin さんが10日前に更新

基盤強化を本番反映。Node 22.22.0へ移行し、競合ジョブ/検索を含むAPIにsame-origin+allowlist Origin検証、JSON強制、レート制限、CRLF/NUL/traversal/XSS入力検証、private/link-local/metadata URL拒否、プロンプトインジェクション境界、固定エラーコードを適用。backend 61/61、frontend 31/31 PASS。公開health 200、DB integrity ok。関連チケット #10556。競合検索機能フラグは引き続き既定OFFで、SearXNG本接続は別工程。

Redmine Admin さんが10日前に更新

SearXNG provider本接続を本番反映(commit 12c99ab)。正式env: COMPETITOR_SEARCH_PROVIDER / SEARXNG_BASE_URL、旧SEARCH_PROVIDER / SEARXNG_ENDPOINTは後方互換。VPS・Node22コンテナからTailnet SearXNG http://100.64.0.2:8888 へJSON検索HTTP 200確認。Content-Type、1MiB、15秒timeout、429/5xx/invalid JSON固定エラー、検索語/結果サニタイズ、private URL拒否、NFKC正規化、一覧・ランキング・比較記事および既知ポータル除外を実装。検索監査metadata(provider/searched_at/query/source_rank/採否理由)をnullable列search_metadata_jsonへ保存可能にし、既存DB migration integrity=ok。テスト backend 77/77、frontend 31/31、計108/108 PASS。公開health 200、コンテナhealthy、Node v22.22.0。COMPETITOR_SEARCH_ENABLED=falseを維持し、公開候補APIは503 feature_unavailable。endpoint/API keyはレスポンス・監査情報へ非公開。バックアップ: /root/backups/vend01-searxng-release-20260729-075956。候補品質は横浜制作で誤候補を返さず0件、大阪工務店で公式候補1件を確認。次工程はフロント候補選択UI/E2Eと限定的な機能ON判定。

Redmine Admin さんが10日前に更新

競合候補選択UIと検索→選択→競合診断ジョブE2Eを本番反映(commit 9dab02f)。UIは診断結果内で候補検索、1〜3件選択、ジョブ作成、queued/running/completed/partial/failed表示、最大2分poll、対象/競合スコア表示に対応。search_metadataはJSメモリ内のみ保持。安全DOM、外部リンクnoopener、strict response normalize、canonical lowercase UUIDv4検証を実装。バックエンドのGET /competitor-jobs/:idがUUIDを拒否していた不具合も修正。各poll GETは15秒Abort、全体120秒上限。古いタイマー/レスポンスが新規処理へ干渉しないrunId+controller identity対策を実装。テスト backend 79/79、frontend 36/36、計115/115 PASS。隔離E2E: SearXNG候補200→job 202→UUID GET 200→frontend normalize成功。Codex最終レビュー APPROVE。本番はCOMPETITOR_SEARCH_ENABLED=falseを維持し、公開APIは503 feature_unavailable。公開HTML/JS更新、health 200、DB integrity ok。バックアップ: /root/backups/vend01-competitor-ui-release-20260729-093317。

他の形式にエクスポート: Atom PDF