Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Cartographier l'ensemble des modules de l'application backend actuelle pour :

| Decision | Choix |
|----------|-------|
| Approche migration | Bottom-up (feuilles d'abord, puis remontee vers les modules couples) |
| Approche migration | Bottom-up (feuilles d'abord, puis remontée vers les modules couples) |
| Contrats API | Decorateurs NestJS natifs + class-validator (abandon de ts-rest) |
| queries-index.ts | Supprime des le depart : chaque module NestJS possede ses propres queries Prisma |
| Systeme d'evenements | `@nestjs/event-emitter` (remplacement progressif de `@cpn-console/hooks`) |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common'
import { HttpStatus, Inject, Injectable } from '@nestjs/common'
import { HealthIndicatorService } from '@nestjs/terminus'
import { ConfigurationService } from '../infrastructure/configuration/configuration.service'

Expand All @@ -16,7 +16,7 @@ export class ArgoCDHealthService {
const url = new URL('/api/version', this.config.argocdUrl).toString()
try {
const response = await fetch(url)
if (response.status < 500) return indicator.up({ httpStatus: response.status })
if (response.status < HttpStatus.INTERNAL_SERVER_ERROR) return indicator.up({ httpStatus: response.status })
return indicator.down({ httpStatus: response.status })
} catch (error) {
return indicator.down(error instanceof Error ? error.message : String(error))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common'
import { HttpStatus, Inject, Injectable } from '@nestjs/common'
import { HealthIndicatorService } from '@nestjs/terminus'
import { ConfigurationService } from '../infrastructure/configuration/configuration.service'

Expand All @@ -17,7 +17,7 @@ export class GitlabHealthService {
const url = new URL('/-/health', urlBase).toString()
try {
const response = await fetch(url)
if (response.status < 500) return indicator.up({ httpStatus: response.status })
if (response.status < HttpStatus.INTERNAL_SERVER_ERROR) return indicator.up({ httpStatus: response.status })
return indicator.down({ httpStatus: response.status })
} catch (error) {
return indicator.down(error instanceof Error ? error.message : String(error))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common'
import { HttpStatus, Inject, Injectable } from '@nestjs/common'
import { HealthIndicatorService } from '@nestjs/terminus'
import { ConfigurationService } from '../infrastructure/configuration/configuration.service'

Expand All @@ -18,7 +18,7 @@ export class KeycloakHealthService {

try {
const response = await fetch(url)
if (response.status < 500) return indicator.up({ httpStatus: response.status })
if (response.status < HttpStatus.INTERNAL_SERVER_ERROR) return indicator.up({ httpStatus: response.status })
return indicator.down({ httpStatus: response.status })
} catch (error) {
return indicator.down(error instanceof Error ? error.message : String(error))
Expand Down
4 changes: 2 additions & 2 deletions apps/server-nestjs/src/modules/nexus/nexus-health.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common'
import { HttpStatus, Inject, Injectable } from '@nestjs/common'
import { HealthIndicatorService } from '@nestjs/terminus'
import { ConfigurationService } from '../infrastructure/configuration/configuration.service'

Expand All @@ -23,7 +23,7 @@ export class NexusHealthService {

try {
const response = await fetch(url, { headers })
if (response.status < 500) return indicator.up({ httpStatus: response.status })
if (response.status < HttpStatus.INTERNAL_SERVER_ERROR) return indicator.up({ httpStatus: response.status })
return indicator.down({ httpStatus: response.status })
} catch (error) {
return indicator.down(error instanceof Error ? error.message : String(error))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common'
import { HttpStatus, Inject, Injectable } from '@nestjs/common'
import { trace } from '@opentelemetry/api'
import { ConfigurationService } from '../infrastructure/configuration/configuration.service'
import { StartActiveSpan } from '../infrastructure/telemetry/telemetry.decorator'
Expand All @@ -10,7 +10,7 @@ export interface NexusFetchOptions {
}

export interface NexusResponse<T = unknown> {
status: number
status: HttpStatus
data: T | null
}

Expand All @@ -21,15 +21,15 @@ export type NexusErrorKind

export class NexusError extends Error {
readonly kind: NexusErrorKind
readonly status?: number
readonly status?: HttpStatus
readonly method?: string
readonly path?: string
readonly statusText?: string

constructor(
kind: NexusErrorKind,
message: string,
details: { status?: number, method?: string, path?: string, statusText?: string } = {},
details: { status?: HttpStatus, method?: string, path?: string, statusText?: string } = {},
) {
super(message)
this.name = 'NexusError'
Expand Down Expand Up @@ -119,7 +119,7 @@ export class NexusHttpClientService {
}

async function handleResponse<T>(response: Response): Promise<NexusResponse<T>> {
if (response.status === 204) return { status: response.status, data: null }
if (response.status === HttpStatus.NO_CONTENT) return { status: response.status, data: null }
const contentType = response.headers.get('content-type') ?? ''
const parsed = contentType.includes('application/json')
? await response.json()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common'
import { HttpStatus, Inject, Injectable } from '@nestjs/common'
import { HealthIndicatorService } from '@nestjs/terminus'
import { ConfigurationService } from '../infrastructure/configuration/configuration.service'

Expand All @@ -21,7 +21,7 @@ export class OpenCdsHealthService {
}

const response = await fetch(url, { headers })
if (response.status < 500) return indicator.up({ httpStatus: response.status })
if (response.status < HttpStatus.INTERNAL_SERVER_ERROR) return indicator.up({ httpStatus: response.status })
return indicator.down({ httpStatus: response.status })
} catch (error) {
return indicator.down(error instanceof Error ? error.message : String(error))
Expand Down
8 changes: 4 additions & 4 deletions apps/server-nestjs/src/modules/project/project.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { FastifyRequest } from 'fastify'
import type { UserContext } from '../infrastructure/auth/auth-user.decorator'
import type { ProjectContext } from '../infrastructure/permission/project/project.guard'
import { AdminAuthorized, projectContract } from '@cpn-console/shared'
import { Body, Controller, Delete, ForbiddenException, Get, HttpCode, Inject, Post, Put, Query, Req, UseGuards } from '@nestjs/common'
import { Body, Controller, Delete, ForbiddenException, Get, HttpCode, HttpStatus, Inject, Post, Put, Query, Req, UseGuards } from '@nestjs/common'
import { json2csv } from 'json-2-csv'
import { AuthUser } from '../infrastructure/auth/auth-user.decorator'
import { RequireProjectAccess } from '../infrastructure/permission/project/project-access.decorator'
Expand Down Expand Up @@ -43,7 +43,7 @@ export class ProjectController {
}

@Post('')
@HttpCode(201)
@HttpCode(HttpStatus.CREATED)
@UseGuards(UserGuard)
@RequireAdminPermission('ManageProjects')
async create(
Expand All @@ -64,7 +64,7 @@ export class ProjectController {
}

@Put('/:projectId')
@HttpCode(200)
@HttpCode(HttpStatus.OK)
@UseGuards(ProjectGuard)
@RequireProjectStatus('initializing', 'created', 'failed', 'warning')
@RequireProjectPermission('Manage')
Expand All @@ -78,7 +78,7 @@ export class ProjectController {
}

@Delete('/:projectId')
@HttpCode(204)
@HttpCode(HttpStatus.NO_CONTENT)
@UseGuards(ProjectGuard)
@RequireProjectPermission('Manage')
async archive(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common'
import { HttpStatus, Inject, Injectable } from '@nestjs/common'
import { HealthIndicatorService } from '@nestjs/terminus'
import { ConfigurationService } from '../infrastructure/configuration/configuration.service'

Expand All @@ -23,7 +23,7 @@ export class RegistryHealthService {

try {
const response = await fetch(url, { method: 'GET', headers })
if (response.status < 500) return indicator.up({ httpStatus: response.status })
if (response.status < HttpStatus.INTERNAL_SERVER_ERROR) return indicator.up({ httpStatus: response.status })
return indicator.down({ httpStatus: response.status })
} catch (error) {
return indicator.down(error instanceof Error ? error.message : String(error))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common'
import { HttpStatus, Inject, Injectable } from '@nestjs/common'
import { trace } from '@opentelemetry/api'
import { ConfigurationService } from '../infrastructure/configuration/configuration.service'
import { encodeBasicAuth } from './registry.utils'
Expand All @@ -13,7 +13,7 @@ export interface RegistryFetchOptions {
}

export interface RegistryResponse<T = unknown> {
status: number
status: HttpStatus
data: T | null
}

Expand All @@ -23,15 +23,15 @@ export type RegistryErrorKind

export class RegistryError extends Error {
readonly kind: RegistryErrorKind
readonly status?: number
readonly status?: HttpStatus
readonly method?: string
readonly path?: string
readonly statusText?: string

constructor(
kind: RegistryErrorKind,
message: string,
details: { status?: number, method?: string, path?: string, statusText?: string } = {},
details: { status?: HttpStatus, method?: string, path?: string, statusText?: string } = {},
) {
super(message)
this.name = 'RegistryError'
Expand Down Expand Up @@ -112,7 +112,7 @@ export class RegistryHttpClientService {
}

async function handleResponse<T>(response: Response): Promise<RegistryResponse<T>> {
if (response.status === 204) return { status: response.status, data: null }
if (response.status === HttpStatus.NO_CONTENT) return { status: response.status, data: null }
const contentType = response.headers.get('content-type') ?? ''
const parsed = contentType.includes('application/json')
? await response.json()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import type { ProjectWithDetails } from './registry-datastore.service'
import type { RegistryResponse } from './registry-http-client.service'
import { faker } from '@faker-js/faker'
import { HttpStatus } from '@nestjs/common'

export function makeOkResponse<T>(data: T): RegistryResponse<T> {
return { status: 200, data }
return { status: HttpStatus.OK, data }
}

export function makeCreatedResponse<T>(data: T): RegistryResponse<T> {
return { status: 201, data }
return { status: HttpStatus.CREATED, data }
}

export function makeNoContent(): RegistryResponse<null> {
return { status: 204, data: null }
return { status: HttpStatus.NO_CONTENT, data: null }
}

export function makeProjectWithDetails(overrides: Partial<ProjectWithDetails> = {}) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { DeepMockProxy } from 'vitest-mock-extended'
import { ENABLED } from '@cpn-console/shared'
import { faker } from '@faker-js/faker'
import { HttpStatus } from '@nestjs/common'
import { Test } from '@nestjs/testing'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { mockDeep } from 'vitest-mock-extended'
Expand Down Expand Up @@ -132,9 +133,9 @@ describe('registryService', () => {
const project = makeProjectWithDetails()
client.addGroupMember.mockImplementation(async (_projectName, body) => {
if (body.member_group.group_name === `/${project.slug}/console/admin` && body.role_id === 2) {
return { status: 400, data: null }
return { status: HttpStatus.BAD_REQUEST, data: null }
}
return { status: 201, data: null }
return { status: HttpStatus.CREATED, data: null }
})

await expect(service.handleUpsert(project)).resolves.toEqual({
Expand Down Expand Up @@ -301,7 +302,7 @@ describe('registryService', () => {
})

it('should not delete project when it does not exist', async () => {
client.getProjectByName.mockResolvedValueOnce({ status: 404, data: null })
client.getProjectByName.mockResolvedValueOnce({ status: HttpStatus.NOT_FOUND, data: null })
await service.handleDelete(makeProjectWithDetails())
expect(client.deleteProjectByName).not.toHaveBeenCalled()
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { HttpStatus } from '@nestjs/common'
import type { Dispatcher, HeadersInit } from 'undici'
import { Inject, Injectable, Logger } from '@nestjs/common'
import { Agent, fetch, Headers, ProxyAgent } from 'undici'
Expand All @@ -19,7 +20,7 @@ export interface OpenCdsRequestOptions {

export class OpenCdsClientError extends Error {
constructor(
public readonly status: number,
public readonly status: HttpStatus,
public readonly statusText: string,
public readonly body?: string,
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { HttpStatus } from '@nestjs/common'
import type { Response } from 'undici'

export class OpenCdsClientError extends Error {
constructor(
public readonly status: number,
public readonly status: HttpStatus,
public readonly statusText: string,
public readonly body?: string,
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common'
import { HttpStatus, Inject, Injectable } from '@nestjs/common'
import { HealthIndicatorService } from '@nestjs/terminus'
import { ConfigurationService } from '../infrastructure/configuration/configuration.service'

Expand All @@ -24,7 +24,7 @@ export class SonarqubeHealthService {

try {
const response = await fetch(url, { headers })
if (response.status < 500) return indicator.up({ httpStatus: response.status })
if (response.status < HttpStatus.INTERNAL_SERVER_ERROR) return indicator.up({ httpStatus: response.status })
return indicator.down({ httpStatus: response.status })
} catch (error) {
return indicator.down(error instanceof Error ? error.message : String(error))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common'
import { HttpStatus, Inject, Injectable } from '@nestjs/common'
import { trace } from '@opentelemetry/api'
import { ConfigurationService } from '../infrastructure/configuration/configuration.service'

Expand All @@ -8,22 +8,22 @@ export interface SonarqubeFetchOptions {
}

export interface SonarqubeResponse<T = unknown> {
status: number
status: HttpStatus
data: T | null
}

export type SonarqubeErrorKind = 'NotConfigured' | 'ClientError' | 'ServerError' | 'Unexpected'

export class SonarqubeError extends Error {
readonly kind: SonarqubeErrorKind
readonly status?: number
readonly status?: HttpStatus
readonly method?: string
readonly path?: string

constructor(
kind: SonarqubeErrorKind,
message: string,
details: { status?: number, method?: string, path?: string } = {},
details: { status?: HttpStatus, method?: string, path?: string } = {},
) {
super(message)
this.name = 'SonarqubeError'
Expand Down Expand Up @@ -99,7 +99,7 @@ function formatErrorMessage(status: number, data: unknown): string {
}

async function handleResponse<T>(response: Response): Promise<SonarqubeResponse<T>> {
if (response.status === 204) return { status: response.status, data: null }
if (response.status === HttpStatus.NO_CONTENT) return { status: response.status, data: null }
const contentType = response.headers.get('content-type') ?? ''
const parsed = contentType.includes('application/json')
? await response.json()
Expand Down
4 changes: 2 additions & 2 deletions apps/server-nestjs/src/modules/vault/vault-health.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable } from '@nestjs/common'
import { HttpStatus, Inject, Injectable } from '@nestjs/common'
import { HealthIndicatorService } from '@nestjs/terminus'
import { ConfigurationService } from '../infrastructure/configuration/configuration.service'

Expand All @@ -17,7 +17,7 @@ export class VaultHealthService {
const url = new URL('/v1/sys/health', urlBase).toString()
try {
const response = await fetch(url)
if (response.status < 500) return indicator.up({ httpStatus: response.status })
if (response.status < HttpStatus.INTERNAL_SERVER_ERROR) return indicator.up({ httpStatus: response.status })
return indicator.down({ httpStatus: response.status })
} catch (error) {
return indicator.down(error instanceof Error ? error.message : String(error))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable, Logger } from '@nestjs/common'
import { HttpStatus, Inject, Injectable, Logger } from '@nestjs/common'
import { trace } from '@opentelemetry/api'
import z from 'zod'
import { ConfigurationService } from '../infrastructure/configuration/configuration.service'
Expand All @@ -19,7 +19,7 @@ export type VaultErrorKind

export class VaultError extends Error {
readonly kind: VaultErrorKind
readonly status?: number
readonly status?: HttpStatus
readonly method?: string
readonly path?: string
readonly statusText?: string
Expand All @@ -28,7 +28,7 @@ export class VaultError extends Error {
constructor(
kind: VaultErrorKind,
message: string,
details: { status?: number, method?: string, path?: string, statusText?: string, reasons?: string[] } = {},
details: { status?: HttpStatus, method?: string, path?: string, statusText?: string, reasons?: string[] } = {},
) {
super(message)
this.name = 'VaultError'
Expand Down Expand Up @@ -113,7 +113,7 @@ export class VaultHttpClientService {
}

private async handleResponse<T>(response: Response, method: string, path: string): Promise<T | null> {
if (response.status === 204) return null
if (response.status === HttpStatus.NO_CONTENT) return null

if (!response.ok) {
await this.throwForStatus(response, method, path)
Expand Down