Skip to content
Back to skills

Backend Index

BSecurity

给本地后端项目建「模块 ↔ 目录/依赖/数据表」索引(.fe-index/):改模块前查依赖与被依赖,改表前查影响模块,接任务先看模块地图。触发:"后端索引"、"后端模块地图"、"改这个模块影响谁"、"改这张表影响哪些模块"。

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 9, 2026
developmentpythongobashdjangocode-reviewgitapifrontendbackend

Works with

  • cli
  • api
  • mcp

Security analysis

B88/100
  • criticalAccesses sensitive system or user directories

Pro scans all 3 files and shows the line behind each finding

Scanned November 9, 2026

npx -y skills add HACK-WU/skills --skill backend-index --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Backend Index?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Backend Index
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/hack-wu-backend-index/badge)](https://www.skillsdirectory.com/skills/hack-wu-backend-index)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: backend-index
description: 给本地后端项目建「模块 ↔ 目录/依赖/数据表」索引(.fe-index/):改模块前查依赖与被依赖,改表前查影响模块,接任务先看模块地图。触发:"后端索引"、"后端模块地图"、"改这个模块影响谁"、"改这张表影响哪些模块"。
---

# 后端模块索引(backend-index)

## 概述

**目的**:把「后端模块」的位置、边界、依赖与被依赖、数据面,从"每次 grep 试探 + 逐条读文件收敛"变成"查表直达"。改某模块前知道要连带看谁;改某张表前知道要通知哪些模块;接后端任务先拿到模块地图。

**功能**:
- 扫描本地后端源码,提取**模块**(NestJS `@Module` / Django app):目录、定义处、挂载前缀、接口数、controller 文件
- **双向依赖**:`模块 → 依赖`(imports 的兄弟模块)+ `模块 → 被依赖`(穷举反查,防漏)
- **表双向**:`模块 → 数据表`(forFeature / `@InjectRepository` / `models.Model` / 跨 app import)+ `表 → 模块`(反向,改表找谁)
- 非 HTTP 入口:MQ 消费者(`@Processor`)、CQRS Handler、定时任务;模块级守卫
- **事件/命令耦合边**:`bus.execute(new X)` → `@CommandHandler(X)` 所在模块、`@InjectQueue('q')` → `@Processor('q')` 所在模块——这类耦合**不经 `imports`**(靠 CQRS 总线 / 队列解耦),但"改一个 Command 或消息结构"照样影响对方。只统计模块自有文件,**每条边都可用 `grep 模块目录` 复验**
- **专家资产探测**:`.module-experts/` 里有哪些专家包、各自关联哪个模块(索引成为专家团的入口)
- **一键重建**:`--emit-tree` 一条命令落盘整棵树;**新鲜度闸门** `--check` 比对 commit
- **诚实降级**:展不开的常量数组、找不到 `@Entity` 的 token、默认命名的表名 → 全部进「待确认」,不猜

**使用场景**:
- 要改 / 删某张数据表 → 先查哪些模块引用了它(防漏通知、防漏回归)
- 要改某个模块的配置 / 依赖 / 对外面 → 先看它依赖谁、谁依赖它
- 新会话接手后端项目 → 一份模块地图建立认知(含"哪些模块有专家资产可深挖")
- 用户说"给后端建索引"、"后端模块地图"、"改这个模块影响谁"、"改这张表影响哪些模块"时
- 之前建过索引的项目再次被问起——**先查 `.fe-index/INDEX.md` 进消费模式**,而不是重跑扫描

---

## 定位

### 与邻接 skill 的分工(防重叠)

| 邻接能力 | 它做什么 | 本 skill 做什么 |
|---|---|---|
| **`expert-team`(.module-experts/)** | 按模块深挖:契约层(怎么用 / 接口契约 / 数据流向 C4 / 关键决策)+ 实现层 Wiki | 只给**位置与依赖骨架**,并**指向**专家资产。**接口清单与契约一律不重复建设**(专家 Step 8.3 已写 ki `tags=api`) |
| **`ki-search` 接口信息** | 可检索的接口原子(按子功能聚合) | 索引给"哪个模块",ki 给"接口怎么用" |
| **`strong-relation`** | 人工/AI 沉淀的模块间强耦合关系 | 机械提取的模块依赖边(覆盖全量、零维护);两者互补,冲突时以代码为准 |
| **`frontend-index`** | 前端「页面 ↔ 接口」索引(`.fe-index/{前端slug}/`) | 后端「模块 ↔ 表 / 依赖」索引(`.fe-index/{后端slug}/`);**跨端 join 见「被其它 skill 集成」** |
| **GitNexus MCP(`impact` / `context`)** | 符号级影响面(需 CLI + 已建索引) | **模块级**视角、零依赖、产物人可读、不依赖 MCP 可用性 |
| **grep / LSP** | 随机访问(搜到什么算什么) | **穷举反查 + 落盘复用**(被依赖 / 表反查 / 跨会话一致) |

**一句话边界**:本 skill 回答「**去哪看、动了谁**」;专家团回答「**是什么、怎么用**」;grep 回答「**具体在哪一行**」。

### 与 `frontend-index` 的关系(同族)

两个 skill **实现独立、产物同根**(`.fe-index/`),口径一致:双模式 / 新鲜度闸门 / 退出码族 / `[待确认]` 不猜 / 脚本提取骨架 + AI 补语义。可以各自单独安装使用。

---

## 核心原则

1. **索引模块,不是索引接口**:接口清单交给专家团与 ki(`tags=api`)——重复建设必然漂移。本索引只在模块卡里记「挂载前缀 + 接口数 + controller 文件」,**不逐接口建表**。
2. **脚本管骨架,AI 管语义**:穷举机械活(模块全集 / 前缀合成 / 依赖反查 / 表反查 / 一键重建)交给脚本;语义判断(模块中文职责、专家关联确认、分组)交给 AI。**不让 AI 重复做穷举提取**(会漏,且每次重建都贵)。
3. **反查必须穷举**:`被依赖` 与 `表 → 模块` 是"扫完全部才知道"的反查——漏一条边就是一份**看起来完整但会误导**的报告。这类活只能机械提取。
4. **失效要显式**:`meta.json` 记 commit,读表前 `--check`;范围外无变化不误报。
5. **不猜**:展不开的数组、找不到声明的 token、默认命名的表 → 进「待确认」,宁可缺,不给错。
6. **双模式分离**:**消费模式**(查表 → 读码,**不跑脚本**)与**建造模式**(采集建库)严格分开。
7. **可见性由集成方负责**:`.fe-index/` 是隐藏目录,本 skill 不擅自往用户的 AGENTS.md / 规则里写钩子。

---

## 产物结构

> **落点一律在【项目根】**(`git rev-parse --show-toplevel`;非 git 仓库则逐级向上找 `.git`):即 `{项目根}/.fe-index/`。
> monorepo 里 `--root` 可以给应用子目录,但**索引属于整个项目**——`--emit-tree` 不带值就落这里,带相对路径也以项目根为基准(不看 cwd)。

```text
{项目根}/.fe-index/
├── INDEX.md                      # 必存在:全项目登记表(一行一应用)—— 后续会话的发现入口
└── {app-slug}/
    ├── index.md                  # 必存在:模块地图 + 依赖图 + 表反查摘要 + 专家资产 + 待确认
    ├── modules/{模块slug}.md     # 每模块一张卡(占位/依赖/表/事件耦合/入口/守卫/专家指针/归属文件)
    ├── tables.md                 # 必存在:表 → 模块(反向索引)
    └── meta.json                 # 必存在:机器可读元信息(commit / 范围 / 统计)—— `--check` 依据
```

| 类别 | 文件 | git 建议 |
|---|---|---|
| 人工维护(发现入口) | `INDEX.md` | 入库(一行一应用,冲突少) |
| 派生产物(脚本生成) | `meta.json` / `index.md` / `modules/` / `tables.md` | 默认不入库(会随代码过期) |

**`INDEX.md` 是这个机制的生命线**:隐藏目录不会被自动发现,每次建造都必须同步更新它。

### INDEX.md 模板(**与 `frontend-index` 共用同一份文件,列结构必须一致**)

```markdown
# 索引登记表(.fe-index/)

> 涉及下列应用的问题,先查对应条目所在的分区/映射表,再看代码

| 应用 | 类型 | slug | 根目录 | 规模 | commit | 生成日期 |
|------|------|------|--------|------|--------|----------|
| cloud-web | frontend | cloud-web | `/root/xpert` | 页面 121 · 接口 66 | `889e265c` | 2026-10-13 |
| server-ai | backend | server-ai | `/root/xpert` | 模块 125 · 表 122 | `889e265c` | 2026-10-13 |
```

**更新纪律**:只增改本应用那一行,**不动其他行**;同一仓库前后端各占一行(slug 不同,不合并)。
**「根目录」列口径**(消费方按此解析):绝对路径直用;**相对路径以 `.fe-index/` 的上一级为基准**(便于跨机器与仓库整体搬迁)。查找登记表时若 `{root}` 下没有,逐级向上找 ≤3 层。

### meta.json 模板(`--check` 依赖,必写)

```json
{
  "slug": "server-ai",
  "kind": "backend",
  "root": "/root/xpert",
  "scope": ["packages/**", "apps/**"],
  "framework": "nestjs",
  "commit": "889e265cdfdec200e5a6446f4463fe43505f84ac",
  "generated": "2026-10-13",
  "stats": { "modules": 125, "tables": 122, "deps_edges": 428, "routes": 806 },
  "scanner": "scan_backend.py v2.0.0"
}
```

> `--emit-tree` 会**自动写** meta.json(含 commit),无需手写;手工建库时(见阶段 2 的小项目分支)必须自己填。

### index.md 模板

```markdown
# {slug} 后端模块索引

> 根目录:`…` · 框架:**nestjs** · 全局前缀:`/api`
> 生成:2026-10-13 · commit:`889e265cdf` · 范围:`packages/**, apps/**`
> 新鲜度校验:`python3 scan_backend.py --root <根> --check --index <本目录>`

**这个索引回答什么**:改某模块要连带看谁、改某张表要通知哪些模块、模块的数据面与非 HTTP 入口、模块的代码在哪。
**接口级契约**见 `.module-experts/` 专家资产与 ki 接口信息(`tags=api`)——本索引不重复建设。

## 1. 模块地图(N)
| 模块 | 目录 | 挂载前缀 | 接口 | 表 | 依赖 | 被依赖 | 非 HTTP 入口 | 专家资产 |
…(每模块一行,链接到 modules/{slug}.md)

## 2. 模块依赖图(M 条边)        ← mermaid graph LR(边 >120 时降级为文本列表)
## 3. 表 → 模块(反向,K 张表)    ← 摘要,完整见 tables.md
## 4. 专家资产(N 个)             ← 专家名 / 路径 / 关联模块(未关联显式标注)
## 5. 待确认(N)                  ← 类型 / 位置 / 内容 / 原因
```

### modules/{模块slug}.md 模板

```markdown
# {模块名}(`{slug}`)
- 位置:`{目录}/` · 归属文件 N 个 · 约 M 行
- 定义:`{module.ts}:{line}`(nestjs) | 挂载前缀:`/api/x` · 接口 N 个 | 置信度:🟢
## 控制器(模块对外面)   ← 文件 / 前缀 / 接口数 / 行号
## 依赖关系              ← 依赖(改它要连带看)/ 被依赖(动它会影响)/ 依赖的库
## 事件/命令耦合          ← 我发出(→ 目标模块 + 命令/队列名)/ 我接收(← 来源模块 + 命令名)
## 数据表(N)           ← 表 / 实体 / 引用次数 / 来源(定义 or import)/ 证据 file:line
## 非 HTTP 入口          ← MQ / CQRS / 定时任务
## 守卫/权限
## 专家资产(深挖读这些)
## 归属文件(N)
```

---

## 工作流

**第一步先判模式**(必做):读 `.fe-index/INDEX.md`(不存在则视为首次建库;被集成时落点以调用方指定为准)。

### 消费模式(查表 → 读码)

1. 读 `.fe-index/INDEX.md` → 找到对应应用与 slug
2. **新鲜度闸门**(必做):
   ```bash
   python3 <skill>/scripts/scan_backend.py --root <根> --check --index .fe-index/{slug}
   ```
   - 退出码 0:新鲜 → 继续
   - 退出码 6:过期 → **先问用户是否重建**(重建 = 重跑 `--emit-tree`,秒级)
   - 退出码 7:缺 `meta.json` → 按"无新鲜度信息"处理,告知用户
   - 退出码 3:git 不可用 / 记录的 commit 不可达 → 按"无法判定"处理,建议重建
3. 按问题查表:
   - "改这张表要注意什么" → `tables.md` 找到表 → 拿到模块清单(定义方 vs 使用方)→ 读对应 `modules/*.md`
   - "改这个模块影响谁" → `modules/{slug}.md` 的**被依赖** → 逐个看
   - "改一个 Command / 队列消息影响谁" → `modules/{slug}.md` 的**事件/命令耦合**段(我发出 → 目标模块;我接收 ← 来源模块)
   - "这个接口/功能在哪" → `index.md` 模块地图按前缀定位模块 → 进模块目录看 controller
   - "这个模块怎么用 / 契约是什么" → **交给专家资产**(模块卡里有指针);没有专家则 ki `tags=api` 或现场读码
4. **命中即止**:不再全库 grep;只有模块定位后需要行级细节时才在模块目录内查

### 建造模式总览

```text
阶段 0 准入与模式判定 → 阶段 1 约定探测(含"值不值得建/要不要跑脚本")→ 阶段 2 提取(脚本 --emit-tree)
   → 阶段 3 语义补充(AI,可选但推荐)→ 阶段 4 登记(INDEX.md)→ 阶段 5 交付与使用协议
```

### 阶段 0:准入判断(AI 自主)

| 信号 | 处置 |
|---|---|
| 目标应用已在 `INDEX.md` 在册 | ➡️ 转**消费模式**(用户要求重建除外) |
| 后端模块 ≤10 个且只要"模块在哪",不需要"谁依赖我 / 改表影响谁" | ➡️ **小项目分支**:AI 直接读代码建索引,不跑脚本(仍需写 meta.json 与 INDEX.md;不承诺 `--check`) |
| 需要反向穷举(被依赖 / 表 → 模块)或模块数 >10 或要跨会话复用 | ✅ 进建造模式(跑脚本) |
| 代码不在本地 / 无源码 | ❌ 退出(本 skill 只索引本地代码) |

### 阶段 1:约定探测(**唯一的用户确认点**)

```bash
python3 <skill>/scripts/scan_backend.py --root <根> --dump-config
```
输出:框架(nestjs / django)、全局前缀、`src_dirs`、模块声明数、建议 include。
- 有 `{项目根}/.fe-index/config.json`(集成方或此前建库留下)→ 脚本**自动读取并应用**(`--config` 可指定路径;只认 `kind=backend`,`--app`/`--slug` 选应用)→ 重建**零猜测**;文件里只有他端条目(如只声明了前端)时**说明一行后忽略,不拦路**
- 与用户确认:**扫描范围**(哪个应用、哪些包、slug 名)
- 框架识别失败(退出码 2)→ 用 `--framework` 显式指定,或收窄 `--include`
- 探测结果建议固化为声明文件(`--dump-config` 会给出 `suggested_config`):与前端共用同一份 `config.json`,各自按 `kind` 取用自己的条目

### 阶段 2:脚本提取

```bash
python3 <skill>/scripts/scan_backend.py --root <根> --framework nestjs \
  --include 'packages/**' --include 'apps/**' --slug server-ai \
  --emit-tree
```
`--emit-tree` 不带值 → 自动落 **`{项目根}/.fe-index/server-ai/`**(推荐用法)。要自定义位置时才给它一个值(绝对路径直用;相对路径以**项目根**为基准)。
一步完成:模块全集 / 前缀 / 依赖图(含被依赖)/ 表双向 / 非 HTTP 入口 / 专家探测 / 待确认 / meta.json。

**退出码处置**:

| 码 | 含义 | 处置 |
|---|---|---|
| 0 | 成功 | 继续 |
| 2 | 未识别框架 | `--framework` 显式指定 / 收窄 `--include` |
| 3 | 根目录不存在或 git 失败 | 修正参数 |
| 4 | 识别到框架但零模块 | 检查 `--include` 是否覆盖后端源码 |
| 5 | 入参非法 | 修正参数 |
| 6 | `--check` 判定过期(范围文件有变化) | 先问用户是否重建(`--emit-tree` 覆盖落盘) |
| 7 | `--check` 缺 `meta.json` 或无 commit | 按"无新鲜度信息"处理,建议重建 |

**成本**:实测 3183 个 TS 文件 0.5 秒(NestJS)/ 5530 个 PY 文件 1.3 秒(Django)。重建近乎零成本——这是"索引不会腐烂"的前提。

### 阶段 3:语义补充(AI,可选但推荐)

脚本出的是**机械骨架**;下面这些 AI 直接读代码补,更准:

1. **模块中文职责**:给核心模块补一句话(写进模块卡顶部)。只补"改代码前需要知道的",不写百科。
2. **专家关联确认**:脚本按名字机械匹配,可能漏(专家用中文业务名)。逐个核对 `未关联` 的专家,人工指到模块卡里。
3. **待确认处理**:读 `index.md` 第 5 节,对影响判断的项(如展不开的数组、缺 `@Entity` 的关键 token)回源码确认,确认结果写进模块卡或 `meta.json` 的 notes。
4. **分组(可选)**:模块 >40 个时,按业务域在 `index.md` 里给模块地图加分组小标题(不改 `modules/` 目录结构)。

**成本闸门**:阶段 3 读文件 ≤15 个(骨架已由脚本给出,只读"需要判断"的)。

### 阶段 4:登记(INDEX.md)

- 脚本没写 `INDEX.md`(它是跨应用登记表):**新增或更新该应用那一行**(应用 / 类型 backend / 根目录 / 范围 / 规模 / commit / 日期)
- 若同项目已有前端索引:保持两个 slug 各自一行,**不要合并**

### 阶段 5:交付

1. 一句话总结:模块数、表数、依赖边数、待确认数、**专家资产覆盖情况**
2. 给出**使用协议**(消费模式三问:改表去哪查 / 改模块去哪查 / 接口契约去哪查)
3. 可选提醒:在 `AGENTS.md` 里加一句"改后端模块或数据表前,先查 `.fe-index/INDEX.md`"(加不加由用户决定,本 skill 不代劳)

---

## 反模式

- ❌ **把接口清单再抄一遍**:专家团/ki 已有(`tags=api`)——重复建设必然漂移,且接口级数据天然过期快
- ❌ **让 AI 全量手工建库**:模块数 >10 或需要反查时会漏边,且每次重建成本高到不会重建 → 索引腐烂
- ❌ **不写 meta.json 就交付**:没有 commit 就无法判断新鲜度,索引会静默过期
- ❌ **跳过 `--check` 直接信表**:代码映射失效是静默的(表还能查,结果是错的)
- ❌ **在建造模式里逐模块读代码**(脚本已给骨架):除非属于阶段 3 的"需要判断"清单
- ❌ **把「未关联」的专家当无关**:专家名多为中文业务名,与代码标识无字面重叠 → 需人工指认
- ❌ **拿默认命名的表名当真**:Django/TypeORM 默认命名在「待确认」里,向用户确认后才写入结论

---

## 行为边界(明确不承诺)

- ❌ 运行时行为:动态模块(`forRootAsync` 里拼出来的)、反射注册的 provider、`@Controller` 路径运行时改写
- ❌ 跨服务:RPC / 微服务另一端的模块(只到本仓声明)
- ❌ 接口级清单与契约(归专家团 / ki)、精确到 `file:line` 的调用链(归 GitNexus / LSP / grep)
- ❌ 非 NestJS / Django 框架的模块体系(可扩展,见 `reference.md` 的规则表)
- ⚠️ monorepo 需 `--include` 限定应用范围;前后端同仓时前端文件会被自动排除(同名类污染,已实测)
- ⚠️ 表名若为框架默认命名(Django `{app}_{模型}` / TypeORM 类名推断)→ 标 🟡 进「待确认」
- ⚠️ 依赖边分两类:**`imports` 声明**(模块间依赖)与**事件/命令耦合**(`bus.execute(new X)` / `@InjectQueue` 配对,只取模块自有文件)。**仍不入图**:字符串主题的事件(`emit('x')`)、跨进程 MQ 主题约定、共享配置 / 环境变量——需要时按 `reference.md` 的抽样核对方法局部 grep 补齐
- ⚠️ 同仓多框架(NestJS + Django 并存)时 `--framework` 一次只扫一侧:脚本会显式告警,另一侧需单独建一个 slug

---

## 被其它 skill 集成(调用契约 · SSOT)

**规则只在本节维护**,调用方引用本 skill,不复制规则。

| 集成方 | 建议用法 | 状态 |
|---|---|---|
| **`index-lookup`(统一查询入口)** | 消费方(`code-review` / `debug` / `product-manager` / `expert-team` / `code-survey` …)**先调它**按代码路径判定该查前端还是后端索引(读同一张 `.fe-index/INDEX.md`),再按本 skill 的查询口径查表 | **推荐接入**:**不要让每个消费方自己实现"选哪端"**,否则口径必然漂移 |
| **跨端 join(与 `frontend-index` 组合)** | 先读后端 `index.md` 的「模块 → 挂载前缀」,再用前端 `apis/{分区}.md` 里的接口路径匹配前缀 → 答"后端改接口 → 前端哪些页面在用" | **可直接用**(两端产物同根、口径已对齐;`@Controller()` 无前缀的模块用「方法路径」提示匹配) |
| `expert-team` | 建完专家包后重跑 `--emit-tree`,专家列会因目录存在而出现 → 索引成为专家团的**发现入口**(解决"建了没人知道") | **可直接用**(产物级衔接,无需改对方) |
| `module-teach` | 讲解某后端模块前读 `modules/{slug}.md` 定位范围与依赖 | **已接入**(「与相邻 skill 的分工与路由」表,`module` 类讲解先用索引锁定范围) |
| `code-survey` / 设计前调研 | 查 `INDEX.md` 命中则消费,未命中再决定是否建库 | **已接入**(「ki-search 与资产复用优先」链,缩小搜索域) |
| `code-change-impact` / `code-review` / `debug` | 改到后端模块或数据表时,用被依赖与表反查确认影响面 | **已接入**(code-change-impact 3.0 / code-review 阶段 2 / debug Step 0) |

> 上表**不声明"已接入"**:本 skill 的产物需要目标项目先建一次索引,集成方需自行降级(无索引时按原流程 grep)。

**全局前缀匹配口径**(跨端 join 的关键,写清防歧义):`挂载前缀 = "/" + global_prefix + controller前缀`;`@Controller()` 无路径时,用方法路径首段(模块卡/表格里显示为"方法路径 `x`、`y`")与前端接口路径做包含匹配。

---

## 更多资源

- `reference.md`:为什么是模块级(设计依据与专家团证据)· 框架提取规则明细 · 脚本参数与退出码全表 · 证据分级与 `[待确认]` 规则 · 两靶子实测数据与已知坑 · 抽样核对方法

Files in this skill

  • SKILL.md20.7 KB
  • reference.md18.9 KB
  • scripts/scan_backend.py88.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in development →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.