專案背景
「AI 廣告看板排程平台」(AI Advertising Display Scheduler)是一套可公開操作的數位看板系統,涵蓋看板管理、素材上傳或生成、播放時段設定,以及模擬播放器上的即時輪播。它把 Digital Signage 產品的核心流程濃縮成一個可實際操作的 side project。
前端用 Vue 3 + Vite,想完整走一遍 Composition API 與 Pinia 的開發體驗;後端用 .NET 8 Web API 跑在 Linux EC2,資料庫沿用既有 RDS PostgreSQL,前端託管在 AWS Amplify。AI 能力分兩階段迭代:Phase 2 以自然語言管理排程(Semantic Kernel function calling),Phase 3 透過 Replicate API 整合 Stable Diffusion 生圖。

系統架構概覽
專案採 monorepo:frontend/ 為 Vue 3 + Vite + Pinia + TanStack Query;backend/ 為 .NET 8 + EF Core + JWT。素材檔案存於 S3,API 透過 nginx 反向代理對外。整體是典型的前後端分離 SaaS 架構,規模控制在 side project 可維護的範圍內,但從後台設定到播放器輪播的流程完整走通。
Multi-tenant 資料隔離
Multi-tenant 不是只在 UI 上分租戶,而是從認證到查詢都強制隔離。JWT payload 帶 tenant_id 與 role,middleware 解析後注入 request-scoped 的 tenant context;EF Core 對所有業務表套用 global query filter,確保 ORM 層自動加上 WHERE tenant_id = current。
寫入時 service 層會覆寫 tenant_id,不信任 client 傳入值。種子資料建立兩個租戶(Coffee & Co. / Retail Plus),landing page 提供公開測試帳號,方便切換帳號驗證隔離是否生效。RBAC 則區分 admin(全 CRUD)與 editor(不可刪除)。
Playback 排程核心
整個平台最重要的商業邏輯是 Playback API:依 device_key 取得「此刻應播放的素材」。ScheduleResolverService 依序檢查日期範圍、星期、時段、campaign 狀態,再以 priority 與 created_at 決定勝出排程。這段邏輯獨立成 service 並附 unit test,Phase 2 的 AI 工具 preview_playback 也直接重用同一套 resolver。
Display Player 頁面每 10 秒 polling 此 API,排程變更後可在短時間內反映到模擬看板,使用者能直接看到「此刻播什麼」。
AI 排程助理:Function Calling 與安全設計
Phase 2 的 AI 助理使用 Semantic Kernel 定義工具集(query_schedules、update_schedule、preview_playback 等)。LLM 解析自然語言後呼叫工具,但有三個刻意設計的護欄:
第一,AI 不繞過業務規則——工具層直接呼叫 Phase 1 的 service,tenant 隔離、時間驗證、RBAC 全部照常生效。第二,寫入類操作走確認流程:AI 先回傳「變更摘要卡片」,使用者按 Confirm 才執行,狀態記錄在 ai_actions 表。第三,完整 audit log,可查 AI 做過哪些操作。
介面上左側是 AI 對話、右側是看板播放器。對助理說「現在在這個看板播 XX 廣告」、確認變更後,十秒內看板畫面就會切換——排程調整與播放結果在同一個畫面連動,比純文字回覆更直觀。
Stable Diffusion 素材生成
Phase 3 採兩段式 pipeline:gpt-4o-mini 先把表單輸入轉成廣告文案與 image prompt,再透過 Replicate API(SDXL / FLUX)生成主視覺。因 diffusion 模型文字不可靠,後端用 ImageSharp 把文案疊加到圖上,輸出可直接排程的成品。
Stable Diffusion 生態雖是 Python,但 .NET 不需要內嵌模型——走 HTTP 託管 API 即可,EC2 不必有 GPU。mock-first 策略讓流程先跑通,再切換 AI_PROVIDER=replicate。
.NET 8 on Linux 部署
後端以 dotnet publish 產出,在 EC2 上以獨立 systemd service(ad-scheduler-api)運行,nginx 反向代理掛 ad-api.yuweiyang.io。GitHub Actions 在 merge main 後 SSH 部署。前端 Amplify 連 GitHub,push 自動 build,自訂網域 ad-demo.yuweiyang.io。
資料庫在既有 RDS 開獨立 database ad_scheduler,不與 blog 混表。這套部署與我個人網站(Amplify + EC2 + RDS + S3)共用基礎設施,額外成本趨近於零。
公開 Demo 與成本控管
既然開放公開存取,就必須假設會被濫用。除了 JWT 登入,還有四層 AI 費用防護:應用層每日對話/生圖額度、rate limiting、OpenAI/Replicate 供應商端 spend limit、AWS Budgets 警報。資料則每日 cron 重置 seed,形成 self-resetting sandboxed demo。
Live Demo 與原始碼
Live Demo:ad-demo.yuweiyang.io
Landing page 提供測試租戶帳密,可直接進後台操作 AI 助理與看板播放器。
結語
這個專案把產品流程、multi-tenant 架構、AI 安全整合與 AWS 部署串成一條可實際操作的線。若你對 Playback 排程判斷、Semantic Kernel 工具設計或部署細節有興趣,歡迎在 demo 上直接操作,或到 GitHub 看 PR 歷史與 README 裡的技術決策說明。