/** * CreditsEngine - 积分引擎核心类 * 协调所有积分操作的主要服务类 * * 验证需求: 17.1-17.5 */ import { IStorageAdapter } from '../adapters/IStorageAdapter'; import { ILogAdapter } from '../adapters/ILogAdapter'; import { CreditsConfig, ChargeParams, ChargeResult, RefundParams, RefundResult, GrantParams, GrantResult, UpgradeTierParams, DowngradeTierParams, TierChangeResult, Transaction, HistoryOptions } from './types'; /** * CreditsEngine 选项类型 * 用于初始化 CreditsEngine 实例 */ export interface CreditsEngineOptions { /** 存储适配器(必需) */ storage: IStorageAdapter; /** SDK 配置(必需) */ config: CreditsConfig; /** 日志适配器(可选,默认使用 ConsoleLogger) */ logger?: ILogAdapter; } /** * CreditsEngine 类 * * 主要服务类,提供所有积分操作: * - charge: 扣费操作 * - refund: 退款操作 * - grant: 发放积分 * - queryBalance: 查询余额 * - getHistory: 获取交易历史 * - validateAccess: 验证访问权限 * * 核心特性: * - 适配器模式:通过 IStorageAdapter 解耦存储层 * - 事务透传:支持将操作嵌入到更大的业务事务中 * - 幂等性:防止重复扣费 * - 重试机制:自动处理瞬态故障 * - 审计日志:记录所有操作用于合规和调试 * - 会员验证:基于会员等级的访问控制 * - 成本计算:灵活的分层定价 * * @example * ```typescript * // 创建 CreditsEngine 实例 * const engine = new CreditsEngine({ * storage: new PrismaAdapter(prisma), * config: { * costs: { * 'generate-post': { default: 10, premium: 8 } * }, * membership: { * tiers: { free: 0, premium: 1 }, * requirements: { 'generate-post': null } * }, * retry: { * enabled: true, * maxAttempts: 3, * initialDelay: 100, * maxDelay: 5000, * backoffMultiplier: 2 * }, * idempotency: { * enabled: true, * ttl: 86400 * }, * audit: { * enabled: true * } * } * }); * * // 执行扣费操作 * const result = await engine.charge({ * userId: 'user-123', * action: 'generate-post', * idempotencyKey: 'unique-key-123' * }); * ``` */ export declare class CreditsEngine { private readonly storage; private readonly config; private readonly logger; private readonly costFormula; private readonly membershipValidator; private readonly idempotencyManager; private readonly auditTrail; private readonly retryHandler; /** * 创建一个新的 CreditsEngine 实例 * * 初始化流程: * 1. 验证必需的配置参数 * 2. 设置存储适配器 * 3. 设置日志记录器(使用提供的或默认的 ConsoleLogger) * 4. 初始化所有特性模块: * - CostFormula: 成本计算 * - MembershipValidator: 会员验证 * - IdempotencyManager: 幂等性管理 * - AuditTrail: 审计日志 * - RetryHandler: 重试处理 * * @param options - CreditsEngine 选项 * @throws {ConfigurationError} 当配置无效时 * * @example * ```typescript * // 使用默认日志记录器 * const engine = new CreditsEngine({ * storage: adapter, * config: myConfig * }); * * // 使用自定义日志记录器 * const engine = new CreditsEngine({ * storage: adapter, * config: myConfig, * logger: new CustomLogger() * }); * ``` * * 验证需求: * - 17.1: 在初始化期间接受 CreditsConfig 对象 * - 17.2: CreditsConfig 包含所有支持操作的成本公式 * - 17.3: CreditsConfig 包含会员等级定义和要求 * - 17.4: CreditsConfig 包含重试策略配置 * - 17.5: CreditsConfig 包含可选行为的功能标志 */ constructor(options: CreditsEngineOptions); /** * 验证配置的完整性和有效性 * * 验证项: * - costs 配置存在且不为空 * - membership 配置存在且包含 tiers 和 requirements * - retry 配置存在且包含所有必需字段 * - idempotency 配置存在且包含所有必需字段 * - audit 配置存在 * - 成本配置中的每个操作都有 default 值 * - 会员等级层次结构有效(数值类型) * * @param config - 要验证的配置 * @throws {ConfigurationError} 当配置无效时 */ private validateConfig; /** * 扣费操作 * * 执行完整的扣费流程: * 1. 幂等性检查 - 如果提供了幂等键且操作已执行,返回缓存结果 * 2. 用户验证 - 检查用户是否存在 * 3. 会员验证 - 检查用户是否有权限执行该操作 * 4. 成本计算 - 根据操作和会员等级计算成本 * 5. 余额检查 - 确保用户有足够的积分 * 6. 余额更新 - 扣除积分 * 7. 交易记录 - 创建交易记录 * 8. 审计日志 - 记录操作 * 9. 幂等记录 - 保存结果用于后续幂等性检查 * * 所有操作在事务中执行(如果提供了事务上下文)或自动提交。 * 任何步骤失败都会导致整个操作回滚(在事务中)。 * * @param params - 扣费参数 * @returns 扣费结果 * @throws {UserNotFoundError} 当用户不存在时 * @throws {MembershipRequiredError} 当用户缺少所需会员资格时 * @throws {InsufficientCreditsError} 当用户积分不足时 * @throws {UndefinedActionError} 当操作未在配置中定义时 * * @example * ```typescript * // 基本扣费 * const result = await engine.charge({ * userId: 'user-123', * action: 'generate-post' * }); * * // 带幂等键的扣费 * const result = await engine.charge({ * userId: 'user-123', * action: 'generate-post', * idempotencyKey: 'unique-key-123' * }); * * // 在事务中扣费 * await prisma.$transaction(async (tx) => { * const result = await engine.charge({ * userId: 'user-123', * action: 'generate-post', * txn: tx * }); * // ... 其他操作 ... * }); * ``` * * 验证需求: * - 4.1: 按顺序执行幂等性检查、用户验证、会员验证、成本计算、余额检查、余额更新、交易记录和审计日志记录 * - 4.2: 如果提供了幂等键且与现有操作匹配,返回缓存的结果而不执行扣费 * - 4.3: 扣费操作在任何步骤失败时,在事务内回滚所有更改 * - 4.4: 扣费成功时,返回包含更新余额和交易 ID 的 ChargeResult * - 4.5: 支持通过 txn 参数将扣费操作包装在外部事务上下文中 */ charge(params: ChargeParams): Promise; /** * 退款操作 * * 执行退款流程: * 1. 幂等性检查 - 如果提供了幂等键且操作已执行,返回缓存结果 * 2. 用户验证 - 检查用户是否存在 * 3. 余额更新 - 增加积分 * 4. 交易记录 - 创建交易记录(正金额表示增加) * 5. 审计日志 - 记录操作 * 6. 幂等记录 - 保存结果用于后续幂等性检查 * * 所有操作在事务中执行(如果提供了事务上下文)或自动提交。 * 任何步骤失败都会导致整个操作回滚(在事务中)。 * * @param params - 退款参数 * @returns 退款结果 * @throws {UserNotFoundError} 当用户不存在时 * * @example * ```typescript * // 基本退款 * const result = await engine.refund({ * userId: 'user-123', * amount: 100, * action: 'refund-order-123' * }); * * // 带幂等键的退款 * const result = await engine.refund({ * userId: 'user-123', * amount: 100, * action: 'refund-order-123', * idempotencyKey: 'refund-unique-key-123' * }); * * // 在事务中退款 * await prisma.$transaction(async (tx) => { * const result = await engine.refund({ * userId: 'user-123', * amount: 100, * action: 'refund-order-123', * txn: tx * }); * // ... 其他操作 ... * }); * ``` * * 验证需求: * - 5.1: 将积分添加到用户余额 * - 5.2: 创建带有正金额的交易记录 * - 5.3: 创建审计日志条目 * - 5.4: 支持退款操作的幂等性 * - 5.5: 支持退款操作的事务上下文 */ refund(params: RefundParams): Promise; /** * 发放积分 * * 执行发放流程: * 1. 验证金额为正数 * 2. 用户验证 - 检查用户是否存在 * 3. 余额更新 - 增加积分 * 4. 交易记录 - 创建交易记录(正金额表示增加) * 5. 审计日志 - 记录操作 * * 所有操作在事务中执行(如果提供了事务上下文)或自动提交。 * 任何步骤失败都会导致整个操作回滚(在事务中)。 * * @param params - 发放参数 * @returns 发放结果 * @throws {UserNotFoundError} 当用户不存在时 * @throws {ConfigurationError} 当发放金额小于或等于零时 * * @example * ```typescript * // 基本发放 * const result = await engine.grant({ * userId: 'user-123', * amount: 100, * action: 'promotion-bonus' * }); * * // 在事务中发放 * await prisma.$transaction(async (tx) => { * const result = await engine.grant({ * userId: 'user-123', * amount: 100, * action: 'promotion-bonus', * txn: tx * }); * // ... 其他操作 ... * }); * ``` * * 验证需求: * - 6.1: 将积分添加到用户余额 * - 6.2: 创建交易记录 * - 6.3: 创建审计日志条目 * - 6.4: 支持发放操作的事务上下文 * - 6.5: 验证发放金额为正数 */ grant(params: GrantParams): Promise; /** * 升级会员等级 * * 执行会员升级流程: * 1. 幂等性检查 - 如果提供了幂等键且操作已执行,返回缓存结果 * 2. 用户验证 - 检查用户是否存在 * 3. 目标等级验证 - 检查目标等级是否在配置中定义 * 4. 升级方向验证 - 确保目标等级高于当前等级 * 5. 等级和积分更新 - 更新用户等级并设置积分为目标等级的上限 * 6. 交易记录创建 - 创建交易记录以记录积分变动 * 7. 审计日志记录 - 记录操作详情 * 8. 幂等记录保存 - 保存结果用于后续幂等性检查 * * 所有操作在事务中执行(如果提供了事务上下文)或自动提交。 * 任何步骤失败都会导致整个操作回滚(在事务中)。 * * @param params - 升级参数 * @returns 等级变更结果 * @throws {UserNotFoundError} 当用户不存在时 * @throws {UndefinedTierError} 当目标等级未在配置中定义时 * @throws {InvalidTierChangeError} 当目标等级不高于当前等级时 * * @example * ```typescript * // 基本升级 * const result = await engine.upgradeTier({ * userId: 'user-123', * targetTier: 'premium' * }); * * // 带会员到期时间的升级 * const result = await engine.upgradeTier({ * userId: 'user-123', * targetTier: 'premium', * membershipExpiresAt: new Date('2025-12-31') * }); * * // 带幂等键的升级 * const result = await engine.upgradeTier({ * userId: 'user-123', * targetTier: 'premium', * idempotencyKey: 'upgrade-unique-key-123' * }); * * // 在事务中升级 * await prisma.$transaction(async (tx) => { * const result = await engine.upgradeTier({ * userId: 'user-123', * targetTier: 'premium', * txn: tx * }); * // ... 其他操作 ... * }); * ``` * * 验证需求: * - 1.1: 验证目标等级高于当前等级 * - 1.2: 更新用户的会员等级字段为目标等级 * - 1.3: 将用户积分设置为目标等级的预设积分上限 * - 1.4: 创建交易记录以记录积分变动 * - 1.5: 创建审计日志记录操作详情 * - 1.6: 目标等级不存在于配置中时抛出配置错误 * - 1.7: 目标等级不高于当前等级时抛出验证错误 * - 1.8: 用户不存在时抛出用户不存在错误 */ upgradeTier(params: UpgradeTierParams): Promise; /** * 降级会员等级 * * 执行会员降级流程: * 1. 幂等性检查 - 如果提供了幂等键且操作已执行,返回缓存结果 * 2. 用户验证 - 检查用户是否存在 * 3. 目标等级验证 - 检查目标等级是否在配置中定义 * 4. 降级方向验证 - 确保目标等级低于当前等级 * 5. 等级和积分更新 - 更新用户等级并设置积分为目标等级的上限 * 6. 会员到期时间清除 - 如果指定,清除会员到期时间 * 7. 交易记录创建 - 创建交易记录以记录积分变动 * 8. 审计日志记录 - 记录操作详情 * 9. 幂等记录保存 - 保存结果用于后续幂等性检查 * * 所有操作在事务中执行(如果提供了事务上下文)或自动提交。 * 任何步骤失败都会导致整个操作回滚(在事务中)。 * * @param params - 降级参数 * @returns 等级变更结果 * @throws {UserNotFoundError} 当用户不存在时 * @throws {UndefinedTierError} 当目标等级未在配置中定义时 * @throws {InvalidTierChangeError} 当目标等级不低于当前等级时 * * @example * ```typescript * // 基本降级 * const result = await engine.downgradeTier({ * userId: 'user-123', * targetTier: 'free' * }); * * // 降级并清除会员到期时间 * const result = await engine.downgradeTier({ * userId: 'user-123', * targetTier: 'free', * clearExpiration: true * }); * * // 带幂等键的降级 * const result = await engine.downgradeTier({ * userId: 'user-123', * targetTier: 'free', * idempotencyKey: 'downgrade-unique-key-123' * }); * * // 在事务中降级 * await prisma.$transaction(async (tx) => { * const result = await engine.downgradeTier({ * userId: 'user-123', * targetTier: 'free', * txn: tx * }); * // ... 其他操作 ... * }); * ``` * * 验证需求: * - 2.1: 验证目标等级低于当前等级 * - 2.2: 更新用户的会员等级字段为目标等级 * - 2.3: 将用户积分设置为目标等级的预设积分上限 * - 2.4: 创建交易记录以记录积分变动 * - 2.5: 创建审计日志记录操作详情 * - 2.6: 目标等级不存在于配置中时抛出配置错误 * - 2.7: 目标等级不低于当前等级时抛出验证错误 * - 2.8: 用户不存在时抛出用户不存在错误 * - 6.3: 降级时可选地清除会员到期时间 */ downgradeTier(params: DowngradeTierParams): Promise; /** * 查询余额 * * 查询用户的当前积分余额。 * * 执行流程: * 1. 获取用户信息 * 2. 验证用户存在 * 3. 返回积分余额 * * 支持事务上下文以确保读取一致性。 * * @param userId - 用户 ID * @param txn - 可选的事务上下文 * @returns 用户当前积分余额(数值类型) * @throws {UserNotFoundError} 当用户不存在时 * * @example * ```typescript * // 基本查询 * const balance = await engine.queryBalance('user-123'); * console.log(`Current balance: ${balance}`); * * // 在事务中查询(确保读取一致性) * await prisma.$transaction(async (tx) => { * const balance = await engine.queryBalance('user-123', tx); * // ... 基于余额的其他操作 ... * }); * ``` * * 验证需求: * - 7.1: 使用有效用户 ID 调用时,返回当前积分余额 * - 7.2: 使用无效用户 ID 调用时,抛出 UserNotFoundError * - 7.3: 支持余额查询的事务上下文以确保读取一致性 * - 7.4: 返回具有适当精度的数值类型余额 */ queryBalance(userId: string, txn?: any): Promise; /** * 获取交易历史 * * 查询用户的积分交易记录,支持分页和过滤。 * * 执行流程: * 1. 通过 StorageAdapter 查询交易记录 * 2. 应用分页参数 (limit, offset) * 3. 应用日期范围过滤 (startDate, endDate) * 4. 应用操作类型过滤 (action) * 5. 返回按时间戳降序排列的交易列表 * * 支持事务上下文以确保读取一致性。 * * @param userId - 用户 ID * @param options - 查询选项 * @returns 交易记录列表,按时间戳降序排列 * * @example * ```typescript * // 获取最近 10 条交易 * const history = await engine.getHistory('user-123', { limit: 10 }); * * // 分页查询 * const history = await engine.getHistory('user-123', { * limit: 20, * offset: 40 * }); * * // 按日期范围过滤 * const history = await engine.getHistory('user-123', { * startDate: new Date('2024-01-01'), * endDate: new Date('2024-12-31') * }); * * // 按操作类型过滤 * const history = await engine.getHistory('user-123', { * action: 'generate-post' * }); * * // 组合多个过滤条件 * const history = await engine.getHistory('user-123', { * limit: 50, * offset: 0, * startDate: new Date('2024-01-01'), * action: 'generate-post' * }); * * // 在事务中查询(确保读取一致性) * await prisma.$transaction(async (tx) => { * const history = await engine.getHistory('user-123', { * limit: 10, * txn: tx * }); * // ... 基于历史的其他操作 ... * }); * ``` * * 验证需求: * - 8.1: 返回指定用户的交易列表 * - 8.2: 通过 limit 和 offset 参数支持分页 * - 8.3: 支持按日期范围过滤 * - 8.4: 支持按操作类型过滤 * - 8.5: 返回按时间戳降序排列的交易 */ getHistory(userId: string, options?: HistoryOptions): Promise; /** * 验证访问权限 * * 检查用户是否有权限执行某个操作。 * 验证用户的会员等级是否满足操作所需的等级。 * * 验证流程: * 1. 获取用户信息 * 2. 检查操作的会员要求 * 3. 验证用户会员等级和过期状态 * 4. 返回验证结果 * * @param userId - 用户 ID * @param action - 操作名称 * @param txn - 可选的事务上下文 * @returns 是否有权限 * @throws {UserNotFoundError} 当用户不存在时 * @throws {MembershipRequiredError} 当用户缺少所需会员资格时 * * @example * ```typescript * // 验证用户是否可以执行操作 * try { * const hasAccess = await engine.validateAccess('user-123', 'generate-post'); * if (hasAccess) { * // 用户有权限 * } * } catch (error) { * if (error instanceof MembershipRequiredError) { * // 用户缺少所需会员资格 * } * } * ``` * * 验证需求: * - 9.1: 检查用户的会员等级是否满足操作所需的等级 * - 9.2: 当用户的会员资格已过期时,将其视为没有会员资格 * - 9.3: 当用户缺少所需会员资格时,抛出 MembershipRequiredError * - 9.4: 当用户具有足够的会员资格时,返回 true * - 9.5: 支持每个操作的可配置会员要求 */ validateAccess(userId: string, action: string, txn?: any): Promise; } //# sourceMappingURL=CreditsEngine.d.ts.map