重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
admin-dashboard by erichowens/some_claude_skills
npx skills add https://github.com/erichowens/some_claude_skills --skill admin-dashboard此技能帮助您扩展管理仪表盘,并按照既定模式构建内部工具。
/admin - 管理仪表盘(用户指标、访问控制、审计)
/dev - 开发者门户(文档、代码浏览器、功能地图)[计划中]
/ops - 运维控制台(基础设施、日志、事件)[计划中]
完整设计规范请参见 docs/ADMIN-DEVELOPER-SUITE.md。
位置:src/app/admin/page.tsx
| 标签页 | 用途 | 数据源 |
|---|---|---|
| 概览 | 快速统计数据(用户、签到、消息) | /api/admin/stats |
| 漏斗 | 用户参与度瀑布图 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
/api/admin/stats| 页面浏览量 | 按页面路径的分析 | /api/admin/stats |
| 用户 | 包含活动的用户名单 | /api/admin/stats |
| 访问请求 | 待处理/已批准/已拒绝的请求 | /api/admin/access-requests |
| 允许的电子邮件 | 电子邮件白名单管理 | /api/admin/allowed-emails |
| 电子邮件模板 | 预览系统电子邮件 | 本地数据 |
| 标签页 | 用途 | 状态 |
|---|---|---|
| 生产健康状态 | API 延迟、核心 Web 指标 | 待处理 |
| 错误跟踪 | HIPAA 安全错误聚合 | 待处理 |
| 外部服务 | Anthropic、数据库、推送状态 | 待处理 |
| AI 分析 | 对话指标、令牌数 | 待处理 |
| 审计日志 | HIPAA 合规查看器 | 待处理 |
// 在 src/app/admin/page.tsx 中,添加一个新的标签页组件
function ProductionHealthTab() {
const [metrics, setMetrics] = useState<APIMetrics | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchMetrics() {
const res = await fetch('/api/admin/metrics');
const data = await res.json();
setMetrics(data);
setLoading(false);
}
fetchMetrics();
}, []);
if (loading) return <div>加载中...</div>;
return (
<div className="space-y-6">
<div className="grid grid-cols-4 gap-4">
<StatCard label="正常运行时间" value={metrics.uptime} />
<StatCard label="平均延迟" value={`${metrics.avgLatency}ms`} />
<StatCard label="错误数(24小时)" value={metrics.errorCount} />
<StatCard label="活跃用户" value={metrics.activeUsers} />
</div>
{/* 更多内容 */}
</div>
);
}
const tabs = [
{ id: 'overview', label: '概览' },
{ id: 'health', label: '生产健康状态' }, // 新增
{ id: 'funnel', label: '漏斗' },
// ...
];
function renderTabContent(tabId: string) {
switch (tabId) {
case 'overview':
return <OverviewTab stats={stats} />;
case 'health':
return <ProductionHealthTab />; // 新增
// ...
}
}
// src/app/api/admin/metrics/route.ts
import { requireAdmin } from '@/db/secure-db';
import { createRateLimiter } from '@/lib/rate-limit';
import { logAdminAction } from '@/lib/hipaa/audit';
const rateLimiter = createRateLimiter({
windowMs: 60000,
maxRequests: 60,
keyPrefix: 'admin:metrics'
});
export async function GET(request: Request) {
// 1. 检查管理员访问权限
const admin = await requireAdmin();
if (!admin) {
return Response.json({ error: '禁止访问' }, { status: 403 });
}
// 2. 应用速率限制
const rateLimitResult = await rateLimiter.check(admin.id);
if (!rateLimitResult.allowed) {
return Response.json(
{ error: '超过速率限制' },
{ status: 429, headers: rateLimitResult.headers }
);
}
// 3. 记录管理员操作
await logAdminAction(
admin.id,
AuditAction.ADMIN_STATS_VIEW,
'metrics',
null
);
// 4. 获取并返回数据
const metrics = await getAPIMetrics();
return Response.json(metrics);
}
function StatCard({
label,
value,
trend,
status
}: {
label: string;
value: string | number;
trend?: 'up' | 'down' | 'neutral';
status?: 'good' | 'warning' | 'error';
}) {
return (
<div className="rounded-lg border bg-card p-4">
<div className="text-sm text-muted-foreground">{label}</div>
<div className="text-2xl font-bold">{value}</div>
{trend && <TrendIndicator direction={trend} />}
{status && <StatusBadge status={status} />}
</div>
);
}
// 使用 SWR 或 React Query 进行实时更新
import useSWR from 'swr';
function useAdminMetrics() {
const { data, error, isLoading } = useSWR(
'/api/admin/metrics',
fetcher,
{ refreshInterval: 30000 } // 每 30 秒刷新一次
);
return { metrics: data, error, isLoading };
}
// 切勿显示用户特定的错误详情
function ErrorList({ errors }: { errors: AggregatedError[] }) {
return (
<div>
{errors.map(error => (
<div key={error.hash}>
<span className="font-mono">{error.type}</span>
<span>{error.path}</span>
<span>{error.count} 次出现</span>
<span>{error.affectedUsers} 用户</span>
{/* 不显示用户 ID,不显示包含 PHI 的错误消息 */}
</div>
))}
</div>
);
}
现有表:
adminUsers - 管理员角色分配allowedEmails - 电子邮件白名单accessRequests - 访问请求队列auditLog - HIPAA 审计追踪pageViews - 导航分析计划中的表(来自设计):
api_metrics - API 计时数据app_errors - 聚合错误service_health - 外部服务状态conversation_analytics - AI 聊天元数据incidents - 事件追踪// 始终对管理路由使用 requireAdmin()
import { requireAdmin } from '@/db/secure-db';
// 仅限超级管理员的功能
const admin = await requireAdmin();
if (admin.role !== 'super_admin') {
return Response.json({ error: '需要超级管理员权限' }, { status: 403 });
}
// 为测试模拟管理员身份验证
vi.mock('@/db/secure-db', () => ({
requireAdmin: vi.fn().mockResolvedValue({
id: 'test-admin',
role: 'admin'
})
}));
describe('管理指标端点', () => {
it('为已认证的管理员返回指标', async () => {
const response = await GET(mockRequest);
expect(response.status).toBe(200);
});
it('为非管理员返回 403', async () => {
vi.mocked(requireAdmin).mockResolvedValueOnce(null);
const response = await GET(mockRequest);
expect(response.status).toBe(403);
});
});
docs/ADMIN-DEVELOPER-SUITE.mdsrc/components/ui/ 中的现有组件每周安装次数
87
仓库
GitHub 星标数
73
首次出现
2026年1月24日
安全审计
安装于
gemini-cli69
codex67
cursor67
opencode66
claude-code65
github-copilot63
This skill helps you extend the admin dashboard and build internal tools following the established patterns.
/admin - Admin Dashboard (user metrics, access control, audit)
/dev - Developer Portal (docs, code browser, feature map) [PLANNED]
/ops - Operations Console (infrastructure, logs, incidents) [PLANNED]
See docs/ADMIN-DEVELOPER-SUITE.md for the full design specification.
Location: src/app/admin/page.tsx
| Tab | Purpose | Data Source |
|---|---|---|
| Overview | Quick stats (users, check-ins, messages) | /api/admin/stats |
| Funnel | User engagement waterfall | /api/admin/stats |
| Page Views | Analytics by page path | /api/admin/stats |
| Users | User roster with activity | /api/admin/stats |
| Access Requests | Pending/approved/denied requests | /api/admin/access-requests |
| Allowed Emails | Email whitelist management | /api/admin/allowed-emails |
| Email Templates | Preview system emails | Local data |
| Tab | Purpose | Status |
|---|---|---|
| Production Health | API latency, Core Web Vitals | Pending |
| Error Tracking | HIPAA-safe error aggregation | Pending |
| External Services | Anthropic, DB, Push status | Pending |
| AI Analytics | Conversation metrics, tokens | Pending |
| Audit Logs | HIPAA compliance viewer | Pending |
// In src/app/admin/page.tsx, add a new tab component
function ProductionHealthTab() {
const [metrics, setMetrics] = useState<APIMetrics | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchMetrics() {
const res = await fetch('/api/admin/metrics');
const data = await res.json();
setMetrics(data);
setLoading(false);
}
fetchMetrics();
}, []);
if (loading) return <div>Loading...</div>;
return (
<div className="space-y-6">
<div className="grid grid-cols-4 gap-4">
<StatCard label="Uptime" value={metrics.uptime} />
<StatCard label="Avg Latency" value={`${metrics.avgLatency}ms`} />
<StatCard label="Errors (24h)" value={metrics.errorCount} />
<StatCard label="Active Users" value={metrics.activeUsers} />
</div>
{/* More content */}
</div>
);
}
const tabs = [
{ id: 'overview', label: 'Overview' },
{ id: 'health', label: 'Production Health' }, // NEW
{ id: 'funnel', label: 'Funnel' },
// ...
];
function renderTabContent(tabId: string) {
switch (tabId) {
case 'overview':
return <OverviewTab stats={stats} />;
case 'health':
return <ProductionHealthTab />; // NEW
// ...
}
}
// src/app/api/admin/metrics/route.ts
import { requireAdmin } from '@/db/secure-db';
import { createRateLimiter } from '@/lib/rate-limit';
import { logAdminAction } from '@/lib/hipaa/audit';
const rateLimiter = createRateLimiter({
windowMs: 60000,
maxRequests: 60,
keyPrefix: 'admin:metrics'
});
export async function GET(request: Request) {
// 1. Check admin access
const admin = await requireAdmin();
if (!admin) {
return Response.json({ error: 'Forbidden' }, { status: 403 });
}
// 2. Apply rate limiting
const rateLimitResult = await rateLimiter.check(admin.id);
if (!rateLimitResult.allowed) {
return Response.json(
{ error: 'Rate limit exceeded' },
{ status: 429, headers: rateLimitResult.headers }
);
}
// 3. Log admin action
await logAdminAction(
admin.id,
AuditAction.ADMIN_STATS_VIEW,
'metrics',
null
);
// 4. Fetch and return data
const metrics = await getAPIMetrics();
return Response.json(metrics);
}
function StatCard({
label,
value,
trend,
status
}: {
label: string;
value: string | number;
trend?: 'up' | 'down' | 'neutral';
status?: 'good' | 'warning' | 'error';
}) {
return (
<div className="rounded-lg border bg-card p-4">
<div className="text-sm text-muted-foreground">{label}</div>
<div className="text-2xl font-bold">{value}</div>
{trend && <TrendIndicator direction={trend} />}
{status && <StatusBadge status={status} />}
</div>
);
}
// Use SWR or React Query for real-time updates
import useSWR from 'swr';
function useAdminMetrics() {
const { data, error, isLoading } = useSWR(
'/api/admin/metrics',
fetcher,
{ refreshInterval: 30000 } // Refresh every 30s
);
return { metrics: data, error, isLoading };
}
// Never show user-specific error details
function ErrorList({ errors }: { errors: AggregatedError[] }) {
return (
<div>
{errors.map(error => (
<div key={error.hash}>
<span className="font-mono">{error.type}</span>
<span>{error.path}</span>
<span>{error.count} occurrences</span>
<span>{error.affectedUsers} users</span>
{/* NO user IDs, NO error messages with PHI */}
</div>
))}
</div>
);
}
Existing tables:
adminUsers - Admin role assignmentsallowedEmails - Email whitelistaccessRequests - Access request queueauditLog - HIPAA audit trailpageViews - Navigation analyticsPlanned tables (from design):
api_metrics - API timing dataapp_errors - Aggregated errorsservice_health - External service statusconversation_analytics - AI chat metadataincidents - Incident tracking// Always use requireAdmin() for admin routes
import { requireAdmin } from '@/db/secure-db';
// For super-admin only features
const admin = await requireAdmin();
if (admin.role !== 'super_admin') {
return Response.json({ error: 'Super admin required' }, { status: 403 });
}
// Mock admin authentication for tests
vi.mock('@/db/secure-db', () => ({
requireAdmin: vi.fn().mockResolvedValue({
id: 'test-admin',
role: 'admin'
})
}));
describe('Admin Metrics Endpoint', () => {
it('returns metrics for authenticated admin', async () => {
const response = await GET(mockRequest);
expect(response.status).toBe(200);
});
it('returns 403 for non-admin', async () => {
vi.mocked(requireAdmin).mockResolvedValueOnce(null);
const response = await GET(mockRequest);
expect(response.status).toBe(403);
});
});
docs/ADMIN-DEVELOPER-SUITE.mdsrc/components/ui/Weekly Installs
87
Repository
GitHub Stars
73
First Seen
Jan 24, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
gemini-cli69
codex67
cursor67
opencode66
claude-code65
github-copilot63
Azure Data Explorer (Kusto) 查询技能:KQL数据分析、日志遥测与时间序列处理
161,200 周安装