gcx/backend/services/referral-service/src/domain/value-objects/referral-chain.vo.ts

59 lines
1.5 KiB
TypeScript

/**
* ReferralChain Value Object
* 推荐链: 存储从直接推荐人到顶层的有序 userId 数组
* chain[0] = 直接推荐人, chain[1] = 推荐人的推荐人, ...
*/
export class ReferralChain {
private static readonly MAX_DEPTH = 50;
private constructor(private readonly _chain: string[]) {
if (_chain.length > ReferralChain.MAX_DEPTH) {
throw new Error(`推荐链深度不能超过 ${ReferralChain.MAX_DEPTH}`);
}
}
static empty(): ReferralChain {
return new ReferralChain([]);
}
static fromArray(chain: string[]): ReferralChain {
return new ReferralChain([...chain]);
}
/**
* 构建新用户的推荐链: 将推荐人 prepend 到其推荐链前
*/
static buildFromReferrer(referrerId: string, referrerChain: string[]): ReferralChain {
const chain = [referrerId, ...referrerChain];
return new ReferralChain(chain.slice(0, ReferralChain.MAX_DEPTH));
}
get depth(): number {
return this._chain.length;
}
/** 直接推荐人 (chain[0]) */
get directReferrer(): string | null {
return this._chain[0] ?? null;
}
/** 获取第 N 级上级 (1-based, 1 = 直接推荐人) */
getReferrerAtLevel(level: number): string | null {
return this._chain[level - 1] ?? null;
}
/** 所有祖先 */
getAllAncestors(): string[] {
return [...this._chain];
}
toArray(): string[] {
return [...this._chain];
}
/** 检查 userId 是否已在链中 (防止循环推荐) */
contains(userId: string): boolean {
return this._chain.includes(userId);
}
}