文章目录
-
- 概要
- [npm 相关命令](#npm 相关命令)
- docker相关命令
- [git 相关命令](#git 相关命令)
- powershell相关命令
- 数据库相关问题
- 概念问题
-
- [RBAC(基于角色的访问控制)------ 推荐方案](#RBAC(基于角色的访问控制)—— 推荐方案)
- TDD(测试驱动开发)
概要
npm 相关命令
- 功能测试
python
npm --prefix backend test -- tests/api/activities.location-filter.test.ts
| 部分 | 具体含义 |
|---|---|
npm |
Node.js 包管理工具,用于执行项目脚本(这里是运行测试) |
--prefix backend |
指定命令的执行目录为 backend(后端项目根目录),避免需要手动 cd backend 再执行命令 |
test |
执行 backend 目录下 package.json 中定义的 test 脚本(通常是 Jest/Mocha 等测试框架的启动命令) |
-- |
分隔符:前面是 npm 命令参数,后面是传递给测试脚本的参数 |
tests/api/activities.location-filter.test.ts |
指定只运行这一个测试文件(而非全部测试),精准测试地点筛选功能 |
- 执行定义的脚本
python
npm --prefix frontend run lint
| 命令部分 | 具体含义 |
|---|---|
npm |
Node.js 包管理工具,执行前端项目的脚本命令 |
--prefix frontend |
指定命令执行目录为 frontend(前端项目根目录),无需手动 cd frontend |
run lint |
执行 frontend/package.json 中定义的 lint 脚本(该脚本已配置 ESLint/Prettier 等工具的校验规则) |
docker相关命令
- 容器内操作
python
docker exec supabase-db psql -U postgres -d postgres -c "\d+ public.profiles"
| 命令部分 | 具体含义 |
|---|---|
docker exec supabase-db |
在运行中的 supabase-db 容器(Supabase 的 PostgreSQL 数据库容器)内执行命令 |
psql -U postgres |
用 PostgreSQL 超级用户 postgres 连接数据库 |
-d postgres |
连接到默认的 postgres 数据库 |
-c "\d+ public.xxx" |
执行 PostgreSQL 内置命令 \d+,查询指定表的详细结构 |
\d+ public.profiles |
重点!\d+ 是 PostgreSQL 的元命令(非 SQL),作用是查看表的完整结构: - 字段名、数据类型、约束(主键 / 外键 / 非空); - 索引、默认值、注释; - 比单纯的 \d 显示更多细节(比如存储参数、统计信息) |
python
docker exec supabase-db psql -U postgres -d postgres -c "select id, title, location from public.activities order by created_at desc;"
| 命令部分 | 具体含义 |
|---|---|
docker exec supabase-db |
在运行中的 supabase-db 容器(Supabase 的 PostgreSQL 数据库容器)内执行命令 |
psql -U postgres |
用 PostgreSQL 超级用户 postgres 连接数据库 |
-d postgres |
连接到默认的 postgres 数据库 |
-c "select ..." |
执行引号内的 SQL 查询语句,执行后退出 |
select id, title, location from public.activities |
查询 activities 表的 3 个核心字段: - id:活动唯一 ID(定位具体数据行); - title:活动标题(快速识别是否为测试数据,比如标题含「测试」「test」); - location:活动地点(辅助识别测试数据,比如地点为「测试地址」); |
order by created_at desc |
按 created_at(创建时间)降序排列,最新创建的测试数据会排在最前面,更容易识别 |
python
docker exec supabase-db psql -U postgres -d postgres -c "select conname, conrelid::regclass as table_name from pg_constraint where confrelid = 'public.activities'::regclass and contype='f';"
| 命令部分 | 具体含义 |
|---|---|
docker exec supabase-db psql -U postgres -d postgres -c |
基础逻辑(和之前一致):进入 Supabase 数据库容器,用 postgres 用户连接数据库,执行后续 SQL |
select conname, conrelid::regclass as table_name |
查询两个核心字段: - conname:外键约束的名称(比如 activity_members_activity_id_fkey); - conrelid::regclass as table_name:将系统内部的表 ID(conrelid)转换为可读的表名(比如 public.activity_members); |
from pg_constraint |
从 PostgreSQL 系统表 pg_constraint 查询(该表存储所有数据库约束:主键、外键、唯一键等) |
where confrelid = 'public.activities'::regclass |
筛选条件 1:只查「引用的主表」是 public.activities 的约束(confrelid = 外键指向的主表 ID) |
and contype='f' |
筛选条件 2:只查外键约束(contype='f' 中 f = foreign key,主键是 p、唯一键是 u) |
- 列出正在运行的容器
python
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}"
| 命令部分 | 具体含义 |
|---|---|
docker ps |
Docker 核心命令:列出正在运行 的容器(如果加 -a 会列出所有容器,包括停止的) |
--format |
自定义输出格式,让结果更规整、只显示需要的信息(避免默认输出冗余内容) |
"table {``{.Names}}\t{``{.Image}}\t{``{.Ports}}" |
定义输出为 "表格格式",只显示 3 个核心字段: - {``{.Names}}:容器名称(比如 supabase-db、supabase-api); - {``{.Image}}:容器使用的镜像(比如 supabase/postgres); - {``{.Ports}}:容器映射的端口(比如 5432/tcp,PostgreSQL 默认端口); - \t:制表符,分隔字段,让表格对齐 |
git 相关命令
- 避免把产物文件提交
python
Add-Content .gitignore "`nbackend/node_modules/`nbackend/dist/`n*.dev.out.log`n*.dev.err.log"
git status --short
| 命令部分 | 核心解释 | 为什么这么做 |
|---|---|---|
Add-Content .gitignore [内容] |
Windows PowerShell 命令,向.gitignore文件末尾追加新的忽略规则: - ```n``:换行符,避免规则挤在一起; - backend/node_modules/:忽略后端依赖包目录(体积大、无需版本控制); - backend/dist/:忽略后端构建产物(可通过源码重新构建); - *.dev.out.log/*.dev.err.log:忽略日志文件(临时产物)。 ⚠️ 如果是 Linux/Mac 终端,改用 echo -e "..." >> .gitignore。 |
核心目的:避免把无意义的产物 / 日志文件提交到 Git 仓库,减少仓库体积,也避免多人协作时因这些文件产生冲突。 |
git status --short |
再次检查状态,确认被忽略的文件是否从 "未跟踪(??)" 状态消失。 | 验证忽略规则是否生效,防止漏加规则导致不该提交的文件被暂存。 |
- 暂存并人工确认提交内容
python
git add -A
git diff --staged --name-only
| 命令部分 | 核心解释 | 为什么这么做 |
|---|---|---|
git add -A |
-A = --all,暂存所有修改:包括已跟踪文件的修改、删除,以及新增的未跟踪文件(但.gitignore 里的文件除外)。 |
把所有需要提交的代码变更纳入 "暂存区",为后续提交做准备。 |
git diff --staged --name-only |
--staged:查看暂存区的变更; --name-only:只显示变更的文件名(不显示具体代码差异)。 |
人工核对:确认暂存区里只有需要提交的业务代码,没有误加的产物 / 日志文件,这是 "防错关键步骤"。 |
- 如果暂存里还有不该提交的文件,取消暂存
python
git restore --staged backend/node_modules backend/dist backend.dev.err.log backend.dev.out.log frontend.dev.err.log frontend.dev.out.log
git diff --staged --name-only
| 命令部分 | 核心解释 | 为什么这么做 |
|---|---|---|
git restore --staged [文件/目录] |
把指定文件 / 目录从 "暂存区" 移除(但保留本地文件不变),相当于 "取消暂存"。 ⚠️ 旧版 Git 可用 git reset HEAD [文件],效果相同。 |
兜底措施:如果步骤 3 发现暂存区有不该提交的文件(比如漏加.gitignore 导致 node_modules 被暂存),用这个命令撤销暂存,避免误提交。 |
git diff --staged --name-only |
再次查看暂存区,确认误暂存的文件已被移除。 | 验证取消暂存操作生效,确保最终提交内容纯净。 |
- 合并到 main:走 PR
python
gh pr create --base main --head feature/socialvibe-stability-chat --title "feat: stabilize chat flow" --body "..."
| 命令部分 | 核心解释 | 为什么推荐 |
|---|---|---|
gh pr create [参数] |
gh:GitHub CLI 工具(需提前安装配置); --base main:PR 的目标分支是 main; --head [功能分支]:PR 的源分支是功能分支; --title:PR 标题; --body:PR 描述(比如修改内容、测试情况、关联的需求 ID 等)。 |
团队协作的最佳实践: 1. PR 支持代码审查(Code Review),让同事检查代码问题; 2. 可配置 CI/CD 自动跑测试、构建,确保合并后 main 分支稳定; 3. 留下合并记录,便于追溯和管理。 |
- 合并完成后清理 worktree
python
git worktree remove D:\codex_code\socialvibe\.worktrees\socialvibe-stability-chat
git branch -d feature/socialvibe-stability-chat
| 命令部分 | 核心解释 | 为什么这么做 |
|---|---|---|
git worktree remove [worktree路径] |
删除该功能分支对应的独立工作树目录。 | 清理磁盘空间,避免多个无用的 worktree 目录堆积。 |
git branch -d [分支名] |
-d:删除本地功能分支(仅当分支已合并到 main 时才能删除); 如果要强制删除未合并的分支,用-D。 |
保持本地分支列表整洁,避免分支过多导致管理混乱。 |
- 从跟踪中移除
python
git rm -r --cached backend/node_modules backend/dist .npm-cache
| 部分 | 含义 |
|---|---|
-r |
递归处理目录(因为后面跟的都是文件夹) |
backend/node_modules |
后端目录下的 Node.js 依赖包(体积大、无需版本控制) |
backend/dist |
后端代码构建后的产物(编译后的文件,可通过源码重新生成) |
.npm-cache |
npm 的缓存目录(临时文件,无需追踪) |
git rm --cached命令的核心作用是:将指定文件 / 目录从 Git 的追踪列表中移除(但保留本地文件)
git rm:本意是删除文件并从 Git 追踪中移除;--cached:关键参数,只移除 Git 追踪关系,本地文件完全保留(如果不加这个参数,本地文件也会被删除);-r:递归处理目录(针对文件夹,比如node_modules这种包含大量子文件的目录必须加)。
powershell相关命令
- 执行SQL,将核心数据写如本地supabase数据库
python
$ Get-Content -Raw admin-system/database/supabase/seeds/seed_core.sql | docker exec -i supabase_db_supabase-project psql -U postgres -d postgres
| 命令 / 参数 | 作用 |
|---|---|
$ |
终端提示符(仅视觉标识,非命令部分); |
Get-Content -Raw admin-system/database/supabase/seeds/seed_core.sql |
PowerShell 读取文件: - Get-Content:读取文件内容; - -Raw:以 "原始字符串" 方式读取(保留 SQL 脚本的换行、格式,避免分段执行导致语法错误); - 路径:指定种子文件的位置; |
| | | 管道符:将前一步读取的 SQL 内容,作为输入传递给后一步命令; |
docker exec -i supabase_db_supabase-project |
Docker 执行命令: - docker exec:在运行中的 Docker 容器内执行命令; - -i:交互式模式(保留标准输入,允许通过管道传递 SQL 内容); - supabase_db_supabase-project:Supabase 数据库容器的名称(本地运行的 PostgreSQL 容器); |
psql -U postgres -d postgres |
PostgreSQL 客户端命令: - psql:PostgreSQL 的命令行客户端; - -U postgres:指定连接数据库的用户(Supabase 默认管理员用户是 postgres); - -d postgres:指定连接的数据库名称(Supabase 默认数据库是 postgres); |
- 删除文件
python
$ Remove-Item -Recurse -Force supabase-project/supabase
| 命令部分 | 具体作用说明 |
|---|---|
Remove-Item |
PowerShell 中用于删除文件 / 文件夹的核心命令(等同于 Windows CMD 的 del/rd,或 Linux/macOS 的 rm); |
-Recurse |
必选参数(删除文件夹时),表示递归删除 :不仅删除文件夹本身,还会删除其中所有子文件、子文件夹(因为 supabase 文件夹包含运行时生成的多层目录和文件); |
-Force |
强制删除参数: - 跳过删除前的确认提示(无需手动确认); - 可以删除隐藏文件 / 系统文件(Supabase 运行时可能生成隐藏配置文件); - 忽略文件 / 文件夹的只读属性; |
supabase-project/supabase |
要删除的文件夹路径: - supabase-project 是项目根目录(或父目录); - supabase 是 Supabase 运行时自动生成的文件夹(包含本地数据库数据、配置缓存、日志等临时 / 运行时文件)。 |
- 执行全局脚本
python
powershell -ExecutionPolicy Bypass -File admin-system/scripts/verify.ps1
| 命令片段 | 中文释义 | 核心作用 | 补充说明 |
|---|---|---|---|
powershell |
调用 PowerShell 解释器 | 启动 PowerShell 程序,作为执行脚本的运行环境 | 系统级命令,需确保 PowerShell 已安装(Windows 自带,macOS/Linux 需手动安装) |
-ExecutionPolicy Bypass |
执行策略设为 "绕过" | 临时跳过 Windows 默认的 PowerShell 脚本执行限制 | 1. Windows 默认执行策略(如 Restricted)会禁止运行本地未签名脚本; 2. 该参数仅对本次执行生效,不会修改系统永久策略; 3. 核心目的:让 verify.ps1 能正常运行,无需手动修改系统权限 |
-File |
指定要运行的脚本文件 | 告诉 PowerShell:后续路径是要执行的 .ps1 脚本文件 |
必选参数,若省略会把脚本路径当作普通字符串处理,无法运行脚本 |
admin-system/scripts/verify.ps1 |
验证脚本的路径 | 指向项目中用于全流程验证的 PowerShell 脚本 | 该脚本通常包含: ✅ 代码语法检查 ✅ 项目构建(编译 / 打包) ✅ 单元测试 / 集成测试 ✅ 依赖完整性校验 ✅ 输出最终验证结果(成功 / 失败) |
- 文件移动
python
$ Move-Item -Path D:/codex_code/ai_workbench/frontend/package-lock.json -Destination D:/codex_code/ai_workbench/frontend/package-lock.pre-real-impl-backup.json
| 命令 / 参数 | 作用 |
|---|---|
$ |
终端提示符(仅视觉标识,非命令的一部分); |
Move-Item |
PowerShell 核心命令:移动 / 重命名文件(相当于 Linux 的 mv 命令); |
-Path D:/codex_code/ai_workbench/frontend/package-lock.json |
源文件路径:指定要备份的本地 package-lock.json 位置; |
-Destination D:/codex_code/ai_workbench/frontend/package-lock.pre-real-impl-backup.json |
目标文件路径: - 将源文件重命名为 package-lock.pre-real-impl-backup.json(保留在同一目录); - 命名规则 pre-real-impl-backup 清晰标识:这是 "应用真实实现前的备份文件",便于后续识别; |
数据库相关问题
以supabase为例:
SERVICE_ROLE_KEY和ANON_KEY区别是什么,为什么在部署的时候,后端需要填写前者,前端需要填写后者?
这两个密钥都是 Supabase 提供的API 访问凭证 ,核心差异是权限等级 和使用场景 ,理解这一点就能明白 "后端用 SERVICE_ROLE_KEY,前端用 ANON_KEY" 的根本原因 ------ 本质是为了权限最小化 和安全防护。
| 密钥类型 | 权限等级 | 本质 | 适用场景 |
|---|---|---|---|
| ANON_KEY(匿名密钥) | 极低权限:仅能访问你在 Supabase 中显式允许匿名用户访问的数据 / 功能 | 面向前端的 "受限凭证" | 前端(浏览器 / 移动端)直接调用 Supabase API |
| SERVICE_ROLE_KEY(服务角色密钥) | 最高权限:绕过所有 Row Level Security (RLS) 规则,可操作 Supabase 中所有数据 / 功能(增删改查、管理用户、执行存储过程等) | 面向后端的 "超级凭证" | 后端服务器(Node.js/Java 等)调用 Supabase API |
概念问题
RBAC(基于角色的访问控制)------ 推荐方案
(1)核心定义
RBAC(Role-Based Access Control)是行业主流、实现成本低、易维护的权限模型,核心逻辑是:
- 先定义「角色」(如 super_admin/admin/analyst/viewer);
- 给「角色」绑定「权限」(菜单可见性、接口访问权限、操作按钮权限);
- 给「用户」分配「角色」(一个用户可绑定多个角色);
- 最终用户的权限 = 所有绑定角色的权限合集。
你提到的四级角色权限边界
| 角色 | 核心权限 | 权限边界(菜单 / 接口粒度) |
|---|---|---|
| super_admin | 全量权限 | 所有菜单可见 + 所有接口可访问(含权限配置、用户管理、系统配置、数据操作、日志查看等) |
| admin | 业务管理权限(无系统配置 / 权限管理) | 业务菜单(项目管理、沙箱运行、日志查看)+ 业务接口(导入 / 启动 / 停止项目);无用户 / 角色管理权限 |
| analyst | 只读 + 数据分析权限(无操作权限) | 所有菜单可见(仅展示)+ 只读接口(查看项目 / 日志 / 状态);无导入 / 启动 / 停止 / 删除等操作权限 |
| viewer | 基础只读权限(无数据分析) | 仅核心菜单(项目列表、基础日志)+ 基础只读接口;无数据分析、系统配置相关权限 |
优势
- 实现简单:主流框架(如 Spring Security、Casbin)都有成熟的 RBAC 插件,无需从零开发;
- 易理解 / 易维护:角色层级清晰,管理员可通过后台直接配置「角色 - 权限」映射,无需改代码;
- 适配中小规模系统:你的 Vite 工作台属于中小规模工具类系统,四级角色完全覆盖需求;
- 审计便捷:可通过「角色」快速追溯用户权限范围,符合合规要求。
劣势
- 灵活性有限:权限仅绑定角色,无法根据「数据范围」「时间」「环境」等动态条件控权(如 "仅允许 admin 查看自己创建的项目");
- 角色膨胀风险:若后续需细分权限(如 "仅允许导入 ZIP 不允许导入文件夹"),可能需要新增角色(如
operator_zip)。
TDD(测试驱动开发)
你先按照 TDD 规范,为后端核心功能(数据库 schema、工具函数、路由接口)编写了一批「故意让其失败」的单元 / 路由测试用例;这些测试现在会失败(因为对应的功能代码还未实现),后续你会根据测试的失败结果,逐步补全实现代码,最终让测试通过(红→绿→重构)。
简单说:你先定义了 "功能要满足什么条件"(测试用例),再去写代码实现功能,而非先写代码再补测试 ------ 这是 TDD 的核心思想,能保证代码从一开始就符合预期行为。
所有测试文件都基于 Vitest (前端 / Node.js 主流测试框架)编写,遵循 describe(测试套件)+ it(测试用例)+ expect(断言)的标准结构:
schema.test.ts--- 数据库表结构生成测试
python
import { describe, expect, it } from "vitest";
import { createSchemaSql } from "../../../../server/db/schema";
describe("schema", () => {
it("contains projects table creation", () => {
const sql = createSchemaSql();
expect(sql).toContain("CREATE TABLE IF NOT EXISTS projects");
});
});
- 测试目标 :验证
createSchemaSql()函数生成的 SQL 语句中,包含「创建 projects 表」的语句;
✅ 现在运行测试会失败(因为
createSchemaSql()还没实现,或返回的 SQL 不含该语句);❗ 后续你需要实现
createSchemaSql(),让它生成包含CREATE TABLE IF NOT EXISTS projects的 SQL,直到测试通过;
- 核心价值:确保数据库 schema 生成逻辑不会遗漏 projects 表,避免后续数据库无该表导致功能报错。
viteInspector.test.ts--- Vite 项目检测工具函数测试
python
import { describe, expect, it } from "vitest";
import { detectPackageManager, inspectViteProjectFiles } from "../../../../server/lib/viteInspector";
describe("viteInspector", () => {
it("prefers pnpm lockfile", () => {
expect(detectPackageManager(["pnpm-lock.yaml"])).toBe("pnpm");
});
it("marks missing package.json as invalid", () => {
const report = inspectViteProjectFiles(["index.html", "src/main.tsx"]);
expect(report.valid).toBe(false);
});
});
-
测试目标:验证两个工具函数的核心逻辑:
①
detectPackageManager:检测到pnpm-lock.yaml文件时,返回包管理器为pnpm;②
inspectViteProjectFiles:项目文件中缺少package.json时,标记项目为无效(valid: false);
持续更新