@ carecard/ 常见用户
1.1.1版和生产数据
CareCard Release 1.1.1是生产基准. 种子为
--seed-release-data 已经完成。 生产集群数据、数据库行、,
并保存存储的用户文件。 没有
完成用户数据擦拭和再创建.
未来生产变化必须使用数据保存迁移。 不重播 完成初始化或运行重置、回滚或种子工作流程 常规生产部署.
这个 已完成的种子库存和核查记录 记录所接受的释放基准和核查限制.
不可转让的测试令不规则:每一次测试必须独立通过之前或之后的测试,每一次执行指令的套房都必须通过. 每个测试必须建立它所需要的状态,隔离可变状态,并清理它拥有的状态;它绝不能依赖另一个测试的设置,突变,或清理. 默认测试,CI,和Husky命令必须使用测试框架的普通命令,不得强迫随机命令. 随机顺序执行只是一种明确的诊断,它所暴露出的每一出故障都必须被固定在根源上.
不可谈判的"根源-原因"解决方案规则:总是识别并解决已核实的根源,使用更强的解决方案,并给出正确,持久,生产质量的结果. 绝不将临时工作、资源增加、重试、压制、绕行或只表现的补丁视为补丁。 验证根-原因 固定真实失败的工作流程 并证明结束状态.
标准化的API响应系统,请求上下文中件,以及Express.js和Next.js微服务的公用功能.
运行时间要求
使用节点.js 24.210. 软件包接受兼容的 Node.js 释放 24.21.0 直至(但不包括)节点 25.
发展规则
不可转让的TDD规则:总是先写出失败的测试,运行以确认它因预期原因失败,然后执行代码并重跑测试直到通过. 所有编码工作都需要测试驱动开发,不得跳过. 仅用于文档或技能编辑,运行相关的焦点非测试 更改道词前验证; 不添加检查的自动测试 出品人、文件或寄存器结构.
不可转让寄存器隔离规则:每个寄存器必须只使用寄存器内包含的文件,代码,定着物,依赖以及服务来运行其Husky钩和测试. 测试和Husky脚本不得导入,要求,阅读,执行,或以其他方式依赖寄存器根外的兄弟姐妹寄存器或路径. app-e2e-测试是唯一的例外,因为交叉存储端到端测试是其明确的责任.
不可转让错误和警告规则:从不压制,沉默,隐藏,降级,过滤,忽略,跳过,或绕过代码,测试,工具,编译器,linters,或验证错误或警告. 修补根源,再重新运行受影响的检查并需要干净的结果. 预期出错路径测试可能断言出错,但绝不能掩盖出乎意料的失败.
不可转让类型脚本类型规则: 永远不要使用类型脚本类型 any; 总是使用特定域类型、通用项目类型、现有项目类型,或 unknown 在所有类型Script- family文件中明确缩小(.ts, (中文(简体) ), .tsx, (中文(简体) ), .mts, (中文(简体) ), .cts,以及 .d.ts) (中文(简体) ).
非可转让代码组织规则:具有相同或等同行为的函数必须在整个CareCard寄存器中使用相同或明显对应的描述性名称,等同的功能必须活在每个寄存器既定架构中同名的文件中. 不允许向后兼容名称,别名,或重复位置.
特征
- 标准反应格式:所有API响应的一致JSON结构.
- 请求上下文中间软件: 自动生成服务所有者
requestId和 W3C 跟踪元数据. - 分布式追踪支持:通过W3C进行基于标准的传播
traceparent。 。 。 . - 结构化应用程序日志:无依赖性 NDJSON 有编辑,关联,和有边框的开发文件.
- 类型安全: 包含类型定义的完整类型脚本支持.
- 下一位.js 兼容性( Express): 在不同节点.js框架之间无缝工作.
- 微服务准备:用于服务识别,环境和版本的内置元数据.
安装
npm install @carecard/common-util
使用量
运通.js
设置中间软件
const express = require('express');
const { requestContext } = require('@carecard/common-util');
const app = express();
// Attach request context (generates a local requestId and continues or creates a W3C trace)
app.use(requestContext);
呼叫另一处
const { createTracePropagationHeaders } = require('@carecard/common-util');
const response = await fetch('http://ms-auth/api/v1/app-auth/server-auth/jwt/introspect', {
method: 'POST',
headers: {
...createTracePropagationHeaders(),
authorization: serviceAuthorization,
},
});
createTracePropagationHeaders() 通过使用
作为下游父母的当前服务期。 它返回一个空对象
当调用外部请求上下文时.
发送回复
const { sendResponse } = require('@carecard/common-util');
app.get('/api/users', (req, res) => {
const users = [{ id: 1, name: 'John Doe' }];
return sendResponse({
req,
res,
message: 'Users fetched successfully',
data: users,
meta: {
pagination: { page: 1, limit: 10, total: 1 },
},
});
});
标准化错误处理
const { error } = require('@carecard/common-util');
const { appErrorHandler, notFound404, throwRecordNotFoundError } = error;
const app = require('express')();
// Usage in controllers
app.get('/api/users/:id', (req, res) => {
const user = null;
if (!user) {
throwRecordNotFoundError({ userMessage: 'User not found' });
}
});
// Handle 404s
app.use(notFound404);
// Central error handler
app.use(appErrorHandler);
Next.js (API 路线)
Java 脚本示例
// pages/api/hello.js
import { sendResponse } from '@carecard/common-util';
export default function handler(req, res) {
return sendResponse({
req,
res,
message: 'Hello from Next.js!',
data: { greeting: 'Welcome' },
});
}
类型脚本示例
// pages/api/hello.ts
import type { NextApiRequest, NextApiResponse } from 'next';
import { sendResponse } from '@carecard/common-util';
export default function handler(req: NextApiRequest, res: NextApiResponse) {
return sendResponse({
req,
res,
message: 'Typed response',
data: { status: 'ok' },
});
}
API 参考
浏览器安全验证支持
浏览器代码和共享验证包必须导入大小写转换和 输入错误从他们的焦点切入点。 这些入境点保留了 相同的公开行为而不装入根包的服务器请求 上下文和微量存储 :
const { keysToSnakeCase } = require('@carecard/common-util/case-converter');
const { throwBadInputError } = require('@carecard/common-util/errors');
大小写转换将嵌入的 JSON 属性保存为可假设的自有数据
属性。 保存的外观密钥, 如 __proto__, (中文(简体) ), constructor,以及
prototype 不创建继承的财产。 保留可扩展元数据为
数据; 绝不使用其显示值作为授权或可执行输入.
集中应用程序记录
从其专用子路径导入仅服务器日志合同, 所以浏览器 捆绑从来不包括Node.js文件系统或加密模块:
const {
createApplicationLogger,
createHttpRequestLogger,
installFatalProcessLogging,
} = require('@carecard/common-util/logging');
const logger = createApplicationLogger({
service: 'ms-example',
serviceVersion: process.env.MS_VERSION,
});
app.use(createHttpRequestLogger(logger));
installFatalProcessLogging(logger);
每一次通话都会发出一个版本的NDJSON记录. 制作符合标准
用于平台收集的输出或标准错误。 发展也
写入 logs/application.ndjson 并保留两个旋转的文件;每个文件是
以 10 MiB 为界。 配置 LOG_FILE_PATH, (中文(简体) ), LOG_LEVEL,以及
LOG_IDENTITY_HMAC_KEY 通过运行时的环境.
LOG_IDENTITY_HMAC_KEY 强制的,必须包含至少32个字符
生产。 日志绝不包含原始用户ID、电子邮件地址、 IP
地址 用户代理字符串 授权材料 饼干 秘密,
符号、请求正文、信头或查询字符串。 用户身份是
HMAC-SHA256 假名,以及其他敏感值在修改之前
连载化。 在同一环境中保持相同的 HMAC 密钥
授权的操作员可以在不恢复源代码的情况下连接一个演员.
installFatalProcessLogging 使用节点.js uncaughtExceptionMonitor;它观察到
致命错误, 不安装例外处理器或更改进程
坠机合同.
读取/写入路由
导入纯服务器路由合同
@carecard/common-util/postgres-routing它拥有三个独立边界
申请程序集合:11个主写连接,8个
复制-读取连接,以及1个只读主倒置连接. 这个
总上限为20个。 仅主数据库工作明确使用
更小的游泳池 从来不建一个复制池.
呼叫者宣布可复制的作品 runReplicaRead; 缺少意图,
写作、迁移、锁和对一致性敏感的读取仍为主
默认. runPrimaryWrite 做一个嵌入式执行上下文 主粘接,所以
以后的工作不能回到复制品。 交易必须获得一个客户
在选择上下文后,保留该客户端,直至承诺或撤回.
复制会话是初始化的 仅读并检查恢复角色, 暂停重播, 并在每次租借前出现字节滞后 。 经核实的发送前 可用性或滞后故障可能获得一个连接只读的初级 倒倒倒相池. 认证、授权、配置和发送 查询失败已关闭, 并且永远不会重播 。 30秒的物理状态 连接寿命让Kubernetes在所有健康的人中分配新会话 读取服务后面的终点.
连接所有权跟随每次检查的释放边界 。 返回或 销毁一个再利用的连接,将它从关闭所有权中移除,并关闭 以后关闭时, 连接永远不会被保留 。 调用已使用 释放后,新出厂的租约完好无损,保留了pg的错误.
路由器按集合角色、查询显示连接计数的 Prometheus 文本 路由,复制获得失败,主倒置,角色不匹配, 电路状态,观察器失败, 和域名报告 stale 读取。 供应 结构化会话和倒计时活动的伐木观察员;从未附加SQL, 证书、主机名或这些活动的个人资料.
sendResponse({ req, res, statusCode, success, code, message, data, error, details, pagination, meta })
发送标准化JSON响应.
requestContext(req, res, next)
附带的中件 :
req.requestId: 服务拥有的UUID v4是此服务请求独有的.req.traceId: W3C 追踪ID 继续从traceparent或新生成.req.spanId:当前服务跨ID.req.parentSpanId: 提供上游间距为ID.req.traceFlags:W3C痕量旗.req.client: 含有appId(从)x-app-id和ip。 。 。 .
要求的ID永远不会被接受为跨服务关联识别符. 使用 w3C追踪识别码以链接到各服务部门的回应和集中记录.
使用 Express , 客户端IP 元数据遵循应用程序的可信任代理
决议。 无法用转发信头替换不信任的套接字地址
通过错误的IPv6信任子网. 保持快捷树的依赖性
proxy-addr 2.0.8 或以后;HTTP回归还核实了正确的范围
信任的转发 .
createError({ code, message, details, fields })
帮助创建标准化错误对象 sendResponse。 。 。 .
标准反应结构
{
"success": true,
"status": "success",
"statusCode": 200,
"code": "OK",
"message": "Success message",
"data": { ... },
"error": null,
"details": null,
"meta": {
"version": "1.0.0",
"service": "my-service",
"environment": "production",
"timestamp": "2024-03-26T00:00:00.000Z",
"requestId": "...",
"traceId": "...",
"client": { "appId": "...", "ip": "..." }
}
}
环境变量
API_VERSION: 用于meta.version(默认 :1.0.0(中文(简体) )SERVICE_NAME: 用于meta.service(默认 :unknown-service(中文(简体) )NODE_ENV: 用于meta.environment(默认 :development(中文(简体) )LOG_LEVEL: 最低结构对数严重性(debug, (中文(简体) ),info, (中文(简体) ),warn,或error(中文(简体) )LOG_FILE_PATH开发 NDJSON 位置LOG_IDENTITY_HMAC_KEY: 用于单向用户身份假名的共享秘密
Auth and RLS 出错边界
反应和出错帮助者暴露出稳定的HTTP技术合同. 呼叫者
自有认证、授权、数据库政策和商业错误
选择。 软件包从不解释自定义的符号要求或角色代码.
答复不得披露全权证书、查询文本或私人来电者的背景.
使用 SQLSTATE 的 PostgreSQL RLS 失败 42501 报告为
NOT_AUTHORIZED 带有面向用户的消息
Not permitted to perform the action 并且没有回复的细节.
软件包独立
该图书馆独立于服务和应用业务规则. 它拥有 可重复使用的响应、错误、记录、跟踪、大小写转换和PostgreSQL 出行机制. 呼叫者提供数据和配置;服务计划, 角色、权限、路线和工作流程政策都由所有者决定.
许可证
公务员制度委员会
测试周期审计失败
当前的软件包测试没有 HTTP 听取器,数据库池, Kafka 客户端, 背景计时器,或完成后的儿童进程。 Mocha的测试超时失败 一个停滞的aync测试, 套房运行 没有保释或强制退出,和npm 保留每个命令的非零状态。 将自然进程退出作为打开 处理回归检查; 校验不能用重复操作隐藏失败, 强制 成功,跳过测试,或输出抑制.
不将未发布的可执行验证代码添加到一个 pkg-* 仓库。 如果有的话
未来测试拥有长寿资源, 或显示套期后悬挂, 添加一个
通过协调软件包版本对合同过程进行监督,
以及消费者传播工作流程。 那个看门人必须回来
当没有帮助者留下时, 立即只允许一个250ms的边界定居点
窗口,用于已停止的帮助者,失败的持久性后人,保存
失败和输出, 使用退出代码 124 仅限真实的外延期限
仍然是最后的后卫,而不是替代明确的清理.
TDD 认证
测试驱动开发是一项不可谈判的要求.
自动测试的唯一目的是验证可观察到的功能和外部可见的行为. 测试必须验证系统通过其公共界面和预期结果所做的工作.
测试不得坚持、检查或依赖实施细节,包括但不限于:
- 存在代码,语句,函数,类,文件或模块等特定行.
- 具体的算法,控制流,可变名称,方法调用,代码片段,或内部执行选择.
- 任何可以改变而不改变外部可观察到的行为的内部结构.
正确的执行可以完全重写或重构而不需要更改功能测试,只要其外部可观察到的行为保持不变.
仅仅因为执行发生变化而外部观察到的行为仍然正确而未能成功的任何测试都是错误设计的,必须重写或去除.
这一要求对所有新的试验都是强制性的,在修改现有试验时必须适用.