# 2025 後端體驗營 - 完整課程內容 > 本文件整合所有每日任務 (Day 1-10) 與最終考題 --- ## 課程總覽 | Day | 主題 | 關鍵概念 | 測驗題數 | |-----|------|----------|----------| | 1 | 報到日:認識 LiveFit | User Story, Wireframe, Swimlane | 20 題 | | 2 | 把程式碼拿到手 | Git, GitHub, Clone | 7 題 | | 3 | 把專案跑起來 | Docker, Container, 前後端分離 | 10 題 | | 4 | 改一個 LOGO 而已 | 前端結構, 靜態資源, 元件 | 10 題 | | 5 | 學會 API 後,各種服務自己接 | API 觀念, HTTP 狀態碼, 環境變數 | 10 題 | | 6 | 資料怎麼變成畫面? | 前端渲染, JSON, 開發者工具 | 10 題 | | 7 | 資料庫幼幼班 | SQL 語法, DBeaver, 資料表 | 10 題 | | 8 | 臉書的登入/登出怎麼做的 | JWT, Cookie, Issue | 10 題 | | 9 | 老闆總是善變的 | 後端結構, Route, Controller | 10 題 | | 10 | 結訓日:完成最終任務 | 整合 Day 1-9、實作驗收 | 最終任務 | | **最終任務** | 實作挑戰 | 初階改檔案 + 進階 Postman | 5+7 題 | --- # Part 1: 每日任務 --- ## Day 1 - 報到日:認識 LiveFit 與需求分析 ### 劇情背景 你是一位剛入職的後端工程師,來到 LiveFit 健身平台報到。老闆海克絲是一位經營五間實體健身房的女強人,現在想要開發一個線上直播小班制健身平台。 ### 學習目標 - 了解「使用者故事 (User Story)」的概念與公式 - 認識「線稿圖 (Wireframe)」的用途 - 學會閱讀「泳道圖 (Swimlane Diagram)」 - 理解 LiveFit 平台的核心商業邏輯 ### 核心概念 #### 使用者故事 (User Story) 從使用者的角度出發,描述他們「想做什麼」以及「為什麼要做」。 **標準公式:** > 身為 [某種角色],我想要 [做某件事],以便於 [得到什麼好處] **LiveFit 範例:** - 訪客:「我想瀏覽教練列表,以便於了解有哪些專長的教練適合我。」 - 會員:「我想購買堂數方案,以便於取得點數來報名喜歡的課程。」 - 教練:「我想建立課程,以便於讓學員可以預約我的直播時段。」 - 管理員:「我想把一般使用者升級為教練,以便於擴張平台的教學師資。」 #### 線稿圖 (Wireframe) 用簡單的線條跟框框畫出介面,告訴我們按鈕放哪、按下去會跳到哪、頁面的基本佈局。 #### 泳道圖 (Swimlane Diagram) 每一條「跑道」代表一個角色,可以清楚看到誰該在什麼時候做什麼事、不同角色之間的互動流程。 ### 測驗題目 (20 題) #### Part 1: 開發觀念篇 (7 題) 1. 使用者故事的標準公式 2. 線稿圖的比喻與用途 3. 為什麼要在寫程式前畫線稿圖 4. 泳道圖的主要功能 5. 不釐清商業邏輯就寫程式的後果 6. 線稿圖通常不包含的元素 7. 泳道圖中每條跑道代表什麼 #### Part 2: LiveFit 商業邏輯篇 (13 題) 8. 使用者如何變成教練 9. 會員如何報名課程 10. 教練的功能需求 11. 訪客無法執行的動作 12. 管理員的主要工作 13. 會員可修改的個人資料 14. 教練如何讓學員更容易找到自己 15. 取消課程的規則 16. 教練編輯課程時可調整的資訊 17. LiveFit 平台的核心營運模式 18. 會員如何查看購買紀錄 19. 教練如何查看課程狀態 20. 誰負責新增堂數方案 ### 海克絲的叮嚀 > 「記住,寫程式之前先搞懂需求,這是最重要的事。如果太快開始寫程式,反倒會寫出很多 Bug。開發之前,一定要問清楚才能進行開發。」 --- ## Day 2 - 把程式碼拿到手:Git 與 GitHub 入門 ### 劇情背景 第二天一早,海克絲正要把專案連結給你,卻突然發現專案是 Public 的——前任後端竟然把專案完全公開在網路上。 ### 學習目標 - 了解 Git 是什麼,以及為什麼需要版本控制 - 認識 GitHub 與 Git 的關係 - 學會 Clone 專案到本地電腦 - 理解 Public 與 Private 專案的差異與安全性 ### 核心概念 #### Git 是什麼? Git 是一個「版本控制系統」,就像是程式碼的時光機。它可以: - 記錄每一次的修改歷史 - 讓你隨時回到過去的版本 - 讓多人同時協作開發 #### GitHub 是什麼? GitHub 是一個「程式碼託管平台」: - 程式碼的雲端硬碟 - 工程師的社群網站 - 開源專案的集散地 #### Git vs GitHub | Git | GitHub | |-----|--------| | 版本控制工具 | 託管平台 | | 裝在你的電腦 | 在網路上 | | 記錄修改歷史 | 儲存和分享程式碼 | #### Clone 是什麼? Clone(克隆)就是把 GitHub 上的專案「下載到你的電腦」。 #### Public vs Private 專案 | Public | Private | |--------|---------| | 任何人都可以看到程式碼 | 只有授權的人可以看到 | | 適合開源專案 | 適合公司內部專案 | | 程式碼漏洞可能被研究 | 較安全 | ### 測驗題目 (7 題) 1. Git 是什麼類型的工具? 2. GitHub 與 Git 的關係是什麼? 3. Clone 的作用是什麼? 4. Git 可以做到以下哪件事? 5. GitHub 上的 Public 專案代表什麼? 6. 為什麼後端專案通常會設成 Private? 7. Clone 完成後,專案會出現在哪裡? ### 海克絲的叮嚀 > 「Git 和 GitHub 是工程師的基本功,就像廚師要會用刀一樣。剛開始可能會覺得有點複雜,但相信我,用久了就會變成直覺。」 --- ## Day 3 - 把專案跑起來:前後端與 Docker 入門 ### 劇情背景 海克絲的合夥人這週想看看專案目前的進度,你得先搞懂這個專案到底是怎麼組成的——前端、後端、還有資料庫。 ### 學習目標 - 了解前端、後端、資料庫各自的角色 - 了解什麼是 Docker 以及為什麼需要它 - 理解 Container(容器)的概念 - 成功啟動 LiveFit 專案的開發環境 ### 核心概念 #### 前端、後端、資料庫是什麼? | 角色 | 電商網站比喻 | 系統中的角色 | |------|----------|--------------| | **前端 (Frontend)** | 網頁商城的頁面 | 使用者看到的畫面,負責互動與呈現 | | **後端 (Backend)** | 訂單處理中心 | 處理商業邏輯,決定要做什麼、怎麼做 | | **資料庫 (Database)** | 商品倉庫 | 儲存所有資料 | **LiveFit 專案的技術棧:** - 前端:Vue.js (Port 3000) - 後端:Node.js (Port 8080) - 資料庫:PostgreSQL (Port 5432) #### 為什麼需要 Docker? Docker 可以把整個執行環境打包成一個「容器」,確保每個人的開發環境一致,避免「在我電腦可以跑」的問題。 #### Container(容器)是什麼? Container 就是 Docker 打包出來的「貨櫃」,裡面包含程式碼、執行環境、系統函式庫、設定檔。 ### 測驗題目 (10 題) #### 前端、後端、資料庫篇 (4 題) 1. 前端的主要職責是什麼? 2. 後端的主要職責是什麼? 3. 資料庫的主要職責是什麼? 4. 使用者點擊「購買課程」後,系統的處理順序是什麼? #### Docker 觀念篇 (3 題) 5. Docker 主要解決什麼問題? 6. Container(容器)是什麼? 7. 為什麼這個專案要用 Docker? #### LiveFit 環境篇 (3 題) 8. LiveFit 專案啟動後會有幾個 Container? 9. 前端服務跑在哪個 Port? 10. 如何確認後端服務是否正常運作? ### 海克絲的叮嚀 > 「Docker 是後端工程師的好夥伴,以前我們要花好幾天設定環境,現在一個指令就搞定。今天成功把環境架起來,代表你已經跨過了最重要的一關。」 --- ## Day 4 - 改一個 LOGO 而已,很難嗎?:前端資料夾與靜態資源 ### 劇情背景 海克絲指著螢幕上的 Logo 問你:「如果我現在要你改這個 Logo,你知道要去哪裡改嗎?」你需要先了解前端的資料夾結構,才知道要去哪裡找東西。 ### 學習目標 - 認識前端專案的資料夾結構 - 了解「靜態資源」與「動態資料」的差異 - 學會找到要修改的檔案位置 - 理解前端如何組織程式碼 ### 核心概念 #### 前端資料夾結構 ```text frontend/ ├── public/ # 靜態資源(不會被編譯) │ ├── logo.png # Logo 圖片 │ └── favicon.ico # 網站小圖示 ├── src/ # 原始碼(會被編譯) │ ├── components/ # 元件(可重複使用的小零件) │ ├── pages/ # 頁面(每個網址對應一個頁面) │ ├── layouts/ # 版面(共用的頁面框架) │ └── assets/ # 資源(圖片、CSS 等) └── index.html # 網站入口 ``` #### 靜態資源 vs 動態資料 | 類型 | 說明 | 例子 | 放哪裡 | |------|------|------|--------| | **靜態資源** | 寫死的、不會變的 | Logo、背景圖、CSS | `public/` 或 `assets/` | | **動態資料** | 從資料庫來的、會變的 | 教練列表、課程資訊 | 後端 API 回傳 | **改 Logo = 換靜態資源 → 去 `public/` 或 `assets/` 找** **改教練名字 = 改動態資料 → 去資料庫改** #### 前端元件是什麼? 元件就像「樂高積木」,可以重複使用: ```text 頁面 = 元件 + 元件 + 元件 ┌─────────────────────────────┐ │ Header 元件(導覽列) │ ├─────────────────────────────┤ │ │ │ CoachCard 元件 CoachCard │ │ CoachCard 元件 CoachCard │ │ │ ├─────────────────────────────┤ │ Footer 元件(頁尾) │ └─────────────────────────────┘ ``` #### 如何找到要改的檔案? | 想改什麼 | 去哪裡找 | |---------|---------| | 網站 Logo | `public/` 或 `src/assets/` | | 網站標題 | `index.html` 的 `<title>` | | 導覽列 | `src/layouts/` 或 `src/components/` | | 某個頁面 | `src/pages/` | ### 測驗題目 (10 題) #### 靜態資源篇 (5 題) 1. Logo 圖片屬於靜態資源還是動態資料? 2. 教練列表的資料屬於靜態資源還是動態資料? 3. 靜態資源通常放在哪個資料夾? 4. 想改網站的 Logo,應該去哪裡找檔案? 5. 為什麼說 Logo 是「靜態」的? #### 前端結構篇 (5 題) 6. `src/components/` 裡面放的是什麼? 7. `src/pages/` 裡面放的是什麼? 8. 元件的概念像什麼? 9. 為什麼要把程式碼分成元件? 10. 想改網站標題,應該去哪個檔案找? ### 海克絲的叮嚀 > 「很多新手一拿到專案就亂找,結果改了半天發現改錯地方。記住:Logo 是靜態的,去 `public/` 找;教練資料是動態的,要改資料庫。搞清楚靜態和動態的差異,找檔案就快多了!」 --- ## Day 5 - 學會 API 後,各種服務自己接!:API 觀念與環境變數 ### 劇情背景 你發現前端好像一直在發請求到 `/api/...` 的地方。海克絲說:「那些就是 API——前端和後端溝通的介面。學會 API,你就打開了通往各種網路服務的大門。」 ### 學習目標 - 理解 API 是什麼以及它的作用 - 學會看懂 API 的回應結果 - 了解 HTTP 狀態碼的意義(判斷成功或失敗) - 認識環境變數 (.env) 與資安觀念 ### 核心概念 #### API 是什麼? API (Application Programming Interface) 就是「程式之間溝通的介面」。 想像 API 就像餐廳的服務生: - 你(前端)跟服務生說要點什麼菜(發送請求) - 服務生把菜單送到廚房(後端) - 廚房做好菜,服務生端給你(回傳資料) #### API 的請求與回應 **發送請求時需要什麼?** ``` 1. URL(網址):要去哪裡?例如 /api/courses 2. 方法:要做什麼?GET(拿資料)、POST(送資料) 3. 資料:要帶什麼?例如登入時帶帳號密碼 ``` **API 回傳什麼?** ```json { "status": "success", "data": { ... } } ``` #### HTTP 狀態碼(判斷 API 有沒有成功) | 狀態碼 | 意義 | 說明 | |--------|------|------| | 200 | OK | 成功 | | 201 | Created | 新增成功 | | 400 | Bad Request | 請求格式錯誤 | | 401 | Unauthorized | 未登入/沒有權限 | | 404 | Not Found | 找不到資源 | | 500 | Server Error | 伺服器錯誤 | **記憶口訣:** - 2xx = 成功 ✅ - 4xx = 你(客戶端)的問題 ⚠️ - 5xx = 我(伺服器)的問題 ❌ #### 環境變數 (.env) 環境變數用來存放「不應該寫死在程式碼裡的設定」: ``` # .env 檔案範例 DATABASE_URL=postgres://localhost:5432/livefit JWT_SECRET=my-super-secret-key API_KEY=abc123xyz ``` **為什麼需要環境變數?** - 🔐 安全性:密碼不會被上傳到 GitHub - 🔄 彈性:不同環境(開發/正式)用不同設定 - 👥 協作:每個人可以用自己的設定 ### 測驗題目 (10 題) #### API 觀念篇 (7 題) 1. API 的全名是什麼? 2. API 在系統中扮演什麼角色? 3. 發送 API 請求時,至少需要提供什麼資訊? 4. HTTP 狀態碼 404 代表什麼? 5. HTTP 狀態碼 200 代表什麼? 6. 2xx 系列的狀態碼通常代表什麼? 7. 看到 500 錯誤,問題出在哪裡? #### 環境變數與資安篇 (3 題) 8. 為什麼密碼不應該直接寫在程式碼裡? 9. .env 檔案應該加入什麼檔案來避免上傳? 10. 環境變數通常用來存放什麼類型的資訊? ### 海克絲的叮嚀 > 「API 是後端工程師的核心技能。當你呼叫 API 時,第一件事就是看狀態碼——200 就放心,4xx 檢查你的請求,5xx 就是後端的鍋。另外,資安觀念要從現在開始養成,密碼、金鑰這些敏感資訊,絕對不能寫死在程式碼裡!」 --- ## Day 6 - 資料怎麼變成畫面?:前端渲染 ### 劇情背景 你好奇教練列表頁面的資料是怎麼顯示出來的。海克絲說:「後端回傳的是 JSON 格式的資料,前端拿到後再『渲染』成你看到的畫面。這個過程就是前端渲染。」 ### 學習目標 - 理解前端如何接收 API 回傳的資料 - 認識 JSON 資料與畫面的對應關係 - 學會用開發者工具觀察 API 回傳的資料 - 了解前端渲染的基本概念 ### 核心概念 #### 什麼是前端渲染? 前端渲染就是把「資料」變成「畫面」的過程。 ``` 後端 API 回傳 JSON → 前端接收資料 → 渲染成 HTML → 使用者看到畫面 ``` #### JSON 資料長什麼樣? 以教練列表 API 為例,回傳的 JSON 可能長這樣: ```json { "coaches": [ { "id": 1, "name": "王小明", "skills": ["瑜珈", "皮拉提斯"], "bio": "10 年教學經驗" }, { "id": 2, "name": "李小華", "skills": ["有氧", "重訓"], "bio": "專業健身教練" } ] } ``` #### JSON 資料與畫面的對應 ``` JSON 資料 畫面顯示 ───────────────────────────────────────── name: "王小明" → 教練名稱 skills: ["瑜珈"] → 技能標籤 bio: "10 年教學經驗" → 教練簡介 ``` #### 前端怎麼渲染? Vue.js 使用 `v-for` 迴圈把陣列資料渲染成多個元件: ```html <div v-for="coach in coaches" :key="coach.id"> <h3>{{ coach.name }}</h3> <p>{{ coach.bio }}</p> </div> ``` #### 用開發者工具觀察 1. 打開瀏覽器 → 按 F12 2. 切換到 Network 分頁 3. 重新整理頁面或點擊功能 4. 找到 API 請求,點擊查看 Response ### 測驗題目 (10 題) #### 前端渲染觀念篇 (5 題) 1. 什麼是前端渲染? 2. 後端 API 通常回傳什麼格式的資料? 3. JSON 的全名是什麼? 4. 為什麼後端不直接回傳 HTML? 5. 前端渲染的流程是什麼? #### 實務應用篇 (5 題) 6. 如何用開發者工具查看 API 回傳的資料? 7. Network 分頁可以看到什麼資訊? 8. Vue.js 用什麼語法把陣列渲染成多個元件? 9. JSON 資料中的 `name` 欄位會對應到畫面的哪裡? 10. 為什麼同一個頁面,不同使用者看到的資料可能不同? ### 海克絲的叮嚀 > 「理解『資料怎麼變成畫面』是很重要的觀念。後端負責提供資料,前端負責呈現。當畫面顯示不正確時,第一步就是打開開發者工具,看看 API 回傳的資料對不對。資料對了,畫面才會對!」 --- ## Day 7 - 資料庫幼幼班:SQL 語法入門 ### 劇情背景 海克絲帶你來到資料庫的世界:「後端工程師有一大半的時間都在跟資料庫打交道。今天我們來學習如何用 SQL 語法跟資料庫溝通。」 ### 學習目標 - 認識關聯式資料庫的基本概念 - 了解 LiveFit 的資料表結構 - 學會基本的 SQL 語法(SELECT、INSERT、UPDATE、DELETE) - 使用 DBeaver 操作資料庫 ### 核心概念 #### 資料庫是什麼? 資料庫就是「有組織的資料儲存庫」,像是一本超大的 Excel。 **LiveFit 使用 PostgreSQL:** 關聯式資料庫,資料以「表格」形式儲存,表格之間可以建立「關聯」。 #### LiveFit 主要資料表 | 資料表 | 說明 | 主要欄位 | |--------|------|----------| | User | 使用者 | id, name, email, password, role | | Coach | 教練 | id, name, bio, user_id | | Course | 課程 | id, title, coach_id, scheduledTime | | CreditPackage | 堂數方案 | id, name, creditCount, price | | CreditPurchase | 購買紀錄 | id, user_id, package_id, quantity | | CourseBooking | 課程預約 | id, user_id, course_id | #### SQL 基本語法 **SELECT(查詢資料):** ```sql -- 查詢所有使用者 SELECT * FROM "USER"; -- 查詢特定欄位 SELECT name, email FROM "USER"; -- 加上條件 SELECT * FROM "USER" WHERE role = 'COACH'; ``` **INSERT(新增資料):** ```sql -- 新增一筆堂數方案 INSERT INTO "CREDIT_PACKAGE" (name, credit_amount, price) VALUES ('體驗方案', 3, 600); ``` **UPDATE(更新資料):** ```sql -- 把某個使用者升級為教練 UPDATE "USER" SET role = 'COACH' WHERE email = 'test@example.com'; ``` **DELETE(刪除資料):** ```sql -- 刪除特定資料(小心使用!) DELETE FROM "COURSE_BOOKING" WHERE id = 123; ``` #### DBeaver 是什麼? DBeaver 是一個資料庫管理工具,可以讓你用圖形介面連接資料庫、執行 SQL、瀏覽資料。 ### 測驗題目 (10 題) #### 資料庫觀念篇 (5 題) 1. 關聯式資料庫的資料是用什麼形式儲存? 2. 「一對多」關係是什麼意思? 3. LiveFit 的購買紀錄存在哪個資料表? 4. 教練和課程之間是什麼關係? 5. SQL 的全名是什麼? #### SQL 語法篇 (5 題) 6. 想要「查詢資料」應該用哪個 SQL 語法? 7. 想要「新增資料」應該用哪個 SQL 語法? 8. 想要「更新資料」應該用哪個 SQL 語法? 9. WHERE 子句的用途是什麼? 10. 為什麼執行 DELETE 要特別小心? ### 海克絲的叮嚀 > 「資料庫是系統的心臟,資料出錯比畫面出錯嚴重多了。SQL 語法不難,但要小心使用——尤其是 UPDATE 和 DELETE,一不小心就可能改錯或刪錯資料!」 --- ## Day 8 - 臉書的登入/登出到底怎麼做的?:JWT 與 Cookie ### 劇情背景 你正在測試 LiveFit 的功能,發現登入之後關掉瀏覽器,再打開還是登入狀態。系統怎麼知道我是誰? ### 學習目標 - 理解為什麼需要身份驗證 - 認識 Cookie 的作用與特性 - 了解 JWT (JSON Web Token) 的原理 - 理解 LiveFit 的登入機制 - 認識 Issue 卡片的用途 ### 核心概念 #### 為什麼需要身份驗證? HTTP 協定本身是「無狀態」的,每次請求都是獨立的,伺服器不會記得你是誰。 #### Cookie 是什麼? Cookie 是瀏覽器存放的「小紙條」,由伺服器設定,每次請求會自動帶上。 #### JWT 是什麼? JWT (JSON Web Token) 是一種「數位身份證」。 **JWT 的結構:** ``` xxxxx.yyyyy.zzzzz │ │ │ │ │ └── Signature(簽名):防止竄改 │ └── Payload(內容):使用者資訊 └── Header(標頭):加密方式 ``` #### LiveFit 的登入流程 ``` 1. 使用者輸入帳號密碼 2. 前端發送 POST /api/users/login 3. 後端驗證帳密,產生 JWT 4. JWT 回傳給前端,存入 Cookie/LocalStorage 5. 之後的請求都帶著 JWT 6. 後端驗證 JWT,確認身份 ``` #### Issue 卡片是什麼? Issue 是用來追蹤「待辦事項」的工具,用於回報 Bug、提出新功能需求、記錄待討論的問題。 **好的 Issue 應該包含:** 1. 標題:簡短描述問題 2. 描述:詳細說明 3. 重現步驟:怎麼讓 Bug 發生 4. 預期結果 vs 實際結果 5. 截圖/錯誤訊息 ### 測驗題目 (10 題) #### 身份驗證觀念篇 (5 題) 1. 為什麼 HTTP 協定需要額外的身份驗證機制? 2. Cookie 是存放在哪裡? 3. JWT 的全名是什麼? 4. JWT 由哪三個部分組成? 5. 為什麼 JWT 無法被偽造? #### 實務應用與 Issue 篇 (5 題) 6. LiveFit 登入成功後會收到什麼? 7. Token 過期後會發生什麼事? 8. Issue 的主要用途是什麼? 9. 好的 Bug 回報應該包含哪些資訊? 10. 為什麼要用 Issue 追蹤 Bug 而不是口頭回報? ### 海克絲的叮嚀 > 「JWT 讓我們可以在不查詢資料庫的情況下驗證使用者身份,效能很好。但要記住,Token 就像鑰匙,被偷走別人就能冒充你。另外,遇到 Bug 不要只是口頭說『壞掉了』,學會用 Issue 清楚描述問題。」 --- ## Day 9 - 老闆總是善變的,加個新功能吧!:後端程式碼結構 ### 劇情背景 海克絲要你新增一個功能——讓教練可以自己編輯個人簡介。你打開後端資料夾,發現裡面有 `routes/`、`controllers/`、`entities/` 好幾個資料夾...這些到底是什麼? ### 學習目標 - 了解後端程式碼的分層架構 - 認識 Route、Controller、Entity 各自的職責 - 學會閱讀現有的後端程式碼 - 理解一個 API 請求是怎麼被處理的 ### 核心概念 #### 後端為什麼要分這麼多資料夾? 就像公司有不同部門,各司其職: | 資料夾 | 角色 | 負責什麼 | |--------|------|----------| | `routes/` | 櫃檯接待 | 決定這個請求要交給誰處理 | | `controllers/` | 業務處理 | 執行商業邏輯、決定要做什麼 | | `entities/` | 資料倉庫 | 定義資料長什麼樣、跟資料庫溝通 | | `middlewares/` | 安檢人員 | 驗證身份、檢查權限 | #### LiveFit 後端結構 ```text backend/ ├── routes/ # 路由:「/api/courses 請到這裡」 │ ├── courses.js │ ├── users.js │ └── admin.js ├── controllers/ # 控制器:「好的,我來處理這個請求」 │ ├── courses.js │ ├── users.js │ └── admin.js ├── entities/ # 實體:「這是 Course 的資料格式」 │ ├── Course.js │ ├── User.js │ └── Coach.js └── middlewares/ # 中間件:「等等,先讓我檢查你的身份」 ├── auth.js └── isCoach.js ``` #### 一個請求的旅程 當使用者點「查看課程」: ```text [使用者] GET /api/courses ↓ [Route] routes/courses.js → 「這個請求交給 controller 處理」 ↓ [Controller] controllers/courses.js → 「去資料庫撈課程資料」 ↓ [Entity] entities/Course.js → 「執行 SELECT * FROM courses」 ↓ [Controller] 「資料拿到了,包裝成 JSON 回傳」 ↓ [使用者] 收到課程列表 ``` #### 實際程式碼長什麼樣? **Route(路由):** ```javascript // routes/courses.js router.get('/', courseController.getAll) // 取得所有課程 router.post('/', courseController.create) // 新增課程 router.put('/:id', courseController.update) // 更新課程 router.delete('/:id', courseController.delete) // 刪除課程 ``` **Controller(控制器):** ```javascript // controllers/courses.js static async getAll(req, res) { const courses = await courseRepo.find() // 從資料庫取資料 res.json({ status: 'success', data: courses }) } ``` ### 測驗題目 (10 題) #### 後端結構觀念篇 (5 題) 1. Route 的主要職責是什麼? 2. Controller 的主要職責是什麼? 3. Entity 定義了什麼? 4. Middleware 通常用來做什麼? 5. 為什麼要把程式碼分成不同資料夾? #### 程式碼閱讀篇 (5 題) 6. 看到 `router.get('/courses', ...)` 代表什麼? 7. Controller 裡的 `req` 和 `res` 分別是什麼? 8. 一個 API 請求的處理順序是什麼? 9. 如果要新增一個 API,需要改哪些檔案? 10. `router.post('/', ...)` 和 `router.get('/', ...)` 有什麼不同? ### 海克絲的叮嚀 > 「後端程式碼分層是有道理的——Route 負責接客、Controller 負責處理、Entity 負責資料。這個模式在任何後端框架都類似。學會看懂這個結構,以後不管用什麼語言,都能快速上手!」 --- ## Day 10 - 結訓日:完成最終任務! ### 劇情背景 結訓日到了,海克絲說:「這九天你學了很多觀念,現在是時候把它們串起來了。今天你要完成最終任務,證明你已經具備後端工程師的基本能力!」 ### 學習目標 - 完成初階任務(7 題程式碼修改) - 完成進階任務(8 步驟前端網站體驗) - 整合 Day 1-9 學到的所有知識 - 體驗完整的 LiveFit 平台運作 ### 最終任務總覽 #### 初階任務(7 題)— 改程式碼 依照指示修改檔案,push 到 GitHub 後由 Actions 自動驗收。 | # | 任務 | 對應觀念 | |---|------|---------| | 1 | 修改網站 Title | Day 4 靜態資源 | | 2 | 更換網站 Logo | Day 4 前端結構 | | 3 | 修改 Token 過期設定 | Day 8 JWT | | 4 | 新增 Entity 欄位說明 | Day 9 後端結構 | | 5 | 修改密碼驗證規則 | Day 9 Controller | | 6 | API 回傳總筆數 | Day 5 API 回應 | | 7 | 修改健康檢查格式 | Day 5 API 格式 | #### 進階任務(8 步驟)— 體驗完整流程 透過前端網站 + DBeaver 操作,體驗 LiveFit 平台的完整業務流程。 | # | 步驟 | 操作方式 | 對應觀念 | |---|------|---------|---------| | 1 | 認識 API 文件 | 瀏覽器 | Day 5 API | | 2 | 註冊兩個帳號 | 前端網站 | Day 5 API 請求 | | 3 | 新增技能 | DBeaver | Day 7 SQL INSERT | | 4 | 升級教練 | DBeaver | Day 7 SQL UPDATE | | 5 | 教練開課 | 前端網站 | Day 1 角色權限 | | 6 | 學員購買堂數 | 前端網站 | Day 7 資料庫 | | 7 | 學員預約課程 | 前端網站 | Day 9 後端處理 | | 8 | 查看預約紀錄 | 前端網站 | Day 6 前端渲染 | ### 繳交方式 **初階任務:** ```bash # 完成所有修改後 git add . git commit -m "完成最終任務" git push ``` → 到 GitHub Actions 頁面確認是否全部通過 ✅ **進階任務:** ```bash # 截圖放入 screenshots/ 資料夾 git add screenshots/ git commit -m "完成進階任務截圖" git push ``` ### 測驗題目 Day 10 沒有測驗題目,你的任務是完成最終任務並繳交! ### 海克絲的叮嚀 > 「恭喜你來到最後一天!這九天你學了很多,從 Git 到 Docker,從 API 到資料庫。現在是時候把這些知識串起來,完成最終任務。記住,動手做才是最好的學習方式。加油,我相信你可以的!」 --- # Part 2: 最終任務 --- ## 最終任務概述 最終任務分為兩個階段: - **初階任務**:修改程式碼(5 題) - **進階任務**:用前端網站體驗完整業務流程(7 步驟) --- ## 一、初階任務(5 題) ### 目標 讓學員體驗「改程式碼 → git push → 自動驗收」的開發流程 ### 形式 依照指示修改檔案 → git push 上傳 → GitHub Actions 自動驗收 ### 繳交方式 1. 完成所有修改後,執行以下 Git 指令: ```bash git add . git commit -m "完成最終任務" git push ``` 2. 到 GitHub Repo 的 Actions 頁面確認是否全部通過 3. 將 GitHub Repo 連結提交給助教 --- ### 題目設計 --- #### 題目 1:修改網站 Title | 項目 | 內容 | |------|------| | **情境說明** | 老闆說網站標題要改成「體驗營結業」版本 | | **修改檔案** | `frontend/index.html` | | **修改內容** | 找到 `<title>` 標籤,修改成以下內容 | **原本:** ```html <title>LiveFit+</title> ``` **請修改成:** ```html <title>LiveFit</title> ``` | **驗證方式** | GitHub Actions 檢查 Title 是否為 `LiveFit`(不含 `+`) | --- #### 題目 2:更換網站 Logo | 項目 | 內容 | |------|------| | **情境說明** | 設計師做了新版 Logo,請把網站的 Logo 換成新版 | | **修改檔案** | `frontend/src/layouts/LayoutHeader.vue` | | **修改內容** | 找到 `logo-text.png`,改成 `logo-text-v2.png` | **原本:** ```html <img src="/logo-text.png" alt="LiveFit+" class="h-6 w-auto" /> ``` **請修改成:** ```html <img src="/logo-text-v2.png" alt="LiveFit+" class="h-6 w-auto" /> ``` | **驗證方式** | GitHub Actions 檢查是否有 `logo-text-v2` | --- #### 題目 3:修改 Token 過期設定 | 項目 | 內容 | |------|------| | **情境說明** | 資安團隊建議 Token 過期時間從 30 天改成 7 天 | | **修改檔案** | `.env.example`(根目錄) | | **修改內容** | 找到 `JWT_EXPIRES_DAY` 設定,將值改成 `7d` | **請修改成:** ``` JWT_EXPIRES_DAY=7d ``` | **驗證方式** | GitHub Actions 檢查是否為 `JWT_EXPIRES_DAY=7d` | --- #### 題目 4:新增 Entity 欄位說明 | 項目 | 內容 | |------|------| | **情境說明** | 新人工程師看不懂資料表欄位的用途,請你加上中文說明 | | **修改檔案** | `backend/entities/CreditPackages.js` | | **修改內容** | 在檔案最上方新增以下註解 | **請新增這段註解:** ```javascript /** * 堂數方案資料表 * * 欄位說明: * - id: 方案編號(UUID) * - name: 方案名稱 * - credit_amount: 包含堂數 * - price: 方案價格 * - createdAt: 建立時間 */ ``` | **驗證方式** | GitHub Actions 檢查是否有 `堂數方案資料表` | --- #### 題目 5:修改密碼長度限制 | 項目 | 內容 | |------|------| | **情境說明** | 資安團隊說密碼長度要從 8 碼提高到 10 碼,以增強帳號安全性 | | **修改檔案** | `backend/controllers/users.js` | | **修改內容** | 找到密碼驗證的正規表達式,把最短長度從 8 改成 10 | **原本:** ```javascript const passwordPattern = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,16}/ ``` **請修改成:** ```javascript const passwordPattern = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{10,16}/ ``` | **驗證方式** | GitHub Actions 檢查是否有 `.{10,16}` | --- #### 題目 6:新增 API 回傳總筆數 | 項目 | 內容 | |------|------| | **情境說明** | 前端要顯示「共有幾種方案」,需要後端回傳 `total` 欄位 | | **修改檔案** | `backend/controllers/creditPackage.js` | | **修改內容** | 找到 `getAll` 函數,在回傳的 JSON 中新增 `total` 欄位 | **原本:** ```javascript res.status(200).json({ status: 'success', data: creditPackage }) ``` **請修改成:** ```javascript res.status(200).json({ status: 'success', total: creditPackage.length, data: creditPackage }) ``` | **驗證方式** | GitHub Actions 檢查是否有 `total: creditPackage.length` | --- #### 題目 7:修改健康檢查回傳格式 | 項目 | 內容 | |------|------| | **情境說明** | DevOps 說監控系統需要 JSON 格式的健康檢查回傳,不能只回傳純文字 | | **修改檔案** | `backend/app.js` | | **修改內容** | 找到 `/healthcheck` 路由,把回傳改成 JSON 格式 | **原本:** ```javascript app.get('/healthcheck', (req, res) => { res.status(200) res.send('OK') }) ``` **請修改成:** ```javascript app.get('/healthcheck', (req, res) => { res.status(200).json({ status: 'success', message: 'OK' }) }) ``` | **驗證方式** | GitHub Actions 檢查是否有 `message: 'OK'` | --- ### 完成後執行 完成以上 7 題後,請執行以下指令提交: ```bash # 1. 查看修改了哪些檔案 git status # 2. 加入所有修改 git add . # 3. 建立 commit git commit -m "完成最終任務" # 4. 推送到 GitHub git push ``` ### 題目總整理 | 題目 | 情境 | 修改檔案 | 驗證關鍵字 | |------|------|----------|-----------| | 1 | 改網站標題 | `frontend/index.html` | `<title>LiveFit</title>` | | 2 | 換網站 Logo | `frontend/src/layouts/LayoutHeader.vue` | `logo-text-v2` | | 3 | 調整 Token 過期 | `.env.example` | `JWT_EXPIRES_DAY=7d` | | 4 | 新增 Entity 說明 | `backend/entities/CreditPackages.js` | `堂數方案資料表` | | 5 | 修改密碼長度 | `backend/controllers/users.js` | `.{10,16}` | | 6 | 新增 API 總筆數 | `backend/controllers/creditPackage.js` | `total: creditPackage.length` | | 7 | 修改健康檢查格式 | `backend/app.js` | `message: 'OK'` | ### GitHub Actions 自動驗收 學員 push 後,GitHub Actions 會自動執行以下檢查: ```yaml # .github/workflows/check-final-mission.yml name: 檢查最終任務 on: push: branches: [main] jobs: check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # ===== 初階任務(7 題)===== - name: 初階 1 - 檢查網站 Title run: grep -q "<title>LiveFit</title>" frontend/index.html - name: 初階 2 - 檢查網站 Logo run: grep -q "logo-text-v2" frontend/src/layouts/LayoutHeader.vue - name: 初階 3 - 檢查 Token 過期設定 run: grep -q "JWT_EXPIRES_DAY=7d" .env.example - name: 初階 4 - 檢查 Entity 說明 run: grep -q "堂數方案資料表" backend/entities/CreditPackages.js - name: 初階 5 - 檢查密碼長度 run: grep -q ".{10,16}" backend/controllers/users.js - name: 初階 6 - 檢查 API 總筆數 run: grep -q "total: creditPackage.length" backend/controllers/creditPackage.js - name: 初階 7 - 檢查健康檢查格式 run: grep -q "message: 'OK'" backend/app.js # ===== 進階任務(8 張截圖)===== - name: 進階 1 - 檢查截圖 API 文件 run: ls screenshots/01-api-doc.* 2>/dev/null | head -1 - name: 進階 2 - 檢查截圖 註冊帳號 run: ls screenshots/02-register.* 2>/dev/null | head -1 - name: 進階 3 - 檢查截圖 新增技能 run: ls screenshots/03-add-skill.* 2>/dev/null | head -1 - name: 進階 4 - 檢查截圖 升級教練 run: ls screenshots/04-upgrade-coach.* 2>/dev/null | head -1 - name: 進階 5 - 檢查截圖 教練開課 run: ls screenshots/05-create-course.* 2>/dev/null | head -1 - name: 進階 6 - 檢查截圖 購買堂數 run: ls screenshots/06-buy-credits.* 2>/dev/null | head -1 - name: 進階 7 - 檢查截圖 預約課程 run: ls screenshots/07-book-course.* 2>/dev/null | head -1 - name: 進階 8 - 檢查截圖 預約紀錄 run: ls screenshots/08-booking-record.* 2>/dev/null | head -1 - name: 全部通過 run: echo "🎉 恭喜!所有任務都通過驗證!" ``` **驗收流程:** 1. 學員 push 到 GitHub 後,Actions 會自動執行 2. 到 Actions 頁面查看結果:綠勾 ✅ = 通過,紅叉 ❌ = 未通過 3. 點擊失敗的步驟可以看到哪一題沒過 --- ## 二、進階任務(前端網站體驗流程) ### 目標 讓學員透過前端網站體驗完整的 LiveFit 平台流程,同時認識 API 文件的存在 ### 形式 前端網站操作為主 + DBeaver 資料庫操作 + 認識 API 文件 ### 繳交方式 每完成一個步驟,截圖存成指定檔名,放入 `screenshots/` 資料夾後 push 上傳。 **截圖檔案規範:** ``` screenshots/ ├── 01-api-doc.png ├── 02-register.png ├── 03-add-skill.png ├── 04-upgrade-coach.png ├── 05-create-course.png ├── 06-buy-credits.png ├── 07-book-course.png └── 08-booking-record.png ``` **注意事項:** - 檔名必須完全一致(包含編號和小寫) - 圖片格式可以是 `.png`、`.jpg`、`.jpeg` - Push 後 GitHub Actions 會自動檢查檔案是否存在 ### 完整流程圖 ``` ┌─────────────────────────────────────────────────────────┐ │ LiveFit 體驗流程 │ ├─────────────────────────────────────────────────────────┤ │ │ │ Step 1: 認識 API 文件 │ │ └── 打開 API 文件,了解後端提供哪些功能 │ │ ↓ │ │ Step 2: 註冊兩個帳號(前端網站) │ │ ├── 帳號 A:之後會升級為教練 │ │ └── 帳號 B:學員角色,用來預約課程 │ │ ↓ │ │ Step 3: 用 DBeaver 新增技能 │ │ └── INSERT 一筆技能資料(升級教練時需要選擇技能) │ │ ↓ │ │ Step 4: 用 DBeaver 升級教練 │ │ └── UPDATE 帳號 A 的 role 為 COACH │ │ ↓ │ │ Step 5: 教練登入 & 開課(前端網站) │ │ ├── 用帳號 A 登入 │ │ └── 建立一堂課程(選擇剛剛新增的技能) │ │ ↓ │ │ Step 6: 學員購買堂數(前端網站) │ │ ├── 用帳號 B 登入 │ │ └── 購買堂數方案 │ │ ↓ │ │ Step 7: 學員預約課程(前端網站) │ │ └── 預約剛剛教練開的課 │ │ ↓ │ │ Step 8: 查看預約紀錄(前端網站) │ │ └── 確認預約成功,體驗完整流程 │ │ │ └─────────────────────────────────────────────────────────┘ ``` ### 詳細步驟說明 --- #### Step 1:認識 API 文件 | 項目 | 內容 | |------|------| | **任務說明** | 打開專案的 API 文件(Swagger 或 README),瀏覽後端提供哪些 API | | **觀察重點** | API 文件會列出所有可用的 API 端點、需要的參數、回傳的格式 | | **思考問題** | 前端網站的每個功能(註冊、登入、購買、預約)背後都對應到哪個 API? | | **帶入觀念** | **API 文件是前後端溝通的橋樑**:後端工程師寫完 API 後,會產出 API 文件讓前端知道怎麼串接。這是團隊協作的重要文件。 | --- #### Step 2:註冊兩個帳號 | 項目 | 內容 | |------|------| | **操作方式** | 前端網站 `localhost:3000` | | **任務說明** | 在網站上註冊兩個帳號 | | **帳號 A** | 姓名:你的名字(教練用)、Email:自訂、密碼:自訂 | | **帳號 B** | 姓名:測試學員、Email:自訂、密碼:自訂 | | **驗證方式** | 截圖註冊成功的畫面 | | **帶入觀念** | **使用者註冊流程**:當你按下「註冊」按鈕,前端會發送 POST 請求到 `/api/users/signup`,後端驗證資料後存入資料庫。 | --- #### Step 3:用 DBeaver 新增技能 | 項目 | 內容 | |------|------| | **操作方式** | DBeaver | | **任務說明** | 新增一筆技能資料,升級教練和開課時都需要選擇技能類型 | | **SQL 指令** | `INSERT INTO "SKILL" (name) VALUES ('瑜珈');` | | **驗證方式** | 截圖 DBeaver 執行成功的畫面,或查詢 `SELECT * FROM "SKILL";` 的結果 | | **帶入觀念** | **資料之間的關聯**:教練(Coach)和課程(Course)都需要關聯到技能(Skill),這是資料庫的「外鍵關聯」。沒有技能資料,就無法升級教練或開課。這就是 Day 7 學到的資料表關聯概念。 | --- #### Step 4:用 DBeaver 升級教練 | 項目 | 內容 | |------|------| | **操作方式** | DBeaver | | **任務說明** | 把帳號 A 的 role 從 USER 改成 COACH | | **SQL 指令** | `UPDATE "USER" SET role = 'COACH' WHERE email = '你的帳號A的Email';` | | **驗證方式** | 截圖 DBeaver 執行成功的畫面 | | **帶入觀念** | **為什麼要用資料庫改?** 因為「升級教練」是管理員功能,一般使用者沒有權限。在真實系統中,這會由管理員在後台操作;在開發階段,我們直接改資料庫比較快。 | --- #### Step 5:教練登入 & 開課 | 項目 | 內容 | |------|------| | **操作方式** | 前端網站 | | **任務說明** | 用帳號 A(已升級為教練)登入,然後建立一堂課程 | | **課程資訊** | 課程名稱、時間、人數上限、課程說明、技能類型(選擇剛剛新增的技能) | | **驗證方式** | 截圖課程建立成功的畫面 | | **帶入觀念** | **角色權限控管**:同一個帳號,升級前只能瀏覽,升級後才能開課。這就是 Day 1 學到的 User Story 在系統中的實現——不同角色有不同權限。 | --- #### Step 6:學員購買堂數 | 項目 | 內容 | |------|------| | **操作方式** | 前端網站 | | **任務說明** | 登出教練帳號,用帳號 B(學員)登入,然後購買堂數方案 | | **操作步驟** | 1. 登出 → 2. 用帳號 B 登入 → 3. 到堂數方案頁面 → 4. 購買任一方案 | | **驗證方式** | 截圖購買成功的畫面,顯示剩餘堂數 | | **帶入觀念** | **購買流程的資料變化**:當你購買成功,後端會在 `CREDIT_PURCHASE` 資料表新增一筆紀錄,並更新你的剩餘堂數。這就是 Day 7 學到的資料庫操作。 | --- #### Step 7:學員預約課程 | 項目 | 內容 | |------|------| | **操作方式** | 前端網站 | | **任務說明** | 用帳號 B 預約剛剛教練開的課程 | | **操作步驟** | 1. 瀏覽課程列表 → 2. 找到教練開的課 → 3. 點擊預約 | | **驗證方式** | 截圖預約成功的畫面 | | **帶入觀念** | **預約流程的資料變化**:預約成功後,後端會在 `COURSE_BOOKING` 新增紀錄,同時扣除你的堂數。這是 Day 9 學到的 CRUD 中的 Create 操作。 | --- #### Step 8:查看預約紀錄 | 項目 | 內容 | |------|------| | **操作方式** | 前端網站 | | **任務說明** | 到「我的課程」或「預約紀錄」頁面,確認預約成功 | | **驗證方式** | 截圖顯示預約紀錄的畫面 | | **帶入觀念** | **完整的使用者旅程**:你剛剛體驗了從註冊、購買、到預約的完整流程。每一步操作的背後,都是前端發送 API 請求、後端處理邏輯、資料庫存取資料。這就是一個完整系統的運作方式! | --- ### 選做:用 Postman 體驗 API 如果你想更深入了解 API 的運作,可以嘗試: | 項目 | 內容 | |------|------| | **任務說明** | 打開 Postman,手動發送一個 API 請求 | | **建議嘗試** | `GET http://localhost:8080/api/coaches` (取得教練列表) | | **觀察重點** | 比較 Postman 的回應和前端網站顯示的資料,是不是一樣? | | **帶入觀念** | **Postman 是 API 測試工具**:前端網站幫你把 API 請求包裝成漂亮的介面,但底層都是在發送 HTTP 請求。Postman 讓你可以直接發送請求,這在開發和除錯時非常有用。 | --- ### DBeaver 操作參考 ```sql -- Step 3: 新增技能(必須先新增,升級教練時需要選擇技能) INSERT INTO "SKILL" (name) VALUES ('瑜珈'); -- 也可以新增多筆技能 INSERT INTO "SKILL" (name) VALUES ('重訓'); INSERT INTO "SKILL" (name) VALUES ('有氧'); -- 查詢確認技能是否新增成功 SELECT * FROM "SKILL"; -- Step 4: 把指定 Email 的使用者升級為教練 UPDATE "USER" SET role = 'COACH' WHERE email = '你的帳號A的Email'; -- 查詢確認是否修改成功 SELECT id, name, email, role FROM "USER" WHERE email = '你的帳號A的Email'; ``` --- ### 學員產出 完成以下截圖並存入 `screenshots/` 資料夾: | 檔名 | 內容 | |------|------| | `01-api-doc.png` | API 文件畫面 | | `02-register.png` | 兩個帳號註冊成功 | | `03-add-skill.png` | DBeaver 新增技能成功 | | `04-upgrade-coach.png` | DBeaver 升級教練成功 | | `05-create-course.png` | 教練開課成功 | | `06-buy-credits.png` | 學員購買堂數成功 | | `07-book-course.png` | 學員預約課程成功 | | `08-booking-record.png` | 預約紀錄畫面 | 完成後執行: ```bash git add screenshots/ git commit -m "完成進階任務截圖" git push ``` --- ## 任務三:微調功能細節 > 以下為貼到任務系統的格式,可直接複製使用 --- ### 任務描述 ## 🎯 任務目標 在這次任務中,你將完成兩個部分: 1. **初階任務(7 題)**:修改程式碼,體驗「改程式碼 → git push → 自動驗收」的開發流程 2. **進階任務(8 步驟)**:透過前端網站體驗完整的 LiveFit 平台流程 這是後端工程師日常工作的縮影:**修改程式碼解決問題,並理解系統如何串連前端、後端與資料庫**。 ## 📝 前置作業 **請先完成以下步驟,再開始進行任務:** 1. **觀看任務攻略影片**:[任務攻略影片連結](請填入影片連結) 2. **下載 Workflow 檔案**:[check-final-mission.yml](請填入下載連結) 3. **將 Workflow 檔案放入專案**:把下載的 `check-final-mission.yml` 放到你專案的 `.github/workflows/` 資料夾中(如果資料夾不存在,請自行建立) 完成前置作業後,即可依序攻略以下任務步驟! --- ## 📝 任務說明與步驟 --- ### Part 1:初階任務(7 題程式碼修改) 依照指示修改檔案,完成後 git push 上傳,GitHub Actions 會自動驗收。 **題目 1:修改網站 Title** - 修改檔案:`frontend/index.html` - 找到 `<title>LiveFit+</title>`,改成 `<title>LiveFit</title>` **題目 2:更換網站 Logo** - 修改檔案:`frontend/src/layouts/LayoutHeader.vue` - 找到 `logo-text.png`,改成 `logo-text-v2.png` **題目 3:修改 Token 過期設定** - 修改檔案:`.env.example`(根目錄) - 找到 `JWT_EXPIRES_DAY`,改成 `JWT_EXPIRES_DAY=7d` **題目 4:新增 Entity 欄位說明** - 修改檔案:`backend/entities/CreditPackages.js` - 在檔案最上方新增以下註解: ```javascript /** * 堂數方案資料表 * * 欄位說明: * - id: 方案編號(UUID) * - name: 方案名稱 * - credit_amount: 包含堂數 * - price: 方案價格 * - createdAt: 建立時間 */ ``` **題目 5:修改密碼長度限制** - 修改檔案:`backend/controllers/users.js` - 找到 `.{8,16}`,改成 `.{10,16}` **題目 6:新增 API 回傳總筆數** - 修改檔案:`backend/controllers/creditPackage.js` - 在 `getAll` 函數的回傳 JSON 中新增 `total: creditPackage.length` **題目 7:修改健康檢查回傳格式** - 修改檔案:`backend/app.js` - 找到 `/healthcheck` 路由,把 `res.send('OK')` 改成: ```javascript res.status(200).json({ status: 'success', message: 'OK' }) ``` --- ### Part 2:進階任務(8 步驟前端體驗) 透過前端網站 + DBeaver 操作,體驗 LiveFit 平台的完整業務流程。 **Step 1:認識 API 文件** 1. 打開專案的 API 文件(Swagger),網址:`http://localhost:8080/api-docs` 2. 瀏覽後端提供哪些 API 端點 **Step 2:註冊兩個帳號** 1. 開啟前端網站:`http://localhost:3000` 2. 註冊 **帳號 A**(之後會升級為教練):姓名、Email、密碼自訂 3. 註冊 **帳號 B**(學員角色):姓名、Email、密碼自訂 **Step 3:用 DBeaver 新增技能** 1. 開啟 DBeaver,連接到 PostgreSQL 資料庫 2. 執行 SQL:`INSERT INTO "SKILL" (name) VALUES ('瑜珈');` 3. 確認新增成功:`SELECT * FROM "SKILL";` **Step 4:用 DBeaver 升級教練** 1. 執行 SQL:`UPDATE "USER" SET role = 'COACH' WHERE email = '你的帳號A的Email';` 2. 確認修改成功:`SELECT id, name, email, role FROM "USER" WHERE email = '你的帳號A的Email';` **Step 5:教練登入 & 開課** 1. 用帳號 A(已升級為教練)登入前端網站 2. 建立一堂課程(填寫課程名稱、時間、人數上限、選擇剛剛新增的技能) **Step 6:學員購買堂數** 1. 登出教練帳號,用帳號 B(學員)登入 2. 到堂數方案頁面,購買任一方案 **Step 7:學員預約課程** 1. 瀏覽課程列表,找到教練開的課 2. 點擊預約課程 **Step 8:查看預約紀錄** 1. 到「我的課程」或「預約紀錄」頁面 2. 確認預約成功 --- ## 📤 繳交內容 請在下方欄位提交以下資訊: ### 1. 你完成的等級 請標註你完成的是哪個等級: - **LV1**:完成初階任務(7 題程式碼修改) - **LV3**:完成初階任務 + 進階任務(7 題 + 8 步驟) ### 2. 你的 GitHub Repo 連結 (請貼上你 Fork 後的儲存庫網址,例如:`https://github.com/你的帳號/2025-backend-camp`) ### 3. 初階任務驗收(LV1、LV3 都要做) 完成 7 題程式碼修改後,執行以下指令: ```bash git add . git commit -m "完成最終任務" git push ``` 到 GitHub Actions 頁面確認是否全部通過 ✅ ### 4. 進階任務截圖(僅 LV3 需要,8 張放入 `screenshots/` 資料夾) | 檔名 | 內容 | |------|------| | `01-api-doc.png` | API 文件畫面(Swagger) | | `02-register.png` | 兩個帳號註冊成功 | | `03-add-skill.png` | DBeaver 新增技能成功 | | `04-upgrade-coach.png` | DBeaver 升級教練成功 | | `05-create-course.png` | 教練開課成功 | | `06-buy-credits.png` | 學員購買堂數成功 | | `07-book-course.png` | 學員預約課程成功 | | `08-booking-record.png` | 預約紀錄畫面 | 完成截圖後執行: ```bash git add screenshots/ git commit -m "完成進階任務截圖" git push ``` 📌 提醒:若操作過程遇到問題,請截圖錯誤訊息至 Discord 的作業討論頻道發問,我們會協助你排除問題! --- ## 四、學到的觀念整理 | 階段 | 學到的觀念 | |------|-----------| | **初階** | 前後端分離架構、資料夾結構、環境變數、開發者工具、資料庫操作、CRUD 程式碼 | | **進階** | API 文件的重要性、完整使用者旅程、角色權限控管、前端操作背後的 API 請求、資料庫與系統的關係 | --- ## 四、需要產出的檔案 | 檔案 | 位置 | 用途 | |------|------|------| | `final-mission.md` | `_private/final-mission/` | 學員看的任務說明 | | `LiveFit.postman_collection.json` | `_private/final-mission/` | Postman Collection | | `upgrade-coach.sql` | `_private/final-mission/` | DBeaver SQL 範例 | --- ## 結訓感言 恭喜你完成了 10 天的後端體驗營與最終任務! 在這段旅程中,你學到了: - Day 1:需求分析與使用者故事 - Day 2:Git 與 GitHub - Day 3:Docker 環境建置 - Day 4:前後端架構 - Day 5:RESTful API - Day 6:前端渲染與 JSON - Day 7:SQL 語法與資料庫 - Day 8:JWT 認證與 Issue - Day 9:CRUD 操作 - Day 10:結訓日與最終任務 這只是後端開發的起點,還有很多東西等著你探索。保持好奇心,持續學習,你一定會成為優秀的工程師! — 海克絲