typescript - วิธีการทำให้นามธรรมของธุรกรรมฐานข้อมูลในระดับการใช้งานกรณีสำหรับ Firebase ในสถาปัตยกรรมสะอาด?
ตอนนี้ฉันกำลังสร้างโครงการโดยใช้หลักการของ Clean Architecture ร่วมกับ Firebase ฉันยังใช้ Turborepo สำหรับโครงสร้าง monorepo ของฉันด้วย
ในฐานโค้ดของฉัน ภายใต้โฟลเดอร์ packages/ มีแพ็กเกจ "core" ที่ประกอบด้วยตรรกะทางธุรกิจของฉัน ซึ่งรวมถึง Entities และ Usecases ตัวอย่างเช่น ฉันมี Entity เช่น User, Promotion และ Affiliate และ usecase เช่น "สร้างรหัส affiliate" ที่ทำงานตรรกะทางธุรกิจกับ Entity ที่เกี่ยวข้อง
export abstract class Usecase<T> {
abstract execute(...args: any[]): Promise<T>;
}
export abstract class UserRepository {
abstract getUser(userId: string): Promise<User>;
abstract createUser(user: User): Promise<string>;
// ...
}
export class CreateAffiliateCodeUsecase implements Usecase<void> {
constructor(private userRepository: UserRepository) {}
async execute(userId: string, code: string): Promise<void> {
const user = await this.userRepository.getUser(userId);
if (!user) {
throw new Error("User not found");
}
if (user.affiliateCodes.includes(code)) {
throw new Error("Code already exists");
}
// ...
}
}
ในการใช้งานของฉัน ตัวสร้างวัตถุถูกฉีดด้วยอินเทอร์เฟซของที่เก็บข้อมูล
ต่อไปในระดับแอปพลิเคชันฉันจะนำมันไปใช้งานและใช้มันพร้อมกับรายละเอียดการใช้งานที่จัดเรียงเรียบร้อยแล้ว:
export abstract class RemoteStorageService {
abstract get(path: string): Promise<any>;
abstract update(path: string): Promise<any>;
// and so on
}
export class UserRepositoryImpl implements core.UserRepository {
constructor(private remoteStorageService: RemoteStorageService) {}
getUser(userId: string): Promise<core.User> {
return this.remoteStorageService.get(`/users/${userId}`);
}
}
export class FirestoreStorageService extends RemoteStorageService {
// implementation
async get(path: string): Promise<any> {
const doc = await this.db.doc(path).get();
if (!doc.exists) {
throw new Error('Document not found');
}
return doc.data();
}
}
คำถามของฉันคือ: ฉันสามารถสรุปการทำธุรกรรมเมื่อเขียนลงสตอเรจในระดับกรณีการใช้งานได้อย่างไรโดยไม่ต้องรู้รายละเอียดการใช้งานธุรกรรมของ Firebase? ฉันต้องการให้มั่นใจว่ากรณีการใช้งานของฉันจะไม่ขึ้นอยู่กับ Firebase โดยตรง
ฉันอยากทำอะไรสักอย่างแบบนี้:
export class CheckAffiliateCodeUsecase implements Usecase<void> {
constructor(
private userRepository: UserRepository,
private promotionRepository: PromotionRepository,
) {}
async execute(// .. //) {
// validations steps here..
// time to make multiple writes to DB
const promotionforNewUser = Promotion.createPromotion(//data1//);
const promotionforOldUser = Promotion.createPromotion(//data2//);
const user = User.getUser(//params//)
user.upgrade(//params//)
// transaction
transaction {
promitionRepository.save(promotionforNewUser)
promitionRepository.save(promotionforOldUser)
userRepository.updateUser(user)
}
}
}