好的!我理解了,你需要: 1. **前端**:现代化框架(React/Vue) 2. **后端**:独立的轻量后端(不用 Next.js API Routes) 3. **部署**:都要简单方便 让我重新设计一个最佳方案!🎯 **最终推荐架构** * * * ### **技术选型** 前端 (SPA): - Framework: Vite + React 18 + TypeScript - UI: Tailwind CSS + shadcn/ui - State: Zustand + TanStack Query - Charts: Recharts + D3.js - 部署: Cloudflare Pages / Vercel (静态托管) 后端 (API): - Framework: Fastify + TypeScript (比Express快2倍) - GitHub SDK: Octokit - Database: PostgreSQL (Supabase免费托管) - Cache: Upstash Redis (Serverless) - 部署: Railway.app ⭐ (一键部署,免费额度够用) 认证: - GitHub OAuth 2.0 - JWT Token 实时通信: - Server-Sent Events (SSE) - 比WebSocket简单 - 或 Pusher (免费版) * * * 🏗️ **系统架构图** ┌─────────────────────────────────────────────────────────────┐ │ 用户浏览器 │ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ React SPA (Vite) │ │ │ │ │ │ │ │ ┌──────────┐ ┌───────────┐ ┌──────────────┐ │ │ │ │ │Dashboard │ │Repository │ │Analytics │ │ │ │ │ │ Page │ │Detail Page│ │ Page │ │ │ │ │ └────┬─────┘ └─────┬─────┘ └──────┬───────┘ │ │ │ │ │ │ │ │ │ │ │ └──────────────┴────────────────┘ │ │ │ │ │ │ │ │ │ ┌─────────▼──────────┐ │ │ │ │ │ TanStack Query │ (数据获取层) │ │ │ │ │ + Axios/Fetch │ │ │ │ │ └─────────┬──────────┘ │ │ │ └──────────────────────┼───────────────────────────────┘ │ └─────────────────────────┼──────────────────────────────────┘ │ HTTPS (REST API) │ ┌─────────────────────────▼──────────────────────────────────┐ │ 后端服务器 (Railway) │ │ │ │ ┌────────────────────────────────────────────────────┐ │ │ │ Fastify API Server (Node.js) │ │ │ │ │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ │ │ │ │ Auth │ │ Repos │ │ Webhooks │ │ │ │ │ │ /login │ │ /repos/* │ │ /webhooks/* │ │ │ │ │ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │ │ │ │ │ │ │ │ │ │ │ └─────────────┴────────────────┘ │ │ │ │ │ │ │ │ │ ┌──────────▼──────────┐ │ │ │ │ │ Service Layer │ │ │ │ │ │ • GitHubService │ │ │ │ │ │ • CacheService │ │ │ │ │ │ • WebhookService │ │ │ │ │ └──────────┬──────────┘ │ │ │ └─────────────────────┼────────────────────────────────┘ │ │ │ │ │ ┌──────────────┼──────────────┐ │ │ │ │ │ │ │ ┌────▼─────┐ ┌────▼────┐ ┌──────▼──────┐ │ │ │ Octokit │ │ Prisma │ │ Redis Cache │ │ │ │ GitHub │ │ ORM │ │ (Upstash) │ │ │ │ API │ └────┬────┘ └─────────────┘ │ │ └──────────┘ │ │ └───────────────────────┼─────────────────────────────────────┘ │ ┌──────▼──────┐ │ PostgreSQL │ │ (Supabase) │ └─────────────┘ ┌────────────────────────────────────────────┐ │ 外部服务 │ │ │ │ ┌──────────────┐ ┌──────────────────┐ │ │ │ GitHub API │ │ GitHub Webhooks │ │ │ │ (公开接口) │ │ (实时事件推送) │ │ │ └──────────────┘ └──────────────────┘ │ └────────────────────────────────────────────┘ * * * 📂 **项目结构** github-dashboard/ ├── frontend/ # 前端项目 (Vite) │ ├── src/ │ │ ├── components/ │ │ │ ├── dashboard/ │ │ │ │ ├── StatsCard.tsx │ │ │ │ ├── ActivityChart.tsx │ │ │ │ └── RepoList.tsx │ │ │ ├── charts/ │ │ │ └── ui/ # shadcn/ui 组件 │ │ ├── pages/ │ │ │ ├── Dashboard.tsx │ │ │ ├── RepoDetail.tsx │ │ │ └── Analytics.tsx │ │ ├── hooks/ │ │ │ ├── useRepos.ts │ │ │ └── useRepoStats.ts │ │ ├── lib/ │ │ │ ├── api.ts # API 请求封装 │ │ │ └── auth.ts # 认证逻辑 │ │ ├── stores/ │ │ │ └── authStore.ts # Zustand store │ │ ├── App.tsx │ │ └── main.tsx │ ├── package.json │ ├── vite.config.ts │ └── tailwind.config.js │ ├── backend/ # 后端项目 (Fastify) │ ├── src/ │ │ ├── routes/ │ │ │ ├── auth.ts # POST /auth/login │ │ │ ├── repos.ts # GET /repos, /repos/:id │ │ │ ├── webhooks.ts # POST /webhooks/github │ │ │ └── stats.ts # GET /stats/* │ │ ├── services/ │ │ │ ├── github.service.ts │ │ │ ├── cache.service.ts │ │ │ └── webhook.service.ts │ │ ├── middlewares/ │ │ │ ├── auth.middleware.ts │ │ │ └── error.middleware.ts │ │ ├── prisma/ │ │ │ └── schema.prisma │ │ ├── types/ │ │ │ └── index.ts │ │ ├── utils/ │ │ │ └── logger.ts │ │ ├── app.ts # Fastify 实例 │ │ └── server.ts # 启动文件 │ ├── package.json │ ├── tsconfig.json │ └── .env.example │ └── README.md * * * 🚀 **部署方案** ### **前端部署:Cloudflare Pages** ⭐ # 1. 构建 cd frontend npm run build # 2. Cloudflare Pages 自动部署 # - 连接 GitHub 仓库 # - 构建命令: npm run build # - 输出目录: dist # - 自动部署: 推送到 main 分支即触发 **优势:** * ✅ 完全免费 * ✅ 全球 CDN(超快) * ✅ 自动 HTTPS * ✅ 无限带宽 * ✅ 支持自定义域名 * * * ### **后端部署:Railway.app** ⭐⭐⭐ # 1. 安装 Railway CLI npm install -g @railway/cli # 2. 登录 railway login # 3. 初始化项目 cd backend railway init # 4. 部署 railway up # 5. 添加数据库 railway add postgresql # 6. 设置环境变量 railway variables set GITHUB_CLIENT_ID=xxx railway variables set GITHUB_CLIENT_SECRET=xxx **Railway 配置文件 (`railway.json`)**: { "$schema": "https://railway.app/railway.schema.json", "build": { "builder": "NIXPACKS" }, "deploy": { "startCommand": "npm run start", "restartPolicyType": "ON_FAILURE", "restartPolicyMaxRetries": 10 } } **优势:** * ✅ 免费额度:$5/月(足够小项目) * ✅ 一键部署,零配置 * ✅ 自动 HTTPS * ✅ 内置 PostgreSQL * ✅ 环境变量管理 * ✅ 自动 Git 同步部署 * * * ### **替代方案对比** | 平台 | 免费额度 | 部署难度 | 启动速度 | 推荐度 | | --- | --- | --- | --- | --- | | **Railway** | $5/月 | ⭐⭐⭐⭐⭐ | 快 | ⭐⭐⭐⭐⭐ | | Render | 750h/月 | ⭐⭐⭐⭐ | 慢(冷启动) | ⭐⭐⭐⭐ | | Fly.io | 3个免费实例 | ⭐⭐⭐ | 快 | ⭐⭐⭐⭐ | | Heroku | 无免费版 | ⭐⭐⭐⭐ | 中等 | ⭐⭐ | * * * 💻 **核心代码示例** ### **后端 - Fastify 入口 (`backend/src/app.ts`)** import Fastify from 'fastify'; import cors from '@fastify/cors'; import jwt from '@fastify/jwt'; import { authRoutes } from './routes/auth'; import { repoRoutes } from './routes/repos'; import { webhookRoutes } from './routes/webhooks'; export function createApp() { const app = Fastify({ logger: true, }); // 插件 app.register(cors, { origin: process.env.FRONTEND_URL || 'http://localhost:5173', credentials: true, }); app.register(jwt, { secret: process.env.JWT_SECRET!, }); // 路由 app.register(authRoutes, { prefix: '/api/auth' }); app.register(repoRoutes, { prefix: '/api/repos' }); app.register(webhookRoutes, { prefix: '/api/webhooks' }); // 健康检查 app.get('/health', async () => { return { status: 'ok', timestamp: new Date().toISOString() }; }); return app; } ### **后端 - GitHub Service (`backend/src/services/github.service.ts`)** import { Octokit } from '@octokit/rest'; import { Redis } from '@upstash/redis'; const redis = new Redis({ url: process.env.UPSTASH_REDIS_URL!, token: process.env.UPSTASH_REDIS_TOKEN!, }); export class GitHubService { private octokit: Octokit; constructor(accessToken: string) { this.octokit = new Octokit({ auth: accessToken }); } async getRepositories() { const cacheKey = 'repos:list'; // 尝试从缓存读取 const cached = await redis.get(cacheKey); if (cached) return cached; // 从 GitHub API 获取 const { data } = await this.octokit.repos.listForAuthenticatedUser({ sort: 'updated', per_page: 100, }); // 缓存5分钟 await redis.set(cacheKey, data, { ex: 300 }); return data; } async getRepositoryStats(owner: string, repo: string) { const cacheKey = `repo:${owner}/${repo}:stats`; const cached = await redis.get(cacheKey); if (cached) return cached; const [repoData, issues, pulls, commits] = await Promise.all([ this.octokit.repos.get({ owner, repo }), this.octokit.issues.listForRepo({ owner, repo, state: 'open' }), this.octokit.pulls.list({ owner, repo, state: 'open' }), this.octokit.repos.listCommits({ owner, repo, per_page: 100, since: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString() }), ]); const stats = { name: repoData.data.name, stars: repoData.data.stargazers_count, forks: repoData.data.forks_count, openIssues: issues.data.length, openPRs: pulls.data.length, commitsLastMonth: commits.data.length, language: repoData.data.language, updatedAt: repoData.data.updated_at, }; await redis.set(cacheKey, stats, { ex: 300 }); return stats; } } ### **前端 - API 客户端 (`frontend/src/lib/api.ts`)** import axios from 'axios'; const api = axios.create({ baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3000/api', timeout: 10000, }); // 请求拦截器:添加 token api.interceptors.request.use((config) => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); // 响应拦截器:处理错误 api.interceptors.response.use( (response) => response, (error) => { if (error.response?.status === 401) { localStorage.removeItem('token'); window.location.href = '/login'; } return Promise.reject(error); } ); export default api; ### **前端 - 数据获取 Hook (`frontend/src/hooks/useRepos.ts`)** import { useQuery } from '@tanstack/react-query'; import api from '@/lib/api'; interface Repository { id: number; name: string; full_name: string; description: string; stargazers_count: number; open_issues_count: number; language: string; } export function useRepositories() { return useQuery({ queryKey: ['repositories'], queryFn: async () => { const { data } = await api.get('/repos'); return data; }, staleTime: 5 * 60 * 1000, // 5分钟 refetchOnWindowFocus: false, }); } export function useRepositoryStats(owner: string, repo: string) { return useQuery({ queryKey: ['repo-stats', owner, repo], queryFn: async () => { const { data } = await api.get(`/repos/${owner}/${repo}/stats`); return data; }, enabled: !!owner && !!repo, staleTime: 5 * 60 * 1000, }); } * * * 🔐 **认证流程** ┌────────┐ ┌──────────┐ ┌─────────┐ │ 前端 │ │ 后端 │ │ GitHub │ └───┬────┘ └────┬─────┘ └────┬────┘ │ │ │ │ 1. 点击 "Login with GitHub" │ │ ├──────────────────────────>│ │ │ │ │ │ 2. 重定向到 GitHub OAuth │ │ ├───────────────────────────┼─────────────────────────>│ │ │ │ │ 3. 用户授权 │ │ │ │<──────────────────────────┤ │ │ │ │ 4. GitHub 回调 + code │ │ │<───────────────────────────┤ │ │ │ │ │ 5. 发送 code 到后端 │ │ ├──────────────────────────>│ │ │ │ │ │ │ 6. 用 code 换 access_token│ │ ├─────────────────────────>│ │ │ │ │ │<──────────────────────────┤ │ │ │ │ 7. 返回 JWT token │ │ │<───────────────────────────┤ │ │ │ │ │ 8. 保存 token 到 localStorage │ │ │ │ * * * 📊 **数据流** 前端 Dashboard 页面加载: 1. 检查 localStorage 是否有 token ├─ 无 → 跳转登录页 └─ 有 → 继续 2. 发起并行请求(TanStack Query): ├─ GET /api/repos (获取仓库列表) ├─ GET /api/stats/overview (总体统计) └─ GET /api/stats/activity (活动数据) 3. 后端处理: ├─ 验证 JWT token ├─ 检查 Redis 缓存 │ ├─ 命中 → 直接返回 │ └─ 未命中 → 调用 GitHub API + 写入缓存 └─ 返回数据 4. 前端渲染: ├─ TanStack Query 自动管理加载/错误状态 ├─ 渲染图表(Recharts) └─ 显示数据卡片 * * * 🎯 **开发步骤** ### **1. 初始化项目** # 创建项目目录 mkdir github-dashboard cd github-dashboard # 初始化前端 npm create vite@latest frontend -- --template react-ts cd frontend npm install npm install @tanstack/react-query axios zustand npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p # 初始化后端 cd .. mkdir backend && cd backend npm init -y npm install fastify @fastify/cors @fastify/jwt npm install @octokit/rest @upstash/redis @prisma/client npm install -D typescript @types/node tsx prisma npx prisma init ### **2. 配置 Railway 部署** cd backend # 创建 railway.json cat > railway.json << EOF { "build": { "builder": "NIXPACKS" }, "deploy": { "startCommand": "npm run start" } } EOF # 部署 railway login railway init railway up ### **3. 配置 Cloudflare Pages** cd frontend # 构建测试 npm run build # 在 Cloudflare Pages Dashboard: # 1. 连接 GitHub 仓库 # 2. 设置构建命令: npm run build # 3. 设置输出目录: dist # 4. 添加环境变量: VITE_API_URL=你的Railway后端URL * * * 🎉 **总结** 这个架构的优势: ✅ **前后端分离** - 各自独立部署和扩展✅ **轻量高效** - Fastify 性能优秀,Vite 开发体验好✅ **部署简单** - Railway + Cloudflare Pages 都是一键部署✅ **成本低廉** - 免费额度足够个人/小团队使用✅ **可扩展性** - 需要时可轻松升级到付费版✅ **现代化** - TypeScript 全栈,类型安全 需要我提供: 1. ✅ 完整的项目初始化脚本? 2. ✅ Prisma Schema 数据库设计? 3. ✅ 前端 Dashboard 组件代码? 4. ✅ 详细的部署文档? 选择任意方向深入!🚀