diff --git a/src/app/pages/agenda/agenda.page.ts b/src/app/pages/agenda/agenda.page.ts index 874a1769b..45eecf355 100644 --- a/src/app/pages/agenda/agenda.page.ts +++ b/src/app/pages/agenda/agenda.page.ts @@ -700,8 +700,6 @@ export class AgendaPage implements OnInit { } catch (error) {} - console.log('selectedCalendarIds', selectedCalendarIds) - let load = 0; for (const selectedCalendar of selectedCalendarIds) { diff --git a/src/app/services/Repositorys/Agenda/agenda-data-repository.service.ts b/src/app/services/Repositorys/Agenda/agenda-data-repository.service.ts index bc9fef857..ca2506e37 100644 --- a/src/app/services/Repositorys/Agenda/agenda-data-repository.service.ts +++ b/src/app/services/Repositorys/Agenda/agenda-data-repository.service.ts @@ -14,6 +14,9 @@ import { AgendaLocalDataSourceService } from './agenda-local-data-source.service import { EEventFilterStatus } from './model/enums'; import { isHttpError } from '../../http.service'; import { TracingType } from '../../monitoring/opentelemetry/tracer'; +import { APINODReturn, APIReturn } from '../../decorator/api-validate-schema.decorator'; +import { EventListDataOutputDTOSchema, EventListOutputDTOSchema } from './model/eventListDTOOutput'; +import { EventToApproveDataOutputDTOSchema } from './model/eventToApproveListOutputDTO'; @Injectable({ providedIn: 'root' @@ -75,7 +78,8 @@ export class AgendaDataRepositoryService { try { const result = await this.agendaDataService.getEvents(userId, startDate, endDate, status, category, type).pipe( map((response) => { - return ListEventMapper.toDomain(response.data, calendarOwnerName, userId) + APINODReturn(EventListDataOutputDTOSchema, response, 'get/Events', tracing) + return ListEventMapper.toDomain(response, calendarOwnerName, userId) } )).toPromise() return ok(result) @@ -83,8 +87,8 @@ export class AgendaDataRepositoryService { if(isHttpError(e)) { tracing?.setAttribute('status.code', e.status.toString()) } else { - console.error(e) - tracing?.setAttribute('map.error', JSON.stringify(e.error)) + tracing?.setAttribute('map.error', 'true') + tracing?.setAttribute('map.error.context', JSON.stringify(e)) } return err(e as HttpErrorResponse) } @@ -93,9 +97,10 @@ export class AgendaDataRepositoryService { async eventToApproveList({ userId, startDate = null, endDate = null, status = EEventFilterStatus.Pending, category = null, type = null, calendarOwnerName = '' }, tracing?: TracingType) { try { - const result = await this.agendaDataService.getEvents(userId, startDate = null, endDate = null, status, category = null, type = null).pipe( + const result = await this.agendaDataService.getEvents(userId, startDate = null, endDate = null, status, category = null, type = null, tracing).pipe( map((response) => { - return EventListToApproveMapper.toDomain(response.data, calendarOwnerName, userId) + APINODReturn(EventToApproveDataOutputDTOSchema, response, 'get/ApproveList', tracing) + return EventListToApproveMapper.toDomain(response, calendarOwnerName, userId) } )).toPromise() @@ -104,8 +109,8 @@ export class AgendaDataRepositoryService { if(isHttpError(e)) { tracing?.setAttribute('status.code', e.status.toString()) } else { - console.error(e) - tracing?.setAttribute('map.error', JSON.stringify(e.error)) + tracing?.setAttribute('map.error', 'true') + tracing?.setAttribute('map.error.context', JSON.stringify(e)) } return err(e as HttpErrorResponse) } diff --git a/src/app/services/Repositorys/Agenda/agenda-data.service.ts b/src/app/services/Repositorys/Agenda/agenda-data.service.ts index e56dddde4..ea135b268 100644 --- a/src/app/services/Repositorys/Agenda/agenda-data.service.ts +++ b/src/app/services/Repositorys/Agenda/agenda-data.service.ts @@ -6,6 +6,8 @@ import { SessionStore } from 'src/app/store/session.service'; import { SharedCalendarListOutputDTO, SharedCalendarListOutputDTOSchema } from './model/sharedCalendarOutputDTO'; import { HttpService } from '../../http.service'; import { APIReturn } from '../../decorator/api-validate-schema.decorator'; +import { TracingType } from '../../monitoring/opentelemetry/tracer'; +import { EventListOutputDTOSchema } from './model/eventListDTOOutput'; @Injectable({ providedIn: 'root' @@ -45,7 +47,8 @@ export class AgendaDataService { return this.http.post(`${this.baseUrl}/Events`, eventData); } - getEvents(userId: number, startDate: string, endDate: string, status: number, category: string, type: string): Observable { + // @APIReturn(EventListOutputDTOSchema, 'get/Events') + getEvents(userId: number, startDate: string, endDate: string, status: number, category: string, type: string, tracing?: TracingType): Observable { let params = new HttpParams() .set('UserId', userId) @@ -131,7 +134,7 @@ export class AgendaDataService { } - @APIReturn(SharedCalendarListOutputDTOSchema) + // @APIReturn(SharedCalendarListOutputDTOSchema, 'Users/${SessionStore.user.UserId}/ShareCalendar') async getSharedCalendar() { return await this.httpService.get(`${this.baseUrl}/Users/${SessionStore.user.UserId}/ShareCalendar`); } diff --git a/src/app/services/Repositorys/Agenda/mapper/EventListMapper.ts b/src/app/services/Repositorys/Agenda/mapper/EventListMapper.ts index 5e8edb0d6..f20c9411a 100644 --- a/src/app/services/Repositorys/Agenda/mapper/EventListMapper.ts +++ b/src/app/services/Repositorys/Agenda/mapper/EventListMapper.ts @@ -17,7 +17,7 @@ export class ListEventMapper { // @XTracer({name:'ListEventMapper/toDomain', log: false, bugPrint: false}) static toDomain(dto: EventListOutputDTO, calendarOwnerName: string, userId: string): EventList { - return dto.map((e) => { + return dto.data.map((e) => { let category; if(e.category == EEventCategory.Oficial) { diff --git a/src/app/services/Repositorys/Agenda/mapper/eventToApproveListMapper.ts b/src/app/services/Repositorys/Agenda/mapper/eventToApproveListMapper.ts index 7ec409acd..78516aeec 100644 --- a/src/app/services/Repositorys/Agenda/mapper/eventToApproveListMapper.ts +++ b/src/app/services/Repositorys/Agenda/mapper/eventToApproveListMapper.ts @@ -19,7 +19,7 @@ export class EventListToApproveMapper { static toDomain(dtoList: EventToApproveListOutputDTO, calendarOwnerName: string, userId: string): EventToApproveList { - return dtoList.map((dto) => { + return dtoList.data.map((dto) => { let category; if(dto.category == EEventCategory.Oficial) { @@ -27,7 +27,7 @@ export class EventListToApproveMapper { } else { category = 'Pessoal' } - + let color; let workflowDisplayName; @@ -112,7 +112,3 @@ export class EventListToApproveMapper { // "InstanceId": "AAMkADVhOGY3ZDQzLTg4ZGEtNDYxMC1iMzc5LTJkMDgwNjMxOWFlZQBGAAAAAABEDW9nKs69TKQcVqQURj8YBwBR2HR2eO7pSpNdD9cc70l+AAAAAAFKAABR2HR2eO7pSpNdD9cc70l+AACK2Od9AAA=", // "originator": "dlima@gabinetedigital.local" // } - - - - diff --git a/src/app/services/Repositorys/Agenda/model/eventListDTOOutput.ts b/src/app/services/Repositorys/Agenda/model/eventListDTOOutput.ts index 54778b587..d8e15335b 100644 --- a/src/app/services/Repositorys/Agenda/model/eventListDTOOutput.ts +++ b/src/app/services/Repositorys/Agenda/model/eventListDTOOutput.ts @@ -1,25 +1,40 @@ import { z } from 'zod'; import { EEventCategory, EEventOwnerType, EEventStatus, EEventType } from './enums'; -const EventSchema = z.array(z.object({ + +const OwnerSchema = z.object({ + wxUserId: z.number(), + wxFullName: z.string(), + wxeMail: z.string(), + userPhoto: z.string(), +}); + + +export const EventListOutputDTOSchema = z.object({ id: z.string(), - owner: z.string().nullable(), + owner: OwnerSchema, ownerType: z.nativeEnum(EEventOwnerType),// ['MD','PR', 'Other'] // Assuming "MD" is the only valid option based on provided data subject: z.string(), body: z.string(), - location: z.string(), + location: z.string().nullable(), startDate: z.string().datetime({ offset: true }), endDate: z.string().datetime({ offset: true }), type: z.nativeEnum(EEventType), // ['Meeting', 'Travel'] = [1,2 ] // category: z.enum(['Oficial', 'Pessoal']), // Assuming "Oficial" is the only valid option based on provided data category: z.nativeEnum(EEventCategory), isRecurring: z.boolean(), - eventRecurrence: z.null(), + eventRecurrence: z.any().nullable(), hasAttachments: z.boolean(), isPrivate: z.boolean(), isAllDayEvent: z.boolean(), // status: z.enum(['Approved']), // Assuming "Approved" is the only valid option based on provided data status: z.nativeEnum(EEventStatus), // Assuming "Approved" is the only valid option based on provided data -})) +}) -export type EventListOutputDTO = z.infer; +export const EventListDataOutputDTOSchema = z.object({ + success: z.boolean(), + message: z.string(), + data: z.array(EventListOutputDTOSchema), +}).nullable(); + +export type EventListOutputDTO = z.infer; diff --git a/src/app/services/Repositorys/Agenda/model/eventToApproveListOutputDTO.ts b/src/app/services/Repositorys/Agenda/model/eventToApproveListOutputDTO.ts index 0bd991fe1..b5d3c4556 100644 --- a/src/app/services/Repositorys/Agenda/model/eventToApproveListOutputDTO.ts +++ b/src/app/services/Repositorys/Agenda/model/eventToApproveListOutputDTO.ts @@ -7,7 +7,7 @@ const EventToApproveList = z.array(z.object({ ownerType: z.nativeEnum(EEventOwnerType), subject: z.string(), body: z.string(), - location: z.string(), + location: z.string().nullable(), startDate: z.string().datetime(), endDate: z.string().datetime(), type: z.nativeEnum(EEventType), @@ -20,4 +20,11 @@ const EventToApproveList = z.array(z.object({ status: z.nativeEnum(EEventStatus) })) -export type EventToApproveListOutputDTO = z.infer; +export const EventToApproveDataOutputDTOSchema = z.object({ + success: z.boolean(), + message: z.string(), + data: EventToApproveList, +}).nullable(); + + +export type EventToApproveListOutputDTO = z.infer; diff --git a/src/app/services/decorator/api-validate-schema.decorator.ts b/src/app/services/decorator/api-validate-schema.decorator.ts index ecc1f468e..73aa318b1 100644 --- a/src/app/services/decorator/api-validate-schema.decorator.ts +++ b/src/app/services/decorator/api-validate-schema.decorator.ts @@ -2,8 +2,9 @@ import { HttpErrorResponse } from '@angular/common/http'; import { Result, err } from 'neverthrow'; import { z, ZodError } from 'zod'; import * as Sentry from '@sentry/capacitor'; +import { TracingType } from '../monitoring/opentelemetry/tracer'; -export function APIReturn(schema: z.ZodTypeAny) { +export function APIReturn(schema: z.ZodTypeAny, path: string) { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { const originalMethod = descriptor.value; @@ -19,13 +20,8 @@ export function APIReturn(schema: z.ZodTypeAny) { if (error instanceof ZodError) { // If validation fails, throw an error with the details // - console.log('unexpected data structure') + console.error('unexpected data structure', path) // Capture the Zod validation error with additional context - Sentry.withScope((scope) => { - scope.setTag('APIReturn', 'user'); - scope.setContext('data', { data: result.value }); - Sentry.captureException(error); - }); console.error('Validation failed:', error.errors); } else { console.log('failed to setup the connection successful') @@ -34,7 +30,7 @@ export function APIReturn(schema: z.ZodTypeAny) { } } } else { - console.log() + // console.log() // result.error. } @@ -43,3 +39,33 @@ export function APIReturn(schema: z.ZodTypeAny) { return descriptor; } } + + +export function APINODReturn(schema: z.ZodTypeAny, data , path: string, tracing?: TracingType) { + + try { + // Validate the result using the provided schema + schema.parse(data); + + } catch (error) { + if (error instanceof ZodError) { + // If validation fails, throw an error with the details + // + console.error('unexpected data structure', path) + // Capture the Zod validation error with additional context + console.error('Validation failed:', error.errors); + + tracing?.setAttribute('APIReturn.error', 'true') + + let i = 0; + for(const schema of error.errors) { + tracing?.setAttribute('map.error.schema-'+i, JSON.stringify(schema)) + } + + } else { + // Throw any other unexpected errors + throw error; + } + } + +} diff --git a/src/app/shared/agenda/event-list/event-list.page.html b/src/app/shared/agenda/event-list/event-list.page.html index fb742836e..41fd02055 100644 --- a/src/app/shared/agenda/event-list/event-list.page.html +++ b/src/app/shared/agenda/event-list/event-list.page.html @@ -52,10 +52,14 @@ (click)="openApproveModal(event.serialNumber, event)" >
-
+

{{event.workflowInstanceDataFields.StartDate | date: 'HH:mm'}}

{{event.workflowInstanceDataFields.EndDate | date: 'HH:mm'}}

+
+

Todo

+

o dia

+

{{event.workflowInstanceDataFields.Subject}}

{{event.workflowInstanceDataFields.StartDate | date: 'd/M/yy' }} - {{ event.workflowInstanceDataFields.EndDate | date: 'dd/M/yy'}} | {{event.workflowInstanceDataFields.Location}}