From 573d0ba3bf994e07eaef4296e5ba3e8d6c4c66d9 Mon Sep 17 00:00:00 2001 From: Hideyuki MORI Date: Sat, 23 May 2026 00:57:55 +0900 Subject: [PATCH] refactor(types): tighten \$REQUEST_JSON + ApiResponse return shapes (#405) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 評価レポート (#401 § 2 Code Quality) 指摘の 2 件: 1. \$REQUEST_JSON が non-parameterized array → array 2. ApiResponse::success() と failure() の戻り型が PHPDoc 上は 両方 array で statically 区別不能 ### Changes #### class/xion/ControllerBase.php - protected \$REQUEST_JSON の PHPDoc を array に parameterize (native type は array のまま、JsonResponder::inputJsonToArray の戻り PHPDoc と整合) - 説明コメントも追加 (REST 状態変化 method のみ populate される旨) #### class/xion/ApiResponse.php - success() の PHPDoc に array_merge 振る舞いと "caller keys win" の 説明を追記。@return は array 維持 (caller-merged keys の存在で正確な shape は表現不能)。 - failure() の @return を array-shape 形式に変更: array{status: 'failure', errorCode: string, errorMessage: string} → 静的解析が failure 戻り値を success と shape で区別可能に。 ### Verification - composer test 99/99 - composer test:http 24/24 (1 expected skip) - composer analyze (Phan) exit 0 (baseline 不変) - composer format:check exit 0 Closes #405. Co-Authored-By: Claude Opus 4.7 (1M context) --- class/xion/ApiResponse.php | 23 +++++++++++++++++------ class/xion/ControllerBase.php | 9 +++++++-- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/class/xion/ApiResponse.php b/class/xion/ApiResponse.php index e05610f..41df841 100644 --- a/class/xion/ApiResponse.php +++ b/class/xion/ApiResponse.php @@ -38,11 +38,18 @@ public function __construct() } /** - * Build a success response. + * Build a success response envelope. * - * @param array $data Response data. + * The returned array always includes `status: 'success'` and + * `errorCode: ''`; any keys supplied in `$data` are merged on top + * (caller-supplied keys win, since `array_merge` keeps the rightmost + * value for duplicate keys). The envelope is wrapped by + * `JsonResponder::responseArray()` so the final REST shape is + * `{ Result: true, Data: { status: 'success', errorCode: '', ... } }`. * - * @return array API response. + * @param array $data Domain-specific data to merge into the envelope. + * + * @return array Success envelope with caller keys merged. */ public function success(array $data = []): array { @@ -53,11 +60,15 @@ public function success(array $data = []): array } /** - * Build a failure response. + * Build a failure response envelope. * - * @param string $errorCode Error code. + * The shape is exactly three keys — `status`, `errorCode`, + * `errorMessage` — and never carries caller-supplied data. The + * PHPDoc uses the array-shape form so static analysis can + * distinguish failure responses from success responses by the + * presence of `errorMessage` (#405, eval report PR #401 § 2). * - * @return array API response. + * @return array{status: 'failure', errorCode: string, errorMessage: string} */ public function failure(string $errorCode): array { diff --git a/class/xion/ControllerBase.php b/class/xion/ControllerBase.php index 888249d..1077c37 100755 --- a/class/xion/ControllerBase.php +++ b/class/xion/ControllerBase.php @@ -129,9 +129,14 @@ abstract class ControllerBase private CsrfProtectionPolicy $csrfProtectionPolicy; /** - * Rest post + * Decoded JSON request body (REST POST / PUT / PATCH / DELETE only). * - * @var array + * Populated by `JsonResponder::inputJsonToArray()` for state-changing + * REST requests; an empty array otherwise. Parameterizing the type + * lets Phan / IDE follow value types through controller code + * (#405, eval report PR #401 § 2). + * + * @var array */ protected array $REQUEST_JSON = [];