Files
Arcrun/.agents/specs/arcrun/landing-page.md
Leo 13b01328c1 docs: add SDD specs + user requirements + tests
- .agents/specs/: spec-driven-dev docs for arcrun MVP, auth-recipe,
  credential-primitives-wasm (active refactor), landing-page,
  sdk-and-website, u6u-core-mvp, u6u-platform-evolution.
- .agents/steerings/tech.md: detailed tech stack rationale.
- docs/user_requirements/: long-form requirements incl. credential
  primitives, pages spec, py strategy analysis.
- tests/: end-to-end harness scaffolding.

These are the durable context backing CLAUDE.md's SDD protocol.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 17:48:24 +08:00

12 KiB
Raw Permalink Blame History

arcrun.dev Landing Page — SDD

目標:給工程師一個門面,可以取得 API Key、管理 Key、探索 APISwagger),同時藉此獲得會員 Email。 原則:先快速可用,不追求功能完整。榮譽牆、Python Lib 是後期。


0. 範圍(這份 SDD 涵蓋)

功能 說明
首頁 Hero 說明 arcrun 是什麼,CTA 取得 API Key
OAuth 登入 Google / GitHub(用自己的 auth recipe — dogfooding
API Key 管理 查看、Rotate、Revoke
Swagger UI 嵌入 /api,讓工程師直接試打
榮譽牆 /integrations 靜態骨架,先列 20 個 recipe,無動態數字
中英切換 ?lang=zh

不在本次範圍Python lib、Donate 整合、Social Proof 即時數字、貢獻者排行。


1. 技術選型

1.1 框架:Next.jsApp Router

選 Next.js 而非 Astro 的原因

  • finally-click 已有完整 Next.js + OAuth 回調實作,可直接複用模式
  • API Key 管理頁有登入態保護需求,Next.js 的 middleware 最直接
  • Cloudflare Pages 支援 Next.js@cloudflare/next-on-pages
  • Astro 在動態路由保護上摩擦較多

1.2 部署:Cloudflare Pages

arcrun.dev → Cloudflare PagesNext.js
API calls → cypher.arcrun.dev(現有 Worker

1.3 儲存:現有 cypher-executor CREDENTIALS_KV + 新增 USERS_KV

現有 cypher-executor Worker 已有:

  • CREDENTIALS_KV{api_key}:cred:{name} 存 tenant credentials
  • RECIPESauth recipes

新增需求:

  • USERS_KV:存 user 帳號,key = user:{provider}:{provider_user_id}
    • value: { email, display_name, api_key, created_at, provider }
  • SESSIONS_KV:存 login sessionkey = sess:{session_id}
    • value: { api_key, email, expires_at }
    • TTL = 7 天

兩個 KV 都加到 cypher-executor wrangler.toml

1.4 OAuth — Dogfooding 自己的 Auth Recipe

登入用 arcrun 自己的 auth recipe

  • 不是用 arcrun auth recipe 的 http_request runner 去打第三方
  • 而是 直接複用 recipe YAML 裡定義的 OAuth App 設定(client_id/secret
  • Worker 端實作 standard OAuth2 authorization_code flow

支援提供商(MVP

  • Googlegoogle_drive recipe 的 OAuth App,或另建 arcrun-login Google App
  • GitHubgithub recipe 的 OAuth App

登入 OAuth App 與 auth recipe 的 OAuth App 可以是同一個(只要 scopes 包含 openid profile email),但更乾淨的做法是登入用獨立的 Google/GitHub App(只要 email scope),auth recipe 用的是資源存取 App。

決策:登入用獨立 OAuth App

  • GOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRET — 只申請 openid profile email
  • GITHUB_CLIENT_IDGITHUB_CLIENT_SECRET — 只申請 read:user + user:email
  • 以 Worker Secret 方式存入 cypher-executor

2. 頁面結構

arcrun.dev/
├── /                    首頁(Hero + Code snippet + CTA
├── /login               登入頁(Google / GitHub 按鈕)
├── /auth/callback       OAuth callbackPages Function
├── /dashboard           API Key 管理(需登入)
├── /api                 Swagger UI(嵌入 swagger.json
└── /integrations        服務目錄(靜態,20 個 recipe)

3. 登入 / OAuth 流程

3.1 流程圖

用戶點「Google 登入」
  → GET /auth/google/startWorker 端)
    → redirect 到 Google OAuthstate = random, 存 SESSIONS_KV sess:state:{state} = {provider, redirect_back}
  → 用戶同意
  → GET /auth/callback?code=...&state=...Worker 端)
    → 驗 state
    → 用 code 換 access_tokenPOST google token endpoint
    → 用 token 取 userinfoGET google userinfo
    → upsert USERS_KV user:{provider}:{provider_id} = {email, display_name, api_key, ...}
    → 若新用戶:呼叫現有 /register?email=... 取得 arcrun API Key
    → 建立 sessionSESSIONS_KV sess:{session_id} = {api_key, email, ...}TTL=7d
    → Set-Cookie: arcrun_session={session_id}; HttpOnly; Secure; SameSite=Lax
    → redirect 到 /dashboard

3.2 「若新用戶取得 API Key」的邏輯

現有 /register endpoint 接受 email 回傳 api_keyHMAC 確定性)。 但 landing page 需要的是真正綁定到用戶帳號的 key,且用戶可以 rotate/revoke。

方案:延伸現有 register endpoint

/register 目前:HMAC(secret, email) → 確定性 api_key,存 CREDENTIALS_KV

新增邏輯:

  1. 若 USERS_KV 已有此 user → 直接用記錄裡的 api_key
  2. 若新 user → 呼叫現有 /register(保持 HMAC 確定性邏輯)→ 拿到 api_key → 存入 USERS_KV

好處:不破壞現有 register 邏輯;登入後的 dashboard 顯示的 key = 現有 key = 封測用的 key。

3.3 Rotate / Revoke

  • Rotate:產生新 UUID v4 key → 更新 USERS_KV 記錄 → 舊 key 失效(透過把新 key 加到 CREDENTIALS_KV,舊 key 的資料都跟著 API Key 命名空間走,所以 credentials 會留在舊 namespace
    • 簡化版:Rotate 後顯示提示「您的 workflow credentials 已和舊 Key 分離,請重新設定」
  • RevokeUSERS_KV 記錄 revoked: true → Worker middleware 拒絕此 key

4. API 端點(新增到 cypher-executor

GET  /auth/google/start                   → redirect 到 Google OAuth
GET  /auth/github/start                   → redirect 到 GitHub OAuth
GET  /auth/callback?code=&state=          → 換 token、建立 session
POST /auth/logout                         → 清 session cookie
GET  /me                                  → 回傳當前登入用戶資訊(需 session cookie 或 API Key
PUT  /me/api-key/rotate                   → 產生新 key
DELETE /me/api-key                        → Revoke(標記撤銷)

5. 前端頁面設計

5.1 首頁(/

Hero:
  Stop fighting OAuth.
  One API key. Every service. Works anywhere.

  [Get API Key — Free]    [View on GitHub]

Before/After:
  40 行 OAuth 程式碼  →  auth.bind("google_drive")

Code Demo(三個 tab):
  Python / JavaScript / HTTPn8n 用戶)

[Get Free API Key] 按鈕

5.2 登入頁(/login

arcrun

登入或建立帳號

[Continue with Google]
[Continue with GitHub]

不需要信用卡。API Key 立即可用。

5.3 Dashboard/dashboard

歡迎,{display_name}

您的 API Key
┌────────────────────────────────┐
│ ak_xxxxxxxxxxxxxxxxxxxx  [複製] │
└────────────────────────────────┘

[Rotate Key]  [Revoke Key]

使用說明:
  Authorization: Bearer {key}
  或 X-Arcrun-API-Key: {key}

[登出]

5.4 Swagger UI/api

  • 嵌入 <SwaggerUIBundle> JSCDN
  • url: 'https://cypher.arcrun.dev/swagger.json'(現有 Worker 已有 /docs openapi endpoint
  • 頂部說明:「這是 arcrun 的原始 API。Python / JS lib 是它的包裝,任何能發 HTTP request 的工具都能直接用。」

5.5 服務目錄(/integrations

  • 靜態列出 20 個 auth recipe(從 seed data 產生)
  • 每個 recipe:名稱、認證方式(static_key / service_account)、所需 credentials
  • 「找不到你要的服務?開 PR 貢獻 Recipe」CTA

6. 檔案結構

arcrun/landing/                         ← 新 Next.js 專案
├── app/
│   ├── layout.tsx
│   ├── page.tsx                        首頁
│   ├── login/
│   │   └── page.tsx
│   ├── dashboard/
│   │   ├── page.tsx
│   │   └── middleware.ts              (或 root middleware
│   ├── api-docs/
│   │   └── page.tsx                   Swagger UI
│   └── integrations/
│       └── page.tsx
├── middleware.ts                       保護 /dashboard(讀 cookie
├── lib/
│   └── auth.ts                        session helpers
├── public/
├── next.config.ts
├── package.json
└── wrangler.toml                      CF Pages 設定

cypher-executor 新增:

arcrun/cypher-executor/src/routes/
├── auth.ts                            ← 新增(OAuth start/callback/logout/me

cypher-executor wrangler.toml 新增:

[[kv_namespaces]]
binding = "USERS_KV"
id = "<to be created>"

[[kv_namespaces]]
binding = "SESSIONS_KV"
id = "455d0505c7534883a4d4985ab8295857"

7. 環境變數 / Secrets

cypher-executorWorker Secrets

GOOGLE_CLIENT_ID          Google OAuth App client_id(僅 openid profile email scope
GOOGLE_CLIENT_SECRET      Google OAuth App client_secret
GITHUB_CLIENT_ID          GitHub OAuth App client_idread:user + user:email scope
GITHUB_CLIENT_SECRET      GitHub OAuth App client_secret
SESSION_SECRET            隨機 32 bytes,用於 HMAC session ID(或直接用 UUID

landingPages Environment Variables

NEXT_PUBLIC_API_BASE      https://cypher.arcrun.dev

8. 實作步驟(Checklist

Phase 1cypher-executor 後端擴充

  • wrangler kv:namespace create USERS_KV → 填入 wrangler.toml (id: 25bef01d079148919578894434d58c4d)
  • wrangler kv:namespace create SESSIONS_KV → 填入 wrangler.toml (id: 455d0505c7534883a4d4985ab8295857)
  • 建立 arcrun/cypher-executor/src/routes/auth.ts
    • GET /auth/google/start
    • GET /auth/github/start
    • GET /auth/callback(換 token → userinfo → upsert USERS_KV → 建 session → Set-Cookie → redirect
    • POST /auth/logout
    • GET /me(讀 session cookie 或 API Key header
    • PUT /me/api-key/rotate
    • DELETE /me/api-keyrevoke
  • src/index.ts 掛載 authRouter
  • wrangler secret put GOOGLE_CLIENT_ID 等 4 個 secrets ← 用戶需自建 Google/GitHub OAuth App
  • wrangler deploy ← 已部署(Worker version 7877857b

Phase 2Next.js Landing 專案

  • npx create-next-app@latest arcrun/landing --typescript --tailwind --app
  • 設定 @cloudflare/next-on-pagesNext.js 15 + .npmrc legacy-peer-deps
  • 建立 middleware.ts(保護 /dashboard,讀 arcrun_session cookie)← 待做
  • 首頁(app/page.tsx):Hero + Code Demo tab + CTA
  • 登入頁(app/login/page.tsx):Google / GitHub 按鈕(href 到 cypher.arcrun.dev/auth/google/start
  • Dashboardapp/dashboard/page.tsx):顯示 API KeyRotate / Revoke 按鈕
  • Swagger UIapp/api-docs/page.tsx):client component,動態 import swagger-ui CDN
  • 服務目錄(app/integrations/page.tsx):靜態,列 20 個 recipe
  • 中英切換 ← 低優先,可延後
  • wrangler pages deployhttps://42a8d302.arcrun-landing.pages.dev
  • Cloudflare dashboard 設定 arcrun.dev custom domain → arcrun-landing Pages project

Phase 3:驗收(待 OAuth Secrets 填入後)

  • Google / GitHub OAuth 完整流程(登入 → dashboard → 看到 key
  • Rotate:新 key 出現
  • Revoke:舊 key 的 API 呼叫回傳 401
  • Swagger UI 正常載入,可試打 /health
  • /integrations 正確列出 20 個服務

9. 待決事項(開始實作前確認)

問題 預設決策
Google OAuth App 是否要另建(只有 email scope? 是,另建;auth recipe 的 App 不動
Rotate 後舊 credentials 是否遷移? 不遷移,顯示提示
Domain arcrun.dev 是否已購入且在 Cloudflare 假設是(wrangler.toml 有設 zone_name
登入後 redirect 預設到 /dashboard 是,可從 ?redirect= 覆寫