Skip to content

Commit 6b2f79e

Browse files
committed
feat(backend): introduce usage module
1 parent bd30441 commit 6b2f79e

16 files changed

+222
-14
lines changed

apps/backend/src/api-key/api-key.module.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { ApiKeyService } from './api-key.service';
99
@Module({
1010
controllers: [ApiKeyController],
1111
providers: [ApiKeyService],
12+
exports: [ApiKeyService],
1213
imports: [LoggerModule, TypeOrmModule.forFeature([ApiKey])],
1314
})
1415
export class ApiKeyModule {}

apps/backend/src/api-key/api-key.service.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,25 @@ export class ApiKeyService {
7777
}
7878
}
7979

80+
public async useApiKey(apiKeyValue: string): Promise<ApiKey> {
81+
try {
82+
const apiKey = await this.apiKeyRepository.findOneOrFail({
83+
where: {
84+
value: apiKeyValue,
85+
},
86+
});
87+
88+
apiKey.lastUsed = new Date();
89+
90+
await this.apiKeyRepository.save(apiKey);
91+
92+
return apiKey;
93+
} catch (error) {
94+
this.loggerService.log(`Failed to fetch owner of API key. ${error}`);
95+
throw new NotFoundApiKeyError();
96+
}
97+
}
98+
8099
private async findApiKeyById(apiKeyId: string): Promise<ApiKey> {
81100
return await this.apiKeyRepository.findOne({ id: apiKeyId });
82101
}

apps/backend/src/app/app.controller.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ import { AppController } from './app.controller';
44
import { AppService } from './app.service';
55
import { LoggerService } from '../logger/logger.service';
66
import { LoggerServiceMock } from '../logger/logger.service.mock';
7+
import { UsageService } from '../usage/usage.service';
78

89
describe('AppController', () => {
910
let appController: AppController;
1011

12+
const usageServiceMock = {};
13+
1114
beforeEach(async () => {
1215
const app: TestingModule = await Test.createTestingModule({
1316
controllers: [AppController],
@@ -17,6 +20,10 @@ describe('AppController', () => {
1720
provide: LoggerService,
1821
useValue: LoggerServiceMock,
1922
},
23+
{
24+
provide: UsageService,
25+
useValue: usageServiceMock,
26+
},
2027
],
2128
}).compile();
2229

apps/backend/src/app/app.controller.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Controller, Get, HttpStatus } from '@nestjs/common';
22
import { ApiTags, ApiResponse } from '@nestjs/swagger';
3+
import { TrackUsage } from '../usage/track-usage.decorator';
34
import { AppService } from './app.service';
45

56
@Controller()
@@ -12,6 +13,7 @@ export class AppController {
1213
status: HttpStatus.OK,
1314
description: 'Application is running',
1415
})
16+
@TrackUsage()
1517
getHello(): string {
1618
return this.appService.getHello();
1719
}

apps/backend/src/app/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { LoggerModule } from '../logger/logger.module';
1313
import { AuthModule } from '../auth/auth.module';
1414
import { ApiKeyModule } from '../api-key/api-key.module';
1515
import { CreditModule } from '../credit/credit.module';
16+
import { UsageModule } from '../usage/usage.module';
1617

1718
@Module({
1819
imports: [
@@ -42,6 +43,7 @@ import { CreditModule } from '../credit/credit.module';
4243
AuthModule,
4344
ApiKeyModule,
4445
CreditModule,
46+
UsageModule,
4547
],
4648
controllers: [AppController],
4749
providers: [AppService],

apps/backend/src/credit/credit.module.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { AppConfigModule } from '../config/config.module';
1010
@Module({
1111
providers: [CreditService],
1212
controllers: [CreditController],
13+
exports: [CreditService],
1314
imports: [TypeOrmModule.forFeature([Credit]), LoggerModule, AppConfigModule],
1415
})
1516
export class CreditModule {}

apps/backend/src/credit/credit.service.ts

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { CreditDuration } from './interface/credit-duration.interface';
1515
import { ReadCreditError } from './error/read-credit.error';
1616
import { CreateCreditError } from './error/create-credit.error';
1717
import { IncrementCreditError } from './error/increment-credit.error';
18+
import { ReadActiveCreditError } from './error/read-active-credit.error';
1819

1920
@Injectable()
2021
export class CreditService {
@@ -65,10 +66,25 @@ export class CreditService {
6566
}
6667
}
6768

68-
public async incrementActiveCreditUsage(user: User): Promise<void> {
69+
public async getActiveCredit(user: User): Promise<Credit> {
6970
try {
70-
const credit = await this.getActiveCredit(user);
71+
const presentDate = new Date();
7172

73+
return await this.creditRepository.findOneOrFail({
74+
where: {
75+
user,
76+
fromDate: LessThan(presentDate),
77+
toDate: MoreThan(presentDate),
78+
},
79+
});
80+
} catch (error) {
81+
this.loggerService.log(`No active credit is available. ${error}`);
82+
throw new ReadActiveCreditError(error);
83+
}
84+
}
85+
86+
public async incrementCreditUsage(credit: Credit): Promise<void> {
87+
try {
7288
this.checkLimit(credit);
7389
credit.incrementUsage();
7490

@@ -85,18 +101,6 @@ export class CreditService {
85101
}
86102
}
87103

88-
private async getActiveCredit(user: User): Promise<Credit> {
89-
const presentDate = new Date();
90-
91-
return await this.creditRepository.findOneOrFail({
92-
where: {
93-
user,
94-
fromDate: LessThan(presentDate),
95-
toDate: MoreThan(presentDate),
96-
},
97-
});
98-
}
99-
100104
private calculateCreditDuration(duration: CreditDuration): {
101105
fromDate: Date;
102106
toDate: Date;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export class ReadActiveCreditError extends Error {
2+
constructor(error) {
3+
super(`No active credit is available. ${error}`);
4+
}
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export class InvalidApiKeyError extends Error {
2+
constructor(error) {
3+
super(`API Key is invalid. ${error}`);
4+
}
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export class NoActiveCreditError extends Error {
2+
constructor(error) {
3+
super(`No active credit available. ${error}`);
4+
}
5+
}

0 commit comments

Comments
 (0)