prowler-ui
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRelated Generic Skills
相关通用技能
- - Const types, flat interfaces
typescript - - No useMemo/useCallback, compiler
react-19 - - App Router, Server Actions
nextjs-15 - - cn() utility, styling rules
tailwind-4 - - Schema validation
zod-4 - - State management
zustand-5 - - Chat/AI features
ai-sdk-5 - - E2E testing (see also
playwright)prowler-test-ui
- - 常量类型、扁平化接口
typescript - - 无需useMemo/useCallback、编译器特性
react-19 - - App Router、Server Actions
nextjs-15 - - cn()工具函数、样式规则
tailwind-4 - - Schema验证
zod-4 - - 状态管理
zustand-5 - - 聊天/AI功能
ai-sdk-5 - - E2E测试(另见
playwright)prowler-test-ui
Tech Stack (Versions)
技术栈(版本)
Next.js 15.5.9 | React 19.2.2 | Tailwind 4.1.13 | shadcn/ui
Zod 4.1.11 | React Hook Form 7.62.0 | Zustand 5.0.8
NextAuth 5.0.0-beta.30 | Recharts 2.15.4
HeroUI 2.8.4 (LEGACY - do not add new components)Next.js 15.5.9 | React 19.2.2 | Tailwind 4.1.13 | shadcn/ui
Zod 4.1.11 | React Hook Form 7.62.0 | Zustand 5.0.8
NextAuth 5.0.0-beta.30 | Recharts 2.15.4
HeroUI 2.8.4 (LEGACY - 请勿新增组件)CRITICAL: Component Library Rule
重要:组件库规则
- ALWAYS: Use + Tailwind (
shadcn/ui)components/shadcn/ - NEVER: Add new HeroUI components (is legacy only)
components/ui/
- 必须:使用+ Tailwind(
shadcn/ui目录)components/shadcn/ - 禁止:新增HeroUI组件(仅为遗留目录)
components/ui/
DECISION TREES
决策树
Component Placement
组件放置规则
New feature UI? → shadcn/ui + Tailwind
Existing HeroUI feature? → Keep HeroUI (don't mix)
Used 1 feature? → features/{feature}/components/
Used 2+ features? → components/shared/
Needs state/hooks? → "use client"
Server component? → No directive needed新功能UI? → 使用shadcn/ui + Tailwind
已有HeroUI功能? → 保留HeroUI(请勿混合使用)
仅用于1个功能? → features/{feature}/components/
用于2个及以上功能? → components/shared/
需要状态/钩子? → 添加"use client"指令
服务端组件? → 无需添加指令Code Location
代码位置规则
Server action → actions/{feature}/{feature}.ts
Data transform → actions/{feature}/{feature}.adapter.ts
Types (shared 2+) → types/{domain}.ts
Types (local 1) → {feature}/types.ts
Utils (shared 2+) → lib/
Utils (local 1) → {feature}/utils/
Hooks (shared 2+) → hooks/
Hooks (local 1) → {feature}/hooks.ts
shadcn components → components/shadcn/
HeroUI components → components/ui/ (LEGACY)Server action → actions/{feature}/{feature}.ts
数据转换逻辑 → actions/{feature}/{feature}.adapter.ts
共享类型(2+功能使用) → types/{domain}.ts
本地类型(仅1个功能使用) → {feature}/types.ts
共享工具函数(2+功能使用) → lib/
本地工具函数(仅1个功能使用) → {feature}/utils/
共享钩子(2+功能使用) → hooks/
本地钩子(仅1个功能使用) → {feature}/hooks.ts
shadcn组件 → components/shadcn/
HeroUI组件 → components/ui/ (遗留目录)Styling Decision
样式决策规则
Tailwind class exists? → className
Dynamic value? → style prop
Conditional styles? → cn()
Static only? → className (no cn())
Recharts/library? → CHART_COLORS constant + var()已有Tailwind类? → 使用className
动态值? → 使用style属性
条件样式? → 使用cn()
仅静态样式? → 使用className(无需cn())
Recharts/第三方库? → 使用CHART_COLORS常量 + var()Scope Rule (ABSOLUTE)
作用域规则(强制)
- Used 2+ places → or
lib/ortypes/(components go inhooks/)components/{domain}/ - Used 1 place → keep local in feature directory
- This determines ALL folder structure decisions
- 用于2个及以上场景 → 放在、
lib/或types/目录(组件放在hooks/)components/{domain}/ - 仅用于1个场景 → 保留在对应功能目录内
- 此规则决定所有文件夹结构的决策
Project Structure
项目结构
ui/
├── app/
│ ├── (auth)/ # Auth pages (login, signup)
│ └── (prowler)/ # Main app
│ ├── compliance/
│ ├── findings/
│ ├── providers/
│ ├── scans/
│ ├── services/
│ └── integrations/
├── components/
│ ├── shadcn/ # shadcn/ui (USE THIS)
│ ├── ui/ # HeroUI (LEGACY)
│ ├── {domain}/ # Domain-specific (compliance, findings, providers, etc.)
│ ├── filters/ # Filter components
│ ├── graphs/ # Chart components
│ └── icons/ # Icon components
├── actions/ # Server actions
├── types/ # Shared types
├── hooks/ # Shared hooks
├── lib/ # Utilities
├── store/ # Zustand state
├── tests/ # Playwright E2E
└── styles/ # Global CSSui/
├── app/
│ ├── (auth)/ # 认证页面(登录、注册)
│ └── (prowler)/ # 主应用
│ ├── compliance/
│ ├── findings/
│ ├── providers/
│ ├── scans/
│ ├── services/
│ └── integrations/
├── components/
│ ├── shadcn/ # shadcn/ui(推荐使用)
│ ├── ui/ # HeroUI(遗留目录)
│ ├── {domain}/ # 领域专属组件(合规、检测结果、提供商等)
│ ├── filters/ # 筛选组件
│ ├── graphs/ # 图表组件
│ └── icons/ # 图标组件
├── actions/ # Server actions
├── types/ # 共享类型
├── hooks/ # 共享钩子
├── lib/ # 工具函数
├── store/ # Zustand状态管理
├── tests/ # Playwright E2E测试
└── styles/ # 全局CSSRecharts (Special Case)
Recharts(特殊情况)
For Recharts props that don't accept className:
typescript
const CHART_COLORS = {
primary: "var(--color-primary)",
secondary: "var(--color-secondary)",
text: "var(--color-text)",
gridLine: "var(--color-border)",
};
// Only use var() for library props, NEVER in className
<XAxis tick={{ fill: CHART_COLORS.text }} />
<CartesianGrid stroke={CHART_COLORS.gridLine} />对于不支持className属性的Recharts props:
typescript
const CHART_COLORS = {
primary: "var(--color-primary)",
secondary: "var(--color-secondary)",
text: "var(--color-text)",
gridLine: "var(--color-border)",
};
// 仅在库属性中使用var(),切勿在className中使用
<XAxis tick={{ fill: CHART_COLORS.text }} />
<CartesianGrid stroke={CHART_COLORS.gridLine} />Form + Validation Pattern
表单+验证模式
typescript
"use client";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
const schema = z.object({
email: z.email(), // Zod 4 syntax
name: z.string().min(1),
});
type FormData = z.infer<typeof schema>;
export function MyForm() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
});
const onSubmit = async (data: FormData) => {
await serverAction(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("email")} />
{errors.email && <span>{errors.email.message}</span>}
<button type="submit">Submit</button>
</form>
);
}typescript
"use client";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
const schema = z.object({
email: z.email(), // Zod 4语法
name: z.string().min(1),
});
type FormData = z.infer<typeof schema>;
export function MyForm() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
});
const onSubmit = async (data: FormData) => {
await serverAction(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("email")} />
{errors.email && <span>{errors.email.message}</span>}
<button type="submit">Submit</button>
</form>
);
}Commands
命令
bash
undefinedbash
undefinedDevelopment
开发环境
cd ui && pnpm install
cd ui && pnpm run dev
cd ui && pnpm install
cd ui && pnpm run dev
Code Quality
代码质量检查
cd ui && pnpm run typecheck
cd ui && pnpm run lint:fix
cd ui && pnpm run format:write
cd ui && pnpm run healthcheck # typecheck + lint
cd ui && pnpm run typecheck
cd ui && pnpm run lint:fix
cd ui && pnpm run format:write
cd ui && pnpm run healthcheck # 类型检查 + 代码规范检查
Testing
测试
cd ui && pnpm run test:e2e
cd ui && pnpm run test:e2e:ui
cd ui && pnpm run test:e2e:debug
cd ui && pnpm run test:e2e
cd ui && pnpm run test:e2e:ui
cd ui && pnpm run test:e2e:debug
Build
构建
cd ui && pnpm run build
cd ui && pnpm start
undefinedcd ui && pnpm run build
cd ui && pnpm start
undefinedQA Checklist Before Commit
提交前QA检查清单
- passes
pnpm run typecheck - passes
pnpm run lint:fix - passes
pnpm run format:write - Relevant E2E tests pass
- All UI states handled (loading, error, empty)
- No secrets in code (use )
.env.local - Error messages sanitized (no stack traces to users)
- Server-side validation present (don't trust client)
- Accessibility: keyboard navigation, ARIA labels
- Mobile responsive (if applicable)
- 执行通过
pnpm run typecheck - 执行通过
pnpm run lint:fix - 执行通过
pnpm run format:write - 相关E2E测试通过
- 所有UI状态已处理(加载、错误、空状态)
- 代码中无敏感信息(使用存储)
.env.local - 错误信息已脱敏(不向用户展示堆栈跟踪)
- 已添加服务端验证(不要信任客户端验证)
- 可访问性:支持键盘导航、ARIA标签
- 移动端适配(如适用)
Migrations Reference
迁移参考
| From | To | Key Changes |
|---|---|---|
| React 18 | 19.1 | Async components, React Compiler (no useMemo/useCallback) |
| Next.js 14 | 15.5 | Improved App Router, better streaming |
| NextUI | HeroUI 2.8.4 | Package rename only, same API |
| Zod 3 | 4 | |
| AI SDK 4 | 5 | |
| 从 | 到 | 主要变化 |
|---|---|---|
| React 18 | 19.1 | 异步组件、React Compiler(无需useMemo/useCallback) |
| Next.js 14 | 15.5 | 优化后的App Router、更流畅的流式渲染 |
| NextUI | HeroUI 2.8.4 | 仅包名变更,API保持一致 |
| Zod 3 | 4 | 使用 |
| AI SDK 4 | 5 | 使用 |
Resources
资源
- Documentation: See references/ for links to local developer guide
- 文档: 查看[references/]获取本地开发者指南链接