From a1cd2d496d5642ed2b58fe96244556c5e12a3ce0 Mon Sep 17 00:00:00 2001 From: Maslyna Date: Tue, 25 Apr 2023 19:51:54 +0200 Subject: [PATCH 01/15] Updated liquibase: - new changesets --- .../com/provedcode/config/InitConfig.java | 58 +- src/main/resources/application-dev.properties | 2 - .../resources/application-prod.properties | 4 +- src/main/resources/application.properties | 13 +- .../db/changelog/changeset/V1/data-V1.sql | 547 ++++++++++++++++++ .../db/changelog/changeset/V1/drop-V1.sql | 14 + .../db/changelog/changeset/V1/schema-V1.sql | 132 +++++ .../{add-data.sql => V2/data-V2.sql} | 36 +- .../db/changelog/changeset/V2/drop-V2.sql | 15 + .../{create-tables.sql => V2/schema-V2.sql} | 27 +- .../db/changelog/db.changelog-master.yaml | 9 +- 11 files changed, 772 insertions(+), 85 deletions(-) create mode 100644 src/main/resources/db/changelog/changeset/V1/data-V1.sql create mode 100644 src/main/resources/db/changelog/changeset/V1/drop-V1.sql create mode 100644 src/main/resources/db/changelog/changeset/V1/schema-V1.sql rename src/main/resources/db/changelog/changeset/{add-data.sql => V2/data-V2.sql} (96%) create mode 100644 src/main/resources/db/changelog/changeset/V2/drop-V2.sql rename src/main/resources/db/changelog/changeset/{create-tables.sql => V2/schema-V2.sql} (88%) diff --git a/src/main/java/com/provedcode/config/InitConfig.java b/src/main/java/com/provedcode/config/InitConfig.java index f4d24bb..82aa7cb 100644 --- a/src/main/java/com/provedcode/config/InitConfig.java +++ b/src/main/java/com/provedcode/config/InitConfig.java @@ -1,29 +1,29 @@ -package com.provedcode.config; - -import com.provedcode.user.mapper.UserInfoMapper; -import com.provedcode.user.repo.UserInfoRepository; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.CommandLineRunner; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Component; - -@Slf4j -@Component -@AllArgsConstructor -public class InitConfig implements CommandLineRunner { - UserInfoRepository userInfoRepository; - PasswordEncoder passwordEncoder; - UserInfoMapper userInfoMapper; - - @Override - public void run(String... args) throws Exception { - // TODO: Method to change passwords for already created users from data1.sql - userInfoRepository.saveAll( - userInfoRepository.findAll().stream() - .map(i -> { - i.setPassword(passwordEncoder.encode(i.getPassword())); - return i; - }).toList()); - } -} \ No newline at end of file +//package com.provedcode.config; +// +//import com.provedcode.user.mapper.UserInfoMapper; +//import com.provedcode.user.repo.UserInfoRepository; +//import lombok.AllArgsConstructor; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.boot.CommandLineRunner; +//import org.springframework.security.crypto.password.PasswordEncoder; +//import org.springframework.stereotype.Component; +// +//@Slf4j +//@Component +//@AllArgsConstructor +//public class InitConfig implements CommandLineRunner { +// UserInfoRepository userInfoRepository; +// PasswordEncoder passwordEncoder; +// UserInfoMapper userInfoMapper; +// +// @Override +// public void run(String... args) throws Exception { +// // TODO: Method to change passwords for already created users from data1.sql +// userInfoRepository.saveAll( +// userInfoRepository.findAll().stream() +// .map(i -> { +// i.setPassword(passwordEncoder.encode(i.getPassword())); +// return i; +// }).toList()); +// } +//} \ No newline at end of file diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 4b8f38f..6bd5814 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -1,7 +1,5 @@ spring.datasource.driver-class-name=org.h2.Driver spring.datasource.username=sa spring.datasource.url=jdbc:h2:mem:./testdb;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DEFAULT_NULL_ORDERING=HIGH -spring.jpa.hibernate.ddl-auto=none -spring.sql.init.mode=always #logging.level.web=DEBUG #logging.level.sql=DEBUG \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index 810d9a1..b0ad889 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -1,5 +1,3 @@ spring.datasource.username=${DB_LOGIN} spring.datasource.password=${DB_PASSWORD} -spring.datasource.url=jdbc:postgresql://${DB_URL} -spring.jpa.hibernate.ddl-auto=none -spring.sql.init.mode=always \ No newline at end of file +spring.datasource.url=jdbc:postgresql://${DB_URL} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index dbc8154..f91aa56 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -11,7 +11,8 @@ spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect spring.datasource.driver-class-name=org.postgresql.Driver spring.h2.console.enabled=true spring.h2.console.path=/h2 -spring.jpa.hibernate.ddl-auto=create-drop +spring.jpa.hibernate.ddl-auto=none +spring.sql.init.mode=always ## ## AWS S3 properties ## @@ -22,14 +23,14 @@ aws-s3.bucket=${BUCKET} ## ## Generate DDL files to create DB ## -spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create-drop -spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=create.sql -spring.jpa.properties.javax.persistence.schema-generation.scripts.create-source=metadata +#spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create-drop +#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=create.sql +#spring.jpa.properties.javax.persistence.schema-generation.scripts.create-source=metadata ## ## Generate DDL files to drop DB ## -spring.jpa.properties.javax.persistence.schema-generation.scripts.drop-target=drop.sql -spring.jpa.properties.javax.persistence.schema-generation.scripts.drop-source=metadata +#spring.jpa.properties.javax.persistence.schema-generation.scripts.drop-target=drop.sql +#spring.jpa.properties.javax.persistence.schema-generation.scripts.drop-source=metadata ## ## DEFAULT PAGE PROPS ## diff --git a/src/main/resources/db/changelog/changeset/V1/data-V1.sql b/src/main/resources/db/changelog/changeset/V1/data-V1.sql new file mode 100644 index 0000000..3b8e80a --- /dev/null +++ b/src/main/resources/db/changelog/changeset/V1/data-V1.sql @@ -0,0 +1,547 @@ +--liquibase formatted sql +--changeset dennis:1 + +insert into authority (id, authority) +values (1, 'TALENT'); +-- -- FOR USER AUTHORITY +-- -- SELECT USER_INFO.ID , LOGIN , PASSWORD, talent_id , AUTHORITY FROM +-- -- USER_INFO +-- -- JOIN user_authorities ON talent_id = USER_INFO.ID +-- -- JOIN AUTHORITY ON AUTHORITY.ID = id + +insert into talent (first_name, last_name, specialization, image) +values ('Serhii', 'Soloviov', 'Java-Developer', 'https://i.pinimg.com/564x/e1/08/49/e10849923a8b2e85a7adf494ebd063e6.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hello! I was born in Ukraine. My profession is Java Back-end developer. Now I`m developing a Java backend using Spring Boot.', 'My cat`s name is Igor'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Java Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Spring Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Spring boot'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'H2 Database'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Here I wrote a program that transforms the written code into music', 'PUBLISHED', '2022-01-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2023-03-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'HIDDEN', '2021-06-08 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'SerhiiSoloviov@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Mykhailo', 'Ordyntsev', 'Java-Developer', 'https://i.pinimg.com/564x/c2/41/31/c24131fe00218467721ba5bacdf0a256.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hello! I was born in Ukraine. My profession is Java Back-end developer. Now I`m developing a Java backend using Spring Boot.', 'I very like anime'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Java Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Hibernate'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Spring Boot'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'MykhailoOrdyntsev_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'MykhailoOrdyntsev_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'MykhailoOrdyntsev_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to first proof', 'DRAFT', '2022-08-07 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'HIDDEN', '2022-04-08 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2022-09-02 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'MykhailoOrdyntsev@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Denis', 'Boyko', 'Java-Developer', 'https://i.pinimg.com/564x/2a/0c/08/2a0c08c421e253ca895c3fdc8c9e08d9.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hello! I was born in Ukraine. My profession is Java Back-end developer. Now I`m developing a Java backend using Spring Boot.', 'I`m a student '); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Java Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Spring Security'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Spring Core'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DenisBoyko_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DenisBoyko_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DenisBoyko_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to first proof', 'DRAFT', '2022-02-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2021-09-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-04-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'DenisBoyko@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Ihor', 'Schurenko', 'Java-Developer', 'https://i.pinimg.com/564x/e1/11/2f/e1112f0b7b63644dc3e313084936dedb.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hello! I was born in Ukraine. My profession is Java Back-end developer. Now I`m developing a Java backend using Spring Boot.', 'I will get married soon'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Java Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'REST API'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'IhorShchurenko_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'IhorShchurenko_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'IhorShchurenko_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Here I describe my rest api project in java', 'PUBLISHED', '2021-08-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2022-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-05-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'IhorShchurenko@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Dmytro', 'Uzun', 'Dev-Ops', 'https://i.pinimg.com/564x/1c/af/87/1caf8771ef3edf351f6f2bf6f1c0a276.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'I am instructing a team that is currently writing my own biography for me.', 'He-he-he, hello everyone!'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Docker'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Mentor'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DmytroUzun_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DmytroUzun_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DmytroUzun_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://github.com/ProvedCode', 'My project where I am a team mentor', 'PUBLISHED', '2023-02-08 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2021-03-03 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-09-05 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'DmytroUzun@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Viktor', 'Voloshko', 'Dev-Ops', 'https://i.pinimg.com/564x/a9/51/ab/a951ab682413b89617235e65564c1e5e.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is dev-ops.', 'I like videogames!'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Docker'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'ViktorVoloshko_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'ViktorVoloshko_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'ViktorVoloshko_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to first proof', 'HIDDEN', '2022-02-09 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2020-04-02 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-08-06 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'ViktorVoloshko@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Olha', 'Moiseienko', 'QA', 'https://i.pinimg.com/564x/6d/9d/43/6d9d437baf4db114c047d927307beb84.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is QA.', 'Glory to Ukraine'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Jira'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'QA'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'OlhaMoiseienko_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'OlhaMoiseienko_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'OlhaMoiseienko_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to first proof', 'HIDDEN', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'My QA Jira project', 'PUBLISHED', '2022-09-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2021-01-09 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'OlhaMoiseienko@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Maxim', 'Kiyashko', 'QA', 'https://i.pinimg.com/564x/80/2d/58/802d58b0302985f9486893d499d3634d.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is QA.', 'Glory to Ukraine'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'QA'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'MaximKiyashko_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'MaximKiyashko_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'MaximKiyashko_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'My custom Arduino OS', 'PUBLISHED', '2023-08-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2023-01-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'PUBLISHED', '2023-02-09 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'MaximKiyashko@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Nikolaiev', 'Oleksii', 'QA', 'https://i.pinimg.com/564x/54/d1/0d/54d10dfce64afefabc9fbbce5de82c87.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is QA.', 'Glory to Ukraine'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'QA'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'NikolaievOleksii_third_talents'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'NikolaievOleksii_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'NikolaievOleksii_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'NikolaievOleksii_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Link to my magnum opus:', 'PUBLISHED', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'HIDDEN', '2023-06-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'NikolaievOleksiio@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Artem', 'Lytvynenko', 'QA', 'https://i.pinimg.com/564x/87/63/55/87635509c5fa7ee496ec351fa7e67eaa.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is QA.', 'Glory to Ukraine'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'QA'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Git'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'ArtemLytvynenko_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'ArtemLytvynenko_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'ArtemLytvynenko_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Here I wrote tasks for the project', 'PUBLISHED', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'HIDDEN', '2023-06-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'ArtemLytvynenko@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Daniil', 'Yevtukhov', 'Java-Script-Developer', 'https://i.pinimg.com/564x/fe/b1/37/feb137d88a3d1c8fb28796db6cbc576f.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is JavaScript developer.', 'I have my own Instagram'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'JavaScript Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'React'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DaniilYevtukhov_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DaniilYevtukhov_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'DaniilYevtukhov_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'My main project where I am making REACT application', 'PUBLISHED', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'HIDDEN', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-06-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'DaniilYevtukhov@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Ruslan', 'Morozov', 'Java-Script-Developer', 'https://i.pinimg.com/736x/36/ae/0e/36ae0ea4aad656f7c3d3175bc33b8399.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is JavaScript developer.', 'Glory to Ukraine'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'JavaScript Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'React'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Node.js'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'RuslanMorozov_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'RuslanMorozov_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'RuslanMorozov_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Here my container for styles', 'PUBLISHED', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to second proof', 'DRAFT', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-06-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'RuslanMorozov@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); + +insert into talent (first_name, last_name, specialization, image) +values ('Ihor', 'Kopieichykov', 'Java-Script-Developer', 'https://i.pinimg.com/564x/0d/f0/83/0df083121bac75f64e3d93c7c5682d04.jpg'); +insert into talent_description (talent_id, BIO, addition_info) +values((select id from talent order by id desc limit 1), 'Hi all! I was born in Ukraine. I am a student. My profession is JavaScript developer.', 'Glory to Ukraine'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_link (talent_id, link) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'JavaScript Core'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'React'); +insert into talent_talents (talent_id, talent_name) +values ((select id from talent order by id desc limit 1), 'Angular'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'IhorKopieichykov_first_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'IhorKopieichykov_second_contact'); +insert into talent_contact (talent_id, contact) +values ((select id from talent order by id desc limit 1), 'IhorKopieichykov_third_contact'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); +insert into talent_attached_file (talent_id, attached_file) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'); + +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Here is my JavaScript library', 'PUBLISHED', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'Here is my main project in Angular', 'PUBLISHED', '2023-06-04 16:00:19'); +insert into talent_proofs (talent_id, link, text, status, created) +values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-06-04 16:00:19'); + +insert into user_info (talent_id, login, password) +values ((select id from talent order by id desc limit 1), 'IhorKopieichykov@gmail.com', 'password'); +insert into user_authorities (user_id, authority_id) +values ((select id from user_info order by id desc limit 1), + (select authority.id from authority where id = 1)); \ No newline at end of file diff --git a/src/main/resources/db/changelog/changeset/V1/drop-V1.sql b/src/main/resources/db/changelog/changeset/V1/drop-V1.sql new file mode 100644 index 0000000..09b1124 --- /dev/null +++ b/src/main/resources/db/changelog/changeset/V1/drop-V1.sql @@ -0,0 +1,14 @@ +--liquibase formatted sql +--changeset mykhailo:2 + +drop table if exists authority cascade; +drop table if exists talent cascade; +drop table if exists talent_attached_file cascade; +drop table if exists talent_contact cascade; +drop table if exists talent_description cascade; +drop table if exists talent_link cascade; +drop table if exists talent_proofs cascade; +drop table if exists talent_talents cascade; +drop table if exists user_authorities cascade; +drop table if exists user_info cascade; +drop table if exists kudos cascade; diff --git a/src/main/resources/db/changelog/changeset/V1/schema-V1.sql b/src/main/resources/db/changelog/changeset/V1/schema-V1.sql new file mode 100644 index 0000000..7eccc32 --- /dev/null +++ b/src/main/resources/db/changelog/changeset/V1/schema-V1.sql @@ -0,0 +1,132 @@ +-- liquibase formatted sql +-- changeset dennis:1 + +drop table if exists authority cascade; + +CREATE TABLE authority +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + authority VARCHAR(20) NOT NULL, + CONSTRAINT pk_authority PRIMARY KEY (id) +); + +drop table if exists talent cascade; +CREATE TABLE talent +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + first_name VARCHAR(20), + last_name VARCHAR(20), + specialization VARCHAR(30), + image VARCHAR(300), + CONSTRAINT pk_talent PRIMARY KEY (id) +); + +drop table if exists talent_attached_file cascade; +CREATE TABLE talent_attached_file +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + attached_file VARCHAR(100), + CONSTRAINT pk_talent_attached_file PRIMARY KEY (id) +); + +drop table if exists talent_contact cascade; +CREATE TABLE talent_contact +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + contact VARCHAR(255), + CONSTRAINT pk_talent_contact PRIMARY KEY (id) +); + +drop table if exists talent_description cascade; +CREATE TABLE talent_description +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + bio VARCHAR(255), + addition_info VARCHAR(255), + CONSTRAINT pk_talent_description PRIMARY KEY (id) +); + +drop table if exists talent_link cascade; +CREATE TABLE talent_link +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + link VARCHAR(255), + CONSTRAINT pk_talent_link PRIMARY KEY (id) +); + +drop table if exists talent_proofs cascade; +CREATE TABLE talent_proofs +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + link VARCHAR(100), + text VARCHAR(255), + status VARCHAR(20) NOT NULL, + created TIMESTAMP, + CONSTRAINT pk_talent_proofs PRIMARY KEY (id) +); + +drop table if exists talent_talents cascade; +CREATE TABLE talent_talents +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + talent_name VARCHAR(255), + CONSTRAINT pk_talent_talents PRIMARY KEY (id) +); + +drop table if exists user_authorities cascade; +CREATE TABLE user_authorities +( + authority_id BIGINT NOT NULL, + user_id BIGINT NOT NULL, + CONSTRAINT pk_user_authorities PRIMARY KEY (authority_id, user_id) +); + +drop table if exists user_info cascade; +CREATE TABLE user_info +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT NOT NULL, + login VARCHAR(100) NOT NULL, + password VARCHAR(255) NOT NULL, + CONSTRAINT pk_user_info PRIMARY KEY (id) +); + + +drop table if exists kudos cascade; +CREATE TABLE kudos +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + talent_id BIGINT, + proof_id BIGINT, + CONSTRAINT pk_kudos PRIMARY KEY (id) +); + + +ALTER TABLE talent_attached_file + ADD CONSTRAINT FK_TALENT_ATTACHED_FILE_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE talent_contact + ADD CONSTRAINT FK_TALENT_CONTACT_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE talent_description + ADD CONSTRAINT FK_TALENT_DESCRIPTION_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE talent_link + ADD CONSTRAINT FK_TALENT_LINK_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE talent_proofs + ADD CONSTRAINT FK_TALENT_PROOFS_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE talent_talents + ADD CONSTRAINT FK_TALENT_TALENTS_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE user_info + ADD CONSTRAINT FK_USER_INFO_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); +ALTER TABLE user_authorities + ADD CONSTRAINT fk_useaut_on_authority FOREIGN KEY (authority_id) REFERENCES authority (id); +ALTER TABLE user_authorities + ADD CONSTRAINT fk_useaut_on_user_info FOREIGN KEY (user_id) REFERENCES user_info (id); +ALTER TABLE kudos + ADD CONSTRAINT FK_KUDOS_ON_PROOF FOREIGN KEY (proof_id) REFERENCES talent_proofs (id); +ALTER TABLE kudos + ADD CONSTRAINT FK_KUDOS_ON_TALENT FOREIGN KEY (talent_id) REFERENCES talent (id); \ No newline at end of file diff --git a/src/main/resources/db/changelog/changeset/add-data.sql b/src/main/resources/db/changelog/changeset/V2/data-V2.sql similarity index 96% rename from src/main/resources/db/changelog/changeset/add-data.sql rename to src/main/resources/db/changelog/changeset/V2/data-V2.sql index ce9026b..e0d6ee0 100644 --- a/src/main/resources/db/changelog/changeset/add-data.sql +++ b/src/main/resources/db/changelog/changeset/V2/data-V2.sql @@ -1,5 +1,5 @@ --liquibase formatted sql ---changeset dennis:1 +--changeset mykhailo:2 -- -- FOR USER AUTHORITY -- -- SELECT USER_INFO.ID , LOGIN , PASSWORD, talent_id , AUTHORITY FROM @@ -50,7 +50,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'HIDDEN', '2021-06-08 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'SerhiiSoloviov@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'SerhiiSoloviov@gmail.com', '$2a$10$EzYxG1DEUek/veK.HzP7B.ynSKE42VbLb4pvFd/v4OwGPNol6buEC'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -93,7 +93,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2022-09-02 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'MykhailoOrdyntsev@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'MykhailoOrdyntsev@gmail.com', '$2a$10$XD60M86n1MDf3AMIixgnnOQq9JVYnnX/umlNFcre0GoC2XgSN/Cfq'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -134,7 +134,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-04-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'DenisBoyko@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'DenisBoyko@gmail.com', '$2a$10$tLm27FGH8Sabz57eNkTwm.bSnhmJHINcqt7dNfZI0NfOwD2o/Drse'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -174,7 +174,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-05-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'IhorShchurenko@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'IhorShchurenko@gmail.com', '$2a$10$X.d4hR.yRf3cK0Go20aTTukOI9u/Zu2cj5WU0iTcDihyhJ5vUHXkq'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -216,7 +216,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-09-05 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'DmytroUzun@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'DmytroUzun@gmail.com', '$2a$10$J2Yuh10BWHy8XYk.T5rd2uOwk/h5EYG1eVXTAOkTkTdQcc5Qzd9.y'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -256,7 +256,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-08-06 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'ViktorVoloshko@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'ViktorVoloshko@gmail.com', '$2a$10$eZX3hBvllxkmH.juZzN72uvFYtphkrxsj14K5BnHHKy4coRV9FMvq'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -298,7 +298,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2021-01-09 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'OlhaMoiseienko@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'OlhaMoiseienko@gmail.com', '$2a$10$lvvX7DZOwCS/Q7zSo.k.oeayTcKHh8rO1yBBkgIbU4VAC7abPfIa2'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -338,7 +338,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'PUBLISHED', '2023-02-09 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'MaximKiyashko@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'MaximKiyashko@gmail.com', '$2a$10$y.g9qHYUOPEkIL8xDc2h1.EdVAG5DYh6OKxf9CRb6s16oHHbr8Bny'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -380,7 +380,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'HIDDEN', '2023-06-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'NikolaievOleksiio@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'NikolaievOleksiio@gmail.com', '$2a$10$nDObO3nDlhWev29qCnzNuOszdg/.ANaMlTirDVWVyLMapYmtSSqza'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -420,7 +420,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'HIDDEN', '2023-06-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'ArtemLytvynenko@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'ArtemLytvynenko@gmail.com', '$2a$10$.M2fHh9NXbkbnrVHeT.lYeInA8K2khuMUL08iG4NuXs18KIeFBmwG'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -460,7 +460,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-06-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'DaniilYevtukhov@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'DaniilYevtukhov@gmail.com', '$2a$10$cDxp6U/YcObKMwZNgtEB5eZFLWXuwFU0lIUSPIkfPdvq9l8JUqGea'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -502,7 +502,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-06-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'RuslanMorozov@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), 'RuslanMorozov@gmail.com', '$2a$10$Hfzp4b6r825g1ZqGzxmal..VNKvo7F4v4YFpBZZ036hmO.7UIWlaK'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -544,7 +544,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-06-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), 'IhorKopieichykov@gmail.com', 'password'); +values ((select id from talent order by id desc limit 1), '$2a$10$D4KM50WemOahkFv1fkrPX.MvVESsE0TYWlkh5TypTE/q4nlv8ooyS', 'password'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -553,7 +553,7 @@ insert into sponsor (amount_kudos, first_name, last_name, image) values (888, 'Maksym', 'Khudoliy', 'https://i.pinimg.com/564x/e1/08/49/e10849923a8b2e85a7adf494ebd063e6.jpg'); insert into user_info (sponsor_id, login, password) -values ((select id from sponsor order by id desc limit 1), 'MaksymKhudoliy@gmail.com', 'password'); +values ((select id from sponsor order by id desc limit 1), 'MaksymKhudoliy@gmail.com', '$2a$10$pDrAuawhi3ADZpVDDr7C6eAcaQwDr5oQ9GdZUUZHSsqyM/vVkpruy'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 2) ); @@ -562,7 +562,7 @@ insert into sponsor (amount_kudos, first_name, last_name, image) values (888, 'Oleksandr', 'Butrym', 'https://i.pinimg.com/564x/c2/41/31/c24131fe00218467721ba5bacdf0a256.jpg'); insert into user_info (sponsor_id, login, password) -values ((select id from sponsor order by id desc limit 1), 'OleksandrButrym@gmail.com', 'password'); +values ((select id from sponsor order by id desc limit 1), 'OleksandrButrym@gmail.com', '$2a$10$R0o8os0t86qyBvg0bO/a6ukuy9VesLapxIkZFLjNupWjvr5Hdjyge'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 2) ); @@ -571,7 +571,7 @@ insert into sponsor (amount_kudos, first_name, last_name, image) values (888, 'Olha', 'Shutylieva', 'https://i.pinimg.com/564x/2a/0c/08/2a0c08c421e253ca895c3fdc8c9e08d9.jpg'); insert into user_info (sponsor_id, login, password) -values ((select id from sponsor order by id desc limit 1), 'OlhaShutylieva@gmail.com', 'password'); +values ((select id from sponsor order by id desc limit 1), 'OlhaShutylieva@gmail.com', '$2a$10$UzwVTVR7E2BW.5hA4XWgy.g0XcM.UbIMBoY1cDnYNPQDhCXEa7eGm'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 2) ); @@ -580,7 +580,7 @@ insert into sponsor (amount_kudos, first_name, last_name, image) values (888, 'Vladyslav', 'Khrychov', 'https://i.pinimg.com/564x/e1/11/2f/e1112f0b7b63644dc3e313084936dedb.jpg'); insert into user_info (sponsor_id, login, password) -values ((select id from sponsor order by id desc limit 1), 'VladyslavKhrychov@gmail.com', 'password'); +values ((select id from sponsor order by id desc limit 1), 'VladyslavKhrychov@gmail.com', '$2a$10$o2va23ZPVVSptyCaSBO/oubpML4xEPZo9Ie0ASt154zNVSKdFrN02'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 2) ); diff --git a/src/main/resources/db/changelog/changeset/V2/drop-V2.sql b/src/main/resources/db/changelog/changeset/V2/drop-V2.sql new file mode 100644 index 0000000..7b0ee1f --- /dev/null +++ b/src/main/resources/db/changelog/changeset/V2/drop-V2.sql @@ -0,0 +1,15 @@ +--liquibase formatted sql +--changeset mykhailo:2 + +drop table if exists authority cascade; +drop table if exists talent cascade; +drop table if exists talent_attached_file cascade; +drop table if exists talent_contact cascade; +drop table if exists talent_description cascade; +drop table if exists talent_link cascade; +drop table if exists talent_proofs cascade; +drop table if exists talent_talents cascade; +drop table if exists user_authorities cascade; +drop table if exists user_info cascade; +drop table if exists kudos cascade; +drop table if exists sponsor cascade; diff --git a/src/main/resources/db/changelog/changeset/create-tables.sql b/src/main/resources/db/changelog/changeset/V2/schema-V2.sql similarity index 88% rename from src/main/resources/db/changelog/changeset/create-tables.sql rename to src/main/resources/db/changelog/changeset/V2/schema-V2.sql index 18a84f4..2519646 100644 --- a/src/main/resources/db/changelog/changeset/create-tables.sql +++ b/src/main/resources/db/changelog/changeset/V2/schema-V2.sql @@ -1,7 +1,8 @@ -- liquibase formatted sql --- changeset dennis:1 +-- changeset mykhailo:2 + +-- tables for sprint 3.2 -drop table if exists authority cascade; CREATE TABLE authority ( @@ -9,8 +10,6 @@ CREATE TABLE authority authority VARCHAR(20) NOT NULL, CONSTRAINT pk_authority PRIMARY KEY (id) ); - -drop table if exists talent cascade; CREATE TABLE talent ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -20,8 +19,6 @@ CREATE TABLE talent image VARCHAR(300), CONSTRAINT pk_talent PRIMARY KEY (id) ); - -drop table if exists talent_attached_file cascade; CREATE TABLE talent_attached_file ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -29,8 +26,6 @@ CREATE TABLE talent_attached_file attached_file VARCHAR(100), CONSTRAINT pk_talent_attached_file PRIMARY KEY (id) ); - -drop table if exists talent_contact cascade; CREATE TABLE talent_contact ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -38,8 +33,6 @@ CREATE TABLE talent_contact contact VARCHAR(255), CONSTRAINT pk_talent_contact PRIMARY KEY (id) ); - -drop table if exists talent_description cascade; CREATE TABLE talent_description ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -48,8 +41,6 @@ CREATE TABLE talent_description addition_info VARCHAR(255), CONSTRAINT pk_talent_description PRIMARY KEY (id) ); - -drop table if exists talent_link cascade; CREATE TABLE talent_link ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -57,8 +48,6 @@ CREATE TABLE talent_link link VARCHAR(255), CONSTRAINT pk_talent_link PRIMARY KEY (id) ); - -drop table if exists talent_proofs cascade; CREATE TABLE talent_proofs ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -69,8 +58,6 @@ CREATE TABLE talent_proofs created TIMESTAMP, CONSTRAINT pk_talent_proofs PRIMARY KEY (id) ); - -drop table if exists talent_talents cascade; CREATE TABLE talent_talents ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -78,16 +65,12 @@ CREATE TABLE talent_talents talent_name VARCHAR(255), CONSTRAINT pk_talent_talents PRIMARY KEY (id) ); - -drop table if exists user_authorities cascade; CREATE TABLE user_authorities ( authority_id BIGINT NOT NULL, user_id BIGINT NOT NULL, CONSTRAINT pk_user_authorities PRIMARY KEY (authority_id, user_id) ); - -drop table if exists user_info cascade; CREATE TABLE user_info ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -97,8 +80,6 @@ CREATE TABLE user_info password VARCHAR(255) NOT NULL, CONSTRAINT pk_user_info PRIMARY KEY (id) ); - -drop table if exists kudos cascade; CREATE TABLE kudos ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -107,8 +88,6 @@ CREATE TABLE kudos amount_kudos BIGINT, CONSTRAINT pk_kudos PRIMARY KEY (id) ); - -drop table if exists sponsor cascade; CREATE TABLE sponsor ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index 41cf880..4a6438c 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -1,6 +1,9 @@ databaseChangeLog: - include: - file: db/changelog/changeset/create-tables.sql - + file: db/changelog/changeset/V1/drop-V1.sql - include: - file: db/changelog/changeset/add-data.sql + file: db/changelog/changeset/V2/drop-V2.sql + - include: + file: db/changelog/changeset/V2/schema-V2.sql + - include: + file: db/changelog/changeset/V2/data-V2.sql \ No newline at end of file From 1ddf4d1a7d833412315647dd8b3fab2860bcc6fb Mon Sep 17 00:00:00 2001 From: Maslyna Date: Tue, 25 Apr 2023 20:46:59 +0200 Subject: [PATCH 02/15] BUGFIX: `GET(/api/v3/proofs/1/kudos)`` has problems after deleting a `sponsor` --- .../model/response/KudosAmountWithSponsor.java | 2 +- .../com/provedcode/kudos/service/KudosService.java | 14 ++++++++------ .../provedcode/sponsor/model/dto/SponsorDTO.java | 2 ++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/provedcode/kudos/model/response/KudosAmountWithSponsor.java b/src/main/java/com/provedcode/kudos/model/response/KudosAmountWithSponsor.java index 16b302b..75b80f9 100644 --- a/src/main/java/com/provedcode/kudos/model/response/KudosAmountWithSponsor.java +++ b/src/main/java/com/provedcode/kudos/model/response/KudosAmountWithSponsor.java @@ -8,6 +8,6 @@ @Builder public record KudosAmountWithSponsor( Long allKudosOnProof, - Map kudosFromSponsor + Map kudosFromSponsor ) { } diff --git a/src/main/java/com/provedcode/kudos/service/KudosService.java b/src/main/java/com/provedcode/kudos/service/KudosService.java index 65dd7bf..7ccd36e 100644 --- a/src/main/java/com/provedcode/kudos/service/KudosService.java +++ b/src/main/java/com/provedcode/kudos/service/KudosService.java @@ -22,6 +22,8 @@ import java.util.HashMap; import java.util.Map; +import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; import static org.springframework.http.HttpStatus.*; @@ -87,22 +89,22 @@ public KudosAmountWithSponsor getProofKudos(long id, Authentication authenticati .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "Proof with id = %s not found".formatted(id))); - if (talent.getId() == talentProof.getTalent().getId()) { - Map kudosFromSponsor = talentProof.getKudos().stream() + if (Objects.equals(talent.getId(), talentProof.getTalent().getId())) { + Map kudosFromSponsor = talentProof.getKudos().stream() .collect(Collectors.toMap( - sponsor -> sponsorMapper.toDto(sponsor.getSponsor()), Kudos::getAmountKudos, - (sponsor, kudos) -> sponsor, + proof -> proof.getSponsor() != null ? sponsorMapper.toDto(proof.getSponsor()) : SponsorDTO.builder().build(), + (prev, next) -> next, HashMap::new )); - Long counter = talentProof.getKudos().stream().map(i -> i.getAmountKudos()) + Long counter = talentProof.getKudos().stream().map(Kudos::getAmountKudos) .mapToLong(Long::intValue).sum(); return KudosAmountWithSponsor.builder() .allKudosOnProof(counter) .kudosFromSponsor(kudosFromSponsor) .build(); } else { - Long counter = talentProof.getKudos().stream().map(i -> i.getAmountKudos()) + Long counter = talentProof.getKudos().stream().map(Kudos::getAmountKudos) .mapToLong(Long::intValue).sum(); return KudosAmountWithSponsor.builder() .allKudosOnProof(counter) diff --git a/src/main/java/com/provedcode/sponsor/model/dto/SponsorDTO.java b/src/main/java/com/provedcode/sponsor/model/dto/SponsorDTO.java index adffbbd..62c3b62 100644 --- a/src/main/java/com/provedcode/sponsor/model/dto/SponsorDTO.java +++ b/src/main/java/com/provedcode/sponsor/model/dto/SponsorDTO.java @@ -1,7 +1,9 @@ package com.provedcode.sponsor.model.dto; import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +@Builder public record SponsorDTO( Long id, @JsonProperty("first_name") From 1b4588d8cc7e95999923f15c5917c0d4da76fadd Mon Sep 17 00:00:00 2001 From: Maslyna Date: Tue, 25 Apr 2023 21:32:51 +0200 Subject: [PATCH 03/15] Little update --- .../kudos/service/KudosService.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/provedcode/kudos/service/KudosService.java b/src/main/java/com/provedcode/kudos/service/KudosService.java index 7ccd36e..2edcdd3 100644 --- a/src/main/java/com/provedcode/kudos/service/KudosService.java +++ b/src/main/java/com/provedcode/kudos/service/KudosService.java @@ -22,8 +22,6 @@ import java.util.HashMap; import java.util.Map; -import java.util.Objects; -import java.util.Optional; import java.util.stream.Collectors; import static org.springframework.http.HttpStatus.*; @@ -71,7 +69,7 @@ public KudosAmount getKudosForSponsor(long id, Authentication authentication) { Sponsor sponsor = sponsorRepository.findById(userInfo.getSponsor().getId()).orElseThrow( () -> new ResponseStatusException(NOT_FOUND, String.format("Sponsor with id = %d not found", id))); - if (sponsor.getId() != userInfo.getSponsor().getId()) { + if (!sponsor.getId().equals(userInfo.getSponsor().getId())) { throw new ResponseStatusException(FORBIDDEN, "Only the account owner can view the number of kudos"); } return new KudosAmount(sponsor.getAmountKudos()); @@ -89,7 +87,11 @@ public KudosAmountWithSponsor getProofKudos(long id, Authentication authenticati .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "Proof with id = %s not found".formatted(id))); - if (Objects.equals(talent.getId(), talentProof.getTalent().getId())) { + Long countOfAllKudos = talentProof.getKudos().stream() + .map(Kudos::getAmountKudos) + .reduce(0L, (prev, next) -> prev + next); + + if (talent.getId().equals(talentProof.getTalent().getId())) { Map kudosFromSponsor = talentProof.getKudos().stream() .collect(Collectors.toMap( Kudos::getAmountKudos, @@ -97,17 +99,14 @@ public KudosAmountWithSponsor getProofKudos(long id, Authentication authenticati (prev, next) -> next, HashMap::new )); - Long counter = talentProof.getKudos().stream().map(Kudos::getAmountKudos) - .mapToLong(Long::intValue).sum(); + return KudosAmountWithSponsor.builder() - .allKudosOnProof(counter) + .allKudosOnProof(countOfAllKudos) .kudosFromSponsor(kudosFromSponsor) .build(); } else { - Long counter = talentProof.getKudos().stream().map(Kudos::getAmountKudos) - .mapToLong(Long::intValue).sum(); return KudosAmountWithSponsor.builder() - .allKudosOnProof(counter) + .allKudosOnProof(countOfAllKudos) .kudosFromSponsor(null).build(); } } From d4da2b9596481c577dd70ad12efa09fdb7e6a8af Mon Sep 17 00:00:00 2001 From: Maslyna Date: Wed, 26 Apr 2023 14:15:59 +0200 Subject: [PATCH 04/15] Removed exception handler for Exception.class --- .../handlers/TalentExceptionHandler.java | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java b/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java index cf460c5..b1a6e08 100644 --- a/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java +++ b/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java @@ -5,14 +5,19 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.context.request.WebRequest; import org.springframework.web.server.ResponseStatusException; import java.sql.SQLException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; @ControllerAdvice public class TalentExceptionHandler { @@ -64,41 +69,39 @@ public static boolean ignoreSQLException(String sqlState) { return false; } - @ExceptionHandler({ Exception.class }) - public ResponseEntity handleAll(Exception ex, WebRequest request) { - ApiError apiError = new ApiError( - HttpStatus.INTERNAL_SERVER_ERROR, ex.getLocalizedMessage(), "error occurred"); - return new ResponseEntity( - apiError, new HttpHeaders(), apiError.getStatus()); - } +// @ExceptionHandler({ Exception.class }) +// public ResponseEntity handleAll(Exception ex, WebRequest request) { +// ApiError apiError = new ApiError(HttpStatus.INTERNAL_SERVER_ERROR, ex.getLocalizedMessage(), "error occurred"); +// return new ResponseEntity<>(apiError, new HttpHeaders(), apiError.getStatus()); +// } //MethodArgumentNotValidException – This exception is thrown // when an argument annotated with @Valid failed validation: // @ResponseStatus(HttpStatus.BAD_REQUEST) // @ExceptionHandler(MethodArgumentNotValidException.class) -// public Map handleValidationExceptions( -// MethodArgumentNotValidException ex) { +// public Map handleValidationExceptions(MethodArgumentNotValidException ex) { // Map errors = new HashMap<>(); -// ex.getBindingResult().getAllErrors().forEach((error) -> { -// String fieldName = ((FieldError) error).getField(); -// String errorMessage = error.getDefaultMessage(); -// errors.put(fieldName, errorMessage); -// }); +// ex.getBindingResult().getAllErrors().forEach( +// (error) -> { +// String fieldName = ((FieldError) error).getField(); +// String errorMessage = error.getDefaultMessage(); +// errors.put(fieldName, errorMessage); +// }); // return errors; // } - @ExceptionHandler({ ConstraintViolationException.class }) - public ResponseEntity handleConstraintViolation( - ConstraintViolationException ex, WebRequest request) { - List errors = new ArrayList<>(); - for (ConstraintViolation violation : ex.getConstraintViolations()) { - errors.add(violation.getRootBeanClass().getName() + " " + - violation.getPropertyPath() + ": " + violation.getMessage()); - } - - ApiError apiError = - new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), errors); - return new ResponseEntity( - apiError, new HttpHeaders(), apiError.getStatus()); - } +// @ExceptionHandler({ ConstraintViolationException.class }) +// public ResponseEntity handleConstraintViolation( +// ConstraintViolationException ex, WebRequest request) { +// List errors = new ArrayList<>(); +// for (ConstraintViolation violation : ex.getConstraintViolations()) { +// errors.add(violation.getRootBeanClass().getName() + " " + +// violation.getPropertyPath() + ": " + violation.getMessage()); +// } +// +// ApiError apiError = +// new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), errors); +// return new ResponseEntity( +// apiError, new HttpHeaders(), apiError.getStatus()); +// } } \ No newline at end of file From 1bea5c8db18cada61b2cdd21c3cec6f3f83540a2 Mon Sep 17 00:00:00 2001 From: Maslyna Date: Wed, 26 Apr 2023 15:25:29 +0200 Subject: [PATCH 05/15] Code refactor: - Created and implemented new refactor idea use @Annotations to documenting REST API with Open API --- Created: --- DeleteProofApiDoc DeleteSponsorApiDoc DeleteTalentApiDoc GetAllProofsApiDoc GetAllSponsorsApiDoc GetAllTalentsApiDoc GetAmountOfKudosApiDoc GetKudosForSponsorApiDoc GetSponsorApiDoc GetTalentApiDoc GetTalentInformationWithProofsApiDoc GetTalentProofByProofIdApiDoc PatchEditProofApiDoc PatchEditSponsorApiDoc PatchEditTalentApiDoc PostAddKudosToProofApiDoc PostSponsorRegistrationApiDoc PostTalentRegistrationApiDoc PostUserLoginApiDoc --- .../kudos/controller/KudosController.java | 77 +--------- .../sponsor/controller/SponsorController.java | 98 +----------- .../talent/controller/TalentController.java | 89 +---------- .../controller/TalentProofController.java | 140 +----------------- .../talent/model/dto/FullTalentDTO.java | 2 +- .../talent/model/request/EditTalent.java | 3 +- .../controller/AuthenticationController.java | 58 +------- .../{ => util}/annotations/UrlList.java | 4 +- .../kudos/GetAmountOfKudosApiDoc.java | 42 ++++++ .../kudos/GetKudosForSponsorApiDoc.java | 42 ++++++ .../kudos/PostAddKudosToProofApiDoc.java | 37 +++++ .../controller/proof/DeleteProofApiDoc.java | 43 ++++++ .../controller/proof/GetAllProofsApiDoc.java | 35 +++++ .../GetTalentInformationWithProofsApiDoc.java | 38 +++++ .../proof/GetTalentProofByProofIdApiDoc.java | 37 +++++ .../proof/PatchEditProofApiDoc.java | 42 ++++++ .../controller/proof/PostAddProofApiDoc.java | 48 ++++++ .../sponsor/DeleteSponsorApiDoc.java | 42 ++++++ .../sponsor/GetAllSponsorsApiDoc.java | 31 ++++ .../controller/sponsor/GetSponsorApiDoc.java | 38 +++++ .../sponsor/PatchEditSponsorApiDoc.java | 47 ++++++ .../controller/talent/DeleteTalentApiDoc.java | 38 +++++ .../talent/GetAllTalentsApiDoc.java | 35 +++++ .../controller/talent/GetTalentApiDoc.java | 34 +++++ .../talent/PatchEditTalentApiDoc.java | 42 ++++++ .../user/PostSponsorRegistrationApiDoc.java | 33 +++++ .../user/PostTalentRegistrationApiDoc.java | 33 +++++ .../controller/user/PostUserLoginApiDoc.java | 37 +++++ .../annotations/impl/UrlListValidator.java | 4 +- 29 files changed, 815 insertions(+), 434 deletions(-) rename src/main/java/com/provedcode/{ => util}/annotations/UrlList.java (84%) create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetAmountOfKudosApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetKudosForSponsorApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/kudos/PostAddKudosToProofApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/proof/DeleteProofApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetAllProofsApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentInformationWithProofsApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentProofByProofIdApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/proof/PatchEditProofApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/proof/PostAddProofApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/DeleteSponsorApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetAllSponsorsApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetSponsorApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/PatchEditSponsorApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/talent/DeleteTalentApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetAllTalentsApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetTalentApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/talent/PatchEditTalentApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/user/PostSponsorRegistrationApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/user/PostTalentRegistrationApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/user/PostUserLoginApiDoc.java rename src/main/java/com/provedcode/{ => util}/annotations/impl/UrlListValidator.java (88%) diff --git a/src/main/java/com/provedcode/kudos/controller/KudosController.java b/src/main/java/com/provedcode/kudos/controller/KudosController.java index 20f8bce..6a3b6b8 100644 --- a/src/main/java/com/provedcode/kudos/controller/KudosController.java +++ b/src/main/java/com/provedcode/kudos/controller/KudosController.java @@ -3,13 +3,10 @@ import com.provedcode.kudos.model.response.KudosAmountWithSponsor; import com.provedcode.kudos.service.KudosService; import com.provedcode.kudos.model.response.KudosAmount; -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.responses.ApiResponses; +import com.provedcode.util.annotations.doc.controller.kudos.GetAmountOfKudosApiDoc; +import com.provedcode.util.annotations.doc.controller.kudos.GetKudosForSponsorApiDoc; +import com.provedcode.util.annotations.doc.controller.kudos.PostAddKudosToProofApiDoc; import lombok.AllArgsConstructor; -import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; @@ -20,55 +17,14 @@ public class KudosController { KudosService kudosService; - @Operation(summary = "Get all available kudos from a sponsor") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = KudosAmount.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to see other sponsor kudos)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST", - content = @Content) - }) + @GetKudosForSponsorApiDoc @PreAuthorize("hasRole('SPONSOR')") @GetMapping("/sponsors/{sponsor-id}/kudos") KudosAmount getKudosForSponsor(@PathVariable("sponsor-id") long id, Authentication authentication) { return kudosService.getKudosForSponsor(id, authentication); } - @Operation(summary = "As a sponsor I want to estimate talent proof by giving kudos") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if sponsor does not have enough kudos)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST", - content = @Content) - }) + @PostAddKudosToProofApiDoc @PreAuthorize("hasRole('SPONSOR')") @PostMapping("/proofs/{proof-id}/kudos/{amount}") void addKudosToProof(@PathVariable("proof-id") long id, @@ -77,28 +33,7 @@ void addKudosToProof(@PathVariable("proof-id") long id, kudosService.addKudosToProof(id, amount, authentication); } - @Operation(summary = "Amount of “kudos” given by sponsors and who gave the “kudos” on proof") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = KudosAmountWithSponsor.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the talent wants to see)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST", - content = @Content) - }) + @GetAmountOfKudosApiDoc @PreAuthorize("hasRole('TALENT')") @GetMapping("/proofs/{proof-id}/kudos") KudosAmountWithSponsor getProofKudos(@PathVariable("proof-id") long id, Authentication authentication) { diff --git a/src/main/java/com/provedcode/sponsor/controller/SponsorController.java b/src/main/java/com/provedcode/sponsor/controller/SponsorController.java index ea61f10..0dc811e 100644 --- a/src/main/java/com/provedcode/sponsor/controller/SponsorController.java +++ b/src/main/java/com/provedcode/sponsor/controller/SponsorController.java @@ -4,15 +4,13 @@ import com.provedcode.sponsor.model.dto.SponsorDTO; import com.provedcode.sponsor.model.dto.SponsorEditDTO; import com.provedcode.sponsor.service.SponsorService; -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.responses.ApiResponses; +import com.provedcode.util.annotations.doc.controller.sponsor.DeleteSponsorApiDoc; +import com.provedcode.util.annotations.doc.controller.sponsor.GetAllSponsorsApiDoc; +import com.provedcode.util.annotations.doc.controller.sponsor.GetSponsorApiDoc; +import com.provedcode.util.annotations.doc.controller.sponsor.PatchEditSponsorApiDoc; import lombok.AllArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; @@ -26,17 +24,7 @@ public class SponsorController { SponsorService sponsorService; SponsorMapper sponsorMapper; - @Operation(summary = "Get all sponsors (SponsorDTO)") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = Page.class, subTypes = {SponsorDTO.class}))), - @ApiResponse( - responseCode = "400", - description = "BAD_REQUEST (parameter: page or size are incorrect)", - content = @Content) - }) + @GetAllSponsorsApiDoc @GetMapping("/sponsors") @ResponseStatus(HttpStatus.OK) Page getSponsors(@RequestParam(value = "page") Optional page, @@ -44,59 +32,14 @@ Page getSponsors(@RequestParam(value = "page") Optional pag return sponsorService.getAllSponsors(page, size).map(sponsorMapper::toDto); } - @Operation(summary = "Get sponsor", - description = "As a sponsor I want to have an opportunity to see my own profile with information") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = SponsorDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "501", - description = "NOT_IMPLEMENTED (login is not valid)", - content = @Content) - }) + @GetSponsorApiDoc @PreAuthorize("hasRole('SPONSOR')") @GetMapping("/sponsors/{id}") SponsorDTO getSponsor(@PathVariable("id") long id, Authentication authentication) { return sponsorMapper.toDto(sponsorService.getSponsorById(id, authentication)); } - @Operation(summary = "Edit information about sponsor", - description = "As a sponsor I want to have an opportunity to edit my personal profile by adding new information, " + - "changing already existing information.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = SponsorDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to change the sponsor)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST", - content = @Content), - @ApiResponse( - responseCode = "501", - description = "NOT_IMPLEMENTED (login is not valid)", - content = @Content) - }) + @PatchEditSponsorApiDoc @PreAuthorize("hasRole('SPONSOR')") @PatchMapping("/sponsors/{id}") SponsorDTO editSponsor(@PathVariable("id") long id, @@ -105,32 +48,7 @@ SponsorDTO editSponsor(@PathVariable("id") long id, return sponsorMapper.toDto(sponsorService.editSponsorById(id, sponsorEditDTO, authentication)); } - @Operation(summary = "Delete sponsor", - description = "As a sponsor I want to have an opportunity to delete personal accounts.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content), - @ApiResponse(responseCode = "404", - description = "NOT FOUND ", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to delete the talent)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST (incorrect id)", - content = @Content), - @ApiResponse( - responseCode = "501", - description = "NOT_IMPLEMENTED (login is not valid)", - content = @Content), - }) + @DeleteSponsorApiDoc @PreAuthorize("hasRole('SPONSOR')") @DeleteMapping("/sponsors/{id}") void deleteSponsor(@PathVariable("id") long id, Authentication authentication) { diff --git a/src/main/java/com/provedcode/talent/controller/TalentController.java b/src/main/java/com/provedcode/talent/controller/TalentController.java index 5ab3d23..8691928 100644 --- a/src/main/java/com/provedcode/talent/controller/TalentController.java +++ b/src/main/java/com/provedcode/talent/controller/TalentController.java @@ -6,18 +6,16 @@ import com.provedcode.talent.model.request.EditTalent; import com.provedcode.talent.service.TalentService; import com.provedcode.user.model.dto.SessionInfoDTO; -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.responses.ApiResponses; +import com.provedcode.util.annotations.doc.controller.talent.DeleteTalentApiDoc; +import com.provedcode.util.annotations.doc.controller.talent.GetAllTalentsApiDoc; +import com.provedcode.util.annotations.doc.controller.talent.GetTalentApiDoc; +import com.provedcode.util.annotations.doc.controller.talent.PatchEditTalentApiDoc; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; @@ -33,21 +31,7 @@ public class TalentController { TalentService talentService; TalentMapper talentMapper; - @Operation(summary = "Get all talents (ShortTalentDTO)", - description = "As a guest I want to see a page with a list of all “talents” cards displayed with a short description about them") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = Page.class, subTypes = {ShortTalentDTO.class}))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD_REQUEST (parameter: page or size are incorrect)", - content = @Content) - }) + @GetAllTalentsApiDoc @GetMapping("/talents") @ResponseStatus(HttpStatus.OK) Page getTalents(@RequestParam(value = "page") Optional page, @@ -55,21 +39,7 @@ Page getTalents(@RequestParam(value = "page") Optional return talentService.getTalentsPage(page, size).map(talentMapper::talentToShortTalentDTO); } - @Operation(summary = "Get talent", - description = "As a talent I want to have an opportunity to see the full information about the talent") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = FullTalentDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - }) + @GetTalentApiDoc @PreAuthorize("hasRole('TALENT')") @GetMapping("/talents/{id}") FullTalentDTO getTalent(@PathVariable("id") long id, Authentication authentication) { @@ -78,29 +48,7 @@ FullTalentDTO getTalent(@PathVariable("id") long id, Authentication authenticati return talentMapper.talentToFullTalentDTO(talentService.getTalentById(id)); } - @Operation(summary = "Edit information about talent", - description = "As a talent I want to have an opportunity to edit my personal profile by adding new information, changing already existing information") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = FullTalentDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to change the talent)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST", - content = @Content) - }) + @PatchEditTalentApiDoc @PreAuthorize("hasRole('TALENT')") @PatchMapping("/talents/{talent-id}") FullTalentDTO editTalent(@PathVariable("talent-id") long id, @@ -109,28 +57,7 @@ FullTalentDTO editTalent(@PathVariable("talent-id") long id, return talentMapper.talentToFullTalentDTO(talentService.editTalent(id, editTalent, authentication)); } - @Operation(summary = "Delete talent", - description = "As a talent I want to have an opportunity to delete personal accounts") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content), - @ApiResponse(responseCode = "404", - description = "NOT FOUND ", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to delete the talent)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST (incorrect id)", - content = @Content) - }) + @DeleteTalentApiDoc @PreAuthorize("hasRole('TALENT')") @DeleteMapping("/talents/{id}") SessionInfoDTO deleteTalent(@PathVariable("id") long id, Authentication authentication) { diff --git a/src/main/java/com/provedcode/talent/controller/TalentProofController.java b/src/main/java/com/provedcode/talent/controller/TalentProofController.java index 7cff2be..7c5500f 100644 --- a/src/main/java/com/provedcode/talent/controller/TalentProofController.java +++ b/src/main/java/com/provedcode/talent/controller/TalentProofController.java @@ -6,16 +6,10 @@ import com.provedcode.talent.model.dto.StatusDTO; import com.provedcode.talent.model.request.AddProof; import com.provedcode.talent.service.TalentProofService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.headers.Header; -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.responses.ApiResponses; +import com.provedcode.util.annotations.doc.controller.proof.*; import jakarta.validation.Valid; import lombok.AllArgsConstructor; import org.springframework.data.domain.Page; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; @@ -30,21 +24,7 @@ public class TalentProofController { TalentProofService talentProofService; TalentProofMapper talentProofMapper; - @Operation(summary = "Get all proofs", - description = "As a guest I want to see a list of all proofs displayed anonymously") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = Page.class, subTypes = {ProofDTO.class}))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST, parameter: page, size or order-by are incorrect", - content = @Content) - }) + @GetAllProofsApiDoc @GetMapping("/proofs") Page getAllProofs(@RequestParam(value = "page") Optional page, @RequestParam(value = "size") Optional size, @@ -53,24 +33,7 @@ Page getAllProofs(@RequestParam(value = "page") Optional page return talentProofService.getAllProofsPage(page, size, orderBy, sortBy).map(talentProofMapper::toProofDTO); } - @Operation(summary = "Get proof") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ProofDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST, parameter: page, proof-id or size are incorrect", - content = @Content) - }) + @GetTalentProofByProofIdApiDoc @GetMapping("/proofs/{proof-id}") @PreAuthorize("hasRole('TALENT')") ProofDTO getTalentProof(@PathVariable(value = "proof-id") long proofId, @@ -78,25 +41,7 @@ ProofDTO getTalentProof(@PathVariable(value = "proof-id") long proofId, return talentProofMapper.toProofDTO(talentProofService.getTalentProof(proofId, authentication)); } - @Operation(summary = "Get all talent proofs", - description = "As a talent I want to see all proofs in personal profile page") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = FullProofDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST, wrong @RequestParam like page, size, order-by, sort-by or incorrect talent-id", - content = @Content) - }) + @GetTalentInformationWithProofsApiDoc @GetMapping("/{talent-id}/proofs") @PreAuthorize("hasRole('TALENT')") FullProofDTO getTalentInformationWithProofs(Authentication authentication, @@ -108,33 +53,7 @@ FullProofDTO getTalentInformationWithProofs(Authentication authentication, return talentProofService.getTalentProofs(talentId, page, size, orderBy, authentication, sortBy); } - @Operation(summary = "Add proof", - description = "As a talent I want to have an opportunity to add my personal proof") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ProofDTO.class)), - headers = {@Header(name = "Location", - description = "The URI of the created proof", - schema = @Schema(type = "string"))} - ), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST, (wrong data to add or incorrect talent-id)", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to add the proof)", - content = @Content) - }) + @PostAddProofApiDoc @PostMapping("/{talent-id}/proofs") @PreAuthorize("hasRole('TALENT')") ResponseEntity addProof(@PathVariable(value = "talent-id") long talentId, @@ -143,29 +62,7 @@ ResponseEntity addProof(@PathVariable(value = "talent-id") long talentId, return talentProofService.addProof(addProof, talentId, authentication); } - @Operation(summary = "Edit information about proof", - description = "As a talent I want to have an opportunity to edit my personal proofs") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ProofDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "Unauthorized", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD REQUEST, (wrong data to edit or incorrect talent-id, proof-id)", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to edit the proof)", - content = @Content) - }) + @PatchEditProofApiDoc @PatchMapping("/{talent-id}/proofs/{proof-id}") @PreAuthorize("hasRole('TALENT')") ProofDTO editProof(Authentication authentication, @@ -176,30 +73,7 @@ ProofDTO editProof(Authentication authentication, talentProofService.editTalentProof(talentId, proofId, proof, authentication)); } - @Operation(summary = "Delete proof", - description = "As a talent I want to have an opportunity to delete my personal proofs") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = StatusDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT FOUND", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD_REQUEST, (incorrect talent-id,proof-id)", - content = @Content), - @ApiResponse( - responseCode = "403", - description = "FORBIDDEN (if not the owner wants to delete the proof or " + - "impossible change proofs status from DRAFT to HIDDEN, it should be PUBLISHED)", - content = @Content) - }) + @DeleteProofApiDoc @DeleteMapping("/{talent-id}/proofs/{proof-id}") @PreAuthorize("hasRole('TALENT')") StatusDTO deleteProof(@PathVariable(value = "talent-id") long talentId, diff --git a/src/main/java/com/provedcode/talent/model/dto/FullTalentDTO.java b/src/main/java/com/provedcode/talent/model/dto/FullTalentDTO.java index 10d8885..b67b317 100644 --- a/src/main/java/com/provedcode/talent/model/dto/FullTalentDTO.java +++ b/src/main/java/com/provedcode/talent/model/dto/FullTalentDTO.java @@ -1,7 +1,7 @@ package com.provedcode.talent.model.dto; import com.fasterxml.jackson.annotation.JsonProperty; -import com.provedcode.annotations.UrlList; +import com.provedcode.util.annotations.UrlList; import jakarta.validation.constraints.NotEmpty; import lombok.Builder; diff --git a/src/main/java/com/provedcode/talent/model/request/EditTalent.java b/src/main/java/com/provedcode/talent/model/request/EditTalent.java index 1014536..cc3dbc1 100644 --- a/src/main/java/com/provedcode/talent/model/request/EditTalent.java +++ b/src/main/java/com/provedcode/talent/model/request/EditTalent.java @@ -1,8 +1,7 @@ package com.provedcode.talent.model.request; import com.fasterxml.jackson.annotation.JsonProperty; -import com.provedcode.annotations.UrlList; -import jakarta.validation.constraints.NotEmpty; +import com.provedcode.util.annotations.UrlList; import lombok.Builder; import java.util.List; diff --git a/src/main/java/com/provedcode/user/controller/AuthenticationController.java b/src/main/java/com/provedcode/user/controller/AuthenticationController.java index 69559c6..b30ee13 100644 --- a/src/main/java/com/provedcode/user/controller/AuthenticationController.java +++ b/src/main/java/com/provedcode/user/controller/AuthenticationController.java @@ -4,16 +4,13 @@ import com.provedcode.user.model.dto.TalentRegistrationDTO; import com.provedcode.user.model.dto.UserInfoDTO; import com.provedcode.user.service.AuthenticationService; -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.responses.ApiResponses; +import com.provedcode.util.annotations.doc.controller.user.PostSponsorRegistrationApiDoc; +import com.provedcode.util.annotations.doc.controller.user.PostTalentRegistrationApiDoc; +import com.provedcode.util.annotations.doc.controller.user.PostUserLoginApiDoc; import jakarta.validation.Valid; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; @@ -24,63 +21,20 @@ public class AuthenticationController { AuthenticationService authenticationService; - @Operation(summary = "Login") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", - description = "SUCCESS", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = UserInfoDTO.class))), - @ApiResponse(responseCode = "404", - description = "NOT_FOUND (Talent not registered)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD_REQUEST", - content = @Content), - @ApiResponse( - responseCode = "401", - description = "UNAUTHORIZED", - content = @Content) - }) + @PostUserLoginApiDoc @PostMapping("/v2/login") UserInfoDTO login(Authentication authentication) { return authenticationService.login(authentication.getName(), authentication.getAuthorities()); } - @Operation(summary = "Talent Registration") - @ApiResponses(value = { - @ApiResponse(responseCode = "201", - description = "CREATED", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = UserInfoDTO.class))), - @ApiResponse(responseCode = "409", - description = "CONFLICT (user with login already exists)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD_REQUEST", - content = @Content), - }) + @PostTalentRegistrationApiDoc @PostMapping("/v2/talents/register") @ResponseStatus(HttpStatus.CREATED) UserInfoDTO register(@RequestBody @Valid TalentRegistrationDTO user) { return authenticationService.register(user); } - @Operation(summary = "Sponsor Registration") - @ApiResponses(value = { - @ApiResponse(responseCode = "201", - description = "CREATED", - content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = UserInfoDTO.class))), - @ApiResponse(responseCode = "409", - description = "CONFLICT (user with login already exists)", - content = @Content), - @ApiResponse( - responseCode = "400", - description = "BAD_REQUEST", - content = @Content), - }) + @PostSponsorRegistrationApiDoc @PostMapping("/v3/sponsors/register") @ResponseStatus(HttpStatus.CREATED) UserInfoDTO register(@RequestBody @Valid SponsorRegistrationDTO user) { diff --git a/src/main/java/com/provedcode/annotations/UrlList.java b/src/main/java/com/provedcode/util/annotations/UrlList.java similarity index 84% rename from src/main/java/com/provedcode/annotations/UrlList.java rename to src/main/java/com/provedcode/util/annotations/UrlList.java index 6a792bc..1530ae9 100644 --- a/src/main/java/com/provedcode/annotations/UrlList.java +++ b/src/main/java/com/provedcode/util/annotations/UrlList.java @@ -1,6 +1,6 @@ -package com.provedcode.annotations; +package com.provedcode.util.annotations; -import com.provedcode.annotations.impl.UrlListValidator; +import com.provedcode.util.annotations.impl.UrlListValidator; import jakarta.validation.Constraint; import jakarta.validation.Payload; diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetAmountOfKudosApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetAmountOfKudosApiDoc.java new file mode 100644 index 0000000..9ea3669 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetAmountOfKudosApiDoc.java @@ -0,0 +1,42 @@ +package com.provedcode.util.annotations.doc.controller.kudos; + +import com.provedcode.kudos.model.response.KudosAmountWithSponsor; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Amount of “kudos” given by sponsors and who gave the “kudos” on proof") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = KudosAmountWithSponsor.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the talent wants to see)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content) +}) +public @interface GetAmountOfKudosApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetKudosForSponsorApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetKudosForSponsorApiDoc.java new file mode 100644 index 0000000..2798f09 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/GetKudosForSponsorApiDoc.java @@ -0,0 +1,42 @@ +package com.provedcode.util.annotations.doc.controller.kudos; + + +import com.provedcode.kudos.model.response.KudosAmount; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get all available kudos from a sponsor") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = KudosAmount.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to see other sponsor kudos)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content) +}) +public @interface GetKudosForSponsorApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/PostAddKudosToProofApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/PostAddKudosToProofApiDoc.java new file mode 100644 index 0000000..77d5ed6 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/kudos/PostAddKudosToProofApiDoc.java @@ -0,0 +1,37 @@ +package com.provedcode.util.annotations.doc.controller.kudos; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "As a sponsor I want to estimate talent proof by giving kudos") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if sponsor does not have enough kudos)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content) +}) +public @interface PostAddKudosToProofApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/proof/DeleteProofApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/DeleteProofApiDoc.java new file mode 100644 index 0000000..5f77466 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/DeleteProofApiDoc.java @@ -0,0 +1,43 @@ +package com.provedcode.util.annotations.doc.controller.proof; + +import com.provedcode.talent.model.dto.StatusDTO; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Delete proof", + description = "As a talent I want to have an opportunity to delete my personal proofs") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = StatusDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD_REQUEST, (incorrect talent-id,proof-id)", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to delete the proof or " + + "impossible change proofs status from DRAFT to HIDDEN, it should be PUBLISHED)", + content = @Content) +}) +public @interface DeleteProofApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetAllProofsApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetAllProofsApiDoc.java new file mode 100644 index 0000000..514600d --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetAllProofsApiDoc.java @@ -0,0 +1,35 @@ +package com.provedcode.util.annotations.doc.controller.proof; + +import com.provedcode.talent.model.dto.ProofDTO; +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.responses.ApiResponses; +import org.springframework.data.domain.Page; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get all proofs", + description = "As a guest I want to see a list of all proofs displayed anonymously") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = Page.class, subTypes = {ProofDTO.class}))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST, parameter: page, size or order-by are incorrect", + content = @Content) +}) +public @interface GetAllProofsApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentInformationWithProofsApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentInformationWithProofsApiDoc.java new file mode 100644 index 0000000..1d6a200 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentInformationWithProofsApiDoc.java @@ -0,0 +1,38 @@ +package com.provedcode.util.annotations.doc.controller.proof; + +import com.provedcode.talent.model.dto.FullProofDTO; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get all talent proofs", + description = "As a talent I want to see all proofs in personal profile page") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = FullProofDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST, wrong @RequestParam like page, size, order-by, sort-by or incorrect talent-id", + content = @Content) +}) +public @interface GetTalentInformationWithProofsApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentProofByProofIdApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentProofByProofIdApiDoc.java new file mode 100644 index 0000000..89ef17d --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/GetTalentProofByProofIdApiDoc.java @@ -0,0 +1,37 @@ +package com.provedcode.util.annotations.doc.controller.proof; + +import com.provedcode.talent.model.dto.ProofDTO; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get proof") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = ProofDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST, parameter: page, proof-id or size are incorrect", + content = @Content) +}) +public @interface GetTalentProofByProofIdApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/proof/PatchEditProofApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/PatchEditProofApiDoc.java new file mode 100644 index 0000000..9dca387 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/PatchEditProofApiDoc.java @@ -0,0 +1,42 @@ +package com.provedcode.util.annotations.doc.controller.proof; + +import com.provedcode.talent.model.dto.ProofDTO; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Edit information about proof", + description = "As a talent I want to have an opportunity to edit my personal proofs") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = ProofDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST, (wrong data to edit or incorrect talent-id, proof-id)", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to edit the proof)", + content = @Content) +}) +public @interface PatchEditProofApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/proof/PostAddProofApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/PostAddProofApiDoc.java new file mode 100644 index 0000000..13fe563 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/proof/PostAddProofApiDoc.java @@ -0,0 +1,48 @@ +package com.provedcode.util.annotations.doc.controller.proof; + +import com.provedcode.talent.model.dto.ProofDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.headers.Header; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Add proof", + description = "As a talent I want to have an opportunity to add my personal proof") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = ProofDTO.class)), + headers = {@Header(name = "Location", + description = "The URI of the created proof", + schema = @Schema(type = "string"))} + ), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "Unauthorized", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST, (wrong data to add or incorrect talent-id)", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to add the proof)", + content = @Content) +}) +public @interface PostAddProofApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/DeleteSponsorApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/DeleteSponsorApiDoc.java new file mode 100644 index 0000000..17968c1 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/DeleteSponsorApiDoc.java @@ -0,0 +1,42 @@ +package com.provedcode.util.annotations.doc.controller.sponsor; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Delete sponsor", + description = "As a sponsor I want to have an opportunity to delete personal accounts.") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content), + @ApiResponse(responseCode = "404", + description = "NOT FOUND ", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to delete the talent)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST (incorrect id)", + content = @Content), + @ApiResponse( + responseCode = "501", + description = "NOT_IMPLEMENTED (login is not valid)", + content = @Content), +}) +public @interface DeleteSponsorApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetAllSponsorsApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetAllSponsorsApiDoc.java new file mode 100644 index 0000000..5423fac --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetAllSponsorsApiDoc.java @@ -0,0 +1,31 @@ +package com.provedcode.util.annotations.doc.controller.sponsor; + +import com.provedcode.sponsor.model.dto.SponsorDTO; +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.responses.ApiResponses; +import org.springframework.data.domain.Page; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get all sponsors (SponsorDTO)") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = Page.class, subTypes = {SponsorDTO.class}))), + @ApiResponse( + responseCode = "400", + description = "BAD_REQUEST (parameter: page or size are incorrect)", + content = @Content) +}) +public @interface GetAllSponsorsApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetSponsorApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetSponsorApiDoc.java new file mode 100644 index 0000000..c194749 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/GetSponsorApiDoc.java @@ -0,0 +1,38 @@ +package com.provedcode.util.annotations.doc.controller.sponsor; + +import com.provedcode.sponsor.model.dto.SponsorDTO; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get sponsor", + description = "As a sponsor I want to have an opportunity to see my own profile with information") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = SponsorDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "501", + description = "NOT_IMPLEMENTED (login is not valid)", + content = @Content) +}) +public @interface GetSponsorApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/PatchEditSponsorApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/PatchEditSponsorApiDoc.java new file mode 100644 index 0000000..dd5b45f --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/sponsor/PatchEditSponsorApiDoc.java @@ -0,0 +1,47 @@ +package com.provedcode.util.annotations.doc.controller.sponsor; + +import com.provedcode.sponsor.model.dto.SponsorDTO; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Edit information about sponsor", + description = "As a sponsor I want to have an opportunity to edit my personal profile by adding new information, " + + "changing already existing information.") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = SponsorDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to change the sponsor)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content), + @ApiResponse( + responseCode = "501", + description = "NOT_IMPLEMENTED (login is not valid)", + content = @Content) +}) +public @interface PatchEditSponsorApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/talent/DeleteTalentApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/DeleteTalentApiDoc.java new file mode 100644 index 0000000..6f0fd00 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/DeleteTalentApiDoc.java @@ -0,0 +1,38 @@ +package com.provedcode.util.annotations.doc.controller.talent; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Delete talent", + description = "As a talent I want to have an opportunity to delete personal accounts") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content), + @ApiResponse(responseCode = "404", + description = "NOT FOUND ", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to delete the talent)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST (incorrect id)", + content = @Content) +}) +public @interface DeleteTalentApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetAllTalentsApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetAllTalentsApiDoc.java new file mode 100644 index 0000000..e5eea66 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetAllTalentsApiDoc.java @@ -0,0 +1,35 @@ +package com.provedcode.util.annotations.doc.controller.talent; + +import com.provedcode.talent.model.dto.ShortTalentDTO; +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.responses.ApiResponses; +import org.springframework.data.domain.Page; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get all talents (ShortTalentDTO)", + description = "As a guest I want to see a page with a list of all “talents” cards displayed with a short description about them") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = Page.class, subTypes = {ShortTalentDTO.class}))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD_REQUEST (parameter: page or size are incorrect)", + content = @Content) +}) +public @interface GetAllTalentsApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetTalentApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetTalentApiDoc.java new file mode 100644 index 0000000..50b42e4 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/GetTalentApiDoc.java @@ -0,0 +1,34 @@ +package com.provedcode.util.annotations.doc.controller.talent; + +import com.provedcode.talent.model.dto.FullTalentDTO; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Get talent", + description = "As a talent I want to have an opportunity to see the full information about the talent") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = FullTalentDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), +}) +public @interface GetTalentApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/talent/PatchEditTalentApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/PatchEditTalentApiDoc.java new file mode 100644 index 0000000..565688e --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/talent/PatchEditTalentApiDoc.java @@ -0,0 +1,42 @@ +package com.provedcode.util.annotations.doc.controller.talent; + +import com.provedcode.talent.model.dto.FullTalentDTO; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Edit information about talent", + description = "As a talent I want to have an opportunity to edit my personal profile by adding new information, changing already existing information") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = FullTalentDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN (if not the owner wants to change the talent)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content) +}) +public @interface PatchEditTalentApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostSponsorRegistrationApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostSponsorRegistrationApiDoc.java new file mode 100644 index 0000000..608da55 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostSponsorRegistrationApiDoc.java @@ -0,0 +1,33 @@ +package com.provedcode.util.annotations.doc.controller.user; + +import com.provedcode.user.model.dto.UserInfoDTO; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Sponsor Registration") +@ApiResponses(value = { + @ApiResponse(responseCode = "201", + description = "CREATED", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = UserInfoDTO.class))), + @ApiResponse(responseCode = "409", + description = "CONFLICT (user with login already exists)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD_REQUEST", + content = @Content), +}) +public @interface PostSponsorRegistrationApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostTalentRegistrationApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostTalentRegistrationApiDoc.java new file mode 100644 index 0000000..1ed2517 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostTalentRegistrationApiDoc.java @@ -0,0 +1,33 @@ +package com.provedcode.util.annotations.doc.controller.user; + +import com.provedcode.user.model.dto.UserInfoDTO; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Talent Registration") +@ApiResponses(value = { + @ApiResponse(responseCode = "201", + description = "CREATED", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = UserInfoDTO.class))), + @ApiResponse(responseCode = "409", + description = "CONFLICT (user with login already exists)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD_REQUEST", + content = @Content), +}) +public @interface PostTalentRegistrationApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostUserLoginApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostUserLoginApiDoc.java new file mode 100644 index 0000000..7948e5c --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/user/PostUserLoginApiDoc.java @@ -0,0 +1,37 @@ +package com.provedcode.util.annotations.doc.controller.user; + +import com.provedcode.user.model.dto.UserInfoDTO; +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.responses.ApiResponses; +import org.springframework.http.MediaType; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Login") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS", + content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, + schema = @Schema(implementation = UserInfoDTO.class))), + @ApiResponse(responseCode = "404", + description = "NOT_FOUND (Talent not registered)", + content = @Content), + @ApiResponse( + responseCode = "400", + description = "BAD_REQUEST", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content) +}) +public @interface PostUserLoginApiDoc { +} diff --git a/src/main/java/com/provedcode/annotations/impl/UrlListValidator.java b/src/main/java/com/provedcode/util/annotations/impl/UrlListValidator.java similarity index 88% rename from src/main/java/com/provedcode/annotations/impl/UrlListValidator.java rename to src/main/java/com/provedcode/util/annotations/impl/UrlListValidator.java index ac473d7..b06a1ac 100644 --- a/src/main/java/com/provedcode/annotations/impl/UrlListValidator.java +++ b/src/main/java/com/provedcode/util/annotations/impl/UrlListValidator.java @@ -1,6 +1,6 @@ -package com.provedcode.annotations.impl; +package com.provedcode.util.annotations.impl; -import com.provedcode.annotations.UrlList; +import com.provedcode.util.annotations.UrlList; import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; From 631829bb2cf8593acf97cabdbe33556332be20d9 Mon Sep 17 00:00:00 2001 From: Denis Boyko Date: Wed, 26 Apr 2023 22:25:30 +0300 Subject: [PATCH 06/15] bug fix --- .../com/provedcode/talent/service/TalentProofService.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/com/provedcode/talent/service/TalentProofService.java b/src/main/java/com/provedcode/talent/service/TalentProofService.java index e4783b4..a411d28 100644 --- a/src/main/java/com/provedcode/talent/service/TalentProofService.java +++ b/src/main/java/com/provedcode/talent/service/TalentProofService.java @@ -29,7 +29,6 @@ import java.net.URI; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.List; import java.util.Optional; import static org.springframework.http.HttpStatus.*; @@ -193,9 +192,6 @@ public TalentProof editTalentProof(long talentId, long proofId, ProofDTO proof, if (proof.link() == null && proof.text() == null) { oldProof.setStatus(proof.status()); } else { - if (oldProofStatus != ProofStatus.DRAFT) - throw new ResponseStatusException(FORBIDDEN, "you cannot edit proofs without DRAFT status"); - oldProof.setLink(proof.link() != null ? proof.link() : oldProof.getLink()) .setText(proof.text() != null ? proof.text() : oldProof.getText()) .setStatus(proof.status()); From 80973351b59ab5278b31bd99b61fc3f2d9189280 Mon Sep 17 00:00:00 2001 From: Maslyna Date: Fri, 28 Apr 2023 17:56:11 +0200 Subject: [PATCH 07/15] aws update --- .../aws/controller/AWSS3BucketController.java | 8 +++++++ .../com/provedcode/aws/service/S3Service.java | 23 ++++++++++++------- .../talent/model/entity/Talent.java | 3 +++ .../db/changelog/changeset/V2/schema-V2.sql | 1 + 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java index 64141d0..54251d3 100644 --- a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java +++ b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java @@ -7,6 +7,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import java.util.Arrays; import java.util.List; @RestController @@ -27,4 +28,11 @@ public void setNewUserImage(@RequestParam("file") MultipartFile file, List getAllFiles() { return fileService.listAllFiles(); } + + @PreAuthorize("hasRole('TALENT')") + @PostMapping("/aws/test") + String testTypeOfFile(@RequestParam("file") MultipartFile file, + Authentication authentication) { + return Arrays.stream(file.getContentType().split("/")).toList().get(1) + " " + file.getOriginalFilename() + " " + file.getName() + " " + file.getResource(); + } } diff --git a/src/main/java/com/provedcode/aws/service/S3Service.java b/src/main/java/com/provedcode/aws/service/S3Service.java index 679c443..39603e8 100644 --- a/src/main/java/com/provedcode/aws/service/S3Service.java +++ b/src/main/java/com/provedcode/aws/service/S3Service.java @@ -18,11 +18,11 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.util.Arrays; import java.util.List; import static org.apache.http.entity.ContentType.*; -import static org.springframework.http.HttpStatus.NOT_FOUND; -import static org.springframework.http.HttpStatus.NOT_IMPLEMENTED; +import static org.springframework.http.HttpStatus.*; @Service @AllArgsConstructor @@ -79,21 +79,28 @@ public void setNewUserImage(MultipartFile file, Authentication authentication) { UserInfo user = userInfoRepository.findByLogin(authentication.getName()) .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "user with login = {%s} not found".formatted(authentication.getName()))); - String fileName = file.getOriginalFilename(); - - String userLogin = authentication.getName(); - String fullPath = "%s/%s".formatted(userLogin, fileName); try { + String fileType = file.getContentType().split("/")[1]; + String userLogin = authentication.getName(); + + String fullPath = "%s/%s".formatted(userLogin, "image.%s".formatted(fileType)); File f = convertMultiPartToFile(file); + if (user.getTalent().getImageName() != null) + s3.deleteObject(awsProperties.bucket(), user.getTalent().getImageName()); + s3.putObject(awsProperties.bucket(), fullPath, f); log.info("image = {}", s3.getUrl(awsProperties.bucket(), fullPath).toString()); + user.getTalent().setImage(s3.getUrl(awsProperties.bucket(), fullPath).toString()); + user.getTalent().setImageName(fullPath); + talentRepository.save(user.getTalent()); - } catch (RuntimeException | IOException e) { - throw new ResponseStatusException(NOT_IMPLEMENTED); + } catch (Exception e) { + throw new ResponseStatusException(BAD_REQUEST); } + } private File convertMultiPartToFile(MultipartFile file) diff --git a/src/main/java/com/provedcode/talent/model/entity/Talent.java b/src/main/java/com/provedcode/talent/model/entity/Talent.java index 331ad63..9e65c3a 100644 --- a/src/main/java/com/provedcode/talent/model/entity/Talent.java +++ b/src/main/java/com/provedcode/talent/model/entity/Talent.java @@ -35,6 +35,9 @@ public class Talent { @URL @Column(name = "image", length = 300) private String image; + @Column(name = "image_name", length = 100) + private String imageName; + @OneToOne(mappedBy = "talent", cascade = CascadeType.ALL, orphanRemoval = true) private TalentDescription talentDescription; @OneToMany(mappedBy = "talent", cascade = CascadeType.ALL, orphanRemoval = true) diff --git a/src/main/resources/db/changelog/changeset/V2/schema-V2.sql b/src/main/resources/db/changelog/changeset/V2/schema-V2.sql index 2519646..ebd940a 100644 --- a/src/main/resources/db/changelog/changeset/V2/schema-V2.sql +++ b/src/main/resources/db/changelog/changeset/V2/schema-V2.sql @@ -17,6 +17,7 @@ CREATE TABLE talent last_name VARCHAR(20), specialization VARCHAR(30), image VARCHAR(300), + image_name VARCHAR(100), CONSTRAINT pk_talent PRIMARY KEY (id) ); CREATE TABLE talent_attached_file From 841014846d518488ed78d814d4665d922a49c13a Mon Sep 17 00:00:00 2001 From: Maslyna Date: Sat, 29 Apr 2023 03:00:33 +0200 Subject: [PATCH 08/15] Created PhotoService --- .../aws/controller/AWSS3BucketController.java | 2 +- .../com/provedcode/aws/service/S3Service.java | 6 ++- .../com/provedcode/util/PhotoService.java | 50 +++++++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/provedcode/util/PhotoService.java diff --git a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java index 54251d3..ae9ac4b 100644 --- a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java +++ b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java @@ -19,7 +19,7 @@ public class AWSS3BucketController { @PreAuthorize("hasRole('TALENT')") @PostMapping("/image/upload") public void setNewUserImage(@RequestParam("file") MultipartFile file, - Authentication authentication) { + Authentication authentication) { fileService.setNewUserImage(file, authentication); } diff --git a/src/main/java/com/provedcode/aws/service/S3Service.java b/src/main/java/com/provedcode/aws/service/S3Service.java index 39603e8..1b1f80c 100644 --- a/src/main/java/com/provedcode/aws/service/S3Service.java +++ b/src/main/java/com/provedcode/aws/service/S3Service.java @@ -8,6 +8,7 @@ import com.provedcode.talent.repo.TalentRepository; import com.provedcode.user.model.entity.UserInfo; import com.provedcode.user.repo.UserInfoRepository; +import com.provedcode.util.PhotoService; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; @@ -32,6 +33,7 @@ public class S3Service implements FileService { AmazonS3 s3; UserInfoRepository userInfoRepository; TalentRepository talentRepository; + PhotoService photoService; @Override public String saveFile(MultipartFile file) { @@ -73,7 +75,7 @@ public void setNewUserImage(MultipartFile file, Authentication authentication) { if (file.isEmpty()) { throw new ResponseStatusException(NOT_IMPLEMENTED, "file must be not empty, actual file-size: %s".formatted(file.getSize())); } - if (!List.of(IMAGE_JPEG.getMimeType(), IMAGE_PNG.getMimeType(), IMAGE_GIF.getMimeType()).contains(file.getContentType())) { + if (photoService.isFileImage(file)) { throw new ResponseStatusException(NOT_IMPLEMENTED, "not supported type: %s".formatted(file.getContentType())); } UserInfo user = userInfoRepository.findByLogin(authentication.getName()) @@ -84,7 +86,7 @@ public void setNewUserImage(MultipartFile file, Authentication authentication) { String userLogin = authentication.getName(); String fullPath = "%s/%s".formatted(userLogin, "image.%s".formatted(fileType)); - File f = convertMultiPartToFile(file); + File f = photoService.degradePhoto(convertMultiPartToFile(file)); if (user.getTalent().getImageName() != null) s3.deleteObject(awsProperties.bucket(), user.getTalent().getImageName()); diff --git a/src/main/java/com/provedcode/util/PhotoService.java b/src/main/java/com/provedcode/util/PhotoService.java new file mode 100644 index 0000000..9ea1a09 --- /dev/null +++ b/src/main/java/com/provedcode/util/PhotoService.java @@ -0,0 +1,50 @@ +package com.provedcode.util; + +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.awt.image.BufferedImage; +import java.awt.Image; +import java.util.List; +import javax.imageio.ImageIO; + +import static org.apache.http.entity.ContentType.*; + + +@Service +@AllArgsConstructor +public class PhotoService { + + public File degradePhoto(File photoFile) throws IOException { + // загружаем изображение из файла + BufferedImage originalImage = ImageIO.read(photoFile); + + // устанавливаем новый размер для изображения + int newWidth = 300; + int newHeight = 300; + + // создаем новое изображение с новым размером + Image resizedImage = originalImage.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH); + + // создаем новый файл для уменьшенного изображения + String fileName = photoFile.getName(); + String fileType = fileName.substring(fileName.lastIndexOf('.') + 1); + File newFile = new File(photoFile.getParent(), fileName); + + // записываем уменьшенное изображение в новый файл + BufferedImage outputImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB); + outputImage.createGraphics().drawImage(resizedImage, 0, 0, null); + ImageIO.write(outputImage, fileType, newFile); + + // возвращаем новый файл + return newFile; + } + + public boolean isFileImage(MultipartFile file) { + return !List.of(IMAGE_JPEG.getMimeType(), IMAGE_PNG.getMimeType(), IMAGE_GIF.getMimeType()).contains(file.getContentType()); + } + +} From 1e9560edaaa8e1f5246ae7d267565d16f0200744 Mon Sep 17 00:00:00 2001 From: Maslyna Date: Sat, 29 Apr 2023 03:10:55 +0200 Subject: [PATCH 09/15] minore update --- src/main/java/com/provedcode/aws/service/S3Service.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/provedcode/aws/service/S3Service.java b/src/main/java/com/provedcode/aws/service/S3Service.java index 1b1f80c..b7d48b1 100644 --- a/src/main/java/com/provedcode/aws/service/S3Service.java +++ b/src/main/java/com/provedcode/aws/service/S3Service.java @@ -100,7 +100,7 @@ public void setNewUserImage(MultipartFile file, Authentication authentication) { talentRepository.save(user.getTalent()); } catch (Exception e) { - throw new ResponseStatusException(BAD_REQUEST); + throw new ResponseStatusException(NOT_IMPLEMENTED, "problems with connection to aws s3"); } } From 44b3666a23c6ffe82c63ded2b6f520bfc683775c Mon Sep 17 00:00:00 2001 From: Ren Date: Sat, 29 Apr 2023 21:02:49 +0300 Subject: [PATCH 10/15] refactored and optimized code --- .../aws/controller/AWSS3BucketController.java | 3 +- .../provedcode/aws/service/FileService.java | 3 + .../com/provedcode/aws/service/S3Service.java | 16 +- .../handlers/TalentExceptionHandler.java | 55 +++--- .../kudos/controller/KudosController.java | 34 ++-- .../provedcode/kudos/model/entity/Kudos.java | 4 +- .../kudos/model/request/SetAmountKudos.java | 9 + .../kudos/repository/KudosRepository.java | 6 +- .../kudos/service/KudosService.java | 113 +++++++----- .../sponsor/controller/SponsorController.java | 17 +- .../EditSponsor.java} | 4 +- .../sponsor/service/SponsorService.java | 90 +++++----- .../utill/ValidateSponsorForCompliance.java | 24 +++ .../talent/controller/TalentController.java | 12 +- .../controller/TalentProofController.java | 28 ++- .../talent/service/TalentProofService.java | 83 +++------ .../talent/service/TalentService.java | 147 +++++++++++++++- .../service/impl/TalentServiceImpl.java | 163 ------------------ .../user/util/UserInfoValidator.java | 24 +++ .../com/provedcode/util/PhotoService.java | 11 +- .../db/changelog/changeset/V2/data-V2.sql | 10 +- .../db/changelog/changeset/V2/schema-V2.sql | 2 +- 22 files changed, 443 insertions(+), 415 deletions(-) create mode 100644 src/main/java/com/provedcode/kudos/model/request/SetAmountKudos.java rename src/main/java/com/provedcode/sponsor/model/{dto/SponsorEditDTO.java => request/EditSponsor.java} (81%) create mode 100644 src/main/java/com/provedcode/sponsor/utill/ValidateSponsorForCompliance.java delete mode 100644 src/main/java/com/provedcode/talent/service/impl/TalentServiceImpl.java create mode 100644 src/main/java/com/provedcode/user/util/UserInfoValidator.java diff --git a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java index ae9ac4b..0f09291 100644 --- a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java +++ b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java @@ -33,6 +33,7 @@ List getAllFiles() { @PostMapping("/aws/test") String testTypeOfFile(@RequestParam("file") MultipartFile file, Authentication authentication) { - return Arrays.stream(file.getContentType().split("/")).toList().get(1) + " " + file.getOriginalFilename() + " " + file.getName() + " " + file.getResource(); + return Arrays.stream(file.getContentType().split("/")).toList().get(1) + " " + file.getOriginalFilename() + + " " + file.getName() + " " + file.getResource(); } } diff --git a/src/main/java/com/provedcode/aws/service/FileService.java b/src/main/java/com/provedcode/aws/service/FileService.java index 78d722b..369898a 100644 --- a/src/main/java/com/provedcode/aws/service/FileService.java +++ b/src/main/java/com/provedcode/aws/service/FileService.java @@ -8,8 +8,11 @@ public interface FileService { String saveFile(MultipartFile file); + byte[] downloadFile(String filename); + String deleteFile(String filename); + List listAllFiles(); void setNewUserImage(MultipartFile file, Authentication authentication); diff --git a/src/main/java/com/provedcode/aws/service/S3Service.java b/src/main/java/com/provedcode/aws/service/S3Service.java index b7d48b1..3caa3ec 100644 --- a/src/main/java/com/provedcode/aws/service/S3Service.java +++ b/src/main/java/com/provedcode/aws/service/S3Service.java @@ -19,11 +19,10 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.util.Arrays; import java.util.List; -import static org.apache.http.entity.ContentType.*; -import static org.springframework.http.HttpStatus.*; +import static org.springframework.http.HttpStatus.NOT_FOUND; +import static org.springframework.http.HttpStatus.NOT_IMPLEMENTED; @Service @AllArgsConstructor @@ -73,13 +72,17 @@ public List listAllFiles() { @Override public void setNewUserImage(MultipartFile file, Authentication authentication) { if (file.isEmpty()) { - throw new ResponseStatusException(NOT_IMPLEMENTED, "file must be not empty, actual file-size: %s".formatted(file.getSize())); + throw new ResponseStatusException(NOT_IMPLEMENTED, + "file must be not empty, actual file-size: %s".formatted(file.getSize())); } if (photoService.isFileImage(file)) { - throw new ResponseStatusException(NOT_IMPLEMENTED, "not supported type: %s".formatted(file.getContentType())); + throw new ResponseStatusException(NOT_IMPLEMENTED, + "not supported type: %s".formatted(file.getContentType())); } UserInfo user = userInfoRepository.findByLogin(authentication.getName()) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "user with login = {%s} not found".formatted(authentication.getName()))); + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "user with login = {%s} not found".formatted( + authentication.getName()))); try { String fileType = file.getContentType().split("/")[1]; @@ -113,5 +116,4 @@ private File convertMultiPartToFile(MultipartFile file) fos.close(); return convFile; } - } \ No newline at end of file diff --git a/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java b/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java index b1a6e08..7da4cc8 100644 --- a/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java +++ b/src/main/java/com/provedcode/handlers/TalentExceptionHandler.java @@ -1,29 +1,34 @@ package com.provedcode.handlers; -import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.validation.FieldError; -import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.context.request.WebRequest; import org.springframework.web.server.ResponseStatusException; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; @ControllerAdvice public class TalentExceptionHandler { - @ExceptionHandler(ResponseStatusException.class) - private ResponseEntity responseStatusExceptionHandler(ResponseStatusException exception) { - return ResponseEntity.status(exception.getStatusCode()).body(exception.getBody()); + public static boolean ignoreSQLException(String sqlState) { + + if (sqlState == null) { + System.out.println("The SQL state is not defined!"); + return false; + } + + // X0Y32: Jar file already exists in schema + if (sqlState.equalsIgnoreCase("X0Y32")) + return true; + + // 42Y55: Table already exists in schema + if (sqlState.equalsIgnoreCase("42Y55")) + return true; + + return false; } @ExceptionHandler({SQLException.class}) @@ -34,10 +39,10 @@ public void printSQLException(SQLException ex) { e.printStackTrace(System.err); System.err.println("SQLState: " + - ((SQLException) e).getSQLState()); + ((SQLException) e).getSQLState()); System.err.println("Error Code: " + - ((SQLException) e).getErrorCode()); + ((SQLException) e).getErrorCode()); System.err.println("Message: " + e.getMessage()); @@ -51,22 +56,16 @@ public void printSQLException(SQLException ex) { } } - public static boolean ignoreSQLException(String sqlState) { - - if (sqlState == null) { - System.out.println("The SQL state is not defined!"); - return false; - } - - // X0Y32: Jar file already exists in schema - if (sqlState.equalsIgnoreCase("X0Y32")) - return true; - - // 42Y55: Table already exists in schema - if (sqlState.equalsIgnoreCase("42Y55")) - return true; + @ExceptionHandler(ResponseStatusException.class) + private ResponseEntity responseStatusExceptionHandler(ResponseStatusException exception) { + return ResponseEntity.status(exception.getStatusCode()).body(exception.getBody()); + } - return false; + @ExceptionHandler(ConstraintViolationException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + private ResponseEntity responseStatusExceptionHandler(ConstraintViolationException exception) { + ApiError apiError = new ApiError(HttpStatus.BAD_REQUEST, exception.getMessage(), exception.toString()); + return new ResponseEntity<>(apiError, new HttpHeaders(), apiError.getStatus()); } // @ExceptionHandler({ Exception.class }) diff --git a/src/main/java/com/provedcode/kudos/controller/KudosController.java b/src/main/java/com/provedcode/kudos/controller/KudosController.java index 6a3b6b8..7f18175 100644 --- a/src/main/java/com/provedcode/kudos/controller/KudosController.java +++ b/src/main/java/com/provedcode/kudos/controller/KudosController.java @@ -1,18 +1,24 @@ package com.provedcode.kudos.controller; +import com.provedcode.kudos.model.request.SetAmountKudos; +import com.provedcode.kudos.model.response.KudosAmount; import com.provedcode.kudos.model.response.KudosAmountWithSponsor; import com.provedcode.kudos.service.KudosService; -import com.provedcode.kudos.model.response.KudosAmount; import com.provedcode.util.annotations.doc.controller.kudos.GetAmountOfKudosApiDoc; import com.provedcode.util.annotations.doc.controller.kudos.GetKudosForSponsorApiDoc; import com.provedcode.util.annotations.doc.controller.kudos.PostAddKudosToProofApiDoc; +import jakarta.validation.Valid; import lombok.AllArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.Optional; + @RestController @AllArgsConstructor +@Validated @RequestMapping("/api/v3/") public class KudosController { KudosService kudosService; @@ -20,23 +26,23 @@ public class KudosController { @GetKudosForSponsorApiDoc @PreAuthorize("hasRole('SPONSOR')") @GetMapping("/sponsors/{sponsor-id}/kudos") - KudosAmount getKudosForSponsor(@PathVariable("sponsor-id") long id, Authentication authentication) { - return kudosService.getKudosForSponsor(id, authentication); - } - - @PostAddKudosToProofApiDoc - @PreAuthorize("hasRole('SPONSOR')") - @PostMapping("/proofs/{proof-id}/kudos/{amount}") - void addKudosToProof(@PathVariable("proof-id") long id, - @PathVariable("amount") Long amount, - Authentication authentication) { - kudosService.addKudosToProof(id, amount, authentication); + KudosAmount getKudosForSponsor(@PathVariable("sponsor-id") long sponsorId, Authentication authentication) { + return kudosService.getKudosForSponsor(sponsorId, authentication); } @GetAmountOfKudosApiDoc @PreAuthorize("hasRole('TALENT')") @GetMapping("/proofs/{proof-id}/kudos") - KudosAmountWithSponsor getProofKudos(@PathVariable("proof-id") long id, Authentication authentication) { - return kudosService.getProofKudos(id, authentication); + KudosAmountWithSponsor getProofKudos(@PathVariable("proof-id") long proofId, Authentication authentication) { + return kudosService.getProofKudos(proofId, authentication); + } + + @PostAddKudosToProofApiDoc + @PreAuthorize("hasRole('SPONSOR')") + @PostMapping("/proofs/{proof-id}/kudos") + void addKudosToProof(@PathVariable("proof-id") long proofId, + @RequestBody @Valid Optional amount, + Authentication authentication) { + kudosService.addKudosToProof(proofId, amount, authentication); } } \ No newline at end of file diff --git a/src/main/java/com/provedcode/kudos/model/entity/Kudos.java b/src/main/java/com/provedcode/kudos/model/entity/Kudos.java index 8cacb21..259c387 100644 --- a/src/main/java/com/provedcode/kudos/model/entity/Kudos.java +++ b/src/main/java/com/provedcode/kudos/model/entity/Kudos.java @@ -17,8 +17,8 @@ public class Kudos { @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Long id; - @Column(name = "amount_kudos") - private Long amountKudos; + @Column(name = "amount") + private Long amount; @ManyToOne @JoinColumn(name = "sponsor_id") private Sponsor sponsor; diff --git a/src/main/java/com/provedcode/kudos/model/request/SetAmountKudos.java b/src/main/java/com/provedcode/kudos/model/request/SetAmountKudos.java new file mode 100644 index 0000000..3d7bbd2 --- /dev/null +++ b/src/main/java/com/provedcode/kudos/model/request/SetAmountKudos.java @@ -0,0 +1,9 @@ +package com.provedcode.kudos.model.request; + +import jakarta.validation.constraints.PositiveOrZero; + +public record SetAmountKudos( + @PositiveOrZero + Long amount +) { +} \ No newline at end of file diff --git a/src/main/java/com/provedcode/kudos/repository/KudosRepository.java b/src/main/java/com/provedcode/kudos/repository/KudosRepository.java index 529129e..3b0f629 100644 --- a/src/main/java/com/provedcode/kudos/repository/KudosRepository.java +++ b/src/main/java/com/provedcode/kudos/repository/KudosRepository.java @@ -1,10 +1,10 @@ package com.provedcode.kudos.repository; import com.provedcode.kudos.model.entity.Kudos; -import com.provedcode.talent.model.entity.Talent; -import com.provedcode.talent.model.entity.TalentProof; import org.springframework.data.jpa.repository.JpaRepository; public interface KudosRepository extends JpaRepository { - long countByProof_Id(Long id); + long countByProofId(Long id); + + boolean existsBySponsorIdAndProofId(Long sponsorId, Long proofId); } \ No newline at end of file diff --git a/src/main/java/com/provedcode/kudos/service/KudosService.java b/src/main/java/com/provedcode/kudos/service/KudosService.java index 2edcdd3..13c1e53 100644 --- a/src/main/java/com/provedcode/kudos/service/KudosService.java +++ b/src/main/java/com/provedcode/kudos/service/KudosService.java @@ -1,6 +1,7 @@ package com.provedcode.kudos.service; import com.provedcode.kudos.model.entity.Kudos; +import com.provedcode.kudos.model.request.SetAmountKudos; import com.provedcode.kudos.model.response.KudosAmount; import com.provedcode.kudos.model.response.KudosAmountWithSponsor; import com.provedcode.kudos.repository.KudosRepository; @@ -8,6 +9,7 @@ import com.provedcode.sponsor.model.dto.SponsorDTO; import com.provedcode.sponsor.model.entity.Sponsor; import com.provedcode.sponsor.repository.SponsorRepository; +import com.provedcode.talent.model.ProofStatus; import com.provedcode.talent.model.entity.Talent; import com.provedcode.talent.model.entity.TalentProof; import com.provedcode.talent.repo.TalentProofRepository; @@ -22,6 +24,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import static org.springframework.http.HttpStatus.*; @@ -37,77 +40,93 @@ public class KudosService { TalentRepository talentRepository; SponsorMapper sponsorMapper; - - public void addKudosToProof(long id, Long amount, Authentication authentication) { - UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Sponsor with id = %s not found".formatted(id))); + public void addKudosToProof(long proofId, Optional setAmountKudos, Authentication authentication) { + String login = authentication.getName(); + UserInfo userInfo = userInfoRepository.findByLogin(login) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "User with login = %s not found".formatted( + login))); Sponsor sponsor = sponsorRepository.findById(userInfo.getSponsor().getId()).orElseThrow( () -> new ResponseStatusException(NOT_FOUND, - String.format("sponsor with id = %d not found", id))); - TalentProof talentProof = talentProofRepository.findById(id) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "Proof with id = %s not found".formatted(id))); - if (sponsor.getAmountKudos() < amount) { + "Sponsor with login = %s not found".formatted(login))); + TalentProof talentProof = talentProofRepository.findById(proofId) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "Proof with id = %d not found".formatted( + proofId))); + + if (kudosRepository.existsBySponsorIdAndProofId(sponsor.getId(), talentProof.getId())) + throw new ResponseStatusException(FORBIDDEN, "The sponsor has already set kudos to this proof"); + if (!talentProof.getStatus().equals(ProofStatus.PUBLISHED)) + throw new ResponseStatusException(FORBIDDEN, "Proof that was kudosed does not have the PUBLISHED status"); + + long obtainedAmount = setAmountKudos.orElse(new SetAmountKudos(1L)).amount(); + if (sponsor.getAmountKudos() < obtainedAmount) { throw new ResponseStatusException(FORBIDDEN, "The sponsor cannot give more kudos than he has"); } - if (amount <= 0) { - throw new ResponseStatusException(BAD_REQUEST, "amount of kudos must be greater than 0"); - } - sponsor.setAmountKudos(sponsor.getAmountKudos() - amount); + sponsor.setAmountKudos(sponsor.getAmountKudos() - obtainedAmount); kudosRepository.save(Kudos.builder() - .amountKudos(amount) - .proof(talentProof) - .sponsor(sponsor) - .build()); + .amount(obtainedAmount) + .proof(talentProof) + .sponsor(sponsor) + .build()); } @Transactional(readOnly = true) - public KudosAmount getKudosForSponsor(long id, Authentication authentication) { - UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Sponsor with id = %s not found".formatted(id))); - Sponsor sponsor = sponsorRepository.findById(userInfo.getSponsor().getId()).orElseThrow( - () -> new ResponseStatusException(NOT_FOUND, - String.format("Sponsor with id = %d not found", id))); - if (!sponsor.getId().equals(userInfo.getSponsor().getId())) { + public KudosAmount getKudosForSponsor(long sponsorId, Authentication authentication) { + String login = authentication.getName(); + UserInfo userInfo = userInfoRepository.findByLogin(login) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "User with login = %s not found".formatted( + login))); + if (!userInfo.getSponsor().getId().equals(sponsorId)) { throw new ResponseStatusException(FORBIDDEN, "Only the account owner can view the number of kudos"); } + Sponsor sponsor = sponsorRepository.findById(sponsorId).orElseThrow( + () -> new ResponseStatusException(NOT_FOUND, + String.format("Sponsor with id = %d not found", sponsorId))); return new KudosAmount(sponsor.getAmountKudos()); } @Transactional(readOnly = true) - public KudosAmountWithSponsor getProofKudos(long id, Authentication authentication) { - UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Sponsor with id = %s not found".formatted(id))); + public KudosAmountWithSponsor getProofKudos(long proofId, Authentication authentication) { + String login = authentication.getName(); + UserInfo userInfo = userInfoRepository.findByLogin(login) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "User with login = %s not found".formatted( + login))); Talent talent = talentRepository.findById(userInfo.getId()) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Talent with id = %s not found".formatted(id))); - TalentProof talentProof = talentProofRepository.findById(id) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Proof with id = %s not found".formatted(id))); + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "Talent with login = %s not found".formatted( + login))); + TalentProof talentProof = talentProofRepository.findById(proofId) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "Proof with id = %s not found".formatted( + proofId))); Long countOfAllKudos = talentProof.getKudos().stream() - .map(Kudos::getAmountKudos) - .reduce(0L, (prev, next) -> prev + next); + .map(Kudos::getAmount) + .reduce(0L, (prev, next) -> prev + next); if (talent.getId().equals(talentProof.getTalent().getId())) { Map kudosFromSponsor = talentProof.getKudos().stream() - .collect(Collectors.toMap( - Kudos::getAmountKudos, - proof -> proof.getSponsor() != null ? sponsorMapper.toDto(proof.getSponsor()) : SponsorDTO.builder().build(), - (prev, next) -> next, - HashMap::new - )); + .collect(Collectors.toMap( + Kudos::getAmount, + proof -> proof.getSponsor() != null + ? sponsorMapper.toDto( + proof.getSponsor()) + : SponsorDTO.builder().build(), + (prev, next) -> next, + HashMap::new + )); return KudosAmountWithSponsor.builder() - .allKudosOnProof(countOfAllKudos) - .kudosFromSponsor(kudosFromSponsor) - .build(); + .allKudosOnProof(countOfAllKudos) + .kudosFromSponsor(kudosFromSponsor) + .build(); } else { return KudosAmountWithSponsor.builder() - .allKudosOnProof(countOfAllKudos) - .kudosFromSponsor(null).build(); + .allKudosOnProof(countOfAllKudos) + .kudosFromSponsor(null).build(); } } } \ No newline at end of file diff --git a/src/main/java/com/provedcode/sponsor/controller/SponsorController.java b/src/main/java/com/provedcode/sponsor/controller/SponsorController.java index 0dc811e..39c5bad 100644 --- a/src/main/java/com/provedcode/sponsor/controller/SponsorController.java +++ b/src/main/java/com/provedcode/sponsor/controller/SponsorController.java @@ -2,23 +2,27 @@ import com.provedcode.sponsor.mapper.SponsorMapper; import com.provedcode.sponsor.model.dto.SponsorDTO; -import com.provedcode.sponsor.model.dto.SponsorEditDTO; +import com.provedcode.sponsor.model.request.EditSponsor; import com.provedcode.sponsor.service.SponsorService; import com.provedcode.util.annotations.doc.controller.sponsor.DeleteSponsorApiDoc; import com.provedcode.util.annotations.doc.controller.sponsor.GetAllSponsorsApiDoc; import com.provedcode.util.annotations.doc.controller.sponsor.GetSponsorApiDoc; import com.provedcode.util.annotations.doc.controller.sponsor.PatchEditSponsorApiDoc; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.PositiveOrZero; import lombok.AllArgsConstructor; import org.springframework.data.domain.Page; -import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.Optional; @RestController @AllArgsConstructor +@Validated @RequestMapping("/api/v3") public class SponsorController { SponsorService sponsorService; @@ -26,9 +30,8 @@ public class SponsorController { @GetAllSponsorsApiDoc @GetMapping("/sponsors") - @ResponseStatus(HttpStatus.OK) - Page getSponsors(@RequestParam(value = "page") Optional page, - @RequestParam(value = "size") Optional size) { + Page getSponsors(@RequestParam(value = "page", defaultValue = "0") @PositiveOrZero Integer page, + @RequestParam(value = "size", defaultValue = "5") @Min(1) @Max(1000) Integer size) { return sponsorService.getAllSponsors(page, size).map(sponsorMapper::toDto); } @@ -43,9 +46,9 @@ SponsorDTO getSponsor(@PathVariable("id") long id, Authentication authentication @PreAuthorize("hasRole('SPONSOR')") @PatchMapping("/sponsors/{id}") SponsorDTO editSponsor(@PathVariable("id") long id, - @RequestBody SponsorEditDTO sponsorEditDTO, + @RequestBody EditSponsor editSponsor, Authentication authentication) { - return sponsorMapper.toDto(sponsorService.editSponsorById(id, sponsorEditDTO, authentication)); + return sponsorMapper.toDto(sponsorService.editSponsorById(id, editSponsor, authentication)); } @DeleteSponsorApiDoc diff --git a/src/main/java/com/provedcode/sponsor/model/dto/SponsorEditDTO.java b/src/main/java/com/provedcode/sponsor/model/request/EditSponsor.java similarity index 81% rename from src/main/java/com/provedcode/sponsor/model/dto/SponsorEditDTO.java rename to src/main/java/com/provedcode/sponsor/model/request/EditSponsor.java index 82867a5..55bf951 100644 --- a/src/main/java/com/provedcode/sponsor/model/dto/SponsorEditDTO.java +++ b/src/main/java/com/provedcode/sponsor/model/request/EditSponsor.java @@ -1,10 +1,10 @@ -package com.provedcode.sponsor.model.dto; +package com.provedcode.sponsor.model.request; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Builder; @Builder -public record SponsorEditDTO( +public record EditSponsor( Long id, @JsonProperty("first_name") String firstName, diff --git a/src/main/java/com/provedcode/sponsor/service/SponsorService.java b/src/main/java/com/provedcode/sponsor/service/SponsorService.java index 933fb69..8beaba7 100644 --- a/src/main/java/com/provedcode/sponsor/service/SponsorService.java +++ b/src/main/java/com/provedcode/sponsor/service/SponsorService.java @@ -2,9 +2,10 @@ import com.provedcode.config.PageProperties; import com.provedcode.kudos.model.entity.Kudos; -import com.provedcode.sponsor.model.dto.SponsorEditDTO; import com.provedcode.sponsor.model.entity.Sponsor; +import com.provedcode.sponsor.model.request.EditSponsor; import com.provedcode.sponsor.repository.SponsorRepository; +import com.provedcode.sponsor.utill.ValidateSponsorForCompliance; import com.provedcode.user.model.entity.UserInfo; import com.provedcode.user.repo.UserInfoRepository; import lombok.AllArgsConstructor; @@ -18,7 +19,8 @@ import java.util.List; import java.util.Optional; -import static org.springframework.http.HttpStatus.*; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.FORBIDDEN; @Service @AllArgsConstructor @@ -27,70 +29,64 @@ public class SponsorService { PageProperties pageProperties; SponsorRepository sponsorRepository; UserInfoRepository userInfoRepository; + ValidateSponsorForCompliance validateSponsorForCompliance; @Transactional(readOnly = true) - public Page getAllSponsors(Optional page, Optional size) { - if (page.orElse(pageProperties.defaultPageNum()) < 0) { - throw new ResponseStatusException(BAD_REQUEST, "'page' query parameter must be greater than or equal to 0"); - } - if (size.orElse(pageProperties.defaultPageSize()) <= 0) { - throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); - } - return sponsorRepository.findAll(PageRequest.of(page.orElse(pageProperties.defaultPageNum()), - size.orElse(pageProperties.defaultPageSize()))); + public Page getAllSponsors(Integer page, Integer size) { + return sponsorRepository.findAll(PageRequest.of(page, size)); } @Transactional(readOnly = true) public Sponsor getSponsorById(long id, Authentication authentication) { - Sponsor sponsor = sponsorRepository.findById(id).orElseThrow( - () -> new ResponseStatusException(NOT_FOUND, String.format("sponsor with id = %d not found", id))); - UserInfo user = userInfoRepository.findByLogin(authentication.getName()) - .orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED, "login is not valid")); - - if (!sponsor.getId().equals(user.getSponsor().getId())) - throw new ResponseStatusException(FORBIDDEN, "The user cannot view someone else's profile"); - return sponsor; + Optional user = userInfoRepository.findByLogin(authentication.getName()); + Optional sponsor = sponsorRepository.findById(id); + validateSponsorForCompliance.userVerification(sponsor, user, id); + return sponsor.get(); } - public Sponsor editSponsorById(long id, SponsorEditDTO sponsorEditDTO, Authentication authentication) { - Sponsor sponsor = sponsorRepository.findById(id) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "sponsor with id = %s not found".formatted(id))); - UserInfo user = userInfoRepository.findByLogin(authentication.getName()) - .orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED, "login is not valid")); - if (!sponsor.getId().equals(user.getSponsor().getId())) { - throw new ResponseStatusException(FORBIDDEN, "The user cannot edit someone else's profile"); - } + public Sponsor editSponsorById(long id, EditSponsor editSponsor, Authentication authentication) { + Optional user = userInfoRepository.findByLogin(authentication.getName()); + Optional sponsor = sponsorRepository.findById(id); + validateSponsorForCompliance.userVerification(sponsor, user, id); + checkEditSponsorNull(editSponsor); - if (sponsorEditDTO.firstName() != null) { - sponsor.setFirstName(sponsorEditDTO.firstName()); + Sponsor editableSponsor = sponsor.get(); + if (editSponsor.firstName() != null) { + editableSponsor.setFirstName(editSponsor.firstName()); } - if (sponsorEditDTO.lastName() != null) { - sponsor.setLastName(sponsorEditDTO.lastName()); + if (editSponsor.lastName() != null) { + editableSponsor.setLastName(editSponsor.lastName()); } - if (sponsorEditDTO.image() != null) { - sponsor.setImage(sponsorEditDTO.image()); + if (editSponsor.image() != null) { + editableSponsor.setImage(editSponsor.image()); } - if (sponsorEditDTO.countOfKudos() != null) { - if (sponsorEditDTO.countOfKudos() > 0) { - sponsor.setAmountKudos(sponsor.getAmountKudos() + sponsorEditDTO.countOfKudos()); + if (editSponsor.countOfKudos() != null) { + if (editSponsor.countOfKudos() > 0) { + editableSponsor.setAmountKudos(editableSponsor.getAmountKudos() + editSponsor.countOfKudos()); } else { throw new ResponseStatusException(BAD_REQUEST, "count of kudos must be greater than 0"); } } - return sponsorRepository.save(sponsor); + return sponsorRepository.save(editableSponsor); } public void deleteSponsor(long id, Authentication authentication) { - Sponsor sponsor = sponsorRepository.findById(id) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "sponsor with id = %s not found".formatted(id))); - UserInfo user = userInfoRepository.findByLogin(authentication.getName()) - .orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED, "login is not valid")); - if (!sponsor.getId().equals(user.getSponsor().getId())) { - throw new ResponseStatusException(FORBIDDEN, "The user cannot edit someone else's profile"); - } + Optional user = userInfoRepository.findByLogin(authentication.getName()); + Optional sponsor = sponsorRepository.findById(id); + validateSponsorForCompliance.userVerification(sponsor, user, id); + + Sponsor deletableSponsor = sponsor.get(); + List kudosList = deletableSponsor.getKudoses().stream().map(i -> { + i.setSponsor(null); + return i; + }).toList(); + deletableSponsor.setKudoses(kudosList); + userInfoRepository.delete(user.get()); + } - List kudosList = sponsor.getKudoses().stream().map(i -> {i.setSponsor(null); return i;}).toList(); - sponsor.setKudoses(kudosList); - userInfoRepository.delete(user); + private void checkEditSponsorNull(EditSponsor editSponsor) { + if (editSponsor.firstName() == null && editSponsor.lastName() == null && editSponsor.image() == null && + editSponsor.countOfKudos() == null) + throw new ResponseStatusException(FORBIDDEN, "you did not provide information to make changes"); } } \ No newline at end of file diff --git a/src/main/java/com/provedcode/sponsor/utill/ValidateSponsorForCompliance.java b/src/main/java/com/provedcode/sponsor/utill/ValidateSponsorForCompliance.java new file mode 100644 index 0000000..ce8a6d0 --- /dev/null +++ b/src/main/java/com/provedcode/sponsor/utill/ValidateSponsorForCompliance.java @@ -0,0 +1,24 @@ +package com.provedcode.sponsor.utill; + +import com.provedcode.sponsor.model.entity.Sponsor; +import com.provedcode.user.model.entity.UserInfo; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import java.util.Optional; + +import static org.springframework.http.HttpStatus.FORBIDDEN; +import static org.springframework.http.HttpStatus.NOT_FOUND; + +@Service +public class ValidateSponsorForCompliance { + + public void userVerification(Optional sponsor, Optional userInfo, long sponsorId) { + if (sponsor.isEmpty() || userInfo.isEmpty()) { + throw new ResponseStatusException(NOT_FOUND, String.format("sponsor with id = %d not found", sponsorId)); + } + if (userInfo.get().getSponsor().getId() != sponsorId) { + throw new ResponseStatusException(FORBIDDEN); + } + } +} diff --git a/src/main/java/com/provedcode/talent/controller/TalentController.java b/src/main/java/com/provedcode/talent/controller/TalentController.java index 8691928..1b9e20d 100644 --- a/src/main/java/com/provedcode/talent/controller/TalentController.java +++ b/src/main/java/com/provedcode/talent/controller/TalentController.java @@ -1,5 +1,6 @@ package com.provedcode.talent.controller; +import com.provedcode.config.PageProperties; import com.provedcode.talent.mapper.TalentMapper; import com.provedcode.talent.model.dto.FullTalentDTO; import com.provedcode.talent.model.dto.ShortTalentDTO; @@ -12,12 +13,16 @@ import com.provedcode.util.annotations.doc.controller.talent.PatchEditTalentApiDoc; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.PositiveOrZero; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.Optional; @@ -27,15 +32,16 @@ @AllArgsConstructor @RequestMapping("/api/v2") @Tag(name = "talent", description = "Talent API") +@Validated public class TalentController { TalentService talentService; TalentMapper talentMapper; @GetAllTalentsApiDoc @GetMapping("/talents") - @ResponseStatus(HttpStatus.OK) - Page getTalents(@RequestParam(value = "page") Optional page, - @RequestParam(value = "size") Optional size) { + @Validated + Page getTalents(@RequestParam(value = "page", defaultValue = "0") @PositiveOrZero Integer page, + @RequestParam(value = "size", defaultValue = "5") @Min(1) @Max(1000) Integer size) { return talentService.getTalentsPage(page, size).map(talentMapper::talentToShortTalentDTO); } diff --git a/src/main/java/com/provedcode/talent/controller/TalentProofController.java b/src/main/java/com/provedcode/talent/controller/TalentProofController.java index 7c5500f..2b5e769 100644 --- a/src/main/java/com/provedcode/talent/controller/TalentProofController.java +++ b/src/main/java/com/provedcode/talent/controller/TalentProofController.java @@ -8,27 +8,35 @@ import com.provedcode.talent.service.TalentProofService; import com.provedcode.util.annotations.doc.controller.proof.*; import jakarta.validation.Valid; +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.PositiveOrZero; import lombok.AllArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import java.util.Optional; - @RestController @AllArgsConstructor @RequestMapping("/api/v2/talents") +@Validated public class TalentProofController { TalentProofService talentProofService; TalentProofMapper talentProofMapper; @GetAllProofsApiDoc @GetMapping("/proofs") - Page getAllProofs(@RequestParam(value = "page") Optional page, - @RequestParam(value = "size") Optional size, - @RequestParam(value = "order-by") Optional orderBy, + Page getAllProofs(@RequestParam(value = "page", defaultValue = "0") @PositiveOrZero Integer page, + @RequestParam(value = "size", defaultValue = "5") @Min(1) @Max(1000) Integer size, + @RequestParam(value = "order-by", defaultValue = "ASC") + @Pattern(regexp = "asc|desc", + flags = {Pattern.Flag.CASE_INSENSITIVE}, + message = "'direction' query param must be equals ASC or DESC") + String orderBy, @RequestParam(value = "sort-by", defaultValue = "created") String... sortBy) { return talentProofService.getAllProofsPage(page, size, orderBy, sortBy).map(talentProofMapper::toProofDTO); } @@ -46,9 +54,13 @@ ProofDTO getTalentProof(@PathVariable(value = "proof-id") long proofId, @PreAuthorize("hasRole('TALENT')") FullProofDTO getTalentInformationWithProofs(Authentication authentication, @PathVariable("talent-id") Long talentId, - @RequestParam(value = "page") Optional page, - @RequestParam(value = "size") Optional size, - @RequestParam(value = "order-by") Optional orderBy, + @RequestParam(value = "page", defaultValue = "0") @PositiveOrZero Integer page, + @RequestParam(value = "size", defaultValue = "5") @Min(1) @Max(1000) Integer size, + @RequestParam(value = "order-by", defaultValue = "ASC") + @Pattern(regexp = "asc|desc", + flags = {Pattern.Flag.CASE_INSENSITIVE}, + message = "'direction' query param must be equals ASC or DESC") + String orderBy, @RequestParam(value = "sort-by", defaultValue = "created") String... sortBy) { return talentProofService.getTalentProofs(talentId, page, size, orderBy, authentication, sortBy); } diff --git a/src/main/java/com/provedcode/talent/service/TalentProofService.java b/src/main/java/com/provedcode/talent/service/TalentProofService.java index a411d28..bbd8434 100644 --- a/src/main/java/com/provedcode/talent/service/TalentProofService.java +++ b/src/main/java/com/provedcode/talent/service/TalentProofService.java @@ -31,7 +31,8 @@ import java.time.format.DateTimeFormatter; import java.util.Optional; -import static org.springframework.http.HttpStatus.*; +import static org.springframework.http.HttpStatus.FORBIDDEN; +import static org.springframework.http.HttpStatus.NOT_FOUND; @Service @AllArgsConstructor @@ -45,33 +46,15 @@ public class TalentProofService { ValidateTalentForCompliance validateTalentForCompliance; @Transactional(readOnly = true) - public Page getAllProofsPage(Optional page, Optional size, Optional orderBy, + public Page getAllProofsPage(Integer page, Integer size, String orderBy, String... sortBy) { - PageRequest pageRequest; - String sortDirection = orderBy.orElseGet(Sort.DEFAULT_DIRECTION::name); - - if (page.orElse(pageProperties.defaultPageNum()) < 0) { - throw new ResponseStatusException(BAD_REQUEST, "'page' query parameter must be greater than or equal to 0"); - } - if (size.orElse(pageProperties.defaultPageSize()) <= 0) { - throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); - } - if (!sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name()) && - !sortDirection.equalsIgnoreCase(Sort.Direction.DESC.name())) { - throw new ResponseStatusException(BAD_REQUEST, "'direction' query param must be equals ASC or DESC"); - } - - try { - pageRequest = PageRequest.of( - page.orElse(pageProperties.defaultPageNum()), - size.orElse(pageProperties.defaultPageSize()), - Sort.Direction.valueOf(sortDirection.toUpperCase()), - sortBy - ); - return talentProofRepository.findByStatus(ProofStatus.PUBLISHED, pageRequest); - } catch (RuntimeException exception) { - throw new ResponseStatusException(BAD_REQUEST, exception.getMessage()); - } + PageRequest pageRequest = PageRequest.of( + page, + size, + Sort.Direction.valueOf(orderBy.toUpperCase()), + sortBy + ); + return talentProofRepository.findByStatus(ProofStatus.PUBLISHED, pageRequest); } @Transactional(readOnly = true) @@ -90,48 +73,25 @@ public TalentProof getTalentProof(long proofId, Authentication authentication) { } @Transactional(readOnly = true) - public FullProofDTO getTalentProofs(Long talentId, Optional page, Optional size, - Optional direction, Authentication authentication, - String... sortProperties) { + public FullProofDTO getTalentProofs(Long talentId, Integer page, Integer size, String direction, + Authentication authentication, String... sortProperties) { Talent talent = talentRepository.findById(talentId) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, - "Talent with id = %s not found".formatted( + "Talent with id = %d not found".formatted( talentId))); UserInfo userInfo = userInfoRepository.findById(talentId) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, - "Talent with id = %s not found".formatted( + "User with id = %d not found".formatted( talentId))); Page proofs; - PageRequest pageRequest; - String sortDirection = direction.orElseGet(Sort.DEFAULT_DIRECTION::name); - - if (page.orElse(pageProperties.defaultPageNum()) < 0) { - throw new ResponseStatusException(BAD_REQUEST, "'page' query parameter must be greater than or equal to 0"); - } - if (size.orElse(pageProperties.defaultPageSize()) <= 0) { - throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); - } - if (!sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name()) && - !sortDirection.equalsIgnoreCase(Sort.Direction.DESC.name())) { - throw new ResponseStatusException(BAD_REQUEST, "'direction' query param must be equals ASC or DESC"); - } - - try { - pageRequest = PageRequest.of( - page.orElse(pageProperties.defaultPageNum()), - size.orElse(pageProperties.defaultPageSize()), - Sort.Direction.valueOf(sortDirection.toUpperCase()), - sortProperties - ); - if (!userInfo.getLogin().equals(authentication.getName())) { - proofs = talentProofRepository.findByTalentIdAndStatus(talentId, ProofStatus.PUBLISHED, pageRequest); - } else { - proofs = talentProofRepository.findByTalentId(talentId, pageRequest); - } - } catch (RuntimeException exception) { - throw new ResponseStatusException(BAD_REQUEST, exception.getMessage()); + PageRequest pageRequest = PageRequest.of(page, size, Sort.Direction.valueOf(direction.toUpperCase()), + sortProperties + ); + if (!userInfo.getLogin().equals(authentication.getName())) { + proofs = talentProofRepository.findByTalentIdAndStatus(talentId, ProofStatus.PUBLISHED, pageRequest); + } else { + proofs = talentProofRepository.findByTalentId(talentId, pageRequest); } - return FullProofDTO.builder() .id(talent.getId()) .image(talent.getImage()) @@ -161,7 +121,6 @@ public ResponseEntity addProof(AddProof addProof, long talentId, Authenticati .status(ProofStatus.DRAFT) .created(LocalDateTime.now()) .build(); - talentProofRepository.save(talentProof); URI location = ServletUriComponentsBuilder diff --git a/src/main/java/com/provedcode/talent/service/TalentService.java b/src/main/java/com/provedcode/talent/service/TalentService.java index 93fb180..48a854d 100644 --- a/src/main/java/com/provedcode/talent/service/TalentService.java +++ b/src/main/java/com/provedcode/talent/service/TalentService.java @@ -1,22 +1,151 @@ package com.provedcode.talent.service; -import com.provedcode.talent.model.dto.ShortTalentDTO; -import com.provedcode.talent.model.entity.Talent; +import com.provedcode.config.PageProperties; +import com.provedcode.talent.model.entity.*; import com.provedcode.talent.model.request.EditTalent; +import com.provedcode.talent.repo.TalentProofRepository; +import com.provedcode.talent.repo.TalentRepository; +import com.provedcode.talent.utill.ValidateTalentForCompliance; import com.provedcode.user.model.dto.SessionInfoDTO; -import org.springframework.security.core.Authentication; +import com.provedcode.user.model.entity.UserInfo; +import com.provedcode.user.repo.AuthorityRepository; +import com.provedcode.user.repo.UserInfoRepository; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; -import com.provedcode.talent.model.dto.FullTalentDTO; +import org.springframework.data.domain.PageRequest; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.server.ResponseStatusException; +import java.util.List; import java.util.Optional; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.NOT_FOUND; + +@Service +@Slf4j +@AllArgsConstructor +@Transactional +public class TalentService { + AuthorityRepository authorityRepository; + TalentProofRepository talentProofRepository; + TalentRepository talentRepository; + UserInfoRepository userInfoRepository; + PageProperties pageProperties; + ValidateTalentForCompliance validateTalentForCompliance; + + @Transactional(readOnly = true) + public Page getTalentsPage(Integer page, Integer size) { + return talentRepository.findAll(PageRequest.of(page, size)); + } + + @Transactional(readOnly = true) + public Talent getTalentById(long id) { + return talentRepository.findById(id).orElseThrow(() -> new ResponseStatusException(NOT_FOUND)); + } + + public Talent editTalent(long id, EditTalent editTalent, Authentication authentication) { + Optional talent = talentRepository.findById(id); + Optional userInfo = userInfoRepository.findByLogin(authentication.getName()); + validateTalentForCompliance.userVerification(talent, userInfo, id); + checkEditTalentNull(editTalent); + + Talent editableTalent = talent.get(); + + TalentDescription editableTalentDescription = editableTalent.getTalentDescription(); + List editableTalentTalents = editableTalent.getTalentTalents(); + List editableTalentLinks = editableTalent.getTalentLinks(); + List editableTalentContacts = editableTalent.getTalentContacts(); + List editableTalentAttachedFiles = editableTalent.getTalentAttachedFiles(); + + if (editTalent.firstName() != null) { + editableTalent.setFirstName(editTalent.firstName()); + } + if (editTalent.lastName() != null) { + editableTalent.setLastName(editTalent.lastName()); + } + if (editTalent.specialization() != null) { + editableTalent.setSpecialization(editTalent.specialization()); + } + if (editTalent.image() != null) { + editableTalent.setImage(editTalent.image()); + } + if (editTalent.additionalInfo() != null || editTalent.bio() != null) { + if (editableTalentDescription != null) { + if (editTalent.additionalInfo() != null) + editableTalentDescription.setAdditionalInfo(editTalent.additionalInfo()); + if (editTalent.bio() != null) + editableTalentDescription.setBio(editTalent.bio()); + } else { + editableTalentDescription = TalentDescription.builder() + .additionalInfo(editTalent.additionalInfo()) + .bio(editTalent.bio()) + .talent(editableTalent) + .build(); + } + editableTalent.setTalentDescription(editableTalentDescription); + } + if (editTalent.talents() != null) { + editableTalentTalents.clear(); + editableTalentTalents.addAll(editTalent.talents().stream().map(s -> TalentTalents.builder() + .talent(editableTalent) + .talentName(s) + .build()).toList()); + editableTalent.setTalentTalents(editableTalentTalents); + } + if (editTalent.links() != null) { + editableTalentLinks.clear(); + editableTalentLinks.addAll(editTalent.links().stream().map(s -> TalentLink.builder() + .talent(editableTalent) + .link(s) + .build()).toList()); + editableTalent.setTalentLinks(editableTalentLinks); + } + if (editTalent.contacts() != null) { + editableTalentContacts.clear(); + editableTalentContacts.addAll(editTalent.contacts().stream().map(s -> TalentContact.builder() + .talent(editableTalent) + .contact(s) + .build()).toList()); + editableTalent.setTalentContacts(editableTalentContacts); + } + if (editTalent.attachedFiles() != null) { + editableTalentAttachedFiles.clear(); + editableTalentAttachedFiles.addAll(editTalent.attachedFiles().stream().map(s -> TalentAttachedFile.builder() + .talent(editableTalent) + .attachedFile( + s) + .build()) + .toList()); + editableTalent.setTalentAttachedFiles(editableTalentAttachedFiles); + } + return talentRepository.save(editableTalent); + } + + public SessionInfoDTO deleteTalentById(long id, Authentication authentication) { + Optional talent = talentRepository.findById(id); + Optional userInfo = userInfoRepository.findByLogin(authentication.getName()); + + validateTalentForCompliance.userVerification(talent, userInfo, id); -public interface TalentService { - Page getTalentsPage(Optional page, Optional size); + UserInfo user = userInfo.get(); + Talent entity = talent.get(); - Talent getTalentById(long id); + user.getAuthorities().clear(); + userInfoRepository.delete(user); + talentRepository.delete(entity); - Talent editTalent(long id, EditTalent editTalent, Authentication authentication); + return new SessionInfoDTO("deleted", "null"); + } - SessionInfoDTO deleteTalentById(long id, Authentication authentication); + private void checkEditTalentNull(EditTalent editTalent) { + if (editTalent.firstName() == null && editTalent.lastName() == null && editTalent.image() == null && + editTalent.specialization() == null && editTalent.additionalInfo() == null && editTalent.bio() == null && + editTalent.talents() == null && editTalent.links() == null && editTalent.contacts() == null && + editTalent.attachedFiles() == null) + throw new ResponseStatusException(BAD_REQUEST, "you did not provide information to make changes"); + } } \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/service/impl/TalentServiceImpl.java b/src/main/java/com/provedcode/talent/service/impl/TalentServiceImpl.java deleted file mode 100644 index 29939c7..0000000 --- a/src/main/java/com/provedcode/talent/service/impl/TalentServiceImpl.java +++ /dev/null @@ -1,163 +0,0 @@ -package com.provedcode.talent.service.impl; - -import com.provedcode.config.PageProperties; -import com.provedcode.talent.model.entity.*; -import com.provedcode.talent.model.request.EditTalent; -import com.provedcode.talent.repo.TalentProofRepository; -import com.provedcode.talent.repo.TalentRepository; -import com.provedcode.talent.service.TalentService; -import com.provedcode.talent.utill.ValidateTalentForCompliance; -import com.provedcode.user.model.dto.SessionInfoDTO; -import com.provedcode.user.model.entity.UserInfo; -import com.provedcode.user.repo.AuthorityRepository; -import com.provedcode.user.repo.UserInfoRepository; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.security.core.Authentication; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.server.ResponseStatusException; - -import java.util.List; -import java.util.Optional; - -import static org.springframework.http.HttpStatus.*; - -@Service -@Slf4j -@AllArgsConstructor -@Transactional -public class TalentServiceImpl implements TalentService { - AuthorityRepository authorityRepository; - TalentProofRepository talentProofRepository; - TalentRepository talentRepository; - UserInfoRepository userInfoRepository; - PageProperties pageProperties; - ValidateTalentForCompliance validateTalentForCompliance; - - @Override - @Transactional(readOnly = true) - public Page getTalentsPage(Optional page, Optional size) { - if (page.orElse(pageProperties.defaultPageNum()) < 0) { - throw new ResponseStatusException(BAD_REQUEST, "'page' query parameter must be greater than or equal to 0"); - } - if (size.orElse(pageProperties.defaultPageSize()) <= 0) { - throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); - } - return talentRepository.findAll(PageRequest.of(page.orElse(pageProperties.defaultPageNum()), - size.orElse(pageProperties.defaultPageSize()))); - } - - @Override - @Transactional(readOnly = true) - public Talent getTalentById(long id) { - Optional talent = talentRepository.findById(id); - if (talent.isEmpty()) { - throw new ResponseStatusException(NOT_FOUND, String.format("talent with id = %d not found", id)); - } - return talent.get(); - } - - @Override - public Talent editTalent(long id, EditTalent editTalent, Authentication authentication) { - if (editTalent.firstName() == null && editTalent.lastName() == null && editTalent.image() == null && - editTalent.specialization() == null && editTalent.additionalInfo() == null && editTalent.bio() == null && - editTalent.talents() == null && editTalent.links() == null && editTalent.contacts() == null && - editTalent.attachedFiles() == null) - throw new ResponseStatusException(BAD_REQUEST, "you did not provide information to make changes"); - - Optional talent = talentRepository.findById(id); - Optional userInfo = userInfoRepository.findByLogin(authentication.getName()); - - validateTalentForCompliance.userVerification(talent, userInfo, id); - - Talent editableTalent = talent.get(); - long idEditableTalent = editableTalent.getId(); - - TalentDescription editableTalentDescription = editableTalent.getTalentDescription(); - List editableTalentTalents = editableTalent.getTalentTalents(); - List editableTalentLinks = editableTalent.getTalentLinks(); - List editableTalentContacts = editableTalent.getTalentContacts(); - List editableTalentAttachedFile = editableTalent.getTalentAttachedFiles(); - - if (editableTalentDescription != null) { - editableTalentDescription - .setAdditionalInfo(editTalent.additionalInfo() != null ? editTalent.additionalInfo() - : editableTalentDescription.getAdditionalInfo()) - .setBio(editTalent.bio() != null ? editTalent.bio() : editableTalentDescription.getBio()); - } else { - editableTalentDescription = TalentDescription.builder() - .additionalInfo(editTalent.additionalInfo()) - .bio(editTalent.bio()) - .talent(editableTalent) - .build(); - } - - if (editTalent.talents() != null) { - editableTalentTalents.clear(); - editableTalentTalents.addAll(editTalent.talents().stream().map(s -> TalentTalents.builder() - .talent(editableTalent) - .talentName(s) - .build()).toList()); - } - - if (editTalent.links() != null) { - editableTalentLinks.clear(); - editableTalentLinks.addAll(editTalent.links().stream().map(l -> TalentLink.builder() - .talent(editableTalent) - .link(l) - .build()).toList()); - } - - if (editTalent.contacts() != null) { - editableTalentContacts.clear(); - editableTalentContacts.addAll(editTalent.contacts().stream().map(s -> TalentContact.builder() - .talent(editableTalent) - .contact(s) - .build()).toList()); - } - - if (editTalent.attachedFiles() != null) { - editableTalentAttachedFile.clear(); - editableTalentAttachedFile.addAll(editTalent.attachedFiles().stream().map(s -> TalentAttachedFile.builder() - .talent(editableTalent) - .attachedFile( - s) - .build()) - .toList()); - } - - editableTalent.setFirstName( - editTalent.firstName() != null ? editTalent.firstName() : editableTalent.getFirstName()) - .setLastName(editTalent.lastName() != null ? editTalent.lastName() : editableTalent.getLastName()) - .setSpecialization(editTalent.specialization() != null ? editTalent.specialization() - : editableTalent.getSpecialization()) - .setImage(editTalent.image() != null ? editTalent.image() : editableTalent.getImage()) - .setTalentDescription(editableTalentDescription) - .setTalentTalents(editableTalentTalents) - .setTalentLinks(editableTalentLinks) - .setTalentContacts(editableTalentContacts) - .setTalentAttachedFiles(editableTalentAttachedFile); - - return talentRepository.save(editableTalent); - } - - @Override - public SessionInfoDTO deleteTalentById(long id, Authentication authentication) { - Optional talent = talentRepository.findById(id); - Optional userInfo = userInfoRepository.findByLogin(authentication.getName()); - - validateTalentForCompliance.userVerification(talent, userInfo, id); - - UserInfo user = userInfo.orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED)); - Talent entity = talent.orElseThrow(() -> new ResponseStatusException(NOT_IMPLEMENTED)); - - user.getAuthorities().clear(); - userInfoRepository.delete(user); - talentRepository.delete(entity); - - return new SessionInfoDTO("deleted", "null"); - } -} \ No newline at end of file diff --git a/src/main/java/com/provedcode/user/util/UserInfoValidator.java b/src/main/java/com/provedcode/user/util/UserInfoValidator.java new file mode 100644 index 0000000..04dd6c4 --- /dev/null +++ b/src/main/java/com/provedcode/user/util/UserInfoValidator.java @@ -0,0 +1,24 @@ +package com.provedcode.user.util; + +import com.provedcode.user.model.entity.UserInfo; +import com.provedcode.user.repo.UserInfoRepository; +import lombok.AllArgsConstructor; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ResponseStatusException; + +import static org.springframework.http.HttpStatus.NOT_FOUND; + +@Component +@AllArgsConstructor +public class UserInfoValidator { + UserInfoRepository userInfoRepository; + + public UserInfo findByLoginOrElseThrow(Authentication authentication) { + String login = authentication.getName(); + return userInfoRepository.findByLogin(login) + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "Sponsor with login = %s not found".formatted( + login))); + } +} diff --git a/src/main/java/com/provedcode/util/PhotoService.java b/src/main/java/com/provedcode/util/PhotoService.java index 9ea1a09..a7b74d3 100644 --- a/src/main/java/com/provedcode/util/PhotoService.java +++ b/src/main/java/com/provedcode/util/PhotoService.java @@ -4,12 +4,12 @@ import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; -import java.awt.image.BufferedImage; -import java.awt.Image; import java.util.List; -import javax.imageio.ImageIO; import static org.apache.http.entity.ContentType.*; @@ -17,7 +17,6 @@ @Service @AllArgsConstructor public class PhotoService { - public File degradePhoto(File photoFile) throws IOException { // загружаем изображение из файла BufferedImage originalImage = ImageIO.read(photoFile); @@ -44,7 +43,7 @@ public File degradePhoto(File photoFile) throws IOException { } public boolean isFileImage(MultipartFile file) { - return !List.of(IMAGE_JPEG.getMimeType(), IMAGE_PNG.getMimeType(), IMAGE_GIF.getMimeType()).contains(file.getContentType()); + return !List.of(IMAGE_JPEG.getMimeType(), IMAGE_PNG.getMimeType(), IMAGE_GIF.getMimeType()) + .contains(file.getContentType()); } - } diff --git a/src/main/resources/db/changelog/changeset/V2/data-V2.sql b/src/main/resources/db/changelog/changeset/V2/data-V2.sql index e0d6ee0..a5de8d5 100644 --- a/src/main/resources/db/changelog/changeset/V2/data-V2.sql +++ b/src/main/resources/db/changelog/changeset/V2/data-V2.sql @@ -544,7 +544,7 @@ insert into talent_proofs (talent_id, link, text, status, created) values ((select id from talent order by id desc limit 1), 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', 'text to third proof', 'DRAFT', '2023-06-04 16:00:19'); insert into user_info (talent_id, login, password) -values ((select id from talent order by id desc limit 1), '$2a$10$D4KM50WemOahkFv1fkrPX.MvVESsE0TYWlkh5TypTE/q4nlv8ooyS', 'password'); +values ((select id from talent order by id desc limit 1), 'IhorKopieichykov@gmail.com', '$2a$10$D4KM50WemOahkFv1fkrPX.MvVESsE0TYWlkh5TypTE/q4nlv8ooyS'); insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 1)); @@ -585,11 +585,11 @@ insert into user_authorities (user_id, authority_id) values ((select id from user_info order by id desc limit 1), (select authority.id from authority where id = 2) ); -insert into kudos (amount_kudos, sponsor_id, proof_id) +insert into kudos (amount, sponsor_id, proof_id) values (100, 1, 1); -insert into kudos (amount_kudos, sponsor_id, proof_id) +insert into kudos (amount, sponsor_id, proof_id) values (200, 2, 1); -insert into kudos (amount_kudos, sponsor_id, proof_id) +insert into kudos (amount, sponsor_id, proof_id) values (200, 3, 1); -insert into kudos (amount_kudos, sponsor_id, proof_id) +insert into kudos (amount, sponsor_id, proof_id) values (300, 4, 1); \ No newline at end of file diff --git a/src/main/resources/db/changelog/changeset/V2/schema-V2.sql b/src/main/resources/db/changelog/changeset/V2/schema-V2.sql index ebd940a..799d7e5 100644 --- a/src/main/resources/db/changelog/changeset/V2/schema-V2.sql +++ b/src/main/resources/db/changelog/changeset/V2/schema-V2.sql @@ -86,7 +86,7 @@ CREATE TABLE kudos id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, sponsor_id BIGINT, proof_id BIGINT, - amount_kudos BIGINT, + amount BIGINT, CONSTRAINT pk_kudos PRIMARY KEY (id) ); CREATE TABLE sponsor From 8605ed42fcd94876e3b2bb80a93b4bcdd9d67389 Mon Sep 17 00:00:00 2001 From: Denis Boyko Date: Sat, 29 Apr 2023 21:57:55 +0300 Subject: [PATCH 11/15] fix .findByLogin(authentication.getName()) - getTalentProofs --- .../aws/controller/AWSS3BucketController.java | 2 +- .../com/provedcode/aws/service/S3Service.java | 10 +-- .../kudos/service/KudosService.java | 80 +++++++++---------- .../talent/service/TalentProofService.java | 56 +++++++------ 4 files changed, 73 insertions(+), 75 deletions(-) diff --git a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java index 0f09291..3b8ff0e 100644 --- a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java +++ b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java @@ -34,6 +34,6 @@ List getAllFiles() { String testTypeOfFile(@RequestParam("file") MultipartFile file, Authentication authentication) { return Arrays.stream(file.getContentType().split("/")).toList().get(1) + " " + file.getOriginalFilename() + - " " + file.getName() + " " + file.getResource(); + " " + file.getName() + " " + file.getResource(); } } diff --git a/src/main/java/com/provedcode/aws/service/S3Service.java b/src/main/java/com/provedcode/aws/service/S3Service.java index 3caa3ec..fa1ea9d 100644 --- a/src/main/java/com/provedcode/aws/service/S3Service.java +++ b/src/main/java/com/provedcode/aws/service/S3Service.java @@ -73,16 +73,16 @@ public List listAllFiles() { public void setNewUserImage(MultipartFile file, Authentication authentication) { if (file.isEmpty()) { throw new ResponseStatusException(NOT_IMPLEMENTED, - "file must be not empty, actual file-size: %s".formatted(file.getSize())); + "file must be not empty, actual file-size: %s".formatted(file.getSize())); } if (photoService.isFileImage(file)) { throw new ResponseStatusException(NOT_IMPLEMENTED, - "not supported type: %s".formatted(file.getContentType())); + "not supported type: %s".formatted(file.getContentType())); } UserInfo user = userInfoRepository.findByLogin(authentication.getName()) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "user with login = {%s} not found".formatted( - authentication.getName()))); + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "user with login = {%s} not found".formatted( + authentication.getName()))); try { String fileType = file.getContentType().split("/")[1]; diff --git a/src/main/java/com/provedcode/kudos/service/KudosService.java b/src/main/java/com/provedcode/kudos/service/KudosService.java index 13c1e53..f506391 100644 --- a/src/main/java/com/provedcode/kudos/service/KudosService.java +++ b/src/main/java/com/provedcode/kudos/service/KudosService.java @@ -43,16 +43,16 @@ public class KudosService { public void addKudosToProof(long proofId, Optional setAmountKudos, Authentication authentication) { String login = authentication.getName(); UserInfo userInfo = userInfoRepository.findByLogin(login) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "User with login = %s not found".formatted( - login))); + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "User with login = %s not found".formatted( + login))); Sponsor sponsor = sponsorRepository.findById(userInfo.getSponsor().getId()).orElseThrow( () -> new ResponseStatusException(NOT_FOUND, - "Sponsor with login = %s not found".formatted(login))); + "Sponsor with login = %s not found".formatted(login))); TalentProof talentProof = talentProofRepository.findById(proofId) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Proof with id = %d not found".formatted( - proofId))); + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "Proof with id = %d not found".formatted( + proofId))); if (kudosRepository.existsBySponsorIdAndProofId(sponsor.getId(), talentProof.getId())) throw new ResponseStatusException(FORBIDDEN, "The sponsor has already set kudos to this proof"); @@ -65,25 +65,25 @@ public void addKudosToProof(long proofId, Optional setAmountKudo } sponsor.setAmountKudos(sponsor.getAmountKudos() - obtainedAmount); kudosRepository.save(Kudos.builder() - .amount(obtainedAmount) - .proof(talentProof) - .sponsor(sponsor) - .build()); + .amount(obtainedAmount) + .proof(talentProof) + .sponsor(sponsor) + .build()); } @Transactional(readOnly = true) public KudosAmount getKudosForSponsor(long sponsorId, Authentication authentication) { String login = authentication.getName(); UserInfo userInfo = userInfoRepository.findByLogin(login) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "User with login = %s not found".formatted( - login))); + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "User with login = %s not found".formatted( + login))); if (!userInfo.getSponsor().getId().equals(sponsorId)) { throw new ResponseStatusException(FORBIDDEN, "Only the account owner can view the number of kudos"); } Sponsor sponsor = sponsorRepository.findById(sponsorId).orElseThrow( () -> new ResponseStatusException(NOT_FOUND, - String.format("Sponsor with id = %d not found", sponsorId))); + String.format("Sponsor with id = %d not found", sponsorId))); return new KudosAmount(sponsor.getAmountKudos()); } @@ -91,42 +91,42 @@ public KudosAmount getKudosForSponsor(long sponsorId, Authentication authenticat public KudosAmountWithSponsor getProofKudos(long proofId, Authentication authentication) { String login = authentication.getName(); UserInfo userInfo = userInfoRepository.findByLogin(login) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "User with login = %s not found".formatted( - login))); + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "User with login = %s not found".formatted( + login))); Talent talent = talentRepository.findById(userInfo.getId()) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Talent with login = %s not found".formatted( - login))); + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "Talent with login = %s not found".formatted( + login))); TalentProof talentProof = talentProofRepository.findById(proofId) - .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, - "Proof with id = %s not found".formatted( - proofId))); + .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, + "Proof with id = %s not found".formatted( + proofId))); Long countOfAllKudos = talentProof.getKudos().stream() - .map(Kudos::getAmount) - .reduce(0L, (prev, next) -> prev + next); + .map(Kudos::getAmount) + .reduce(0L, (prev, next) -> prev + next); if (talent.getId().equals(talentProof.getTalent().getId())) { Map kudosFromSponsor = talentProof.getKudos().stream() - .collect(Collectors.toMap( - Kudos::getAmount, - proof -> proof.getSponsor() != null - ? sponsorMapper.toDto( - proof.getSponsor()) - : SponsorDTO.builder().build(), - (prev, next) -> next, - HashMap::new - )); + .collect(Collectors.toMap( + Kudos::getAmount, + proof -> proof.getSponsor() != null + ? sponsorMapper.toDto( + proof.getSponsor()) + : SponsorDTO.builder().build(), + (prev, next) -> next, + HashMap::new + )); return KudosAmountWithSponsor.builder() - .allKudosOnProof(countOfAllKudos) - .kudosFromSponsor(kudosFromSponsor) - .build(); + .allKudosOnProof(countOfAllKudos) + .kudosFromSponsor(kudosFromSponsor) + .build(); } else { return KudosAmountWithSponsor.builder() - .allKudosOnProof(countOfAllKudos) - .kudosFromSponsor(null).build(); + .allKudosOnProof(countOfAllKudos) + .kudosFromSponsor(null).build(); } } } \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/service/TalentProofService.java b/src/main/java/com/provedcode/talent/service/TalentProofService.java index bbd8434..e429765 100644 --- a/src/main/java/com/provedcode/talent/service/TalentProofService.java +++ b/src/main/java/com/provedcode/talent/service/TalentProofService.java @@ -65,7 +65,7 @@ public TalentProof getTalentProof(long proofId, Authentication authentication) { () -> new ResponseStatusException(NOT_FOUND, "user with this token not found")); if (talentProof.getTalent().getId().equals(userInfo.getTalent().getId()) || - talentProof.getStatus().equals(ProofStatus.PUBLISHED)) { + talentProof.getStatus().equals(ProofStatus.PUBLISHED)) { return talentProof; } else { throw new ResponseStatusException(FORBIDDEN); @@ -76,16 +76,14 @@ public TalentProof getTalentProof(long proofId, Authentication authentication) { public FullProofDTO getTalentProofs(Long talentId, Integer page, Integer size, String direction, Authentication authentication, String... sortProperties) { Talent talent = talentRepository.findById(talentId) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, - "Talent with id = %d not found".formatted( - talentId))); - UserInfo userInfo = userInfoRepository.findById(talentId) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, - "User with id = %d not found".formatted( - talentId))); + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, + "Talent with id = %d not found".formatted( + talentId))); + UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); Page proofs; PageRequest pageRequest = PageRequest.of(page, size, Sort.Direction.valueOf(direction.toUpperCase()), - sortProperties + sortProperties ); if (!userInfo.getLogin().equals(authentication.getName())) { proofs = talentProofRepository.findByTalentIdAndStatus(talentId, ProofStatus.PUBLISHED, pageRequest); @@ -93,19 +91,19 @@ public FullProofDTO getTalentProofs(Long talentId, Integer page, Integer size, S proofs = talentProofRepository.findByTalentId(talentId, pageRequest); } return FullProofDTO.builder() - .id(talent.getId()) - .image(talent.getImage()) - .firstName(talent.getFirstName()) - .lastName(talent.getLastName()) - .specialization(talent.getSpecialization()) - .proofs(proofs.map(i -> ProofDTO.builder() - .id(i.getId()) - .created(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss") - .format(i.getCreated())) - .link(i.getLink()) - .text(i.getText()) - .status(i.getStatus()).build())) - .build(); + .id(talent.getId()) + .image(talent.getImage()) + .firstName(talent.getFirstName()) + .lastName(talent.getLastName()) + .specialization(talent.getSpecialization()) + .proofs(proofs.map(i -> ProofDTO.builder() + .id(i.getId()) + .created(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss") + .format(i.getCreated())) + .link(i.getLink()) + .text(i.getText()) + .status(i.getStatus()).build())) + .build(); } public ResponseEntity addProof(AddProof addProof, long talentId, Authentication authentication) { @@ -115,12 +113,12 @@ public ResponseEntity addProof(AddProof addProof, long talentId, Authenticati validateTalentForCompliance.userVerification(talent, userInfo, talentId); TalentProof talentProof = TalentProof.builder() - .talent(talent.get()) - .link(addProof.link()) - .text(addProof.text()) - .status(ProofStatus.DRAFT) - .created(LocalDateTime.now()) - .build(); + .talent(talent.get()) + .link(addProof.link()) + .text(addProof.text()) + .status(ProofStatus.DRAFT) + .created(LocalDateTime.now()) + .build(); talentProofRepository.save(talentProof); URI location = ServletUriComponentsBuilder @@ -146,7 +144,7 @@ public TalentProof editTalentProof(long talentId, long proofId, ProofDTO proof, throw new ResponseStatusException(FORBIDDEN, "you cannot change proofs status to DRAFT"); if (oldProofStatus == ProofStatus.DRAFT && proof.status() == ProofStatus.HIDDEN) throw new ResponseStatusException(FORBIDDEN, - "you cannot change proofs status from DRAFT to HIDDEN, it should be PUBLISHED"); + "you cannot change proofs status from DRAFT to HIDDEN, it should be PUBLISHED"); if (proof.link() == null && proof.text() == null) { oldProof.setStatus(proof.status()); From 0382ddc62195c282fe28e30ad4d7ac6f68a025e7 Mon Sep 17 00:00:00 2001 From: Denis Boyko Date: Sat, 29 Apr 2023 22:00:01 +0300 Subject: [PATCH 12/15] fix !userInfo.getTalent().getId().equals(talentId) --- .../java/com/provedcode/talent/service/TalentProofService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/provedcode/talent/service/TalentProofService.java b/src/main/java/com/provedcode/talent/service/TalentProofService.java index e429765..3880350 100644 --- a/src/main/java/com/provedcode/talent/service/TalentProofService.java +++ b/src/main/java/com/provedcode/talent/service/TalentProofService.java @@ -85,7 +85,7 @@ public FullProofDTO getTalentProofs(Long talentId, Integer page, Integer size, S PageRequest pageRequest = PageRequest.of(page, size, Sort.Direction.valueOf(direction.toUpperCase()), sortProperties ); - if (!userInfo.getLogin().equals(authentication.getName())) { + if (!userInfo.getTalent().getId().equals(talentId)) { proofs = talentProofRepository.findByTalentIdAndStatus(talentId, ProofStatus.PUBLISHED, pageRequest); } else { proofs = talentProofRepository.findByTalentId(talentId, pageRequest); From ae08a0cf257542c5c3070cd4238ab37749ca075a Mon Sep 17 00:00:00 2001 From: Maslyna Date: Mon, 1 May 2023 19:09:23 +0200 Subject: [PATCH 13/15] Doc update --- .../aws/controller/AWSS3BucketController.java | 6 +++ .../com/provedcode/aws/service/S3Service.java | 8 ++-- .../handlers/AwsS3ExceptionHandler.java | 17 ++++++++ .../com/provedcode/handlers/dto/ErrorDTO.java | 7 ++++ .../aws/GetAllAWSBucketFilesDevApiDoc.java | 34 +++++++++++++++ .../controller/aws/GetFileInfoDevApiDoc.java | 29 +++++++++++++ .../aws/PostSetNewUserImageApiDoc.java | 42 +++++++++++++++++++ 7 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/provedcode/handlers/AwsS3ExceptionHandler.java create mode 100644 src/main/java/com/provedcode/handlers/dto/ErrorDTO.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetAllAWSBucketFilesDevApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetFileInfoDevApiDoc.java create mode 100644 src/main/java/com/provedcode/util/annotations/doc/controller/aws/PostSetNewUserImageApiDoc.java diff --git a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java index ae9ac4b..3a49d63 100644 --- a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java +++ b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java @@ -1,6 +1,9 @@ package com.provedcode.aws.controller; import com.provedcode.aws.service.FileService; +import com.provedcode.util.annotations.doc.controller.aws.GetAllAWSBucketFilesDevApiDoc; +import com.provedcode.util.annotations.doc.controller.aws.GetFileInfoDevApiDoc; +import com.provedcode.util.annotations.doc.controller.aws.PostSetNewUserImageApiDoc; import lombok.AllArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; @@ -16,6 +19,7 @@ public class AWSS3BucketController { FileService fileService; + @PostSetNewUserImageApiDoc @PreAuthorize("hasRole('TALENT')") @PostMapping("/image/upload") public void setNewUserImage(@RequestParam("file") MultipartFile file, @@ -23,12 +27,14 @@ public void setNewUserImage(@RequestParam("file") MultipartFile file, fileService.setNewUserImage(file, authentication); } + @GetFileInfoDevApiDoc @PreAuthorize("hasRole('TALENT')") @GetMapping("/files") List getAllFiles() { return fileService.listAllFiles(); } + @GetAllAWSBucketFilesDevApiDoc @PreAuthorize("hasRole('TALENT')") @PostMapping("/aws/test") String testTypeOfFile(@RequestParam("file") MultipartFile file, diff --git a/src/main/java/com/provedcode/aws/service/S3Service.java b/src/main/java/com/provedcode/aws/service/S3Service.java index b7d48b1..439ee94 100644 --- a/src/main/java/com/provedcode/aws/service/S3Service.java +++ b/src/main/java/com/provedcode/aws/service/S3Service.java @@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.server.ResponseStatusException; @@ -28,6 +29,7 @@ @Service @AllArgsConstructor @Slf4j +@Transactional public class S3Service implements FileService { AWSProperties awsProperties; AmazonS3 s3; @@ -73,10 +75,10 @@ public List listAllFiles() { @Override public void setNewUserImage(MultipartFile file, Authentication authentication) { if (file.isEmpty()) { - throw new ResponseStatusException(NOT_IMPLEMENTED, "file must be not empty, actual file-size: %s".formatted(file.getSize())); + throw new ResponseStatusException(BAD_REQUEST, "file must be not empty, actual file-size: %s".formatted(file.getSize())); } if (photoService.isFileImage(file)) { - throw new ResponseStatusException(NOT_IMPLEMENTED, "not supported type: %s".formatted(file.getContentType())); + throw new ResponseStatusException(BAD_REQUEST, "not supported type: %s".formatted(file.getContentType())); } UserInfo user = userInfoRepository.findByLogin(authentication.getName()) .orElseThrow(() -> new ResponseStatusException(NOT_FOUND, "user with login = {%s} not found".formatted(authentication.getName()))); @@ -100,7 +102,7 @@ public void setNewUserImage(MultipartFile file, Authentication authentication) { talentRepository.save(user.getTalent()); } catch (Exception e) { - throw new ResponseStatusException(NOT_IMPLEMENTED, "problems with connection to aws s3"); + throw new ResponseStatusException(SERVICE_UNAVAILABLE, "problems with connection to aws s3"); } } diff --git a/src/main/java/com/provedcode/handlers/AwsS3ExceptionHandler.java b/src/main/java/com/provedcode/handlers/AwsS3ExceptionHandler.java new file mode 100644 index 0000000..a77af66 --- /dev/null +++ b/src/main/java/com/provedcode/handlers/AwsS3ExceptionHandler.java @@ -0,0 +1,17 @@ +package com.provedcode.handlers; + +import com.provedcode.handlers.dto.ErrorDTO; +import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +import static org.springframework.http.HttpStatus.BAD_REQUEST; + +@ControllerAdvice +public class AwsS3ExceptionHandler { + @ExceptionHandler(FileSizeLimitExceededException.class) + public ResponseEntity fileSizeLimitExceededExceptionHandler(FileSizeLimitExceededException e) { + return ResponseEntity.status(BAD_REQUEST).body(new ErrorDTO("file size is too large")); + } +} diff --git a/src/main/java/com/provedcode/handlers/dto/ErrorDTO.java b/src/main/java/com/provedcode/handlers/dto/ErrorDTO.java new file mode 100644 index 0000000..8269a4c --- /dev/null +++ b/src/main/java/com/provedcode/handlers/dto/ErrorDTO.java @@ -0,0 +1,7 @@ +package com.provedcode.handlers.dto; + +import lombok.Builder; + +@Builder +public record ErrorDTO (String message) { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetAllAWSBucketFilesDevApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetAllAWSBucketFilesDevApiDoc.java new file mode 100644 index 0000000..7e45042 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetAllAWSBucketFilesDevApiDoc.java @@ -0,0 +1,34 @@ +package com.provedcode.util.annotations.doc.controller.aws; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Dev`s endpoint, uses to get names of all files at AWS S3") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS"), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "503", + description = "SERVICE UNAVAILABLE (connection to AWS S3 failed)", + content = @Content + ) +}) +public @interface GetAllAWSBucketFilesDevApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetFileInfoDevApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetFileInfoDevApiDoc.java new file mode 100644 index 0000000..a11c8c0 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/aws/GetFileInfoDevApiDoc.java @@ -0,0 +1,29 @@ +package com.provedcode.util.annotations.doc.controller.aws; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Dev`s endpoint, uses to get information about file") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS"), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content) +}) +public @interface GetFileInfoDevApiDoc { +} diff --git a/src/main/java/com/provedcode/util/annotations/doc/controller/aws/PostSetNewUserImageApiDoc.java b/src/main/java/com/provedcode/util/annotations/doc/controller/aws/PostSetNewUserImageApiDoc.java new file mode 100644 index 0000000..562e1f1 --- /dev/null +++ b/src/main/java/com/provedcode/util/annotations/doc/controller/aws/PostSetNewUserImageApiDoc.java @@ -0,0 +1,42 @@ +package com.provedcode.util.annotations.doc.controller.aws; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Operation(summary = "Set new Talent`s image") +@ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "SUCCESS"), + @ApiResponse( + responseCode = "400", + description = "BAD REQUEST", + content = @Content), + @ApiResponse( + responseCode = "401", + description = "UNAUTHORIZED", + content = @Content), + @ApiResponse( + responseCode = "403", + description = "FORBIDDEN", + content = @Content), + @ApiResponse( + responseCode = "404", + description = "NOT FOUND", + content = @Content), + @ApiResponse( + responseCode = "503", + description = "SERVICE UNAVAILABLE (connection to AWS S3 failed)", + content = @Content + ) +}) +public @interface PostSetNewUserImageApiDoc { +} From 1a1f0278211edfa74a71ff2a3643bb0ea73e9016 Mon Sep 17 00:00:00 2001 From: Maslyna Date: Tue, 2 May 2023 02:20:17 +0200 Subject: [PATCH 14/15] New test endpoint for images --- .../aws/controller/AWSS3BucketController.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java index 7d8e4bb..70a2d6f 100644 --- a/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java +++ b/src/main/java/com/provedcode/aws/controller/AWSS3BucketController.java @@ -1,6 +1,10 @@ package com.provedcode.aws.controller; +import com.amazonaws.HttpMethod; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest; import com.provedcode.aws.service.FileService; +import com.provedcode.config.AWSProperties; import com.provedcode.util.annotations.doc.controller.aws.GetAllAWSBucketFilesDevApiDoc; import com.provedcode.util.annotations.doc.controller.aws.GetFileInfoDevApiDoc; import com.provedcode.util.annotations.doc.controller.aws.PostSetNewUserImageApiDoc; @@ -10,7 +14,10 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import java.net.URL; +import java.time.Instant; import java.util.Arrays; +import java.util.Date; import java.util.List; @RestController @@ -18,6 +25,8 @@ @RequestMapping("/api/v3/talents") public class AWSS3BucketController { FileService fileService; + AWSProperties awsProperties; + AmazonS3 amazonS3; @PostSetNewUserImageApiDoc @PreAuthorize("hasRole('TALENT')") @@ -36,10 +45,22 @@ List getAllFiles() { @GetAllAWSBucketFilesDevApiDoc @PreAuthorize("hasRole('TALENT')") - @PostMapping("/aws/test") + @PostMapping("/aws/test-of-filetype") String testTypeOfFile(@RequestParam("file") MultipartFile file, Authentication authentication) { return Arrays.stream(file.getContentType().split("/")).toList().get(1) + " " + file.getOriginalFilename() + " " + file.getName() + " " + file.getResource(); } + + @GetMapping("/aws/test") + URL getURL() { + GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(awsProperties.bucket(), "MykhailoOrdyntsev@gmail.com/image.jpeg") + .withMethod(HttpMethod.GET); + Instant expiration = Instant.now().plusMillis(1000L * 60 * 60 * 24 * 7); + + urlRequest.setExpiration(Date.from(expiration)); + URL url = amazonS3.generatePresignedUrl(urlRequest); + return url; + } + } From c8402321792fb3f9dacb0bc33d6ec60971eb25bc Mon Sep 17 00:00:00 2001 From: Maslyna Date: Wed, 3 May 2023 12:51:28 +0200 Subject: [PATCH 15/15] DB EDIT: SIZE UP --- .../resources/db/changelog/changeset/V2/schema-V2.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/db/changelog/changeset/V2/schema-V2.sql b/src/main/resources/db/changelog/changeset/V2/schema-V2.sql index 799d7e5..19ba151 100644 --- a/src/main/resources/db/changelog/changeset/V2/schema-V2.sql +++ b/src/main/resources/db/changelog/changeset/V2/schema-V2.sql @@ -38,15 +38,15 @@ CREATE TABLE talent_description ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, talent_id BIGINT NOT NULL, - bio VARCHAR(255), - addition_info VARCHAR(255), + bio VARCHAR(2000), + addition_info VARCHAR(500), CONSTRAINT pk_talent_description PRIMARY KEY (id) ); CREATE TABLE talent_link ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, talent_id BIGINT NOT NULL, - link VARCHAR(255), + link VARCHAR(500), CONSTRAINT pk_talent_link PRIMARY KEY (id) ); CREATE TABLE talent_proofs @@ -54,7 +54,7 @@ CREATE TABLE talent_proofs id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, talent_id BIGINT NOT NULL, link VARCHAR(100), - text VARCHAR(255), + text VARCHAR(1000), status VARCHAR(20) NOT NULL, created TIMESTAMP, CONSTRAINT pk_talent_proofs PRIMARY KEY (id)