forked from valueadd-poland/pimp-my-pr
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(api-repository): add backend for timeline statistics
-add endpoint for acquiring statistics -upgrade github/gitlab/bitbucket remote repositories to handle pagination and state filters -add util for processing prs into timeline staticstics, currently the following fields are available: { sumCount: all PR that were open in subperiod avgCount: avg count of PR that were open in subperiod avgWaitingTime: avg time taht prs were waiting since creation } resolve valueadd-poland#160 - backend
- Loading branch information
1 parent
be06135
commit 06ffa08
Showing
63 changed files
with
872 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
libs/server/repository/api-rest/src/lib/controllers/timeline.controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { ApiBearerAuth, ApiOkResponse, ApiTags } from '@nestjs/swagger'; | ||
import { Controller, Get, Param, Query, UseGuards, UsePipes, ValidationPipe } from '@nestjs/common'; | ||
import { AuthGuard, Credentials, RequestCredentials } from '@pimp-my-pr/server/auth/public'; | ||
import { | ||
GetPrTimelineQuery, | ||
PrTimelineReadModel, | ||
TimelineFacade | ||
} from '@pimp-my-pr/server/repository/core/application-services'; | ||
import { GenerateTimelineDto } from '../dtos/generate-timeline.dto'; | ||
import { decreaseDateByTimelineStep } from '@pimp-my-pr/server/repository/util'; | ||
import { TimelineStep } from '@pimp-my-pr/shared/domain'; | ||
|
||
@ApiTags('timeline') | ||
@UseGuards(AuthGuard) | ||
@ApiBearerAuth() | ||
@Controller('timeline') | ||
export class TimelineController { | ||
constructor(private timelineFacade: TimelineFacade) {} | ||
|
||
@ApiOkResponse({ type: [PrTimelineReadModel] }) | ||
@Get('pr/:repositoryId') | ||
generateTimeline( | ||
@Credentials() credentials: RequestCredentials, | ||
@Param('repositoryId') repositoryId: string, | ||
@Query() query: GenerateTimelineDto | ||
): Promise<PrTimelineReadModel> { | ||
return this.timelineFacade.getPrTimeLine( | ||
new GetPrTimelineQuery( | ||
query.step, | ||
query.timelineFrom, | ||
query.timelineTo, | ||
credentials.token, | ||
repositoryId, | ||
credentials.platform, | ||
// TODO: Find a better solution to handle this problem | ||
decreaseDateByTimelineStep(query.timelineFrom, TimelineStep.MONTH, 3) | ||
) | ||
); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
libs/server/repository/api-rest/src/lib/dtos/generate-timeline.dto.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
import { IsDate, IsIn } from 'class-validator'; | ||
import { Transform } from 'class-transformer'; | ||
import { TimelineStep } from '@pimp-my-pr/shared/domain'; | ||
|
||
export class GenerateTimelineDto { | ||
@ApiProperty({ enum: TimelineStep }) | ||
@IsIn(Object.values(TimelineStep)) | ||
step: TimelineStep; | ||
|
||
@ApiProperty({ | ||
description: 'Beginning of the tracked period - every subsequent record is older' | ||
}) | ||
@IsDate() | ||
@Transform(value => new Date(value)) | ||
timelineFrom: Date; | ||
|
||
@ApiProperty({ | ||
description: 'Beginning of the tracked period - every subsequent record is older' | ||
}) | ||
@IsDate() | ||
@Transform(value => new Date(value)) | ||
timelineTo: Date; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
...tory/core/application-services/src/lib/queries/get-pr-timeline/get-pr-timeline.handler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { IQueryHandler, QueryHandler } from '@nestjs/cqrs'; | ||
import { GetPrTimelineQuery } from './get-pr-timeline.query'; | ||
import { | ||
PrRepository, | ||
prRepositoryFactoryToken, | ||
RepositoryRepository | ||
} from '@pimp-my-pr/server/repository/core/domain-services'; | ||
import { PrTimelineReadModel } from '@pimp-my-pr/server/repository/core/application-services'; | ||
import { | ||
getTimeLineHistory, | ||
InvalidTimelineParametersException, | ||
PrEntity, | ||
PrState | ||
} from '@pimp-my-pr/server/repository/core/domain'; | ||
import { prTimelineModelFactory } from '../../read-models/factories/pr-timeline-model.factory'; | ||
import { Inject } from '@nestjs/common'; | ||
import { Platform } from '@pimp-my-pr/shared/domain'; | ||
import { getStepsCount, traversePagesUntil } from '@pimp-my-pr/server/repository/util'; | ||
|
||
@QueryHandler(GetPrTimelineQuery) | ||
export class GetPrTimelineHandler implements IQueryHandler<GetPrTimelineQuery> { | ||
constructor( | ||
@Inject(prRepositoryFactoryToken) | ||
private prRepositoryFactory: (platform: Platform) => PrRepository, | ||
private repoRepository: RepositoryRepository | ||
) {} | ||
|
||
async execute(query: GetPrTimelineQuery): Promise<PrTimelineReadModel> { | ||
const { repositoryId, step, timelineFrom, timelineTo, token, platform, createdAfter } = query; | ||
const { fullName } = await this.repoRepository.getById(repositoryId); | ||
const prRepository = this.prRepositoryFactory(platform); | ||
|
||
const prs = await traversePagesUntil<PrEntity>( | ||
async page => | ||
await prRepository.findByRepositoryId(fullName, token, { | ||
prState: PrState.ALL, | ||
page, | ||
onPage: 100 | ||
}), | ||
100, | ||
createdAfter | ||
); | ||
const stepsCount = getStepsCount(timelineFrom, timelineTo, step); | ||
if (stepsCount === 0) throw new InvalidTimelineParametersException('timelineFrom'); | ||
|
||
const records = getTimeLineHistory(prs, step, timelineTo, stepsCount); | ||
return prTimelineModelFactory(records, query, prs.length); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
...sitory/core/application-services/src/lib/queries/get-pr-timeline/get-pr-timeline.query.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { IQuery } from '@nestjs/cqrs'; | ||
import { Platform, TimelineStep } from '@pimp-my-pr/shared/domain'; | ||
|
||
export class GetPrTimelineQuery implements IQuery { | ||
constructor( | ||
public step: TimelineStep, | ||
public timelineFrom: Date, | ||
public timelineTo: Date, | ||
public token: string, | ||
public repositoryId: string, | ||
public platform: Platform, | ||
public createdAfter: Date | ||
) {} | ||
} |
29 changes: 29 additions & 0 deletions
29
...itory/core/application-services/src/lib/queries/get-pr-timeline/pr-timeline.read-model.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { TimelineRecord } from '@pimp-my-pr/server/repository/core/domain'; | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
import { TimelineStep } from '@pimp-my-pr/shared/domain'; | ||
|
||
export class PrTimelineReadModel { | ||
@ApiProperty({ | ||
enum: TimelineStep | ||
}) | ||
step: TimelineStep; | ||
|
||
@ApiProperty() | ||
dateFrom: Date; | ||
|
||
@ApiProperty() | ||
dateTo: Date; | ||
|
||
@ApiProperty({ | ||
description: 'Pull requests were taken into account that were created after this date' | ||
}) | ||
createdAfter: Date; | ||
|
||
@ApiProperty({ | ||
type: [TimelineRecord] | ||
}) | ||
data: TimelineRecord[]; | ||
|
||
@ApiProperty() | ||
totalPrs: number; | ||
} |
20 changes: 20 additions & 0 deletions
20
...tory/core/application-services/src/lib/read-models/factories/pr-timeline-model.factory.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { | ||
GetPrTimelineQuery, | ||
PrTimelineReadModel | ||
} from '@pimp-my-pr/server/repository/core/application-services'; | ||
import { TimelineRecord } from '@pimp-my-pr/server/repository/core/domain'; | ||
|
||
export const prTimelineModelFactory = ( | ||
prRecords: TimelineRecord[], | ||
query: GetPrTimelineQuery, | ||
totalPrs: number | ||
): PrTimelineReadModel => { | ||
return { | ||
data: prRecords, | ||
step: query.step, | ||
dateFrom: query.timelineFrom, | ||
dateTo: query.timelineTo, | ||
createdAfter: query.createdAfter, | ||
totalPrs | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
libs/server/repository/core/application-services/src/lib/timeline.facade.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { QueryBus } from '@nestjs/cqrs'; | ||
import { GetPrTimelineQuery } from './queries/get-pr-timeline/get-pr-timeline.query'; | ||
import { PrTimelineReadModel } from './queries/get-pr-timeline/pr-timeline.read-model'; | ||
import { Injectable } from '@nestjs/common'; | ||
|
||
@Injectable() | ||
export class TimelineFacade { | ||
constructor(private queryBus: QueryBus) {} | ||
|
||
getPrTimeLine(query: GetPrTimelineQuery): Promise<PrTimelineReadModel> { | ||
return this.queryBus.execute(query); | ||
} | ||
} |
7 changes: 6 additions & 1 deletion
7
libs/server/repository/core/domain-services/src/lib/repositories/pr.repository.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,12 @@ | ||
import { PrEntity } from '@pimp-my-pr/server/repository/core/domain'; | ||
import { PrRepositoryFetchParams } from '@pimp-my-pr/server/repository/core/domain'; | ||
|
||
export const prRepositoryFactoryToken = Symbol('prRepositoryFactory'); | ||
|
||
export abstract class PrRepository { | ||
abstract findByRepositoryId(repositoryId: string, token: string): Promise<PrEntity[]>; | ||
abstract findByRepositoryId( | ||
repositoryId: string, | ||
token: string, | ||
params?: PrRepositoryFetchParams | ||
): Promise<PrEntity[]>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 2 additions & 1 deletion
3
libs/server/repository/core/domain/src/lib/entities/pr.entity.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
libs/server/repository/core/domain/src/lib/entities/timeline-record.entity.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { ApiProperty } from '@nestjs/swagger'; | ||
|
||
export class TimelineRecord { | ||
@ApiProperty() | ||
dataFrom: Date; | ||
@ApiProperty() | ||
sumCount: number; | ||
@ApiProperty() | ||
avgCount: number; | ||
@ApiProperty() | ||
avgWaitingTime: number; | ||
/** | ||
* This property is required to calculate total prs in any period on timeline | ||
*/ | ||
@ApiProperty() | ||
closedBefore: number; | ||
/** | ||
* This property is required to calculate total prs in any period on timeline | ||
*/ | ||
@ApiProperty() | ||
openedAfter: number; | ||
} |
5 changes: 5 additions & 0 deletions
5
libs/server/repository/core/domain/src/lib/enums/pr-state.enum.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export enum PrState { | ||
OPEN = 'OPEN', | ||
CLOSED = 'CLOSED', | ||
ALL = 'ALL' | ||
} |
7 changes: 7 additions & 0 deletions
7
...server/repository/core/domain/src/lib/exceptions/invalid-timeline-parameters.exception.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { CoreUnprocessableEntityException } from '@pimp-my-pr/server/shared/domain'; | ||
|
||
export class InvalidTimelineParametersException extends CoreUnprocessableEntityException { | ||
constructor(paramName: string) { | ||
super(`Invalid ${paramName}`); | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
libs/server/repository/core/domain/src/lib/interfaces/i-time-trackable.interface.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export interface ITimeTrackable { | ||
createdAt: Date; | ||
closedAt?: Date; | ||
} |
7 changes: 7 additions & 0 deletions
7
.../server/repository/core/domain/src/lib/interfaces/pr-repository-fetch-params.interface.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { PrState } from '../enums/pr-state.enum'; | ||
|
||
export interface PrRepositoryFetchParams { | ||
prState?: PrState; | ||
page?: number; | ||
onPage?: number; | ||
} |
4 changes: 4 additions & 0 deletions
4
libs/server/repository/core/domain/src/lib/interfaces/timeline-bucket-item.interface.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export interface TimelineBucketItem<T> { | ||
entity: T; | ||
timeIn: number; | ||
} |
5 changes: 5 additions & 0 deletions
5
libs/server/repository/core/domain/src/lib/interfaces/timeline-bucket.interface.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { TimelineBucketItem } from './timeline-bucket-item.interface'; | ||
|
||
export interface TimelineBuckets<T> { | ||
[label: number]: TimelineBucketItem<T>[]; | ||
} |
4 changes: 4 additions & 0 deletions
4
libs/server/repository/core/domain/src/lib/interfaces/timeline-date-range.interface.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export interface TimelineDateRange { | ||
dateFrom: Date; | ||
dateTo: Date; | ||
} |
Oops, something went wrong.