羊田包装工
为 Felloh 无服务器项目提供核心功能的共享库,包括依赖注入,记录,请求处理,数据库实体,以及AWS Lambda函数的响应模型.
安装
npm install @felloh-org/lambda-wrapper
# or
yarn add @felloh-org/lambda-wrapper
快速启动
import { LambdaWrapper, DEFINITIONS, ResponseModel } from '@felloh-org/lambda-wrapper';
const configuration = {
SERVICE_NAME: 'my-service',
};
export const handler = LambdaWrapper(configuration, async (di, request) => {
const logger = di.get(DEFINITIONS.LOGGER);
const warehouse = di.get(DEFINITIONS.WAREHOUSE);
logger.info('Processing request');
// Your handler logic here
return new ResponseModel({ message: 'Success' }, 200).generate();
});
羊田包装工
核心包装器函数取一个配置对象和一个处理器函数,返回一个Lambda相容函数与内置的依赖性注入,错误处理,记录,和度量衡相匹配.
import { LambdaWrapper } from '@felloh-org/lambda-wrapper';
const handler = LambdaWrapper(configuration, async (di, request, callback) => {
// di - DependencyInjection container with all services
// request - RequestService instance with parsed request data
// callback - Lambda callback (for non-async handlers)
});
处理器模式
Async 处理器( 建议):
export const handler = LambdaWrapper(config, async (di, request) => {
const response = new ResponseModel({ result: 'ok' }, 200);
return response.generate();
});
回调处理器 :
export const handler = LambdaWrapper(config, (di, request, callback) => {
const response = new ResponseModel({ result: 'ok' }, 200);
callback(null, response.generate());
});
丢出错误作为回复 :
export const handler = LambdaWrapper(config, async (di, request) => {
const params = request.getAll();
if (!params.email) {
const error = new ResponseModel({}, 422);
error.addError({
title: 'Validation Error',
message: 'Email is required',
});
throw error; // Returns a 422 response, not a 500
}
// continue processing...
});
处理错误
包装器自动捕获出错并返回适当的响应 :
- 弹出反应模式 - 返回当前响应(例如400、404、422)
- 抛出 Lambda 终结 - 使用错误返回回复
code属性 - 未处理错误 - 返回500个回复并记录出错
- 数据库大小限制出错 - 返回413个响应
5xx错误自动被记录;4xx错误没有.
温暖支持
包装手柄 无服务器插件加热 自动事件。 当检测到暖和事件时, 处理器会立即返回而不执行您的代码 .
依赖性注射系统
每个操作员都会收到 DependencyInjection 作为第一个参数。 该集装箱提供内置服务及您注册的任何定制服务.
内设服务
| 服务 | 定义 | 说明 |
|---|---|---|
| 锁定器 | DEFINITIONS.LOGGER | 与温斯顿和巴塞利姆进行结构化伐木 |
| 请求 | DEFINITIONS.REQUEST | 解析 HTTP 请求数据 |
| 仓库 | DEFINITIONS.WAREHOUSE | TypeORM 数据库连接管理器 |
| 认证 | DEFINITIONS.AUTHENTICATION | 用户作用和组织检查 |
| 用户 | DEFINITIONS.USER | 目前来自Cognitto JWT索赔的用户 |
| 事件桥 | DEFINITIONS.EVENT_BRIDGE | AWS 事件Bridge 事件发布 |
| 秘诀 | DEFINITIONS.SECRETS | AWS 有缓存的秘密管理器 |
| HTTP 密码 | DEFINITIONS.HTTP | 基于 Axios 的 HTTP 客户端 |
| 网页 | DEFINITIONS.WEBHOOK | HMAC 签名的 Webhook 发送 |
| 审计 | DEFINITIONS.AUDIT_LOGGER | 通过 EventBridge 创建审计活动 |
| 支付启动对象 | DEFINITIONS.PAYMENT_INITIATION_OBJECT | 支付联系和电子商务查询 |
| 追踪 | DEFINITIONS.TRACING | OpenTeleometry 跨度和属性, 导出到 Honeycomb |
自定义服务
通过扩展创建自定义服务 DependencyAwareClass数字 :
import { DependencyAwareClass, DEFINITIONS } from '@felloh-org/lambda-wrapper';
class PaymentProcessor extends DependencyAwareClass {
async processPayment(transactionId) {
const logger = this.getContainer().get(DEFINITIONS.LOGGER);
const warehouse = this.getContainer().get(DEFINITIONS.WAREHOUSE);
const connection = await warehouse.connect();
const repo = connection.getRepository(TransactionEntity);
const transaction = await repo.findOne({ where: { id: transactionId } });
logger.info(`Processing payment ${transactionId}`);
return transaction;
}
}
在配置中注册自定义服务 :
const configuration = {
DEPENDENCIES: {
PAYMENT_PROCESSOR: PaymentProcessor,
},
};
export const handler = LambdaWrapper(configuration, async (di, request) => {
const processor = di.get('PAYMENT_PROCESSOR');
await processor.processPayment('txn_123');
});
集装箱 API
// Get a service
const logger = di.get(DEFINITIONS.LOGGER);
// Get the raw Lambda event
const event = di.getEvent();
// Get the Lambda context
const context = di.getContext();
// Get configuration values
const config = di.getConfiguration(); // full config
const dbHost = di.getConfiguration('DB_HOST'); // specific key, returns null if missing
// Check if running in serverless-offline
if (di.isOffline) {
// local development mode
}
服务
请求服务
解析并提供所有HTTP请求数据的访问权限.
const request = di.get(DEFINITIONS.REQUEST);
// Get a single parameter (checks query params for GET, body for POST)
const email = request.get('email');
const page = request.get('page', '1'); // with default value
// Get all parameters
const allParams = request.getAll();
// Force reading from query string regardless of HTTP method
const queryParams = request.getAll('GET');
// Path parameters
const id = request.getPathParameter('id');
const allPath = request.getPathParameter(); // all path params
// Headers (case-insensitive)
const contentType = request.getHeader('Content-Type');
const allHeaders = request.getAllHeaders();
// Authorization
const token = request.getAuthorizationToken(); // extracts Bearer token
// Client info
const ip = request.getIp();
const browser = request.getUserBrowserAndDevice(); // parsed user-agent
// AWS event records (SQS, SNS, etc.)
const record = request.getAWSRecords();
内容类型支持 :
请求服务根据 Content-Type 页眉 :
application/json- JSON分析application/x-www-form-urlencoded- 表格数据解析text/xml- XML 通过 xml2js 解析multipart/form-data- 以缓冲支持的文件上传解析
请求验证 :
const constraints = {
email: { presence: true, email: true },
amount: { presence: true, numericality: { greaterThan: 0 } },
start_date: { datetime: { dateOnly: true } },
};
await request.validateAgainstConstraints(constraints);
// Resolves on success, rejects with a 422 ResponseModel on failure
审定用途 验证.js 与日期支持 通过瞬间.
Logger 服务
结构化伐木与温斯顿和巴塞利姆集成. 漂亮的打印输出在服务器无线模式下.
const logger = di.get(DEFINITIONS.LOGGER);
// Standard logging
logger.info('Payment processed successfully');
logger.error(new Error('Connection failed'));
logger.warning(error); // routes to error() or info() based on LOGGER_SOFT_WARNING env
// Labels (lightweight markers for tracing)
logger.label('payment-initiated');
logger.label('silent-label', true); // silent = not logged to console
// Metrics
logger.metric('response_time', 250);
logger.metric('ip_address', '10.0.0.1', true); // silent = not logged to console
// Object inspection
logger.object('Processing payload', { id: 1, amount: 500 });
logger.object('Failed response', errorObj, 'error'); // supports 'info', 'warning', 'error'
Axios 错误会自动调整到 config, (中文(简体) ), message, (中文(简体) ), response.status,以及 response.data - 从日志中取出动词请求/标题数据.
追踪服务( 蜂窝站 / OpenTeleometry)
每件被包裹的引用都用OpenTeleometter来追踪,并用OTLP/HTTP来导出至Honeycomb. 追踪是 关闭,除非 HONEYCOMB_API_KEY 设定 - 没有它,OpenTeleometry API 推出非记录跨度,所以服务可以无条件叫这些帮助者.
每一次引用你得到的, 没有代码更改的服务:
- 以触发器命名的一个根跨( q)
POST /organisations/{id},事件桥detail-type, (中文(简体) ),aws:sqs <function>),携带faas.invocation_id, (中文(简体) ),faas.coldstart, (中文(简体) ),faas.trigger,HTTP方法/路线/路径/客户IP/用户代理,http.response.status_code,以及felloh.request_id从ResponseModel体质; - 每个孩子的跨度
HTTPService.request()调用( n)HTTP POST,与server.address, (中文(简体) ),url.path和响应状态; 查询字符串从未被记录); - 每个
logger.error()记录为活动期间的例外事件。 记录出错并仍然返回 2xx 的处理器保留出错的追踪,所以"没有失败请求的错误"仍然可以查询; 2; - 5xx 回复并投出错误标记此间距为错误
error.type· ; - 处理器返回前明确冲出(Lambda在之后立即冻结进程),以
HONEYCOMB_FLUSH_TIMEOUT_MS。 。 。 .
const tracing = di.get(DEFINITIONS.TRACING);
// Add business context to the invocation span - the fields you will actually query by
tracing.setAttributes({ organisation_id: organisation.id, transaction_id: transaction.id });
// Wrap a unit of work in a child span
const score = await tracing.withSpan('risk.score', async (span) => {
span.setAttribute('model', 'laya');
return scorer.score(narrative);
});
tracing.isEnabled(); // true when spans are being exported
tracing.getTracer(); // raw OpenTelemetry tracer for anything else
错误细节: 跨度足够查找断层
当引用失败(推错,4xx/5xx回复,或记录在请求中的错误)时,引用跨度会带平坦可查询的字段,这样一个人或AI就可以将问题从Honeycomb中缩小:
| 外地 | 它告诉你什么 |
|---|---|
faas.handler, (中文(简体) ), code.function | Lambda 处理器出口handler.signup)和被包裹的函数的名称(Signup),即要打开的文件 |
aws.log.group.names, (中文(简体) ), aws.log.stream.names, (中文(简体) ), aws.xray.trace_id, (中文(简体) ), faas.invocation_id | 恰好在云表记录中 |
error.type, (中文(简体) ), error.message, (中文(简体) ), error.stack, (中文(简体) ), error.code, (中文(简体) ), error.cause | 投出的错误, 堆放于 4 KB |
db.query.text, (中文(简体) ), db.query.parameters, (中文(简体) ), db.response.status_code, (中文(简体) ), db.error.detail, (中文(简体) ), db.error.position, (中文(简体) ), db.error.constraint, (中文(简体) ), db.error.table, (中文(简体) ), db.error.hint | 对于 TypeORM/ Postgres 失败: 准确的语句、其(已编辑) 参数和 SQLSTATE 细节 |
felloh.upstream.method, (中文(简体) ), felloh.upstream.url, (中文(简体) ), felloh.upstream.status_code, (中文(简体) ), felloh.upstream.response_body | 给服务商或其他服务商打不通的电话 被叫的是什么 回来的是什么 |
felloh.response.errors | 这个 errors[] 阵列返回 API |
enduser.id, (中文(简体) ), felloh.request.path_parameters, (中文(简体) ), felloh.request.query, (中文(简体) ), felloh.request.body | 谁打电话和什么。 车体被编辑(密码、信使、卡片号码、IBAN、排序代码和相近的密钥被替换)并被封为4 KB |
faas.remaining_time_ms, (中文(简体) ), faas.timeout_imminent | 期末剩余预算;因超时监督而关闭的时间段 faas.timeout_imminent = true |
service.version | 管道提供时部署的承诺 GIT_SHA, (中文(简体) ), COMMIT_SHA 或者说 SERVICE_VERSION |
Honeycomb 数据集定义
Honeycomb 的 Home, 服务映射和出错率特性绑定在下面选择的字段 数据集设置 – 定义。包装器为每一个都发出一个字段;当Honeycomb问:
| 定义 | 将包裹寄出 | 页:1 |
|---|---|---|
| 错误 | error | 一个短 Type: message 每个失败跨度上的字符串: 5xx 响应, 无 HTTP 结果的抛出, 通过登录的错误 logger.error()或者超时监视器 缺少健康跨度和4xx反应,包括处理者投出404分和422分 Response; 保持跨度状态未设并仍然携带 felloh.response.errors。 。 。 . |
| HTTP 状态代码 | http.response.status_code | 当前 OpenTelemotry 名称; Honeycomb 的默认猜想是旧的 http.status_code,所以明确选择. |
| 路线 | http.route | API Gateway资源,例如:. /organisations/{id}。 。 。 . |
| 用户 | enduser.id | 当请求被认证时,来自授权方的Cognitto用户ID. |
| 姓名、服务名称、持续时间、追踪/扫描/父母身份证 | name, (中文(简体) ), service.name, (中文(简体) ), duration_ms, (中文(简体) ), trace.trace_id, (中文(简体) ), trace.span_id, (中文(简体) ), trace.parent_id | 由Honeycomb 的 OTLP 摄入; 无选择 . |
| 元数据: 注释类型 | meta.annotation_type | span_event 对于例外的事件,我们发出, link 为跨度链接。 一旦这些数据到达,由OTLP摄入. |
| 元数据: 链接 Span ID / 链接跟踪 ID | trace.link.span_id, (中文(简体) ), trace.link.trace_id | 由OTLP 摄入填充; 包件今天不创建链接 . |
| 日志: 严重性 | severity | 在包装的例外事件,总是 error。 。 。 . |
| 日志: 消息 | message | 显示包装的例外事件: 日志上下文加错误消息 。 标准 exception.message 还送来了. |
包装器只发送痕迹,所以两个日志定义绑定在跨事件上,而不是单独的日志流上.
两种行为值得了解:
- 超时监视器. 击出超时的Lambda在代码运行前被杀死 所以不会留下任何痕迹 在截止时间(剩余时间减去冲出时间和小差)之前不久,包装器将引用时段作为错误关闭,标记它
faas.timeout_imminent,并输出它。 如果接线员完成后, 横幅会保持原样 . - 请求捕捉尸体 如下
HONEYCOMB_CAPTURE_REQUEST数字 :errors(默认)只将修改后的身体附在无效的引用上,always把它固定在每一行间,off从来没有寄出去。 路径参数和查询字符串总是被记录(已编辑).
配置(每个服务在 serverless.yml provider.environment,输油管值:
| 变量 | 默认 | 目的 |
|---|---|---|
HONEYCOMB_API_KEY | 未设置( 跟踪关闭) | Honeycomb 摄入键。 设定它可以追踪. |
HONEYCOMB_API_ENDPOINT | https://api.honeycomb.io | 使用 https://api.eu1.honeycomb.io 给欧盟的团队. |
OTEL_SERVICE_NAME | SERVICE_NAME函数名称 | Honeycomb 每个服务名称创建一个数据集. |
HONEYCOMB_DATASET | 未设定 | Honeycomb Classic;基于环境的团队会让它不设. |
HONEYCOMB_SAMPLE_RATE | 1 | 在根部保留1个N的痕迹. 纸币携带 SampleRate 所以Honeycomb重磅计数。 头部采样不能看到出错,所以保持1,直到体积强. |
HONEYCOMB_FLUSH_TIMEOUT_MS | 2000 | 在每次引用中都添加了导出时的上行键等值 . |
HONEYCOMB_CAPTURE_REQUEST | errors | 附加已编辑的请求正文时 : errors, (中文(简体) ), always 或者说 off。 。 。 . |
GIT_SHA 编号 : COMMIT_SHA 编号 : SERVICE_VERSION | Lambda 函数版本 | 报为 service.version,所以一个追踪名称 部署的承诺。 把它从管道. |
资源属性来自Lambda环境: service.name, (中文(简体) ), service.version, (中文(简体) ), deployment.environment.name (单位:千美元)STAGE, (中文(简体) ), cloud.region, (中文(简体) ), faas.name, (中文(简体) ), faas.version, (中文(简体) ), faas.max_memory。 。 。 .
注释:
- 供养者为容器的生命而活;温取再用.
Tracing.reset()泪下 (测试). - 出口者是一个普通的HTTPS呼叫Honeycomb,所以在寒冷的起步中增加了几百毫秒,并且大致是每次引用的冲出回程. 遥测失败被记录下来,并且永远不会失败请求.
- 如果Lambda地层已经注册了一个全局追踪器提供商,它就赢了;包装器的提供商则只冲出一个空缓冲器.
仓库服务
管理连接缓存中的 TypeORM 数据库连接 .
const warehouse = di.get(DEFINITIONS.WAREHOUSE);
// Get a connection (cached by default)
const connection = await warehouse.connect();
// Force a new connection (bypass cache)
const fresh = await warehouse.connect(null, false);
// Connect to a specific database
const analytics = await warehouse.connect('analytics_db');
// Health check
await warehouse.status();
连接类型 :
通过 WAREHOUSE_TYPE 环境变量 :
postgres- 直接使用 PostgreSQL 连接WAREHOUSE_HOST, (中文(简体) ),WAREHOUSE_USERNAME, (中文(简体) ),WAREHOUSE_PASSWORD, (中文(简体) ),WAREHOUSE_DATABASEpostgres-ssm- 使用AWS保密管理器获取的证书DB_CREDS_ARN
认证 服务
检查用户角色和组织访问. Lazy-初始化了第一次使用时的数据库连接 .
const auth = di.get(DEFINITIONS.AUTHENTICATION);
await auth.init();
// Check organisation access and roles in one call
// Throws a 401 ResponseModel if checks fail
await auth.checkUserRoles('org-123', ['admin', 'finance']);
// Check organisation access only
await auth.checkUserRoles('org-123');
// Check roles only
await auth.checkUserRoles(null, ['admin']);
// Individual checks
const roles = await auth.fetchUserRoles(); // ['admin', 'viewer']
const hasAdmin = await auth.hasRole('admin'); // true/false
const orgs = await auth.fetchUserOrganisations(user); // includes descendants
HTTPServices (韩语)
基于Axios的HTTP客户端具有可配置的超时功能.
const http = di.get(DEFINITIONS.HTTP);
// Default timeout is 10 seconds
http.setDefaultTimeout(30000);
const response = await http.request({
method: 'POST',
url: 'https://api.example.com/payments',
headers: { Authorization: 'Bearer token' },
data: { amount: 1000 },
});
保密服务
从 AWS 机密管理器获取并缓存机密 .
const secrets = di.get(DEFINITIONS.SECRETS);
// Fetched once, then cached for the Lambda execution
const creds = await secrets.get('arn:aws:secretsmanager:eu-west-1:123:secret:db-creds');
// { username: 'admin', password: '...', host: '...', ... }
Webhook 服务
HMAC -SHA256号调度员在网络上签名.
const webhook = di.get(DEFINITIONS.WEBHOOK);
await webhook.send(
'https://example.com/webhook',
{ event: 'payment.completed', transaction_id: 'txn_123' },
'webhook-signing-secret'
);
// POST with X-Signature header containing HMAC-SHA256 hex digest
审计
通过 EventBridge 创建审计线索事件 .
const auditLogger = di.get(DEFINITIONS.AUDIT_LOGGER);
await auditLogger.createEvent('payment.refunded', 'entity-123', 'org-456');
反应模式
所有Lambda的回复都使用标准格式,并附有CORS头.
import { ResponseModel } from '@felloh-org/lambda-wrapper';
// Basic response
const response = new ResponseModel({ users: [] }, 200);
return response.generate();
// Building a response
const response = new ResponseModel();
response.setData({ id: 1, name: 'Test' });
response.setCode(201);
response.setMetaVariable('pagination', { page: 1, total: 10 });
response.setBodyVariable('warnings', ['Deprecated field used']);
return response.generate();
// Adding errors
const error = new ResponseModel({}, 422);
error.addError({
title: 'Validation Error',
message: 'Email is not valid',
documentation_url: 'https://developers.felloh.com/errors#error-responses',
type: 'validation',
code: 'validation.email',
});
throw error; // or return error.generate()
// Static shorthand
return ResponseModel.generate({ result: 'ok' }, 200);
生成的响应格式 :
{
"statusCode": 200,
"headers": {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true
},
"body": "{\"data\":{},\"errors\":[],\"meta\":{\"code\":200,\"reason\":\"OK\",\"message\":\"The request was successful\",\"request_id\":\"uuid-v4\"}}"
}
支持的状态代码 :
| 代码 | 原因 |
|---|---|
| 200个 | |
| 201 (韩语) | 已创建 |
| 204 (韩语) | 无内容 |
| 400个 | 错误请求 |
| 401 (中文(简体) ) | 未经授权 |
| 403 (韩语) | 禁止 |
| 404 (韩语) | 未找到 |
| 406个 | 无法接受 |
| 410个 | 不见了 |
| 413号 | 请求实体太大 |
| 422个 | 无法处理的实体 |
| 429个 | 请求过多 |
| 500个 | 内部服务器出错 |
| 502 (中文(简体) ) | 错误的网关 |
| 第503条 | 服务不可用 |
| 504 (中文(简体) ) | 网关超时 |
状态模型
用于健康检查和服务状况报告.
import { StatusModel, STATUS_TYPES } from '@felloh-org/lambda-wrapper';
const status = new StatusModel('database', STATUS_TYPES.OK);
// STATUS_TYPES: OK, ACCEPTABLE_FAILURE, APPLICATION_FAILURE
Lambda 终止
用于终止 Lambda 执行的自定义错误类, 并带有特定的状态代码和消费者化消息 .
import { LambdaTermination } from '@felloh-org/lambda-wrapper';
// Terminates with a 503 response
throw new LambdaTermination(
'Payment provider timeout after 30s', // internal (logged)
503, // status code
'Service temporarily unavailable', // body (returned to consumer)
'Provider X timed out' // details
);
事件桥事件
将打出的事件发布到 AWS EventBridge .
import {
LambdaWrapper,
DEFINITIONS,
TransactionCompleteEvent,
TransactionCompleteEmailEvent,
UserRegistrationEvent,
CSVEmailEvent,
RefundRequestEmailEvent,
BaseEvent,
} from '@felloh-org/lambda-wrapper';
export const handler = LambdaWrapper(config, async (di) => {
const eventBridge = di.get(DEFINITIONS.EVENT_BRIDGE);
// Use a pre-built event
const event = new TransactionCompleteEvent();
event.setDetailParam('transaction_id', 'txn_123');
await eventBridge.put(event);
// Or build a custom event
const custom = new BaseEvent('order.shipped');
custom.setDetailParam('order_id', 'ord_456');
custom.setDetail({ order_id: 'ord_456', carrier: 'DHL' });
await eventBridge.put(custom);
});
可用事件类型 :
| 活动 | 说明 |
|---|---|
BaseEvent | 常规事件, 设置您自己的细节类型 |
TransactionCompleteEvent | 已完成的交易 |
TransactionCompleteEmailEvent | 交易收据电子邮件 |
UserRegistrationEvent | 新用户注册 |
UserPasswordChangedEvent | 密码已更改 |
UserPasswordResetEvent | 请求重新设置密码 |
SandboxRegistrationEvent | 沙盒账户注册 |
CSVEmailEvent | CSV 导出电子邮件 |
POSCRequestEmailEvent | POSC 请求电子邮件 |
RefundRequestEmailEvent | 退款请求通知 |
Webhook 模型
为 Webhook 有效载荷格式化交易和退款数据.
import { TransactionWebhookModel, RefundWebhookModel } from '@felloh-org/lambda-wrapper';
// Transaction webhook
const payload = new TransactionWebhookModel(transaction, 'Payment received');
const data = payload.get();
// { transaction: { id, narrative }, amount, booking, status, currency, surcharge, ... }
数据库(TypeORM)
实体
库包括按域排列的 TypeORM 实体 :
| 域名 | 说明 |
|---|---|
payment | 交易、退款、退款、付款链接、电子商务、供应商、会话 |
user | 用户、组织、角色、功能、网络呼号、账单、合作伙伴、门户网站 |
bank | 账户、分类账、结算、支付、调整、受益人 |
agent-data | 预订、部件、供应商、包件类型 |
acquirer | BIN数据、批量、调整、波段率、交易结算 |
aisp | 开放式银行交易、无卡账户/协议/要求 |
nuapay | Nuapay账户、余额、受益人、交易 |
nuvei | 努维伊批、商、交易、元数据 |
trust-payments | 信托付款批次、商户、交易、收费、手续费 |
total-processing | 处理交易和元数据共计 |
planet | 行星交易、元数据、批次 |
saltedge | 盐源账户、连接、客户、交易、线索 |
basis-theory | 切换符号 |
go-cardless | 无卡德组织配置 |
marketing | 营销联系人和ESU |
reference | 国家 |
playbook | 游戏本、请求、秘密、版本 |
移徙
根据数据库运行迁移 :
# Create database schemas
yarn orm:schema:create
# Run pending migrations
yarn orm:migration:run
# Generate a new migration
yarn orm:migration:generate <name>
# Revert last migration
yarn orm:revert
移徙需要下列环境变量:
| 变量 | 说明 |
|---|---|
WAREHOUSE_TYPE | postgres 或者说 postgres-ssm |
WAREHOUSE_HOST | 数据库主机(用于 postgres 类型) |
WAREHOUSE_USERNAME | 数据库用户名(用于 postgres 类型) |
WAREHOUSE_PASSWORD | 数据库密码(用于 postgres 类型) |
WAREHOUSE_DATABASE | 数据库名称 |
WAREHOUSE_SCHEMA | 数据库计划 |
DB_CREDS_ARN | 保密管理器 ARN (用于 postgres-ssm 类型) |
数据库 Schemas
数据库按以下计划编排: user, (中文(简体) ), payment, (中文(简体) ), bank, (中文(简体) ), agent_data, (中文(简体) ), nuapay, (中文(简体) ), trust_payments, (中文(简体) ), total_processing, (中文(简体) ), token, (中文(简体) ), nuvei, (中文(简体) ), reference, (中文(简体) ), saltedge, (中文(简体) ), acquirer, (中文(简体) ), operations, (中文(简体) ), basis_theory, (中文(简体) ), aisp, (中文(简体) ), go_cardless, (中文(简体) ), planet, (中文(简体) ), marketing, (中文(简体) ), amex, (中文(简体) ), crm, (中文(简体) ), shield。 。 。 .
公用事业
已证实 延迟
为重试逻辑提供随机延迟,并带有可配置的延迟配置.
import { PromisifiedDelay } from '@felloh-org/lambda-wrapper';
// High latency profile (2-20s delays, weighted towards shorter)
const delay = new PromisifiedDelay(true);
// Standard latency profile (2-5s delays)
const delay = new PromisifiedDelay(false);
// Use in retry loop
for (let attempt = 0; attempt < 3; attempt++) {
try {
return await makeRequest();
} catch (error) {
await delay.get();
}
}
发展
图标
# Build for production (webpack)
yarn build
# Build for TypeORM migrations (babel)
yarn build:orm
# Run linter
yarn lint
# Run tests with coverage
yarn test
# Run dependency vulnerability audit
yarn audit:check
# Run database migrations
yarn orm:migration:run
# Generate a new migration
yarn orm:migration:generate <name>
# Revert last migration
yarn orm:revert
# Create database schemas
yarn orm:schema:create
环境变量
| 变量 | 说明 |
|---|---|
SERVICE_NAME | 记录和活动的服务标识符 |
EVENT_BRIDGE_ARN | AWS 事件桥总线 ARN |
REGION | AWS 区域 |
WAREHOUSE_TYPE | 数据库连接类型( E)postgres 或者说 postgres-ssm(中文(简体) ) |
WAREHOUSE_HOST | 数据库主机 |
WAREHOUSE_USERNAME | 数据库用户名 |
WAREHOUSE_PASSWORD | 数据库密码 |
WAREHOUSE_DATABASE | 数据库名称 |
WAREHOUSE_SCHEMA | 数据库计划 |
DB_CREDS_ARN | 数据库证书的秘密管理器 ARN |
DB_LOGGING | 设定为 true 启用 TypeORM 查询记录 |
LOGGER_SOFT_WARNING | 设定为 true 将警告降为信息级别 |
IS_OFFLINE | 由无服务器离线设定用于本地开发 |
项目结构
src/
├── action/ # Action handlers (e.g. unmatched route)
├── config/ # Dependency definitions
├── dependency-injection/ # DI container and base class
├── entity/ # TypeORM entities by domain
├── enums/ # Shared enumerations
├── event/ # EventBridge event classes
├── migration/ # Database migrations by schema
├── model/ # Response, status, and webhook models
├── service/ # Core services (logger, request, warehouse, auth, etc.)
├── util/ # Utilities (LambdaTermination, PromisifiedDelay)
└── wrapper/ # Lambda wrapper implementation
排雷中心/发改委
该项目使用Concle CI,管道如下:
- 测试 - 平行进行林特、测试和依赖性审计
- 移徙。 装入 - 制定计划,在中转时进行迁移
- 移徙、生产 - 成功后促进生产
- 迁移.sandbox - 成功后升入沙盒
测试
测试与源文件(如. src/service/logger.test.js 并行 src/service/logger.js) (中文(简体) ).
yarn test
许可证
麻省理工学院