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 は日付付きの事実、未解決境界、自信のない箇所を残す台帳です。
現在の完成判定
- Feature matrix: pass 175 / fail 2 / targetOut 9(
feature-implementation-matrix.md現在値。runner parser 準拠で 186 feature 行。admin order create 096 は限定 Web+DB runner20260611-admin-order-create-browser-regression-fixed2、admin order bulk-delete 098 は20260611-admin-order-bulk-delete-browser-regression、trade-law 127 は20260611-admin-trade-law-browser-regression、order-status settings 129 は20260611-admin-order-status-settings-browser-regression、mail-template 131/132 は20260611-admin-mail-template-browser-regression、CSV設定更新 134 は20260611-admin-csv-config-browser-regression-2、admin member 139-142 は20260611-admin-member-browser-regression-emailfix、authority-role 143 は20260611-admin-authority-role-browser-regression、admin system 146/150 は20260611-admin-system-browser-regression-fixed、calendar 124/125 は20260611-admin-calendar-browser-regression-fixed、master-data 136/137 は20260611-admin-master-data-update-browser-regression、news 158-160 は20260611-admin-news-browser-regression-fixed、page 162-164 は20260611-admin-page-browser-regression-fixed、block 166-168 は20260611-admin-block-edit-browser-regression、layout 170 は20260611-admin-layout-browser-regression、content CSS/JS 172/174 は20260611-admin-content-css-js-browser-regression-fixed、template 176-178 は20260611-admin-template-active-browser-regressionで実フォーム/認証境界に接続済み。plugin 180-183 は migration scope 外として targetOut) - OpenAPI operations: 最新の全件run
20260611-web-db-all-routesは pass 169 / fail 65 / targetOut 3。限定回帰runでPOST /admin/order/create、POST /admin/order/bulk-delete、POST /admin/trade-law、POST /admin/order/import-shipping、PUT /admin/order-status、POST /admin/mail-template、DELETE /admin/mail-template、POST /admin/csv-config、POST /admin/authority-role、admin member 139-142、content 154/156/172/174、PUT /admin/security、POST /admin/two-factor-auth、POST /admin/calendar、DELETE /admin/calendar、POST /admin/news/news-list、PUT /admin/news/news、DELETE /admin/news/news、POST /admin/page/page-list、PUT /admin/page/page、DELETE /admin/page/page、PUT /admin/block/block、PUT /admin/layout/layout、PUT /admin/master-data、PUT /admin/master-data-editは pass 証跡を追加したが、次の全件runで再集計するまで公式集計へ混ぜない。 - NG cases: pass 19 / fail 0(
20260611-form-negative-visible-ui-regression-1278080で可視エラーUI数まで確認) - PHPUnit targeted gates:
hypermedia/http/ Psalm は green。 - Full PHPUnit: 既存の
composer test -- --no-progress契約は green(1935 tests, 27375 assertions)。 - Current generated API docs:
composer doc:api後は 237 operations / audit gaps 0。20260610-web-db-all-routesは 237 operations 母集団で再実行済み。 - 20260608 で既知 fail だった
注文履歴詳細/再注文は、Web購入flow由来の注文で green。 - 全 feature fail は Admin 側。限定回帰runで見えた
unsafe operation not executedと 404 screen/action の内訳は、次の全件runで再集計する。 - 2026-06-10 follow-up で、required workflow 内の admin direct
doCreateOrder使用は 0 件になった。注文を必要とする workflow は storefront checkout 由来のorderNoを使う。 - 2026-06-10 追加 follow-up で、admin customer create -> detail readback -> list search -> delete は
flow-admin-customer-maintenanceとして Hypermedia/HTTP green になった。237-operation Web+DB browser runner では 087 会員作成と 089 会員削除をLocation、一覧 readback、削除後 0件表示で pass に更新した。 - 2026-06-10 product follow-up で、admin product create/read/update/copy/bulk status/delete は Hypermedia/HTTP と Web+DB browser runner の両方で green。商品一覧 HTML には unsafe action token、
productCodes[]、copy/delete/bulk status action を実 affordance として出し、HTML context の bulk status / delete は 303 PRG として確認した。 - 2026-06-10 category/tag follow-up で、admin category create/update/delete と tag create/delete は Hypermedia/HTTP と Web+DB browser runner の両方で green。操作URLは一覧/詳細の form action、
Location、削除 anchor/token から取得し、カテゴリ詳細は input value readback、削除は一覧から消えたことを確認した。 - 2026-06-10 payment follow-up で、admin payment create/update/delete は Hypermedia/HTTP と Web+DB browser runner の両方で green。フォーム名は Resource の
paymentMethodName/ruleMin/ruleMaxに揃え、create/update/delete は HTML context で 303 PRG、Locationreadback、削除後一覧から消えたことを確認した。 - 2026-06-10 非会員購入 follow-up で、旧 Web+DB runner が
POST /shopping/non-memberのLocationevidence だけで pass としていた不足を確認した。ブラウザー form POST は201 Createdでは遷移しないため、HTMLフォーム境界は303 /shopping/confirm?preOrderId=...&paymentMethodId=...に修正し、非会員の購入者情報はdtb_orderの注文者スナップショットとして保持・読戻しする regression を追加した。in-app browser 接続不可のため、スクリーンショット evidence は次回 run で差し替える。 - 2026-06-11 追加確認で、fresh DB の
/shopping/non-member有効POSTがdtb_order.payment_id -> dtb_payment.idFK違反で 503 になる穴を確認した。既存 workflow は先に admin 支払方法作成を実行していたため、fresh DB 直後のゲスト購入を表現していなかった。Fake/Resource 側はDefaultPaymentMethodFactoryの fallback をDB制約なしで使い、旧HTTPフォームテストもLocationまでしか見ていなかった。 - 2026-06-11 fix で
sql/seed/dtb-system-master.sqlに installer-level の初期支払方法(代金引換/クレジットカード)を追加し、HttpSqlNonMemberCheckoutFormTestで SQL HTML context の GET/shopping/non-member-> 有効POST -> GET/shopping/confirmを確認する regression を追加した。confirm HTML は見出し、入力メール、支払方法名まで readback する。 - 2026-06-11 follow-up で
flow-customer-purchaseから購入前の admindoCreatePaymentsetup を削除した。購入flowは商品だけをWeb/HTTPで作り、支払方法はsetup-dbの installer master を使う。WorkflowBackdoorStateCoverageTestに、customer purchase flow がdoCreatePaymentを使ったら fail する guard を追加した。 - 2026-06-11 browser runner follow-up で、
scripts/web-e2e-runner.mjsから購入用のadmin-payment-createsetup を削除した。runner の支払方法 CRUD は maintenance step に分離し、購入はsetup-dbの初期支払方法を使う。POST /shopping/non-memberは 303Location: /shopping/confirm?...を必須にし、実ブラウザーで confirm URL を開いて非会員メールと代金引換の readback、スクリーンショットscreenshots/20260611-non-member-browser-regression/setup/shopping-non-member-confirm.pngを evidence にする。WorkflowBackdoorStateCoverageTestには runner がこの浅い判定へ戻らない guard も追加した。 - 2026-06-11 規格/規格分類 follow-up で、admin class-name create/update/delete と class-category create/update/delete は
flow-admin-class-maintenanceとして Hypermedia/HTTP green になった。HTML form はclassNameLabel/classCategoryNameを送信し、backend_nameは表示専用に戻した。browser runner では20260611-admin-class-browser-regression-fixedで rows 072-074 / 078-080 を 303 PRG、Locationreadback、削除後一覧から消えたことで pass に更新した。 - 2026-06-11 追加 follow-up で、非会員購入の空POSTとメール確認不一致を
HttpSqlNonMemberCheckoutFormTestに追加した。SQL HTML context の実フォームPOSTで400、同じお客様情報の入力画面、inline入力してください。/メールアドレスが一致しません。、入力値再表示、例外ページなしを確認する。 - 2026-06-11 追加 follow-up で、会員登録を
HttpSqlCustomerRegistrationFormTestに追加した。SQL HTML context のGET /entry-> 空POST inline error(パスワード非再表示) -> 有効POST303 /entry/complete->POST /login303 /mypage->GET /mypage/changeの登録メール readback まで確認する。これにより、runner がLocationを手で辿って隠していたログイン成功POSTの200再描画を、HTMLフォーム送信時は PRG に修正した。 - 2026-06-11 admin CSV follow-up で、商品CSV/カテゴリCSVの
import_filemultipart upload をHttpSqlAdminCsvUploadFormTestに追加した。旧routerは$_FILESを読まないため商品CSVは{"code":400,"message":"csv"}、カテゴリCSVは空CSVとして200再描画していた。修正後は router がimport_fileをcsvとしてResourceへ渡し、HTML contextでは商品/カテゴリCSV import後に 303 PRG、商品詳細/カテゴリ一覧でreadbackする。 - 2026-06-11 admin class CSV follow-up で、規格CSV/規格分類CSVの
import_filemultipart upload と一覧readbackをHttpSqlAdminCsvUploadFormTestに追加した。旧EccubeClassCsvCompatibilityはCSV行数を数えるだけでdtb_class_name/dtb_class_categoryに永続化していなかった。修正後は既存のClassNameStorageInterface/ClassCategoryStorageInterfaceとID providerでupsertし、HTML contextでは 303 PRG、規格一覧/規格分類一覧でreadbackする。flow-admin-csv-exchangeも count 確認だけではなく、Locationを辿って規格名IDを取得し、そのIDで規格分類CSVを取り込んだ後に一覧readbackする。 - 2026-06-11 admin CSV設定更新 follow-up で、
20260611-admin-csv-config-browser-regressionがPOST /admin/csv-configを実行したものの400 {"code":400,"message":"columns"}で落ちることを確認した。HTTP regression はcolumns[...]を直接 POST していたため、実画面のcsvOutput[]/csvNotOutput[]と submit 時 hiddencolumns[...]生成の境界を見逃していた。修正後は Resource が HTML multi-select field をcolumnsへ正規化し、テンプレートの submit handler は jQuery 依存を外して vanilla JS で hiddencolumns[...]を生成する。併せて EC-CUBE seed のmtb_csv_typeに合わせて CSV type ID(1=商品, 2=会員, 3=受注, 4=配送)を修正し、dtb_csv置換SQLは multi-statement 依存をやめて delete/insert に分割した。 - 2026-06-11 admin CSV設定更新 regression
npm run web:e2e -- --run-id=20260611-admin-csv-config-browser-regression-2 --base-url=http://127.0.0.1:18094 --limit=134 --skip-negative --no-probe-uncovered --no-update-matrix: row 134 は pass。POST /admin/csv-configはhttpStatus=303、Location=/admin/csv-config?csvType=3、GET /admin/order/export-orderの CSV header はpaymentTotal,orderNo,orderDate。スクリーンショットdocs/web-e2e/screenshots/20260611-admin-csv-config-browser-regression-2/setup/admin-csv-config-update.pngを保存した。この件は CSRF bypass ではなく、実フォームの入力形状と JavaScript dependency の見落としだった。 - 2026-06-11 admin order-status settings follow-up で、
HttpSqlAdminOrderStatusFormTestを追加し、SQL HTML context のGET /admin/order-status-> form action/admin/order-status?_method=put-> hiddencsrfToken->POSToverride ->303 /admin/order-status-> settings row readback を確認した。旧 GET は hidden CSRF が空で、onPut()は HTML context でも同じ template を再描画してorderStatusesが空になるため、browser form としては成功後画面が壊れていた。修正後はOrderStatus::onGet()がcsrfTokenを出し、HTML context のPUTは 303 PRG で戻る。 - 2026-06-11 admin order-status settings browser regression
npm run web:e2e -- --run-id=20260611-admin-order-status-settings-browser-regression --base-url=http://127.0.0.1:18096 --limit=130 --skip-negative --no-probe-uncovered --no-update-matrix: row 129 は pass。PUT /admin/order-statusは setup operation evidencehttpStatus=303、Location=/admin/order-status、settings page readback。スクリーンショットdocs/web-e2e/screenshots/20260611-admin-order-status-settings-browser-regression/setup/admin-order-status-settings-update.pngを保存した。 - 2026-06-11 admin mail-template follow-up で、
HttpSqlAdminMailTemplateFormTestを追加し、SQL HTML context のGET /admin/mail-template->POST /admin/mail-template/create-> selected edit form ->POST /admin/mail-templatewith realmail_subject-> readback -> rendered delete affordance ->DELETE /admin/mail-template-> list readback を確認した。旧 Resource/flow はmailSubjectを直接POSTしていたため、HTML field namemail_subject、form action、hiddenmailTemplateId、削除 affordance を見逃していた。さらに画面の削除可否をid > 2で仮判定しており、fresh DB では作成行が id=2 になって削除ボタンが出なかった。修正後はdtb_mail_template.deletableを Entity/Final/Resource へ通してMail.isDeletableを決める。 - 2026-06-11 admin mail-template browser regression
npm run web:e2e -- --run-id=20260611-admin-mail-template-browser-regression --base-url=http://127.0.0.1:18095 --limit=133 --skip-negative --no-probe-uncovered --no-update-matrix: row 131/132 は pass。POST /admin/mail-templateはhttpStatus=303、Location=/admin/mail-template?mailTemplateId=...、selected form のmail_subjectvalue readback。DELETE /admin/mail-templateは rendered delete href から303 /admin/mail-template、select option から消えたことを確認。スクリーンショットdocs/web-e2e/screenshots/20260611-admin-mail-template-browser-regression/setup/admin-mail-template-update.png/admin-mail-template-delete.pngを保存した。 - 2026-06-11 form negative follow-up で、
20260611-form-negative-regressionを--skip-negativeなしで実行した。entry 空POST、entry メール/パスワード確認不一致、login 認証失敗/形式不正、contact 必須/長文、non-member 空POST、CSRF欠落、未ログイン系など NG 19件は pass / fail 0。スクリーンショットはdocs/web-e2e/screenshots/20260611-form-negative-regression/negative/に保存した。feature summary は pass 41 / fail 143 / targetOut 2 だが、--limit=43による未実行行を fail として含むため、このrunはフォームNG証跡として扱う。 - 2026-06-11 環境確認で、in-app browser / Chrome はローカルマシン、Codex の
php -S/curl/ Playwright はリモート実行環境を見ており、同じlocalhost/127.0.0.1でも別マシンを指していたことを確認した。これにより、手元ブラウザで見えない画面を runner が pass とする不一致が起きていた。以後、手元ブラウザ証跡と runner 証跡を同一視しない。手元ブラウザで検証する場合は、そのマシンで同じ branch / DB / PHP server を起動し、結果JSONとは別に「local browser evidence」として記録する。 - 2026-06-11 追加の環境確認で、リモート側でも
php -S localhost:8080は名前解決により[::1]:8080のみを listen し、127.0.0.1:8080とは別境界になり得ることを確認した。さらにlsof -nP -iTCP:8080 -sTCP:LISTEN/lsof -nP -iTCP:18080 -sTCP:LISTEN/curl --max-time 2で、既存 server を停止したことを確認した。runner を起動する前には、必ず listener 空状態を確認してから 1本だけ起動する。 - 2026-06-11 visible error UI regression
20260611-form-negative-visible-ui-regression-1278080はリモート実行環境の127.0.0.1:8080に対する--only-negative限定runとして実行し、NG 19件 pass / fail 0。entry 空POSTはstatus=400、visibleErrorUi=6/1、finalhttp://127.0.0.1:8080/entry、スクリーンショットdocs/web-e2e/screenshots/20260611-form-negative-visible-ui-regression-1278080/negative/ng-entry-required-missing.pngを保存した。non-member 空POSTはvisibleErrorUi=11/1、contact 空POSTはvisibleErrorUi=4/1、admin login 認証失敗はvisibleErrorUi=1/1。このrunはローカルChromeの目視証跡ではなく、リモート runner 証跡として扱う。 - 2026-06-11 admin member follow-up で、
HttpSqlAdminMemberFormTestを追加し、SQL HTML context の admin member create ->Locationdetail readback -> name update -> list delete form -> soft delete redirect を確認した。HTML form は create/update/delete の action、CSRF、mode=member_form、authority select、passwordConfirm を実フォーム境界として送る。編集時は password/passwordConfirm を出さず、department/work/2FA/password change は現 Resource/OpenAPI 契約外として永続化しない。 - 2026-06-11 content operation follow-up で、
HttpSqlAdminContentOperationFormTestを追加し、SQL HTML context の cache clear、maintenance toggle、CSS更新、JavaScript更新を実フォームから確認した。GET は CSRF token を出し、HTML form は_method=put/mode=content_operation_formを送る。Cache は 303/admin/content/cacheへPRG、Maintenance はvar/tmp/maintenance-mode.flagの marker-file 境界で enable/disable readback、CSS/JS はvar/tmp/customize-assets-<DATABASE_URL hash>.jsonの runtime 境界で textarea readback する。 - 2026-06-11 content operation browser regression
20260611-content-operation-browser-regressionは、リモート runner の127.0.0.1:18080/ DBbemart_e2e_content_20260611に対する--limit=156run。154 キャッシュ削除と 156 メンテナンス切替は setup operation evidence で pass。このrun時点では 139-142 admin member が runner の業務状態作成へ未接続で fail だったが、後続の20260611-admin-member-browser-regression-emailfixで実フォーム境界へ接続して pass に更新した。 - 2026-06-11 admin member browser regression
20260611-admin-member-browser-regression-emailfixは、リモート runner の127.0.0.1:18080/ DBbemart_e2e_member_20260611_emailfixに対する--limit=142run。139-142 は pass、業務状態作成も pass。直前のcacheclearrun で見えた admin customer setup fail は、runner が長い run ID をそのままadmin-customer-<run-id>@example.testとして使い local-part 64 文字制限を超えた検証ハーネス不具合だったため、短いtaxonomySuffixを使うように修正した。 - 2026-06-11 admin system browser regression
20260611-admin-system-browser-regression-fixedは、リモート runner の127.0.0.1:18080/ DBbemart_e2e_system_20260611_fixedに対する--limit=150run。146 セキュリティ設定更新は、実 form action/admin/security?_method=put、CSRF、trustedHostsの送信後に GET/admin/securityで value readback する形で pass。150 二要素認証実行は、2FA setup 後の別 browser context で/admin/two-factor-authを経由し、TOTP verification から/admin/indexへ戻ることで pass。旧 run のような「operation evidence だけ pass だが setup readback fail」は採用しない。 - 2026-06-11 master-data follow-up で、
HttpSqlAdminMasterDataFormTestを追加し、SQL HTML context のGET /admin/master-data->#form1action/admin/master-data?_method=put->masterType=paymentsubmit ->form#form2のrows[*]readback ->POST /admin/master-data-edit?_method=put->303 /admin/master-data?masterType=payment-> payment row name readback を確認した。限定 Web+DB runner20260611-admin-master-data-update-browser-regressionで row 136/137 は setup operation evidence と screenshot 付きで pass。 - 同 follow-up の full
httpで、前段の支払方法CRUDが作った長い表示名によりPUT /admin/master-dataresponse schema のrows[*].name maxLength=32が 400 を返すことを確認した。これは test data を短くして隠さず、master row が支払方法/配送方法/ニュース/規格など複数SQL masterを代表する contract としてget/put-admin-master-dataのrows[*].nameを 255 に修正した。 - row 137 は
EccubeMasterDataWriterの process-local write をやめ、AdminMasterRegistry::listRows()が読む payment/delivery/tag/className/classCategory/member/news storage へ接続した。generic form はid+nameしか送らないため、writer は既存 row を読み、非表示列(charge/visible/classNameId/passwordHash/publishDate など)を保持してname相当列だけを書き戻す。ignoredvar/tmpoverlay は採用していない。 - 2026-06-11 CSRF 方針確認: 現コードに
NullCSRFbinding はない。Fake context はtests/Fake/Reason/Service/FakeCsrfTokenの固定 token 検証、HTML SQL context はEccubeSharedCsrfTokenAdapterとX-BeMart-Test-Csrf-Token/ hiddencsrfTokenの一致で通している。isValid()が常に true なのは smoke 専用ResourceSmokeCsrfTokenだけ。今後「テスト時は Null CSRF」を採用するなら、フォーム token の表示/送信 affordance と CSRF 検証無効化を分けて設計し、browser evidence を弱めないようにする。 - 2026-06-11 authority-role follow-up で、
POST /admin/authority-roleの HTML form と Resource 契約の不一致を閉じた。GET はdtb_authority_roleから URL deny rules を読み、POST は EC-CUBE form shapeAuthorityRoles[*][Authority]/AuthorityRoles[*][deny_url]を DB-backed に保存し、HTML context では303 /admin/authority-roleへPRGする。既存 member role flip shapeloginId/authorityは残し、FlowAdminSystemOperationTestも継続 green。FlowAdminAuthorityRoleRulesTest、HttpSqlAdminAuthorityRoleFormTest、限定 browser run20260611-admin-authority-role-browser-regressionで form action、hidden CSRF、303、deny URL readback、screenshotscreenshots/20260611-admin-authority-role-browser-regression/setup/admin-authority-role-update.pngを確認した。 - 2026-06-11 calendar follow-up で、定休日カレンダー 124/125 を実フォーム境界へ接続した。
POST /admin/calendarはGET /admin/calendarの#form1action/admin/calendar?operation=createと CSRF を使い、303 PRG 後に作成行を readback する。DELETE /admin/calendarは作成行の削除 href/admin/calendar?calendarId=...&_method=deleteから実行し、削除後に一覧から消えたことを確認する。Title/Holiday/CalendarIdsemantic variable 未登録 Notice が HTTP header/body を壊していたため、既存 ID/日付語彙と同じ型契約の Semantic を追加した。 - 2026-06-11 news follow-up で、ニュース 158-160 を実フォーム境界へ接続した。
AdminNewsFormは EC-CUBE 互換 id を残しつつnewsTitle/publishDate/newsUrl/newsDescription/linkMethodの canonical field name を送る。GET /admin/news/newsの create form action は/admin/news/news-list、edit form action は/admin/news/news?newsId=...&_method=put。HTML context の create/update/delete は 303 PRG とし、HttpSqlAdminNewsFormTestと限定 browser run20260611-admin-news-browser-regression-fixedで detail/list readback、削除後一覧から消えること、screenshotsadmin-news-create.png/admin-news-update.png/admin-news-delete.pngを確認した。 - 2026-06-11 page follow-up で、ページ 162-164 を実フォーム境界へ接続した。
AdminPageFormは EC-CUBE 互換 id を残しつつpageName/pageUrl/pageFileNameの canonical field name を送る。tpl_data/ meta / layout join は現 Resource/OpenAPI 契約外なので disabled 表示境界に留め、送信しない。GET /admin/page/pageの create form action は/admin/page/page-list、edit form action は/admin/page/page?pageId=...&_method=put。pageEditType=0の user page に delete affordance を出し、tpage_remove.sqlは MediaQuery で実行できる1文 multi-table DELETE に直した。HttpSqlAdminPageFormTestと限定 browser run20260611-admin-page-browser-regression-fixedで detail/list readback、削除後一覧から消えること、screenshotsadmin-page-create.png/admin-page-update.png/admin-page-delete.pngを確認した。 - 2026-06-11 template follow-up で、テンプレート 176-178 を実フォーム境界へ接続した。upload は BEAR manual の
#[InputFile]/Koriym\FileUpload\FileUpload::fromFile()(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)に合わせ、Resource/Hypermedia はFileUpload::fromFile(__DIR__ . '/../fixtures/template-upload.zip')、HTTP/browser は同じ form action へ multipart/form-data で送る。active template は EC-CUBE 本番 asset deploy ではなく ignoredvar/tmp/template-active-<DATABASE_URL hash>.txtの runtime readback 境界として保持し、GET/admin/template/template-listのtemplates[].activeと radiochecked="checked"に投影する。HttpSqlAdminTemplateFormTestと限定 browser run20260611-admin-template-active-browser-regressionで upload後一覧表示、select後checked表示、delete後一覧非表示、screenshotsadmin-template-upload.png/admin-template-select.png/admin-template-delete.pngを確認した。 - 2026-06-11 template follow-up 中に、HTTP/browser context が古い
var/tmp/html-eccube-sql-hal-app/{di,injector,twig}を見て、実装後も checked が出ない false fail を確認した。以後、コード変更後の HTTP/browser runner は PHP server 起動前に compiled context cache を消す。HttpSqlAdminTemplateFormTestとscripts/web-e2e-runner.mjsにはこの cache cleanup を入れた。ただし既に起動済みの PHP server が injector を保持している場合は、cache cleanup だけでは足りないので server を再起動する。
止める基準
- 実フォーム、
_links、HTML form action、Location、ALPS rel から操作URLを得られない unsafe 操作は実行しない。 - 業務状態を作るために直接SQL seed、fixture boundary、runner専用の直POST bodyを追加しない。
- 画面到達だけで副作用を pass にしない。作成・更新・削除は readback 画面または別ロール画面で postcondition を確認する。
- 外部決済、実SMTP、本番ファイル破壊、実プラグインインストールなどは targetOut とし、fake/noop 境界を確認できる場合だけ別途 pass にする。
- テストを通すためだけの ResourceObject wrapper、URI route mapper、固定dummy fixture、DBリセット、強制ID採番補正は追加しない。根拠が不足している場合は fail/follow-up として残す。
自信がない/証拠不足として残す箇所
次の項目は、現時点で「作れば通る」実装をしてはいけない。標準の Hypermedia/HTTP workflow に戻せる証拠を集められない場合は、fail または targetOut として残して止める。
- Admin unsafe operation は、画面到達だけでは成功扱いにしない。実フォームまたは表現上の action/link から payload を復元できるまで、runner 専用の直POST/PUT/DELETEは作らない。
- 非会員購入フォーム送信は、
Locationヘッダだけで pass にしない。ブラウザーで遷移可能な 303、確認画面の購入者情報 readback、完了後の注文履歴/再注文までを同一注文で確認する。 POST /admin/delete-customerの HTML 境界 503 は修正済み。対応ではHttpAdminCustomerDeleteHtmlTestを先に追加し、HTML context では 303/admin/customer-listへ PRG する契約として確認した。以後も template missing を隠すだけの ResourceObject wrapper や runner 側成功扱いは追加しない。- Admin 404 screen/action は、固定IDを仮定しない。create flow 由来のIDで edit/delete/readback へ進める workflow ができるまで、404をマスタデータ不足として握りつぶさない。
- SQL-backed Resource suite は、履歴・schema・fixture helper の整合が取れるまで復元しない。
SqlFixturesTraitの空実装、固定dummy値、NOT NULL/FK を満たすだけの最小行投入はしない。 - HTTP projection で Resource workflow と違う挙動が出た場合は、HTTP 側を正として扱う。ただし HTTP を通すために test context や session/fake state を追加する前に、HTML form/CSRF/Cookie/redirect の観測結果を記録する。
- CSRF test boundary は現状 Null ではない。固定 token fake や test header を使う場合でも、画面に hidden
csrfTokenが出て、同一 cookie/context で送信されることを確認する。検証無効化へ寄せる場合は、フォーム affordance の確認まで消さない。 - Noop/fake 境界は、境界契約が表現またはテストで観測できる場合だけ pass にする。実SMTP、実決済、破壊的ファイル操作は、観測不能なまま成功扱いにしない。
- Raw
vendor/bin/phpunit --no-progressは、Composer script が指定する 512MB memory limit を通らないため TCPDF PDF export で停止する。これは project test contract の差として扱い、調査前に skip や軽量 renderer で隠さない。 BEAR.Dev.HtmlLinkAuditwarning は full suite green でも大量に残る。warning を成功扱いから消す前に、Resource meta の target 判定と HTML/profile 表現のどちらが正かを確認する。get-admin-class-name-class-name-list.json/get-admin-class-category-class-category-list.jsonのname.maxLengthは 32 だが、ClassNameLabel/ClassCategoryNameSemantic と EC-CUBE schema は 255 文字を許す。今回のCSV回帰では短い値で通したが、schemaを32のままにするか255へ戻すかは、Semantic-Ex生成元とFake観察値を確認してから別途直す。localhost/127.0.0.1の手動確認結果は、ローカル/リモートの実行場所が揃っていなければ証跡へ混ぜない。フォームエラー表示の成否を判定する場合は、どのマシンの browser がどのマシンの PHP server を見ているか、listener 確認、DB URL、run ID を揃える。- Admin member の
department、work、2FA、password change は、今回の member form regression では完成扱いにしない。AdminMemberFormは department/work/2FA を表示境界に留め、編集時の authority/password 更新も Resource/OpenAPI/ALPS の保存 transition が揃うまで追加しない。 - Admin member の 139-142 は限定 Web+DB runner
20260611-admin-member-browser-regression-emailfixで green。実フォーム操作で作ったloginIdを detail/edit/delete rows へ渡し、delete form affordance からDELETE /admin/memberを確認した。ただしdepartment、work、2FA、password change は引き続き完成扱いにしない。 - Cache clear / maintenance toggle の 154/156 は限定 browser regression
20260611-content-operation-browser-regressionで pass。CSS/JavaScript 更新の 172/174 は20260611-admin-content-css-js-browser-regression-fixedで pass。Maintenance marker-file は ignoredvar/tmp/maintenance-mode.flag、customize asset は ignoredvar/tmp/customize-assets-<DATABASE_URL hash>.jsonに限定し、本番運用ファイルへの反映は引き続き targetOut 境界として扱う。 - Authority role update の 143 は限定 browser regression
20260611-admin-authority-role-browser-regressionで pass。証跡はscreenshots/20260611-admin-authority-role-browser-regression/setup/admin-authority-role-update.png。実フォームAuthorityRoles[0][Authority]/AuthorityRoles[0][deny_url]/ hidden CSRF からPOST /admin/authority-roleを実行し、303 PRG とdtb_authority_rolereadback まで確認した。 - Security update の 146 は限定 browser regression
20260611-admin-system-browser-regression-fixedで pass。ただし writer は本番設定ファイルではなく ignoredvar/tmp/security-config.jsonに保存する runtime 境界なので、demo の可観測な設定更新として扱い、本番運用ファイル更新の完成扱いにはしない。 - Two-factor auth の 150 は限定 browser regression
20260611-admin-system-browser-regression-fixedで pass。TOTP はFakeTwoFactorAuth境界で、実デバイス登録や外部認証アプリの検証は対象外。 - Calendar create/delete の 124/125 は限定 browser regression
20260611-admin-calendar-browser-regression-fixedで pass。証跡はscreenshots/20260611-admin-calendar-browser-regression-fixed/setup/admin-calendar-holiday-create.pngとscreenshots/20260611-admin-calendar-browser-regression-fixed/setup/admin-calendar-holiday-delete.png。更新操作も同 flow 内でadmin-calendar-holiday-update.pngに readback を残したが、matrix 行としては作成/削除のみを pass に更新する。 - News create/update/delete の 158-160 は限定 browser regression
20260611-admin-news-browser-regression-fixedで pass。証跡はscreenshots/20260611-admin-news-browser-regression-fixed/setup/admin-news-create.png、admin-news-update.png、admin-news-delete.png。この修正は HTML form action/field-name mismatch と delete ALPS rel 誤りを閉じる範囲に限定し、本文/URLの追加仕様や公開/非公開visibleは完成扱いにしない。 - Page create/update/delete の 162-164 は限定 browser regression
20260611-admin-page-browser-regression-fixedで pass。証跡はscreenshots/20260611-admin-page-browser-regression-fixed/setup/admin-page-create.png、admin-page-update.png、admin-page-delete.png。この修正は HTML form action/field-name mismatch、pageEditType=0delete affordance、削除SQLの1文化を閉じる範囲に限定し、tpl_data、meta、layout join、実Twigファイル生成は完成扱いにしない。
調査済みだが採用しなかった回避策
- Hypermedia workflow の
ResourceObjectを eager render して snapshot 化する wrapper は採用しない。href()/linkHref()の標準挙動とズレ、goContactFormのような実リンク解決を壊すことを確認したため削除した。 - PHPUnit process-isolation は採用しない。
#[Depends]が返すResourceObject内の Closure を serialize できず、workflow の形を変えるだけの回避になる。 - SQL-backed Resource suite 用の
SqlFixturesTraitを空実装や固定dummy戻り値で作らない。現tests/Resource/Sqlが要求する fixture helper は多く、schema/FK/NOT NULL と履歴上の意図を確認して復元する必要がある。 dtb_customer.id重複を隠すために flow 内で DB を drop/create したり、テスト専用の採番補正を追加したりしない。2026-06-10 の調査では、原因は採番 SQL ではなくWorkflowDbSessionがprodcompiled context を使っていたため Resource 操作が別 connection/autocommit になったことだった。
Follow-up groups
Test harness / suite reliability
vendor/bin/phpunit --testsuite hypermedia は、2026-06-10 の follow-up 修正後に green。旧状態では assertion failure ではなく PHP process の異常終了で止まっていた。
確認済み:
WorkflowDbSessionTest: green。Resource POST で作った顧客が workflow transaction 内で見え、restore()後に消えることを guard している。- 2026-06-10 中間修正時点の
vendor/bin/phpunit --testsuite hypermedia --no-progress: green(232 tests, 1085 assertions)。 - 2026-06-10 中間修正時点の
vendor/bin/phpunit --testsuite http --no-progress: green(215 tests, 1078 assertions)。 vendor/bin/psalm --no-progress: green(errors 0、info 180)。- 2026-06-10 追加 follow-up 後の
vendor/bin/phpunit --testsuite hypermedia --no-progress: green(258 tests, 1240 assertions)。 - 2026-06-10 追加 follow-up 後の
vendor/bin/phpunit --testsuite http --no-progress: green(228 tests, 1181 assertions)。 - 2026-06-10 追加 follow-up 後の
WorkflowBackdoorStateCoverageTest+WorkflowSkeletonCoverageTest: green(40 tests, 222 assertions)。 - 2026-06-10 admin customer follow-up 後の
vendor/bin/phpunit --testsuite hypermedia --no-progress: green(267 tests, 1293 assertions)。 - 2026-06-10 admin customer workflow follow-up 後、HTML delete regression 追加前の
vendor/bin/phpunit --testsuite http --no-progress: green(234 tests, 1222 assertions)。 - 2026-06-10 admin customer follow-up 後の
vendor/bin/psalm --no-progress: green(errors 0、info 180)。 - 2026-06-10 admin customer follow-up 後の
composer doc:api: green。docs/api/audit.mdは resources 147 / operations 237 / request schema 157 / gaps 0。 - 2026-06-10 admin customer follow-up 後の
HttpAdminCustomerDeleteHtmlTest: green(1 test, 12 assertions)。 - 2026-06-10 admin customer follow-up 後の
FlowAdminCustomerMaintenanceTest+Http\FlowAdminCustomerMaintenanceTest: green(12 tests, 82 assertions)。 - 2026-06-10 admin customer follow-up 後の
vendor/bin/phpunit --testsuite http --no-progress: green(235 tests, 1234 assertions)。 - 2026-06-10 admin customer follow-up 後の
vendor/bin/psalm --no-progress: green(errors 0、info 180)。 - 2026-06-10 admin customer follow-up 後の
npm run web:e2e -- --run-id=20260610-web-db-all-routes --base-url=http://127.0.0.1:18080: feature 104 pass / 77 fail / 5 targetOut、OpenAPI 159 pass / 75 fail / 3 targetOut、NG 19 pass / 0 fail。 - 2026-06-10 product follow-up 後の
AdminProductResourceTest+AdminProductBulkStatusResourceTest+AdminProductListHtmlRenderTest+FlowAdminProductPublishTest+Http\FlowAdminProductPublishTest: green(49 tests, 283 assertions)。 - 2026-06-10 product follow-up 後の
vendor/bin/phpunit --testsuite hypermedia --no-progress: green(267 tests, 1293 assertions)。 - 2026-06-10 product follow-up 後の
vendor/bin/phpunit --testsuite http --no-progress: green(235 tests, 1234 assertions)。 - 2026-06-10 product follow-up 後の
vendor/bin/psalm --no-progress: green(errors 0、info 180)。 - 2026-06-10 product follow-up 後の
npm run web:e2e -- --run-id=20260610-web-db-all-routes --base-url=http://127.0.0.1:18080: feature 110 pass / 71 fail / 5 targetOut、OpenAPI 164 pass / 70 fail / 3 targetOut、NG 19 pass / 0 fail。 - 2026-06-10 category/tag follow-up 後の
AdminCategoryResourceTest+AdminTagResourceTest+AdminCategoryEditHtmlRenderTest: green(29 tests, 65 assertions)。 - 2026-06-10 category/tag follow-up 後の
FlowAdminCategoryMaintenanceTest+FlowAdminTagMaintenanceTest: green(12 tests, 65 assertions)。 - 2026-06-10 category/tag follow-up 後の HTTP projection
FlowAdminCategoryMaintenanceTest+FlowAdminTagMaintenanceTest: green(12 tests, 65 assertions)。 - 2026-06-10 category/tag follow-up 後の
npm run web:e2e -- --run-id=20260610-web-db-all-routes --base-url=http://127.0.0.1:18080: feature 115 pass / 66 fail / 5 targetOut、OpenAPI 167 pass / 67 fail / 3 targetOut、NG 19 pass / 0 fail。 - 2026-06-10 payment follow-up 後の
AdminPaymentResourceTest+AdminPaymentEditHtmlRenderTest+AdminPaymentListHtmlRenderTest+FlowAdminShopConfigurationTest+ HTTP projectionFlowAdminShopConfigurationTest: green(61 tests, 285 assertions)。 - 2026-06-10 payment follow-up 後の
npm run web:e2e -- --run-id=20260610-web-db-all-routes --base-url=http://127.0.0.1:18080: feature 117 pass / 64 fail / 5 targetOut、OpenAPI 169 pass / 65 fail / 3 targetOut、NG 19 pass / 0 fail。 - 2026-06-10 非会員購入 follow-up 後の
HttpCheckoutEntryFormTest --filter NonMember: green(2 tests, 47 assertions)。有効な browser form submit が 303 で/shopping/confirm?preOrderId=...&paymentMethodId=...へ進む契約を確認した。 - 2026-06-10 非会員購入 follow-up 後の
OrderConfirmedTest --filter Guest: green(1 test, 14 assertions)。customerIdを持たない非会員注文は注文者スナップショットから確認画面の customer projection を作る。 - 2026-06-10 非会員購入 follow-up 後の
HttpCheckoutEntryFormTest、OrderConfirmedTest+NonMemberSubmittedTest+CheckoutCompletedTest+AdminOrderFetchedTest、ShoppingConfirmResourceTest+ShoppingCompleteResourceTest+AdminOrderResourceTest: green。 - 2026-06-10 非会員購入 follow-up 後の
vendor/bin/phpunit --testsuite hypermedia --no-progress: green(287 tests, 1395 assertions)。 - 2026-06-10 非会員購入 follow-up 後の
vendor/bin/phpunit --testsuite http --no-progress: green(251 tests, 1359 assertions)。 - 2026-06-10 非会員購入 follow-up 中の in-app browser 接続は
Browser is not available: iabで不可。実ブラウザーでのスクリーンショット再証跡は未完了。 - 2026-06-10 非会員購入 follow-up 中に
tests/Resource/Sql/CheckoutResourceSqlTest.phpを直接実行したところ、既存のSqlFixturesTrait/be/tests/Sql/bootstrap.php削除により PHPUnit load 前に停止した。SQL-backed Resource suite は現 worktree では検証ゲートとして使えない。 - 2026-06-11 fresh DB seed 後の
HttpSqlNonMemberCheckoutFormTest: green(1 test, 31 assertions)。SQL HTML context で非会員フォーム有効POST後、confirm画面にメールと代金引換が表示されることを確認した。 - 2026-06-11 fresh DB seed 後の実サーバー
127.0.0.1:18080: GET/shopping/non-member-> 有効フォームPOST は 303、GET/shopping/confirm?...は 200。confirm HTML に入力メールと代金引換(¥0)を確認した。 - 2026-06-11 payment setup 削除後の
FlowCustomerPurchaseTest+ HTTP projection +WorkflowBackdoorStateCoverageTest: green(138 tests, 515 assertions)。 - 2026-06-11 browser runner regression
npm run web:e2e -- --run-id=20260611-non-member-browser-regression --base-url=http://127.0.0.1:18080 --limit=60 --skip-negative --no-probe-uncovered --no-update-matrix: setup business state は pass。POST /shopping/non-memberevidence は 303 Location、confirm finalUrl、非会員メール、代金引換、screenshot を保存した。feature summary は pass 58 / fail 126 / targetOut 2 だが、fail の大半は--limit=60による未実行行であり、この run は非会員購入境界の差し替え証跡として扱う。 - 2026-06-11 規格/規格分類 follow-up 後の
FlowAdminClassMaintenanceTest+ HTTP projection: green(30 tests, 180 assertions)。class-name/class-category の create -> readback -> update -> readback -> delete -> readback を、固定 unsafe URI ではなくLink/Locationから確認した。 - 2026-06-11 規格/規格分類 follow-up 後の
AdminClassNameListHtmlRenderTest+AdminClassCategoryListHtmlRenderTest: green(6 tests, 33 assertions)。HTML form が canonical fieldclassNameLabel/classCategoryNameを送信し、backend_nameを送信しないことを確認した。 - 2026-06-11 browser runner regression
npm run web:e2e -- --run-id=20260611-admin-class-browser-regression-fixed --base-url=http://127.0.0.1:18080 --limit=83 --skip-negative --no-probe-uncovered --no-update-matrix: rows 072-074 / 078-080 は pass。規格/規格分類 CRUD の HTTP status はすべて 303、Locationreadback とスクリーンショットをdocs/web-e2e/screenshots/20260611-admin-class-browser-regression-fixed/setup/に保存した。061/067/076/082/083 は unsafe 未実行 fail のまま残す。 - 2026-06-11 規格/規格分類 follow-up 後の
vendor/bin/phpunit --testsuite hypermedia --no-progress: green(323 tests, 1532 assertions)。 - 2026-06-11 規格/規格分類 follow-up 後の
vendor/bin/phpunit --testsuite http --no-progress: green(266 tests, 1485 assertions)。 - 2026-06-11 規格/規格分類 follow-up 後の
vendor/bin/psalm --no-progress: green(errors 0、info 180)。 - 2026-06-11 root/no-password DB URL(
mysql://root@127.0.0.1:3306/eccubedb_test?...)でのHttpSqlNonMemberCheckoutFormTest: green(3 tests, 74 assertions)。空POSTは400でフォーム内エラーを表示し、メール確認不一致は入力値を再表示する。 - 2026-06-11 root/no-password DB URL での
HttpSqlCustomerRegistrationFormTest: green(2 tests, 82 assertions)。登録NGのinline error、登録成功、ログイン303 /mypage、/mypage/changeでの登録メール readback を確認した。 - 2026-06-11 root/no-password DB URL での registration/non-member 関連 targeted gate:
FlowCustomerRegistrationTest+ HTTP projection +HttpCheckoutEntryFormTest+HttpSqlNonMemberCheckoutFormTest+HttpSqlCustomerRegistrationFormTestは green(27 tests, 396 assertions)。 - 2026-06-11 root/no-password DB URL での
HttpSqlAdminCsvUploadFormTest: green(2 tests, 51 assertions)。商品CSV multipart upload は 303/admin/product-list後に商品詳細で productCode/name をreadback、カテゴリCSV multipart upload は 303/admin/category/category-list後にカテゴリ一覧で categoryName をreadbackした。 - 2026-06-11 browser runner regression
npm run web:e2e -- --run-id=20260611-admin-csv-browser-regression --base-url=http://127.0.0.1:18080 --limit=83 --skip-negative --no-probe-uncovered --no-update-matrix: row 061 商品CSV取込と row 067 カテゴリCSV取込は pass。POST /admin/product-csvは 303 + 商品詳細readback screenshot、POST /admin/category/csvは 303 + カテゴリ一覧readback screenshot を保存した。 - 2026-06-11 browser runner regression
npm run web:e2e -- --run-id=20260611-admin-class-csv-browser-regression --base-url=http://127.0.0.1:18080 --limit=83 --skip-negative --no-probe-uncovered --no-update-matrix: row 076 規格CSV取込と row 082 規格分類CSV取込は pass。POST /admin/product/csv-class-nameは 303 + 規格一覧readback screenshot、POST /admin/product/csv-class-categoryは 303 + 規格分類一覧readback screenshot を保存した。row 083 商品規格編集は、保存Resource/Be Finalがないため fail のまま。 - 2026-06-11 order-history maildate regression: まず
FlowCustomerPurchaseTestに会員購入 -> admin配送先更新 -> admin追跡番号更新 -> admin受注メール送信 -> 会員注文履歴詳細のステップを追加し、mailHistories[0].sendDateschema error を再現した。order_history_by_order_no.sql修正後、FlowCustomerPurchaseTestは green(45 tests, 177 assertions)、HTTP projectiontests/Http/FlowCustomerPurchaseTest.phpも green(45 tests, 177 assertions)。 - 2026-06-11 browser runner regression
npm run web:e2e -- --run-id=20260611-order-history-maildate-regression --base-url=http://127.0.0.1:18080 --limit=109 --skip-negative --no-probe-uncovered --no-update-matrix: feature 102 pass / 82 fail / 2 targetOut、OpenAPI 103 pass / 131 fail / 3 targetOut。025 注文履歴一覧と 026 注文履歴詳細は 200 pass、105 受注メール送信も setup operation evidence で pass。この時点の fail は既知の 083/091/096/098/108 と--limit=109による未実行行が中心だったが、108 は20260611-admin-order-shipping-csv-import-regression-fixed、098 は20260611-admin-order-bulk-delete-browser-regressionで後続修正済み。 - 2026-06-11
tests/Resource/Sql/MypageHistoryResourceSqlTest.phpはSqlFixturesTraitが現 worktree に存在せず、PHPUnit load 前に停止した。sendDateassertion は追加したが、この suite は引き続き SQL-backed Resource suite restoration 境界として扱う。 - 2026-06-11 出荷CSV取込 follow-up 後の
FlowAdminOrderFulfillmentTest: green(33 tests, 138 assertions)。POST /admin/order/import-shippingは受注flow由来の注文番号を使い、CSV upload 後に出荷CSV export でTRK-CSV-*の追跡番号を readback する。 - 2026-06-11 出荷CSV取込 follow-up 後の HTTP projection
tests/Http/FlowAdminOrderFulfillmentTest.php: green(33 tests, 138 assertions)。 - 2026-06-11 browser runner regression
npm run web:e2e -- --run-id=20260611-admin-order-shipping-csv-import-regression-fixed --base-url=http://127.0.0.1:18080 --limit=109 --skip-negative --no-probe-uncovered --no-update-matrix: row 108 出荷CSV取込は pass。POST /admin/order/import-shippingはhttpStatus=200、import後の出荷CSV export に注文番号とTRK-CSV-*が含まれることを確認し、スクリーンショットdocs/web-e2e/screenshots/20260611-admin-order-shipping-csv-import-regression-fixed/setup/admin-order-shipping-csv-import.pngを保存した。 - 2026-06-11 受注削除 follow-up 後の
HttpSqlAdminOrderBulkDeleteFormTest: green(1 test, 80 assertions)。SQL HTML context で商品作成 -> 非会員購入 -> 受注一覧 formids[]/ hiddenmode/ JS action readback ->POST /admin/order/bulk-delete->303 /admin/order-list-> 受注詳細注文取消readback を確認した。 - 2026-06-11 browser runner regression
npm run web:e2e -- --run-id=20260611-admin-order-bulk-delete-browser-regression --base-url=http://127.0.0.1:18087 --limit=98 --skip-negative --no-probe-uncovered --no-update-matrix: row 098 受注削除は pass。POST /admin/order/bulk-deleteはhttpStatus=303、Location=/admin/order-list、mode=order_bulk_delete_form、対象注文番号、受注詳細注文取消readback、スクリーンショットdocs/web-e2e/screenshots/20260611-admin-order-bulk-delete-browser-regression/setup/admin-order-bulk-delete.pngを保存した。 - 2026-06-11 特定商取引法 follow-up 後の
HttpSqlAdminTradeLawFormTest: green(1 test, 30 assertions)。SQL HTML context でGET /admin/trade-lawの行フォームtrade_law_1_name/trade_law_1_descriptionと hidden CSRF を読み、POST /admin/trade-law後に303 /admin/trade-law、再GETで更新行をreadbackした。 - 2026-06-11 browser runner regression
npm run web:e2e -- --run-id=20260611-admin-trade-law-browser-regression --base-url=http://127.0.0.1:18088 --limit=127 --skip-negative --no-probe-uncovered --no-update-matrix: row 127 特定商取引法更新は pass。POST /admin/trade-lawはhttpStatus=303、Location=/admin/trade-law、EC-CUBE互換行フォームからのtradeLawBody正規化、管理画面readback、スクリーンショットdocs/web-e2e/screenshots/20260611-admin-trade-law-browser-regression/setup/admin-trade-law-update.pngを保存した。 - 2026-06-11 form negative regression
npm run web:e2e -- --run-id=20260611-form-negative-regression --base-url=http://127.0.0.1:18080 --limit=43 --no-probe-uncovered --no-update-matrix: negative cases 19 pass / 0 fail。entry/non-member の空POSTは400で同じフォーム画面に戻り、inline入力してください。を含む。login 認証失敗は401と日本語エラー文を記録した。 - 2026-06-11 form negative targeted gate:
HttpCheckoutEntryFormTest+HttpSqlNonMemberCheckoutFormTest+HttpSqlCustomerRegistrationFormTest: green(13 tests, 344 assertions)。 - 2026-06-11 admin member form targeted gate:
HttpSqlAdminMemberFormTest: green(1 test, 72 assertions)。create/detail/update/list/delete を SQL HTML context のフォーム action/CSRF/redirect/readback で確認した。 - 2026-06-11 admin member related gates:
AdminMemberHtmlRenderTest: green(3 tests, 18 assertions)、FlowAdminSystemOperationTest: green(23 tests, 95 assertions)、HTTP projectiontests/Http/FlowAdminSystemOperationTest.php: green(23 tests, 95 assertions)。HTTP projection の初回失敗は stale compiled DI と並列 PHPUnit 実行による DB deadlock で、cache cleanup 後に直列再実行して green。 - 2026-06-11 admin member combined targeted gate:
HttpSqlAdminMemberFormTest+AdminMemberHtmlRenderTest+ Hypermedia/HTTPFlowAdminSystemOperationTestを直列実行し green(51 tests, 285 assertions)。BEAR.Dev.HtmlLinkAuditwarning は残るが failure ではないため、HTML link audit follow-up として別に扱う。 - 2026-06-11 admin system targeted gate:
HttpSqlAdminSystemFormTest+AdminSecurityResourceTest+ Hypermedia/HTTPFlowAdminSystemOperationTestを stale compiled context cleanup 後に直列実行し green(52 tests, 225 assertions)。Security form は実 CSRF token と_method=putを使い、trustedHostsの runtime readback を確認した。 - 2026-06-11 admin system browser regression
npm run web:e2e -- --run-id=20260611-admin-system-browser-regression-fixed --base-url=http://127.0.0.1:18080 --limit=150 --skip-negative --no-probe-uncovered --no-update-matrix: feature summary は pass 134 / fail 50 / targetOut 2、OpenAPI は pass 135 / fail 99 / targetOut 3。146 セキュリティ設定更新と 150 二要素認証実行は setup operation evidence で pass。fail の大半は--limit=150による未実行行と既知の Admin unsafe operations であり、この run は admin system 146/150 の限定証跡として扱う。 - 2026-06-11 admin calendar targeted gate:
AdminCalendarResourceTest+AdminCalendarHtmlRenderTest+ Hypermedia/HTTPFlowAdminShopConfigurationTest+HttpSqlAdminCalendarFormTestを直列実行し green(55 tests, 375 assertions)。定休日 create -> update -> readback -> delete -> readback を Resource/HTTP/HTML form の全境界で確認した。 - 2026-06-11 admin calendar browser regression
npm run web:e2e -- --run-id=20260611-admin-calendar-browser-regression-fixed --base-url=http://127.0.0.1:18080 --limit=125 --skip-negative --no-probe-uncovered --no-update-matrix: row 124/125 は setup operation evidence で pass。feature summary は pass 119 / fail 65 / targetOut 2、OpenAPI は pass 120 / fail 114 / targetOut 3。fail の大半は--limit=125による未実行行と既知の Admin unsafe operations であり、この run は calendar 124/125 の限定証跡として扱う。 - 2026-06-11 content operation targeted gate:
HttpSqlAdminContentOperationFormTest+AdminContentSideEffectResourceTest: green(10 tests, 130 assertions)。Cache clear は form から 303 PRG、Maintenance は enable/disable の readback、CSS/JS は form submit 後の textarea readback を確認した。 - 2026-06-11 content operation related gate: Hypermedia/HTTP
FlowAdminSystemOperationTest: green(46 tests, 190 assertions)。BEAR.Dev.HtmlLinkAuditwarning は残るが failure ではないため、HTML link audit follow-up として別に扱う。 FlowCustomerInquiryTest+FlowCustomerRegistrationTest: green。FlowCustomerPurchaseTest+FlowCustomerRegistrationTest: green。実行前後でdtb_customer件数が増えないことを確認済み。FlowAdminMasterDataUpdateTest: green。FlowAdminProductPublishTest: green。admin product create -> update -> copy -> bulk status update -> delete -> storefront readback を Hypermedia + HTTP で確認済み。FlowAdminCsvExchangeTest: green。FlowAdminMasterDataUpdateTest+FlowAdminCsvExchangeTest: green。FlowAdminCsvExchangeTest+FlowAdminShopConfigurationTest: green。FlowAdminOrderFulfillmentTest+FlowAdminProductPublishTest+FlowAdminShopConfigurationTest+FlowAdminSystemOperationTest: green。WorkflowBackdoorStateCoverageTest+WorkflowSkeletonCoverageTest: green。composer test -- --no-progress: green(1935 tests, 27375 assertions, Memory 138.50 MB)。
修正済み:
WorkflowDbSessionはhtml-prod-eccube-sql-hal-appではなくhtml-eccube-sql-hal-appを使う。in-process Hypermedia workflow は Resource 操作と readback query が同じ SQL connection/transaction を共有する必要があり、HTTP/prod 境界は HTTP workflow で別途確認する。- 旧挙動では Resource POST 直後に transaction 側 connection から行が見えず、
restore()後にdtb_customer行が残った。現在はWorkflowDbSessionTestとFlowCustomerPurchaseTest+FlowCustomerRegistrationTestで rollback を確認している。 FlowCustomerInquiryTestはtest-hal-appfake context からWorkflowDbSessionの SQL-backed workflow へ移した。問い合わせ送信は NoopMailer 境界なので、Web+DB 主証跡として扱える。FlowAdminMasterDataUpdateTestはadmin-test-hal-appfake context からWorkflowDbSessionの SQL-backed workflow へ移した。MasterDataWriterInterfaceの実装は in-memory 境界で、破壊的 DB/file 更新は行わない。- 旧再現の
FlowAdminMailTemplateMaintenanceTest->FlowAdminMasterDataUpdateTestとFlowCustomerAccountMaintenanceTest->FlowCustomerInquiryTestはどちらも green。 - HTTP projection の
FlowAdminMasterDataUpdateTestは、他の Admin HTTP workflow と同じprod-json-index.php境界へ揃えた。古いadmin-json-index.phpはX-BeMart-Test-Admin-Id/ CSRF header を session へ反映しないため、PUT が 403 になっていた。 flow-admin-product-publishにdoCopyProduct、doBulkUpdateProductStatus、doDeleteProductと削除後 readback を追加した。操作URLは admin product/list 表現の rel から取得し、固定URIや runner 専用 payload は追加していない。product_copy.sqlとproduct_status_bulk_update.sqlは、末尾SELECTが semicolon で終わっておらず Ray MediaQuery の SQL split で最後の readback/count query が実行されていなかった。SQL 終端を修正し、copy readback とchangedCountを SQL-backed workflow で確認した。- Admin 商品一覧 HTML に、copy/delete/bulk status の unsafe action token と action を実 affordance として出した。delete は
_method=deleteを POST body で送る HTML 境界に直し、bulk status/delete は HTML context で 303/admin/product-listへ PRG する契約にした。AdminProductListHtmlRenderTest、AdminProductBulkStatusResourceTest、AdminProductResourceTestと Web+DB runner で確認済み。 flow-admin-category-maintenanceとflow-admin-tag-maintenanceを追加した。カテゴリは一覧のdoCreateCategoryrel から作成、Locationの詳細 readback、詳細表現のdoUpdateCategory/doDeleteCategoryrel から更新・削除、削除後 list readback まで確認した。タグは一覧のdoCreateTagrel から作成、一覧 readback、doDeleteTagrel から削除、削除後 list readback まで確認した。- Category HTML に削除 affordance を追加し、HTML context の create/update/delete は 303 PRG として確認した。
tcategory_remove.sqlは末尾 semicolon 欠落により MediaQuery の最後の DELETE が実行されていなかったため修正した。 - Web+DB runner はカテゴリ/タグについても、HTML form action / anchor token /
Locationから unsafe operation を実行する。カテゴリ詳細 readback は本文ではなくinput[name="categoryName"]の value を正として確認する。 - Web+DB runner は支払い方法についても、HTML form action / anchor token /
_method/Locationから unsafe operation を実行する。購入用の支払方法を削除しないため、maintenance 用の別支払方法を作成し、更新 readback と削除後 list readback を確認する。 MailTemplateStorageInterface::update()がvoidになったため、戻り値を持つ fake fixture として残っていたbe/var/fake/query/tmail_template_update.jsonlを削除した。これは fake を足す修正ではなく、MediaQuery coverage guard の「non-void DbQuery だけが fake fixture を持つ」契約に合わせた。- 新規
POST page://self/admin/mail-template/createResource に対応する smoke fixture を追加した。ResourceSmoke の母集団と Resource meta の不一致を解消するためで、業務状態作成の主証跡としては扱わない。 flow-admin-order-fulfillmentは admindoCreateOrderではなく、admin affordance で支払方法と商品を作成し、storefront の商品一覧 -> 商品詳細 -> cart -> non-member checkout -> complete で得たorderNoを admin 受注更新/対応状況/配送先/追跡番号/メール/PDF/CSV に渡す形へ修正した。Hypermedia/HTTP targeted はどちらも green(31 tests, 118 assertions)。flow-admin-mail-template-maintenanceの受注メール送信確認も admindoCreateOrder依存を削除し、storefront checkout 由来のorderNoでgoOrderMail/doSendOrderMailを確認する形へ修正した。Hypermedia/HTTP targeted はどちらも green(9 tests, 91 assertions)。WorkflowBackdoorStateCoverageTestに、required workflow でdoCreateOrderを使った場合に fail する guard を追加した。手元の grep でもtests/Hypermedia/tests/Http/tests/SupportのdoCreateOrder残存は 0 件。WorkflowBackdoorStateCoverageTestに、flow-customer-purchaseがdoCreatePaymentを使った場合に fail する guard を追加した。支払方法CRUDはflow-admin-shop-configurationの責務で、購入flowの前提作成に使わない。flow-admin-customer-maintenanceを追加し、admin customer list のdoCreateCustomerrel から作成、Locationの詳細 readback、goCustomerListでの検索 readback、doDeleteCustomerrel での削除、削除後 list return まで確認した。Hypermedia/HTTP targeted はどちらも green(各 6 tests, 41 assertions; combined 12 tests, 82 assertions)。browser runner ではCreateCustomerのLocation: /admin/customer?email=...と一覧行から会員IDを観測して 087 を pass にし、POST /admin/delete-customerは HTML context の PRG 303 と削除後 0件 readback で 089 を pass にした。CustomerListのdoCreateCustomerrel を実 Resource/OpenAPI と同じpage://self/admin/create-customerに直し、doDeleteCustomer/doResendActivationMailrel も Resource 表現に追加した。HTTP projection では stale compiled context が古い link を返したため、var/tmp/*eccube-sql-hal-appを消して再実行し、source と runtime の不一致であることを確認した。
現時点で 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 の実装変更は行わない。
確認済み:
vendor/bin/phpunit --testsuite hypermedia --no-progress: green。FlowAdminOrderFulfillmentTestを含む複数 Hypermedia workflow の targeted 実行: green。vendor/bin/phpunit --testsuite http --no-progress: green。vendor/bin/psalm --no-progress: green。composer test -- --no-progress: green。
未確認:
- raw
vendor/bin/phpunitも green にすべきか、既存composer test契約を正式な full suite command として docs/AGENTS 側へ寄せるべきか。 - browser runner の PDF download evidence と PHPUnit PDF export の検証責務をどう分けるべきか。
禁止する回避:
- 新規の
memory_limit引き上げを、既存composer test契約の確認なしに追加する。 testExportsOrderPdfを skip/incomplete にする。- PDF export の検証を削除する。
- テスト専用の軽量 PDF renderer に差し替えて業務境界を隠す。
HTML link audit warnings
Full suite green でも BEAR.Dev.HtmlLinkAudit warning は多数出力される。主な reason は target-missing と html-missing。これは今回の green 判定では failure ではないが、Hypermedia 完成判定では無視し続けるべきではない。
扱い方:
- warning を抑制して green 表示をきれいにするだけの変更はしない。
- Resource meta 上の URI、HTML template の form/action/link、ALPS rel のどれが正準かを確認してから、必要な
#[Link]または HTML affordance を直す。 - Web+DB runner の Admin unsafe operation を閉じるときに、同じ rel/action の warning も一緒に減らす。
SQL-backed Resource suite restoration
tests/Resource/Sql/WithdrawResourceSqlTest.php の直接実行では、既存の SqlFixturesTrait 定義がこの worktree で見つからず PHPUnit bootstrap 前に停止する。さらに AbstractResourceSqlTestCase が前提にする be/tests/Sql/bootstrap.php も現 worktree に存在しない。
確認済み:
composer.jsonのtest:sqlはSQL PHPUnit suite is disabled; Sql folders are ignored by phpunit.xml.を表示するだけ。phpunit.xmlはtests/Resource/Sqlを fake suite から除外しているが、SQL suite を定義していない。- 履歴では
c47dd51a Remove SQL PHPUnit suiteがbe/tests/Sql一式を削除している。復元する場合は履歴版のbootstrap.php/SqlFixturesTrait.php/AbstractSqlTestCase.phpを現在のsql/setup-db.shと docs に合わせて戻す。 sql/README.mdはvendor/bin/phpunit --testsuite bemart-sqlと Resource SQL の実行を記載しているが、現composer.json/phpunit.xmlとは一致しない。sql/README.mdは DB unreachable を fail fast とし、docs/methodology/sql-test-baseline.mdは unreachable を skip としており方針が矛盾している。
この suite は Web+DB 完成判定の主証跡ではなく、SQL-backed Resource の境界テストである。直接 SQL fixture はここでは許容されうるが、Hypermedia/HTTP/browser の業務状態作成には使わない。
復元する場合の最小方針:
be/tests/Sql/bootstrap.phpを履歴から戻し、現AbstractResourceSqlTestCaseが期待する['skip' => bool, 'reason'?, 'pdo'?]shape に合わせる。SqlFixturesTraitは履歴版をベースに、現tests/Resource/Sqlが使う helper だけを schema/FK/NOT NULL に沿って復元する。空実装・固定dummy戻り値は禁止。phpunit.xml/composer test:sql/sql/README.mdの suite 名と skip/fail 方針を揃える。- 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より難しい理由:
- 071-082 は
dtb_class_name/dtb_class_categoryのマスタCRUDだが、083 はそのマスタを商品へ結びつけるdtb_product_classのSKU行編集で、対象テーブルも業務意味も違う。 - EC-CUBE の商品規格編集は、規格1 × 規格2 の matrix から複数SKU行を作り、それぞれに商品コード、価格、在庫、在庫無制限、送料などを持たせる。現在のTwig portは editor shell と空の新規行だけで、既存商品から ProductClass matrix を読む read model がない。
- HTML form は
POST /admin/product/product-class、matrix はPUT /admin/product/product-classを期待しているが、Resource method、ALPS descriptor、OpenAPI request schema、Be Input/Final、SQL write contract が揃っていない。 - 商品詳細、カート、注文は
ProductClassQueryInterface/dtb_product_classを参照するため、083 の保存は表示だけでなく購買導線の SKU 解決にも影響する。保存後の readback は管理画面だけでなく、必要に応じて商品詳細またはカート投入まで確認する。
083 を green にしてよい条件:
- Hypermedia workflow を先に追加し、admin product detail から
goAdminProductProductClassを辿って ProductClass editor に入り、保存 affordance を表現する。 onGet()が対象商品の既存 ProductClass 行を read model として返し、class-name/class-category 由来のIDと表示名、商品コード、価格、在庫、在庫無制限、送料を画面に出す。- 保存 transition は Resource/OpenAPI/ALPS/HTML form/Be Input/Final/SQL が同じ field shape を共有する。直接SQL seedで ProductClass を作って通すのは禁止する。
- OK case は保存後に 303 PRG し、管理画面または商品詳細で更新後のSKU情報を readback する。
- 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 から実行する。
確認済み:
FlowAdminCustomerMaintenanceTest: green(6 tests, 41 assertions)。Http\FlowAdminCustomerMaintenanceTest: green(6 tests, 41 assertions)。FlowAdminCustomerMaintenanceTest+Http\FlowAdminCustomerMaintenanceTest: green(12 tests, 82 assertions)。vendor/bin/phpunit --testsuite hypermedia --no-progress: green(267 tests, 1293 assertions)。vendor/bin/phpunit --testsuite http --no-progress: green(235 tests, 1234 assertions)。
未完成として残す境界:
Admin\CustomerはonGet()のみで、HTML form は/admin/customer?customerId=...に POST する。OpenAPI 上も admin customer update operation はなく、ALPS でも admin 用の update transition は定義されていない。ここにPUT /admin/customerworkflow をテスト都合で作らない。Admin\CustomerDeliveryEditは GET renderer のみで、docblock も「この wave では永続化 ALPS transition なし」としている。HTML form は空 action の POST だが、OpenAPI/Resource 上の保存 operation はない。PUT /admin/customer-delivery-editをテスト都合で追加しない。ResendActivationMailは Resource/OpenAPI/ALPS があるが、admin create と public entry はどちらもstatus=2の有効会員を作る。再送対象の仮登録会員(customerStatus=1かつsecretKeyあり)を Web/HTTP 遷移で作る導線がまだない。直接DBで provisional customer を作らない。さらに public registration の完了画面は「仮登録完了」と表示する一方で、実際の registered customer は即時ログイン可能な本会員として保存される。この不一致を隠して再送だけ pass にしない。次に進めるなら、entry -> mail noop/secretKey -> activation -> login の email verification branch を先に workflow 化する。- Web+DB browser runner は 237-operation 母集団で再実行済み。matrix の 087/089 は、実フォーム/HTTP境界の evidence と readback が取れたため pass に更新した。
次に実装する場合は、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 とした。
PUT /admin/order: 受注詳細フォームから保存し、受注詳細 readback を確認。POST /admin/order-status: 受注一覧のステータス変更 affordance から送信し、対象注文の状態更新を確認。PUT /admin/order/shipping-address: 配送先フォームから保存し、GET /admin/order/export-shippingのCSV readbackで住所・電話番号を確認。PUT /admin/order/tracking-number: 受注一覧の追跡番号 action から送信し、JSON{"status":"OK"}と出荷CSV readbackを確認。POST /admin/order/shipping-notify-mail: 出荷通知メール画面のフォームから fake/noop 境界として送信。POST /admin/order/send-mail: 受注メール確認画面のフォームから fake/noop 境界として送信。GET /admin/order/export-order,GET /admin/order/export-shipping,GET /admin/order/export-order-pdf: 同一認証CookieのHTTP境界でCSV/PDF downloadを確認。
この修正で、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 から削除を確認した。
- HTML form:
#form_bulkが hiddencsrfTokenとmode=order_bulk_delete_form、対象行 checkboxids[]を出すことを確認。 - Browser/HTTP: 受注一覧画面の JS affordance が公開する
/admin/order/bulk-deleteを action として使い、同一 cookie/CSRF でids[]を POST、303 /admin/order-listを確認。 - Readback:
GET /admin/order?orderNo=...で対象注文の対応状況が注文取消になったことを確認。スクリーンショットはdocs/web-e2e/screenshots/20260611-admin-order-bulk-delete-browser-regression/setup/admin-order-bulk-delete.png。 - Regression:
HttpSqlAdminOrderBulkDeleteFormTestは SQL HTML context で商品作成 -> 非会員購入 -> 受注一覧 form 検出 -> bulk delete -> 受注詳細 readback を直接SQL seedなしで確認する。
未完成として残す境界:
POST /admin/order/create: 2026-06-11 follow-up で、受注0件の/admin/order-listにも新規作成リンクを表示し、blank editor の form action を/admin/order/createに切り替えた。HttpSqlAdminOrderCreateFormTestは SQL HTML context でGET /admin/order-list->GET /admin/order/edit-> form action POST ->303 /admin/order?orderNo=...-> 受注詳細 readback と、数値項目NGの400 {"code":400,"message":"paymentMethodId"}を確認する。限定 browser run20260611-admin-order-create-browser-regression-fixed2ではPOST /admin/order/createが setup operation evidence として pass、詳細画面で customerId/productCode/productName/請求金額を readback した。ただし required workflow の注文作成は引き続き storefront checkout 由来を正とし、admin direct create を業務状態seedとして使わない。POST /admin/order/import-shipping: 2026-06-11 follow-up で CSV upload 後の永続化と出荷CSV readback を Hypermedia/HTTP/browser に戻し、pass に更新した。今後の全件runで matrix と OpenAPI operation 集計を確定する。- 注文履歴一覧/詳細: 同じ
fixed4run で/mypage/historyと/mypage/order-historyがmailHistories[0].sendDateの形式不正 400 になった。これはFlowCustomerPurchaseTestに会員購入 -> admin受注メール送信 -> 会員注文履歴詳細の regression を追加して再現した。原因は MariaDBJSON_OBJECTがdtb_mail_history.send_dateを2026-06-11 06:00:00.000000のようにマイクロ秒付きで返し、schema が EC-CUBE/Fake 観察の秒までの日時を期待していたこと。order_history_by_order_no.sqlでDATE_FORMAT(..., '%Y-%m-%d %H:%i:%s')に揃え、Hypermedia/HTTP/browser で 025/026 が green に戻った。
メールは実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 で同じ業務状態を作れなかったこと。
修正後の確認:
- HTML form: 新規作成は
/admin/memberへ POST、編集は/admin/member?_method=put、削除は一覧の POST form/admin/member?loginId=...&_method=deleteを使う。各フォームはcsrfTokenとmode=member_formを送る。 - HTTP/SQL:
HttpSqlAdminMemberFormTestは admin login 後にフォームからメンバーを作成し、Locationの詳細画面で loginId/name/authority を readback、編集で name を更新、一覧の削除フォームから soft delete して303 /admin/member-listを確認する。 - Hypermedia/HTTP projection:
FlowAdminSystemOperationTestは従来の admin system workflow として green。HTML form regression はこの workflow が覆っていなかった browser boundary を補う。
残す境界:
department、work、2FA、password change、編集時の authority 変更は今回実装しない。現UpdateMemberInputはname更新のみで、doc/comment でも department は Wave 8 外とされているため、テストを通すためだけの永続化列や dummy state は追加しない。- SQL-backed Resource suite の直接実行は
SqlFixturesTrait不在で PHPUnit load 前に停止する。admin member の主証跡は Hypermedia/HTTP/HTML form regression とし、SQL Resource suite restoration は別 follow-up に残す。 20260611-content-operation-browser-regressionでは 139-142 は fail だったが、原因は runner setup の未接続と stale compiled template/cache だった。MemberList.html.twigの外側 wrapper を<form>から<div id="form1" data-form-name="form1">に変え、削除 form をブラウザ DOM 上の affordance として見えるようにした後、20260611-admin-member-browser-regression-emailfixで 139-142 は pass に更新した。
2026-06-11 配送方法CRUD回帰
全件run 20260611-web-db-all-routes では配送方法作成/編集/削除が browser fail のままだった。原因は Web+DB runner が既存ID前提の画面到達だけを見ており、配送方法を実フォームから作成して、そのIDで編集/削除する業務状態を作っていなかったこと。
修正後の確認:
- Hypermedia:
FlowAdminShopConfigurationTestにtestConfirmsDeliveryRemovedを追加し、goDeliveryListで削除後一覧を readback する。 - HTTP projection:
tests/Http/FlowAdminShopConfigurationTest.phpは同じ workflow を継承し、Resource と同じ delivery create -> update -> delete -> list readback が green。 - Browser/Web+DB: 限定run
20260611-admin-delivery-browser-regressionで 117/118/119 が pass。runner は/admin/delivery/deliveryの HTML form action から create/update を実行し、削除は一覧行のdata-urlと削除モーダル token を使う。削除後一覧に更新後配送名が残らないことを確認する。
証跡:
- 結果JSON:
docs/web-e2e/results/20260611-admin-delivery-browser-regression.json - レポート:
docs/web-e2e/20260611-admin-delivery-browser-regression-report.md - 作成:
docs/web-e2e/screenshots/20260611-admin-delivery-browser-regression/setup/admin-delivery-maintenance-create.png - 編集:
docs/web-e2e/screenshots/20260611-admin-delivery-browser-regression/setup/admin-delivery-maintenance-update.png - 削除:
docs/web-e2e/screenshots/20260611-admin-delivery-browser-regression/setup/admin-delivery-maintenance-delete.png
この 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 していなかった。
修正後の確認:
- Hypermedia/HTTP:
FlowAdminShopConfigurationTestのtestUpdatesBaseInfoが既存の正準契約。doUpdateBaseInforel から POST し、shopNamereadback を確認する。 - Browser/Web+DB: 限定run
20260611-admin-base-info-browser-regressionで 111 が pass。runner は#shop_master_formの action から POST し、HTML form の実フィールド名(shop_name,shop_kana,phone_numberなど)で送る。POST後に/admin/base-infoを再GETし、input[name="shop_name"]が更新値になっていることを確認する。
証跡:
- 結果JSON:
docs/web-e2e/results/20260611-admin-base-info-browser-regression.json - レポート:
docs/web-e2e/20260611-admin-base-info-browser-regression-report.md - 更新:
docs/web-e2e/screenshots/20260611-admin-base-info-browser-regression/setup/admin-base-info-update.png
この 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 に接続されていなかったこと。
修正後の確認:
- Resource/HTML:
GET /admin/trade-lawは hiddencsrfTokenとmode=trade_law_formを出す。POST /admin/trade-lawは既存のtradeLawBody直POSTを維持しつつ、HTML行フィールドをname: description形式の本文blobへ正規化する。HTML form mode では303 /admin/trade-lawにPRGする。 - HTTP/SQL:
HttpSqlAdminTradeLawFormTestは admin form action/CSRF/行フィールドからPOSTし、再GETで更新した販売業者・所在地をreadbackする。 - Browser/Web+DB: 限定run
20260611-admin-trade-law-browser-regressionで 127 が pass。runner は form action/admin/trade-lawと hidden CSRFを使い、POST /admin/trade-lawのoperationEvidenceに 303、Location、readback、screenshot を保存した。
証跡:
- 結果JSON:
docs/web-e2e/results/20260611-admin-trade-law-browser-regression.json - レポート:
docs/web-e2e/20260611-admin-trade-law-browser-regression-report.md - 更新:
docs/web-e2e/screenshots/20260611-admin-trade-law-browser-regression/setup/admin-trade-law-update.png
残す境界: 公開側 /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後遷移を代表していなかったこと。
修正後の確認:
- Hypermedia/HTTP:
FlowAdminShopConfigurationTestのtestCreatesTaxRuleはHTMLフォームと同じtaxRate文字列、applyDateのYYYY-MM-DDTHH:mm形式で送る。ResourceはapplyDateをYYYY-MM-DD HH:mm:00に正規化し、schemaが要求する正準日時で応答する。 - Resource:
TaxRule::onDeleteは支払/配送DELETEと同じく、HTML contextでは303 /admin/tax-rule/tax-rule-listに戻す。Resource/HAL contextでは従来どおり削除bodyを返す。 - Browser/Web+DB: 限定run
20260611-admin-tax-rule-browser-regression-fixed2で 121/122 が pass。runner は#form1の action から作成POSTを実行し、作成後一覧の#ex-tax_rule-{id}を確認する。削除は行の削除モーダル内リンクから_method=deleteを実行し、削除後一覧に行が残らないことを確認する。
証跡:
- 結果JSON:
docs/web-e2e/results/20260611-admin-tax-rule-browser-regression-fixed2.json - レポート:
docs/web-e2e/20260611-admin-tax-rule-browser-regression-fixed2-report.md - 作成:
docs/web-e2e/screenshots/20260611-admin-tax-rule-browser-regression-fixed2/setup/admin-tax-rule-create.png - 削除:
docs/web-e2e/screenshots/20260611-admin-tax-rule-browser-regression-fixed2/setup/admin-tax-rule-delete.png
この 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) にする。
- 直前画面が実際に公開している HTML form action / link href / Location から unsafe URL を取得する。
- 同一 browser context の cookie と CSRF token で HTTP 境界を送信する。
- HTML context では 303 PRG または期待される HTTP error を確認する。
- 成功系は最終画面で DB readback された業務状態を確認する。削除は一覧非表示または 404 を確認する。
- 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 の例
- 画面 edit form が既存行を prefill できない場合:
GET用の Be Input / Final / SQL read model がないならPUTfeature は fail。テスト側だけで既存値を合成しない。 - 破壊的ファイル操作・外部SMTP・外部決済: restore plan または fake/noop contract がない場合は targetOut または fail。実運用境界を壊して pass にしない。
- Web/HTTP で業務状態を作れない場合: 直接 SQL seed で補わず 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 ができなかった。
修正後の確認:
- HTML form:
/admin/content/cache?_method=putと/admin/content/maintenance?_method=putは hiddencsrfTokenとmode=content_operation_formを送る。Maintenance は canonical fieldenabled=1/0を送る。 - HTTP/SQL:
HttpSqlAdminContentOperationFormTestは cache clear の 303 PRG と readback、maintenance enable ->無効にするreadback、disable ->有効にするreadback、CSS/JS 更新後の textarea readback を確認する。 - Boundary: maintenance state は EC-CUBE 本番 marker file ではなく、ignored
var/tmp/maintenance-mode.flagに限定する。実本番運用ファイルへの反映は引き続き targetOut。 - Resource/Hypermedia: Resource contract は
modeなしでは従来どおり200 OKの action body を返し、HTML form submit のみ303 See Otherにする。
証跡:
HttpSqlAdminContentOperationFormTest+AdminContentSideEffectResourceTest: green(10 tests, 130 assertions)。- Hypermedia/HTTP
FlowAdminSystemOperationTest: green(46 tests, 190 assertions)。 - Limited Web+DB runner
20260611-content-operation-browser-regression: rows 154/156 は setup operation evidence で pass。スクリーンショットはscreenshots/20260611-content-operation-browser-regression/setup/admin-cache-clear.pngとscreenshots/20260611-content-operation-browser-regression/setup/admin-maintenance-enable.png。 - 結果JSON:
docs/web-e2e/results/20260611-content-operation-browser-regression.json - レポート:
docs/web-e2e/20260611-content-operation-browser-regression-report.md
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削除を確認できなかったこと。
修正後の確認:
- HTML form:
/admin/block/blockの新規作成フォームはaction="/admin/block/block-list"、name="blockName"/name="blockFileName"を送る。block_htmlは現Resource contractでは保存対象外なので disabled とし、schema境界へ流さない。 - Resource:
BlockList::onPostとBlock::onDeleteは HTML context で 303 PRG を返す。Block::onDeleteの ALPS はdoDeleteBlockに修正した。 - SQL:
tblock_remove.sqlはdtb_blockとdtb_block_positionを1つの multi-table DELETE で消す。 - Read model:
GetAdminBlockInput/AdminBlockFetchedを追加し、既存BlockStorageInterface::item()を使ってGET /admin/block/block?blockId=...が編集フォームを prefill する。新しい fake store や runner 合成値は追加しない。 - HTTP/SQL:
HttpSqlAdminBlockFormTestは作成 form action、canonical field、作成後Locationの編集フォーム prefill、PUT 303、一覧 readback、削除後一覧非表示を確認する。 - Hypermedia/HTTP projection:
FlowAdminContentPublishTestは block create 後のLocationを辿り、作成した blockId/name を読んでから update する。 - Browser/Web+DB: 限定run
20260611-admin-block-edit-browser-regressionで 166/167/168 が pass。167 はGET /admin/block/block?blockId=...の prefill を確認し、フォーム action/admin/block/block?blockId=...&_method=putから PUT、一覧 readback と screenshot を残した。
証跡:
- 結果JSON:
docs/web-e2e/results/20260611-admin-block-edit-browser-regression.json - レポート:
docs/web-e2e/20260611-admin-block-edit-browser-regression-report.md - 作成:
docs/web-e2e/screenshots/20260611-admin-block-edit-browser-regression/setup/admin-block-create.png - 編集:
docs/web-e2e/screenshots/20260611-admin-block-edit-browser-regression/setup/admin-block-update.png - 削除:
docs/web-e2e/screenshots/20260611-admin-block-edit-browser-regression/setup/admin-block-delete.png
この 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 で更新できるようにした。
修正後の確認:
- Read model:
GetAdminLayoutInput/AdminLayoutFetchedを追加し、既存LayoutStorageInterface::item()を使ってGET /admin/layout/layout?layoutId=...が編集フォームを prefill する。新しい fake store や runner 合成値は追加していない。 - Resource/HTML:
LayoutListはgoLayoutrel を公開し、Layout::onGetはgoLayoutとdoUpdateLayoutを公開する。HTML form はaction="/admin/layout/layout?layoutId=...&_method=put"を出し、EC-CUBE由来のnamefield をlayoutNameと同じ意味として受ける。 - HTTP/SQL:
HttpSqlAdminLayoutFormTestは一覧の編集リンク、編集フォーム prefill、PUT 303、一覧 readback を確認する。 - Hypermedia/HTTP projection:
FlowAdminContentPublishTestはgoLayoutList -> goLayout -> doUpdateLayoutの順で辿る。 - Browser/Web+DB: 限定run
20260611-admin-layout-browser-regressionで 170 が pass。GET /admin/layout/layout?layoutId=1の prefill を確認し、フォーム action から PUT、303 Location=/admin/layout/layout-list、一覧 readback と screenshot を残した。
証跡:
- 結果JSON:
docs/web-e2e/results/20260611-admin-layout-browser-regression.json - レポート:
docs/web-e2e/20260611-admin-layout-browser-regression-report.md - 編集:
docs/web-e2e/screenshots/20260611-admin-layout-browser-regression/setup/admin-layout-update.png
この run は --limit=170 の限定回帰であり、171 以降の未実行 fail は新規failではない。次の全件runで matrix のレイアウト行を全件run証跡へ置き換える。
次の実装単位
- Admin customer edit / delivery / resend の rel と action を Resource/OpenAPI/ALPS/HTML で照合し、保存 transition または再送対象の作成導線がないものは引き続き fail として残す。
scripts/web-e2e-runner.mjsが browser 上の実フォームから admin create/delete/order/mail unsafe 操作を実行できるように、先に対応する Hypermedia/HTTP regression と HTML form/action 観測を追加する。- Browser で残った CRUD fail ごとに Hypermedia/HTTP regression を追加し、赤を確認してから実装を直す。
- LinkAudit warning を rel 単位で分類し、Resource meta / HTML / profile docs のどれが正かを確認してから failure gate 化する。