Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: merge into main #257

Merged
merged 40 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
afc1745
fix: handle null state data in DB when saving survey unit state data
davdarras Apr 8, 2024
f8af35d
fix: use previousDate instead of newDate for null integrity in updati…
davdarras Apr 8, 2024
cfc8445
fix: allow patch methods in cors (#232)
davdarras Apr 8, 2024
5f64bc9
Merge branch 'develop' into fix/cors-headers
davdarras Apr 8, 2024
3927a36
Merge pull request #235 from InseeFr/fix/cors-headers
davdarras Apr 8, 2024
46aef0d
Merge pull request #236 from InseeFr/fix/allow-put-su-from-surveyunit
davdarras Apr 8, 2024
81ecb01
fix: resolve native insert when current data has no collected attribu…
davdarras Apr 10, 2024
060f419
fix: improve perf on native insert of collected data (#238)
davdarras Apr 10, 2024
7b1c5d7
fix: schema names for input output on openapi spec (#239)
davdarras Apr 15, 2024
a0634f6
fix: from string to json node objects (#240)
davdarras Apr 15, 2024
a4836f1
fix: disable app collected update
davdarras Apr 16, 2024
621a835
fix: add openapi schema for arraynode/objectnode
davdarras Apr 16, 2024
6867d82
fix(deps): update dependencies
davdarras Apr 16, 2024
049ac00
fix: add collected data even if data is null
davdarras Apr 16, 2024
4bc676e
feat: add endpoint to retrieve questionnaire data directly (#243)
davdarras Apr 30, 2024
a68cd7c
feat: add endpoint to update partial collected data/state data at the…
davdarras Apr 30, 2024
533c2ea
feat: add json validation for metadata/personalization/data/collected…
davdarras May 17, 2024
8442f57
ci: handle develop snapshots on demand
davdarras May 22, 2024
59f6eaf
feat: add new campaign creation endpoint
davdarras May 22, 2024
4f308bb
feat: restrict module usages from domain modules
davdarras May 22, 2024
4fd84b7
chore(deps): update all minor dependencies
davdarras May 22, 2024
f0eea0e
feat: add default configuration when no role claim configured
davdarras May 22, 2024
649dba7
fix: add json validation for survey unit temp zone
davdarras May 23, 2024
fc4962f
fix: resolve schema correctly in swagger
davdarras May 23, 2024
9765e0d
fix: allow empty data when saving diff data/state data (#248)
davdarras May 27, 2024
54b49b1
feat: add endpoint retrieving survey unit metadata (#249)
davdarras Jun 6, 2024
611f790
fix: add survey units unique constraints in DB (#250)
davdarras Jun 7, 2024
b440495
doc: resolve openapi scpe for deposit proof
davdarras Jun 7, 2024
df8cad7
doc: openapi depositproof add binary format in content schema
davdarras Jun 7, 2024
11b699f
fix: comment buggy annotation for openapi in deposit proof controller
davdarras Jun 7, 2024
fe35483
fix: avoid manipulating metadata cache object
davdarras Jun 14, 2024
acf8e5b
Merge branch 'develop' into renovate/all-minor-patch
davdarras Jun 14, 2024
5542d4d
Merge pull request #251 from InseeFr/renovate/all-minor-patch
davdarras Jun 14, 2024
5671ec1
fix: temporarily enable additional properties for data
davdarras Jun 14, 2024
cd59115
test: temporarily enable additional properties for data
davdarras Jun 14, 2024
af58eb6
fix: loosen types on json schemas (#252)
davdarras Jun 14, 2024
611f53f
fix: add required metadata attributes when retrieving survey unit met…
davdarras Jun 18, 2024
ed54b65
fix: disallow reviewers to put data/state-data
davdarras Jun 24, 2024
c41a5e9
fix: when deleting campaign, reset survey unit cache
davdarras Jun 24, 2024
5435d7d
fix: when updating survey-unit, allow null state (#256)
davdarras Jul 4, 2024
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
6 changes: 2 additions & 4 deletions .github/workflows/create-snapshot.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
name: Build release candidate

on:
push:
branches:
- v4-develop #temp branch
- develop
workflow_dispatch:
branches: [ develop ]

jobs:
check-version:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/sonar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ on:
push:
branches:
- main
- v4-develop #temp branch
- develop
pull_request:
types: [opened, synchronize, reopened]
Expand Down
2 changes: 1 addition & 1 deletion .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.7/apache-maven-3.9.7-bin.zip
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.7/apache-maven-3.9.7-bin.zip
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<description>Modules for queen back-office</description>

<properties>
<revision>4.2.7</revision>
<revision>4.3.12</revision>
<changelist></changelist>
<java.version>21</java.version>
<maven.compiler.source>21</maven.compiler.source>
Expand All @@ -30,7 +30,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.0</version>
<version>3.3.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

Expand Down
2 changes: 1 addition & 1 deletion queen-application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<version>${revision}${changelist}</version>
</parent>
<artifactId>queen-application</artifactId>
<name>queen-application</name>
<name>queen-api</name>
<description>API for Queen/Stromae</description>

<properties>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package fr.insee.queen.application.campaign.component;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import fr.insee.queen.application.surveyunit.dto.output.*;
import fr.insee.queen.domain.surveyunit.service.exception.MetadataValueNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Component
@RequiredArgsConstructor
public class MetadataComponentConverter implements MetadataConverter {
public static final String METADATA_CONTEXT = "inseeContext";
public static final String METADATA_OBJECTIVES = "Enq_ObjectifsCourts";
public static final String METADATA_LABEL = "Enq_LibelleEnquete";
public static final String METADATA_VARIABLES = "variables";
public static final String METADATA_VARIABLE_NAME = "name";
public static final String METADATA_VARIABLE_VALUE = "value";
public static final String METADATA_LOGOS = "logos";
public static final String METADATA_LOGO_LABEL = "label";
public static final String METADATA_LOGO_URL = "url";

private final ObjectMapper mapper;

public MetadataDto convert(ObjectNode metadataNode) {
QuestionnaireContextDto context = extractMetadataContext(metadataNode);

JsonNode metadataVariablesNode = metadataNode.get(METADATA_VARIABLES);
if(metadataVariablesNode == null || !metadataVariablesNode.isArray()) {
throw new MetadataValueNotFoundException(METADATA_VARIABLES);
}
String shortObjectives = extractMetadataVariable(metadataVariablesNode, METADATA_OBJECTIVES);
String shortLabel = extractMetadataVariable(metadataVariablesNode, METADATA_LABEL);
List<MetadataVariableDto> variables = getVariables((ArrayNode)metadataVariablesNode);
LogoDtos logos = null;

JsonNode metadataLogosNode = metadataNode.get(METADATA_LOGOS);
if(metadataLogosNode != null && metadataLogosNode.isArray()) {
logos = getLogos((ArrayNode)metadataLogosNode);
}
return new MetadataDto(variables, logos, context, shortLabel, shortObjectives);
}

private List<MetadataVariableDto> getVariables(ArrayNode variablesNode) {
List<MetadataVariableDto> variables = new ArrayList<>();
Iterator<JsonNode> iteratorVariables = variablesNode.elements();
while(iteratorVariables.hasNext()) {
JsonNode variableNode = iteratorVariables.next();
JsonNode nameNode = variableNode.get(METADATA_VARIABLE_NAME);
if(METADATA_OBJECTIVES.equals(nameNode.textValue()) || METADATA_LABEL.equals(nameNode.textValue())) {
continue;
}
JsonNode valueNode = variableNode.get(METADATA_VARIABLE_VALUE);
variables.add(new MetadataVariableDto(nameNode.textValue(), mapper.convertValue(valueNode, Object.class)));
}
return variables;
}

private LogoDtos getLogos(ArrayNode metadataLogosNode) {
LogoDto mainLogo = null;
List<LogoDto> secondaryLogos = new ArrayList<>();
Iterator<JsonNode> iteratorMetadataLogosNode = metadataLogosNode.elements();

while(iteratorMetadataLogosNode.hasNext()) {
JsonNode variableNode = iteratorMetadataLogosNode.next();
JsonNode urlNode = variableNode.get(METADATA_LOGO_URL);
JsonNode labelNode = variableNode.get(METADATA_LOGO_LABEL);
LogoDto logo = new LogoDto(urlNode.textValue(), labelNode.textValue());
if(mainLogo == null) {
mainLogo = logo;
continue;
}
secondaryLogos.add(logo);
}
if(mainLogo == null) {
return null;
}

if(secondaryLogos.isEmpty()) {
return LogoDtos.createWithMainLogoOnly(mainLogo);
}
return LogoDtos.create(mainLogo, secondaryLogos);
}

private QuestionnaireContextDto extractMetadataContext(ObjectNode metadata) {
JsonNode metadataValue = metadata.get(METADATA_CONTEXT);

if(metadataValue == null || !metadataValue.isTextual()) {
throw new MetadataValueNotFoundException(METADATA_CONTEXT);
}
return QuestionnaireContextDto.getQuestionnaireContext(metadataValue.textValue());
}

private String extractMetadataVariable(JsonNode metadataVariables, String metadataKey) {
Iterator<JsonNode> iteratorVariables = metadataVariables.elements();
while(iteratorVariables.hasNext()) {
JsonNode variable = iteratorVariables.next();

if(! variable.isObject()) {
throw new MetadataValueNotFoundException(metadataKey);
}
JsonNode name = variable.get(METADATA_VARIABLE_NAME);
if(!metadataKey.equals(name.textValue())) {
continue;
}

JsonNode value = variable.get(METADATA_VARIABLE_VALUE);
if(!value.isTextual()) {
throw new MetadataValueNotFoundException(metadataKey);
}
return value.textValue();
}
throw new MetadataValueNotFoundException(metadataKey);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package fr.insee.queen.application.campaign.component;

import com.fasterxml.jackson.databind.node.ObjectNode;
import fr.insee.queen.application.surveyunit.dto.output.*;

public interface MetadataConverter {
MetadataDto convert(ObjectNode metadataNode);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fr.insee.queen.application.campaign.controller;

import fr.insee.queen.application.campaign.dto.input.CampaignCreationData;
import fr.insee.queen.application.campaign.dto.input.CampaignCreationDataV2;
import fr.insee.queen.application.campaign.dto.output.CampaignSummaryDto;
import fr.insee.queen.application.configuration.auth.AuthorityPrivileges;
import fr.insee.queen.application.pilotage.controller.PilotageComponent;
Expand Down Expand Up @@ -47,10 +48,12 @@ public List<CampaignSummaryDto> getListCampaign() {
}

/**
* @deprecated
* Create a new campaign
*
* @param campaignInputDto the value to create
*/
@Deprecated(since = "4.3.0")
@Operation(summary = "Create a campaign")
@PostMapping(path = "/campaigns")
@PreAuthorize(AuthorityPrivileges.HAS_ADMIN_PRIVILEGES)
Expand All @@ -59,6 +62,19 @@ public void createCampaign(@Valid @RequestBody CampaignCreationData campaignInpu
campaignService.createCampaign(CampaignCreationData.toModel(campaignInputDto));
}

/**
* Create a new campaign
*
* @param campaignInputDto the value to create
*/
@Operation(summary = "Create a campaign")
@PostMapping(path = "/campaign")
@PreAuthorize(AuthorityPrivileges.HAS_ADMIN_PRIVILEGES)
@ResponseStatus(HttpStatus.CREATED)
public void createCampaignV2(@Valid @RequestBody CampaignCreationDataV2 campaignInputDto) {
campaignService.createCampaign(CampaignCreationDataV2.toModel(campaignInputDto));
}

/**
* Delete a campaign. The deletion is processed in two cases:
* - the campaign is closed (check on pilotage api)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package fr.insee.queen.application.campaign.controller;

import com.fasterxml.jackson.databind.node.ObjectNode;
import fr.insee.queen.application.configuration.auth.AuthorityPrivileges;
import fr.insee.queen.application.web.validation.IdValid;
import fr.insee.queen.application.web.validation.json.SchemaType;
import fr.insee.queen.domain.campaign.service.MetadataService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -36,7 +41,8 @@ public class MetadataController {
@Operation(summary = "Get metadata for a campaign ")
@GetMapping(path = "/campaign/{id}/metadata")
@PreAuthorize(AuthorityPrivileges.HAS_USER_PRIVILEGES)
public String getMetadataByCampaignId(@IdValid @PathVariable(value = "id") String campaignId) {
@ApiResponse(responseCode = "200", content = {@Content(mediaType = "application/json", schema = @Schema(ref = SchemaType.Names.METADATA))})
public ObjectNode getMetadataByCampaignId(@IdValid @PathVariable(value = "id") String campaignId) {
return metadataService.getMetadata(campaignId);
}

Expand All @@ -49,7 +55,8 @@ public String getMetadataByCampaignId(@IdValid @PathVariable(value = "id") Strin
@Operation(summary = "Get metadata for a questionnaire ")
@GetMapping(path = "/questionnaire/{id}/metadata")
@PreAuthorize(AuthorityPrivileges.HAS_USER_PRIVILEGES)
public String getMetadataByQuestionnaireId(@IdValid @PathVariable(value = "id") String questionnaireId) {
@ApiResponse(responseCode = "200", content = {@Content(mediaType = "application/json", schema = @Schema(ref = SchemaType.Names.METADATA))})
public ObjectNode getMetadataByQuestionnaireId(@IdValid @PathVariable(value = "id") String questionnaireId) {
return metadataService.getMetadataByQuestionnaireId(questionnaireId);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package fr.insee.queen.application.campaign.controller;

import com.fasterxml.jackson.databind.node.ArrayNode;
import fr.insee.queen.application.campaign.dto.input.NomenclatureCreationData;
import fr.insee.queen.application.configuration.auth.AuthorityPrivileges;
import fr.insee.queen.application.web.validation.IdValid;
import fr.insee.queen.application.web.validation.json.SchemaType;
import fr.insee.queen.domain.campaign.service.NomenclatureService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
Expand Down Expand Up @@ -36,7 +41,7 @@ public class NomenclatureController {
*/
@Operation(summary = "Get all nomenclatures Ids ")
@GetMapping(path = "/nomenclatures")
@PreAuthorize(AuthorityPrivileges.HAS_MANAGEMENT_PRIVILEGES)
@PreAuthorize(AuthorityPrivileges.HAS_REVIEWER_PRIVILEGES)
public List<String> getNomenclaturesId() {
return nomenclatureService.getAllNomenclatureIds();
}
Expand All @@ -46,14 +51,14 @@ public List<String> getNomenclaturesId() {
* Retrieve a nomenclature
*
* @param nomenclatureId the id of nomenclature
* @return {@link String} the nomenclature in json format
* @return {@link ArrayNode} the nomenclature in json format
*/
@Operation(summary = "Get Nomenclature")
@GetMapping(path = "/nomenclature/{id}")
@PreAuthorize(AuthorityPrivileges.HAS_USER_PRIVILEGES)
public String getNomenclatureById(@IdValid @PathVariable(value = "id") String nomenclatureId) {
@ApiResponse(responseCode = "200", content = {@Content(mediaType = "application/json", schema = @Schema(ref = SchemaType.Names.NOMENCLATURE))})
public ArrayNode getNomenclatureById(@IdValid @PathVariable(value = "id") String nomenclatureId) {
return nomenclatureService.getNomenclature(nomenclatureId).value();

}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fr.insee.queen.application.campaign.controller;

import com.fasterxml.jackson.databind.node.ObjectNode;
import fr.insee.queen.application.campaign.dto.input.QuestionnaireModelCreationData;
import fr.insee.queen.application.campaign.dto.output.QuestionnaireModelIdDto;
import fr.insee.queen.application.campaign.dto.output.QuestionnaireModelValueDto;
Expand Down Expand Up @@ -45,7 +46,7 @@ public class QuestionnaireModelController {
*/
@Operation(summary = "Get questionnaire list for a campaign ")
@GetMapping(path = "/campaign/{id}/questionnaires")
@PreAuthorize(AuthorityPrivileges.HAS_MANAGEMENT_PRIVILEGES)
@PreAuthorize(AuthorityPrivileges.HAS_REVIEWER_PRIVILEGES)
public List<QuestionnaireModelValueDto> getQuestionnaireDatasByCampaignId(
@IdValid @PathVariable(value = "id") String campaignId) {
return questionnaireModelService
Expand All @@ -55,6 +56,7 @@ public List<QuestionnaireModelValueDto> getQuestionnaireDatasByCampaignId(
}

/**
* @deprecated
* Retrieve the data structure of a questionnaire
*
* @param questionnaireModelId the id of questionnaire
Expand All @@ -63,8 +65,22 @@ public List<QuestionnaireModelValueDto> getQuestionnaireDatasByCampaignId(
@Operation(summary = "Get questionnnaire")
@GetMapping(path = "/questionnaire/{id}")
@PreAuthorize(AuthorityPrivileges.HAS_USER_PRIVILEGES)
public QuestionnaireModelValueDto getQuestionnaireData(@IdValid @PathVariable(value = "id") String questionnaireModelId) {
return new QuestionnaireModelValueDto(questionnaireModelService.getQuestionnaireData(questionnaireModelId));
@Deprecated(since = "4.2.12")
public QuestionnaireModelValueDto getQuestionnaireValue(@IdValid @PathVariable(value = "id") String questionnaireModelId) {
return new QuestionnaireModelValueDto(getQuestionnaireData(questionnaireModelId));
}

/**
* Retrieve the data structure of a questionnaire
*
* @param questionnaireModelId the id of questionnaire
* @return the data linked to the questionnaire
*/
@Operation(summary = "Get questionnnaire data")
@GetMapping(path = "/questionnaire/{id}/data")
@PreAuthorize(AuthorityPrivileges.HAS_USER_PRIVILEGES)
public ObjectNode getQuestionnaireData(@IdValid @PathVariable(value = "id") String questionnaireModelId) {
return questionnaireModelService.getQuestionnaireData(questionnaireModelId);
}

/**
Expand All @@ -75,7 +91,7 @@ public QuestionnaireModelValueDto getQuestionnaireData(@IdValid @PathVariable(va
*/
@Operation(summary = "Get list of questionnaire ids for a campaign")
@GetMapping(path = "/campaign/{id}/questionnaire-id")
@PreAuthorize(AuthorityPrivileges.HAS_MANAGEMENT_PRIVILEGES)
@PreAuthorize(AuthorityPrivileges.HAS_REVIEWER_PRIVILEGES)
public List<QuestionnaireModelIdDto> getQuestionnaireIdsByCampaignId(
@IdValid @PathVariable(value = "id") String campaignId) {
return questionnaireModelService
Expand Down Expand Up @@ -106,7 +122,7 @@ public void createQuestionnaire(@RequestBody @Valid QuestionnaireModelCreationDa
*/
@Operation(summary = "Search questionnaire ids linked to survey units")
@PostMapping(path = "/survey-units/questionnaire-model-id")
@PreAuthorize(AuthorityPrivileges.HAS_MANAGEMENT_PRIVILEGES)
@PreAuthorize(AuthorityPrivileges.HAS_REVIEWER_PRIVILEGES)
public ResponseEntity<SurveyUnitOkNokDto> getQuestionnaireModelIdBySurveyUnits(
@NotEmpty @RequestBody List<String> surveyUnitIdsToSearch) {
List<SurveyUnitSummary> surveyUnitsFound = surveyUnitService.findSummariesByIds(surveyUnitIdsToSearch);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.fasterxml.jackson.databind.node.ObjectNode;
import fr.insee.queen.application.web.validation.IdValid;
import fr.insee.queen.domain.campaign.model.Campaign;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
Expand All @@ -20,6 +21,7 @@
* @param metadata campaign metadata
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(name = "CampaignCreation")
public record CampaignCreationData(
@IdValid
String id,
Expand All @@ -35,6 +37,6 @@ public static Campaign toModel(CampaignCreationData campaign) {
if (campaign.metadata() != null) {
metadataValue = campaign.metadata.value();
}
return new Campaign(campaign.id, campaign.label, campaign.questionnaireIds, metadataValue.toString());
return new Campaign(campaign.id, campaign.label, campaign.questionnaireIds, metadataValue);
}
}
Loading
Loading