Article

Penny Lens Serverless 技术架构

2026年6月24日 · 11 分钟阅读 · ixNieStudio

基于支付宝小程序云 Serverless 的云原生后端服务,为 Penny Lens 系统提供统一的数据存储、业务逻辑处理和 API 接口服务。

Penny Lens Serverless 技术架构

🎯 产品定位

Penny Lens Serverless 是基于支付宝小程序云 Serverless 的云原生后端服务,为 Penny Lens 系统提供统一的数据存储、业务逻辑处理和 API 接口服务。通过云原生架构,提供高可用性、自动扩缩容和低成本的后端解决方案。

✨ 核心价值

1. 云原生架构

  • 自动扩缩容: 根据负载自动调整资源
  • 高可用性: 99.9% 的服务可用性保证
  • 弹性计算: 按需分配计算资源
  • 成本优化: 按使用量付费,降低成本

2. 统一后端服务

  • API 统一: 为 PC 端和移动端提供统一 API
  • 数据同步: 多端数据实时同步
  • 业务逻辑: 统一的业务逻辑处理
  • 数据安全: 企业级数据安全保护

3. 开发效率

  • 快速部署: 一键部署到云端
  • 自动运维: 无需手动运维管理
  • 监控告警: 自动监控和告警
  • 日志管理: 自动日志收集和分析

🏗️ 系统架构

Penny Lens Serverless 采用云原生架构,基于支付宝小程序云 Serverless + TypeScript + MongoDB 构建,提供高可用性、自动扩缩容和低成本的后端解决方案。

🛠️ 技术栈

核心框架

数据库与存储

开发工具

📁 项目结构

src/
├── config/ # 配置文件
│ └── index.ts # 配置入口
├── controllers/ # 控制器层
│ ├── UserController.ts
│ ├── AssetController.ts
│ ├── AccountingController.ts
│ ├── BudgetController.ts
│ ├── StatisticsController.ts
│ ├── SubscriptionController.ts
│ ├── SavingsController.ts
│ └── ShortLinkController.ts
├── services/ # 服务层
│ ├── UserService.ts
│ ├── AssetService.ts
│ ├── AccountingService.ts
│ ├── BudgetService.ts
│ ├── StatisticsService.ts
│ ├── SubscriptionService.ts
│ ├── SavingsService.ts
│ └── ShortLinkService.ts
├── types/ # 类型定义
│ ├── BaseService.ts # 基础服务类
│ ├── BaseController.ts # 基础控制器类
│ ├── appResponse.ts # 统一响应格式
│ ├── User.ts
│ ├── Asset.ts
│ ├── Accounting.ts
│ ├── Budget.ts
│ ├── Statistics.ts
│ ├── Subscription.ts
│ ├── Savings.ts
│ └── ShortLink.ts
├── exceptions/ # 异常处理
│ └── AppException.ts
├── enums/ # 枚举定义
│ └── HttpEnum.ts
├── router.ts # 路由配置
├── routes.ts # 路由定义
└── index.ts # 入口文件

🔧 开发规约架构

1. 基础架构层

BaseService - 基础服务类

/**
* 基础服务类
* 提供通用的数据库操作和业务逻辑处理
*/
export abstract class BaseService {
/**
* 构建基础查询条件
*/
protected buildBaseQueryCondition(userInfo: UserResponse): any {
return {
userId: userInfo.id,
delFlag: false
};
}
/**
* 分页查询
*/
protected async paginateQuery<T>(
collection: any,
where: any,
page: number,
pageSize: number,
orderBy: { field: string; order: "asc" | "desc"; }[] = [{ field: "createdAt", order: "desc" }]
): Promise<Page<T>> {
// 分页查询实现
}
/**
* 验证记录是否存在
*/
protected async validateRecordExists(
collection: any,
condition: any,
errorMessage: string
): Promise<any> {
// 记录存在性验证实现
}
/**
* 验证用户访问权限
*/
protected async validateUserAccess(
record: any,
userInfo: UserResponse,
errorMessage: string
): Promise<void> {
// 用户权限验证实现
}
}

BaseController - 基础控制器类

/**
* 基础控制器类
* 提供统一的请求处理和响应格式
*/
export abstract class BaseController {
/**
* 包装异步方法,自动处理异常
*/
protected wrapAsync<T>(
asyncFn: () => Promise<T>,
successMessage: string = "操作成功"
): Promise<AppResponse<T>> {
try {
const data = await asyncFn();
return {
code: 200,
message: successMessage,
data
};
} catch (error) {
// 统一异常处理
return this.handleError(error);
}
}
/**
* 统一错误处理
*/
private handleError(error: unknown): AppResponse<null> {
if (error instanceof AppException) {
return {
code: error.code,
message: error.message,
data: null
};
}
const errorMessage = error instanceof Error ? error.message : "未知错误";
return {
code: 500,
message: `服务器错误: ${errorMessage}`,
data: null
};
}
}

2. 异常处理架构

/**
* 应用异常基类
*/
export abstract class AppException extends Error {
constructor(
public code: number,
public message: string,
public data?: any
) {
super(message);
this.name = 'AppException';
}
}
/**
* 验证异常
*/
export class ValidationException extends AppException {
constructor(message: string, data?: any) {
super(400, message, data);
}
}
/**
* 认证异常
*/
export class AuthenticationException extends AppException {
constructor(message: string = 'Authentication failed') {
super(401, message);
}
}
/**
* 授权异常
*/
export class AuthorizationException extends AppException {
constructor(message: string = 'Access denied') {
super(403, message);
}
}
/**
* 未找到异常
*/
export class NotFoundException extends AppException {
constructor(message: string = 'Resource not found') {
super(404, message);
}
}
/**
* 数据库异常
*/
export class DatabaseException extends AppException {
constructor(message: string = 'Database operation failed') {
super(500, message);
}
}

3. 路由配置架构

/**
* 路由配置接口
*/
export interface RouteConfig {
controller: any;
method: string;
requireAuth: boolean;
}
/**
* 批量构建路由配置
*/
export function buildRoutes(
serviceName: string,
actions: Array<{ action: string; requireAuth: boolean }>,
controller: any
): Record<string, RouteConfig> {
const routes: Record<string, RouteConfig> = {};
actions.forEach(({ action, requireAuth }) => {
const routeKey = `${serviceName}.${action}`;
const methodName = METHOD_MAPPINGS[routeKey] || action;
routes[routeKey] = {
controller,
method: methodName,
requireAuth
};
});
return routes;
}
/**
* 方法映射表(特殊 action 到 service 方法名的映射)
*/
export const METHOD_MAPPINGS: Record<string, string> = {
"asset.record.queryByAssetId": "queryListByAssetId",
"user.generateQrCodeLogin": "generateQrCodeLogin",
"user.confirmQrCodeLogin": "confirmQrCodeLogin",
"user.pollQrCodeLogin": "pollQrCodeLogin",
};

🔧 核心功能模块

1. 用户管理模块

功能: 用户注册、登录、信息管理、QR码登录

技术实现:

  • JWT Token 认证
  • 多平台登录支持(微信、支付宝)
  • QR码跨设备登录
  • 用户信息加密存储
  • 权限控制

开发规约实现:

// Service 层
export class UserService extends BaseService {
public async create(params: UserCreateRequest, userInfo: UserResponse): Promise<{ id: string; }> {
// 使用 buildBaseQueryCondition 构建查询条件
// 使用 validateRecordExists 验证记录存在性
// 抛出具体的业务异常
}
}
// Controller 层
export class UserController extends BaseController {
async create(params: UserCreateRequest, userInfo: UserResponse): Promise<AppResponse<{ id: string; }>> {
return this.wrapAsync(
async () => {
return this.userService.create(params, userInfo);
},
"创建用户成功",
);
}
}

相关文件:

  • controllers/UserController.ts - 用户控制器
  • services/UserService.ts - 用户服务
  • types/User.ts - 用户类型定义

2. 资产管理模块

功能: 资产增删改查、余额管理、转账功能

技术实现:

  • 多账户类型支持
  • 实时余额计算
  • 资产变化记录
  • 转账功能

开发规约实现:

// Service 层
export class AssetService extends BaseService {
public async create(params: AssetCreateRequest, userInfo: UserResponse): Promise<{ id: string; }> {
// 参数验证
if (!params.name) {
throw new ValidationException("资产名称不能为空");
}
// 构建基础查询条件
const baseCondition = this.buildBaseQueryCondition(userInfo);
// 检查资产是否已存在
const existingAsset = await assetCollection
.where({
...baseCondition,
name: params.name,
delFlag: false
})
.get();
if (existingAsset.data.length > 0) {
throw new ValidationException("资产名称已存在");
}
// 创建资产记录
const assetData = {
...params,
userId: userInfo.id,
delFlag: false,
createdAt: Date.now(),
updatedAt: Date.now()
};
const result = await assetCollection.add(assetData);
return { id: result._id };
}
}

相关文件:

  • controllers/AssetController.ts - 资产控制器
  • services/AssetService.ts - 资产服务
  • types/Asset.ts - 资产类型定义

3. 记账管理模块

功能: 收入、支出、转账记录管理

技术实现:

  • 复式记账法
  • 分类管理
  • 批量操作
  • 数据验证

开发规约实现:

// Service 层
export class AccountingService extends BaseService {
public async create(params: AccountingCreateRequest, userInfo: UserResponse): Promise<{ id: string; }> {
// 使用 validateRecordExists 验证资产存在
const asset = await this.validateRecordExists(
assetCollection,
{ _id: params.assetId, userId: userInfo.id },
"资产不存在"
);
// 使用 validateUserAccess 验证用户权限
await this.validateUserAccess(asset, userInfo, "无权限操作该资产");
// 业务逻辑处理
// ...
}
}

相关文件:

  • controllers/AccountingController.ts - 记账控制器
  • services/AccountingService.ts - 记账服务
  • types/Accounting.ts - 记账类型定义

4. 预算管理模块

功能: 预算设置、执行监控、预警提醒

技术实现:

  • 分类预算设置
  • 实时执行监控
  • 超支预警系统
  • 预算分析报告

开发规约实现:

// Service 层
export class BudgetService extends BaseService {
public async query(params: BudgetQueryRequest, userInfo: UserResponse): Promise<Page<Budget>> {
const baseCondition = this.buildBaseQueryCondition(userInfo);
const whereCondition = {
...baseCondition,
...(params.categoryId && { categoryId: params.categoryId }),
...(params.status && { status: params.status })
};
return this.paginateQuery(
budgetCollection,
whereCondition,
params.page || 1,
params.pageSize || 20,
[{ field: "createdAt", order: "desc" }]
);
}
}

相关文件:

  • controllers/BudgetController.ts - 预算控制器
  • services/BudgetService.ts - 预算服务
  • types/Budget.ts - 预算类型定义

5. 统计分析模块

功能: 收支统计、趋势分析、报表生成

技术实现:

  • 多维度统计分析
  • 实时数据计算
  • 报表生成
  • 数据导出

开发规约实现:

// Service 层
export class StatisticsService extends BaseService {
public async getIncomeStatistics(params: StatisticsRequest, userInfo: UserResponse): Promise<StatisticsResponse> {
// 使用 buildBaseQueryCondition 构建查询条件
const baseCondition = this.buildBaseQueryCondition(userInfo);
// 复杂的统计查询逻辑
// ...
}
}

相关文件:

  • controllers/StatisticsController.ts - 统计控制器
  • services/StatisticsService.ts - 统计服务
  • types/Statistics.ts - 统计类型定义

🔄 数据流架构

请求处理流程

用户请求 → 路由分发 → 权限验证 → 控制器处理 → 服务层业务逻辑 → 数据库操作 → 响应返回
↓ ↓ ↓ ↓ ↓ ↓ ↓
路由匹配 身份验证 参数验证 业务处理 数据查询 结果处理 状态返回

开发规约流程:

  1. 路由分发: 使用 buildRoutes 函数批量构建路由配置
  2. 权限验证: 根据 requireAuth 属性进行身份验证
  3. 控制器处理: 使用 wrapAsync 包装业务逻辑,自动处理异常
  4. 服务层业务逻辑: 继承 BaseService,使用工具方法进行数据库操作
  5. 数据库操作: 使用统一的查询条件和分页查询
  6. 异常处理: 使用具体的业务异常类,提供清晰的错误信息

数据同步机制

实时同步

  • 用户操作: 用户操作实时同步到数据库
  • 状态更新: 服务状态实时更新
  • 数据一致性: 保证数据一致性

批量同步

  • 定时任务: 定时同步数据
  • 数据备份: 定期数据备份
  • 统计分析: 定期统计分析

开发规约数据流

// 1. 路由配置
export const routes: Record<string, RouteConfig> = {
...buildRoutes("user", userActions, userController),
...buildRoutes("asset", assetActions, assetController),
};
// 2. 控制器处理
export class UserController extends BaseController {
async create(params: UserCreateRequest, userInfo: UserResponse): Promise<AppResponse<{ id: string; }>> {
return this.wrapAsync(
async () => {
// 简单的参数验证
if (!params.username) {
throw new ValidationException("用户名不能为空");
}
// 调用服务层
return this.userService.create(params, userInfo);
},
"创建用户成功",
);
}
}
// 3. 服务层业务逻辑
export class UserService extends BaseService {
public async create(params: UserCreateRequest, userInfo: UserResponse): Promise<{ id: string; }> {
// 构建基础查询条件
const baseCondition = this.buildBaseQueryCondition(userInfo);
// 检查用户名是否已存在
const existingUser = await userCollection
.where({
...baseCondition,
username: params.username,
delFlag: false
})
.get();
if (existingUser.data.length > 0) {
throw new ValidationException("用户名已存在");
}
// 创建用户记录
const userData = {
...params,
userId: userInfo.id,
delFlag: false,
createdAt: Date.now(),
updatedAt: Date.now()
};
const result = await userCollection.add(userData);
return { id: result._id };
}
}

🔐 安全架构

认证机制

// JWT Token 认证
export class AuthService {
generateToken(user: User): string {
return jwt.sign(
{ userId: user._id, username: user.username },
process.env.JWT_SECRET!,
{ expiresIn: '7d' }
);
}
verifyToken(token: string): any {
return jwt.verify(token, process.env.JWT_SECRET!);
}
}

权限控制

// 权限中间件
export const requireAuth = (req: Request, res: Response, next: NextFunction) => {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
throw new AuthenticationException('Token required');
}
try {
const decoded = authService.verifyToken(token);
req.user = decoded;
next();
} catch (error) {
throw new AuthenticationException('Invalid token');
}
};

数据加密

// 数据加密服务
export class EncryptionService {
encrypt(text: string): string {
const cipher = crypto.createCipher('aes-256-cbc', process.env.ENCRYPTION_KEY!);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
}
decrypt(encryptedText: string): string {
const decipher = crypto.createDecipher('aes-256-cbc', process.env.ENCRYPTION_KEY!);
let decrypted = decipher.update(encryptedText, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
}

⚡ 性能优化

数据库优化

// 数据库索引
export const createIndexes = async () => {
// 用户索引
await db.collection('users').createIndex({ username: 1 }, { unique: true });
await db.collection('users').createIndex({ email: 1 }, { unique: true });
// 资产索引
await db.collection('assets').createIndex({ userId: 1 });
await db.collection('assets').createIndex({ type: 1 });
// 记账记录索引
await db.collection('accounting').createIndex({ userId: 1, date: -1 });
await db.collection('accounting').createIndex({ categoryId: 1 });
};

缓存机制

// 缓存服务
export class CacheService {
private cache = new Map<string, { data: any; timestamp: number; ttl: number }>();
set(key: string, data: any, ttl: number = 300000): void {
this.cache.set(key, {
data,
timestamp: Date.now(),
ttl
});
}
get(key: string): any | null {
const item = this.cache.get(key);
if (!item) return null;
if (Date.now() - item.timestamp > item.ttl) {
this.cache.delete(key);
return null;
}
return item.data;
}
}

🧪 测试策略

单元测试

// 用户服务测试
describe('UserService', () => {
let userService: UserService;
beforeEach(() => {
userService = new UserService();
});
it('should create user successfully', async () => {
const userData = {
username: 'testuser',
email: 'test@example.com',
password: 'password123'
};
const result = await userService.createUser(userData);
expect(result).toBeDefined();
expect(result.username).toBe(userData.username);
});
});

集成测试

// API 集成测试
describe('User API', () => {
it('should login successfully', async () => {
const response = await request(app)
.post('/api/user/login')
.send({
username: 'testuser',
password: 'password123'
});
expect(response.status).toBe(200);
expect(response.body.code).toBe(200);
expect(response.body.data.token).toBeDefined();
});
});

🚀 部署架构

开发环境

  • 本地开发: 本地开发环境
  • 热重载: 实时代码更新
  • 调试工具: 调试工具支持
  • 代码检查: ESLint + TypeScript

生产环境

  • 云函数部署: 自动部署到云端
  • 数据库配置: 生产数据库配置
  • 监控告警: 生产环境监控
  • 备份恢复: 数据备份和恢复

📊 监控和运维

性能监控

  • 服务监控: 服务性能监控
  • 数据库监控: 数据库性能监控
  • 错误监控: 错误日志监控
  • 业务监控: 业务指标监控

日志管理

  • 访问日志: 用户访问记录
  • 错误日志: 系统错误和异常
  • 业务日志: 业务操作记录
  • 性能日志: 性能指标记录

🔄 持续集成

代码管理

  • 版本控制: Git 版本控制
  • 代码审查: Pull Request 代码审查
  • 自动化测试: 单元测试、集成测试
  • 代码质量: ESLint、TypeScript 检查

部署流程

  • 自动化构建: CI/CD 自动化构建
  • 环境管理: 开发、测试、生产环境
  • 回滚机制: 快速回滚机制
  • 灰度发布: 渐进式发布

📈 扩展性

功能扩展

  • 模块化设计: 模块化功能设计
  • 插件系统: 可扩展的插件系统
  • 接口标准化: 标准化接口设计
  • 版本兼容: 版本兼容性管理

技术扩展

  • 微服务化: 微服务架构演进
  • 容器化: 容器化部署
  • 云原生: 云原生架构
  • 智能化: AI 和机器学习集成

📋 开发规约总结

核心规约要点

  1. Service 层规范:

    • 继承 BaseService 基类
    • 使用 buildBaseQueryCondition 构建查询条件
    • 使用 paginateQuery 进行分页查询
    • 使用 validateRecordExists 验证记录存在性
    • 使用 validateUserAccess 验证用户权限
    • 抛出具体的业务异常类
  2. Controller 层规范:

    • 继承 BaseController 基类
    • 使用 wrapAsync 包装业务逻辑
    • 不使用 public 关键字
    • 使用 async () => { return ... } 格式
    • 未使用的参数使用下划线前缀
  3. 路由配置规范:

    • 使用 buildRoutes 函数批量构建路由
    • 明确指定 requireAuth 属性
    • 使用 METHOD_MAPPINGS 处理特殊方法映射
  4. 异常处理规范:

    • 使用统一的异常处理机制
    • 抛出具体的业务异常类
    • 提供清晰的错误信息
  5. 数据库操作规范:

    • 统一在文件顶部定义数据库连接和集合
    • 使用 cloud.database() 获取数据库实例
    • 集合名称使用小写复数形式
    • 避免链式 where 调用

开发检查清单

在开发新功能时,请确保:

  • Service 类继承 BaseService
  • Controller 类继承 BaseController
  • 使用 wrapAsync 包装业务逻辑
  • 不使用 public 关键字
  • 使用 buildBaseQueryCondition 构建查询条件
  • 使用 paginateQuery 进行分页查询
  • 使用具体的业务异常类
  • routes.ts 中注册路由
  • 遵循统一的命名规范
  • 添加完整的 JSDoc 注释

🎯 目标用户

主要用户群体

  1. 开发者

    • 需要云原生后端服务的开发者
    • 需要快速部署的开发者
    • 需要低成本解决方案的开发者
  2. 企业用户

    • 需要高可用性服务的企业
    • 需要自动扩缩容的企业
    • 需要统一后端服务的企业
  3. 个人用户

    • 需要数据同步的用户
    • 需要多端支持的用户
    • 需要数据安全的用户

Penny Lens Serverless - 让后端服务更简单、更可靠、更高效 🚀