Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ A personal collection of [Agent Skills](https://docs.claude.com/en/docs/claude-c
| Skill | What it does |
| --- | --- |
| [github-star-recall](./skills/github-star-recall) | Rediscover and prune forgotten GitHub stars, one at a time. |
| [j10c-frontend-playbook](./skills/j10c-frontend-playbook) | My personal React + TypeScript rules for AI agents writing code on my behalf. |
|| [j10c-frontend-playbook](./skills/j10c-frontend-playbook) | My personal React + TypeScript rules for AI agents writing code on my behalf. Includes fix-patterns/ — empirical weakness patterns from Taro/Vue projects with self-check lists and fix templates. |
| [soco-cli](./skills/soco-cli) | Sonos automation — alarms, sleep timers, scripted scenes. |

## Install
Expand Down
18 changes: 18 additions & 0 deletions skills/j10c-frontend-playbook/fix-patterns/INDEX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Fix Patterns Index

基于 WeJH-Taro 全仓库 321 条 fix commit 分析提炼的前端薄弱模式库。
每个模式含定义、触发条件、真实 commit 引证、自检清单和修复模板。

持续监控:每日 23:00 Hermes cron job 自动扫描 j10ccc 新合入的 PR,
命中既有薄弱模式时自动追加具体例子到对应文件。

| 模式 | 文件 | Commit 数 | 占比 | 一句话定义 |
|------|------|-----------|------|-----------|
| UI/样式架构缺陷 | [weak-ui-style.md](weak-ui-style.md) | 101 | 31.5% | CSS 隔离缺失、z-index 冲突、深色模式未同步 |
| 业务逻辑盲区 | [weak-logic-bug.md](weak-logic-bug.md) | 89 | 27.7% | 边界输入未处理、浮点精度丢失、key 重复 |
| 类型守卫与空指针 | [weak-type-null.md](weak-type-null.md) | 34 | 10.6% | 类型定义不当、null/undefined 未守卫、不当断言 |

---

*数据来源:zjutjh/WeJH-Taro 全仓库 fix commit 审计(2023-08 至 2026-05)*
*持续追加:Hermes cron job `daily-pr-fix-pattern-review`(ID: e10817b586fb)*
46 changes: 46 additions & 0 deletions skills/j10c-frontend-playbook/fix-patterns/weak-logic-bug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# 业务逻辑盲区

> 边界输入未处理、浮点精度丢失、key 重复、数据流不完整等业务逻辑遗漏

## 触发条件

- 新功能涉及数值计算(特别是浮点运算)
- 使用 `v-for`/`map` 渲染列表但 key 生成逻辑可能重复
- API 返回值可能为空数组/null/undefined
- 功能模块涉及状态切换或多步骤流程
- 日期/时间格式化与展示

## 真实 Commit 引证

| # | Commit | 说明 |
|---|--------|------|
| 1 | [9cc0789](https://github.com/zjutjh/WeJH-Taro/commit/9cc07895a8d32c8c439592ab753e23bd22860508) | fix(score): 修复浮点数加法导致绩点值出错 |
| 2 | [6bd1134](https://github.com/zjutjh/WeJH-Taro/commit/6bd113411cce523f32dd1dae5dc99ddcf7ce3f15) | fix(lessonTable): 某天上下午有同一节课, v-for中key会一样导致问题 |
| 3 | [646af91](https://github.com/zjutjh/WeJH-Taro/commit/646af9196aff81a25f83da2149b243e56e25f25a) | fix: 消费记录保留两位小数 |

本项目共 89 条业务逻辑 Bug + 数据展示 fix commit(占 27.7%),为第二大修复类别。

## 自检清单

- [ ] 浮点运算是否使用 `toFixed()` 或整数化后计算?
- [ ] `v-for`/`map` 的 key 是否保证唯一(日期+节次+课程ID 等组合 key)?
- [ ] API 返回空值/null/undefined 是否有兜底展示(非空白区域)?
- [ ] 边界输入(零值/空数组/极值)是否逐一测试?
- [ ] 多步骤流程是否有"上一步未完成就进入下一步"的防护?

## 修复模板

```typescript
// 1. 浮点精度
const gpa = +(totalPoints / totalCredits).toFixed(2);

// 2. 唯一 key 生成
const lessonKey = `${day}-${period}-${course.id}`;

// 3. 空值兜底
const displayName = data?.name ?? '暂无数据';

// 4. 边界守卫
const items = Array.isArray(data) ? data : [];
const first = items[0] ?? defaultItem;
```
53 changes: 53 additions & 0 deletions skills/j10c-frontend-playbook/fix-patterns/weak-type-null.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# 类型守卫与空指针

> TypeScript 类型定义不当、null/undefined 未守卫、不当类型断言导致的运行时错误

## 触发条件

- 访问 API 返回值的嵌套属性
- 从 Store/Vuex/Pinia 获取状态
- 使用 `as` 类型断言或 `!` 非空断言
- 数组索引访问(`arr[0]`)未判断长度
- 对 `Record<K, V>` 的值做属性访问
- 重构/重命名后修改类型定义

## 真实 Commit 引证

| # | Commit | 说明 |
|---|--------|------|
| 1 | [27a32d4](https://github.com/zjutjh/WeJH-Taro/commit/27a32d4d2baad7fe08850502a9966949cf5c7991) | fix: term-picker default value fits the type defination |
| 2 | [c6ec966](https://github.com/zjutjh/WeJH-Taro/commit/c6ec9665f00f6cc46bfbdc6620ce46b61eeef9e1) | fix(bus): placeholder 取值越界 |
| 3 | [2caeff1](https://github.com/zjutjh/WeJH-Taro/commit/2caeff15c8790a5169c088a524517a057d1d03e5) | fix: 可能的空指针问题,以及预处理 parseFloat |

本项目共 34 条类型错误 + 空指针 + 边界 fix commit(占 10.6%),是代码质量的系统性薄弱点。

## 自检清单

- [ ] 所有 API 返回值是否标注了可能为 `undefined` 的字段?
- [ ] 是否存在 `as X` 或 `!` 非空断言在业务逻辑中?(应替换为类型守卫)
- [ ] 数组索引访问前是否检查了 `.length`?
- [ ] `Record<K, V>` 的值访问是否用了可选链 `?.`?
- [ ] 重构(重命名/移动/拆分)后是否运行了 `pnpm typecheck`?

## 修复模板

```typescript
// 1. 用类型守卫替代 as 断言
function isUser(val: unknown): val is User {
return typeof val === 'object' && val !== null && 'id' in val;
}

// 2. 可选链 + 空值合并
const name = user?.profile?.name ?? '未知用户';

// 3. 数组安全访问
const first = arr.length > 0 ? arr[0] : undefined;

// 4. 收紧类型定义(而非放宽)
interface ApiResp {
data: UserInfo | null; // 明确 null 可能
}

// 5. 重构后必须 typecheck
// pnpm typecheck
```
53 changes: 53 additions & 0 deletions skills/j10c-frontend-playbook/fix-patterns/weak-ui-style.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# UI/样式架构缺陷

> CSS 隔离缺失、z-index 冲突、深色模式未同步、样式穿透等视觉层面反复修复的问题

## 触发条件

- 新增页面/组件涉及深色模式适配
- 使用了全局 CSS 或未采用 CSS Modules 隔离
- 设置了硬编码 z-index 值
- 修改主题色/主题系统相关代码
- Taro 组件样式穿透(`styleIsolation` 配置)

## 真实 Commit 引证

| # | Commit | 说明 |
|---|--------|------|
| 1 | [9da5cb8](https://github.com/zjutjh/WeJH-Taro/commit/9da5cb81719ea2e589662ddf0bb16b2935184e2b) | fix(lessonstable): 统一了深色,亮色模式,统一了css modules |
| 2 | [2d375bb](https://github.com/zjutjh/WeJH-Taro/commit/2d375bb9d03fea5caecd08f02c110ae55c56a1a9) | fix(lessonstable): 修复了边框毛玻璃层高显示与课表和时间线冲突的问题 |
| 3 | [27cbe9d](https://github.com/zjutjh/WeJH-Taro/commit/27cbe9d2d0f9729112d07a6364a418a3981dc7a4) | fix(nav-bar): style isolation |

本项目共 101 条 UI/样式 fix commit(占 31.5%),为最高频修复类别。

## 自检清单

- [ ] 新组件是否使用 CSS Modules(`*.module.scss`)隔离样式?
- [ ] 深色模式下所有颜色是否已同步定义(CSS 变量或 `@media (prefers-color-scheme: dark)`)?
- [ ] z-index 是否遵循项目约定层级,而非随意赋值?
- [ ] Taro 组件是否配置了 `styleIsolation: 'apply-shared'` 或 `'isolated'`?
- [ ] 主题色变更是否覆盖了所有使用该色的组件?

## 修复模板

```scss
// 1. 使用 CSS Modules 隔离
// index.module.scss
.container { /* scoped styles */ }

// 2. CSS 变量适配深色模式
.card {
background: var(--wjh-color-bg-card);
}

@media (prefers-color-scheme: dark) {
:root {
--wjh-color-bg-card: #1a1a1a;
}
}

// 3. z-index 约定
// < 100: 内容层级
// 100-200: 弹层/浮层
// 200+: 模态/全局
```