iW
iWish 工具平台接入标准化规范
*.iwishapp.cn · Cloudflare + Supabase

iWish 工具平台接入标准化规范

平台一句话架构:Cloudflare Pages/Functions 托管前端与轻后端 + Supabase 做数据与登录 + 各工具以独立项目挂到 *.iwishapp.cn(首选子域名 你的工具.iwishapp.cn,或子路径 tools.iwishapp.cn/你的工具)。
面向:要把工具接入平台的同事 维护:陈俊宇(规范)· 台林(Supabase/账号) 吸收现网:feed-workbench · iwish-onboarding 更新:2026-06-25
ℹ︎
本页是 Markdown 源《iWish 工具平台接入标准化规范.md》的在线版,可直接挂到平台当对接指南。看到 <向台林索取> 就是占位,必须替换成真实值(见第 9 章)。

1平台架构总览

用户访问 你的工具.iwishapp.cn(或 tools.iwishapp.cn/你的工具)→ Cloudflare 边缘提供静态 UI(public/)与轻后端(functions/)→ 后端读写台林维护的 Supabase(数据 + 统一登录)。

用户浏览器
   │  https://你的工具.iwishapp.cn/   (或 tools.iwishapp.cn/你的工具/)
   ▼
Cloudflare(CDN + 边缘)
   ├─ Pages 静态资源  public/      ← 你的 UI
   └─ Pages Functions functions/   ← 轻后端 / 调第三方 API / 校验登录
        │
        ▼
Supabase(台林 · oddfmupuuokyfxzcidvl)
   ├─ Auth      统一登录(微信/Google)
   └─ Postgres  数据 + RLS + 角色/组织

职责边界

你(工具作者)负责平台 / 台林负责
UI、交互、业务逻辑Cloudflare 账号与 Pages 接入审批
改造成 Pages 结构(public/+functions/*.iwishapp.cn 域名与子域名/子路径路由
套用统一设计令牌与外壳布局Supabase 项目、Auth、登录 provider
在 Supabase 建自己的表 + 开 RLS组织/角色/权限主数据表
wrangler pages secret 配自己的密钥平台级密钥与基础设施可用性

2接入前置 Checklist

3第一步:改造成 Pages 结构 + 三种挂载

你的工具/
├── public/          # 构建产物 / 静态资源(Pages 部署根目录)
├── functions/       # (可选)Pages Functions = 边缘轻后端
│   └── api/xxx.js   # 自动映射到 /api/xxx
├── wrangler.toml
├── package.json
└── README.md

3.1 wrangler.toml 模板

name = "yourtool"                  # 全小写短横线
compatibility_date = "2024-01-01"
pages_build_output_dir = "public"  # 构建产物目录

[vars]
# 只放非敏感公开变量;密钥一律走 wrangler pages secret
SUPABASE_URL = "https://oddfmupuuokyfxzcidvl.supabase.co"
这是平台现有工具 ai-promotion-generator / dtc-promo-cloudflare 的真实写法,照抄即可。

3.2 三种挂载形态与 base(配错会白屏,先和管理员定)

形态地址base 配置
① 子域名独立项目
首选
你的工具.iwishapp.cnVite base:'/'(默认);纯静态零配置
② 子路径独立项目tools.iwishapp.cn/你的工具/Vite 必须 base:'/你的工具/',否则 /assets/* 404
③ 并入主 SPA
(现网 feed-workbench)
tools.iwishapp.cn/你的工具 客户端路由资源走根 /assets/base:'/';API 用 /api/你的工具/*
// 形态② vite.config.ts
export default defineConfig({
  base: '/你的工具/',     // 子路径独立项目必须;子域名 / 并入主 SPA 用 '/'
  build: { outDir: 'public' },
})
⚠︎
挂载方式 → 第 9 章向平台管理员确认。形态② base 配错会整页白屏。纯静态单 HTML 工具走形态①零配置(现网 iwish-onboarding 即此)。

4第二步:轻后端用 Pages Functions

functions/api/hello.js → 自动暴露为 /api/hello。除 onRequest,也可 onRequestGet / onRequestPost 分方法导出。

export async function onRequest({ request, env }) {
  const cors = {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'POST, OPTIONS',
    'Access-Control-Allow-Headers': 'Content-Type, Authorization',
  };
  if (request.method === 'OPTIONS')
    return new Response(null, { headers: { ...cors, 'Access-Control-Max-Age': '86400' } });
  if (request.method !== 'POST') return json({ error: 'Method not allowed' }, 405, cors);

  try {
    const body = await request.json();
    const API_KEY = env.SOME_API_KEY;          // 密钥从 env 取,不硬编码
    if (!API_KEY) return json({ error: 'SOME_API_KEY not configured' }, 500, cors);
    // ...调第三方 API / 处理业务...
    return json({ ok: true }, 200, cors);
  } catch (e) { return json({ error: String(e) }, 500, cors); }
}
function json(obj, status, cors) {
  return new Response(JSON.stringify(obj),
    { status, headers: { 'Content-Type': 'application/json', ...cors } });
}
密钥红线:npx wrangler pages secret put SOME_API_KEY --project-name yourtool 注入,只存在 Cloudflare。绝不写进 wrangler.toml、前端代码或 git。前端只能拿"公开 key"(如 Supabase anon key)。

5第三步:数据接 Supabase

Project Refoddfmupuuokyfxzcidvl(组织 Iwish System Pro)
Project URLhttps://oddfmupuuokyfxzcidvl.supabase.co
anon public key<向台林索取>(公开 key,可放前端)
service_role key<向台林索取> 仅 Functions,绝不进前端

5.1 前端初始化

import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
const supabase = createClient(
  'https://oddfmupuuokyfxzcidvl.supabase.co',
  '<向台林索取:anon key>'
);

5.2 建表命名约定(多工具共用一库)

5.3 RLS 是安全红线(必须开)

alter table yourtool_records enable row level security;
create policy "owner can read"  on yourtool_records
  for select using (auth.uid() = user_id);
create policy "owner can write" on yourtool_records
  for insert with check (auth.uid() = user_id);
没开 RLS 的表不允许上线。不确定 policy 怎么写,先设成"仅登录用户可访问",再找台林 review。

6第四步:统一登录对接(Supabase Auth)

统一用 Supabase Auth(台林账号系统)登录,方式为微信/Google。你的工具不自建登录、不存密码,只对接。

⚠︎
截至本规范,台林的微信/Google provider 仍在联调推进中。上线前向台林确认当前实际可用的登录方式

6.1 前端发起登录 / 拿会话

await supabase.auth.signInWithOAuth({
  provider: 'google',
  options: { redirectTo: 'https://你的工具.iwishapp.cn/' },  // 子路径填到对应路径
});
const { data: { user } } = await supabase.auth.getUser();
if (!user) location.href = '/login.html';   // 未登录 → 登录页

6.2 Functions 里服务端校验 token

const token = (request.headers.get('Authorization') || '').replace('Bearer ', '');
const res = await fetch('https://oddfmupuuokyfxzcidvl.supabase.co/auth/v1/user', {
  headers: { Authorization: `Bearer ${token}`, apikey: env.SUPABASE_ANON_KEY },
});
if (!res.ok) return new Response('Unauthorized', { status: 401 });
const user = await res.json();   // user.id / email → 继续业务

6.3 角色 / 组织(RBAC)

拿到 user.id 后,从台林维护的组织/角色表读角色、部门、权限点,据此控制菜单和按钮。具体表名第 9 章向台林确认;工具侧只做"按权限显示/隐藏"。

6.4 现网另一种实践(feed-workbench:Google OAuth via Functions)

ℹ︎
现网 feed-workbench 把 Google OAuth 放在 CF Functions 服务端:/api/auth/login → /api/auth/callback → /api/auth/session/<id>,前端不持有 client_secret,session 经 URL 回传后 history.replaceState 清掉。401 统一派发全局 app:auth-expired 事件一处重置登录态——这套 fetch 封装无论用哪种登录都值得抄。本规范标准仍是 Supabase Auth,二者择一,向台林确认平台口径。

7第五步:样式规范(统一设计令牌)★

目标:平台每个工具看起来都是"iWish 一家人"。下面这套令牌(取自 iwishweb.com 官网主题色)直接复制进 CSS,颜色/圆角/阴影/字体全用变量,不要自调一套蓝

7.1 调色板

主色·深海军蓝#00367C
亮蓝·强调#0067FF
蓝·加深#005EE9
浅蓝底#E7F6FF
页面底#F5F7FA
正文字#1E293B
成功#10B981
警告#F59E0B
危险#EF4444
信息#06B6D4

7.2 令牌 :root(直接粘贴)

:root{
  --logo-primary:#00367C; --logo-secondary:#0067FF; --logo-light:#E7F6FF; --logo-accent:#005EE9;
  --bg-primary:#F5F7FA; --bg-card:#FFFFFF; --bg-hover:#EDF1F7;
  --text-primary:#1E293B; --text-secondary:#64748B; --text-muted:#94A3B8;
  --border-color:#E2E8F0;
  --success:#10B981; --warning:#F59E0B; --danger:#EF4444; --info:#06B6D4;
  --shadow:0 1px 3px rgba(0,0,0,.08); --shadow-lg:0 10px 25px rgba(0,54,124,.12);
  --radius:12px; --radius-sm:8px; --sidebar-width:248px;
}
body{font-family:'Noto Sans SC',-apple-system,sans-serif;
  background:var(--bg-primary);color:var(--text-primary);line-height:1.6}

7.3 字体

<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;600;700&display=swap" rel="stylesheet">

7.4 平台外壳 + 组件规范

本页就是范例:顶栏品牌渐变(64px)+ 侧栏导航(248px)+ 主内容卡片。带后台的工具统一用这套骨架;单页工具可省侧栏,但顶栏渐变与配色要一致。

组件规范
卡片bg-card + 1px border-color + radius:12px + shadow
主按钮背景 logo-primary,文字白,radius-sm,hover 抬阴影
次按钮白底 + 1px border-color,文字 text-secondary
状态徽章成功绿 警告 危险 信息
表单输入框 focus 边框转 logo-primary;label 用 text-secondary
空/加载态必须有:空数据给引导,加载给 skeleton/spinner,别白屏

五态徽章系统(借鉴现网 iwish-onboarding,凡"接入项/配置项/任务"状态统一用这套):

完成未完成/失败待处理警告重要

.badge{display:inline-block;padding:2px 9px;border-radius:11px;font-size:12px;font-weight:600}
.b-done{background:#E3F7E9;color:#2E9E51}  /* 完成 */
.b-no  {background:#FDE9EF;color:#C83E6B}  /* 未完成 / 失败 */
.b-todo{background:#EEF1F6;color:#8A93A6}  /* 待处理 */
.b-warn{background:#FFF3DF;color:#D9912A}  /* 警告 */
.b-imp {background:#E7F0FF;color:#2F6BD8}  /* 重要 */

7.5 Tailwind / Vue 项目令牌映射

theme:{ extend:{ colors:{
  brand:{ primary:'#00367C', secondary:'#0067FF', light:'#E7F6FF', accent:'#005EE9' },
  bg:{ app:'#F5F7FA', card:'#FFFFFF', hover:'#EDF1F7' },
  ink:{1:'#1E293B',2:'#64748B',3:'#94A3B8'}, line:'#E2E8F0',
  ok:'#10B981', warn:'#F59E0B', danger:'#EF4444', info:'#06B6D4',
}, borderRadius:{ DEFAULT:'12px', sm:'8px' } }}

7.6 响应式 + 文案

⚠︎
画面文案硬规:UI 不要出现 执行/生成/校验/Ingest/Query/Lint/Step 这类内部流程词当标题/按钮/标签,要展示就改写成业务语言(如"生成"→"创建报告")。

8第六步:部署上线(挂到 *.iwishapp.cn)

  1. 代码进 git,.gitignore 排除 .env / 密钥 / node_modules
  2. 创建 Cloudflare Pages 项目,连 GitHub;构建命令纯静态站留空、Vite 填 npm run build;输出目录 public(或 dist)。
  3. 配密钥:npx wrangler pages secret put XXX --project-name yourtool
  4. 配路由:子域名(你的工具.iwishapp.cn 加自定义域)或子路径由平台管理员在 Cloudflare 侧配规则——通常不是你自己点。
  5. 用 push 产生的预览 URL(<项目>.pages.dev)验完再切正式。
  6. 打开 你的工具.iwishapp.cn,走一遍 登录 → 核心功能 → 数据读写。

9信息确认清单(向台林 / 平台管理员索取)

要的东西找谁用在哪
Supabase anon public key台林前端初始化
service_role key(如需服务端写库)台林仅 Functions
当前已开通的登录方式台林第 6 章登录
读角色/组织的表名与字段台林第 6.3 RBAC
表名前缀 / 是否独立 schema台林第 5.2 建表
挂载方式:子域名 / 子路径 / 并入主 SPA平台管理员base + 路由(见 3.2)
Pages 项目创建/部署权限平台管理员第 8 章部署

10上线前验收清单

11红线汇总(别踩)

  1. 密钥不进前端、不进 git、不进 wrangler.toml —— 只走 secret / env。
  2. Supabase 表必须开 RLS —— 没开等于裸奔。
  3. 不自建用户体系 —— 统一 Supabase Auth,不存密码。
  4. 不动别人的表 / 不擅改共享 schema —— 改结构先同步台林。
  5. 挂载 base 配对 —— 子路径独立项目改 vite base,子域名/并入主 SPA 用 /
  6. UI 不暴露内部流程词 —— 给用户看的是业务语言。

12参考现网项目(可借鉴的真实模式)

12.1 feed-workbench(tools.iwishapp.cn/feed-workbench)— SPA 子路径 + 服务端鉴权

12.2 iwish-onboarding(iwish-onboarding.pages.dev)— 单 HTML + 声明式配置矩阵

12.3 通用可借鉴清单

onRequestGet / onRequestPost 分方法导出 wrangler 加 D1 / KV / Workflows 绑定 Cloudflare Access 作第二条鉴权路(前端零 token) Next.js 用 @supabase/ssr(createBrowserClient + middleware 守卫) 版本锁 supabase-js@2.45.0 + ssr@0.5.0

完整文字版(含最小可运行模板目录树、相关资料链接)见 Markdown 源《iWish 工具平台接入标准化规范.md》。