From 86b5008570ec0786aaced269b937a749fd62dd4b Mon Sep 17 00:00:00 2001 From: CheerC Date: Wed, 24 Jun 2026 20:52:34 +0800 Subject: [PATCH] chore: remove dead _checkPermission param + add CI coverage gate (refs #107) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sub-tasks completed: 1. _checkPermission(createdBy) → _checkPermission() - Remove unused createdBy parameter (dead since #152 — all logged-in users can edit) - Remove createdBy argument from all 4 callers (saveData, updateScheduleMetadata, deleteSchedule, copySchedule) - Remove now-unused 'const createdBy = rowValues[3]' declarations - Remove unused rowValues destructuring in updateScheduleMetadata and deleteSchedule - Update backendSignatureContracts.test.js param count 1 → 0 2. EXTRACTED_TO_LIB cleanup — no action needed (grep found zero matches) 3. CI coverage gate — change t8 Vitest step from 'npm test' to 'npx vitest run --coverage' so coverage thresholds are enforced 4. PHP P2 — existing 60 PHP tests already cover: - index.php routing (IndexRoutesTest.php, 10 tests) - generate_iframe.php access (AccessControlTest.php, 5 tests) ESLint 0 errors, all 1164 tests pass, coverage thresholds pass. refs #107 Agend-Agent: cb-team-impl2 Agend-Branch: chore/107-cleanup Agend-Issued-At: 2026-06-24T12:47:06.972137+00:00 --- .github/workflows/ci.yml | 4 ++-- tests/unit/backendSignatureContracts.test.js | 2 +- "\347\250\213\345\274\217\347\242\274.js" | 22 ++++++++------------ 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e7539d5..8190a93 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,8 +24,8 @@ jobs: run: bash scripts/check-tailwind.sh - name: t7 PHP syntax check run: find classroom_viewer -name '*.php' ! -path '*/vendor/*' -exec php -l {} \; - - name: t8 Vitest - run: npm test + - name: t8 Vitest + coverage gate + run: npx vitest run --coverage - name: Install pcov for PHP coverage run: | sudo pecl install pcov diff --git a/tests/unit/backendSignatureContracts.test.js b/tests/unit/backendSignatureContracts.test.js index 4479bd1..b79cdd7 100644 --- a/tests/unit/backendSignatureContracts.test.js +++ b/tests/unit/backendSignatureContracts.test.js @@ -58,7 +58,7 @@ const EXPECTED_SIGNATURES = [ ['_getSs', 0], ['getConfig', 1], ['_findScheduleRowInfo', 2], - ['_checkPermission', 1], + ['_checkPermission', 0], ['getSheet', 1], ['getOrCreateSheet', 1], ['doGet', 0], diff --git "a/\347\250\213\345\274\217\347\242\274.js" "b/\347\250\213\345\274\217\347\242\274.js" index 5cf555c..107e183 100644 --- "a/\347\250\213\345\274\217\347\242\274.js" +++ "b/\347\250\213\345\274\217\347\242\274.js" @@ -38,9 +38,9 @@ function _findScheduleRowInfo(scheduleId, dataSheet) { /** * Checks if the current user has permission to manage a schedule. * Throws an error if permission is denied. - * @param {string} createdBy The email of the user who created the schedule. + * Ref: #152 — No per-user check needed; all logged-in users can edit. */ -function _checkPermission(createdBy) { +function _checkPermission() { const currentUser = Session.getActiveUser().getEmail(); // Ref: #62 — Guard against empty email (e.g. time-driven triggers return '') if (!currentUser) throw new Error('未登入,無法執行此操作'); @@ -205,9 +205,8 @@ function saveData(payload) { throw new Error(`在索引中找不到 ID 為 "${scheduleId}" 的課表。`); } - // Ref: #5 — Enforce admin/creator permission before modifying schedule data - const createdBy = rowValues[3]; - _checkPermission(createdBy); + // Ref: #5 — Enforce login check before modifying schedule data + _checkPermission(); const serverLastModified = new Date(rowValues[2]).toISOString(); if (serverLastModified !== lastModified) { @@ -361,13 +360,12 @@ function updateScheduleMetadata(scheduleInfo) { // Ref: #67.5 — Renamed from r const dataSheet = getOrCreateSheet(SHEET_DATA); const newMetaTimestamp = checkMetadata(dataSheet, metadataTimestamp); - const { index: rowIndex, values: rowValues } = _findScheduleRowInfo(id, dataSheet); + const { index: rowIndex } = _findScheduleRowInfo(id, dataSheet); if (rowIndex === -1) { throw new Error(`在索引中找不到 ID 為 \"${id}\" 的課表。`); } - const createdBy = rowValues[3]; - _checkPermission(createdBy); + _checkPermission(); // Update name if provided if (newName) { @@ -408,7 +406,7 @@ function deleteSchedule(scheduleInfo) { const dataSheet = getOrCreateSheet(SHEET_DATA); const newMetaTimestamp = checkMetadata(dataSheet, metadataTimestamp); - const { index: rowIndex, values: rowValues } = _findScheduleRowInfo(id, dataSheet); + const { index: rowIndex } = _findScheduleRowInfo(id, dataSheet); if (rowIndex === -1) { // Ref: #67.6 — Intentional idempotent design: if schedule is already gone from index, // return success rather than error. This handles race conditions and retries gracefully. @@ -416,8 +414,7 @@ function deleteSchedule(scheduleInfo) { return { success: true, newMetadataTimestamp: newMetaTimestamp }; } - const createdBy = rowValues[3]; - _checkPermission(createdBy); + _checkPermission(); const ss = _getSs(); const scheduleSheet = ss.getSheetByName(id); @@ -458,8 +455,7 @@ function copySchedule(copyInfo) { throw new Error(`在索引中找不到來源課表 (ID: ${sourceId})。`); } // Ref: #41 — Enforce permission check before copying (same pattern as rename/delete) - const createdBy = sourceRowValues[3]; - _checkPermission(createdBy); + _checkPermission(); const sourceIsDraft = sourceRowValues[4] === true; const ss = _getSs();