/** * WPML compatibility functions * * @global array $duplicated_posts Array to store the posts being duplicated. * * @package Yoast\WP\Duplicate_Post * @since 3.2 */ add_action( 'admin_init', 'duplicate_post_wpml_init' ); /** * Add handlers for WPML compatibility. */ function duplicate_post_wpml_init() { if ( defined( 'ICL_SITEPRESS_VERSION' ) ) { add_action( 'dp_duplicate_page', 'duplicate_post_wpml_copy_translations', 10, 3 ); add_action( 'dp_duplicate_post', 'duplicate_post_wpml_copy_translations', 10, 3 ); add_action( 'shutdown', 'duplicate_wpml_string_packages', 11 ); } } global $duplicated_posts; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: Renaming a global variable is a BC break. $duplicated_posts = []; /** * Copy post translations. * * @global SitePress $sitepress Instance of the Main WPML class. * @global array $duplicated_posts Array of duplicated posts. * * @param int $post_id ID of the copy. * @param WP_Post $post Original post object. * @param string $status Status of the new post. */ function duplicate_post_wpml_copy_translations( $post_id, $post, $status = '' ) { global $sitepress; global $duplicated_posts; remove_action( 'dp_duplicate_page', 'duplicate_post_wpml_copy_translations', 10 ); remove_action( 'dp_duplicate_post', 'duplicate_post_wpml_copy_translations', 10 ); $current_language = $sitepress->get_current_language(); $trid = $sitepress->get_element_trid( $post->ID ); if ( ! empty( $trid ) ) { $translations = $sitepress->get_element_translations( $trid ); $new_trid = $sitepress->get_element_trid( $post_id ); foreach ( $translations as $code => $details ) { if ( $code !== $current_language ) { if ( $details->element_id ) { $translation = get_post( $details->element_id ); if ( ! $translation ) { continue; } $new_post_id = duplicate_post_create_duplicate( $translation, $status ); if ( ! is_wp_error( $new_post_id ) ) { $sitepress->set_element_language_details( $new_post_id, 'post_' . $translation->post_type, $new_trid, $code, $current_language ); } } } } // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: see above. $duplicated_posts[ $post->ID ] = $post_id; } } /** * Duplicate string packages. * * @global array() $duplicated_posts Array of duplicated posts. */ function duplicate_wpml_string_packages() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: renaming the function would be a BC-break. global $duplicated_posts; foreach ( $duplicated_posts as $original_post_id => $duplicate_post_id ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. $original_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $original_post_id ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. $new_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $duplicate_post_id ); if ( is_array( $original_string_packages ) ) { foreach ( $original_string_packages as $original_string_package ) { $translated_original_strings = $original_string_package->get_translated_strings( [] ); foreach ( $new_string_packages as $new_string_package ) { $cache = new WPML_WP_Cache( 'WPML_Package' ); $cache->flush_group_cache(); $new_strings = $new_string_package->get_package_strings(); foreach ( $new_strings as $new_string ) { if ( isset( $translated_original_strings[ $new_string->name ] ) ) { foreach ( $translated_original_strings[ $new_string->name ] as $language => $translated_string ) { do_action( // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. 'wpml_add_string_translation', $new_string->id, $language, $translated_string['value'], $translated_string['status'] ); } } } } } } } } ローカル再開の手順(Dev-Portal / K8s) – Raqqa

ローカル再開の手順(Dev-Portal / K8s)

1) Git を最新化(※コマンドは今回は書かない)

  • 目的:ローカル作業ディレクトリを 最新main(または指定ブランチ)に揃える
  • 注意:未コミット変更がある場合は、退避(stash)or 別ブランチへ退避してから更新

2) Minikube / Kubernetes を起動

  • Minikube プロファイルを決めて起動(あなたの運用に合わせる)
  • ingress-nginx が必要なら有効化
  • 既存の namespace / リソースが残っている場合は、まず状態確認(Pod/Service/Ingress)

3) kustomize で Dev 環境をデプロイ

  • 対象:k8s/overlays/dev
  • 反映内容(あなたが貼ったものの前提)
    • portal-dev namespace
    • portal-api Deployment + Service + Ingress
    • Postgres(devportal用)
    • Chroma(search/upsert用)
    • Odoo(別ns運用でもOK、同一overlayでもOK)

4) 起動確認(最低限)

  • portal-api が Ready になること
    • /healthz
    • /health/ready(DB疎通)
  • postgres が Ready になること(devportal DB)
  • chroma の heartbeat が通ること(任意だが後で必要)
  • odoo が起動して Web に到達できること(後続のSQL実行テストで必要)

5) ポートフォワード / hosts(必要なら)

  • portal-api/docs を開ける状態にする
  • odoo のUIにアクセスできる状態にする
  • Ingress を使う場合は hosts の確認(odoo.local / api.local など)

Dev-Portal 開発内容(今回のスコープ)

A. Odoo DB へ “直接SQL実行” を可能にする(最優先)

目的:Dev-Portal が Odoo の Postgres に接続して SELECT を実行し、結果を返せるようにする

  • portal-api の env に Odoo DB 接続情報を追加
    • ODOO_DATABASE_URL(最短)
    • もしくは ODOO_DB_HOST/PORT/NAME/USER/PASSWORD から組み立て
  • K8s 上で portal-api Pod から Odoo DB へ疎通確認
    • SELECT 1
    • information_schema 参照
    • Odooテーブル(例:res_partner)の参照

B. /sql/execute_params を Dev-Portal 側で実装(I/F固定)

目的sql_params(opaque)を受け取り、SQLを生成して Odoo DB からデータ抽出し返す

処理フロー(確定版)

  1. sql_params を受け取る(中身は解釈するが nlq-dev 側は触らない)
  2. **Chroma(カスタム)**で補助情報検索(fields/view_common など)
  3. **LLM(Odoo標準)**で SQL を組み立て
  4. sql_guard を適用(SELECT-only / 1 statement / LIMIT など)
  5. Odoo DB に SQL を投げる(read-only)
  6. columns/rows/row_count/executed_sql を返す
    • executed_sql は参考情報として返却OK

C. Chroma 周りのバグ修正(今回やる)

  • すでにあなたが指定:api/app/services/chroma_query.py 修正済み(全文を反映)
  • (可能なら)collection を “検索で勝手に作らない” 方針に統一
  • SQL fallback(portal_chroma_doc 検索)が落ちても全体は継続するように維持

D. 一連のパイプラインを dev 環境で通しテスト(本番前の確認)

目的:本番に渡す前に「doc生成→Chroma upsert→検索→SQL生成→実行→返却」まで通す

  • portal_chroma_docqueued が作られる(package)
  • chroma_upsertqueued → upserted になる
  • chroma_query / search で hits が返る
  • /sql/execute_params が結果セットを返せる

今この時点で “追加で必要になる可能性が高い情報”

(起動してから確認できるので、今は保留でOK)

  • Odoo DB の実体(host/namespace/DB名)が dev overlay と一致しているか
  • Odoo の代表テーブル(例:res_partner)に実データが入っているか
  • Chroma collection 名(portal_field_ja, portal_view_common_ja)が実際に存在するか
  • OpenAI API Key が dev で使えるか(embedding + LLM)

Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です