BeMart

20260610 Web+DB follow-ups

20260610 Web+DB follow-ups

20260610-web-db-all-routes で fail として残した項目です。ここにあるものは、runner側で成功扱いにするのではなく、先に Hypermedia/HTTP workflow へ戻してから実装修正・ブラウザ再検証を行います。

完成判定の恒久ルールは completion-evidence-rules.md を正とします。この follow-up は日付付きの事実、未解決境界、自信のない箇所を残す台帳です。

現在の完成判定

止める基準

自信がない/証拠不足として残す箇所

次の項目は、現時点で「作れば通る」実装をしてはいけない。標準の Hypermedia/HTTP workflow に戻せる証拠を集められない場合は、fail または targetOut として残して止める。

調査済みだが採用しなかった回避策

Follow-up groups

Test harness / suite reliability

vendor/bin/phpunit --testsuite hypermedia は、2026-06-10 の follow-up 修正後に green。旧状態では assertion failure ではなく PHP process の異常終了で止まっていた。

確認済み:

修正済み:

現時点で targeted Hypermedia/HTTP suite reliability と Composer full suite の未解決項目はない。残る follow-up は Web+DB browser/HTTP 側の未実行 Admin unsafe operations、Admin 404 screen/action、SQL-backed Resource suite restoration、HTML link audit warning の整理。

Full PHPUnit / PDF memory boundary

Raw vendor/bin/phpunit --no-progress は、2026-06-10 の follow-up 修正後も green ではない。停止箇所は tests/Hypermedia/FlowAdminOrderFulfillmentTest.php:247 の goExportOrderPdf で、TCPDF が vendor/tecnickcom/tcpdf/fonts/cid0jp.php を読み込む途中に Allowed memory size of 134217728 bytes exhausted で PHP process が終了した。

ただし composer.json の既存 test script は php -d memory_limit=512M ./vendor/bin/phpunit を project test contract として定義している。この契約では composer test -- --no-progress が green(1935 tests, 27375 assertions)で完了したため、現時点では PDF renderer の実装変更は行わない。

確認済み:

未確認:

禁止する回避:

Full suite green でも BEAR.Dev.HtmlLinkAudit warning は多数出力される。主な reason は target-missing と html-missing。これは今回の green 判定では failure ではないが、Hypermedia 完成判定では無視し続けるべきではない。

扱い方:

SQL-backed Resource suite restoration

tests/Resource/Sql/WithdrawResourceSqlTest.php の直接実行では、既存の SqlFixturesTrait 定義がこの worktree で見つからず PHPUnit bootstrap 前に停止する。さらに AbstractResourceSqlTestCase が前提にする be/tests/Sql/bootstrap.php も現 worktree に存在しない。

確認済み:

この suite は Web+DB 完成判定の主証跡ではなく、SQL-backed Resource の境界テストである。直接 SQL fixture はここでは許容されうるが、Hypermedia/HTTP/browser の業務状態作成には使わない。

復元する場合の最小方針:

  1. be/tests/Sql/bootstrap.php を履歴から戻し、現 AbstractResourceSqlTestCase が期待する ['skip' => bool, 'reason'?, 'pdo'?] shape に合わせる。
  2. SqlFixturesTrait は履歴版をベースに、現 tests/Resource/Sql が使う helper だけを schema/FK/NOT NULL に沿って復元する。空実装・固定dummy戻り値は禁止。
  3. phpunit.xml / composer test:sql / sql/README.md の suite 名と skip/fail 方針を揃える。
  4. Final-direct integration の再導入は G-23 の方針と衝突しうるため、Resource SQL 復元とは別PRで判断する。

Admin catalog / master CRUD

対象: カテゴリ、タグ、規格、規格分類、商品規格、CSV取込。

商品作成、詳細 readback、編集、コピー、一括公開状態変更、削除は 2026-06-10 product follow-up で green。商品/カテゴリ/規格/規格分類CSV取込は 2026-06-11 follow-up で multipart upload と readback まで green。残る商品系は商品規格編集。

カテゴリ作成/編集/削除、タグ作成/削除、規格作成/編集/削除、規格分類作成/編集/削除は Hypermedia/HTTP と browser setup evidence の両方で green。操作URLは一覧/詳細の form action、Location、削除 anchor/token から取得し、作成/更新後の readback と削除後の一覧非表示を確認した。

残る商品カタログ系は商品規格編集。商品CSV取込、カテゴリCSV取込、規格CSV取込、規格分類CSV取込は 2026-06-11 admin CSV follow-up で、ブラウザでフォームとCSRFを取得し、multipart upload後に一覧/readbackで結果を確認済み。

商品規格編集は現状で止める。src/Resource/Page/Admin/Product/ProductClass.php は onGet() のみで、template は POST /admin/product/product-class を出しているが、Resource/OpenAPI 上の保存 transition は PUT /admin/product/product-class として未実装。Be 側にも UpdateProductClassInput / ProductClassUpdated は存在しない。ここで runner 専用の直PUTや空のFinalを作ると、商品規格の本質である class-name/class-category -> price/stock/product-code の行更新を隠すだけになる。

083 商品規格編集が他の規格CRUDより難しい理由:

083 を green にしてよい条件:

  1. Hypermedia workflow を先に追加し、admin product detail から goAdminProductProductClass を辿って ProductClass editor に入り、保存 affordance を表現する。
  2. onGet() が対象商品の既存 ProductClass 行を read model として返し、class-name/class-category 由来のIDと表示名、商品コード、価格、在庫、在庫無制限、送料を画面に出す。
  3. 保存 transition は Resource/OpenAPI/ALPS/HTML form/Be Input/Final/SQL が同じ field shape を共有する。直接SQL seedで ProductClass を作って通すのは禁止する。
  4. OK case は保存後に 303 PRG し、管理画面または商品詳細で更新後のSKU情報を readback する。
  5. NG case は必須欠落、数値不正、存在しない productCode / classCategoryId、CSRF 不一致で inline error または HTTP error を確認する。

Admin customer workflow

対象: 会員作成、会員編集、会員削除、会員配送先編集、認証メール再送。

2026-06-10 追加 follow-up で、作成・検索 readback・削除は workflow 化した。CustomerList の doCreateCustomer rel を page://self/admin/create-customer に修正し、doDeleteCustomer / doResendActivationMail rel を Resource 表現へ追加した。flow-admin-customer-maintenance は admin customer list -> create -> Location detail -> list search readback -> delete -> list return を、固定 unsafe URI ではなく公開 rel から実行する。

確認済み:

未完成として残す境界:

次に実装する場合は、admin customer edit / delivery / resend の正準 transition を Resource/OpenAPI/ALPS/HTML form で揃える。そこまで確認できない場合、残りの admin customer 保守は browser fail のまま残す。

Admin order fulfillment

対象: 受注編集、配送先編集、追跡番号更新、対応状況変更、出荷通知メール、受注メール、出荷CSV取込。

注文は admin direct create ではなく、customer purchase flow 由来の注文を使う。2026-06-10 follow-up で Hypermedia/HTTP workflow はこの形に修正済み。

2026-06-11 限定回帰 20260611-admin-order-browser-regression-fixed4 では、Web/HTTP 購入で作った注文を管理画面側から操作し、次を pass とした。

この修正で、shipping_put.sql / shipping_update_tracking.sql が HTML/browser context で複数 statement の INSERT を実行できず、配送先行が作られない問題も直した。修正は runner の判定緩和ではなく、単一 statement の upsert にして実アプリ境界で永続化できるようにしたもの。

2026-06-11 限定回帰 20260611-admin-order-bulk-delete-browser-regression では、Web/HTTP 購入で作った非会員注文を使い、受注一覧の bulk delete form から削除を確認した。

未完成として残す境界:

メールは実SMTPを targetOut にし、fake/noop 境界の契約を Hypermedia/HTTP で確認できる場合だけ pass にする。

Shop/system singleton settings

対象: 基本情報、支払方法編集/削除、配送方法、税率、定休日、特定商取引法、受注ステータス、CSV設定、マスタデータ、メンバー、権限、セキュリティ、2FA。

現在値を実フォームから読み、同じ値または明確な可逆変更だけを送る。設定を壊す可能性がある場合は targetOut にする。メンバー/ニュース/ページの 404 は、先に create flow でIDを作ってから edit/delete に進む。

2026-06-11 メンバーCRUD HTMLフォーム回帰

全件run 20260611-web-db-all-routes では、メンバー作成が unsafe operation not executed: POST /admin/member、詳細/編集/削除が固定ID前提の 404 final=/admin/member として fail のままだった。原因は、Resource workflow は admin member を作れていた一方で、HTML form 境界に action/CSRF/authority/passwordConfirm/delete POST affordance が不足しており、browser/HTTP で同じ業務状態を作れなかったこと。

修正後の確認:

残す境界:

2026-06-11 配送方法CRUD回帰

全件run 20260611-web-db-all-routes では配送方法作成/編集/削除が browser fail のままだった。原因は Web+DB runner が既存ID前提の画面到達だけを見ており、配送方法を実フォームから作成して、そのIDで編集/削除する業務状態を作っていなかったこと。

修正後の確認:

証跡:

この run は --limit=120 の限定回帰であり、121 以降の --limit により未実行 は新規failではない。次の全件runで matrix の配送行を全件run証跡へ置き換える。

2026-06-11 基本情報更新回帰

全件run 20260611-web-db-all-routes では基本情報更新が unsafe operation not executed: POST /admin/base-info のままだった。Hypermedia/HTTP workflow は doUpdateBaseInfo を通していたが、Web+DB runner が HTML の #shop_master_form から POST していなかった。

修正後の確認:

証跡:

この run は --limit=112 の限定回帰であり、113 以降の --limit により未実行 は新規failではない。次の全件runで matrix の基本情報更新行を全件run証跡へ置き換える。

2026-06-11 特定商取引法更新回帰

全件run 20260611-web-db-all-routes では特定商取引法更新が unsafe operation not executed: POST /admin/trade-law のままだった。原因は、Resource/Hypermedia は tradeLawBody 直POSTで通っていた一方、HTML form は EC-CUBE互換の行フィールド trade_law_1_name / trade_law_1_description を送っており、HTTP/browser 境界で tradeLawBody に接続されていなかったこと。

修正後の確認:

証跡:

残す境界: 公開側 /help/trade-law は Help/TradeLaw resource 側に「admin-editable TradeLaw store の aggregation は TODO」と明記されている。今回の完成扱いは admin 更新フォームと管理画面 readback までであり、公開ページへの行表示連動は別 follow-up とする。

この run は --limit=127 の限定回帰であり、128 以降の --limit により未実行 は新規failではない。次の全件runで matrix の特定商取引法更新行を全件run証跡へ置き換える。

2026-06-11 税率設定CRUD回帰

全件run 20260611-web-db-all-routes では税率設定作成/削除が browser fail のままだった。最初の限定runでは作成POSTが400、削除が503になった。原因は Hypermedia/HTTP workflow が Resource 直叩き用の値(taxRate を float、applyDate を日付のみ)で通っており、HTMLフォームが送る datetime-local 値(YYYY-MM-DDTHH:mm)とHTML contextのDELETE後遷移を代表していなかったこと。

修正後の確認:

証跡:

この run は --limit=123 の限定回帰であり、124 以降の --limit により未実行 は新規failではない。次の全件runで matrix の税率設定行を全件run証跡へ置き換える。

Content / filesystem / plugin boundaries

対象: キャッシュ削除、メンテナンス切替、ニュース、ページ、ブロック、レイアウト、CSS/JavaScript、テンプレート追加、プラグイン操作。

ファイルシステムや運用状態を壊す操作は restore plan がない限り pass にしない。安全に検証できるものは一時名で create -> readback -> update -> delete を行い、削除後の404または一覧非表示を確認する。

Unsafe operation pass gate

POST / PUT / DELETE を含む feature は、画面表示だけでは pass にしない。次の全てを満たした場合だけ ✔ pass または ✔ pass(setup operation evidence) にする。

  1. 直前画面が実際に公開している HTML form action / link href / Location から unsafe URL を取得する。
  2. 同一 browser context の cookie と CSRF token で HTTP 境界を送信する。
  3. HTML context では 303 PRG または期待される HTTP error を確認する。
  4. 成功系は最終画面で DB readback された業務状態を確認する。削除は一覧非表示または 404 を確認する。
  5. screenshot と結果JSONの operationEvidence に method/path/status/action/readback text を残す。

これを満たせない場合は、Resource単体や hardcoded URI のテストが green でも browser feature は fail のまま残す。手札がない状態で fixture / fake / direct SQL seed / runner 内の擬似成功処理を足して pass にしない。

この gate は WorkflowBackdoorStateCoverageTest で runner source も検査する。特に、unsafe operation は screenshot 付き setup evidence がない限り pass にならず、runner 証跡は local browser と同一視できない network boundary を必ず report/JSON に残す。

Stop/fail の例

2026-06-11 CSS/JavaScript更新の停止判断と解消

当初、CSS更新 row 172 / JavaScript更新 row 174 は pass にしなかった。Resource と HTML form はあるが、GET body に csrfToken がなく、writer は request 間 readback できない in-memory 境界で、実 public/assets/css/customize.css / customize.js へは書かない状態だったため。

今回の修正で、Css / Js GET は CSRF token を返し、HTML form は mode=content_operation_form を送る。PUT は HTML context では 303 PRG になり、EccubeCustomizeAssetWriter は public asset を壊さない ignored var/tmp/customize-assets-<DATABASE_URL hash>.json に保存する。HttpSqlAdminContentOperationFormTest は GET form -> POST _method=put -> 303 -> GET textarea readback を CSS/JS 両方で確認した。

限定 browser run 20260611-admin-content-css-js-browser-regression-fixed でも row 172 / 174 は setup operation evidence で pass。証跡は docs/web-e2e/results/20260611-admin-content-css-js-browser-regression-fixed.json、screenshots docs/web-e2e/screenshots/20260611-admin-content-css-js-browser-regression-fixed/setup/admin-content-css-update.png / admin-content-js-update.png。

残る境界: 実 public/assets/css/customize.css / customize.js への反映は production-cutover residual。backup/restore plan なしでは実 public asset を書き換えて pass にしない。

2026-06-11 Template lifecycle の停止判断

テンプレート追加 row 176 と削除 row 178 は、20260611-admin-template-upload-browser-regression で pass に更新した。TemplateAdd form は templateCode / templateName / file を出し、Resource は #[InputFile] FileUpload|ErrorFileUpload|null $file を受ける。Resource/Hypermedia は BEAR manual の FileUpload::fromFile()、HTTP projection と SQL HTML regression は multipart/form-data で同じ upload 境界を確認する。BEAR manual: https://bearsunday.github.io/manuals/1.0/ja/resource_param.html#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88

row 176 は upload 後にテンプレート一覧でテンプレート名と radio value を readback し、row 178 は削除後の一覧非表示を readback した。証跡は docs/web-e2e/results/20260611-admin-template-upload-browser-regression.json と docs/web-e2e/screenshots/20260611-admin-template-upload-browser-regression/setup/admin-template-upload.png / admin-template-delete.png。

残る row 177 有効化は pass にしない。EccubeTemplateCompatibility::select() は no-op で、active template の readback がない。進める条件は、select 後に一覧または設定表示で active template を確認できる projection を追加し、HttpSqlAdminTemplateFormTest と Web+DB runner が PUT/PRG/readback/screenshot を残すこと。

2026-06-11 Plugin lifecycle の対象外判断

プラグイン操作 rows 180-183 は、Web+DB 完成判定では targetOut とする。flow-manage-plugin は docs/migration-status.md でも out of scope で、実 plugin upload/install runtime(download/unzip/composer/migrate/cache)はこの migration の対象外。HTML も install form を持たず、プラグイン行がない fresh DB では enable/disable/delete の実 affordance を作れない。

ここで runner から POST /admin/plugin-list を直叩きして前提 plugin 行を作ると、「テストを通すための stub registry」になる。plugin lifecycle を将来 in-scope に戻すなら、まず EC-CUBE の plugin install/search subtree に対応する正規画面、CSRF、HTML 303 PRG、readback、fake/noop 境界の仕様を追加し、その後に browser evidence を取る。

2026-06-11 Cache/Maintenance HTMLフォーム回帰

全件run 20260611-web-db-all-routes では cache clear / maintenance toggle が unsafe operation not executed のままだった。原因は、GET画面にCSRF tokenがなく実フォーム送信が403になり、maintenance form は maintenance=on/off を送る一方で Resource は enabled を期待していたこと。また EccubeMaintenanceMode は in-process singleton だけで、PHP server の複数リクエスト間 readback ができなかった。

修正後の確認:

証跡:

2026-06-11 Block create/edit/delete HTMLフォーム回帰

全件run 20260611-web-db-all-routes ではブロック作成/編集/削除が unsafe operation not executed のままだった。原因は、HTML form が EC-CUBE名(name, file_name, block_html)で送信され、Resource が要求する canonical 名(blockName, blockFileName)と一致していなかったこと、作成 form action が collection endpoint ではなく single endpoint を向いていたこと、削除SQLが複数 statement で実DB削除を確認できなかったこと。

修正後の確認:

証跡:

この run は --limit=168 の限定回帰であり、169 以降の未実行 fail は新規failではない。次の全件runで matrix のブロック行を全件run証跡へ置き換える。

2026-06-11 Layout edit HTMLフォーム回帰

全件run 20260611-web-db-all-routes ではレイアウト編集が unsafe operation not executed のままだった。原因は、GET /admin/layout/layout?layoutId=... が新規レイアウト用の空フォームを描き、既存 row の prefill と _method=put form action を出していなかったこと。レイアウトの block-position designer は引き続き deferred 境界だが、現 ALPS/Resource contract の保存対象である layoutName は Web/HTTP/DB で更新できるようにした。

修正後の確認:

証跡:

この run は --limit=170 の限定回帰であり、171 以降の未実行 fail は新規failではない。次の全件runで matrix のレイアウト行を全件run証跡へ置き換える。

次の実装単位

  1. Admin customer edit / delivery / resend の rel と action を Resource/OpenAPI/ALPS/HTML で照合し、保存 transition または再送対象の作成導線がないものは引き続き fail として残す。
  2. scripts/web-e2e-runner.mjs が browser 上の実フォームから admin create/delete/order/mail unsafe 操作を実行できるように、先に対応する Hypermedia/HTTP regression と HTML form/action 観測を追加する。
  3. Browser で残った CRUD fail ごとに Hypermedia/HTTP regression を追加し、赤を確認してから実装を直す。
  4. LinkAudit warning を rel 単位で分類し、Resource meta / HTML / profile docs のどれが正かを確認してから failure gate 化する。