如何用 Codex 寫了一個記帳 App:從需求到程式碼的完整實作

之前一直都是透過 Excel 記帳,好處是自由度很高,不管是分類、統計還是自己拉圖表都不是什麼問題。但最大的問題就是手機操作起來真的很麻煩。平常在外面買個東西、吃個飯,想要順手記上一筆,還得打開 Excel、找到正確的工作表,再慢慢輸入日期、分類、金額等資料。

久而久之,常常就變成晚點再記,然後晚點就忘記了。

既然現在 AI 寫程式已經越來越方便,那不然請 Codex 幫忙看看,能不能乾脆做一個符合自己需求的記帳 App?從我想要一個簡單的記帳 App開始,先把需求整理清楚,再把規格交給 Codex,看看最後能不能真的做出一個自己每天都能拿來使用的記帳工具。

不要急著叫 Codex 寫程式,先把需求想清楚。

雖然 Codex 可以直接根據一句幫我做記帳 App 開始寫程式,但這也代表很多事情必須由它自己決定,例如要使用什麼技術、資料怎麼儲存,甚至連哪些功能應該出現在第一版,都可能變成 Codex 自由發揮。

與其做到一半才發現方向跟自己想的不一樣,不如一開始就把範圍講清楚。

不過本人也不是什麼厲害的程式高手,要我一開始就直接規劃出完整的技術架構,實在有點太為難自己了,更別說馬上決定該用哪些框架、資料庫與前端技術。

像下面這套技術架構,當然也不是我一開始就憑空想出來的。

  • Backend:.NET 8 / ASP.NET Core Web API
  • ORM:Entity Framework Core
  • Database:SQLite
  • Frontend:React + TypeScript
  • UI:Tailwind CSS
  • Chart:Recharts
  • App 型態:Responsive Web App + PWA

還是先請 ChatGPT 幫我們進行規劃囉

我想請 Codex 開發個簡單的記帳 App 請先幫我規劃需要的功能

建議直接把這份規劃進一步整理成 Codex 可以直接開始施工的規格,包含技術架構、資料庫 Schema、API、頁面清單、UI Wireframe、開發階段與驗收條件。

好的,整理成 Codex 可以直接開始施工的規格。

我們就可以得到一份很棒的開發規格書

接著打開 Codex 建立一個新的專案與對話,將規格書貼上。

本機環境忘記安裝 .NET SDK 8.0.425,補上後就順利完成了。

已經把專案提交到 Github 給大家參考

程式寫完了,真正麻煩的才正要開始。

現在寫程式可能已經不是最困難的部分了,只要先把需求與規格整理清楚,透過 Codex 很快就能協助建立 Backend、Frontend、Database,甚至連 API、操作畫面與測試都可以一起處理。

真正麻煩的是這些東西到底要怎麼部署?畢竟程式能在開發電腦上跑起來,跟把它變成一套隨時可以使用、穩定運作的服務完全是兩回事。

想到之後還得處理執行環境、版本相依、服務自動啟動,以及未來程式更新等問題。為了省去這些麻煩,我最後還是決定乾脆把整套系統全部包成 Docker。

接著到 Codex 建立另一個對話,協助我們把 React 前端與 .NET API 打包成同一個 Docker 容器。

如何透過容器運行這個 App

請先安裝 Docker Desktop 以及 WSL 再依下列步驟設定。

在專案的資料夾新增 Dockerfile

FROM node:24-bookworm-slim AS frontend
WORKDIR /web
RUN npm install -g pnpm@11
COPY frontend/simple-expense-tracker-web/package.json frontend/simple-expense-tracker-web/pnpm-lock.yaml ./
COPY frontend/simple-expense-tracker-web/pnpm-workspace.yaml ./
RUN pnpm install --frozen-lockfile
COPY frontend/simple-expense-tracker-web/ ./
RUN pnpm build

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY . .
COPY --from=frontend /web/dist ./frontend/simple-expense-tracker-web/dist
RUN dotnet publish backend/SimpleExpenseTracker.Api \
    -c Release -o /app/publish

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish .
RUN mkdir -p /data && chown app:app /data
USER app
ENV ASPNETCORE_HTTP_PORTS=8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "SimpleExpenseTracker.Api.dll"]

在同一資料夾新增 .dockerignore,避免把本機建置檔與記帳資料打包進映像

**/node_modules
**/dist
**/bin
**/obj
**/publish
**/*.db
**/*.db-*
.git
**/.env*

在同一資料夾新增 compose.yaml

services:
  app:
    build: .
    ports:
      - "5080:8080"
      - "8080:8080"
    environment:
      ASPNETCORE_ENVIRONMENT: Production
      ConnectionStrings__Default: "Data Source=/data/expense-tracker.db"
      AllowedHosts: "*"
      TZ: Asia/Taipei
    volumes:
      - expense-data:/data
    restart: unless-stopped

volumes:
  expense-data:

用 PowerShell 啟動

cd "C:\Users\介勛\Documents\ChatGPT\簡易記帳 App 開發\SimpleExpenseTracker"
docker compose up -d --build
[+] Building 39.9s (26/26) FINISHED                                             
[+] up 4/4
✔ Image simpleexpensetracker-app Built
✔ Network simpleexpensetracker_default Created
✔ Volume simpleexpensetracker_expense-data Created
✔ Container simpleexpensetracker-app-1 Started

打開 Docker Desktop 就可以看到我們的容器已經順利運行起來了

輸入 URL 確認一下功能是否正常

接下來映像檔上傳到遠端倉庫,登入 Docker Hub 與輸入你的帳號與密碼。

docker login -u jieshiun
i Info → A Personal Access Token (PAT) can be used instead.
To create a PAT, visit https://app.docker.com/settings


Password:

Login Succeeded

將本機映像檔加上你的使用者名稱與儲存庫標籤

docker tag simpleexpensetracker-app:latest jieshiun/simpleexpensetracker-app:1.0

將標記好的映像檔上傳到遠端倉庫

docker push jieshiun/simpleexpensetracker-app:1.0

映像檔僅有 100 MB,整體非常輕量。

使用容器運行

我們先到 Container Station 的儲存空間,建立容器稍後使用的 Volume。

  • expense_data:將 SQLite 放在持久化 Volume,讓重建容器後仍會保留帳目。

接著建立容器,輸入映像檔名稱,下一步。

  • 映像檔:jieshiun/simpleexpensetracker-app:1.0

設定容器,點選進階設定。

點選網路,網路模式選擇自訂 Bridge,勾選使用靜態 IP 位址,套用。

點選儲存空間,新增儲存空間對應如下,點選套用。

  • expense_data:/data

我們至少需要新增以下環境變數,點選套用。

  • ASPNETCORE_ENVIRONMENT:Production
  • ConnectionStrings__Default:Data Source=/data/expense-tracker.db
  • AllowedHosts:*
  • TZ:Asia/Taipei

確認摘要無誤後,點選完成。

容器順利運行

使用應用程式運行

到應用程式,點選建立。

version: '3'

services:
  simpleexpensetracker:
    image: 'jieshiun/simpleexpensetracker-app:1.0'
    restart: unless-stopped
    networks:
      qnet:
        ipv4_address: 192.168.0.103
    environment:
      ASPNETCORE_ENVIRONMENT: 'Production'
      ConnectionStrings__Default: 'Data Source=/data/expense-tracker.db'
      AllowedHosts: '*'
      TZ: 'Asia/Taipei'
    volumes:
      - expense_data:/data

volumes:
  expense_data:

networks:
  qnet:
    external: true
    name: qnet-static-eth0-0fa2ce

訪問設定的 IP 位置,正常畫面如下。

網域 DNS 設定

首先到您購買網域名稱的平台,確認 DNS 設定是否正確。

我們使用 money.ivancheng.tw 作為 App 的網域名稱

  • CNAME 紀錄:money 指向根網域,例如 ivancheng.tw。

還沒有設定 DDNS 的朋友,這邊可以先手動指定 IP 位址,畢竟路由器的 IP 變動不會這麼頻繁。

Godaddy 的 DNS 會先將 money.ivancheng.tw 解析至家中的 Nginx Proxy Manager,之後再透過域名幫我們反向代理到正確的 App 服務。

反向代理設定

接著我們到 Nginx Proxy Manager 的管理介面,設定根據使用者存取的網域名稱,判斷流量應該轉送至哪一個內部服務。

建立 Proxy Host 如下

  • Domain Names:money.ivancheng.tw
  • Scheme:HTTP
  • Forward Hostname / IP:您的 App IP 與 Forward Port

免費 SSL/TLS 憑證設定

可以讓 Nginx Proxy Manager 自動向 Let’s Encrypt 申請免費 SSL/TLS 憑證,之後也會負責憑證的續期。

前提是 DNS 已經正確指向你的對外 IP,而且 Router 有將 TCP 80、443 導向 Nginx Proxy Manager。

編輯 Proxy Host,切換到 SSL 頁面。

接著 SSL Certificate 選擇 Request a new Certificate。

  • Force SSL:自動將 HTTP 連線重新導向 HTTPS,確保網站統一透過加密連線存取。
  • HTTP/2 Support:讓瀏覽器更有效率地載入網站的 CSS、JavaScript、圖片等資源,對 WordPress 很適合。
  • HSTS Enabled:告訴瀏覽器這個網站之後只能使用 HTTPS,不要再嘗試使用 HTTP。不建議剛設定反向代理與憑證時馬上開啟,因為瀏覽器收到 HSTS 後會記住這個設定,如果之後 SSL、DNS 或反向代理設定出錯,測試與除錯會比較麻煩。
  • HSTS Sub-domains:除非你可以確定網域底下所有現在及未來使用的子網域都會提供 HTTPS,否則暫時不要開比較保險。
  • Use DNS Challenge:另外一種 Let’s Encrypt 網域驗證方式,我們的情況不用開。
  • Trust Upstream Forwarded Proto Headers:選項主要是當 Nginx Proxy Manager 前面還有另一層 Reverse Proxy、Load Balancer 或 CDN 時使用。

點選 Save,可以看到 SSL 已經變成 Let’s Encrypt。

最後確認 Nginx Proxy Manager 能夠根據使用者存取的網域名稱來進行導向

讓 Web 彷彿手機原生 App

要在 iOS 上安裝和使用 PWA 漸進式網頁應用程式,您必須使用 Safari 瀏覽器開啟網站,並透過加入主畫面功能將其釘選在手機桌面。

  • 使用 iPhone 或 iPad 的 Safari 瀏覽器開啟目標網站。
  • 點選下方工具列中間的分享圖示。
  • 在選單中向下滑動並點選加入主畫面。
  • 確認名稱無誤後,點擊右上角的新增,即可在主畫面上像使用 App 一樣開啟全螢幕模式。

Access List

Nginx Proxy Manager 的 Access List 支援 HTTP Basic Authentication,你可以建立帳號與密碼,並指定某個 Proxy Host 必須通過驗證才能進入。這樣甚至不需要修改 React 或 ASP.NET Core 的程式,就能先替整個網站加上一層簡單的登入保護。

很適合我們這種自己或家人使用的記帳 App,不用為了一個記帳工具另外開發會員系統。

只要在 Proxy Host 的 Access List 選擇對應的設定,Nginx Proxy Manager 就會要求輸入帳號與密碼,必須通過驗證才能進入記帳 App 囉。

原本只是覺得用 Excel 記帳在手機上實在不太方便,沒想到最後一路從整理需求、規劃功能、選擇技術架構,到請 Codex 寫程式,甚至連 Docker、Nginx Proxy Manager 與 HTTPS 都一起處理了。

我最大的感想反而不是 AI 寫程式真的很厲害,而是現在要做一套自己用的小工具,門檻真的比以前低了非常多。現在已經不需要等到什麼都學會了才開始,原本只是腦中想想的記帳 App 就這樣真的跑起來了。