Skip to content

Commit

Permalink
Feat/package details (#267)
Browse files Browse the repository at this point in the history
* feat: add package details

* feat: view released package details

* feat: view released package details 2

* feat: improve details display

* fix: vertex.id
  • Loading branch information
mbystedt authored Sep 18, 2024
1 parent c50f9f9 commit ae331d3
Show file tree
Hide file tree
Showing 56 changed files with 1,197 additions and 438 deletions.
8 changes: 8 additions & 0 deletions src/collection/collection.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,14 @@ export class CollectionController {
name: 'dir',
required: false,
})
@ApiQuery({
name: 'offset',
required: false,
})
@ApiQuery({
name: 'limit',
required: false,
})
@ApiQuery({
name: 'id',
required: false,
Expand Down
2 changes: 0 additions & 2 deletions src/collection/collection.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,6 @@ export class CollectionService {

async getServiceDetails(serviceId: string) {
const service = await this.graphRepository.getServiceDetails(serviceId);
const builds = await this.buildRepository.searchBuild(serviceId, 0, 5);
if (!service) {
throw new NotFoundException({
statusCode: 404,
Expand All @@ -305,7 +304,6 @@ export class CollectionService {
}
return {
...service,
builds,
};
}

Expand Down
20 changes: 18 additions & 2 deletions src/collection/dto/collection-search-result.dto.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
// Shared DTO: Copy in back-end and front-end should be identical

export class CollectionSearchResult<T> {
data!: T[];
import { VertexRestDto } from '../../persistence/dto/vertex-rest.dto';
import { CollectionDtoUnion } from '../../persistence/dto/collection-dto-union.type';
import { GraphDirectedRestCombo } from '../../persistence/dto/collection-combo-rest.dto';

export class CollectionSearchResult<
T extends CollectionDtoUnion[keyof CollectionDtoUnion],
> {
data!: CollectionCombo<T>[];
meta!: {
total: number;
};
}

export class CollectionCombo<
T extends CollectionDtoUnion[keyof CollectionDtoUnion],
> {
type!: 'vertex';
collection!: T;
vertex!: VertexRestDto;
upstream!: GraphDirectedRestCombo[];
downstream!: GraphDirectedRestCombo[];
}
32 changes: 32 additions & 0 deletions src/collection/dto/package-build-search-query.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Type } from 'class-transformer';
import { IsInt, IsOptional, IsString } from 'class-validator';

export class PackageBuildSearchQuery {
@IsOptional()
@IsString()
@Type(() => String)
serviceId?: string;

@IsOptional()
@IsString()
@Type(() => String)
vertexId?: string;

@IsOptional()
@IsString()
@Type(() => String)
sort?: string;

@IsOptional()
@IsString()
@Type(() => String)
dir?: string;

@IsInt()
@Type(() => Number)
offset: number;

@IsInt()
@Type(() => Number)
limit: number;
}
11 changes: 11 additions & 0 deletions src/graph/intention-sync.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { CollectionRepository } from '../persistence/interfaces/collection.repos
import { IntentionActionPointerDto } from '../persistence/dto/intention-action-pointer.dto';
import { BuildRepository } from '../persistence/interfaces/build.repository';
import { BrokerAccountDto } from '../persistence/dto/broker-account.dto';
import { IntentionRepository } from '../persistence/interfaces/intention.repository';

interface OverlayMapBase {
key: string;
Expand All @@ -43,6 +44,7 @@ export class IntentionSyncService {
private readonly collectionRepository: CollectionRepository,
private readonly graphService: GraphService,
private readonly graphRepository: GraphRepository,
private readonly intentionRepository: IntentionRepository,
private readonly persistenceUtilService: PersistenceUtilService,
private readonly actionUtil: ActionUtil,
) {}
Expand Down Expand Up @@ -128,6 +130,15 @@ export class IntentionSyncService {
parsedVersion,
action.package,
);

// Warning: Setting it here because close uses sideffects
action.package.id = packageBuild.id;

await this.intentionRepository.setActionPackageBuildRef(
intention.id,
action.id,
packageBuild.id,
);
}

if (action.action === 'package-installation') {
Expand Down
1 change: 1 addition & 0 deletions src/intention/dto/package-rest.dto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export class PackageRestDto {
id?: string;
architecture?: string;
buildGuid?: string;
buildNumber?: number;
Expand Down
11 changes: 11 additions & 0 deletions src/intention/dto/package.dto.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import { Transform } from 'class-transformer';
import { IsNumber, IsOptional, IsString } from 'class-validator';
import { Entity, Column } from 'typeorm';
import { ObjectId } from 'mongodb';
import { ApiProperty } from '@nestjs/swagger';

@Entity()
export class PackageDto {
@Column()
@IsOptional()
@ApiProperty({ type: () => String })
@Transform((value) =>
value.obj.id ? new ObjectId(value.obj.id.toString()) : null,
)
id?: ObjectId;

@IsString()
@IsOptional()
@Column()
Expand Down
2 changes: 1 addition & 1 deletion src/intention/intention.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ export class IntentionService {

this.auditService.recordIntentionClose(req, intention, reason);
if (outcome === 'success') {
// All openned intention have link to account
// All open intention have link to account
const account = await this.getAccount(intention.accountId?.toString());
await this.intentionSync.sync(intention, account);
}
Expand Down
38 changes: 37 additions & 1 deletion src/package/package.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@ import {
Get,
Param,
Post,
Query,
Req,
UseGuards,
UsePipes,
ValidationPipe,
} from '@nestjs/common';
import { ApiQuery } from '@nestjs/swagger';
import { Request as ExpressRequest } from 'express';
import { get } from 'radash';

import { BrokerOidcAuthGuard } from '../auth/broker-oidc-auth.guard';
import { OAUTH2_CLIENT_MAP_GUID } from '../constants';
import { PackageService } from './package.service';
import { PackageBuildDto } from '../persistence/dto/package-build.dto';
import { BrokerCombinedAuthGuard } from '../auth/broker-combined-auth.guard';
import { PackageBuildSearchQuery } from '../collection/dto/package-build-search-query.dto';
import { PackageBuildSearchResult } from '../persistence/dto/package-build-rest.dto';

@Controller({
path: 'package',
Expand All @@ -21,8 +29,36 @@ import { PackageBuildDto } from '../persistence/dto/package-build.dto';
export class PackageController {
constructor(private readonly service: PackageService) {}

@Get(':id')
@Post('search')
@UseGuards(BrokerOidcAuthGuard)
@UsePipes(new ValidationPipe({ transform: true }))
@ApiQuery({
name: 'serviceId',
required: true,
})
@ApiQuery({
name: 'sort',
required: false,
})
@ApiQuery({
name: 'dir',
required: false,
})
async search(
@Query() query: PackageBuildSearchQuery,
): Promise<PackageBuildSearchResult> {
console.log(query);
return this.service.search(
query.serviceId,
query.sort,
query.dir,
query.offset,
query.limit,
);
}

@Get(':id')
@UseGuards(BrokerCombinedAuthGuard)
async get(@Param('id') id: string): Promise<PackageBuildDto> {
return this.service.get(id);
}
Expand Down
3 changes: 2 additions & 1 deletion src/package/package.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { Module } from '@nestjs/common';
import { PackageController } from './package.controller';
import { PackageService } from './package.service';
import { AuditModule } from '../audit/audit.module';
import { AuthModule } from '../auth/auth.module';
import { PersistenceModule } from '../persistence/persistence.module';
import { RedisModule } from '../redis/redis.module';

@Module({
imports: [AuditModule, PersistenceModule, RedisModule],
imports: [AuthModule, AuditModule, PersistenceModule, RedisModule],
controllers: [PackageController],
providers: [PackageService],
})
Expand Down
10 changes: 10 additions & 0 deletions src/package/package.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ export class PackageService {
return this.buildRepository.getBuild(id);
}

async search(
serviceId: string,
sort: string | undefined,
dir: string | undefined,
offset: number,
limit: number,
) {
return this.buildRepository.searchBuild(serviceId, offset, limit);
}

async approve(req: Request, id: string, userGuid: string): Promise<boolean> {
const user = req.user;
const packageDto = await this.buildRepository.getBuild(id);
Expand Down
7 changes: 7 additions & 0 deletions src/persistence/dto/package-build-rest.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ import { PackageRestDto } from '../../intention/dto/package-rest.dto';
import { IntentionActionPointerRestDto } from './intention-action-pointer-rest.dto';
import { TimestampRestDto } from './timestamp-rest.dto';

export class PackageBuildSearchResult {
data!: PackageBuildRestDto[];
meta!: {
total: number;
};
}

class PackageBuildApprovalRestDto {
environment!: string;
user!: string;
Expand Down
5 changes: 2 additions & 3 deletions src/persistence/dto/service-rest.dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { CollectionSearchResult } from '../../collection/dto/collection-search-result.dto';
import { PackageBuildRestDto } from './package-build-rest.dto';
import { PackageBuildSearchResult } from './package-build-rest.dto';
import { ServiceInstanceDetailsResponseDto } from './service-instance-rest.dto';
import { VaultConfigRestDto } from './vault-config-rest.dto';
import { VertexPointerRestDto } from './vertex-pointer-rest.dto';
Expand All @@ -16,5 +15,5 @@ export class ServiceRestDto extends VertexPointerRestDto {

export class ServiceDetailsResponseDto extends ServiceRestDto {
serviceInstance: ServiceInstanceDetailsResponseDto[];
builds: CollectionSearchResult<PackageBuildRestDto>;
builds: PackageBuildSearchResult;
}
4 changes: 2 additions & 2 deletions src/persistence/interfaces/build.repository.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { CollectionSearchResult } from '../../collection/dto/collection-search-result.dto';
import { PackageDto } from '../../intention/dto/package.dto';
import { SemverVersion } from '../../util/action.util';
import { EnvironmentDto } from '../dto/environment.dto';
import { IntentionActionPointerDto } from '../dto/intention-action-pointer.dto';
import { PackageBuildSearchResult } from '../dto/package-build-rest.dto';
import { PackageBuildDto } from '../dto/package-build.dto';
import { UserDto } from '../dto/user.dto';

Expand Down Expand Up @@ -31,7 +31,7 @@ export abstract class BuildRepository {
serviceId: string,
offset: number,
limit: number,
): Promise<CollectionSearchResult<PackageBuildDto>>;
): Promise<PackageBuildSearchResult>;

public abstract approvePackage(
packageBuild: PackageBuildDto,
Expand Down
6 changes: 6 additions & 0 deletions src/persistence/interfaces/intention.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,11 @@ export abstract class IntentionRepository {
limit: number,
): Promise<IntentionSearchResult>;

public abstract setActionPackageBuildRef(
id: ObjectId,
actionId: string,
packageId: ObjectId,
): Promise<void>;

public abstract cleanupTransient(transientTtl: number): Promise<void>;
}
15 changes: 15 additions & 0 deletions src/persistence/mongo/intention-mongo.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,21 @@ export class IntentionMongoRepository implements IntentionRepository {
});
}

public async setActionPackageBuildRef(
id: ObjectId,
actionId: string,
packageId: ObjectId,
): Promise<void> {
await this.intentionRepository.updateOne(
{ _id: id, 'actions.id': actionId },
{
$set: {
'actions.$.package.id': packageId,
},
},
);
}

public async cleanupTransient(transientTtl: number): Promise<void> {
this.intentionRepository.deleteMany({
'event.transient': true,
Expand Down
Loading

0 comments on commit ae331d3

Please sign in to comment.