faasjs-best-practices

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Global Rules

全局规则

  • Read
    tsconfig.json
    and any extended TypeScript config before choosing import paths.
  • Prefer FaasJS TypeScript loader support for direct Node execution, and keep local TypeScript imports extensionless instead of adding
    .ts
    or
    .tsx
    suffixes.
  • Prefer aliases already defined in TypeScript config over deep relative imports.
  • Keep short relative imports for nearby files in the same feature or directory.
  • Do not invent a new alias in code unless the corresponding
    tsconfig.json
    and runtime resolver are configured in the same change.
  • Keep changes minimal and task-scoped: no extra features, drive-by refactors, opportunistic cleanup, feature flags, transition shims, or speculative future-proofing.
  • Use zod for input validation at system boundaries (user input, external APIs, config files) where a schema defines the expected shape. Zod's
    .safeParse()
    provides type-safe validation with automatic type inference, eliminating handwritten validation functions and keeping types in sync.
  • Keep internal runtime type checks (
    typeof
    ,
    instanceof
    ,
    === null/undefined
    ) as-is. Replacing these with zod would increase code volume and add parsing overhead with no benefit—they are control-flow predicates, not input validation. The rule is: zod for external input contracts,
    typeof
    /
    instanceof
    for internal type interrogation.
  • Keep code direct: validate at system boundaries, fail fast on invalid internal data, and do not add silent fallbacks or impossible-case handling.
  • Avoid unnecessary intermediate variables: return or pass values directly instead of assigning to a single-use variable. An intermediate variable is justified when it documents a non-trivial condition, is referenced more than once, or breaks a long chain for readability.
  • Do not destructure function parameters; access them through the parameter object (e.g.,
    input.xxx
    or
    props.xxx
    ) so the source of each value is immediately visible.
  • Do not create standalone type aliases or interfaces when TypeScript can infer the type from the expression, schema, or return statement; rely on inference first and add explicit types only at API boundaries, shared contracts, or where inference is ambiguous.
  • Extract helpers, hooks, components, or abstractions only when they are reused, create a real boundary, or simplify a large block; keep one-off code inline unless the body is over about 20 lines.
  • Document package public exports with JSDoc. Add JSDoc for shared app exports when the caller contract is not obvious. Do not add comments, docstrings, or type annotations to untouched code.
  • Delete confirmed-dead code directly instead of leaving temporary tricks such as
    _unused
    renames, type re-exports, or
    // removed
    markers.
  • Keep files under about 500 lines by splitting along real boundaries before they grow too large.
  • Treat
    vp check --fix
    and
    vp test
    as the default acceptance gates before handoff; if either cannot run, record the reason and the narrower validation that was completed.
  • 在选择导入路径前,先阅读
    tsconfig.json
    及所有扩展的TypeScript配置文件。
  • 优先使用FaasJS TypeScript加载器以支持直接Node执行,本地TypeScript导入无需添加
    .ts
    .tsx
    后缀,保持无扩展名状态。
  • 优先使用TypeScript配置中已定义的别名,而非深层相对导入。
  • 同一功能或目录下的邻近文件,使用简短的相对导入。
  • 除非在同一变更中配置了对应的
    tsconfig.json
    和运行时解析器,否则不要在代码中创建新的别名。
  • 保持变更最小化且聚焦任务:不添加额外功能、顺带重构、临时清理、功能标志、过渡垫片或投机性的前瞻性修改。
  • 在系统边界(用户输入、外部API、配置文件)处使用zod进行输入验证,通过定义Schema来规范预期的数据结构。Zod的
    .safeParse()
    方法提供带自动类型推断的类型安全验证,无需手写验证函数,同时保持类型同步。
  • 保留内部运行时类型检查(
    typeof
    instanceof
    === null/undefined
    )。用zod替换这些检查会增加代码量并带来解析开销,却无任何益处——它们是控制流谓词,而非输入验证。规则是:外部输入契约使用zod,内部类型检查使用
    typeof
    /
    instanceof
  • 保持代码直接:在系统边界处验证输入,遇到无效内部数据时快速失败,不要添加静默回退或不可能场景的处理逻辑。
  • 避免不必要的中间变量:直接返回或传递值,而非赋值给仅使用一次的变量。仅当中间变量能记录非平凡条件、被多次引用,或为提升可读性拆分长调用链时,才使用中间变量。
  • 不要解构函数参数;通过参数对象访问(例如
    input.xxx
    props.xxx
    ),以便每个值的来源一目了然。
  • 当TypeScript可以从表达式、Schema或返回语句中推断类型时,不要创建独立的类型别名或接口;优先依赖类型推断,仅在API边界、共享契约或推断模糊的地方添加显式类型。
  • 仅当辅助函数、钩子、组件或抽象被复用、形成实际边界,或简化大块代码时,才进行提取;除非代码体超过约20行,否则一次性代码保持内联。
  • 用JSDoc记录包的公共导出。当调用方契约不明确时,为共享应用导出添加JSDoc。不要为未修改的代码添加注释、文档字符串或类型注解。
  • 直接删除已确认废弃的代码,不要留下临时标记,例如
    _unused
    重命名、类型重导出或
    // removed
    注释。
  • 在文件过大前,按照实际边界拆分,保持文件行数在约500行以内。
  • vp check --fix
    vp test
    作为交付前的默认验收标准;若其中任一无法运行,需记录原因及已完成的更窄范围验证。

Security And Boundary Checklist

安全与边界检查清单

Use this checklist whenever code handles users, tenants, permissions, secrets, external input, or persistent data.
  • Validate external input at the boundary with
    defineApi
    schemas, HTTP parsing, or the relevant integration adapter.
  • Check whether the API needs current-user, tenant, organization, project, role, or permission scoping before reading or mutating data.
  • Prefer project plugins for auth, tenant, request metadata, and other cross-cutting business context.
  • Return expected client errors with explicit HTTP status codes; reserve unexpected
    500
    failures for internal failures.
  • Do not log secrets, tokens, passwords, cookies, full sensitive payloads, or unredacted third-party responses.
每当代码处理用户、租户、权限、密钥、外部输入或持久化数据时,请使用此检查清单。
  • 在边界处使用
    defineApi
    Schema、HTTP解析或相关集成适配器验证外部输入。
  • 在读取或修改数据前,检查API是否需要当前用户、租户、组织、项目、角色或权限范围限制。
  • 优先使用项目插件处理认证、租户、请求元数据及其他横切业务上下文。
  • 返回带有明确HTTP状态码的预期客户端错误;将意外的
    500
    错误留给内部故障场景。
  • 不要记录密钥、令牌、密码、Cookie、完整敏感负载或未脱敏的第三方响应。

Guidelines

指南

  • Getting Started Guide: Covers the full setup, first feature walkthrough, project structure, key concepts, and daily workflow for new developers and new projects.
  • Curated Stack Guide: Covers the Rails-inspired default stack, official React/Ant Design/PostgreSQL path, plugin extension boundaries, auth/permission scope, and replacement rules.
  • Application Slices Guide: Covers vertical UI/API/database/test slices, recommended file layout, agent workflow, and why FaasJS avoids generator-heavy development.
  • Ant Design Guide: Covers
    @faasjs/ant-design
    page structure, routing, CRUD composition, feature-local APIs, and UI feedback patterns.
  • File Conventions: Covers where to place pages, components, hooks, and
    .api.ts
    files, plus when separate files are worth creating.
  • Code Comments Guide: Covers package public JSDoc expectations, caller contract conventions, when shared app exports need docs, and how to explain non-standard code without narrating it line by line.
  • Node Utils Guide: Covers Node-only helpers for env/config loading, function and plugin bootstrapping, module loading, and shared logging.
  • Project Config Guide: Covers how to keep
    tsconfig.json
    ,
    vite.config.ts
    , and shared tooling config aligned with FaasJS defaults.
  • CLI and Tooling Guide: Covers the FaasJS CLI, Vite Plus commands, project scaffolding, migrations, type generation, testing, common errors, and environment variables.
  • Testing Guide: Covers shared testing principles such as choosing test level, keeping mock boundaries narrow, and avoiding unnecessary mocks.
  • React Guide: Covers React component and hook patterns in FaasJS, especially avoiding native
    useEffect
    and handling non-primitive dependencies safely.
  • React Data Fetching Guide: Covers when to use
    useFaas
    ,
    useFaasStream
    ,
    faas
    , or wrapper components, and how to handle loading, error, and retry states.
  • React Testing Guide: Covers request-related React testing with
    setMock
    , shared cleanup,
    jsdom
    , and common request-flow scenarios on top of the shared Testing Guide.
  • defineApi Guide: Covers building
    .api.ts
    endpoints with
    defineApi
    , inline schemas, typed
    params
    , error handling, and validation expectations.
  • Jobs Guide: Covers
    .job.ts
    files,
    defineJob
    ,
    enqueueJob
    , workers, scheduler cron enqueueing, retries, idempotency, and testing.
  • Logger Guide: Covers when to reuse injected loggers versus creating
    Logger
    instances, how to choose log levels, and how to time slow operations.
  • Naming Convention Guide: Covers identifier naming (camelCase/PascalCase), file/directory naming, abbreviation rules, and cross-package naming consistency.
  • Plugins Guide: Covers the
    Plugin
    interface, lifecycle methods (
    onMount
    /
    onInvoke
    ), injecting fields via
    DefineApiInject
    , config-driven loading through
    faas.yaml
    , manual registration in code, config merging precedence, and plugin testing.
  • CRUD Patterns Guide: Covers the complete CRUD vertical slice — shared items metadata, list/detail/create/update/delete patterns, testing, and agent efficiency tips for faster page generation.
  • Utils Guide: Covers portable helpers from
    @faasjs/utils
    for deep merging and converting text or JSON to and from streams.
  • PG Query Builder and Raw SQL Guide: Covers preferring
    QueryBuilder
    clauses, choosing raw SQL fallbacks deliberately, keeping client bootstrap consistent, and narrowing row shapes intentionally.
  • PG Table Types Guide: Covers declaration merging on
    Tables
    , concrete row shapes, and keeping query inference aligned with table definitions.
  • PG Schema and Migrations Guide: Covers timestamped migrations,
    SchemaBuilder
    ,
    TableBuilder
    , and transactional schema changes.
  • PG Testing Guide: Covers
    PgVitestPlugin()
    , shared
    DATABASE_URL
    bootstrap, and pairing runtime assertions with
    expectTypeOf(...)
    .
  • 入门指南:涵盖完整设置流程、首个功能演练、项目结构、核心概念及日常工作流,适用于新开发者和新项目。
  • 精选技术栈指南:涵盖受Rails启发的默认技术栈、官方React/Ant Design/PostgreSQL路径、插件扩展边界、认证/权限范围及替换规则。
  • 应用切片指南:涵盖垂直UI/API/数据库/测试切片、推荐文件布局、Agent工作流,以及FaasJS为何避免重度依赖生成器的开发方式。
  • Ant Design指南:涵盖
    @faasjs/ant-design
    页面结构、路由、CRUD组合、功能本地API及UI反馈模式。
  • 文件约定:涵盖页面、组件、钩子及
    .api.ts
    文件的存放位置,以及何时值得创建单独文件。
  • 代码注释指南:涵盖包公共JSDoc的要求、调用方契约约定、共享应用导出何时需要文档,以及如何解释非标准代码而无需逐行叙述。
  • Node工具指南:涵盖仅适用于Node的辅助工具,包括环境/配置加载、函数和插件引导、模块加载及共享日志。
  • 项目配置指南:涵盖如何使
    tsconfig.json
    vite.config.ts
    及共享工具配置与FaasJS默认设置保持一致。
  • CLI与工具指南:涵盖FaasJS CLI、Vite Plus命令、项目脚手架、迁移、类型生成、测试、常见错误及环境变量。
  • 测试指南:涵盖共享测试原则,例如选择测试层级、缩小模拟边界及避免不必要的模拟。
  • React指南:涵盖FaasJS中的React组件和钩子模式,尤其强调避免原生
    useEffect
    及安全处理非原始依赖。
  • React数据获取指南:涵盖何时使用
    useFaas
    useFaasStream
    faas
    或包装组件,以及如何处理加载、错误和重试状态。
  • React测试指南:涵盖使用
    setMock
    进行请求相关的React测试、共享清理、
    jsdom
    ,以及在共享测试指南基础上的常见请求流场景。
  • defineApi指南:涵盖使用
    defineApi
    构建
    .api.ts
    端点、内联Schema、带类型的
    params
    、错误处理及验证要求。
  • 任务指南:涵盖
    .job.ts
    文件、
    defineJob
    enqueueJob
    、工作进程、调度器定时入队、重试、幂等性及测试。
  • 日志器指南:涵盖何时复用注入的日志器与创建
    Logger
    实例、如何选择日志级别,以及如何记录慢操作的耗时。
  • 命名约定指南:涵盖标识符命名(camelCase/PascalCase)、文件/目录命名、缩写规则及跨包命名一致性。
  • 插件指南:涵盖
    Plugin
    接口、生命周期方法(
    onMount
    /
    onInvoke
    )、通过
    DefineApiInject
    注入字段、通过
    faas.yaml
    实现配置驱动加载、代码中的手动注册、配置合并优先级及插件测试。
  • CRUD模式指南:涵盖完整的CRUD垂直切片——共享项元数据、列表/详情/创建/更新/删除模式、测试,以及提升Agent页面生成效率的技巧。
  • 工具函数指南:涵盖
    @faasjs/utils
    中的可移植辅助函数,包括深度合并、文本或JSON与流之间的转换。
  • PG查询构建器与原生SQL指南:涵盖优先使用
    QueryBuilder
    子句、谨慎选择原生SQL回退、保持客户端引导一致,以及有意缩小行数据结构。
  • PG表类型指南:涵盖
    Tables
    上的声明合并、具体行数据结构,以及保持查询推断与表定义一致。
  • PG Schema与迁移指南:涵盖带时间戳的迁移、
    SchemaBuilder
    TableBuilder
    及事务性Schema变更。
  • PG测试指南:涵盖
    PgVitestPlugin()
    、共享
    DATABASE_URL
    引导,以及将运行时断言与
    expectTypeOf(...)
    结合使用。