diff --git a/.github/workflows/deploy-dev.yml b/.github/workflows/deploy-dev.yml new file mode 100644 index 00000000..89c19b45 --- /dev/null +++ b/.github/workflows/deploy-dev.yml @@ -0,0 +1,22 @@ +name: Deploy Survey Dev + +on: + push: + branches: + - dev-release + +jobs: + deploy: + name: Deploy to server + runs-on: ubuntu-latest + + steps: + - name: SSH and deploy + uses: appleboy/ssh-action@v1.0.3 + with: + host: ${{ secrets.DEV_SSH_HOST }} + username: ${{ secrets.DEV_SSH_USER }} + key: ${{ secrets.DEV_SSH_PRIVATE_KEY }} + script: | + cd ~/Microservices/survey-dev-configs + ./deploy.sh dev-release diff --git a/src/common/dto/pagination.dto.ts b/src/common/dto/pagination.dto.ts index 0a0974ec..11688002 100644 --- a/src/common/dto/pagination.dto.ts +++ b/src/common/dto/pagination.dto.ts @@ -13,6 +13,11 @@ export class FiltersDto { @IsOptional() @IsString() status?: string; + + @ApiPropertyOptional({ description: 'Filter by context type (e.g. learner, none)' }) + @IsOptional() + @IsString() + contextType?: string; } export class PaginationDto { diff --git a/src/common/responses/api-response.ts b/src/common/responses/api-response.ts index 388e4e16..a8707cf2 100644 --- a/src/common/responses/api-response.ts +++ b/src/common/responses/api-response.ts @@ -37,7 +37,7 @@ export class APIResponse { ts: new Date().toISOString(), params, responseCode: statusCode, - ...result, + result, }; return response.status(statusCode).json(resObj); } catch (e) { diff --git a/src/modules/response/dto/create-response.dto.ts b/src/modules/response/dto/create-response.dto.ts index fa005ffe..9ba51794 100644 --- a/src/modules/response/dto/create-response.dto.ts +++ b/src/modules/response/dto/create-response.dto.ts @@ -8,6 +8,7 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; export class CreateResponseDto { @ApiProperty({ description: 'Survey ID to respond to' }) + @IsOptional() @IsUUID() surveyId: string; diff --git a/src/modules/response/services/response.service.ts b/src/modules/response/services/response.service.ts index 78fb9a7e..6e03ab9f 100644 --- a/src/modules/response/services/response.service.ts +++ b/src/modules/response/services/response.service.ts @@ -134,7 +134,7 @@ export class ResponseService { return APIResponse.success( response, apiId, - { data: saved }, + saved, HttpStatus.CREATED, RESPONSE_MESSAGES.RESPONSE_CREATE_SUCCESS, ); @@ -186,7 +186,7 @@ export class ResponseService { return APIResponse.success( response, apiId, - { data: result }, + result, HttpStatus.OK, RESPONSE_MESSAGES.RESPONSE_LIST_SUCCESS, ); @@ -225,7 +225,7 @@ export class ResponseService { return APIResponse.success( response, apiId, - { data: surveyResponse }, + surveyResponse, HttpStatus.OK, RESPONSE_MESSAGES.RESPONSE_READ_SUCCESS, ); @@ -322,7 +322,7 @@ export class ResponseService { return APIResponse.success( response, apiId, - { data: saved }, + saved, HttpStatus.OK, RESPONSE_MESSAGES.RESPONSE_UPDATE_SUCCESS, ); @@ -434,7 +434,7 @@ export class ResponseService { return APIResponse.success( response, apiId, - { data: saved }, + saved, HttpStatus.OK, RESPONSE_MESSAGES.RESPONSE_SUBMIT_SUCCESS, ); @@ -494,7 +494,7 @@ export class ResponseService { return APIResponse.success( response, apiId, - { data: result }, + result, HttpStatus.OK, RESPONSE_MESSAGES.RESPONSE_STATS_SUCCESS, ); @@ -532,14 +532,32 @@ export class ResponseService { return surveyResponse; } + private isConditionMet(field: any, allFields: any[], responseData: Record): boolean { + const logic = field.conditionalLogic; + if (!logic || !logic.depends_on || !logic.show_if) return true; + + const parentField = allFields.find(f => f.fieldName === logic.depends_on); + if (!parentField) return true; + + const parentValue = responseData[parentField.fieldId]; + const showIf: string[] = logic.show_if; + + if (Array.isArray(parentValue)) { + return parentValue.some(v => showIf.includes(v)); + } + return showIf.includes(parentValue); + } + private validateRequiredFields(survey: any, surveyResponse: SurveyResponse): void { const errors: string[] = []; + const allFields = (survey.sections || []).flatMap((s: any) => s.fields || []); + for (const section of survey.sections || []) { for (const field of section.fields || []) { - if (field.isRequired) { - const value = surveyResponse.responseData[field.fieldId]; - const fileIds = surveyResponse.fileUploadIds[field.fieldId]; + if (field.isRequired && this.isConditionMet(field, allFields, surveyResponse.responseData ?? {})) { + const value = (surveyResponse.responseData ?? {})[field.fieldId]; + const fileIds = (surveyResponse.fileUploadIds ?? {})[field.fieldId]; const isUploadField = ['image_upload', 'video_upload', 'file_upload'].includes( field.fieldType, diff --git a/src/modules/survey/services/survey.service.ts b/src/modules/survey/services/survey.service.ts index be676370..bc8a3e58 100644 --- a/src/modules/survey/services/survey.service.ts +++ b/src/modules/survey/services/survey.service.ts @@ -125,7 +125,7 @@ export class SurveyService { return APIResponse.success( response, apiId, - { data: result }, + result, HttpStatus.CREATED, RESPONSE_MESSAGES.SURVEY_CREATE_SUCCESS, ); @@ -186,6 +186,13 @@ export class SurveyService { }); } + // Filter by contextType if provided + if (filters?.contextType) { + queryBuilder = queryBuilder.andWhere('survey.contextType = :contextType', { + contextType: filters.contextType, + }); + } + const [surveys, total] = await queryBuilder .orderBy(`survey.${sortBy}`, sortOrder) .skip(pagination.skip) @@ -207,7 +214,7 @@ export class SurveyService { return APIResponse.success( response, apiId, - { data: result }, + result, HttpStatus.OK, RESPONSE_MESSAGES.SURVEY_LIST_SUCCESS, ); @@ -246,7 +253,7 @@ export class SurveyService { return APIResponse.success( response, apiId, - { data: survey }, + survey, HttpStatus.OK, RESPONSE_MESSAGES.SURVEY_READ_SUCCESS, ); @@ -316,7 +323,7 @@ export class SurveyService { return APIResponse.success( response, apiId, - { data: result }, + result, HttpStatus.OK, RESPONSE_MESSAGES.SURVEY_UPDATE_SUCCESS, ); @@ -395,7 +402,7 @@ export class SurveyService { return APIResponse.success( response, apiId, - { data: survey }, + survey, HttpStatus.OK, RESPONSE_MESSAGES.SURVEY_PUBLISH_SUCCESS, ); @@ -453,7 +460,7 @@ export class SurveyService { return APIResponse.success( response, apiId, - { data: survey }, + survey, HttpStatus.OK, RESPONSE_MESSAGES.SURVEY_CLOSE_SUCCESS, ); @@ -509,7 +516,7 @@ export class SurveyService { return APIResponse.success( response, apiId, - { data: { surveyId } }, + { surveyId }, HttpStatus.OK, RESPONSE_MESSAGES.SURVEY_DELETE_SUCCESS, );