refactor: organize backend by business responsibility

This commit is contained in:
2026-09-13 13:52:57 +03:00
parent 7fde3ece6e
commit 8ba005346d
145 changed files with 3027 additions and 2346 deletions
@@ -0,0 +1,60 @@
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
import {
TbankClient,
TbankTokenService,
} from '../../../integrations/tbank/tbank.api';
import { PrismaService } from '../../../prisma/prisma.service';
import { PortfolioService } from '../portfolio/portfolio.api';
type TbankTokenValidator = Pick<TbankClient, 'validateToken'>;
@Injectable()
export class TbankConnectionService {
constructor(
private readonly prisma: PrismaService,
private readonly tokens: TbankTokenService,
@Inject(TbankClient) private readonly tbank: TbankTokenValidator,
private readonly portfolio: PortfolioService,
) {}
async status(userId: string) {
const connection = await this.prisma.tbankConnection.findUnique({
where: { userId },
});
return {
connected: Boolean(connection),
connectedAt: connection?.connectedAt.toISOString() ?? null,
};
}
async put(userId: string, value: string) {
const token = value.trim();
if (!token) throw new BadRequestException({ code: 'VALIDATION_ERROR' });
await this.tokens.translateInvalidToken(() =>
this.tbank.validateToken(token),
);
const encryptedToken = this.tokens.encrypt(token);
const connection = await this.prisma.tbankConnection.upsert({
where: { userId },
create: {
userId,
encryptedToken,
connectedAt: new Date(),
},
update: {
encryptedToken,
connectedAt: new Date(),
},
});
this.portfolio.invalidate(userId);
return {
connected: true,
connectedAt: connection.connectedAt.toISOString(),
};
}
async delete(userId: string): Promise<void> {
await this.prisma.tbankConnection.deleteMany({ where: { userId } });
this.portfolio.invalidate(userId);
}
}