From 39c66f030abb3d6923ca76167125c9eac5e0701f Mon Sep 17 00:00:00 2001 From: marcos-silva-rodrigues Date: Mon, 25 May 2026 14:01:00 -0300 Subject: [PATCH] FIX: release note endpoint --- docsfera.json | 23 ++++++++++ src/app.module.ts | 3 ++ .../release_note/dto/release_note.dto.ts | 14 ++++++ .../release_note.controller.spec.ts | 20 ++++++++ .../release_note/release_note.controller.ts | 26 +++++++++++ .../release_note/release_note.module.ts | 10 ++++ .../release_note/release_note.service.spec.ts | 18 ++++++++ .../release_note/release_note.service.ts | 46 +++++++++++++++++++ 8 files changed, 160 insertions(+) create mode 100644 src/modules/release_note/dto/release_note.dto.ts create mode 100644 src/modules/release_note/release_note.controller.spec.ts create mode 100644 src/modules/release_note/release_note.controller.ts create mode 100644 src/modules/release_note/release_note.module.ts create mode 100644 src/modules/release_note/release_note.service.spec.ts create mode 100644 src/modules/release_note/release_note.service.ts diff --git a/docsfera.json b/docsfera.json index 00b43df..c68e491 100644 --- a/docsfera.json +++ b/docsfera.json @@ -8636,6 +8636,29 @@ "Health" ] } + }, + "/release_note": { + "get": { + "operationId": "ReleaseNoteController_getLatestReleaseNote", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + }, + "security": [ + { + "access-token": [] + } + ] + } } }, "info": { diff --git a/src/app.module.ts b/src/app.module.ts index 0865ad2..4db914b 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -35,6 +35,8 @@ import { ShareMetadataModule } from './modules/share-metadata/share-metadata.mod import { ApiKeyModule } from './modules/api-key/api-key.module'; import { PlatformApiModule } from './modules/platform-api/platform-api.module'; import { StorageExplorerModule } from './modules/storage-explorer/storage-explorer.module'; +import { ReleaseNoteModule } from './modules/release_note/release_note.module'; + @Module({ providers: [ @@ -79,6 +81,7 @@ import { StorageExplorerModule } from './modules/storage-explorer/storage-explor StorageExplorerModule, //Always leave HealthModule last, so it is on the bottom of swagger HealthModule, + ReleaseNoteModule, ], }) export class AppModule {} diff --git a/src/modules/release_note/dto/release_note.dto.ts b/src/modules/release_note/dto/release_note.dto.ts new file mode 100644 index 0000000..22cc745 --- /dev/null +++ b/src/modules/release_note/dto/release_note.dto.ts @@ -0,0 +1,14 @@ +export type ReleaseNoteDTO = { + id: string; + date: string; + tag: string; + title: string; + visible: boolean; + expiryDate: string; + content: string; + showEmojis: boolean; + image?: string; + link?: string; + linkText?: string; + }; + \ No newline at end of file diff --git a/src/modules/release_note/release_note.controller.spec.ts b/src/modules/release_note/release_note.controller.spec.ts new file mode 100644 index 0000000..921eca1 --- /dev/null +++ b/src/modules/release_note/release_note.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ReleaseNoteController } from './release_note.controller'; +import { ReleaseNoteService } from './release_note.service'; + +describe('ReleaseNoteController', () => { + let controller: ReleaseNoteController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [ReleaseNoteController], + providers: [ReleaseNoteService], + }).compile(); + + controller = module.get(ReleaseNoteController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/modules/release_note/release_note.controller.ts b/src/modules/release_note/release_note.controller.ts new file mode 100644 index 0000000..fde44bd --- /dev/null +++ b/src/modules/release_note/release_note.controller.ts @@ -0,0 +1,26 @@ +import { Controller, Get, Inject } from '@nestjs/common'; +import { ReleaseNoteService } from './release_note.service'; +import { Authenticated } from 'src/decorators/authentication.decorator'; +import { Language } from 'src/decorators/language.decorator'; +import { LanguageEnum } from 'src/utils/languages.enum'; +import DadosferaLogger from '@dadosfera/dadosfera-logs'; + +@Controller('release_note') +@Authenticated() +export class ReleaseNoteController { + logger: DadosferaLogger; + + constructor( + @Inject(DadosferaLogger) + dadosferaLogger: DadosferaLogger, + private readonly releaseNoteService: ReleaseNoteService, + ) { + this.logger = dadosferaLogger.logger; + } + + @Get() + async getLatestReleaseNote(@Language() language: LanguageEnum) { + this.logger.info(`Fetching latest release note for language: ${language}`); + return await this.releaseNoteService.getLatestReleaseNote(language); + } +} diff --git a/src/modules/release_note/release_note.module.ts b/src/modules/release_note/release_note.module.ts new file mode 100644 index 0000000..60cb55c --- /dev/null +++ b/src/modules/release_note/release_note.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { ReleaseNoteService } from './release_note.service'; +import { ReleaseNoteController } from './release_note.controller'; +import DadosferaLogger from '@dadosfera/dadosfera-logs'; + +@Module({ + controllers: [ReleaseNoteController], + providers: [ReleaseNoteService, DadosferaLogger] +}) +export class ReleaseNoteModule {} diff --git a/src/modules/release_note/release_note.service.spec.ts b/src/modules/release_note/release_note.service.spec.ts new file mode 100644 index 0000000..72add9d --- /dev/null +++ b/src/modules/release_note/release_note.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ReleaseNoteService } from './release_note.service'; + +describe('ReleaseNoteService', () => { + let service: ReleaseNoteService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ReleaseNoteService], + }).compile(); + + service = module.get(ReleaseNoteService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/modules/release_note/release_note.service.ts b/src/modules/release_note/release_note.service.ts new file mode 100644 index 0000000..776d6e0 --- /dev/null +++ b/src/modules/release_note/release_note.service.ts @@ -0,0 +1,46 @@ +import { Inject, Injectable } from '@nestjs/common'; +import axios, { AxiosInstance } from 'axios'; +import { LanguageEnum } from 'src/utils/languages.enum'; +import { ReleaseNoteDTO } from './dto/release_note.dto'; +import DadosferaLogger from '@dadosfera/dadosfera-logs'; + +@Injectable() +export class ReleaseNoteService { + client: AxiosInstance; + logger: DadosferaLogger; + + constructor( + @Inject(DadosferaLogger) + dadosferaLogger: DadosferaLogger, + ) { + this.logger = dadosferaLogger.logger; + this.client = axios.create({ + baseURL: process.env.FIREBASE_BASE_URL, + }); + } + + async getLatestReleaseNote(lang: LanguageEnum) { + try { + const lng = lang.split('-'); + const language = lng[0] + '-' + lng[1].toUpperCase(); + + const endpoint = `/release_note/${language}.json`; + const { + data, + status, + config + } = await this.client.get(endpoint) + this.logger.info(`Fetched release note for language: ${lang} with status: ${status}`); + this.logger.info(`Request URL: ${config.baseURL}/${config.url}`); + + return data; + } catch (error) { + this.logger.error(`Error fetching release note: ${error.message}`); + + if (axios.isAxiosError(error)) { + this.logger.error(`Axios error details: ${error.toJSON()}`); + } + } + + } +}