生活分享
實作功能:完成待辦篩選
從 start 材料補上 Active/Completed 篩選,保留資料格式並用正常與邊界案例驗收。
閱讀時間約 14 分鐘 · 操作 30 分鐘

返回 Codex 教學總目錄Codex 學習中心:完整教學目錄從安裝、第一個任務到 MD 規則與進階整合,規劃 60 篇 Codex 教學、十個單元。依程度、平台、需求或指令搜尋下一篇;尚未公開的教學會標示狀態,方便安排學習路線。閱讀全文
目標與準備
本段提到的教學與資源: 專案閱讀先讀懂一個既有專案用唯讀流程找到啟動點、資料流與測試,產生有檔案依據的專案地圖。閱讀全文
Plan 模式篇Plan 模式:先規劃再實作Plan 模式適合還需要決定範圍或做法的工作。它幫你把需求整理成可實作的計畫,但計畫本身不是已完成的程式。使用時先定義要討論的問題,再檢查計畫是否包含輸入、輸出、限制與驗證。閱讀全文練習審閱與交付計畫;這篇把焦點放在功能從失敗到完成的證據。題目相同,驗收更深入:不能只看畫面剩一列就說篩選成功,還要證明被隱藏的資料沒有被刪除、排序不變,兩個相同標題仍能依識別碼正確處理。
步驟 1:從未完成版本建立基準
從練習 ZIP 的 start 複製五個檔案到新的 codex-feature-lab,不沿用已完成的 expected,也不把前一篇修好的 core.mjs 帶進來。開啟資料夾後確認路徑;PowerShell 用 Get-Location,macOS/Linux 用 pwd。保留 start 原版,先跑下列既有測試,預期 2 項通過、1 項篩選失敗。
node --test core.test.mjs
先讀 index.html 的選項與 app.js 的 filter change 事件,確認控制項已經存在。缺少的是 visibleTasks 的行為,不需要重寫 UI 或安裝框架。這也是先讀專案的價值:檔案名稱看起來像前端,不代表所有變更都要從畫面開始。將既有失敗結果記在筆記,後續不能靠刪測試改寫成功。
步驟 2:用案例固定完成條件
將下列三個驗收測試存為根目錄 filter.test.mjs。它是本篇新增的測試檔,不覆蓋 core.test.mjs。第一個用 a 與 c 兩個同名 Read,確認完成篩選保留兩個識別碼且順序相同;第二個確認 All 沒丟資料;第三個涵蓋三種空清單。凍結輸入會讓不當原地修改更容易被抓出來。
import test from "node:test";
import assert from "node:assert/strict";
import { visibleTasks } from "./core.mjs";
const tasks = Object.freeze([
Object.freeze({ id: "a", title: "Read", completed: true }),
Object.freeze({ id: "b", title: "Build", completed: false }),
Object.freeze({ id: "c", title: "Read", completed: true }),
]);
const ids = (items) => items.map((item) => item.id);
test("filters preserve identity and order with duplicate titles", () => {
assert.deepEqual(ids(visibleTasks(tasks, "active")), ["b"]);
assert.deepEqual(ids(visibleTasks(tasks, "completed")), ["a", "c"]);
assert.deepEqual(ids(tasks), ["a", "b", "c"]);
});
test("All retains every task without changing its completion state", () => {
assert.deepEqual(ids(visibleTasks(tasks, "all")), ["a", "b", "c"]);
assert.deepEqual(tasks.map((task) => task.completed), [true, false, true]);
});
test("every filter accepts an empty list", () => {
for (const filter of ["all", "active", "completed"]) {
assert.deepEqual(visibleTasks(Object.freeze([]), filter), []);
}
});
node --test core.test.mjs filter.test.mjs
在 start 起點,合併執行應是 4 過、2 敗:既有篩選測試與新第一項測試會失敗,All 和空陣列本來就通過。這讓你知道新測試確實能抓到缺少篩選的問題。若出現語法錯誤或找不到檔案,先修正儲存位置與複製內容;它們不是預期的功能失敗,不能混成同一個紅燈。
步驟 3:實作最小功能
桌面版加入 codex-feature-lab 為本機專案並建立新任務;CLI 從此練習目錄執行 codex。確認任務路徑後,貼上完整要求。這時原始程式只有 core.mjs 可修改,新增的 filter.test.mjs 內容也已經固定。若模型認為需要其他檔案,先請它指出具體原因;不要一開始就讓它把所有測試、畫面與設定一起「整理」。沒有讀到測試時,要求先讀,避免只照自然語言猜測。
Implement the missing filters in this codex-feature-lab.
Read index.html, app.js, core.mjs, core.test.mjs and filter.test.mjs first.
Modify only visibleTasks in core.mjs: all keeps every task, active returns unfinished tasks, completed returns finished tasks. Preserve original order, IDs and input data. Do not edit tests, add dependencies or change UI/storage.
Run node --test core.test.mjs filter.test.mjs. Inspect the final diff and report actual results and any unperformed browser checks. Stop and explain if the requested scope cannot satisfy the tests. Do not publish or deploy.
參考實作如下。filter 產生符合條件的新陣列,裡面仍引用原任務物件;這個函式只挑選,不修改物件,因此符合本題要求。All 可以回傳原陣列,不必為了看起來「更安全」進行沒有必要的深層複製。使用 !task.completed 與 task.completed 的差別要能自己讀懂,不能只認測試變綠。
export function visibleTasks(tasks, filter) {
if (filter === "active") return tasks.filter((task) => !task.completed);
if (filter === "completed") return tasks.filter((task) => task.completed);
return tasks;
}
步驟 4:驗收資料、畫面與範圍
重跑同一條測試命令,參考修正預期 6 項全過。接著核對差異:原本五個檔案只改了 core.mjs,另外多一個你新增的 filter.test.mjs。若測試 assertions 被刪除,先恢復固定測試再跑;若增加無關檔案,逐一檢查來源,不能因為成功摘要漂亮就忽略範圍。修改完成與驗收完成分開記錄。
從 codex-feature-lab 啟動 Python HTTP 預覽,Windows 用 py -m http.server 4173 --bind 127.0.0.1,macOS/Linux 用 python3 代替 py,瀏覽器開 http://127.0.0.1:4173。先處理自己原有預覽的埠占用,不停其他服務。直接雙擊 HTML 可能因模組限制載入失敗;若看到舊畫面,確認伺服器目錄及重新整理後再判斷。
先保留仍需要的舊練習紀錄,再於 About this exercise 使用 Reset practice data。選 All tasks 並確認空清單後,依序加入 Read、Build、Read,勾選第一與第三項。照表切換,再回 All 確認三筆都在;同名項目以原先位置與勾選狀態辨認。取消第一項完成後,Completed 應只剩原第三項,Active 應保留原第一項與 Build。最後切回 All 重新整理,確認狀態仍在。
| 檢查點 | All | Active | Completed |
|---|---|---|---|
| 原第一、第三項完成 | Read、Build、Read | Build | Read、Read |
| 原第一項取消完成 | Read、Build、Read | Read、Build | 原第三項 Read |
| 清空教材任務後 | 空 | 空 | 空 |
反例驗證:全數計數與同名任務
畫面練習中,Read、Build、Read 共三筆,第一和第三筆完成時,All/Active/Completed 的列數分別為 3/1/2,但三種畫面的計數都應是 1 active / 3 total。取消第一筆完成後,三種列數變成 3/2/1,計數都為 2 active / 3 total。app.js 用完整 tasks 計數;只通過核心篩選測試不能證明畫面計數正確,請另記實際結果。
六項測試通過後,先把修好的 core.mjs 複製到練習資料夾外保存。在練習版只暫時把 Completed 分支替換成下面的錯誤寫法,再跑原兩個測試檔。它先按完成狀態篩選,再按 title 去重,會遺失 ID c;預期 5 過 1 敗。原三項測試單獨跑仍全過,因為其兩筆資料沒有同名。讀出失敗的實際 ID 後,立刻用剛才保存的修正版恢復 core.mjs,應回到 6 過 0 敗;測試檔保持不變。
if (filter === "completed") return tasks.filter((task) => task.completed).filter((task, index, selected) => selected.findIndex((other) => other.title === task.title) === index);
若反例沒有失敗,先確認有執行 filter.test.mjs、第三筆仍為不同 ID 的 Read,以及正在測試修改過的副本。若變成語法或找不到模組錯誤,先恢復檔案再核對替換位置;那不是成功抓到去重缺陷。這個反例只檢查測試覆蓋,不需要改 UI 或提交錯誤版本。
失敗排除、交付與還原
篩選時資料真的少了,先看是否錯把 filter 結果寫回 tasks 或保存;畫面數量對但同名任務不對,要檢查是否用 title 代替 id。核心全過但畫面無變,先讀 app.js 是否載入正確 core.mjs,並核對 HTTP 來源與瀏覽器快取。不要連續要求「再修一次」卻不提供哪個表格列失敗,先把重現順序與預期寫清楚。
交付應包含六項測試摘要、畫面案例、最終差異,以及沒有操作的檢查清單。重做時停止預覽,只從 start 還原 core.mjs;若保留新測試,應回到 4 過 2 敗,若只執行舊測試,則是 2 過 1 敗。保留兩個命令的差別,避免把測試數量不同誤當另一個故障。圖中 1 是固定案例,2 是限定修改,3 是回歸與還原。這些是可執行參考材料,不是聲稱已替你執行 Codex 任務。
返回 Codex 教學總目錄Codex 學習中心:完整教學目錄從安裝、第一個任務到 MD 規則與進階整合,規劃 60 篇 Codex 教學、十個單元。依程度、平台、需求或指令搜尋下一篇;尚未公開的教學會標示狀態,方便安排學習路線。閱讀全文
閱讀完整文字說明
Three numbered stages: identify the starting point, perform the exercise, and verify the result. Original illustration, not a product screenshot.


同主題延伸閱讀
生活分享
Codex 學習中心:完整教學目錄
從安裝、第一個任務到 MD 規則與進階整合,規劃 60 篇 Codex 教學、十個單元。依程度、平台、需求或指令搜尋下一篇;尚未公開的教學會標示狀態,方便安排學習路線。
生活分享
Worktree 與多任務隔離
Worktree 讓同一個 Git 程式庫有不同的工作目錄,各自承接不同分支。它適合讓兩項工作分開改檔,但資料庫、連接埠與外部服務仍可能共用,不能把檔案隔離當成所有資源隔離。
生活分享
實戰:製作小網站
從 brief.md 規劃並製作 Small Steps 待辦網站,完成新增、完成、刪除、篩選與本機資料保存。將 HTML、CSS、資料函式、畫面事件與測試分開,以 Node 測試和瀏覽器操作驗收,並留下可重新啟動與還原的交接紀錄。
生活分享
用量與效率:減少重工
記錄任務條件、模型選項、時間與成果,找出能減少無效重試和過多上下文的調整。
引用本文的文章
最新旅遊情報攻略

情報
2026 韓國楓葉預測:雪嶽山 10 月 20 日、首爾近郊 10 月底、內藏山與漢拏山 11 月上旬
韓國山林廳 2026 年 9 月 22 日公布的楓紅高峰預測:雪嶽山 10 月 20 日,春川、國立樹木園到首爾植物園落在 10 月 28 日到 11 月 2 日,內藏山 11 月 4 日、漢拏山 11 月 6 日,整體比最近 5 年晚約 0.8 天。整理各地楓樹與銀杏的預測日、首爾出發怎麼排,以及出發前去哪裡看即時楓況。2026 年 10 月查證。
- 季節活動
- 自然
- 觀景

攻略胡志明市
胡志明市到頭頓一日遊:白藤碼頭搭高速船、船票與班次,下船就是胡梅纜車與耶穌基督像
人在胡志明市挪一天去頭頓看海:市中心的白藤高速船碼頭搭船,航程 120 分鐘到頭頓的胡梅碼頭,平日成人 320,000 越南盾、週末 350,000,回程末班平日 15:00。下船就是胡梅纜車站,同一條路上有白宮,小山頂上是耶穌基督像。平日一天只有兩班船,整天要從末班船倒推著排。
- 交通
- 行程範例
- 海灘

攻略沖繩
沖繩不開車攻略:單軌只到浦添,美麗海水族館要坐兩個多小時的巴士,回那霸的最後一班直達車 17:22 就開走
不租車的沖繩怎麼移動:那霸市區靠沖繩都市單軌電車(ゆいレール),那霸機場站到終點てだこ浦西 19 站、17 公里、37 分鐘,一日券 1,000 日圓;美麗海水族館有那霸機場直達的高速巴士,單程 2,000 日圓起、官方時刻表上 2 小時上下,下車後還要走 10 分鐘;古宇利島要在今帰仁村役場轉車,當天來回光坐車就六個半小時;回程的最後一班直達車 17:22 就從記念公園前開走(2026 年 9 月查證)。
- 交通
- 行程範例
- 預算