Skip to content

Commit

Permalink
Merge pull request #232 from navikt/detaljerChips
Browse files Browse the repository at this point in the history
Legge til støtte for lagring av valgte informasjons-bokser i Overblikk
  • Loading branch information
slovrid authored Aug 16, 2023
2 parents 924fe10 + 49a00b2 commit 2014a42
Show file tree
Hide file tree
Showing 13 changed files with 509 additions and 25 deletions.
54 changes: 35 additions & 19 deletions src/main/java/no/nav/pto/veilarbfilter/database/Table.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,50 @@
package no.nav.pto.veilarbfilter.database;

import lombok.experimental.UtilityClass;

@UtilityClass
public class Table {
public static class Filter {
public static String TABLE_NAME = "Filter";
public static String FILTER_ID = "filter_id";
public static String FILTER_NAVN = "filter_navn";
public static String VALGTE_FILTER = "valgte_filter";
public static String OPPRETTET = "opprettet";
public static String FILTER_CLEANUP = "filter_cleanup";
public static final String TABLE_NAME = "Filter";
public static final String FILTER_ID = "filter_id";
public static final String FILTER_NAVN = "filter_navn";
public static final String VALGTE_FILTER = "valgte_filter";
public static final String OPPRETTET = "opprettet";
public static final String FILTER_CLEANUP = "filter_cleanup";
private Filter() { throw new UnsupportedOperationException(); }
}

public static class MineLagredeFilter {
public static String TABLE_NAME = "minelagredefilter";
public static String FILTER_ID = "mine_filter_id";
public static String VEILEDER_ID = "veileder_id";
public static String AKTIV = "aktiv";
public static String NOTE = "note";
public static String SORT_ORDER = "sort_order";
public static final String TABLE_NAME = "minelagredefilter";
public static final String FILTER_ID = "mine_filter_id";
public static final String VEILEDER_ID = "veileder_id";
public static final String AKTIV = "aktiv";
public static final String NOTE = "note";
public static final String SORT_ORDER = "sort_order";
private MineLagredeFilter() { throw new UnsupportedOperationException(); }
}

public static class VeilederGrupperFilter {
public static String TABLE_NAME = "veiledergrupperfilter";
public static String FILTER_ID = "veiledergruppe_filter_id";
public static String ENHET_ID = "enhet_id";

public static final String TABLE_NAME = "veiledergrupperfilter";
public static final String FILTER_ID = "veiledergruppe_filter_id";
public static final String ENHET_ID = "enhet_id";
private VeilederGrupperFilter() { throw new UnsupportedOperationException(); }
}

public static class MetricsReporterInfo {
public static String TABLE_NAME = "MetricsReporterInfo";
public static String REPORTER_ID = "reporter_id";
public static String OPPRETTET = "opprettet";
public static final String TABLE_NAME = "MetricsReporterInfo";
public static final String REPORTER_ID = "reporter_id";
public static final String OPPRETTET = "opprettet";
private MetricsReporterInfo() { throw new UnsupportedOperationException(); }
}

public static class OverblikkVisning {
public static final String TABLE_NAME = "OverblikkVisning";
public static final String OVERBLIKK_VISNING_ID = "overblikk_visning_id";
public static final String VEILEDER_ID = "veileder_id";
public static final String SIST_ENDRET = "sist_endret";
public static final String VISNING = "visning";
private OverblikkVisning() { throw new UnsupportedOperationException(); }
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package no.nav.pto.veilarbfilter.domene;

import java.util.List;
import java.util.UUID;

public record OverblikkVisning(
UUID id,
List<String> visning
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package no.nav.pto.veilarbfilter.domene;

public enum OverblikkVisningAlternativer {
CV, JOBBONSKER, REGISTRERING, OPPFOLGING, YTELSER, PERSONALIA
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package no.nav.pto.veilarbfilter.domene;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

import java.util.List;

public record OverblikkVisningRequest(
List<String> overblikkVisning
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package no.nav.pto.veilarbfilter.domene;

import java.util.List;

public record OverblikkVisningResponse(
List<String> overblikkVisning
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package no.nav.pto.veilarbfilter.repository;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import no.nav.pto.veilarbfilter.domene.OverblikkVisning;
import no.nav.pto.veilarbfilter.domene.value.VeilederId;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.*;

import static no.nav.pto.veilarbfilter.database.Table.OverblikkVisning.*;
import static no.nav.pto.veilarbfilter.util.DateUtils.fromLocalDateTimeToTimestamp;
import static no.nav.pto.veilarbfilter.util.PostgresqlUtils.mapTilPostgresqlArray;

@Repository
@Slf4j
@RequiredArgsConstructor
public class OverblikkVisningRepository {
private final NamedParameterJdbcTemplate db;

public Optional<OverblikkVisning> hent(VeilederId veilederId) {
MapSqlParameterSource paramSource = new MapSqlParameterSource().addValue("veilederid", veilederId.getValue());
String sql = String.format("SELECT * FROM %s where %s = :veilederid", TABLE_NAME, VEILEDER_ID);

try {
OverblikkVisning overblikkVisning = db.queryForObject(
sql,
paramSource,
(rs, rowNum) -> new OverblikkVisning(
(UUID) rs.getObject(OVERBLIKK_VISNING_ID),
Arrays.asList((String[]) rs.getArray(VISNING).getArray())
)
);
return Optional.ofNullable(overblikkVisning);
} catch (EmptyResultDataAccessException e) {
return Optional.empty();
}
}

public void oppdater(UUID overblikkVisningId, List<String> overblikkVisning) {
MapSqlParameterSource paramSource = new MapSqlParameterSource()
.addValue("overblikkvisningid", overblikkVisningId)
.addValue("visning", mapTilPostgresqlArray(overblikkVisning))
.addValue("sistendret", fromLocalDateTimeToTimestamp(LocalDateTime.now()));

String query = String.format("""
UPDATE %s SET %s = :visning::varchar[], %s = :sistendret
WHERE %s = :overblikkvisningid
""",
TABLE_NAME,
VISNING,
SIST_ENDRET,
OVERBLIKK_VISNING_ID
);

db.update(query, paramSource);
}

public void opprett(VeilederId veilederId, List<String> overblikkVisning) {
MapSqlParameterSource paramSource = new MapSqlParameterSource().addValues(Map.ofEntries(
Map.entry("overblikkvisningid", UUID.randomUUID()),
Map.entry("veilederid", veilederId.getValue()),
Map.entry("visning", mapTilPostgresqlArray(overblikkVisning)),
Map.entry("sistendret", fromLocalDateTimeToTimestamp(LocalDateTime.now()))
));
String query = String.format("""
INSERT INTO %s (%s, %s, %s, %s) VALUES (:overblikkvisningid, :veilederid, :visning::varchar[], :sistendret)
""",
TABLE_NAME,
OVERBLIKK_VISNING_ID,
VEILEDER_ID,
VISNING,
SIST_ENDRET
);

db.update(query, paramSource);
}

public void slett(VeilederId veilederId) {
MapSqlParameterSource paramSource = new MapSqlParameterSource().addValue("veilederid", veilederId.getValue());
String query = String.format("DELETE FROM %s WHERE %s = :veilederid", TABLE_NAME, VEILEDER_ID);

db.update(query, paramSource);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package no.nav.pto.veilarbfilter.rest;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import no.nav.pto.veilarbfilter.auth.AuthUtils;
import no.nav.pto.veilarbfilter.domene.OverblikkVisning;
import no.nav.pto.veilarbfilter.domene.OverblikkVisningAlternativer;
import no.nav.pto.veilarbfilter.domene.OverblikkVisningRequest;
import no.nav.pto.veilarbfilter.domene.OverblikkVisningResponse;
import no.nav.pto.veilarbfilter.domene.value.VeilederId;
import no.nav.pto.veilarbfilter.service.OverblikkVisningService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.Collections;
import java.util.Optional;

import static no.nav.pto.veilarbfilter.util.SecureLogUtils.secureLog;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

@RequiredArgsConstructor
@Slf4j
@RestController
@RequestMapping(value = "/api/overblikkvisning", produces = APPLICATION_JSON_VALUE)
public class OverblikkVisningController {

private final OverblikkVisningService overblikkVisningService;

@PostMapping
public ResponseEntity<Object> lagreOverblikkvisningForInnloggetVeileder(@RequestBody OverblikkVisningRequest overblikkVisningRequest) {
VeilederId veilederId = AuthUtils.getInnloggetVeilederIdent();

try {
validerRequest(overblikkVisningRequest);
overblikkVisningService.lagreOverblikkVisning(veilederId, overblikkVisningRequest.overblikkVisning());
return ResponseEntity.noContent().build();
} catch (IllegalArgumentException e) {
secureLog.error(String.format("Klarte ikke å lagre overblikk visning for veilederId: %s. Grunn: ulovlige verdier i request.", veilederId), e);
return ResponseEntity.badRequest().build();
} catch (Exception e) {
secureLog.error(String.format("Klarte ikke å lagre overblikk visning for veilederId: %s.", veilederId), e);
return ResponseEntity.internalServerError().build();
}
}

@GetMapping
public ResponseEntity<OverblikkVisningResponse> hentOverblikkvisningForInnloggetVeileder() {
VeilederId veilederId = AuthUtils.getInnloggetVeilederIdent();

try {
Optional<OverblikkVisning> visningsListe = overblikkVisningService.hentOverblikkVisning(veilederId);
return visningsListe
.map(overblikkVisning -> ResponseEntity.ok().body(new OverblikkVisningResponse(overblikkVisning.visning())))
.orElseGet(() -> ResponseEntity.ok().body(new OverblikkVisningResponse(Collections.emptyList())));
} catch (Exception e) {
secureLog.error(String.format("Klarte ikke å hente overblikk visning for veilederId: %s", veilederId), e);
return ResponseEntity.internalServerError().build();
}
}

@DeleteMapping
public ResponseEntity<Object> slettOverblikkvisningForInnloggetVeileder() {
VeilederId veilederId = AuthUtils.getInnloggetVeilederIdent();

try {
overblikkVisningService.slettOverblikkVisning(veilederId);
return ResponseEntity.noContent().build();
} catch (Exception e) {
secureLog.error(String.format("Klarte ikke å slette overblikk visning for veilederId: %s", veilederId), e);
return ResponseEntity.internalServerError().build();
}
}

private void validerRequest(OverblikkVisningRequest overblikkVisningRequest) {

boolean alleValgteAlternativerErLovlige = overblikkVisningRequest.overblikkVisning().stream()
.map(String::toUpperCase)
.allMatch(valgtAlternativ ->
Arrays.stream(OverblikkVisningAlternativer.values())
.map(Enum::name)
.anyMatch(lovligAlternativ -> lovligAlternativ.equals(valgtAlternativ))
);

if (!alleValgteAlternativerErLovlige) {
throw new IllegalArgumentException();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package no.nav.pto.veilarbfilter.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import no.nav.pto.veilarbfilter.domene.OverblikkVisning;
import no.nav.pto.veilarbfilter.domene.value.VeilederId;
import no.nav.pto.veilarbfilter.repository.OverblikkVisningRepository;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
@Slf4j
@RequiredArgsConstructor
public class OverblikkVisningService {

private final OverblikkVisningRepository overblikkVisningRepository;

public Optional<OverblikkVisning> hentOverblikkVisning(VeilederId veilederId) {
return overblikkVisningRepository.hent(veilederId);
}

public void lagreOverblikkVisning(VeilederId veilederId, List<String> overblikkVisning) {
Optional<OverblikkVisning> maybeEksisterendeOverblikkVisning = overblikkVisningRepository.hent(veilederId);

maybeEksisterendeOverblikkVisning.ifPresentOrElse(
(eksisterendeOverblikkVisning) -> overblikkVisningRepository.oppdater(eksisterendeOverblikkVisning.id(), overblikkVisning),
() -> overblikkVisningRepository.opprett(veilederId, overblikkVisning)
);
}

public void slettOverblikkVisning(VeilederId veilederId) {
overblikkVisningRepository.slett(veilederId);
}
}
14 changes: 14 additions & 0 deletions src/main/java/no/nav/pto/veilarbfilter/util/PostgresqlUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package no.nav.pto.veilarbfilter.util;

import java.util.List;
import java.util.stream.Collectors;

public final class PostgresqlUtils {
private PostgresqlUtils() {
throw new UnsupportedOperationException();
}

public static String mapTilPostgresqlArray(List<String> elementer) {
return elementer.stream().collect(Collectors.joining(",", "{", "}"));
}
}
12 changes: 12 additions & 0 deletions src/main/java/no/nav/pto/veilarbfilter/util/SecureLogUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package no.nav.pto.veilarbfilter.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class SecureLogUtils {
private SecureLogUtils() {
throw new UnsupportedOperationException();
}

public static final Logger secureLog = LoggerFactory.getLogger("SecureLog");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CREATE TABLE OverblikkVisning
(
OVERBLIKK_VISNING_ID UUID NOT NULL,
VEILEDER_ID VARCHAR(32) NOT NULL,
SIST_ENDRET TIMESTAMP NOT NULL,
VISNING VARCHAR(32)[] NOT NULL,
PRIMARY KEY (OVERBLIKK_VISNING_ID)
);

CREATE UNIQUE INDEX overblikk_visning_veileder_id_index ON OverblikkVisning (VEILEDER_ID, OVERBLIKK_VISNING_ID);
Loading

0 comments on commit 2014a42

Please sign in to comment.