Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
677dc44
feat-flag!: Update SED fields based on HTI-5
kekey1 Jun 22, 2026
3e380c7
feat-flag: Support different file headings based on flag state
kekey1 Jun 23, 2026
cb6622e
Merge branch 'staging' into OCD-5318
kekey1 Jun 23, 2026
59267e3
fix: Use correct logic for task/participant upload parsing
kekey1 Jun 23, 2026
2abcd39
feat-flag: Do not check for required tasks/participants
kekey1 Jun 23, 2026
89392f2
feat-flag: Add error if both UCD fields are filled in
kekey1 Jun 23, 2026
e44b81c
feat-flag: Copy existing tasks/participants for sed
kekey1 Jun 23, 2026
06f0e9b
feat: Return either UCD name or details in "value" field
kekey1 Jun 23, 2026
51da1d8
refactor: Remove unused variable
kekey1 Jun 23, 2026
acf18cd
feat-flag: Stop including Full Usability Report in Questionable URL data
kekey1 Jun 24, 2026
e09cf99
feat-flag: Write UCD processes to SED download file
kekey1 Jun 24, 2026
cac800c
feat-flag: Remove SED Summary fields after flag is flipped
kekey1 Jun 25, 2026
95bf33c
Merge branch 'staging' into OCD-5318
kekey1 Jun 25, 2026
29dd3e4
feat-flag: Save UCD Processes, never test tools
kekey1 Jun 25, 2026
b80b2d4
feat-flag: Remove sed fields in an annotation-based way
kekey1 Jun 26, 2026
9cd8ac0
fix: Use systemwide JsonMapper to write out listing details
kekey1 Jul 6, 2026
4ebfa9c
feat: Also hide UCD fields after flag flip
kekey1 Jul 8, 2026
cc6e388
fix: Ensure activity isn't writing out hidden JSON fields
kekey1 Jul 8, 2026
f380243
feat: Save UCD processes from just "value"
kekey1 Jul 9, 2026
3a770ee
Merge branch 'staging' into OCD-5318
kekey1 Jul 13, 2026
43dd55c
Merge branch 'staging' into OCD-5318
kekey1 Jul 15, 2026
907f32b
feat: Allow UCD process name only, details only, or name + details
kekey1 Jul 15, 2026
0c960c6
fix: Allow multiple "Custom" UCD processes
kekey1 Jul 16, 2026
e41507e
fix: Allow both UCD fields in upload file
kekey1 Jul 16, 2026
234b61e
fix: Correctly normalize UCD processes when name is missing
kekey1 Jul 16, 2026
d914f85
Merge branch 'staging' into OCD-5318
kekey1 Jul 17, 2026
8cba728
fix: Update normalization of UCD processes
kekey1 Jul 20, 2026
a151cd6
test: Remove incorrect test
kekey1 Jul 20, 2026
3f7ef9b
Merge branch 'staging' into OCD-5318
kekey1 Jul 21, 2026
216bad8
Merge branch 'staging' into OCD-5318
kekey1 Jul 24, 2026
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 @@ -87,7 +87,7 @@ public class CHPLConfig implements WebMvcConfigurer, EnvironmentAware {
private Boolean tryItOutEnabled;

@Autowired
private DeprecatedResponseFieldAnnotationIntrospector deprecatedResponseFieldAnnotationIntrospector;
private IgnorableResponseFieldAnnotationIntrospector ignorableResponseFieldAnnotationIntrospector;

@Lazy
@Autowired
Expand Down Expand Up @@ -117,7 +117,7 @@ public void setEnvironment(Environment e) {
@Primary
public JsonMapper jsonMapper() {
JsonMapper mapper = JsonMapper.builder()
.annotationIntrospector(deprecatedResponseFieldAnnotationIntrospector)
.annotationIntrospector(ignorableResponseFieldAnnotationIntrospector)
.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package gov.healthit.chpl;

import org.ff4j.FF4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import gov.healthit.chpl.api.deprecatedUsage.DeprecatedResponseField;
import gov.healthit.chpl.sed.DeprecatedSedSummaryData;
import gov.healthit.chpl.sed.DeprecatedSedTestTaskData;
import lombok.extern.log4j.Log4j2;
import tools.jackson.databind.cfg.MapperConfig;
import tools.jackson.databind.introspect.AnnotatedMember;
import tools.jackson.databind.introspect.JacksonAnnotationIntrospector;

@Log4j2
@Component
public class IgnorableResponseFieldAnnotationIntrospector extends JacksonAnnotationIntrospector {
private static final long serialVersionUID = 7316344670464634840L;

@Autowired
private Environment env;

@Autowired
private FF4j ff4j;

@Override
public boolean hasIgnoreMarker(MapperConfig<?> config, AnnotatedMember m) {
if (super.hasIgnoreMarker(config, m)) {
return true;
} else {
return isDeprecatedAndIgnorable(m) || isSedAndIgnorable(m);
}
}

private boolean isDeprecatedAndIgnorable(AnnotatedMember m) {
Boolean returnDeprecatedFields = Boolean.valueOf(env.getProperty("response.returnDeprecatedFields"));
boolean isDeprecated = _findAnnotation(m, DeprecatedResponseField.class) != null;
return !returnDeprecatedFields && isDeprecated;
}

private boolean isSedAndIgnorable(AnnotatedMember m) {
boolean isHti5Erd = ff4j.check(FeatureList.HTI_5_ERD);
boolean isSedSummary = _findAnnotation(m, DeprecatedSedSummaryData.class) != null;
boolean isSedTestTask = _findAnnotation(m, DeprecatedSedTestTaskData.class) != null;
return isHti5Erd && (isSedSummary || isSedTestTask);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ private FeatureList() {

public static final String CMS_DISABLED = "cms-disabled";
public static final String DEMOGRAPHIC_CHANGE_REQUEST = "demographic-change-request";
public static final String HTI_5_ERD = "hti-5-erd";
public static final String INSIGHTS_DISPLAY = "insights-display";
public static final String SERVICE_BASE_URL_LIST_CHANGE_REQUEST = "sbul-change-request";
public static final String RWT_CHANGE_REQUEST = "rwt-change-request";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.ff4j.FF4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import gov.healthit.chpl.FeatureList;
import gov.healthit.chpl.certificationCriteria.CertificationCriteriaManager;
import gov.healthit.chpl.certificationCriteria.CertificationCriterion;
import gov.healthit.chpl.certificationCriteria.CertificationCriterionWithAttributes;
Expand Down Expand Up @@ -82,19 +84,23 @@ public class ListingCsvDataWriter {
private static final int SED_TESTING_DATE_COL = 40;
private static final int PARTICIPANT_START_COL = 41;
private static final int TASK_START_COL = 50;
private static final int CRITERIA_START_COL = 65;
private static final int CRITERIA_START_COL_PRE_HTI5 = 65;
private static final int CRITERIA_START_COL = 38;
private static final int ADDITIONAL_SOFTWARE_COL_COUNT = 5;
private static final int UCD_PROCESS_COL_COUNT = 2;
private static final int SED_TESTING_COL_COUNT = 2;

private CertificationCriteriaManager criteriaManager;
private StandardManager standardManager;
private DateFormat dateFormat;
private FF4j ff4j;

@Autowired
public ListingCsvDataWriter(CertificationCriteriaManager criteriaManager, StandardManager standardManager) {
public ListingCsvDataWriter(CertificationCriteriaManager criteriaManager, StandardManager standardManager,
FF4j ff4j) {
this.criteriaManager = criteriaManager;
this.standardManager = standardManager;
this.ff4j = ff4j;
this.dateFormat = new SimpleDateFormat(ListingUploadHandlerUtil.UPLOAD_DATE_FORMAT);
}

Expand All @@ -121,11 +127,13 @@ public List<List<String>> getCsvData(CertifiedProductSearchDetails listing, int
addAccessibilityStandards(csvDataMatrix, listing.getAccessibilityStandards());
csvDataMatrix[0][K1_URL_COL] = listing.getMandatoryDisclosures();
addCqms(csvDataMatrix, listing.getCqmResults());
csvDataMatrix[0][SED_REPORT_URL_COL] = listing.getSedReportFileLocation();
csvDataMatrix[0][SED_INTENDED_USERS_COL] = listing.getSedIntendedUserDescription();
csvDataMatrix[0][SED_TESTING_DATE_COL] = listing.getSedTestingEndDay() != null ? dateFormat.format(DateUtil.toDate(listing.getSedTestingEndDay())) : "";
addParticipants(csvDataMatrix, listing.getSed());
addTasks(csvDataMatrix, listing.getSed());
if (!ff4j.check(FeatureList.HTI_5_ERD)) {
csvDataMatrix[0][SED_REPORT_URL_COL] = listing.getSedReportFileLocation();
csvDataMatrix[0][SED_INTENDED_USERS_COL] = listing.getSedIntendedUserDescription();
csvDataMatrix[0][SED_TESTING_DATE_COL] = listing.getSedTestingEndDay() != null ? dateFormat.format(DateUtil.toDate(listing.getSedTestingEndDay())) : "";
addParticipants(csvDataMatrix, listing.getSed());
addTasks(csvDataMatrix, listing.getSed());
}
addCertificationResults(csvDataMatrix, getAllAvailableCriteriaAsCertResults(listing), listing.getSed());

List<List<String>> records = new ArrayList<List<String>>();
Expand Down Expand Up @@ -445,7 +453,7 @@ private void addTasks(String[][] csvDataMatrix, CertifiedProductSed sed) {
}

private void addCertificationResults(String[][] csvDataMatrix, List<CertificationResult> certResults, CertifiedProductSed sed) {
int currCol = CRITERIA_START_COL;
int currCol = !ff4j.check(FeatureList.HTI_5_ERD) ? CRITERIA_START_COL_PRE_HTI5 : CRITERIA_START_COL;
for (int i = 0; i < certResults.size(); i++) {
int currCertResultStartCol = currCol;
CertificationResult certResult = certResults.get(i);
Expand Down Expand Up @@ -652,19 +660,21 @@ private int addSed(String[][] csvDataMatrix, CertificationResult certResult, Cer
}
currCol += UCD_PROCESS_COL_COUNT;

List<TestTask> testTasks = getTestTasksForCriterion(certResult.getCriterion(), sed);
if (!CollectionUtils.isEmpty(testTasks)) {
for (int i = 0; i < testTasks.size(); i++) {
int sedTestingCol = currCol;
TestTask testTask = testTasks.get(i);
csvDataMatrix[i][sedTestingCol++] = testTask.getFriendlyId();
String participants = testTask.getTestParticipants().stream()
.map(participant -> participant.getFriendlyId())
.collect(Collectors.joining(";"));
csvDataMatrix[i][sedTestingCol++] = participants;
if (!ff4j.check(FeatureList.HTI_5_ERD)) {
List<TestTask> testTasks = getTestTasksForCriterion(certResult.getCriterion(), sed);
if (!CollectionUtils.isEmpty(testTasks)) {
for (int i = 0; i < testTasks.size(); i++) {
int sedTestingCol = currCol;
TestTask testTask = testTasks.get(i);
csvDataMatrix[i][sedTestingCol++] = testTask.getFriendlyId();
String participants = testTask.getTestParticipants().stream()
.map(participant -> participant.getFriendlyId())
.collect(Collectors.joining(";"));
csvDataMatrix[i][sedTestingCol++] = participants;
}
}
currCol += SED_TESTING_COL_COUNT;
}
currCol += SED_TESTING_COL_COUNT;
}
return currCol;
}
Expand Down
Loading
Loading