> findAllPostType() {
+ return ResponseEntity
+ .status(HttpStatus.OK)
+ .body(postTypeService.findAll());
+ }
+
+ /**
+ * Gets post by its id.
+ *
+ * Checks if found post exists, if no - returns HttpStatus 'NOT FOUND'.
+ *
+ * @param postId id of post that we want to get
+ * @return found post and HttpStatus 'OK'
+ */
+ @GetMapping(POST_GET_POST_BY_ID)
+ @ApiOperation(value = "Get post by Id, as a path variable.")
+ public ResponseEntity getPostById(@PathVariable("postId") Integer postId) {
+ PostDTO postDTO = postService.findPostById(postId);
+ return ResponseEntity
+ .status((postDTO != null) ? HttpStatus.OK : HttpStatus.NOT_FOUND)
+ .body(postDTO);
+ }
+
+ /**
+ * Gets all posts by directions by post types and by origins.
+ *
+ * If something went wrong returns HttpStatus 'NO CONTENT'.
+ *
+ * @param pageable interface for pagination information
+ * @param directions direction's ids by which the search is performed
+ * @param types the type's ids by which the search is performed
+ * @param origins the origin's ids by which the search is performed
+ * @return page with all posts filtered by directions, by post types and by origins and HttpStatus 'OK'
+ */
+ @GetMapping(POST_ALL_POSTS)
+ @ApiOperation(value = "Get posts, filtered by directions, post types and origins.")
+ public ResponseEntity> getAllPostsByDirectionsByPostTypesAndByOrigins(
+ @PageableDefault Pageable pageable,
+ @ApiParam(value = "Multiple comma-separated direction IDs, e.g. ?directions=1,2,3,4", type = "string")
+ @RequestParam(required = false) Set directions,
+ @ApiParam(value = "Multiple comma-separated post types IDs, e.g. ?post types=1,2,3,4", type = "string")
+ @RequestParam(required = false) Set types,
+ @ApiParam(value = "Multiple comma-separated origins IDs, e.g. ?origins=1,2,3,4...", type = "string")
+ @RequestParam(required = false) Set origins) {
+ try {
+ return ResponseEntity
+ .status(HttpStatus.OK)
+ .body(postService
+ .findAllByDirectionsAndByPostTypesAndByOrigins(directions, types, origins, pageable));
+ } catch (EntityNotFoundException e) {
+ return ResponseEntity
+ .status(HttpStatus.NO_CONTENT)
+ .body(null);
+ }
+ }
+
+ /**
+ * Deletes post by id (marks post as archived).
+ *
+ * Checks if user has authority to delete found post.
+ * If something went wrong returns unsuccessful response message.
+ *
+ * @param userPrincipal authorized user data
+ * @param postId the post id
+ * @return marks found post as archived and prints that post was successfully deleted
+ */
+ @DeleteMapping(POST_GET_POST_BY_ID)
+ @PreAuthorize("hasAnyAuthority('DELETE_POST', 'DELETE_OWN_POST')")
+ @ApiOperation(value = "Delete post by Id, as a path variable.",
+ authorizations = {@Authorization(value = "Authorization")})
+ public ResponseEntity archivePostById(
+ @AuthenticationPrincipal UserPrincipal userPrincipal,
+ @PathVariable("postId") Integer postId
+ ) {
+ ApiResponseMessage apiResponseMessage;
+ try {
+ apiResponseMessage = ApiResponseMessage.builder()
+ .success(postService.archivePostById(userPrincipal, postId))
+ .message(String.format("post %s deleted successfully", postId))
+ .build();
+ } catch (EntityNotFoundException e) {
+ apiResponseMessage = ApiResponseMessage.builder()
+ .success(false)
+ .message(e.getMessage())
+ .build();
+ }
+ return ResponseEntity.ok().body(apiResponseMessage);
+ }
+
+ /**
+ * Updates post by id.
+ *
+ * Checks if user has authority to update found post.
+ * If something went wrong returns unsuccessful response message.
+ *
+ * @param userPrincipal authorized user data
+ * @param postSaveFromUserDTO DTO of updated post
+ * @return updates post in db and prints message 'post updated successfully'
+ */
+ @PutMapping()
+ @PreAuthorize("hasAnyAuthority('UPDATE_POST', 'UPDATE_OWN_POST')")
+ @ApiOperation(value = "Update post by Id, as a path variable.",
+ authorizations = {@Authorization(value = "Authorization")})
+ public ResponseEntity updatePostById(
+ @AuthenticationPrincipal UserPrincipal userPrincipal,
+ @Valid @RequestBody PostSaveFromUserDTO postSaveFromUserDTO) {
+
+ ApiResponseMessage apiResponseMessage;
+ try {
+ apiResponseMessage = ApiResponseMessage.builder()
+ .success(postService.updatePostById(userPrincipal, postSaveFromUserDTO))
+ .message(String.format("post %s updated successfully", postSaveFromUserDTO.getId()))
+ .build();
+ } catch (EntityNotFoundException | ForbiddenPermissionsException e) {
+ apiResponseMessage = ApiResponseMessage.builder()
+ .success(false)
+ .message(e.getMessage())
+ .build();
+ }
+ return ResponseEntity.ok().body(apiResponseMessage);
+ }
+
+ /**
+ * Gets posts filtered by author id and directions.
+ *
+ * If something went wrong returns 'NOT FOUND' HttpStatus.
+ *
+ * @param pageable interface for pagination information
+ * @param authorId the author id
+ * @param directions directions ids
+ * @return found posts filtered by author id and directions and HttpStatus 'OK'
+ */
+ @GetMapping(POST_GET_POST_BY_AUTHOR_ID_AND_DIRECTIONS)
+ @ApiOperation(value = "Get post by author Id, as a path variable, and directions.")
+ public ResponseEntity> getPostsByAuthorIdAndDirections(
+ @PageableDefault(size = 12) Pageable pageable, @NotNull Integer authorId,
+ @ApiParam(value = "Multiple comma-separated direction IDs, e.g. ?directions=1,2,3,4", type = "string")
+ @RequestParam(required = false) @NotNull Set directions) {
+ Page posts = postService
+ .findPostsByAuthorIdAndDirections(pageable, authorId, directions);
+ return ResponseEntity
+ .status((posts.getTotalElements() != 0) ? HttpStatus.OK : HttpStatus.NOT_FOUND)
+ .body(posts);
+ }
+
+ /**
+ * Gets latest posts by post types and origin with names of fields
+ *
+ * @param pageable interface for pagination information
+ * @return found posts filtered by Post Types and origins with names of main page fields and HttpStatus 'OK'
+ */
+ @GetMapping(POST_LATEST_BY_POST_TYPES_AND_ORIGINS)
+ @ApiPageable
+ @ApiOperation(value = "Find latest published posts by post types and origins")
+ public ResponseEntity> findLatestByPostTypesAndOrigins(
+ @PageableDefault(size = 16) Pageable pageable) {
+ Page posts = postService.findLatestByPostTypesAndOrigins(pageable);
+ return ResponseEntity
+ .status((posts.getTotalElements() != 0) ? HttpStatus.OK : HttpStatus.NOT_FOUND)
+ .body(posts);
+ }
+
+ @ApiPageable
+ @ApiOperation(value = "Get Post View Count")
+ @GetMapping(POST_VIEW_COUNT)
+ public Integer getPostViewCount(@RequestParam String url) {
+ return postService.getPostViewCount(url);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/controller/PostTypesController.java b/src/main/java/com/softserveinc/dokazovi/controller/PostTypesController.java
new file mode 100644
index 00000000..53370139
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/controller/PostTypesController.java
@@ -0,0 +1,42 @@
+package com.softserveinc.dokazovi.controller;
+
+import com.softserveinc.dokazovi.dto.post.PostTypeDTO;
+import com.softserveinc.dokazovi.service.PostTypeService;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+import static com.softserveinc.dokazovi.controller.EndPoints.POST_TYPES;
+import static com.softserveinc.dokazovi.controller.EndPoints.POST_TYPES_ALL_TYPES_BY_USER;
+
+/**
+ * Class PostTypesController responsible for handling requests for post types
+ */
+@RestController
+@RequestMapping(POST_TYPES)
+@RequiredArgsConstructor
+public class PostTypesController {
+
+ private final PostTypeService postTypeService;
+
+ /**
+ * getAllPostTypesByUserId method returns all post types of posts published by certain user
+ *
+ * @param userId Id of user whose materials we want to receive
+ * @return 'OK' HttpStatus and method call from service
+ */
+ @GetMapping(POST_TYPES_ALL_TYPES_BY_USER)
+ @ApiOperation(value = "Get all types of materials by userId")
+ public ResponseEntity> getAllPostTypesByUserId(@PathVariable("userId") Integer userId) {
+ return ResponseEntity
+ .status(HttpStatus.OK)
+ .body(postTypeService.findAllPostTypesByUserId(userId));
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/controller/RegionController.java b/src/main/java/com/softserveinc/dokazovi/controller/RegionController.java
new file mode 100644
index 00000000..b02bed85
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/controller/RegionController.java
@@ -0,0 +1,39 @@
+package com.softserveinc.dokazovi.controller;
+
+import com.softserveinc.dokazovi.dto.region.RegionDTO;
+import com.softserveinc.dokazovi.service.RegionService;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+import static com.softserveinc.dokazovi.controller.EndPoints.REGION;
+
+/**
+ * The Class RegionController responsible for handling requests for regions
+ */
+@RestController
+@RequestMapping(REGION)
+@RequiredArgsConstructor
+public class RegionController {
+
+ private final RegionService regionService;
+
+ /**
+ * Gets all regions method returns all regions from db.
+ *
+ * @return all regions and HttpStatus 'OK'
+ */
+ @GetMapping
+ @ApiOperation(value = "Get all regions")
+ public ResponseEntity> getAllRegions() {
+ return ResponseEntity
+ .status(HttpStatus.OK)
+ .body(regionService.findAllRegions());
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/controller/TagController.java b/src/main/java/com/softserveinc/dokazovi/controller/TagController.java
new file mode 100644
index 00000000..42e72ed7
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/controller/TagController.java
@@ -0,0 +1,68 @@
+package com.softserveinc.dokazovi.controller;
+
+import com.softserveinc.dokazovi.dto.tag.TagDTO;
+import com.softserveinc.dokazovi.dto.tag.TagSaveDTO;
+import com.softserveinc.dokazovi.service.TagService;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.Authorization;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+
+import static com.softserveinc.dokazovi.controller.EndPoints.TAG;
+import static com.softserveinc.dokazovi.controller.EndPoints.TAG_FIND_BY_VALUE;
+
+/**
+ * The Class TagController responsible for handling requests for regions
+ */
+@RestController
+@RequestMapping(TAG)
+@RequiredArgsConstructor
+public class TagController {
+
+ private final TagService tagService;
+
+ /**
+ * Find tag by its name (or by several letters it contains).
+ *
+ * @param value the name of tag
+ * @param limit the limit of results amount
+ * @return list with limited amount of found tags and 'OK' http status
+ */
+ @GetMapping(TAG_FIND_BY_VALUE)
+ public ResponseEntity> findByValue(
+ @RequestParam String value,
+ @RequestParam(defaultValue = "5") Integer limit) {
+ return ResponseEntity
+ .status(HttpStatus.OK)
+ .body(tagService.findTagsByValue(value, limit));
+ }
+
+ /**
+ * Saves (creates) new tag.
+ *
+ * Checks if user has authority to save new tag.
+ *
+ * @param tagSaveDTO DTO that contains new tag info.
+ * @return saved tag and 'CREATED' http status.
+ */
+ @PostMapping
+ @PreAuthorize("hasAuthority('SAVE_TAG')")
+ @ApiOperation(value = "Save tag",
+ authorizations = {@Authorization(value = "Authorization")})
+ public ResponseEntity saveTag(@Valid @RequestBody TagSaveDTO tagSaveDTO) {
+ return ResponseEntity
+ .status(HttpStatus.CREATED)
+ .body(tagService.save(tagSaveDTO));
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/controller/UserController.java b/src/main/java/com/softserveinc/dokazovi/controller/UserController.java
new file mode 100644
index 00000000..5ea223c6
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/controller/UserController.java
@@ -0,0 +1,117 @@
+package com.softserveinc.dokazovi.controller;
+
+import com.softserveinc.dokazovi.annotations.ApiPageable;
+import com.softserveinc.dokazovi.dto.user.UserDTO;
+import com.softserveinc.dokazovi.pojo.UserSearchCriteria;
+import com.softserveinc.dokazovi.security.UserPrincipal;
+import com.softserveinc.dokazovi.service.UserService;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.Authorization;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.web.PageableDefault;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Set;
+
+import static com.softserveinc.dokazovi.controller.EndPoints.USER;
+import static com.softserveinc.dokazovi.controller.EndPoints.USER_ALL_EXPERTS;
+import static com.softserveinc.dokazovi.controller.EndPoints.USER_GET_CURRENT_USER;
+import static com.softserveinc.dokazovi.controller.EndPoints.USER_GET_USER_BY_ID;
+import static com.softserveinc.dokazovi.controller.EndPoints.USER_RANDOM_EXPERTS;
+
+/**
+ * The User controller is responsible for handling requests for users.
+ */
+
+@RestController
+@RequestMapping(USER)
+@RequiredArgsConstructor
+public class UserController {
+
+ private final UserService userService;
+
+ /**
+ * Gets preview of random experts,
+ * filtered by directions.
+ * Default 12 max per page.
+ *
+ * @param pageable interface for pagination information
+ * @param directions direction id
+ * @return page with found posts and 'OK' httpStatus
+ */
+ @GetMapping(USER_RANDOM_EXPERTS)
+ @ApiPageable
+ @ApiOperation(value = "Get preview of random experts, filtered by directions. Default 12 max per page.")
+ public ResponseEntity> getRandomExpertPreview(
+ @PageableDefault(size = 12) Pageable pageable,
+ @ApiParam(value = "Multiple comma-separated direction IDs, e.g. ?directions=1,2,3,4", type = "string")
+ @RequestParam(required = false) Set directions) {
+ return ResponseEntity
+ .status(HttpStatus.OK)
+ .body(userService.findRandomExpertPreview(directions, pageable));
+ }
+
+ /**
+ * Gets all experts depending on the parameters coming through the request,
+ * ordered by relevance.
+ * Default 6 max per page.
+ *
+ * @param pageable interface for pagination information
+ * @param userSearchCriteria binds request parameters to an object
+ * @return page with found experts and 'OK' httpStatus
+ */
+ @GetMapping(USER_ALL_EXPERTS)
+ @ApiPageable
+ @ApiOperation(value = "Get experts ordered by name, then filtered by directions and/or regions."
+ + " Default 6 per page.")
+ public ResponseEntity> getAllExpertsByDirectionsAndByRegionsOrderedByRelevance(
+ @PageableDefault(size = 6) Pageable pageable, UserSearchCriteria userSearchCriteria) {
+ return ResponseEntity
+ .status(HttpStatus.OK)
+ .body(userService.findAllExperts(userSearchCriteria, pageable));
+ }
+
+ /**
+ * Gets the user by its id.
+ * Checks if the user exists. If no - returns HttpStatus 'NOT FOUND'.
+ *
+ * @param userId id of user that we want to get
+ * @return found user and HttpStatus 'OK'
+ */
+ @GetMapping(USER_GET_USER_BY_ID)
+ @ApiOperation(value = "Get expert by Id, as a path variable.")
+ public ResponseEntity getExpertById(@PathVariable("userId") Integer userId) {
+ UserDTO userDTO = userService.findExpertById(userId);
+ return ResponseEntity
+ .status((userDTO != null) ? HttpStatus.OK : HttpStatus.NOT_FOUND)
+ .body(userDTO);
+ }
+
+ /**
+ * Gets current user.
+ * Checks if userPrincipal exists via findExpertById method.
+ * If no - returns HttpStatus 'NOT FOUND'.
+ *
+ * @param userPrincipal id of user that we want to get
+ * @return found user and HttpStatus 'OK'
+ */
+ @GetMapping(USER_GET_CURRENT_USER)
+ @ApiOperation(value = "Get current user",
+ authorizations = {@Authorization(value = "Authorization")})
+ public ResponseEntity getCurrentUser(@AuthenticationPrincipal UserPrincipal userPrincipal) {
+ UserDTO userDTO = userService.findExpertById(userPrincipal.getId());
+ return ResponseEntity
+ .status((userDTO != null) ? HttpStatus.OK : HttpStatus.NOT_FOUND)
+ .body(userDTO);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/controller/VersionController.java b/src/main/java/com/softserveinc/dokazovi/controller/VersionController.java
index 7ae19eb8..339cb2b4 100644
--- a/src/main/java/com/softserveinc/dokazovi/controller/VersionController.java
+++ b/src/main/java/com/softserveinc/dokazovi/controller/VersionController.java
@@ -1,26 +1,34 @@
package com.softserveinc.dokazovi.controller;
-import com.softserveinc.dokazovi.util.BuildVersion;
-import org.springframework.beans.factory.annotation.Autowired;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.info.BuildProperties;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+/**
+ * The Version controller responsible for handling requests about project build version.
+ */
@RestController
-@RequestMapping(EndPoints.WEB_API)
+@RequestMapping(EndPoints.VERSION)
+@RequiredArgsConstructor
public class VersionController {
- private final BuildVersion buildVersion;
+ private final BuildProperties buildProperties;
- @Autowired
- public VersionController(BuildVersion buildVersion) {
- this.buildVersion = buildVersion;
- }
-
- @GetMapping(EndPoints.VERSION)
- public ResponseEntity getBuildVersion() {
- return new ResponseEntity<>(buildVersion, HttpStatus.OK);
+ /**
+ * Returns all build-related information of project version.
+ *
+ * @return build properties and 'OK' HttpStatus
+ */
+ @GetMapping
+ @ApiOperation(value = "Get build version")
+ public ResponseEntity getBuildVersion() {
+ return ResponseEntity
+ .status(HttpStatus.OK)
+ .body(buildProperties);
}
}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/direction/DirectionDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/direction/DirectionDTO.java
new file mode 100644
index 00000000..d52e4b20
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/direction/DirectionDTO.java
@@ -0,0 +1,36 @@
+package com.softserveinc.dokazovi.dto.direction;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * The DirectionDTO is responsible for passing
+ * direction data from server to the client.
+ */
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DirectionDTO {
+
+ @NotNull(message = "Direction id are required")
+ private Integer id;
+
+ @NotBlank(message = "Direction name cannot be empty")
+ private String name;
+
+ @NotBlank(message = "Direction label cannot be empty")
+ private String label;
+
+ private String color;
+
+ private Boolean hasDoctors;
+
+ private Boolean hasPosts;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/direction/DirectionDTOForSavingPost.java b/src/main/java/com/softserveinc/dokazovi/dto/direction/DirectionDTOForSavingPost.java
new file mode 100644
index 00000000..3328dceb
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/direction/DirectionDTOForSavingPost.java
@@ -0,0 +1,22 @@
+package com.softserveinc.dokazovi.dto.direction;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * The DirectionDTOForSavingPost is responsible for passing
+ * direction saving post data from the server to the client.
+ */
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DirectionDTOForSavingPost {
+ @NotNull(message = "Direction id are required")
+ private Integer id;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/origin/OriginDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/origin/OriginDTO.java
new file mode 100644
index 00000000..72eb0d17
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/origin/OriginDTO.java
@@ -0,0 +1,28 @@
+package com.softserveinc.dokazovi.dto.origin;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * The OriginDTO is responsible for passing origin data from server to the client.
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OriginDTO {
+
+ @NotNull(message = "Origin id are required")
+ private Integer id;
+
+ @NotBlank(message = "Origin name cannot be empty")
+ private String name;
+
+ @NotBlank(message = "Origin parameter cannot be empty")
+ private String parameter;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/origin/OriginDTOForSavingPost.java b/src/main/java/com/softserveinc/dokazovi/dto/origin/OriginDTOForSavingPost.java
new file mode 100644
index 00000000..fc9d15a3
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/origin/OriginDTOForSavingPost.java
@@ -0,0 +1,21 @@
+package com.softserveinc.dokazovi.dto.origin;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * The OriginDTOForSavingPost is responsible for passing origin data for saving post
+ * from server to the client.
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class OriginDTOForSavingPost {
+ @NotNull(message = "Origin id are required")
+ private Integer id;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/payload/ApiResponseMessage.java b/src/main/java/com/softserveinc/dokazovi/dto/payload/ApiResponseMessage.java
new file mode 100644
index 00000000..7d0bf442
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/payload/ApiResponseMessage.java
@@ -0,0 +1,16 @@
+package com.softserveinc.dokazovi.dto.payload;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class ApiResponseMessage {
+ private boolean success;
+ private String message;
+
+ public ApiResponseMessage(boolean success, String message) {
+ this.success = success;
+ this.message = message;
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/payload/AuthResponse.java b/src/main/java/com/softserveinc/dokazovi/dto/payload/AuthResponse.java
new file mode 100644
index 00000000..232acc47
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/payload/AuthResponse.java
@@ -0,0 +1,13 @@
+package com.softserveinc.dokazovi.dto.payload;
+
+import lombok.Data;
+
+@Data
+public class AuthResponse {
+ private String accessToken;
+ private String tokenType = "Bearer";
+
+ public AuthResponse(String accessToken) {
+ this.accessToken = accessToken;
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/payload/LoginRequest.java b/src/main/java/com/softserveinc/dokazovi/dto/payload/LoginRequest.java
new file mode 100644
index 00000000..0dbd18be
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/payload/LoginRequest.java
@@ -0,0 +1,20 @@
+package com.softserveinc.dokazovi.dto.payload;
+
+import lombok.Data;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+
+@Data
+public class LoginRequest {
+
+ @NotBlank
+ @Email
+ private String email;
+
+ @NotBlank
+ @Size(min = 3, max = 20, message = "Password length must be from 4 to 16 symbols")
+ private String password;
+
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/payload/SignUpRequest.java b/src/main/java/com/softserveinc/dokazovi/dto/payload/SignUpRequest.java
new file mode 100644
index 00000000..d3a45e5f
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/payload/SignUpRequest.java
@@ -0,0 +1,22 @@
+package com.softserveinc.dokazovi.dto.payload;
+
+import lombok.Data;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+
+@Data
+public class SignUpRequest {
+
+ @NotBlank
+ private String name;
+
+ @NotBlank
+ @Email
+ private String email;
+
+ @NotBlank
+ @Size(min = 3, max = 20, message = "Password length must be from 4 to 16 symbols")
+ private String password;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/post/PostDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/post/PostDTO.java
new file mode 100644
index 00000000..fc1d0f00
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/post/PostDTO.java
@@ -0,0 +1,39 @@
+package com.softserveinc.dokazovi.dto.post;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.softserveinc.dokazovi.dto.direction.DirectionDTO;
+import com.softserveinc.dokazovi.dto.origin.OriginDTO;
+import com.softserveinc.dokazovi.dto.tag.TagDTO;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.sql.Timestamp;
+import java.util.Set;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class PostDTO {
+
+ private Integer id;
+ private String title;
+ private String preview;
+ private String content;
+ private String videoUrl;
+ private String previewImageUrl;
+ private PostUserDTO author;
+ private Set directions;
+ private Set tags;
+ private PostTypeDTO type;
+ private Set origins;
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd.MM.yyyy")
+ private Timestamp createdAt;
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd.MM.yyyy")
+ private Timestamp modifiedAt;
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd.MM.yyyy")
+ private Timestamp publishedAt;
+ private Integer importanceOrder;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/post/PostMainPageDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/post/PostMainPageDTO.java
new file mode 100644
index 00000000..48c185a1
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/post/PostMainPageDTO.java
@@ -0,0 +1,18 @@
+package com.softserveinc.dokazovi.dto.post;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Set;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class PostMainPageDTO {
+
+ private String fieldName;
+ private Set postDTOS;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/post/PostSaveFromUserDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/post/PostSaveFromUserDTO.java
new file mode 100644
index 00000000..833cf06f
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/post/PostSaveFromUserDTO.java
@@ -0,0 +1,50 @@
+package com.softserveinc.dokazovi.dto.post;
+
+import com.softserveinc.dokazovi.annotations.DirectionExists;
+import com.softserveinc.dokazovi.annotations.OriginExists;
+import com.softserveinc.dokazovi.annotations.PostTypeExists;
+import com.softserveinc.dokazovi.dto.direction.DirectionDTOForSavingPost;
+import com.softserveinc.dokazovi.dto.origin.OriginDTOForSavingPost;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.util.Set;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class PostSaveFromUserDTO {
+
+ private Integer id;
+
+ @NotNull(message = "Author id is required")
+ private Integer authorId;
+
+ private String title;
+
+ private String videoUrl;
+
+ private String previewImageUrl;
+
+ @NotBlank(message = "Preview field cannot be empty")
+ private String preview;
+
+ @NotBlank(message = "Content field cannot be empty")
+ private String content;
+
+ @NotNull(message = "PostType are required")
+ @PostTypeExists
+ private PostTypeIdOnlyDTO type;
+
+ @NotNull(message = "At least one topic are required")
+ @Size(min = 1, max = 3, message = "Number of chosen topics is from 1 to 3. ")
+ private Set<@DirectionExists DirectionDTOForSavingPost> directions;
+
+ private Set<@OriginExists OriginDTOForSavingPost> origins;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/post/PostTypeDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/post/PostTypeDTO.java
new file mode 100644
index 00000000..0e02b2ca
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/post/PostTypeDTO.java
@@ -0,0 +1,22 @@
+package com.softserveinc.dokazovi.dto.post;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class PostTypeDTO {
+
+ @NotNull(message = "PostType id are required")
+ private Integer id;
+
+ @NotBlank(message = "PostType name cannot be empty")
+ private String name;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/post/PostTypeIdOnlyDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/post/PostTypeIdOnlyDTO.java
new file mode 100644
index 00000000..227c87ac
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/post/PostTypeIdOnlyDTO.java
@@ -0,0 +1,19 @@
+package com.softserveinc.dokazovi.dto.post;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class PostTypeIdOnlyDTO {
+
+ @NotNull(message = "PostType id are required")
+ private Integer id;
+
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/post/PostUserDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/post/PostUserDTO.java
new file mode 100644
index 00000000..ebbabfe8
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/post/PostUserDTO.java
@@ -0,0 +1,16 @@
+package com.softserveinc.dokazovi.dto.post;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class PostUserDTO {
+
+ private Integer id;
+ private String firstName;
+ private String lastName;
+ private String avatar;
+ private String bio;
+ private PostUserInstitutionDTO mainInstitution;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/post/PostUserInstitutionCityDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/post/PostUserInstitutionCityDTO.java
new file mode 100644
index 00000000..e8a381b4
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/post/PostUserInstitutionCityDTO.java
@@ -0,0 +1,11 @@
+package com.softserveinc.dokazovi.dto.post;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class PostUserInstitutionCityDTO {
+ private Integer id;
+ private String name;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/post/PostUserInstitutionDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/post/PostUserInstitutionDTO.java
new file mode 100644
index 00000000..0a99d9ea
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/post/PostUserInstitutionDTO.java
@@ -0,0 +1,12 @@
+package com.softserveinc.dokazovi.dto.post;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class PostUserInstitutionDTO {
+ private Integer id;
+ private String name;
+ private PostUserInstitutionCityDTO city;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/region/RegionDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/region/RegionDTO.java
new file mode 100644
index 00000000..e59768f7
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/region/RegionDTO.java
@@ -0,0 +1,17 @@
+package com.softserveinc.dokazovi.dto.region;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * The Region DTO is responsible for passing region data from the server to the client.
+ */
+
+@Data
+@Builder
+public class RegionDTO {
+
+ private Integer id;
+ private String name;
+ private Boolean usersPresent;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/tag/TagDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/tag/TagDTO.java
new file mode 100644
index 00000000..82391d43
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/tag/TagDTO.java
@@ -0,0 +1,22 @@
+package com.softserveinc.dokazovi.dto.tag;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class TagDTO {
+
+ @NotNull(message = "Tag id are required")
+ private Integer id;
+
+ @NotBlank(message = "Tag cannot be empty")
+ private String tag;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/tag/TagSaveDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/tag/TagSaveDTO.java
new file mode 100644
index 00000000..df0626e6
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/tag/TagSaveDTO.java
@@ -0,0 +1,19 @@
+package com.softserveinc.dokazovi.dto.tag;
+
+import com.softserveinc.dokazovi.annotations.TagUnique;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class TagSaveDTO {
+ @TagUnique
+ @NotBlank(message = "Tag field cannot be empty")
+ private String tag;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/user/LatestUserPostDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/user/LatestUserPostDTO.java
new file mode 100644
index 00000000..9beae02b
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/user/LatestUserPostDTO.java
@@ -0,0 +1,18 @@
+package com.softserveinc.dokazovi.dto.user;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * The LatestUserPostDTO is responsible for passing latest user post data from server to the client.
+ */
+
+@Data
+@Builder
+public class LatestUserPostDTO {
+
+ private Integer id;
+
+ private String title;
+
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/user/UserDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/user/UserDTO.java
new file mode 100644
index 00000000..aa78c52c
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/user/UserDTO.java
@@ -0,0 +1,43 @@
+package com.softserveinc.dokazovi.dto.user;
+
+import com.softserveinc.dokazovi.dto.direction.DirectionDTO;
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.Set;
+
+/**
+ * The User DTO is responsible for passing user data from the server to the client.
+ */
+
+@Data
+@Builder
+public class UserDTO {
+
+ private Integer id;
+
+ private String firstName;
+
+ private String lastName;
+
+ private String email;
+
+ private String qualification;
+
+ private String phone;
+
+ private String avatar;
+
+ private String bio;
+
+ private String socialNetwork;
+
+ private Set directions;
+
+ private UserInstitutionDTO mainInstitution;
+
+ private Set institutions;
+
+ private LatestUserPostDTO lastAddedPost;
+
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/user/UserInstitutionCityDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/user/UserInstitutionCityDTO.java
new file mode 100644
index 00000000..b8b2638e
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/user/UserInstitutionCityDTO.java
@@ -0,0 +1,17 @@
+package com.softserveinc.dokazovi.dto.user;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * The UserInstitutionCityDTO is responsible for passing latest user institution city data from server to the client.
+ */
+
+@Data
+@Builder
+public class UserInstitutionCityDTO {
+
+ private Integer id;
+
+ private String name;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/dto/user/UserInstitutionDTO.java b/src/main/java/com/softserveinc/dokazovi/dto/user/UserInstitutionDTO.java
new file mode 100644
index 00000000..19c3451f
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/dto/user/UserInstitutionDTO.java
@@ -0,0 +1,21 @@
+package com.softserveinc.dokazovi.dto.user;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * The UserInstitutionDTO is responsible for passing latest user institution city data from server to the client.
+ */
+
+
+@Data
+@Builder
+public class UserInstitutionDTO {
+
+ private Integer id;
+
+ private UserInstitutionCityDTO city;
+
+ private String name;
+
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/CharityEntity.java b/src/main/java/com/softserveinc/dokazovi/entity/CharityEntity.java
new file mode 100644
index 00000000..8e689c36
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/CharityEntity.java
@@ -0,0 +1,46 @@
+package com.softserveinc.dokazovi.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import java.sql.Timestamp;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity(name = "charity_entity")
+@Table(name = "charities")
+public class CharityEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "charity_id")
+ private Integer id;
+
+ @Column(name = "body", columnDefinition = "TEXT")
+ private String body;
+
+ @ManyToOne
+ @JoinColumn(name = "author_id")
+ private DoctorEntity author;
+
+ @CreationTimestamp
+ private Timestamp createdAt;
+
+ @UpdateTimestamp
+ private Timestamp modifiedAt;
+
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/CityEntity.java b/src/main/java/com/softserveinc/dokazovi/entity/CityEntity.java
new file mode 100644
index 00000000..57674b28
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/CityEntity.java
@@ -0,0 +1,40 @@
+package com.softserveinc.dokazovi.entity;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity(name = "city_entity")
+@Table(name = "cities")
+public class CityEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "city_id")
+ private Integer id;
+
+ private String name;
+
+ @ManyToOne
+ @JoinColumn(name = "region_id", nullable = false)
+ @JsonIdentityInfo(
+ property = "id",
+ generator = ObjectIdGenerators.PropertyGenerator.class)
+ private RegionEntity region;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/DirectionEntity.java b/src/main/java/com/softserveinc/dokazovi/entity/DirectionEntity.java
new file mode 100644
index 00000000..b1b377fd
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/DirectionEntity.java
@@ -0,0 +1,59 @@
+package com.softserveinc.dokazovi.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+import org.hibernate.annotations.ColumnDefault;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+import java.util.Set;
+
+/**
+ * The Direction Entity is responsible for correlating with
+ * Directions table in the database.
+ */
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity(name = "direction_entity")
+@Table(name = "directions")
+public class DirectionEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "direction_id")
+ private Integer id;
+
+ private String name;
+ private String label;
+
+ @Column(length = 7)
+ private String color;
+
+ @ColumnDefault("false")
+ private Boolean hasDoctors;
+
+ @ColumnDefault("false")
+ private Boolean hasPosts;
+
+ @ManyToMany(mappedBy = "directions")
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Set posts;
+
+ @ManyToMany(mappedBy = "directions")
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Set users;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/DoctorEntity.java b/src/main/java/com/softserveinc/dokazovi/entity/DoctorEntity.java
new file mode 100644
index 00000000..91f116bc
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/DoctorEntity.java
@@ -0,0 +1,132 @@
+package com.softserveinc.dokazovi.entity;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+import com.softserveinc.dokazovi.entity.enumerations.UserPromotionLevel;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import org.hibernate.annotations.ColumnDefault;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
+import javax.persistence.Table;
+import java.util.Set;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity(name = "doctor_entity")
+@Table(name = "doctors")
+public class DoctorEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "doctor_id")
+ private Integer id;
+
+ private String qualification;
+
+ @Column(columnDefinition = "TEXT")
+ private String bio;
+
+ @Column(columnDefinition = "TEXT")
+ private String socialNetwork;
+
+ @ColumnDefault("1.0")
+ private Double promotionScale;
+
+ private Long publishedPosts;
+
+ @Setter(AccessLevel.NONE)
+ private Long rating;
+
+ @Enumerated(EnumType.ORDINAL)
+ @ColumnDefault("0")
+ private UserPromotionLevel promotionLevel;
+
+ @ManyToOne
+ @JoinColumn(name = "institution_id")
+ @JsonIdentityInfo(
+ property = "id",
+ generator = ObjectIdGenerators.PropertyGenerator.class)
+ private InstitutionEntity mainInstitution;
+
+ @OneToOne(cascade = {CascadeType.REFRESH, CascadeType.MERGE}, fetch = FetchType.LAZY)
+ @JoinColumn(name = "user_id", referencedColumnName = "user_id")
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ @JsonIdentityInfo(
+ property = "id",
+ generator = ObjectIdGenerators.PropertyGenerator.class)
+ private UserEntity profile;
+
+ @OneToMany(mappedBy = "author")
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ @JsonIdentityInfo(
+ property = "id",
+ generator = ObjectIdGenerators.PropertyGenerator.class)
+ private Set charities;
+
+ @ManyToMany
+ @JoinTable(
+ name = "doctors_institutions",
+ joinColumns = {@JoinColumn(name = "doctor_id")},
+ inverseJoinColumns = {@JoinColumn(name = "institution_id")}
+ )
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ @JsonIdentityInfo(
+ property = "id",
+ generator = ObjectIdGenerators.PropertyGenerator.class)
+ private Set institutions;
+
+ @ManyToMany(fetch = FetchType.EAGER)
+ @JoinTable(
+ name = "doctors_directions",
+ joinColumns = {@JoinColumn(name = "doctor_id")},
+ inverseJoinColumns = {@JoinColumn(name = "direction_id")}
+ )
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ @JsonIdentityInfo(
+ property = "id",
+ generator = ObjectIdGenerators.PropertyGenerator.class)
+ private Set directions;
+
+ private void updateUserRating() {
+ rating = (long) Math.ceil(publishedPosts * promotionScale);
+ }
+
+ @PreUpdate
+ public void preUpdateFunction() {
+ updateUserRating();
+ }
+
+ @PrePersist
+ public void prePersistFunction() {
+ updateUserRating();
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/InstitutionEntity.java b/src/main/java/com/softserveinc/dokazovi/entity/InstitutionEntity.java
new file mode 100644
index 00000000..ecf1828a
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/InstitutionEntity.java
@@ -0,0 +1,54 @@
+package com.softserveinc.dokazovi.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import java.util.Set;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity(name = "institution_entity")
+@Table(name = "institutions")
+public class InstitutionEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "institution_id")
+ private Integer id;
+
+ @Column(name = "name", nullable = false)
+ private String name;
+
+ @ManyToOne
+ @JoinColumn(name = "city_id", nullable = false)
+ private CityEntity city;
+
+ @Column(name = "address", nullable = false)
+ private String address;
+
+ @OneToMany(mappedBy = "mainInstitution")
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Set mainDoctorsInstitution;
+
+ @ManyToMany(mappedBy = "institutions")
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Set doctors;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/OriginEntity.java b/src/main/java/com/softserveinc/dokazovi/entity/OriginEntity.java
new file mode 100644
index 00000000..3edf1b45
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/OriginEntity.java
@@ -0,0 +1,43 @@
+package com.softserveinc.dokazovi.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+import java.util.Set;
+
+/**
+ * The Origin Entity is responsible for correlating with Origins table in the database.
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity(name = "origin_entity")
+@Table(name = "origins")
+public class OriginEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "origin_id")
+ private Integer id;
+
+ private String name;
+
+ private String parameters;
+
+ @ManyToMany(mappedBy = "origins")
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Set posts;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/PostEntity.java b/src/main/java/com/softserveinc/dokazovi/entity/PostEntity.java
new file mode 100644
index 00000000..ead859f3
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/PostEntity.java
@@ -0,0 +1,113 @@
+package com.softserveinc.dokazovi.entity;
+
+import com.softserveinc.dokazovi.entity.enumerations.PostStatus;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+import org.hibernate.annotations.ColumnDefault;
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import java.sql.Timestamp;
+import java.util.Set;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity(name = "post_entity")
+@Table(name = "posts")
+public class PostEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "post_id")
+ private Integer id;
+
+ private String title;
+
+ @Column(columnDefinition = "TEXT")
+ private String content;
+
+ @Column(columnDefinition = "TEXT")
+ private String preview;
+
+ @Column(name = "video_url")
+ private String videoUrl;
+
+ @Column(name = "preview_image_url")
+ private String previewImageUrl;
+
+ @ColumnDefault("false")
+ private Boolean important;
+
+ @ManyToOne(cascade = {CascadeType.REFRESH, CascadeType.MERGE})
+ @JoinColumn(name = "author_id")
+ private UserEntity author;
+
+ @ManyToOne
+ @JoinColumn(name = "type_id")
+ private PostTypeEntity type;
+
+ @Enumerated(EnumType.STRING)
+ private PostStatus status;
+
+ @ManyToMany(cascade = {CascadeType.REFRESH}, fetch = FetchType.EAGER)
+ @JoinTable(
+ name = "posts_directions",
+ joinColumns = {@JoinColumn(name = "post_id")},
+ inverseJoinColumns = {@JoinColumn(name = "direction_id")}
+ )
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Set directions;
+
+ @ManyToMany(cascade = {CascadeType.REFRESH}, fetch = FetchType.EAGER)
+ @JoinTable(
+ name = "posts_tags",
+ joinColumns = {@JoinColumn(name = "post_id")},
+ inverseJoinColumns = {@JoinColumn(name = "tag_id")}
+ )
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Set tags;
+
+ @ManyToMany(cascade = {CascadeType.REFRESH}, fetch = FetchType.EAGER)
+ @JoinTable(
+ name = "posts_origins",
+ joinColumns = {@JoinColumn(name = "post_id")},
+ inverseJoinColumns = {@JoinColumn(name = "origin_id")}
+ )
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Set origins;
+
+ @CreationTimestamp
+ private Timestamp createdAt;
+
+ @UpdateTimestamp
+ private Timestamp modifiedAt;
+
+ @CreationTimestamp
+ private Timestamp publishedAt;
+
+ @ColumnDefault("null")
+ private Integer importanceOrder;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/PostTypeEntity.java b/src/main/java/com/softserveinc/dokazovi/entity/PostTypeEntity.java
new file mode 100644
index 00000000..11a54062
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/PostTypeEntity.java
@@ -0,0 +1,38 @@
+package com.softserveinc.dokazovi.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import java.util.Set;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity(name = "post_type_entity")
+@Table(name = "post_types")
+public class PostTypeEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "type_id")
+ private Integer id;
+
+ private String name;
+
+ @OneToMany(mappedBy = "type")
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Set posts;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/ProviderEntity.java b/src/main/java/com/softserveinc/dokazovi/entity/ProviderEntity.java
new file mode 100644
index 00000000..30100884
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/ProviderEntity.java
@@ -0,0 +1,49 @@
+package com.softserveinc.dokazovi.entity;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity(name = "provider_entity")
+@Table(name = "providers")
+public class ProviderEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "provider_id")
+ private Integer id;
+
+ @Column(name = "provider_name")
+ private String name;
+
+ private String email;
+
+ private String userIdByProvider;
+
+ @ManyToOne(optional = false)
+ @JoinColumn(name = "user_id", nullable = false)
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ @JsonIdentityInfo(
+ property = "id",
+ generator = ObjectIdGenerators.PropertyGenerator.class)
+ private UserEntity user;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/RegionEntity.java b/src/main/java/com/softserveinc/dokazovi/entity/RegionEntity.java
new file mode 100644
index 00000000..a1e88373
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/RegionEntity.java
@@ -0,0 +1,45 @@
+package com.softserveinc.dokazovi.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import java.util.Set;
+
+/**
+ * The Region Entity is responsible for correlating with
+ * Regions table in the database.
+ */
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity(name = "region_entity")
+@Table(name = "regions")
+public class RegionEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "region_id")
+ private Integer id;
+
+ private String name;
+
+ private Boolean usersPresent;
+
+ @OneToMany(mappedBy = "region")
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Set cities;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/RoleEntity.java b/src/main/java/com/softserveinc/dokazovi/entity/RoleEntity.java
new file mode 100644
index 00000000..8caefc81
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/RoleEntity.java
@@ -0,0 +1,43 @@
+package com.softserveinc.dokazovi.entity;
+
+import com.softserveinc.dokazovi.entity.enumerations.RolePermission;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.Table;
+import java.util.Set;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity(name = "role_entity")
+@Table(name = "roles")
+public class RoleEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "role_id")
+ private Integer id;
+
+ @Column(name = "role_name")
+ private String name;
+
+ @ElementCollection(targetClass = RolePermission.class, fetch = FetchType.EAGER)
+ @CollectionTable(name = "role_permission", joinColumns = @JoinColumn(name = "role_id"))
+ @Enumerated(EnumType.STRING)
+ private Set permissions;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/TagEntity.java b/src/main/java/com/softserveinc/dokazovi/entity/TagEntity.java
new file mode 100644
index 00000000..a89091a4
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/TagEntity.java
@@ -0,0 +1,39 @@
+package com.softserveinc.dokazovi.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+import java.util.Set;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity(name = "tag_entity")
+@Table(name = "tags")
+public class TagEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "tag_id")
+ private Integer id;
+
+ @Column(unique = true)
+ private String tag;
+
+ @ManyToMany(mappedBy = "tags")
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Set posts;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/UserEntity.java b/src/main/java/com/softserveinc/dokazovi/entity/UserEntity.java
new file mode 100644
index 00000000..47322d42
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/UserEntity.java
@@ -0,0 +1,101 @@
+package com.softserveinc.dokazovi.entity;
+
+import com.softserveinc.dokazovi.entity.enumerations.PostStatus;
+import com.softserveinc.dokazovi.entity.enumerations.UserStatus;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+import org.hibernate.annotations.CreationTimestamp;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import java.sql.Timestamp;
+import java.util.Comparator;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * The User Entity is responsible for correlating with User table in the database.
+ */
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity(name = "user_entity")
+@Table(name = "users")
+public class UserEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "user_id")
+ private Integer id;
+ private String firstName;
+ private String lastName;
+ private String email;
+ private String password;
+ private String phone;
+ private String avatar;
+
+ @Enumerated(EnumType.STRING)
+ private UserStatus status;
+
+ @OneToMany(mappedBy = "author")
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Set posts;
+
+ @ManyToOne(fetch = FetchType.EAGER)
+ @JoinColumn(name = "role_id")
+ private RoleEntity role;
+
+ @OneToOne(mappedBy = "profile", fetch = FetchType.LAZY)
+ private DoctorEntity doctor;
+
+ @CreationTimestamp
+ private Timestamp createdAt;
+
+ @OneToMany(fetch = FetchType.EAGER, mappedBy = "user", cascade = CascadeType.ALL)
+ @EqualsAndHashCode.Exclude
+ @ToString.Exclude
+ private Set userProviderEntities;
+
+ @Column(name = "enabled")
+ @EqualsAndHashCode.Exclude
+ private Boolean enabled;
+
+ /**
+ * Gets latest expert post, if it exists.
+ * If not - returns null
+ *
+ * @return the resulting post entity
+ */
+ public PostEntity getLatestExpertPost() {
+ if (posts == null || posts.isEmpty()) {
+ return null;
+ }
+ return posts.stream()
+ .filter(postEntity -> Objects.equals(postEntity.getStatus(), PostStatus.PUBLISHED))
+ .max(Comparator.comparing(PostEntity::getCreatedAt))
+ .orElse(null);
+ }
+
+ public boolean getEnabled() {
+ return this.enabled;
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/VerificationToken.java b/src/main/java/com/softserveinc/dokazovi/entity/VerificationToken.java
new file mode 100644
index 00000000..7ddc5935
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/VerificationToken.java
@@ -0,0 +1,40 @@
+package com.softserveinc.dokazovi.entity;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity(name = "verification_token_entity")
+@Table(name = "verification_tokens")
+public class VerificationToken {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ private String token;
+
+ @OneToOne(targetEntity = UserEntity.class, fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
+ @JoinColumn(name = "user_id")
+ @JsonIdentityInfo(
+ property = "id",
+ generator = ObjectIdGenerators.PropertyGenerator.class)
+ private UserEntity user;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/enumerations/AuthProvider.java b/src/main/java/com/softserveinc/dokazovi/entity/enumerations/AuthProvider.java
new file mode 100644
index 00000000..8324b2a1
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/enumerations/AuthProvider.java
@@ -0,0 +1,7 @@
+package com.softserveinc.dokazovi.entity.enumerations;
+
+public enum AuthProvider {
+ LOCAL,
+ FACEBOOK,
+ GOOGLE
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/enumerations/PostStatus.java b/src/main/java/com/softserveinc/dokazovi/entity/enumerations/PostStatus.java
new file mode 100644
index 00000000..0bbcedcf
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/enumerations/PostStatus.java
@@ -0,0 +1,5 @@
+package com.softserveinc.dokazovi.entity.enumerations;
+
+public enum PostStatus {
+ DRAFT, MODERATION_FIRST_SIGN, MODERATION_SECOND_SIGN, PUBLISHED, ARCHIVED
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/enumerations/RolePermission.java b/src/main/java/com/softserveinc/dokazovi/entity/enumerations/RolePermission.java
new file mode 100644
index 00000000..4490db42
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/enumerations/RolePermission.java
@@ -0,0 +1,19 @@
+package com.softserveinc.dokazovi.entity.enumerations;
+
+import org.springframework.security.core.GrantedAuthority;
+
+public enum RolePermission implements GrantedAuthority {
+ SAVE_OWN_PUBLICATION,
+ SAVE_TAG,
+ DELETE_POST,
+ DELETE_OWN_POST,
+ UPDATE_POST,
+ UPDATE_OWN_POST,
+ SAVE_PUBLICATION,
+ SET_IMPORTANCE;
+
+ @Override
+ public String getAuthority() {
+ return name();
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/enumerations/UserPromotionLevel.java b/src/main/java/com/softserveinc/dokazovi/entity/enumerations/UserPromotionLevel.java
new file mode 100644
index 00000000..bcd4d5c0
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/enumerations/UserPromotionLevel.java
@@ -0,0 +1,5 @@
+package com.softserveinc.dokazovi.entity.enumerations;
+
+public enum UserPromotionLevel {
+ BASIC, PROMOTED, TOP
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/entity/enumerations/UserStatus.java b/src/main/java/com/softserveinc/dokazovi/entity/enumerations/UserStatus.java
new file mode 100644
index 00000000..fd7f4769
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/entity/enumerations/UserStatus.java
@@ -0,0 +1,5 @@
+package com.softserveinc.dokazovi.entity.enumerations;
+
+public enum UserStatus {
+ NEW, ACTIVE, DELETED
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/exception/BadRequestException.java b/src/main/java/com/softserveinc/dokazovi/exception/BadRequestException.java
new file mode 100644
index 00000000..29e2735f
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/exception/BadRequestException.java
@@ -0,0 +1,15 @@
+package com.softserveinc.dokazovi.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(HttpStatus.BAD_REQUEST)
+public class BadRequestException extends RuntimeException {
+ public BadRequestException(String message) {
+ super(message);
+ }
+
+ public BadRequestException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/exception/DtoException.java b/src/main/java/com/softserveinc/dokazovi/exception/DtoException.java
new file mode 100644
index 00000000..bdbaa37a
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/exception/DtoException.java
@@ -0,0 +1,8 @@
+package com.softserveinc.dokazovi.exception;
+
+public abstract class DtoException extends RuntimeException {
+
+ protected DtoException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/exception/EntityNotFoundException.java b/src/main/java/com/softserveinc/dokazovi/exception/EntityNotFoundException.java
new file mode 100644
index 00000000..a69c3187
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/exception/EntityNotFoundException.java
@@ -0,0 +1,13 @@
+package com.softserveinc.dokazovi.exception;
+
+public class EntityNotFoundException extends RuntimeException {
+ private static final String MESSAGE = "Entity not found";
+
+ public EntityNotFoundException() {
+ super(MESSAGE);
+ }
+
+ public EntityNotFoundException(String msg) {
+ super(msg);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/exception/ForbiddenPermissionsException.java b/src/main/java/com/softserveinc/dokazovi/exception/ForbiddenPermissionsException.java
new file mode 100644
index 00000000..2e565235
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/exception/ForbiddenPermissionsException.java
@@ -0,0 +1,13 @@
+package com.softserveinc.dokazovi.exception;
+
+public class ForbiddenPermissionsException extends RuntimeException {
+ private static final String MESSAGE = "Forbidden permission";
+
+ public ForbiddenPermissionsException() {
+ super(MESSAGE);
+ }
+
+ public ForbiddenPermissionsException(String msg) {
+ super(msg);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/exception/InvalidIdDtoException.java b/src/main/java/com/softserveinc/dokazovi/exception/InvalidIdDtoException.java
new file mode 100644
index 00000000..e02b069d
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/exception/InvalidIdDtoException.java
@@ -0,0 +1,8 @@
+package com.softserveinc.dokazovi.exception;
+
+public class InvalidIdDtoException extends DtoException {
+
+ public InvalidIdDtoException(Object o) {
+ super(o + " has invalid id");
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/exception/OAuth2AuthenticationProcessingException.java b/src/main/java/com/softserveinc/dokazovi/exception/OAuth2AuthenticationProcessingException.java
new file mode 100644
index 00000000..f161a99b
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/exception/OAuth2AuthenticationProcessingException.java
@@ -0,0 +1,13 @@
+package com.softserveinc.dokazovi.exception;
+
+import org.springframework.security.core.AuthenticationException;
+
+public class OAuth2AuthenticationProcessingException extends AuthenticationException {
+ public OAuth2AuthenticationProcessingException(String msg, Throwable t) {
+ super(msg, t);
+ }
+
+ public OAuth2AuthenticationProcessingException(String msg) {
+ super(msg);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/exception/ResourceNotFoundException.java b/src/main/java/com/softserveinc/dokazovi/exception/ResourceNotFoundException.java
new file mode 100644
index 00000000..f29ef93f
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/exception/ResourceNotFoundException.java
@@ -0,0 +1,30 @@
+package com.softserveinc.dokazovi.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(HttpStatus.NOT_FOUND)
+public class ResourceNotFoundException extends RuntimeException {
+ private final String resourceName;
+ private final String fieldName;
+ private final transient Object fieldValue;
+
+ public ResourceNotFoundException(String resourceName, String fieldName, Object fieldValue) {
+ super(String.format("%s not found with %s : '%s'", resourceName, fieldName, fieldValue));
+ this.resourceName = resourceName;
+ this.fieldName = fieldName;
+ this.fieldValue = fieldValue;
+ }
+
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ public Object getFieldValue() {
+ return fieldValue;
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/exception/handler/ApiError.java b/src/main/java/com/softserveinc/dokazovi/exception/handler/ApiError.java
new file mode 100644
index 00000000..4d5b9293
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/exception/handler/ApiError.java
@@ -0,0 +1,14 @@
+package com.softserveinc.dokazovi.exception.handler;
+
+import lombok.Builder;
+import lombok.Data;
+import org.springframework.http.HttpStatus;
+
+import java.util.List;
+
+@Data
+@Builder
+public class ApiError {
+ private HttpStatus status;
+ private List errors;
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/exception/handler/CustomRestExceptionHandler.java b/src/main/java/com/softserveinc/dokazovi/exception/handler/CustomRestExceptionHandler.java
new file mode 100644
index 00000000..efaa59d7
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/exception/handler/CustomRestExceptionHandler.java
@@ -0,0 +1,48 @@
+package com.softserveinc.dokazovi.exception.handler;
+
+import com.softserveinc.dokazovi.exception.DtoException;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.context.request.WebRequest;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@ControllerAdvice
+public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler {
+
+ // 400
+
+ @Override
+ protected ResponseEntity handleMethodArgumentNotValid(final MethodArgumentNotValidException ex,
+ final HttpHeaders headers, final HttpStatus status, final WebRequest request) {
+ logger.info(ex.getClass().getName());
+
+ List errors = ex.getBindingResult().getFieldErrors()
+ .stream()
+ .map(error -> error.getField() + ": " + error.getDefaultMessage())
+ .collect(Collectors.toList());
+
+ final ApiError apiError = ApiError.builder()
+ .status(HttpStatus.BAD_REQUEST)
+ .errors(errors)
+ .build();
+ return handleExceptionInternal(ex, apiError, headers, apiError.getStatus(), request);
+ }
+
+ @ExceptionHandler({DtoException.class})
+ public ResponseEntity handleEntityException(final DtoException ex) {
+ logger.info(ex.getClass().getName());
+ final ApiError apiError = ApiError.builder()
+ .status(HttpStatus.BAD_REQUEST)
+ .errors(Collections.singletonList(ex.getLocalizedMessage()))
+ .build();
+ return new ResponseEntity<>(apiError, new HttpHeaders(), apiError.getStatus());
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/mapper/CityMapper.java b/src/main/java/com/softserveinc/dokazovi/mapper/CityMapper.java
new file mode 100644
index 00000000..73089080
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/mapper/CityMapper.java
@@ -0,0 +1,16 @@
+package com.softserveinc.dokazovi.mapper;
+
+
+import com.softserveinc.dokazovi.dto.post.PostUserInstitutionCityDTO;
+import com.softserveinc.dokazovi.dto.user.UserInstitutionCityDTO;
+import com.softserveinc.dokazovi.entity.CityEntity;
+import org.mapstruct.Mapper;
+
+@Mapper(componentModel = "spring")
+public interface CityMapper {
+
+ UserInstitutionCityDTO toExpertInstitutionCityDTO(CityEntity cityEntity);
+
+ PostUserInstitutionCityDTO toPostUserInstitutionCityDTO(CityEntity cityEntity);
+
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/mapper/DirectionMapper.java b/src/main/java/com/softserveinc/dokazovi/mapper/DirectionMapper.java
new file mode 100644
index 00000000..29c92707
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/mapper/DirectionMapper.java
@@ -0,0 +1,16 @@
+package com.softserveinc.dokazovi.mapper;
+
+import com.softserveinc.dokazovi.dto.direction.DirectionDTO;
+import com.softserveinc.dokazovi.entity.DirectionEntity;
+import org.mapstruct.Mapper;
+
+/**
+ * The Direction Mapper is responsible for conversions
+ * between the Direction entity and the Direction DTO.
+ */
+
+@Mapper(componentModel = "spring")
+public interface DirectionMapper {
+
+ DirectionDTO toDirectionDTO(DirectionEntity directionEntity);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/mapper/InstitutionMapper.java b/src/main/java/com/softserveinc/dokazovi/mapper/InstitutionMapper.java
new file mode 100644
index 00000000..75ad6c0d
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/mapper/InstitutionMapper.java
@@ -0,0 +1,14 @@
+package com.softserveinc.dokazovi.mapper;
+
+import com.softserveinc.dokazovi.dto.post.PostUserInstitutionDTO;
+import com.softserveinc.dokazovi.dto.user.UserInstitutionDTO;
+import com.softserveinc.dokazovi.entity.InstitutionEntity;
+import org.mapstruct.Mapper;
+
+@Mapper(componentModel = "spring")
+public interface InstitutionMapper {
+
+ PostUserInstitutionDTO toPostUserInstitutionDTO (InstitutionEntity institution);
+
+ UserInstitutionDTO toExpertInstitutionDTO (InstitutionEntity institution);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/mapper/OriginMapper.java b/src/main/java/com/softserveinc/dokazovi/mapper/OriginMapper.java
new file mode 100644
index 00000000..d8ee02f3
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/mapper/OriginMapper.java
@@ -0,0 +1,14 @@
+package com.softserveinc.dokazovi.mapper;
+
+import com.softserveinc.dokazovi.dto.origin.OriginDTO;
+import com.softserveinc.dokazovi.entity.OriginEntity;
+import org.mapstruct.Mapper;
+
+/**
+ * The Origin Mapper is responsible for conversions between the origin entity and the origin DTO.
+ */
+@Mapper(componentModel = "spring")
+public interface OriginMapper {
+
+ OriginDTO toOriginDTO(OriginEntity originEntity);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/mapper/PostMapper.java b/src/main/java/com/softserveinc/dokazovi/mapper/PostMapper.java
new file mode 100644
index 00000000..6a092e26
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/mapper/PostMapper.java
@@ -0,0 +1,24 @@
+package com.softserveinc.dokazovi.mapper;
+
+import com.softserveinc.dokazovi.dto.post.PostDTO;
+import com.softserveinc.dokazovi.dto.post.PostSaveFromUserDTO;
+import com.softserveinc.dokazovi.dto.user.LatestUserPostDTO;
+import com.softserveinc.dokazovi.entity.PostEntity;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.ReportingPolicy;
+
+@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
+public interface PostMapper {
+
+ @Mapping(target = "author.mainInstitution", source = "author.doctor.mainInstitution")
+ @Mapping(target = "author.bio", source = "author.doctor.bio")
+ PostDTO toPostDTO(PostEntity postEntity);
+
+ PostEntity toPostEntity(PostSaveFromUserDTO postSaveFromUserDTO);
+
+ PostEntity updatePostEntityFromDTO(PostSaveFromUserDTO postSaveFromUserDTO, @MappingTarget PostEntity postEntity);
+
+ LatestUserPostDTO toLatestExpertPostDTO(PostEntity post);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/mapper/PostTypeMapper.java b/src/main/java/com/softserveinc/dokazovi/mapper/PostTypeMapper.java
new file mode 100644
index 00000000..bdd0282b
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/mapper/PostTypeMapper.java
@@ -0,0 +1,10 @@
+package com.softserveinc.dokazovi.mapper;
+
+import com.softserveinc.dokazovi.dto.post.PostTypeDTO;
+import com.softserveinc.dokazovi.entity.PostTypeEntity;
+import org.mapstruct.Mapper;
+
+@Mapper(componentModel = "spring")
+public interface PostTypeMapper {
+ PostTypeDTO toPostTypeDTO(PostTypeEntity postTypeEntity);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/mapper/RegionMapper.java b/src/main/java/com/softserveinc/dokazovi/mapper/RegionMapper.java
new file mode 100644
index 00000000..e164250f
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/mapper/RegionMapper.java
@@ -0,0 +1,16 @@
+package com.softserveinc.dokazovi.mapper;
+
+import com.softserveinc.dokazovi.dto.region.RegionDTO;
+import com.softserveinc.dokazovi.entity.RegionEntity;
+import org.mapstruct.Mapper;
+
+/**
+ * The Region Mapper is responsible for conversions
+ * between the Region entity and the Region DTO.
+ */
+
+@Mapper(componentModel = "spring")
+public interface RegionMapper {
+
+ RegionDTO toRegionDTO(RegionEntity regionEntity);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/mapper/TagMapper.java b/src/main/java/com/softserveinc/dokazovi/mapper/TagMapper.java
new file mode 100644
index 00000000..9af2b149
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/mapper/TagMapper.java
@@ -0,0 +1,17 @@
+package com.softserveinc.dokazovi.mapper;
+
+import com.softserveinc.dokazovi.dto.tag.TagDTO;
+import com.softserveinc.dokazovi.dto.tag.TagSaveDTO;
+import com.softserveinc.dokazovi.entity.TagEntity;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+
+@Mapper(componentModel = "spring")
+public interface TagMapper {
+
+ TagDTO toTagDTO(TagEntity tagEntity);
+
+ @Mapping(target = "id", ignore = true)
+ @Mapping(target = "posts", ignore = true)
+ TagEntity toTagEntity(TagSaveDTO tagSaveDTO);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/mapper/UserMapper.java b/src/main/java/com/softserveinc/dokazovi/mapper/UserMapper.java
new file mode 100644
index 00000000..8dc967f8
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/mapper/UserMapper.java
@@ -0,0 +1,23 @@
+package com.softserveinc.dokazovi.mapper;
+
+import com.softserveinc.dokazovi.dto.user.UserDTO;
+import com.softserveinc.dokazovi.entity.UserEntity;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.factory.Mappers;
+
+/**
+ * The User Mapper is responsible for conversions between the user entity and the user DTO.
+ */
+
+@Mapper(componentModel = "spring")
+public interface UserMapper {
+
+ PostMapper POST_MAPPER = Mappers.getMapper(PostMapper.class);
+
+ @Mapping(target = "id", source = "userEntity.id")
+ @Mapping(target = ".", source = "userEntity.doctor")
+ @Mapping(target = "lastAddedPost",
+ expression = "java(POST_MAPPER.toLatestExpertPostDTO(userEntity.getLatestExpertPost()))")
+ UserDTO toUserDTO(UserEntity userEntity);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/pojo/BindingControllerAdvice.java b/src/main/java/com/softserveinc/dokazovi/pojo/BindingControllerAdvice.java
new file mode 100644
index 00000000..aab807ca
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/pojo/BindingControllerAdvice.java
@@ -0,0 +1,21 @@
+package com.softserveinc.dokazovi.pojo;
+
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.InitBinder;
+
+/**
+ * The BindingControllerAdvice is responsible for configuring the data binder globally for the whole application.
+ */
+
+@ControllerAdvice
+public class BindingControllerAdvice {
+
+ /**
+ * Accepts the binder as an input.
+ */
+ @InitBinder
+ public void initBinder(WebDataBinder binder) {
+ binder.initDirectFieldAccess();
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/pojo/UserSearchCriteria.java b/src/main/java/com/softserveinc/dokazovi/pojo/UserSearchCriteria.java
new file mode 100644
index 00000000..01648934
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/pojo/UserSearchCriteria.java
@@ -0,0 +1,66 @@
+package com.softserveinc.dokazovi.pojo;
+
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiParam;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * The UserSearchCriteria has a list of fields which match with
+ * request parameters that will be bound from the HTTP request,
+ * standard getters/setters, and a no-argument constructor..
+ */
+
+@Data
+@EqualsAndHashCode
+public class UserSearchCriteria {
+
+ @ApiParam(value = "Multiple comma-separated direction IDs, e.g. ?directions=1,2,3,4", type = "string")
+ private Set directions;
+
+ private @ApiParam(value = "Multiple comma-separated region IDs, e.g. ?regions=1,2,3,4", type = "string")
+ Set regions;
+
+ @ApiParam(value = "User name", type = "string")
+ private String userName = "";
+
+ /**
+ * Validates the name according to regular expression.
+ * Returns user name or first name and last name depending on
+ * whether the userName contains any spaces after trimming.
+ */
+ @ApiModelProperty(hidden = true)
+ public List getUserNameList() {
+ String patternName = "[A-ZА-Яa-zа-яЇїІіЄєҐґ\\'\\s\\-]{1,}";
+
+ String name = this.userName.trim();
+
+ if (!Pattern.matches(patternName, name)) {
+ return new ArrayList<>();
+ }
+
+ List result = Arrays.asList(name.split(" "));
+ result.sort(Collections.reverseOrder());
+
+ return result;
+ }
+
+ public boolean hasRegions() {
+ return this.regions != null && !this.regions.isEmpty();
+ }
+
+ public boolean hasDirections() {
+ return this.directions != null && !this.directions.isEmpty();
+ }
+
+ public boolean hasName() {
+ return this.userName.length() > 0;
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/repositories/DirectionRepository.java b/src/main/java/com/softserveinc/dokazovi/repositories/DirectionRepository.java
new file mode 100644
index 00000000..42185da6
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/repositories/DirectionRepository.java
@@ -0,0 +1,57 @@
+package com.softserveinc.dokazovi.repositories;
+
+import com.softserveinc.dokazovi.entity.DirectionEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * The Direction Repository is responsible for encapsulation a set of Direction objects stored in the database and
+ * operations that can be performed on them.
+ */
+
+@Repository
+public interface DirectionRepository extends JpaRepository {
+
+ /**
+ * Updates the directions status. If the directions have at least
+ * one doctor, its status changes to "true". In other
+ * cases - "false"
+ */
+ @Query(nativeQuery = true,
+ value = " UPDATE DIRECTIONS"
+ + " SET HAS_DOCTORS = TRUE"
+ + " WHERE DIRECTION_ID IN (SELECT DISTINCT DIRECTION_ID FROM DOCTORS_DIRECTIONS) ")
+ @Modifying
+ void updateDirectionsHasDoctorsStatus();
+
+ /**
+ * Updates the directions status. If the directions have at least
+ * one post, its status changes to "true". In other cases -
+ * "false"
+ */
+ @Query(nativeQuery = true,
+ value = "UPDATE DIRECTIONS"
+ + " SET HAS_POSTS = TRUE"
+ + " WHERE DIRECTION_ID IN (SELECT DISTINCT DIRECTION_ID FROM POSTS_DIRECTIONS)")
+ @Modifying
+ void updateDirectionsHasPostsStatus();
+
+ /**
+ * Gets all directions by user id.
+ *
+ * @param userId user id from service
+ * @return returns the directions entity list
+ */
+ @Query(nativeQuery = true,
+ value = "SELECT * FROM DIRECTIONS"
+ + " WHERE DIRECTION_ID IN (SELECT DISTINCT DIRECTION_ID FROM POSTS_DIRECTIONS "
+ + " WHERE POST_ID IN (SELECT DISTINCT POST_ID FROM POSTS "
+ + " WHERE AUTHOR_ID IN (:userId) ))")
+ @Modifying
+ List findAllDirectionsByUserId(Integer userId);
+}
+
diff --git a/src/main/java/com/softserveinc/dokazovi/repositories/DoctorRepository.java b/src/main/java/com/softserveinc/dokazovi/repositories/DoctorRepository.java
new file mode 100644
index 00000000..4ce05acd
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/repositories/DoctorRepository.java
@@ -0,0 +1,13 @@
+package com.softserveinc.dokazovi.repositories;
+
+import com.softserveinc.dokazovi.entity.DoctorEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+@Transactional
+public interface DoctorRepository extends JpaRepository {
+
+ DoctorEntity getByProfileId(Integer profileId);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/repositories/InstitutionRepository.java b/src/main/java/com/softserveinc/dokazovi/repositories/InstitutionRepository.java
new file mode 100644
index 00000000..3ae31abe
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/repositories/InstitutionRepository.java
@@ -0,0 +1,9 @@
+package com.softserveinc.dokazovi.repositories;
+
+import com.softserveinc.dokazovi.entity.InstitutionEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface InstitutionRepository extends JpaRepository {
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/repositories/OriginRepository.java b/src/main/java/com/softserveinc/dokazovi/repositories/OriginRepository.java
new file mode 100644
index 00000000..97a35ca4
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/repositories/OriginRepository.java
@@ -0,0 +1,13 @@
+package com.softserveinc.dokazovi.repositories;
+
+import com.softserveinc.dokazovi.entity.OriginEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * The Origin Repository is responsible for encapsulation a set of
+ * Origin objects stored in the database and operations that can be performed on them.
+ */
+@Repository
+public interface OriginRepository extends JpaRepository {
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/repositories/PostRepository.java b/src/main/java/com/softserveinc/dokazovi/repositories/PostRepository.java
new file mode 100644
index 00000000..b324f3d4
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/repositories/PostRepository.java
@@ -0,0 +1,148 @@
+package com.softserveinc.dokazovi.repositories;
+
+import com.softserveinc.dokazovi.entity.DirectionEntity;
+import com.softserveinc.dokazovi.entity.PostEntity;
+import com.softserveinc.dokazovi.entity.enumerations.PostStatus;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import java.util.Set;
+
+@Repository
+public interface PostRepository extends JpaRepository {
+
+ Page findAllByImportantIsTrueAndStatus(PostStatus status, Pageable pageable);
+
+ Page findAllByStatus(PostStatus postStatus, Pageable pageable);
+
+ Page findAllByDirectionsContainsAndStatus(
+ DirectionEntity direction, PostStatus postStatus, Pageable pageable);
+
+ Page findAllByDirectionsContainsAndTypeIdInAndStatus(
+ DirectionEntity direction, Set typeId, PostStatus postStatus, Pageable pageable);
+
+ Page findAllByDirectionsContainsAndTagsIdInAndStatus(
+ DirectionEntity direction, Set tagId, PostStatus postStatus, Pageable pageable);
+
+ Page findAllByDirectionsContainsAndTypeIdInAndTagsIdInAndStatus(
+ DirectionEntity direction, Set typeId, Set tagId, PostStatus postStatus,
+ Pageable pageable);
+
+ Page findAllByAuthorIdAndStatus(Integer authorId, PostStatus postStatus, Pageable pageable);
+
+ Page findAllByAuthorIdAndTypeIdInAndStatus(
+ Integer authorId, Set typeId, PostStatus postStatus, Pageable pageable);
+
+ @Query(nativeQuery = true,
+ value = " UPDATE POSTS "
+ + " SET IMPORTANT = FALSE, "
+ + " IMPORTANCE_ORDER = NULL "
+ + " WHERE POST_ID > 0;")
+ @Modifying
+ void removeImportantPostsAndOrder(Set importantPostIds);
+
+ @Query(nativeQuery = true,
+ value = " UPDATE POSTS "
+ + " SET IMPORTANCE_ORDER = (:postNumber), "
+ + " IMPORTANT = TRUE "
+ + " WHERE POST_ID = (:postId) ")
+ @Modifying
+ void setImportantPostOrder(Integer postNumber, Integer postId);
+
+
+ @Query(nativeQuery = true,
+ value = "SELECT * FROM POSTS "
+ + " WHERE POSTS.STATUS IN ('PUBLISHED')"
+ + " ORDER BY POST_ID",
+ countQuery = "SELECT COUNT(POSTS.POST_ID) FROM POSTS"
+ + " WHERE POSTS.STATUS IN ('PUBLISHED')")
+ Page findAll(Pageable pageable);
+
+ @Query(nativeQuery = true,
+ value = " SELECT P.* FROM POSTS P "
+ + " WHERE (P.AUTHOR_ID IN (:authorId)) "
+ + " AND(array_length(ARRAY[(:typesIds)],1)>0 "
+ + " AND P.TYPE_ID IN (:typesIds)) "
+ + " AND (array_length(ARRAY [(:directionsIds)], 1) > 0 "
+ + " AND P.POST_ID IN (SELECT POST_ID "
+ + " FROM POSTS_DIRECTIONS "
+ + " WHERE DIRECTION_ID IN (:directionsIds)))"
+ + " AND P.STATUS IN ('PUBLISHED') ")
+ Page findAllByExpertAndByDirectionsAndByPostType(Integer authorId, Set typesIds,
+ Set directionsIds, Pageable pageable);
+
+ @Query(nativeQuery = true,
+ value = "SELECT P1.* "
+ + " FROM POSTS P1 "
+ + " WHERE ((array_length(ARRAY [(:typesIds)], 1) > 0 "
+ + " AND P1.TYPE_ID IN (:typesIds)) "
+ + " OR (array_length(ARRAY [(:directionsIds)], 1) > 0 "
+ + " AND P1.POST_ID IN (SELECT POST_ID "
+ + " FROM POSTS_DIRECTIONS "
+ + " WHERE DIRECTION_ID IN (:directionsIds))) "
+ + " OR (array_length(ARRAY [(:originsIds)], 1) > 0 "
+ + " AND P1.POST_ID IN (SELECT POST_ID "
+ + " FROM POSTS_ORIGINS "
+ + " WHERE ORIGIN_ID IN (:originsIds)))) "
+ + " AND P1.STATUS IN ('PUBLISHED') "
+ )
+ Page findAllByDirectionsAndByPostTypesAndByOrigins(Set typesIds, Set originsIds,
+ Set directionsIds, Pageable pageable);
+
+ @Query(nativeQuery = true,
+ value = " SELECT P.* "
+ + " FROM POSTS P "
+ + " WHERE (P.AUTHOR_ID IN (:authorId)) "
+ + " AND (array_length(ARRAY [(:directionsIds)], 1) > 0 "
+ + " AND P.POST_ID IN (SELECT POST_ID "
+ + " FROM POSTS_DIRECTIONS "
+ + " WHERE DIRECTION_ID IN (:directionsIds))) "
+ + " AND P.STATUS IN ('PUBLISHED')")
+ Page findPostsByAuthorIdAndDirections(Pageable pageable, Integer authorId, Set directionsIds);
+
+ @Query(nativeQuery = true,
+ value = " SELECT P1.* "
+ + " FROM POSTS P1 "
+ + " WHERE (P1.POST_ID IN (SELECT POST_ID"
+ + " FROM POSTS_ORIGINS"
+ + " WHERE ORIGIN_ID = 1))"
+ + " AND P1.STATUS IN ('PUBLISHED')"
+ + " AND P1.TYPE_ID NOT IN (2)"
+ + " ORDER BY CREATED_AT DESC")
+ Page findLatestByPostTypeExpertOpinion(Pageable pageable);
+
+ @Query(nativeQuery = true,
+ value = " SELECT P1.* "
+ + " FROM POSTS P1 "
+ + " WHERE (P1.POST_ID IN (SELECT POST_ID "
+ + " FROM POSTS_ORIGINS "
+ + " WHERE ORIGIN_ID = 2)) "
+ + " AND P1.STATUS IN ('PUBLISHED') "
+ + " AND P1.TYPE_ID NOT IN (2) "
+ + " ORDER BY CREATED_AT DESC ")
+ Page findLatestByPostTypeMedia(Pageable pageable);
+
+
+ @Query(nativeQuery = true,
+ value = " SELECT P1.*"
+ + " FROM POSTS P1 "
+ + " WHERE (P1.POST_ID IN (SELECT POST_ID "
+ + " FROM POSTS_ORIGINS "
+ + " WHERE ORIGIN_ID = 3)) "
+ + " AND P1.STATUS IN ('PUBLISHED') "
+ + " AND P1.TYPE_ID NOT IN (2) "
+ + " ORDER BY CREATED_AT DESC ")
+ Page findLatestByPostTypeTranslation(Pageable pageable);
+
+ @Query(nativeQuery = true,
+ value = "SELECT P1.* "
+ + " FROM POSTS P1 "
+ + " WHERE P1.TYPE_ID IN (2) "
+ + " AND P1.STATUS IN ('PUBLISHED') "
+ + " ORDER BY CREATED_AT DESC ")
+ Page findLatestByOriginVideo(Pageable pageable);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/repositories/PostTypeRepository.java b/src/main/java/com/softserveinc/dokazovi/repositories/PostTypeRepository.java
new file mode 100644
index 00000000..67be66aa
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/repositories/PostTypeRepository.java
@@ -0,0 +1,20 @@
+package com.softserveinc.dokazovi.repositories;
+
+import com.softserveinc.dokazovi.entity.PostTypeEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface PostTypeRepository extends JpaRepository {
+
+ @Query(nativeQuery = true,
+ value = " SELECT * "
+ + " FROM POST_TYPES"
+ + " WHERE (TYPE_ID IN (SELECT DISTINCT P.TYPE_ID "
+ + " FROM POSTS P "
+ + " WHERE P.AUTHOR_ID IN (:userId))) ")
+ List findAllPostTypesByUserId(Integer userId);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/repositories/ProviderRepository.java b/src/main/java/com/softserveinc/dokazovi/repositories/ProviderRepository.java
new file mode 100644
index 00000000..3847c291
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/repositories/ProviderRepository.java
@@ -0,0 +1,10 @@
+package com.softserveinc.dokazovi.repositories;
+
+
+import com.softserveinc.dokazovi.entity.ProviderEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface ProviderRepository extends JpaRepository {
+
+ Boolean existsByEmailAndName(String email, String name);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/repositories/RegionRepository.java b/src/main/java/com/softserveinc/dokazovi/repositories/RegionRepository.java
new file mode 100644
index 00000000..44f081ea
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/repositories/RegionRepository.java
@@ -0,0 +1,29 @@
+package com.softserveinc.dokazovi.repositories;
+
+import com.softserveinc.dokazovi.entity.RegionEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+/**
+ * The Region Repository is responsible for encapsulation a set of
+ * Region objects stored in the database and operations that can be performed on them.
+ */
+
+@Repository
+public interface RegionRepository extends JpaRepository {
+
+ /**
+ * Updates the regions status.
+ * If regions have at least one doctor, its status changes to "true".
+ * In other cases - "false"
+ */
+ @Query(nativeQuery = true, value = "UPDATE REGIONS "
+ + "SET USERS_PRESENT=TRUE "
+ + " WHERE REGION_ID IN (SELECT DISTINCT REGION_ID FROM CITIES"
+ + " WHERE CITY_ID IN (SELECT DISTINCT CITY_ID FROM INSTITUTIONS"
+ + " WHERE INSTITUTION_ID IN (SELECT DISTINCT INSTITUTION_ID FROM DOCTORS)))")
+ @Modifying
+ void updateRegionsStatus();
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/repositories/RoleRepository.java b/src/main/java/com/softserveinc/dokazovi/repositories/RoleRepository.java
new file mode 100644
index 00000000..d66c5348
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/repositories/RoleRepository.java
@@ -0,0 +1,12 @@
+package com.softserveinc.dokazovi.repositories;
+
+import com.softserveinc.dokazovi.entity.RoleEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface RoleRepository extends JpaRepository {
+ Optional getRoleEntityByName(String name);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/repositories/TagRepository.java b/src/main/java/com/softserveinc/dokazovi/repositories/TagRepository.java
new file mode 100644
index 00000000..32a3323b
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/repositories/TagRepository.java
@@ -0,0 +1,16 @@
+package com.softserveinc.dokazovi.repositories;
+
+import com.softserveinc.dokazovi.entity.TagEntity;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface TagRepository extends JpaRepository {
+
+ @Override
+ @Cacheable("tags")
+ List findAll();
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/repositories/UserRepository.java b/src/main/java/com/softserveinc/dokazovi/repositories/UserRepository.java
new file mode 100644
index 00000000..4756d3f2
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/repositories/UserRepository.java
@@ -0,0 +1,217 @@
+package com.softserveinc.dokazovi.repositories;
+
+import com.softserveinc.dokazovi.entity.UserEntity;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+/**
+ * The User Repository is responsible for encapsulation a set of
+ * User objects stored in the database and operations that can be performed on them.
+ */
+
+@Repository
+public interface UserRepository extends JpaRepository {
+
+ /**
+ * Gets the user by its email.
+ *
+ * @param email user email from service
+ * @return optional user entity page
+ */
+ @Query(nativeQuery = true,
+ value = "SELECT * FROM users u WHERE user_id= ("
+ + "SELECT u.user_id FROM providers u WHERE u.email IN (:email) LIMIT 1)")
+ Optional findByEmail(@Param("email") String email);
+
+ /**
+ * Gets the page of random doctors.
+ *
+ * @param pageable interface for pagination information received from user service
+ * @return the resulting user entity page
+ */
+ @Query(nativeQuery = true,
+ value = " SELECT U.* FROM DOCTORS D "
+ + " JOIN USERS U ON D.USER_ID = U.USER_ID "
+ + " ORDER BY RANDOM() ")
+ Page findRandomExperts(Pageable pageable);
+
+ /**
+ * Gets the page of doctors by directions id.
+ *
+ * @param pageable interface for pagination information received from user service
+ * @param directionsIds received from user service
+ * @return the resulting user entity page
+ */
+ @Query(nativeQuery = true,
+ value = " SELECT U.* FROM ( "
+ + " SELECT DD.DOCTOR_ID FROM DOCTORS_DIRECTIONS DD "
+ + " WHERE DD.DIRECTION_ID IN (:directionsIds) "
+ + " GROUP BY DD.DOCTOR_ID "
+ + " ) DOCS_DIRS "
+ + " JOIN DOCTORS D ON DOCS_DIRS.DOCTOR_ID=D.DOCTOR_ID "
+ + " JOIN USERS U ON D.USER_ID = U.USER_ID "
+ + " ORDER BY RANDOM() ",
+ countQuery = " SELECT COUNT(DISTINCT DD.DOCTOR_ID) FROM DOCTORS_DIRECTIONS DD "
+ + " WHERE DD.DIRECTION_ID IN (:directionsIds) ")
+ Page findRandomExpertsByDirectionsIdIn(Iterable directionsIds, Pageable pageable);
+
+ /**
+ * Gets the page of doctors order by promotion level and rating.
+ *
+ * @param pageable interface for pagination information received from user service
+ * @return the resulting user entity page
+ */
+ @Query(nativeQuery = true,
+ value = " SELECT U.* FROM DOCTORS D "
+ + " JOIN USERS U ON U.USER_ID = D.USER_ID "
+ + " ORDER BY D.PROMOTION_LEVEL DESC, D.RATING DESC, "
+ + " U.LAST_NAME, U.FIRST_NAME ")
+ Page findDoctorsProfiles(Pageable pageable);
+
+ /**
+ * Gets the page of doctors by directions ids and regions Ids.
+ *
+ * @param pageable interface for pagination information received from user service
+ * @param directionsIds received from user service
+ * @param regionsIds received from user service
+ * @return the resulting user entity page
+ */
+ @Query(nativeQuery = true,
+ value = " SELECT U.* FROM ( "
+ + " SELECT DOCTOR_ID FROM DOCTORS D "
+ + " JOIN INSTITUTIONS I ON D.INSTITUTION_ID=I.INSTITUTION_ID "
+ + " JOIN CITIES C ON I.CITY_ID=C.CITY_ID "
+ + " WHERE C.REGION_ID IN (:regionsIds) "
+ + " ) DOCS_REG "
+ + " JOIN ( "
+ + " SELECT DD.DOCTOR_ID, COUNT(DD.DIRECTION_ID) DIR_MATCHED "
+ + " FROM DOCTORS_DIRECTIONS DD "
+ + " WHERE DD.DIRECTION_ID IN (:directionsIds) "
+ + " GROUP BY DD.DOCTOR_ID "
+ + " ) DOCS_DIR ON DOCS_REG.DOCTOR_ID=DOCS_DIR.DOCTOR_ID "
+ + " JOIN DOCTORS D ON DOCS_DIR.DOCTOR_ID=D.DOCTOR_ID "
+ + " JOIN USERS U ON U.USER_ID = D.USER_ID "
+ + " ORDER BY DOCS_DIR.DIR_MATCHED DESC, D.PROMOTION_LEVEL DESC, D.RATING DESC, "
+ + " U.LAST_NAME, U.FIRST_NAME ",
+ countQuery = " SELECT COUNT(DOCS_DIR.DOCTOR_ID) FROM ( "
+ + " SELECT DOCTOR_ID FROM DOCTORS D "
+ + " JOIN INSTITUTIONS I ON D.INSTITUTION_ID=I.INSTITUTION_ID "
+ + " JOIN CITIES C ON I.CITY_ID=C.CITY_ID "
+ + " WHERE C.REGION_ID IN (:regionsIds) "
+ + " ) DOCS_REG "
+ + " JOIN ( "
+ + " SELECT DISTINCT DD.DOCTOR_ID FROM DOCTORS_DIRECTIONS DD "
+ + " WHERE DD.DIRECTION_ID IN (:directionsIds) "
+ + " ) DOCS_DIR ON DOCS_REG.DOCTOR_ID=DOCS_DIR.DOCTOR_ID ")
+ Page findDoctorsProfiles(
+ Iterable directionsIds, Iterable regionsIds, Pageable pageable);
+
+ /**
+ * Gets the page of doctors by regions ids.
+ *
+ * @param pageable interface for pagination information received from user service
+ * @param regionsIds received from user service
+ * @return the resulting user entity page
+ */
+ @Query(nativeQuery = true,
+ value = " SELECT U.* FROM ( "
+ + " SELECT D.PROMOTION_LEVEL, D.RATING, D.USER_ID FROM DOCTORS D "
+ + " JOIN INSTITUTIONS I ON D.INSTITUTION_ID=I.INSTITUTION_ID "
+ + " JOIN CITIES C ON I.CITY_ID=C.CITY_ID "
+ + " WHERE C.REGION_ID IN (:regionsIds) "
+ + " ) DOCS_REG "
+ + " JOIN USERS U ON U.USER_ID = DOCS_REG.USER_ID "
+ + " ORDER BY DOCS_REG.PROMOTION_LEVEL DESC, DOCS_REG.RATING DESC, "
+ + " U.LAST_NAME, U.FIRST_NAME ",
+ countQuery = " SELECT COUNT(D.DOCTOR_ID) FROM DOCTORS D "
+ + " JOIN INSTITUTIONS I ON D.INSTITUTION_ID=I.INSTITUTION_ID "
+ + " JOIN CITIES C ON I.CITY_ID=C.CITY_ID "
+ + " WHERE C.REGION_ID IN (:regionsIds) ")
+ Page findDoctorsProfilesByRegionsIds(
+ Iterable regionsIds, Pageable pageable);
+
+ /**
+ * Gets the page of doctors by directions ids.
+ *
+ * @param pageable interface for pagination information received from user service
+ * @param directionsIds received from user service
+ * @return the resulting user entity page
+ */
+ @Query(nativeQuery = true,
+ value = " SELECT U.* FROM ( "
+ + " SELECT DD.DOCTOR_ID, COUNT(DD.DIRECTION_ID) DIR_MATCHED"
+ + " FROM DOCTORS_DIRECTIONS DD "
+ + " WHERE DD.DIRECTION_ID IN (:directionsIds) "
+ + " GROUP BY DD.DOCTOR_ID "
+ + " ) DOCS_DIR "
+ + " JOIN DOCTORS D ON DOCS_DIR.DOCTOR_ID=D.DOCTOR_ID "
+ + " JOIN USERS U ON U.USER_ID=D.USER_ID "
+ + " ORDER BY DOCS_DIR.DIR_MATCHED DESC, D.PROMOTION_LEVEL DESC, D.RATING DESC, "
+ + " U.LAST_NAME, U.FIRST_NAME ",
+ countQuery = " SELECT COUNT(DISTINCT DD.DOCTOR_ID) FROM DOCTORS_DIRECTIONS DD "
+ + " WHERE DD.DIRECTION_ID IN (:directionsIds) ")
+ Page findDoctorsProfilesByDirectionsIds(
+ Iterable directionsIds, Pageable pageable);
+
+ /**
+ * Gets the page of doctors by single name.
+ *
+ * @param name user name received from user service
+ * @param pageable interface for pagination information received from user service
+ * @return the resulting user entity page
+ */
+ @Query(nativeQuery = true,
+ value = " SELECT U.* FROM USERS U"
+ + " JOIN DOCTORS D ON U.USER_ID = D.USER_ID"
+ + " WHERE UPPER(U.FIRST_NAME) LIKE CONCAT(UPPER(:name), '%') OR "
+ + " UPPER(U.LAST_NAME) LIKE CONCAT(UPPER(:name), '%')")
+ Page findDoctorsByName(@Param("name") String name, Pageable pageable);
+
+ /**
+ * Gets the page of doctors by firstName and lastName. *
+ * Sorts the experts according to the coincidence. First, the experts with the same firstname and lastname are
+ * displayed. Through the CASE...WHEN...THEN statement, the TURN parameter is defined. Then results of the SELECT
+ * statement are sorted according to the parameter TURN.
+ *
+ * @param firstName received from user service
+ * @param lastName received from user service
+ * @param pageable interface for pagination information received from user service
+ * @return the resulting user entity page
+ */
+ @Query(nativeQuery = true,
+ value = "SELECT *, "
+ + " CASE "
+ + " WHEN ((UPPER(U.FIRST_NAME) LIKE CONCAT(UPPER(:firstName), '%') "
+ + " AND UPPER(U.LAST_NAME) LIKE CONCAT(UPPER(:lastName), '%'))) "
+ + " OR ((UPPER(U.FIRST_NAME) LIKE CONCAT(UPPER(:lastName), '%')"
+ + " AND UPPER(U.LAST_NAME) LIKE CONCAT(UPPER(:firstName), '%'))) THEN 1"
+ + " WHEN (UPPER(U.LAST_NAME) LIKE CONCAT(UPPER(:lastName), '%')) "
+ + " OR (UPPER(U.LAST_NAME) LIKE CONCAT(UPPER(:firstName), '%'))"
+ + " OR (UPPER(U.FIRST_NAME) LIKE CONCAT(UPPER(:firstName), '%')) "
+ + " OR (UPPER(U.FIRST_NAME) LIKE CONCAT(UPPER(:lastName), '%')) THEN 2"
+ + " ELSE 3 "
+ + " END as TURN "
+ + " FROM USERS U "
+ + " JOIN DOCTORS D ON U.USER_ID = D.USER_ID "
+ + " WHERE (UPPER(U.LAST_NAME) LIKE CONCAT(UPPER(:lastName), '%')) "
+ + " OR (UPPER(U.LAST_NAME) LIKE CONCAT(UPPER(:firstName), '%'))"
+ + " OR (UPPER(U.FIRST_NAME) LIKE CONCAT(UPPER(:lastName), '%'))"
+ + " OR (UPPER(U.FIRST_NAME) LIKE CONCAT(UPPER(:firstName), '%'))"
+ + " ORDER BY TURN")
+ Page findDoctorsByName(
+ @Param("firstName") String firstName, @Param("lastName") String lastName, Pageable pageable);
+
+ /**
+ * Checks whether the user exists by email.
+ *
+ * @param email received from user service
+ * @return true or false
+ */
+ Boolean existsByEmail(String email);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/repositories/VerificationTokenRepository.java b/src/main/java/com/softserveinc/dokazovi/repositories/VerificationTokenRepository.java
new file mode 100644
index 00000000..a71b9e23
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/repositories/VerificationTokenRepository.java
@@ -0,0 +1,9 @@
+package com.softserveinc.dokazovi.repositories;
+
+import com.softserveinc.dokazovi.entity.VerificationToken;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface VerificationTokenRepository extends JpaRepository {
+
+ VerificationToken findByToken(String token);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/security/CustomUserDetailsService.java b/src/main/java/com/softserveinc/dokazovi/security/CustomUserDetailsService.java
new file mode 100644
index 00000000..57f40e90
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/security/CustomUserDetailsService.java
@@ -0,0 +1,39 @@
+package com.softserveinc.dokazovi.security;
+
+import com.softserveinc.dokazovi.entity.UserEntity;
+import com.softserveinc.dokazovi.exception.ResourceNotFoundException;
+import com.softserveinc.dokazovi.repositories.UserRepository;
+import lombok.AllArgsConstructor;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@AllArgsConstructor
+public class CustomUserDetailsService implements UserDetailsService {
+
+ private final UserRepository userRepository;
+
+ @Override
+ @Transactional
+ public UserDetails loadUserByUsername(String email)
+ throws UsernameNotFoundException {
+ UserEntity user = userRepository.findByEmail(email)
+ .orElseThrow(() ->
+ new UsernameNotFoundException("User not found with email : " + email)
+ );
+
+ return UserPrincipal.create(user);
+ }
+
+ @Transactional
+ public UserDetails loadUserById(Integer id) {
+ UserEntity user = userRepository.findById(id).orElseThrow(
+ () -> new ResourceNotFoundException("User", "id", id)
+ );
+
+ return UserPrincipal.create(user);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/security/RestAuthenticationEntryPoint.java b/src/main/java/com/softserveinc/dokazovi/security/RestAuthenticationEntryPoint.java
new file mode 100644
index 00000000..9b853128
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/security/RestAuthenticationEntryPoint.java
@@ -0,0 +1,24 @@
+package com.softserveinc.dokazovi.security;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
+
+ private static final Logger logger = LoggerFactory.getLogger(RestAuthenticationEntryPoint.class);
+
+ @Override
+ public void commence(HttpServletRequest httpServletRequest,
+ HttpServletResponse httpServletResponse,
+ AuthenticationException e) throws IOException {
+ logger.error("Responding with unauthorized error. Message - {}", e.getMessage());
+ httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,
+ e.getLocalizedMessage());
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/security/TokenAuthenticationFilter.java b/src/main/java/com/softserveinc/dokazovi/security/TokenAuthenticationFilter.java
new file mode 100644
index 00000000..ef6c7554
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/security/TokenAuthenticationFilter.java
@@ -0,0 +1,58 @@
+package com.softserveinc.dokazovi.security;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.util.StringUtils;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+
+public class TokenAuthenticationFilter extends OncePerRequestFilter {
+
+ @Autowired
+ private TokenProvider tokenProvider;
+
+ @Autowired
+ private CustomUserDetailsService customUserDetailsService;
+
+ private static final Logger tokenAuthenticationFilterLogger = LoggerFactory
+ .getLogger(TokenAuthenticationFilter.class);
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
+ throws ServletException, IOException {
+ try {
+ String jwt = getJwtFromRequest(request);
+ if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
+ Integer userId = tokenProvider.getUserIdFromToken(jwt);
+ UserDetails userDetails = customUserDetailsService.loadUserById(userId);
+ UsernamePasswordAuthenticationToken authentication =
+ new UsernamePasswordAuthenticationToken(userDetails,
+ null, userDetails.getAuthorities());
+ authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+ }
+ } catch (Exception ex) {
+ tokenAuthenticationFilterLogger.error("Could not set user authentication in security context", ex);
+ }
+ filterChain.doFilter(request, response);
+ }
+
+ protected String getJwtFromRequest(HttpServletRequest request) {
+ String bearerToken = request.getHeader("Authorization");
+ if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
+ return bearerToken.substring(7);
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/security/TokenProvider.java b/src/main/java/com/softserveinc/dokazovi/security/TokenProvider.java
new file mode 100644
index 00000000..f58e5cfb
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/security/TokenProvider.java
@@ -0,0 +1,72 @@
+package com.softserveinc.dokazovi.security;
+
+import com.softserveinc.dokazovi.config.AppProperties;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.MalformedJwtException;
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.SignatureException;
+import io.jsonwebtoken.UnsupportedJwtException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+public class TokenProvider {
+
+ private static final Logger logger = LoggerFactory.getLogger(TokenProvider.class);
+
+ private AppProperties appProperties;
+
+ public TokenProvider(AppProperties appProperties) {
+ this.appProperties = appProperties;
+ }
+
+ public String createToken(Authentication authentication) {
+ UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
+ Date now = new Date();
+ Date expiryDate = new Date(now.getTime() + appProperties.getAuth().getTokenExpirationMsec());
+ Map claims = new HashMap<>();
+ claims.put("Permissions",userPrincipal.getAuthorities().toString());
+ return Jwts.builder()
+ .setSubject(Long.toString(userPrincipal.getId()))
+ .setIssuedAt(new Date())
+ .setExpiration(expiryDate)
+ .addClaims(claims)
+ .signWith(SignatureAlgorithm.HS512, appProperties.getAuth().getTokenSecret())
+ .compact();
+ }
+
+ public Integer getUserIdFromToken(String token) {
+ Claims claims = Jwts.parser()
+ .setSigningKey(appProperties.getAuth().getTokenSecret())
+ .parseClaimsJws(token)
+ .getBody();
+
+ return Integer.parseInt(claims.getSubject());
+ }
+
+ public boolean validateToken(String authToken) {
+ try {
+ Jwts.parser().setSigningKey(appProperties.getAuth().getTokenSecret()).parseClaimsJws(authToken);
+ return true;
+ } catch (SignatureException ex) {
+ logger.error("Invalid JWT signature");
+ } catch (MalformedJwtException ex) {
+ logger.error("Invalid JWT token");
+ } catch (ExpiredJwtException ex) {
+ logger.error("Expired JWT token");
+ } catch (UnsupportedJwtException ex) {
+ logger.error("Unsupported JWT token");
+ } catch (IllegalArgumentException ex) {
+ logger.error("JWT claims string is empty.");
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/security/UserPrincipal.java b/src/main/java/com/softserveinc/dokazovi/security/UserPrincipal.java
new file mode 100644
index 00000000..981302cc
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/security/UserPrincipal.java
@@ -0,0 +1,102 @@
+package com.softserveinc.dokazovi.security;
+
+
+import com.softserveinc.dokazovi.entity.RoleEntity;
+import com.softserveinc.dokazovi.entity.UserEntity;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.NoArgsConstructor;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.oauth2.core.user.OAuth2User;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class UserPrincipal implements OAuth2User, UserDetails {
+
+ private Integer id;
+ private String email;
+ private String password;
+ private RoleEntity role;
+ private transient Map attributes;
+
+ public static UserPrincipal create(UserEntity user) {
+ return UserPrincipal.builder()
+ .id(user.getId())
+ .email(user.getEmail())
+ .password(user.getPassword())
+ .role(user.getRole())
+ .build();
+ }
+
+ public static UserPrincipal create(UserEntity user, Map attributes) {
+ UserPrincipal userPrincipal = UserPrincipal.create(user);
+ userPrincipal.setAttributes(attributes);
+ return userPrincipal;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ @Override
+ public String getPassword() {
+ return password;
+ }
+
+ @Override
+ public String getUsername() {
+ return getEmail();
+ }
+
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isAccountNonLocked() {
+ return true;
+ }
+
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ @Override
+ public Collection extends GrantedAuthority> getAuthorities() {
+ if (role == null) {
+ return Collections.emptySet();
+ }
+ return role.getPermissions();
+ }
+
+ @Override
+ public Map getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(Map attributes) {
+ this.attributes = attributes;
+ }
+
+ @Override
+ public String getName() {
+ return String.valueOf(id);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/security/oauth2/CustomOAuth2UserService.java b/src/main/java/com/softserveinc/dokazovi/security/oauth2/CustomOAuth2UserService.java
new file mode 100644
index 00000000..42c8550e
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/security/oauth2/CustomOAuth2UserService.java
@@ -0,0 +1,96 @@
+package com.softserveinc.dokazovi.security.oauth2;
+
+
+import com.softserveinc.dokazovi.entity.ProviderEntity;
+import com.softserveinc.dokazovi.entity.RoleEntity;
+import com.softserveinc.dokazovi.entity.UserEntity;
+import com.softserveinc.dokazovi.entity.enumerations.UserStatus;
+import com.softserveinc.dokazovi.exception.OAuth2AuthenticationProcessingException;
+import com.softserveinc.dokazovi.repositories.ProviderRepository;
+import com.softserveinc.dokazovi.repositories.RoleRepository;
+import com.softserveinc.dokazovi.repositories.UserRepository;
+import com.softserveinc.dokazovi.security.UserPrincipal;
+import com.softserveinc.dokazovi.security.oauth2.user.OAuth2UserInfo;
+import com.softserveinc.dokazovi.security.oauth2.user.OAuth2UserInfoFactory;
+import com.softserveinc.dokazovi.util.StringToNameParser;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.authentication.InternalAuthenticationServiceException;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
+import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
+import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
+import org.springframework.security.oauth2.core.user.OAuth2User;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import java.util.Optional;
+
+@Service
+@RequiredArgsConstructor
+public class CustomOAuth2UserService extends DefaultOAuth2UserService {
+
+ private final UserRepository userRepository;
+ private final ProviderRepository userProviderRepository;
+ private final RoleRepository roleRepository;
+
+ @Override
+ public OAuth2User loadUser(OAuth2UserRequest oauth2UserRequest) throws OAuth2AuthenticationException {
+ OAuth2User oauth2User = super.loadUser(oauth2UserRequest);
+
+ try {
+ return processOAuth2User(oauth2UserRequest, oauth2User);
+ } catch (AuthenticationException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new InternalAuthenticationServiceException(ex.getMessage(), ex.getCause());
+ }
+ }
+
+ private OAuth2User processOAuth2User(OAuth2UserRequest oauth2UserRequest, OAuth2User oauth2User) {
+ OAuth2UserInfo oauth2UserInfo = OAuth2UserInfoFactory
+ .getOAuth2UserInfo(oauth2UserRequest.getClientRegistration().getRegistrationId(),
+ oauth2User.getAttributes());
+ if (StringUtils.isEmpty(oauth2UserInfo.getEmail())) {
+ throw new OAuth2AuthenticationProcessingException("Email not found from OAuth2 provider");
+ }
+
+ Optional userOptional = userRepository.findByEmail(oauth2UserInfo.getEmail());
+
+ UserEntity user;
+ if (userOptional.isPresent()) {
+ user = userOptional.get();
+ user = updateExistingUser(user, oauth2UserInfo);
+ } else {
+ user = registerNewUser(oauth2UserRequest, oauth2UserInfo);
+ }
+
+ return UserPrincipal.create(user, oauth2User.getAttributes());
+ }
+
+ private UserEntity registerNewUser(OAuth2UserRequest oauth2UserRequest, OAuth2UserInfo oauth2UserInfo) {
+ ProviderEntity provider = new ProviderEntity();
+ provider.setName(oauth2UserRequest.getClientRegistration().getRegistrationId());
+ provider.setUserIdByProvider(oauth2UserInfo.getId());
+ UserEntity user = new UserEntity();
+ StringToNameParser.setUserNameFromRequest(oauth2UserInfo, user);
+ provider.setEmail(oauth2UserInfo.getEmail());
+ user.setEmail(oauth2UserInfo.getEmail());
+ user.setAvatar(oauth2UserInfo.getImageUrl());
+ user.setStatus(UserStatus.NEW);
+ Optional roleEntity = roleRepository.getRoleEntityByName("Doctor");
+ user.setRole(roleEntity.orElse(null));
+ user.setEnabled(true);
+ UserEntity savedUser = userRepository.save(user);
+ provider.setUser(savedUser);
+ userProviderRepository.save(provider);
+ return savedUser;
+ }
+
+ private UserEntity updateExistingUser(UserEntity existingUser, OAuth2UserInfo oauth2UserInfo) {
+ existingUser.setFirstName(oauth2UserInfo.getName().split(" ")[0]);
+ existingUser.setLastName(oauth2UserInfo.getName().split(" ")[1]);
+ existingUser.setAvatar(oauth2UserInfo.getImageUrl());
+ return userRepository.save(existingUser);
+ }
+
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/security/oauth2/HttpCookieOAuth2AuthorizationRequestRepository.java b/src/main/java/com/softserveinc/dokazovi/security/oauth2/HttpCookieOAuth2AuthorizationRequestRepository.java
new file mode 100644
index 00000000..aa8cae43
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/security/oauth2/HttpCookieOAuth2AuthorizationRequestRepository.java
@@ -0,0 +1,54 @@
+package com.softserveinc.dokazovi.security.oauth2;
+
+
+import com.nimbusds.oauth2.sdk.util.StringUtils;
+import com.softserveinc.dokazovi.util.CookieUtils;
+import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository;
+import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@Component
+public class HttpCookieOAuth2AuthorizationRequestRepository implements
+ AuthorizationRequestRepository {
+ public static final String OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME = "oauth2_auth_request";
+ public static final String REDIRECT_URI_PARAM_COOKIE_NAME = "redirect_uri";
+ private static final int COOKIE_EXPIRE_SECONDS = 180;
+
+ @Override
+ public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest request) {
+ return CookieUtils.getCookie(request, OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME)
+ .map(cookie -> CookieUtils.deserialize(cookie, OAuth2AuthorizationRequest.class))
+ .orElse(null);
+ }
+
+ @Override
+ public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationRequest,
+ HttpServletRequest request, HttpServletResponse response) {
+ if (authorizationRequest == null) {
+ CookieUtils.deleteCookie(request, response, OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME);
+ CookieUtils.deleteCookie(request, response, REDIRECT_URI_PARAM_COOKIE_NAME);
+ return;
+ }
+
+ CookieUtils.addCookie(response, OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME,
+ CookieUtils.serialize(authorizationRequest), COOKIE_EXPIRE_SECONDS);
+ String redirectUriAfterLogin = request.getParameter(REDIRECT_URI_PARAM_COOKIE_NAME);
+ if (StringUtils.isNotBlank(redirectUriAfterLogin)) {
+ CookieUtils.addCookie(response, REDIRECT_URI_PARAM_COOKIE_NAME,
+ redirectUriAfterLogin, COOKIE_EXPIRE_SECONDS);
+ }
+ }
+
+ @Override
+ public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request) {
+ return this.loadAuthorizationRequest(request);
+ }
+
+ public void removeAuthorizationRequestCookies(HttpServletRequest request, HttpServletResponse response) {
+ CookieUtils.deleteCookie(request, response, OAUTH2_AUTHORIZATION_REQUEST_COOKIE_NAME);
+ CookieUtils.deleteCookie(request, response, REDIRECT_URI_PARAM_COOKIE_NAME);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/security/oauth2/OAuth2AuthenticationFailureHandler.java b/src/main/java/com/softserveinc/dokazovi/security/oauth2/OAuth2AuthenticationFailureHandler.java
new file mode 100644
index 00000000..a35fa954
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/security/oauth2/OAuth2AuthenticationFailureHandler.java
@@ -0,0 +1,40 @@
+package com.softserveinc.dokazovi.security.oauth2;
+
+
+import com.softserveinc.dokazovi.util.CookieUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
+import org.springframework.stereotype.Component;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+import static com.softserveinc.dokazovi.security.oauth2.HttpCookieOAuth2AuthorizationRequestRepository.REDIRECT_URI_PARAM_COOKIE_NAME;
+
+
+@Component
+@RequiredArgsConstructor
+public class OAuth2AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
+
+ private final HttpCookieOAuth2AuthorizationRequestRepository httpCookieOAuth2AuthorizationRequestRepository;
+
+ @Override
+ public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
+ AuthenticationException exception) throws IOException {
+ String targetUrl = CookieUtils.getCookie(request, REDIRECT_URI_PARAM_COOKIE_NAME)
+ .map(Cookie::getValue)
+ .orElse(("/"));
+
+ targetUrl = UriComponentsBuilder.fromUriString(targetUrl)
+ .queryParam("error", exception.getLocalizedMessage())
+ .build().toUriString();
+
+ httpCookieOAuth2AuthorizationRequestRepository.removeAuthorizationRequestCookies(request, response);
+
+ getRedirectStrategy().sendRedirect(request, response, targetUrl);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/security/oauth2/OAuth2AuthenticationSuccessHandler.java b/src/main/java/com/softserveinc/dokazovi/security/oauth2/OAuth2AuthenticationSuccessHandler.java
new file mode 100644
index 00000000..8cc7adbe
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/security/oauth2/OAuth2AuthenticationSuccessHandler.java
@@ -0,0 +1,94 @@
+package com.softserveinc.dokazovi.security.oauth2;
+
+
+import com.softserveinc.dokazovi.config.AppProperties;
+import com.softserveinc.dokazovi.exception.BadRequestException;
+import com.softserveinc.dokazovi.security.TokenProvider;
+import com.softserveinc.dokazovi.util.CookieUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
+import org.springframework.stereotype.Component;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Optional;
+
+import static com.softserveinc.dokazovi.security.oauth2.HttpCookieOAuth2AuthorizationRequestRepository.REDIRECT_URI_PARAM_COOKIE_NAME;
+
+
+@Component
+public class OAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
+
+ private TokenProvider tokenProvider;
+
+ private AppProperties appProperties;
+
+ private HttpCookieOAuth2AuthorizationRequestRepository httpCookieOAuth2AuthorizationRequestRepository;
+
+
+ @Autowired
+ OAuth2AuthenticationSuccessHandler(TokenProvider tokenProvider, AppProperties appProperties,
+ HttpCookieOAuth2AuthorizationRequestRepository
+ httpCookieOAuth2AuthorizationRequestRepository) {
+ this.tokenProvider = tokenProvider;
+ this.appProperties = appProperties;
+ this.httpCookieOAuth2AuthorizationRequestRepository = httpCookieOAuth2AuthorizationRequestRepository;
+ }
+
+ @Override
+ public void onAuthenticationSuccess(
+ HttpServletRequest request, HttpServletResponse response, Authentication authentication)
+ throws IOException {
+ String targetUrl = determineTargetUrl(request, response, authentication);
+
+ if (response.isCommitted()) {
+ logger.debug("Response has already been committed. Unable to redirect to " + targetUrl);
+ return;
+ }
+
+ clearAuthenticationAttributes(request, response);
+ getRedirectStrategy().sendRedirect(request, response, targetUrl);
+ }
+
+ @Override
+ protected String determineTargetUrl(
+ HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
+ Optional redirectUri = CookieUtils.getCookie(request, REDIRECT_URI_PARAM_COOKIE_NAME)
+ .map(Cookie::getValue);
+
+ if (redirectUri.isPresent() && !isAuthorizedRedirectUri(redirectUri.get())) {
+ throw new BadRequestException("Sorry! We've got an Unauthorized Redirect" +
+ " URI and can't proceed with the authentication");
+ }
+
+ String targetUrl = redirectUri.orElse(getDefaultTargetUrl());
+
+ String token = tokenProvider.createToken(authentication);
+
+ return UriComponentsBuilder.fromUriString(targetUrl)
+ .queryParam("token", token)
+ .build().toUriString();
+ }
+
+ protected void clearAuthenticationAttributes(HttpServletRequest request, HttpServletResponse response) {
+ super.clearAuthenticationAttributes(request);
+ httpCookieOAuth2AuthorizationRequestRepository.removeAuthorizationRequestCookies(request, response);
+ }
+
+ private boolean isAuthorizedRedirectUri(String uri) {
+ URI clientRedirectUri = URI.create(uri);
+
+ return appProperties.getOauth2().getAuthorizedRedirectUris()
+ .stream()
+ .anyMatch(authorizedRedirectUri -> {
+ URI authorizedURI = URI.create(authorizedRedirectUri);
+ return authorizedURI.getHost().equalsIgnoreCase(clientRedirectUri.getHost())
+ && authorizedURI.getPort() == clientRedirectUri.getPort();
+ });
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/security/oauth2/user/FacebookOAuth2UserInfo.java b/src/main/java/com/softserveinc/dokazovi/security/oauth2/user/FacebookOAuth2UserInfo.java
new file mode 100644
index 00000000..cc49f54b
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/security/oauth2/user/FacebookOAuth2UserInfo.java
@@ -0,0 +1,38 @@
+package com.softserveinc.dokazovi.security.oauth2.user;
+
+import java.util.Map;
+
+public class FacebookOAuth2UserInfo extends OAuth2UserInfo {
+ public FacebookOAuth2UserInfo(Map attributes) {
+ super(attributes);
+ }
+
+ @Override
+ public String getId() {
+ return (String) attributes.get("id");
+ }
+
+ @Override
+ public String getName() {
+ return (String) attributes.get("name");
+ }
+
+ @Override
+ public String getEmail() {
+ return (String) attributes.get("email");
+ }
+
+ @Override
+ public String getImageUrl() {
+ if (attributes.containsKey("picture")) {
+ Map pictureObj = (Map) attributes.get("picture");
+ if (pictureObj.containsKey("data")) {
+ Map dataObj = (Map) pictureObj.get("data");
+ if (dataObj.containsKey("url")) {
+ return (String) dataObj.get("url");
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/security/oauth2/user/GoogleOAuth2UserInfo.java b/src/main/java/com/softserveinc/dokazovi/security/oauth2/user/GoogleOAuth2UserInfo.java
new file mode 100644
index 00000000..5bd1d3fc
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/security/oauth2/user/GoogleOAuth2UserInfo.java
@@ -0,0 +1,30 @@
+package com.softserveinc.dokazovi.security.oauth2.user;
+
+import java.util.Map;
+
+public class GoogleOAuth2UserInfo extends OAuth2UserInfo {
+
+ public GoogleOAuth2UserInfo(Map attributes) {
+ super(attributes);
+ }
+
+ @Override
+ public String getId() {
+ return (String) attributes.get("sub");
+ }
+
+ @Override
+ public String getName() {
+ return (String) attributes.get("name");
+ }
+
+ @Override
+ public String getEmail() {
+ return (String) attributes.get("email");
+ }
+
+ @Override
+ public String getImageUrl() {
+ return (String) attributes.get("picture");
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/security/oauth2/user/OAuth2UserInfo.java b/src/main/java/com/softserveinc/dokazovi/security/oauth2/user/OAuth2UserInfo.java
new file mode 100644
index 00000000..a28d9b8c
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/security/oauth2/user/OAuth2UserInfo.java
@@ -0,0 +1,23 @@
+package com.softserveinc.dokazovi.security.oauth2.user;
+
+import java.util.Map;
+
+public abstract class OAuth2UserInfo {
+ protected Map attributes;
+
+ protected OAuth2UserInfo(Map attributes) {
+ this.attributes = attributes;
+ }
+
+ public Map getAttributes() {
+ return attributes;
+ }
+
+ public abstract String getId();
+
+ public abstract String getName();
+
+ public abstract String getEmail();
+
+ public abstract String getImageUrl();
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/security/oauth2/user/OAuth2UserInfoFactory.java b/src/main/java/com/softserveinc/dokazovi/security/oauth2/user/OAuth2UserInfoFactory.java
new file mode 100644
index 00000000..eb8d6fdb
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/security/oauth2/user/OAuth2UserInfoFactory.java
@@ -0,0 +1,25 @@
+package com.softserveinc.dokazovi.security.oauth2.user;
+
+
+
+import com.softserveinc.dokazovi.entity.enumerations.AuthProvider;
+import com.softserveinc.dokazovi.exception.OAuth2AuthenticationProcessingException;
+
+import java.util.Map;
+
+public class OAuth2UserInfoFactory {
+
+ private OAuth2UserInfoFactory() {
+ }
+
+ public static OAuth2UserInfo getOAuth2UserInfo(String registrationId, Map attributes) {
+ if (registrationId.equalsIgnoreCase(AuthProvider.GOOGLE.toString())) {
+ return new GoogleOAuth2UserInfo(attributes);
+ } else if (registrationId.equalsIgnoreCase(AuthProvider.FACEBOOK.toString())) {
+ return new FacebookOAuth2UserInfo(attributes);
+ } else {
+ throw new OAuth2AuthenticationProcessingException("Sorry! Login with "
+ + registrationId + " is not supported yet.");
+ }
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/DirectionService.java b/src/main/java/com/softserveinc/dokazovi/service/DirectionService.java
new file mode 100644
index 00000000..3bf430ef
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/DirectionService.java
@@ -0,0 +1,16 @@
+package com.softserveinc.dokazovi.service;
+
+import com.softserveinc.dokazovi.dto.direction.DirectionDTO;
+
+import java.util.List;
+
+public interface DirectionService {
+
+ List findAllDirections();
+
+ List findAllDirectionsByUserId(Integer userId);
+
+ void updateDirectionsHasDoctorsStatus();
+
+ void updateDirectionsHasPostsStatus();
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/OriginService.java b/src/main/java/com/softserveinc/dokazovi/service/OriginService.java
new file mode 100644
index 00000000..a6b5dca2
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/OriginService.java
@@ -0,0 +1,8 @@
+package com.softserveinc.dokazovi.service;
+
+import com.softserveinc.dokazovi.dto.origin.OriginDTO;
+import java.util.List;
+
+public interface OriginService {
+ List findAllOrigins();
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/PostService.java b/src/main/java/com/softserveinc/dokazovi/service/PostService.java
new file mode 100644
index 00000000..5e429882
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/PostService.java
@@ -0,0 +1,44 @@
+package com.softserveinc.dokazovi.service;
+
+import com.softserveinc.dokazovi.dto.post.PostDTO;
+import com.softserveinc.dokazovi.dto.post.PostMainPageDTO;
+import com.softserveinc.dokazovi.dto.post.PostSaveFromUserDTO;
+import com.softserveinc.dokazovi.entity.enumerations.PostStatus;
+import com.softserveinc.dokazovi.security.UserPrincipal;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+import java.util.Set;
+
+public interface PostService {
+
+ PostDTO findPostById(Integer postId);
+
+ Page findAllByStatus(PostStatus postStatus, Pageable pageable);
+
+ Page findImportantPosts(Pageable pageable);
+
+ Page findAllByDirection(
+ Integer directionId, Set typeId, Set tagId, PostStatus postStatus, Pageable pageable);
+
+ PostDTO saveFromUser(PostSaveFromUserDTO postSaveDTO, UserPrincipal user);
+
+ Page findAllByDirectionsAndByPostTypesAndByOrigins(
+ Set directionId, Set typeId, Set originId, Pageable pageable);
+
+ Page findPostsByAuthorIdAndDirections(
+ Pageable pageable, Integer expertId, Set directions);
+
+ Boolean archivePostById(UserPrincipal userId, Integer postId);
+
+ Boolean updatePostById(UserPrincipal userId, PostSaveFromUserDTO postSaveDTO);
+
+ Page findLatestByPostTypesAndOrigins(Pageable pageable);
+
+ Page findAllByExpertAndTypeAndDirections(Integer expertId, Set typeId, Set directionId,
+ Pageable pageable);
+
+ Boolean setPostsAsImportantWithOrder(Set importantPostIds);
+
+ Integer getPostViewCount(String url);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/PostTypeService.java b/src/main/java/com/softserveinc/dokazovi/service/PostTypeService.java
new file mode 100644
index 00000000..21e4af98
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/PostTypeService.java
@@ -0,0 +1,12 @@
+package com.softserveinc.dokazovi.service;
+
+import com.softserveinc.dokazovi.dto.post.PostTypeDTO;
+
+import java.util.List;
+
+public interface PostTypeService {
+
+ List findAll();
+
+ List findAllPostTypesByUserId(Integer userId);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/ProviderService.java b/src/main/java/com/softserveinc/dokazovi/service/ProviderService.java
new file mode 100644
index 00000000..d105ab5b
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/ProviderService.java
@@ -0,0 +1,14 @@
+package com.softserveinc.dokazovi.service;
+
+import com.softserveinc.dokazovi.entity.ProviderEntity;
+import com.softserveinc.dokazovi.entity.UserEntity;
+
+import java.util.Optional;
+
+public interface ProviderService {
+
+ Optional createLocalProviderEntityForUser(UserEntity userEntity, String email);
+
+ boolean existsByLocalEmail(String email);
+
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/RegionService.java b/src/main/java/com/softserveinc/dokazovi/service/RegionService.java
new file mode 100644
index 00000000..a14d9b21
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/RegionService.java
@@ -0,0 +1,12 @@
+package com.softserveinc.dokazovi.service;
+
+import com.softserveinc.dokazovi.dto.region.RegionDTO;
+
+import java.util.List;
+
+public interface RegionService {
+
+ List findAllRegions();
+
+ public void updateRegionsStatus();
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/TagService.java b/src/main/java/com/softserveinc/dokazovi/service/TagService.java
new file mode 100644
index 00000000..0e39bc2c
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/TagService.java
@@ -0,0 +1,13 @@
+package com.softserveinc.dokazovi.service;
+
+import com.softserveinc.dokazovi.dto.tag.TagDTO;
+import com.softserveinc.dokazovi.dto.tag.TagSaveDTO;
+
+import java.util.List;
+
+public interface TagService {
+
+ TagDTO save(TagSaveDTO tagSaveDTO);
+
+ List findTagsByValue(String value, Integer limit);
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/UserService.java b/src/main/java/com/softserveinc/dokazovi/service/UserService.java
new file mode 100644
index 00000000..39a4ae02
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/UserService.java
@@ -0,0 +1,30 @@
+package com.softserveinc.dokazovi.service;
+
+import com.softserveinc.dokazovi.dto.user.UserDTO;
+import com.softserveinc.dokazovi.entity.UserEntity;
+import com.softserveinc.dokazovi.entity.VerificationToken;
+import com.softserveinc.dokazovi.pojo.UserSearchCriteria;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+import java.util.Set;
+
+public interface UserService {
+
+ UserEntity findByEmail(String email);
+
+ Page findAll(Pageable pageable);
+
+ UserDTO findExpertById(Integer userId);
+
+ Page findAllExperts(UserSearchCriteria userSearchCriteria, Pageable pageable);
+
+ Page findRandomExpertPreview(Set directionsIds, Pageable pageable);
+
+ void setEnableTrue(UserEntity user);
+
+ void createVerificationToken(UserEntity user, String token);
+
+ VerificationToken getVerificationToken(String verificationToken);
+
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/impl/DirectionServiceImpl.java b/src/main/java/com/softserveinc/dokazovi/service/impl/DirectionServiceImpl.java
new file mode 100644
index 00000000..e67da6f1
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/impl/DirectionServiceImpl.java
@@ -0,0 +1,74 @@
+package com.softserveinc.dokazovi.service.impl;
+
+import com.softserveinc.dokazovi.dto.direction.DirectionDTO;
+import com.softserveinc.dokazovi.mapper.DirectionMapper;
+import com.softserveinc.dokazovi.repositories.DirectionRepository;
+import com.softserveinc.dokazovi.service.DirectionService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import javax.transaction.Transactional;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * The DirectionServiceImpl is responsible for doing any required logic
+ * with the direction data received by the Direction Controller.
+ * It provides logic to operate on the data sent to and from the Direction repository.
+ */
+
+@Service
+@RequiredArgsConstructor
+public class DirectionServiceImpl implements DirectionService {
+
+ private final DirectionRepository directionRepository;
+ private final DirectionMapper directionMapper;
+
+ /**
+ * Gets all directions.
+ *
+ * @return all found directions
+ */
+ @Override
+ public List findAllDirections() {
+ return directionRepository.findAll().stream()
+ .map(directionMapper::toDirectionDTO)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Gets all directions by user id.
+ *
+ * @param userId received from Directions controller
+ * @return found directions by user id from directions repository
+ */
+ @Override
+ public List findAllDirectionsByUserId(Integer userId) {
+ return directionRepository.findAllDirectionsByUserId(userId).stream()
+ .map(directionMapper::toDirectionDTO)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Updates the directions status depending on the availability of doctors in it.
+ * Runs every four hours
+ */
+ @Override
+ @Transactional
+ @Scheduled(cron = "0 0 */4 * * *")
+ public void updateDirectionsHasDoctorsStatus() {
+ directionRepository.updateDirectionsHasDoctorsStatus();
+ }
+
+ /**
+ * Updates the directions status depending on the availability of posts in it.
+ * Runs every four hours
+ */
+ @Override
+ @Transactional
+ public void updateDirectionsHasPostsStatus() {
+ directionRepository.updateDirectionsHasPostsStatus();
+ }
+
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/impl/OriginServiceImpl.java b/src/main/java/com/softserveinc/dokazovi/service/impl/OriginServiceImpl.java
new file mode 100644
index 00000000..dece51cb
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/impl/OriginServiceImpl.java
@@ -0,0 +1,35 @@
+package com.softserveinc.dokazovi.service.impl;
+
+import com.softserveinc.dokazovi.dto.origin.OriginDTO;
+import com.softserveinc.dokazovi.mapper.OriginMapper;
+import com.softserveinc.dokazovi.repositories.OriginRepository;
+import com.softserveinc.dokazovi.service.OriginService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * The OriginServiceImpl is responsible for doing any logic
+ * required with the origin data received by the Origin Controller.
+ * It provides logic to operate on the data sent to and from the Origin repository.
+ */
+@Service
+@RequiredArgsConstructor
+public class OriginServiceImpl implements OriginService {
+
+ private final OriginRepository originRepository;
+ private final OriginMapper originMapper;
+
+ /**
+ * Find all origins.
+ *
+ * @return list of all origins
+ */
+ @Override
+ public List findAllOrigins() {
+ return originRepository.findAll().stream()
+ .map(originMapper::toOriginDTO)
+ .collect(Collectors.toList());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/softserveinc/dokazovi/service/impl/PostServiceImpl.java b/src/main/java/com/softserveinc/dokazovi/service/impl/PostServiceImpl.java
new file mode 100644
index 00000000..322c1f5d
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/impl/PostServiceImpl.java
@@ -0,0 +1,307 @@
+package com.softserveinc.dokazovi.service.impl;
+
+import com.softserveinc.dokazovi.analytics.GoogleAnalytics;
+import com.softserveinc.dokazovi.dto.post.PostDTO;
+import com.softserveinc.dokazovi.dto.post.PostMainPageDTO;
+import com.softserveinc.dokazovi.dto.post.PostSaveFromUserDTO;
+import com.softserveinc.dokazovi.entity.DirectionEntity;
+import com.softserveinc.dokazovi.entity.PostEntity;
+import com.softserveinc.dokazovi.entity.UserEntity;
+import com.softserveinc.dokazovi.entity.enumerations.PostStatus;
+import com.softserveinc.dokazovi.exception.EntityNotFoundException;
+import com.softserveinc.dokazovi.exception.ForbiddenPermissionsException;
+import com.softserveinc.dokazovi.mapper.PostMapper;
+import com.softserveinc.dokazovi.repositories.DirectionRepository;
+import com.softserveinc.dokazovi.repositories.OriginRepository;
+import com.softserveinc.dokazovi.repositories.PostRepository;
+import com.softserveinc.dokazovi.repositories.PostTypeRepository;
+import com.softserveinc.dokazovi.repositories.UserRepository;
+import com.softserveinc.dokazovi.security.UserPrincipal;
+import com.softserveinc.dokazovi.service.PostService;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+import org.springframework.transaction.annotation.Transactional;
+
+import java.sql.Timestamp;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Service
+@RequiredArgsConstructor
+public class PostServiceImpl implements PostService {
+
+ private static final Logger logger = LoggerFactory.getLogger(PostServiceImpl.class);
+
+ private final PostRepository postRepository;
+ private final PostMapper postMapper;
+ private final UserRepository userRepository;
+ private final PostTypeRepository postTypeRepository;
+ private final DirectionRepository directionRepository;
+ private final OriginRepository originRepository;
+ private final GoogleAnalytics googleAnalytics;
+
+ @Override
+ public PostDTO findPostById(Integer postId) {
+ return postMapper.toPostDTO(postRepository.findById(postId).orElse(null));
+ }
+
+ @Override
+ public PostDTO saveFromUser(PostSaveFromUserDTO postDTO, UserPrincipal userPrincipal) {
+ PostEntity mappedEntity = getPostEntityFromPostDTO(postDTO);
+
+ UserEntity userEntity = userRepository.getOne(userPrincipal.getId());
+ mappedEntity.setImportant(false);
+
+ mappedEntity.setCreatedAt(Timestamp.valueOf(LocalDateTime.now()));
+
+ if (userEntity.getId().equals(postDTO.getAuthorId()) && userPrincipal.getAuthorities().stream()
+ .anyMatch(grantedAuthority -> grantedAuthority
+ .getAuthority().equals("SAVE_OWN_PUBLICATION"))) {
+ mappedEntity.setStatus(PostStatus.PUBLISHED);
+ mappedEntity.setAuthor(userEntity);
+ return postMapper.toPostDTO(postRepository.save(mappedEntity));
+ }
+
+ if (!userEntity.getId().equals(postDTO.getAuthorId()) && userPrincipal.getAuthorities()
+ .stream().anyMatch(grantedAuthority ->
+ grantedAuthority.getAuthority().equals("SAVE_PUBLICATION"))) {
+ mappedEntity.setStatus(PostStatus.PUBLISHED);
+ mappedEntity.setAuthor(userRepository.getOne(postDTO.getAuthorId()));
+ return postMapper.toPostDTO(postRepository.save(mappedEntity));
+ }
+
+ if (!userEntity.getId().equals(postDTO.getAuthorId()) || userPrincipal.getAuthorities().stream()
+ .noneMatch(grantedAuthority ->
+ grantedAuthority.getAuthority().equals("SAVE_OWN_PUBLICATION"))
+ && userPrincipal.getAuthorities().stream().noneMatch(grantedAuthority ->
+ grantedAuthority.getAuthority().equals("SAVE_PUBLICATION"))) {
+ throw new ForbiddenPermissionsException();
+ }
+ directionRepository.updateDirectionsHasPostsStatus();
+ return postMapper.toPostDTO(mappedEntity);
+ }
+
+ @Override
+ public Page findAllByDirectionsAndByPostTypesAndByOrigins(Set directionIds, Set typeIds,
+ Set originIds, Pageable pageable) {
+ if (directionIds == null && typeIds == null && originIds == null) {
+ return postRepository.findAll(pageable)
+ .map(postMapper::toPostDTO);
+ }
+ Set directions = validateIdsValues(directionIds);
+ Set types = validateIdsValues(typeIds);
+ Set origins = validateIdsValues(originIds);
+ try {
+ return postRepository.findAllByDirectionsAndByPostTypesAndByOrigins(types, origins, directions, pageable)
+ .map(postMapper::toPostDTO);
+ } catch (Exception e) {
+ logger.error(String.format("Fail with posts filter with params directionIds=%s, typeIds=%s, originIds=%s",
+ directionIds, typeIds, originIds));
+ throw new EntityNotFoundException("Id does not exist");
+ }
+ }
+
+ private Set validateIdsValues(Set ids) {
+ return ids != null ? ids : new HashSet<>();
+ }
+
+ @Override
+ public Page findAllByStatus(PostStatus postStatus, Pageable pageable) {
+ return postRepository.findAllByStatus(postStatus, pageable)
+ .map(postMapper::toPostDTO);
+ }
+
+ @Override
+ public Page findImportantPosts(Pageable pageable) {
+ return postRepository.findAllByImportantIsTrueAndStatus(PostStatus.PUBLISHED, pageable)
+ .map(postMapper::toPostDTO);
+ }
+
+ @Override
+ public Page findAllByDirection(
+ Integer directionId, Set typeId, Set tagId, PostStatus postStatus, Pageable pageable) {
+ DirectionEntity direction = DirectionEntity.builder()
+ .id(directionId)
+ .build();
+ if (typeId == null && tagId == null) {
+ return postRepository.findAllByDirectionsContainsAndStatus(direction, postStatus, pageable)
+ .map(postMapper::toPostDTO);
+ } else if (typeId == null) {
+ return postRepository.findAllByDirectionsContainsAndTagsIdInAndStatus(
+ direction, tagId, postStatus, pageable)
+ .map(postMapper::toPostDTO);
+ } else if (tagId == null) {
+ return postRepository.findAllByDirectionsContainsAndTypeIdInAndStatus(
+ direction, typeId, postStatus, pageable)
+ .map(postMapper::toPostDTO);
+ }
+ return postRepository.findAllByDirectionsContainsAndTypeIdInAndTagsIdInAndStatus(
+ direction, typeId, tagId, postStatus, pageable)
+ .map(postMapper::toPostDTO);
+ }
+
+ @Override
+ public Page findPostsByAuthorIdAndDirections(
+ Pageable pageable, Integer authorId, Set directions) {
+
+ return postRepository.findPostsByAuthorIdAndDirections(pageable, authorId, directions)
+ .map(postMapper::toPostDTO);
+ }
+
+ @Override
+ @Transactional
+ public Boolean archivePostById(UserPrincipal userPrincipal, Integer postId)
+ throws EntityNotFoundException {
+
+ PostEntity mappedEntity = postRepository
+ .findById(postId)
+ .orElseThrow(() -> new EntityNotFoundException(String.format("Post with %s not found", postId)));
+
+ Integer userId = userPrincipal.getId();
+ Integer authorId = mappedEntity.getAuthor().getId();
+
+ if (userId.equals(authorId) && userPrincipal.getAuthorities().stream().anyMatch(grantedAuthority ->
+ grantedAuthority.getAuthority().equals("DELETE_OWN_POST"))) {
+ mappedEntity.setStatus(PostStatus.ARCHIVED);
+ mappedEntity.setModifiedAt(Timestamp.valueOf(LocalDateTime.now()));
+ postRepository.save(mappedEntity);
+ }
+
+ if (!userId.equals(authorId) && userPrincipal.getAuthorities().stream().anyMatch(grantedAuthority ->
+ grantedAuthority.getAuthority().equals("DELETE_POST"))) {
+ mappedEntity.setStatus(PostStatus.ARCHIVED);
+ mappedEntity.setModifiedAt(Timestamp.valueOf(LocalDateTime.now()));
+ postRepository.save(mappedEntity);
+ }
+
+ if ((!userId.equals(authorId) || userPrincipal.getAuthorities().stream().noneMatch(grantedAuthority ->
+ grantedAuthority.getAuthority().equals("DELETE_OWN_POST")))
+ && userPrincipal.getAuthorities().stream().noneMatch(grantedAuthority ->
+ grantedAuthority.getAuthority().equals("DELETE_POST"))) {
+ throw new ForbiddenPermissionsException();
+ }
+ directionRepository.updateDirectionsHasPostsStatus();
+ return true;
+ }
+
+ @Override
+ @Transactional
+ public Boolean updatePostById(UserPrincipal userPrincipal, PostSaveFromUserDTO postDTO)
+ throws EntityNotFoundException {
+
+ PostEntity mappedEntity = getPostEntityFromPostDTO(postDTO);
+ mappedEntity.setModifiedAt(Timestamp.valueOf(LocalDateTime.now()));
+
+ Integer userId = userPrincipal.getId();
+ Integer authorId = mappedEntity.getAuthor().getId();
+
+ if (userId.equals(authorId) && checkAuthority(userPrincipal, "UPDATE_OWN_POST")) {
+ mappedEntity.setStatus(PostStatus.PUBLISHED);
+ saveEntity(mappedEntity);
+ } else if (!userId.equals(authorId) && checkAuthority(userPrincipal, "UPDATE_POST")) {
+ mappedEntity.setStatus(PostStatus.PUBLISHED);
+ mappedEntity.setAuthor(userRepository.getOne(postDTO.getAuthorId()));
+ saveEntity(mappedEntity);
+ } else {
+ throw new ForbiddenPermissionsException();
+ }
+ return true;
+ }
+
+ private void saveEntity(PostEntity mappedEntity) {
+ postRepository.save(mappedEntity);
+ directionRepository.updateDirectionsHasPostsStatus();
+ }
+
+ private boolean checkAuthority(UserPrincipal userPrincipal, String authority) {
+ return userPrincipal.getAuthorities().stream().anyMatch(grantedAuthority ->
+ grantedAuthority.getAuthority().equals(authority));
+ }
+
+ @Override
+ @Transactional
+ public Page findLatestByPostTypesAndOrigins(Pageable pageable) {
+ PostMainPageDTO expertOptions = PostMainPageDTO.builder()
+ .fieldName("expertOpinion")
+ .postDTOS(postRepository.findLatestByPostTypeExpertOpinion(PageRequest.of(pageable.getPageNumber(), 4))
+ .map(postMapper::toPostDTO).toSet()).build();
+ PostMainPageDTO media = PostMainPageDTO.builder()
+ .fieldName("media")
+ .postDTOS(postRepository.findLatestByPostTypeMedia(PageRequest.of(pageable.getPageNumber(), 4))
+ .map(postMapper::toPostDTO).toSet()).build();
+ PostMainPageDTO translation = PostMainPageDTO.builder()
+ .fieldName("translation")
+ .postDTOS(postRepository.findLatestByPostTypeTranslation(PageRequest.of(pageable.getPageNumber(), 4))
+ .map(postMapper::toPostDTO).toSet()).build();
+ PostMainPageDTO video = PostMainPageDTO.builder()
+ .fieldName("video")
+ .postDTOS(postRepository.findLatestByOriginVideo(PageRequest.of(pageable.getPageNumber(), 4))
+ .map(postMapper::toPostDTO).toSet()).build();
+
+ return new PageImpl<>(List.of(expertOptions, media, translation, video));
+ }
+
+ @Override
+ public Page findAllByExpertAndTypeAndDirections(Integer expertId, Set typeId,
+ Set directionId, Pageable pageable) {
+ if (typeId == null && directionId == null) {
+ return postRepository.findAllByAuthorIdAndStatus(expertId, PostStatus.PUBLISHED, pageable)
+ .map(postMapper::toPostDTO);
+ }
+ if (typeId == null) {
+ return postRepository.findPostsByAuthorIdAndDirections(pageable, expertId, directionId)
+ .map(postMapper::toPostDTO);
+ }
+ if (directionId == null) {
+ return postRepository
+ .findAllByAuthorIdAndTypeIdInAndStatus(expertId, typeId, PostStatus.PUBLISHED, pageable)
+ .map(postMapper::toPostDTO);
+ }
+ return postRepository.findAllByExpertAndByDirectionsAndByPostType(expertId, typeId, directionId, pageable)
+ .map(postMapper::toPostDTO);
+ }
+
+ @Override
+ @Transactional
+ public Boolean setPostsAsImportantWithOrder(Set importantPostIds) {
+ if (importantPostIds == null) {
+ return false;
+ }
+ postRepository.removeImportantPostsAndOrder(importantPostIds);
+ List importantPostIdsList = new ArrayList<>(importantPostIds);
+ for (int i = 0; i < importantPostIdsList.size(); i++) {
+ postRepository.setImportantPostOrder((i + 1), importantPostIdsList.get(i));
+ }
+ return true;
+ }
+
+
+ private PostEntity getPostEntityFromPostDTO(PostSaveFromUserDTO postDTO) {
+ Integer postId = postDTO.getId();
+ PostEntity mappedEntity;
+ if (postId == null) {
+ mappedEntity = postMapper.toPostEntity(postDTO);
+
+ } else {
+ PostEntity byId = postRepository.findById(postId)
+ .orElseThrow(EntityNotFoundException::new);
+ mappedEntity = postMapper.updatePostEntityFromDTO(postDTO, byId);
+ }
+ return mappedEntity;
+ }
+
+ @Override
+ public Integer getPostViewCount(String url) {
+ return googleAnalytics.getPostViewCount(url);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/softserveinc/dokazovi/service/impl/PostTypeServiceImpl.java b/src/main/java/com/softserveinc/dokazovi/service/impl/PostTypeServiceImpl.java
new file mode 100644
index 00000000..1f1fc7bd
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/impl/PostTypeServiceImpl.java
@@ -0,0 +1,35 @@
+package com.softserveinc.dokazovi.service.impl;
+
+import com.softserveinc.dokazovi.dto.post.PostTypeDTO;
+import com.softserveinc.dokazovi.mapper.PostTypeMapper;
+import com.softserveinc.dokazovi.repositories.PostTypeRepository;
+import com.softserveinc.dokazovi.service.PostTypeService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+@RequiredArgsConstructor
+public class PostTypeServiceImpl implements PostTypeService {
+
+ private final PostTypeRepository postTypeRepository;
+ private final PostTypeMapper postTypeMapper;
+
+ @Override
+ public List findAll() {
+ return postTypeRepository.findAll()
+ .stream()
+ .map(postTypeMapper::toPostTypeDTO)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public List findAllPostTypesByUserId(Integer userId) {
+ return postTypeRepository.findAllPostTypesByUserId(userId)
+ .stream()
+ .map(postTypeMapper::toPostTypeDTO)
+ .collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/impl/ProviderServiceImpl.java b/src/main/java/com/softserveinc/dokazovi/service/impl/ProviderServiceImpl.java
new file mode 100644
index 00000000..7c982d75
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/impl/ProviderServiceImpl.java
@@ -0,0 +1,34 @@
+package com.softserveinc.dokazovi.service.impl;
+
+import com.softserveinc.dokazovi.entity.ProviderEntity;
+import com.softserveinc.dokazovi.entity.UserEntity;
+import com.softserveinc.dokazovi.entity.enumerations.AuthProvider;
+import com.softserveinc.dokazovi.repositories.ProviderRepository;
+import com.softserveinc.dokazovi.service.ProviderService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+
+@Service
+@RequiredArgsConstructor
+public class ProviderServiceImpl implements ProviderService {
+
+ private final ProviderRepository providerRepository;
+
+ @Override
+ public Optional createLocalProviderEntityForUser(UserEntity userEntity, String email) {
+ ProviderEntity providerEntity = ProviderEntity.builder()
+ .user(userEntity)
+ .email(email)
+ .userIdByProvider(userEntity.getId().toString())
+ .name(AuthProvider.LOCAL.toString())
+ .build();
+ return Optional.of(providerRepository.save(providerEntity));
+ }
+
+ @Override
+ public boolean existsByLocalEmail(String email) {
+ return providerRepository.existsByEmailAndName(email, AuthProvider.LOCAL.name());
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/impl/RegionServiceImpl.java b/src/main/java/com/softserveinc/dokazovi/service/impl/RegionServiceImpl.java
new file mode 100644
index 00000000..f3868e34
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/impl/RegionServiceImpl.java
@@ -0,0 +1,50 @@
+package com.softserveinc.dokazovi.service.impl;
+
+import com.softserveinc.dokazovi.dto.region.RegionDTO;
+import com.softserveinc.dokazovi.mapper.RegionMapper;
+import com.softserveinc.dokazovi.repositories.RegionRepository;
+import com.softserveinc.dokazovi.service.RegionService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import javax.transaction.Transactional;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * The RegionServiceImpl is responsible for doing any required logic
+ * with the user data received by the Region Controller.
+ * It provides logic to operate on the data sent to and from the Region repository.
+ */
+
+@Service
+@RequiredArgsConstructor
+public class RegionServiceImpl implements RegionService {
+
+ private final RegionRepository regionRepository;
+ private final RegionMapper regionMapper;
+
+ /**
+ * Gets all regions.
+ *
+ * @return all found regions
+ */
+ @Override
+ public List findAllRegions() {
+ return regionRepository.findAll().stream()
+ .map(regionMapper::toRegionDTO)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Updates the region status depending on the availability of doctors in it.
+ * Runs every four hours
+ */
+ @Override
+ @Transactional
+ @Scheduled(cron = "0 0 */4 * * *")
+ public void updateRegionsStatus() {
+ regionRepository.updateRegionsStatus();
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/impl/TagServiceImpl.java b/src/main/java/com/softserveinc/dokazovi/service/impl/TagServiceImpl.java
new file mode 100644
index 00000000..64940680
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/impl/TagServiceImpl.java
@@ -0,0 +1,38 @@
+package com.softserveinc.dokazovi.service.impl;
+
+import com.softserveinc.dokazovi.dto.tag.TagDTO;
+import com.softserveinc.dokazovi.dto.tag.TagSaveDTO;
+import com.softserveinc.dokazovi.entity.TagEntity;
+import com.softserveinc.dokazovi.mapper.TagMapper;
+import com.softserveinc.dokazovi.repositories.TagRepository;
+import com.softserveinc.dokazovi.service.TagService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+@RequiredArgsConstructor
+public class TagServiceImpl implements TagService {
+
+ private final TagRepository tagRepository;
+ private final TagMapper tagMapper;
+
+ @CacheEvict(value = "tags", allEntries = true)
+ public TagDTO save(TagSaveDTO tagSaveDTO) {
+ TagEntity tagEntity = tagRepository.save(tagMapper.toTagEntity(tagSaveDTO));
+ return tagMapper.toTagDTO(tagEntity);
+ }
+
+ public List findTagsByValue(String value, Integer limit) {
+ String filter = value.toLowerCase();
+ return tagRepository.findAll()
+ .stream()
+ .filter(tagDTO -> tagDTO.getTag().toLowerCase().contains(filter))
+ .limit(limit)
+ .map(tagMapper::toTagDTO)
+ .collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/service/impl/UserServiceImpl.java b/src/main/java/com/softserveinc/dokazovi/service/impl/UserServiceImpl.java
new file mode 100644
index 00000000..2ab02ce7
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/service/impl/UserServiceImpl.java
@@ -0,0 +1,213 @@
+package com.softserveinc.dokazovi.service.impl;
+
+import com.softserveinc.dokazovi.dto.user.UserDTO;
+import com.softserveinc.dokazovi.entity.UserEntity;
+import com.softserveinc.dokazovi.entity.VerificationToken;
+import com.softserveinc.dokazovi.exception.BadRequestException;
+import com.softserveinc.dokazovi.exception.EntityNotFoundException;
+import com.softserveinc.dokazovi.mapper.UserMapper;
+import com.softserveinc.dokazovi.pojo.UserSearchCriteria;
+import com.softserveinc.dokazovi.repositories.UserRepository;
+import com.softserveinc.dokazovi.repositories.VerificationTokenRepository;
+import com.softserveinc.dokazovi.service.UserService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import javax.transaction.Transactional;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * The UserServiceImpl is responsible for doing any required logic
+ * with the user data received by the User Controller.
+ * It provides logic to operate on the data sent to and from the User repository.
+ */
+
+@Service
+@RequiredArgsConstructor
+public class UserServiceImpl implements UserService {
+
+ private final UserRepository userRepository;
+ private final UserMapper userMapper;
+ private final VerificationTokenRepository tokenRepository;
+ private final PasswordEncoder passwordEncoder;
+
+ private static final String HAS_NO_DIRECTIONS = "hasNoDirections";
+ private static final String HAS_NO_REGIONS = "hasNoRegions";
+ private static final String HAS_NO_USERNAME = "hasNoUserName";
+
+ /**
+ * Gets user by email.
+ *
+ * @param email email of user that we want to get
+ * @return found user by email from user repository
+ */
+ @Override
+ public UserEntity findByEmail(String email) {
+ return userRepository.findByEmail(email).orElse(null);
+ }
+
+ /**
+ * Gets all users.
+ *
+ * @param pageable received from User controller
+ * @return all found users
+ */
+ @Override
+ public Page findAll(Pageable pageable) {
+ return userRepository.findAll(pageable);
+ }
+
+ /**
+ * Gets user by id.
+ *
+ * @param userId received from User controller
+ * @return found doctor by id from user repository
+ */
+ @Override
+ public UserDTO findExpertById(Integer userId) {
+ return userMapper.toUserDTO(userRepository.findById(userId).orElse(null));
+ }
+
+ /**
+ * Gets doctors by search criteria.
+ * For example, if directions, regions and user name fields
+ * are empty, the findDoctorsProfiles method without parameters is called
+ *
+ * @param userSearchCriteria received from User controller
+ * @param pageable received from User controller
+ * @return found doctor by criteria
+ */
+ @Override
+ @Transactional
+ public Page findAllExperts(UserSearchCriteria userSearchCriteria, Pageable pageable) {
+
+ if (validateParameters(userSearchCriteria, HAS_NO_DIRECTIONS, HAS_NO_REGIONS, HAS_NO_USERNAME)) {
+ return userRepository.findDoctorsProfiles(pageable).map(userMapper::toUserDTO);
+ }
+
+ List userName = userSearchCriteria.getUserNameList();
+
+ if ((validateParameters(userSearchCriteria, HAS_NO_DIRECTIONS, HAS_NO_REGIONS)) && userName.size() == 1) {
+ final String name = userName.get(0);
+ return userRepository.findDoctorsByName(name, pageable).map(userMapper::toUserDTO);
+ }
+
+ if ((validateParameters(userSearchCriteria, HAS_NO_DIRECTIONS, HAS_NO_REGIONS)) && userName.size() == 2) {
+ final String firstName = userName.get(0);
+ final String lastName = userName.get(1);
+ return userRepository.findDoctorsByName(firstName, lastName, pageable).map(userMapper::toUserDTO);
+ }
+
+ if ((validateParameters(userSearchCriteria, HAS_NO_DIRECTIONS, HAS_NO_USERNAME))) {
+ return userRepository.findDoctorsProfilesByRegionsIds(
+ userSearchCriteria.getRegions(), pageable)
+ .map(userMapper::toUserDTO);
+ }
+
+ if ((validateParameters(userSearchCriteria, HAS_NO_REGIONS, HAS_NO_USERNAME))) {
+ return userRepository.findDoctorsProfilesByDirectionsIds(
+ userSearchCriteria.getDirections(), pageable)
+ .map(userMapper::toUserDTO);
+ }
+
+ if ((validateParameters(userSearchCriteria, HAS_NO_USERNAME))) {
+ return userRepository
+ .findDoctorsProfiles(userSearchCriteria.getDirections(), userSearchCriteria.getRegions(), pageable)
+ .map(userMapper::toUserDTO);
+ }
+
+ throw new EntityNotFoundException("Wrong search parameters");
+ }
+
+ private boolean validateParameters(UserSearchCriteria userSearchCriteria, String... args) {
+
+ if (args.length == 3) {
+ return !userSearchCriteria.hasName() && !userSearchCriteria.hasRegions() && !userSearchCriteria
+ .hasDirections();
+ }
+
+ if (args.length == 2 && args[0].contains(HAS_NO_DIRECTIONS) && args[1].contains(HAS_NO_REGIONS)) {
+ return !userSearchCriteria.hasRegions() && !userSearchCriteria.hasDirections();
+ }
+
+ if (args.length == 2 && args[0].contains(HAS_NO_DIRECTIONS) && args[1].contains(HAS_NO_USERNAME)) {
+ return !userSearchCriteria.hasDirections() && !userSearchCriteria.hasName();
+ }
+
+ if (args.length == 2 && args[0].contains(HAS_NO_REGIONS) && args[1].contains(HAS_NO_USERNAME)) {
+
+ return !userSearchCriteria.hasRegions() && !userSearchCriteria.hasName();
+ }
+
+ if (args.length == 1 && args[0].contains(HAS_NO_USERNAME)) {
+ return !userSearchCriteria.hasName();
+ }
+
+ return false;
+ }
+
+ /**
+ * Gets random experts by directions.
+ * If directions are empty, gets random experts without filters
+ *
+ * @param directionsIds the directions ids received from User controller
+ * @param pageable received from User controller
+ * @return found doctor by directions
+ */
+ @Override
+ public Page findRandomExpertPreview(Set directionsIds, Pageable pageable) {
+ if (CollectionUtils.isEmpty(directionsIds)) {
+ return userRepository.findRandomExperts(pageable)
+ .map(userMapper::toUserDTO);
+ }
+
+ return userRepository.findRandomExpertsByDirectionsIdIn(directionsIds, pageable)
+ .map(userMapper::toUserDTO);
+ }
+
+ /**
+ * Sets the user is enabled.
+ *
+ * @param user user received from Auth controller
+ */
+ @Override
+ public void setEnableTrue(UserEntity user) {
+ UserEntity userEntity = userRepository.findById(user.getId()).orElse(null);
+ if (userEntity == null) {
+ throw new BadRequestException("Something went wrong!!!");
+ }
+ userEntity.setEnabled(true);
+ userRepository.save(userEntity);
+ }
+
+ /**
+ * Gets the verification token received from tokenRepository.
+ *
+ * @param verificationToken received from Auth controller
+ * @return found VerificationToken
+ */
+ @Override
+ public VerificationToken getVerificationToken(String verificationToken) {
+ return tokenRepository.findByToken(verificationToken);
+ }
+
+ /**
+ * Gets the verification token received from tokenRepository.
+ *
+ * @param user user received from Mail Sender
+ * @param token token received from Mail Sender
+ */
+ @Override
+ public void createVerificationToken(UserEntity user, String token) {
+ VerificationToken myToken = VerificationToken.builder()
+ .user(user)
+ .token(token)
+ .build();
+ tokenRepository.save(myToken);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/util/BuildVersion.java b/src/main/java/com/softserveinc/dokazovi/util/BuildVersion.java
deleted file mode 100644
index 0ad81483..00000000
--- a/src/main/java/com/softserveinc/dokazovi/util/BuildVersion.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.softserveinc.dokazovi.util;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-@Component
-public class BuildVersion {
-
- @Value("${info.build.version}")
- private String version;
-
- public String getVersion() {
- return version;
- }
-
- public void setVersion(String version) {
- this.version = version;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/softserveinc/dokazovi/util/CookieUtils.java b/src/main/java/com/softserveinc/dokazovi/util/CookieUtils.java
new file mode 100644
index 00000000..13425c82
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/util/CookieUtils.java
@@ -0,0 +1,61 @@
+package com.softserveinc.dokazovi.util;
+
+import org.springframework.util.SerializationUtils;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Base64;
+import java.util.Optional;
+
+public class CookieUtils {
+
+ private CookieUtils() {
+ }
+
+ public static Optional getCookie(HttpServletRequest request, String name) {
+ Cookie[] cookies = request.getCookies();
+
+ if (cookies != null && cookies.length > 0) {
+ for (Cookie cookie : cookies) {
+ if (cookie.getName().equals(name)) {
+ return Optional.of(cookie);
+ }
+ }
+ }
+ return Optional.empty();
+ }
+
+ public static void addCookie(HttpServletResponse response, String name, String value, int maxAge) {
+ Cookie cookie = new Cookie(name, value);
+ cookie.setPath("/");
+ cookie.setHttpOnly(true);
+ cookie.setMaxAge(maxAge);
+ response.addCookie(cookie);
+ }
+
+ public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String name) {
+ Cookie[] cookies = request.getCookies();
+ if (cookies != null && cookies.length > 0) {
+ for (Cookie cookie : cookies) {
+ if (cookie.getName().equals(name)) {
+ cookie.setValue("");
+ cookie.setPath("/");
+ cookie.setMaxAge(0);
+ response.addCookie(cookie);
+ }
+ }
+ }
+ }
+
+ public static String serialize(Object object) {
+ return Base64.getUrlEncoder()
+ .encodeToString(SerializationUtils.serialize(object));
+ }
+
+ public static T deserialize(Cookie cookie, Class cls) {
+ return cls.cast(SerializationUtils.deserialize(
+ Base64.getUrlDecoder().decode(cookie.getValue())));
+ }
+
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/util/MailSenderUtil.java b/src/main/java/com/softserveinc/dokazovi/util/MailSenderUtil.java
new file mode 100644
index 00000000..c53ab722
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/util/MailSenderUtil.java
@@ -0,0 +1,45 @@
+package com.softserveinc.dokazovi.util;
+
+import com.softserveinc.dokazovi.entity.UserEntity;
+import com.softserveinc.dokazovi.service.UserService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.MimeMessageHelper;
+import org.springframework.stereotype.Component;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.text.MessageFormat;
+import java.util.UUID;
+
+@Component
+@RequiredArgsConstructor
+public class MailSenderUtil {
+ private final JavaMailSender javaMailSender;
+ private final UserService userService;
+ @Value("${host.url}")
+ private String hostUrl;
+
+ public void sendMessage(UserEntity user) throws IOException, MessagingException {
+ String token = UUID.randomUUID().toString();
+ userService.createVerificationToken(user, token);
+ String confirmationUrl = hostUrl + "/api/auth/verification?token=" + token;
+ MimeMessage message = javaMailSender.createMimeMessage();
+ MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8");
+ String template = readHtmlFile("verificationMail.html");
+ template = MessageFormat.format(template, confirmationUrl);
+ message.setContent(template, "text/html");
+ helper.setTo(user.getEmail());
+ helper.setSubject("DOKAZOVI");
+ javaMailSender.send(message);
+ }
+
+ public String readHtmlFile(String fileName) throws IOException {
+ String file = "src/main/resources/template/" + fileName;
+ return Files.readString(Path.of(file));
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/util/StringToNameParser.java b/src/main/java/com/softserveinc/dokazovi/util/StringToNameParser.java
new file mode 100644
index 00000000..94d141e4
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/util/StringToNameParser.java
@@ -0,0 +1,44 @@
+package com.softserveinc.dokazovi.util;
+
+import com.softserveinc.dokazovi.dto.payload.SignUpRequest;
+import com.softserveinc.dokazovi.entity.UserEntity;
+import com.softserveinc.dokazovi.security.oauth2.user.OAuth2UserInfo;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class StringToNameParser {
+
+ private StringToNameParser() {
+ }
+
+ public static void setUserNameFromRequest(SignUpRequest signUpRequest, UserEntity user) {
+ List strings = Arrays.asList(signUpRequest.getName().split(" "));
+ parseString(strings, user);
+ }
+
+ public static void setUserNameFromRequest(OAuth2UserInfo oauth2UserInfo, UserEntity user) {
+ List strings = Arrays.asList(oauth2UserInfo.getName().split(" "));
+ parseString(strings, user);
+ }
+
+ public static void parseString(List strings, UserEntity user) {
+ if (strings.isEmpty()) {
+ user.setFirstName("user");
+ }
+ if (strings.size() == 2) {
+ user.setFirstName(strings.get(0));
+ user.setLastName(strings.get(1));
+ }
+ if (strings.size() != 2) {
+ for (String n : strings) {
+ if ((user.getFirstName() == null)) {
+ user.setFirstName(n);
+ } else {
+ user.setFirstName(user.getFirstName() + " " + n);
+ }
+ }
+ }
+
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/validator/DirectionExistsValidator.java b/src/main/java/com/softserveinc/dokazovi/validator/DirectionExistsValidator.java
new file mode 100644
index 00000000..f4bc40d9
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/validator/DirectionExistsValidator.java
@@ -0,0 +1,38 @@
+package com.softserveinc.dokazovi.validator;
+
+import com.softserveinc.dokazovi.annotations.DirectionExists;
+import com.softserveinc.dokazovi.dto.direction.DirectionDTOForSavingPost;
+import com.softserveinc.dokazovi.repositories.DirectionRepository;
+import lombok.RequiredArgsConstructor;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * The DirectionExistsValidator is responsible for validation
+ * a Direction DTO. It defines the logic to validate if the direction exists.
+ */
+
+@RequiredArgsConstructor
+public class DirectionExistsValidator implements ConstraintValidator {
+
+ private final DirectionRepository repository;
+
+ /**
+ * Validates the Direction DTO for saving post.
+ * If direction id is zero, it returns "false".
+ *
+ * @param value DirectionDTOForSavingPost to validate
+ * @param context context in which the constraint is evaluated
+ * @return true or false
+ */
+
+ @Override
+ public boolean isValid(DirectionDTOForSavingPost value, ConstraintValidatorContext context) {
+ Integer id = value.getId();
+ if (id == null) {
+ return false;
+ }
+ return repository.existsById(id);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/validator/OriginExistsValidator.java b/src/main/java/com/softserveinc/dokazovi/validator/OriginExistsValidator.java
new file mode 100644
index 00000000..d928669a
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/validator/OriginExistsValidator.java
@@ -0,0 +1,23 @@
+package com.softserveinc.dokazovi.validator;
+
+import com.softserveinc.dokazovi.annotations.OriginExists;
+import com.softserveinc.dokazovi.dto.origin.OriginDTOForSavingPost;
+import com.softserveinc.dokazovi.repositories.OriginRepository;
+import lombok.RequiredArgsConstructor;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+@RequiredArgsConstructor
+public class OriginExistsValidator implements ConstraintValidator {
+ private final OriginRepository repository;
+
+ @Override
+ public boolean isValid(OriginDTOForSavingPost value, ConstraintValidatorContext context) {
+ Integer id = value.getId();
+ if (id == null) {
+ return false;
+ }
+ return repository.existsById(id);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/validator/PostTypeExistsValidator.java b/src/main/java/com/softserveinc/dokazovi/validator/PostTypeExistsValidator.java
new file mode 100644
index 00000000..82872332
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/validator/PostTypeExistsValidator.java
@@ -0,0 +1,27 @@
+package com.softserveinc.dokazovi.validator;
+
+import com.softserveinc.dokazovi.annotations.PostTypeExists;
+import com.softserveinc.dokazovi.dto.post.PostTypeIdOnlyDTO;
+import com.softserveinc.dokazovi.repositories.PostTypeRepository;
+import lombok.RequiredArgsConstructor;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+@RequiredArgsConstructor
+public class PostTypeExistsValidator implements ConstraintValidator {
+
+ private final PostTypeRepository repository;
+
+ @Override
+ public boolean isValid(PostTypeIdOnlyDTO value, ConstraintValidatorContext context) {
+ if (value == null) {
+ return true;
+ }
+ Integer id = value.getId();
+ if (id == null) {
+ return false;
+ }
+ return repository.existsById(id);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/validator/TagExistsValidator.java b/src/main/java/com/softserveinc/dokazovi/validator/TagExistsValidator.java
new file mode 100644
index 00000000..48b33eee
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/validator/TagExistsValidator.java
@@ -0,0 +1,24 @@
+package com.softserveinc.dokazovi.validator;
+
+import com.softserveinc.dokazovi.annotations.TagExists;
+import com.softserveinc.dokazovi.dto.tag.TagDTO;
+import com.softserveinc.dokazovi.repositories.TagRepository;
+import lombok.RequiredArgsConstructor;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+@RequiredArgsConstructor
+public class TagExistsValidator implements ConstraintValidator {
+
+ private final TagRepository repository;
+
+ @Override
+ public boolean isValid(TagDTO value, ConstraintValidatorContext context) {
+ Integer id = value.getId();
+ if (id == null) {
+ return false;
+ }
+ return repository.existsById(id);
+ }
+}
diff --git a/src/main/java/com/softserveinc/dokazovi/validator/TagUniqueValidator.java b/src/main/java/com/softserveinc/dokazovi/validator/TagUniqueValidator.java
new file mode 100644
index 00000000..7cd20055
--- /dev/null
+++ b/src/main/java/com/softserveinc/dokazovi/validator/TagUniqueValidator.java
@@ -0,0 +1,30 @@
+package com.softserveinc.dokazovi.validator;
+
+import com.softserveinc.dokazovi.annotations.TagUnique;
+import com.softserveinc.dokazovi.entity.TagEntity;
+import com.softserveinc.dokazovi.repositories.TagRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.ignoreCase;
+
+@RequiredArgsConstructor
+public class TagUniqueValidator implements ConstraintValidator {
+
+ private final TagRepository repository;
+ private final ExampleMatcher modelMatcher = ExampleMatcher.matching()
+ .withIgnorePaths("id")
+ .withMatcher("tag", ignoreCase());
+
+ @Override
+ public boolean isValid(String value, ConstraintValidatorContext context) {
+ TagEntity tagEntity = TagEntity.builder()
+ .tag(value)
+ .build();
+ return !repository.exists(Example.of(tagEntity, modelMatcher));
+ }
+}
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
new file mode 100644
index 00000000..fef26bc9
--- /dev/null
+++ b/src/main/resources/application-dev.properties
@@ -0,0 +1 @@
+spring.flyway.locations=classpath:/db/migration,classpath:/db/testdata
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 3bd16014..a4813ba9 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,5 +1,40 @@
+spring.profiles.active=${SPRING_PROFILE:dev}
+logging.level.io.swagger.models.parameters.AbstractSerializableParameter=ERROR
+spring.jackson.serialization.fail-on-empty-beans=false
+server.servlet.context-path=/api
+server.port=${PORT:8080}
+endpoints.cors=${ALLOWED_ORIGIN: http://localhost:3000, https://dokazovi-fe.herokuapp.com, http://127.0.0.1:3000,\
+ http://127.0.0.2:3000}
+analytics.creds=${GOOGLE_CREDENTIALS}
+
+#-------------------------
+# Database PostgresSQL
+#-------------------------
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=${DATASOURCE_URL:jdbc:postgresql://localhost:5432/dokazovi}
spring.datasource.username=${DATASOURCE_USER:dokazovi}
spring.datasource.password=${DATASOURCE_PASSWORD:dokazovi}
-info.build.version=${BUILD_VERSION:0.0.0}
\ No newline at end of file
+spring.jpa.database-platform=${SPRING_JPA_DATABASE_PLATFORM:org.hibernate.dialect.PostgreSQLDialect}
+spring.jpa.show-sql=false
+
+#-------------------------
+# FileSystem settings
+#-------------------------
+url.assets.path = ${URL_RESOURCE_PATH:assets}
+fs.root = ${FS_RESOURCE_PATH:C://dokazovi//assets//}
+fs.images = ${fs.root}images
+
+#-------------------------
+# JavaMail Configuration
+#-------------------------
+host.url=${HOST_URL:http://localhost:8080}
+support.email=${JAVA_MAIL_SUPPORT}
+spring.mail.host=smtp.gmail.com
+spring.mail.port=465
+spring.mail.protocol=smtps
+spring.mail.username=${JAVA_MAIL_USERNAME}
+spring.mail.password=${JAVA_MAIL_PASSWORD}
+spring.mail.properties.mail.transport.protocol=smtps
+spring.mail.properties.mail.smtps.auth=true
+spring.mail.properties.mail.smtps.starttls.enable=true
+spring.mail.properties.mail.smtps.timeout=8000
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 00000000..d9b443ac
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,31 @@
+spring:
+ security:
+ oauth2:
+ client:
+ registration:
+ google:
+ clientId: ${GOOGLE_CLIENT_ID}
+ clientSecret: ${GOOGLE_CLIENT_SECRET}
+ scope:
+ - email
+ - profile
+ facebook:
+ clientId: ${FACEBOOK_CLIENT_ID}
+ clientSecret: ${FACEBOOK_CLIENT_SECRET}
+ scope:
+ - email
+ - public_profile
+ provider:
+ facebook:
+ authorizationUri: https://www.facebook.com/v9.0/dialog/oauth
+ tokenUri: https://graph.facebook.com/v9.0/oauth/access_token
+ userInfoUri: https://graph.facebook.com/v9.0/me?fields=id,first_name,middle_name,last_name,name,email,verified,is_verified,picture.width(250).height(250)
+app:
+ auth:
+ tokenSecret: 926D96C90030DD58429D2751AC1BDBBC
+ tokenExpirationMsec: 864000000
+ oauth2:
+ authorizedRedirectUris:
+ - http://localhost:3000/oauth2/redirect
+ - http://localhost:3001/oauth2/redirect
+
diff --git a/src/main/resources/db/migration/V10__add_importanceOrder_to_posts.sql b/src/main/resources/db/migration/V10__add_importanceOrder_to_posts.sql
new file mode 100644
index 00000000..0eb08db4
--- /dev/null
+++ b/src/main/resources/db/migration/V10__add_importanceOrder_to_posts.sql
@@ -0,0 +1,2 @@
+ALTER TABLE POSTS
+ ADD COLUMN IMPORTANCE_ORDER INTEGER DEFAULT NULL;
\ No newline at end of file
diff --git a/src/main/resources/db/migration/V1__init_db.sql b/src/main/resources/db/migration/V1__init_db.sql
new file mode 100644
index 00000000..bf52626e
--- /dev/null
+++ b/src/main/resources/db/migration/V1__init_db.sql
@@ -0,0 +1,213 @@
+CREATE TABLE ROLES
+(
+ ROLE_ID SERIAL NOT NULL
+ CONSTRAINT ROLES_PKEY
+ PRIMARY KEY,
+ ROLE_NAME VARCHAR
+);
+
+CREATE TABLE USERS
+(
+ USER_ID SERIAL NOT NULL
+ CONSTRAINT USERS_PKEY
+ PRIMARY KEY,
+ EMAIL VARCHAR,
+ PASSWORD VARCHAR,
+ STATUS VARCHAR,
+ FIRST_NAME VARCHAR,
+ LAST_NAME VARCHAR,
+ PHONE VARCHAR,
+ CREATED_AT TIMESTAMP DEFAULT NOW(),
+ AVATAR VARCHAR,
+ ENABLED BOOLEAN,
+ ROLE_ID INTEGER
+ CONSTRAINT USERS_ROLE_ID_FKEY
+ REFERENCES ROLES
+);
+
+CREATE TABLE REGIONS
+(
+ REGION_ID SERIAL NOT NULL
+ CONSTRAINT REGIONS_PKEY
+ PRIMARY KEY,
+ NAME VARCHAR
+);
+
+CREATE TABLE TAGS
+(
+ TAG_ID SERIAL NOT NULL
+ CONSTRAINT TAGS_PKEY
+ PRIMARY KEY,
+ TAG VARCHAR
+ CONSTRAINT UNIQUE_NAME
+ UNIQUE
+);
+
+CREATE TABLE CHARITIES
+(
+ CHARITY_ID SERIAL NOT NULL
+ CONSTRAINT CHARITIES_PKEY
+ PRIMARY KEY,
+ BODY TEXT,
+ AUTHOR_ID INTEGER
+ CONSTRAINT CHARITIES_AUTHOR_ID_FKEY
+ REFERENCES USERS,
+ CREATED_AT TIMESTAMP DEFAULT NOW(),
+ MODIFIED_AT TIMESTAMP DEFAULT NOW()
+);
+
+CREATE TABLE DIRECTIONS
+(
+ DIRECTION_ID SERIAL NOT NULL
+ CONSTRAINT DIRECTIONS_PKEY
+ PRIMARY KEY,
+ LABEL VARCHAR,
+ COLOR VARCHAR(7) DEFAULT NULL::CHARACTER VARYING,
+ NAME VARCHAR
+);
+
+CREATE TABLE POST_TYPES
+(
+ TYPE_ID SERIAL NOT NULL
+ CONSTRAINT POST_TYPES_PKEY
+ PRIMARY KEY,
+ NAME VARCHAR
+);
+
+CREATE TABLE POSTS
+(
+ POST_ID SERIAL NOT NULL
+ CONSTRAINT POSTS_PKEY
+ PRIMARY KEY,
+ AUTHOR_ID INTEGER
+ CONSTRAINT POSTS_AUTHOR_ID_FKEY
+ REFERENCES USERS,
+ TYPE_ID INTEGER
+ CONSTRAINT POSTS_TYPE_ID_FKEY
+ REFERENCES POST_TYPES,
+ TITLE VARCHAR,
+ CONTENT TEXT,
+ STATUS VARCHAR,
+ IMPORTANT BOOLEAN,
+ CREATED_AT TIMESTAMP DEFAULT NOW(),
+ MODIFIED_AT TIMESTAMP DEFAULT NOW(),
+ PREVIEW TEXT
+);
+
+ALTER TABLE POSTS
+ ADD COLUMN VIDEO_URL VARCHAR DEFAULT '',
+ ADD COLUMN PREVIEW_IMAGE_URL VARCHAR DEFAULT '';
+
+CREATE TABLE POSTS_TAGS
+(
+ POST_ID INTEGER
+ CONSTRAINT POSTS_TAGS_POST_ID_FKEY
+ REFERENCES POSTS,
+ TAG_ID INTEGER
+ CONSTRAINT POSTS_TAGS_TAG_ID_FKEY
+ REFERENCES TAGS
+);
+
+CREATE TABLE POSTS_DIRECTIONS
+(
+ POST_ID INTEGER
+ CONSTRAINT POSTS_DIRECTIONS_POST_ID_FKEY
+ REFERENCES POSTS,
+ DIRECTION_ID INTEGER
+ CONSTRAINT POSTS_DIRECTIONS_DIRECTION_ID_FKEY
+ REFERENCES DIRECTIONS
+);
+
+CREATE TABLE CITIES
+(
+ CITY_ID INTEGER GENERATED BY DEFAULT AS IDENTITY
+ CONSTRAINT CITIES_PKEY
+ PRIMARY KEY,
+ NAME VARCHAR(255),
+ REGION_ID INTEGER
+ CONSTRAINT CITIES_REGION_ID_FKEY
+ REFERENCES REGIONS
+);
+
+CREATE TABLE INSTITUTIONS
+(
+ INSTITUTION_ID SERIAL NOT NULL
+ CONSTRAINT INSTITUTIONS_PKEY
+ PRIMARY KEY,
+ NAME VARCHAR,
+ ADDRESS VARCHAR,
+ CITY_ID INTEGER
+ CONSTRAINT INSTITUTIONS_CITY_ID_FKEY
+ REFERENCES CITIES
+);
+
+CREATE TABLE VERIFICATION_TOKENS
+(
+ ID SERIAL NOT NULL
+ CONSTRAINT VERIFICATION_TOKENS_PKEY
+ PRIMARY KEY,
+ TOKEN VARCHAR,
+ USER_ID INTEGER
+ CONSTRAINT VERIFICATION_TOKENS_USER_ID_FKEY
+ REFERENCES USERS
+);
+
+CREATE TABLE PROVIDERS
+(
+ PROVIDER_ID SERIAL NOT NULL
+ CONSTRAINT PROVIDERS_PKEY
+ PRIMARY KEY,
+ PROVIDER_NAME VARCHAR,
+ EMAIL VARCHAR,
+ USER_ID_BY_PROVIDER VARCHAR,
+ USER_ID INTEGER
+ CONSTRAINT PROVIDERS_USER_ID_FKEY
+ REFERENCES USERS
+);
+
+CREATE TABLE DOCTORS
+(
+ DOCTOR_ID SERIAL NOT NULL
+ CONSTRAINT DOCTORS_PKEY
+ PRIMARY KEY,
+ QUALIFICATION VARCHAR,
+ BIO VARCHAR,
+ USER_ID INTEGER
+ CONSTRAINT DOCTORS_USER_ID_FKEY
+ REFERENCES USERS,
+ INSTITUTION_ID INTEGER
+ CONSTRAINT DOCTORS_INSTITUTION_ID_FKEY
+ REFERENCES INSTITUTIONS,
+ PROMOTION_SCALE REAL DEFAULT 1.0,
+ PROMOTION_LEVEL INTEGER DEFAULT 0,
+ PUBLISHED_POSTS BIGINT DEFAULT 0,
+ RATING BIGINT DEFAULT 0
+);
+
+CREATE TABLE DOCTORS_INSTITUTIONS
+(
+ DOCTOR_ID INTEGER
+ CONSTRAINT DOCTORS_INSTITUTIONS_DOCTOR_ID_FKEY
+ REFERENCES DOCTORS,
+ INSTITUTION_ID INTEGER
+ CONSTRAINT DOCTORS_INSTITUTIONS_INSTITUTION_ID_FKEY
+ REFERENCES INSTITUTIONS
+);
+
+CREATE TABLE DOCTORS_DIRECTIONS
+(
+ DOCTOR_ID INTEGER
+ CONSTRAINT DOCTORS_DIRECTIONS_DOCTOR_ID_FKEY
+ REFERENCES DOCTORS,
+ DIRECTION_ID INTEGER
+ CONSTRAINT DOCTORS_DIRECTIONS_DIRECTION_ID_FKEY
+ REFERENCES DIRECTIONS
+);
+
+CREATE TABLE ROLE_PERMISSION
+(
+ ROLE_ID INTEGER
+ CONSTRAINT ROLE_ID_ROLE_ID_FK
+ REFERENCES ROLES,
+ PERMISSIONS VARCHAR
+);
diff --git a/src/main/resources/db/migration/V2__add_origins_table.sql b/src/main/resources/db/migration/V2__add_origins_table.sql
new file mode 100644
index 00000000..8d1d9f4b
--- /dev/null
+++ b/src/main/resources/db/migration/V2__add_origins_table.sql
@@ -0,0 +1,10 @@
+CREATE TABLE ORIGINS
+(
+ ORIGIN_ID SERIAL NOT NULL
+ CONSTRAINT ORIGINS_PKEY
+ PRIMARY KEY,
+ NAME VARCHAR,
+ PARAMETERS VARCHAR
+);
+
+
diff --git a/src/main/resources/db/migration/V3__add_posts_origins_table.sql b/src/main/resources/db/migration/V3__add_posts_origins_table.sql
new file mode 100644
index 00000000..e79bae54
--- /dev/null
+++ b/src/main/resources/db/migration/V3__add_posts_origins_table.sql
@@ -0,0 +1,11 @@
+CREATE TABLE POSTS_ORIGINS
+(
+ POST_ID INTEGER
+ CONSTRAINT POSTS_ORIGINS_POST_ID_FKEY
+ REFERENCES POSTS,
+ ORIGIN_ID INTEGER
+ CONSTRAINT POSTS_ORIGINS_ORIGIN_ID_FKEY
+ REFERENCES ORIGINS
+);
+
+
diff --git a/src/main/resources/db/migration/V4__add_has_doctors_column_to_directions.sql b/src/main/resources/db/migration/V4__add_has_doctors_column_to_directions.sql
new file mode 100644
index 00000000..dc5db35e
--- /dev/null
+++ b/src/main/resources/db/migration/V4__add_has_doctors_column_to_directions.sql
@@ -0,0 +1,2 @@
+ALTER TABLE DIRECTIONS
+ ADD COLUMN HAS_DOCTORS BOOLEAN NOT NULL DEFAULT 'false';
\ No newline at end of file
diff --git a/src/main/resources/db/migration/V5__add_region_status_column.sql b/src/main/resources/db/migration/V5__add_region_status_column.sql
new file mode 100644
index 00000000..b7009515
--- /dev/null
+++ b/src/main/resources/db/migration/V5__add_region_status_column.sql
@@ -0,0 +1,2 @@
+ALTER TABLE REGIONS
+ ADD COLUMN USERS_PRESENT BOOLEAN NOT NULL DEFAULT 'false';
diff --git a/src/main/resources/db/migration/V6__add_has_posts_column_to_directions.sql b/src/main/resources/db/migration/V6__add_has_posts_column_to_directions.sql
new file mode 100644
index 00000000..ea957723
--- /dev/null
+++ b/src/main/resources/db/migration/V6__add_has_posts_column_to_directions.sql
@@ -0,0 +1,2 @@
+ALTER TABLE DIRECTIONS
+ ADD COLUMN HAS_POSTS BOOLEAN NOT NULL DEFAULT 'false';
\ No newline at end of file
diff --git a/src/main/resources/db/migration/V7__add_published_date_column.sql b/src/main/resources/db/migration/V7__add_published_date_column.sql
new file mode 100644
index 00000000..cf58f6ad
--- /dev/null
+++ b/src/main/resources/db/migration/V7__add_published_date_column.sql
@@ -0,0 +1,2 @@
+ALTER TABLE POSTS
+ ADD PUBLISHED_AT TIMESTAMP DEFAULT NOW();
\ No newline at end of file
diff --git a/src/main/resources/db/migration/V8__delete_some_post_types.sql b/src/main/resources/db/migration/V8__delete_some_post_types.sql
new file mode 100644
index 00000000..c53e6eab
--- /dev/null
+++ b/src/main/resources/db/migration/V8__delete_some_post_types.sql
@@ -0,0 +1,6 @@
+delete from posts_tags where post_id in (select post_id from posts where type_id=4);
+delete from posts_directions where post_id in (select post_id from posts where type_id=4);
+delete from posts_origins where post_id in (select post_id from posts where type_id=4);
+delete from posts where type_id=4;
+delete from post_types where type_id=4;
+
diff --git a/src/main/resources/db/migration/V9__add_social_network_column_to_doctors.sql b/src/main/resources/db/migration/V9__add_social_network_column_to_doctors.sql
new file mode 100644
index 00000000..96ba1cbc
--- /dev/null
+++ b/src/main/resources/db/migration/V9__add_social_network_column_to_doctors.sql
@@ -0,0 +1,2 @@
+ALTER TABLE DOCTORS
+ ADD COLUMN SOCIAL_NETWORK VARCHAR DEFAULT '';
\ No newline at end of file
diff --git a/src/main/resources/db/testdata/V1.1__add_demo_data.sql b/src/main/resources/db/testdata/V1.1__add_demo_data.sql
new file mode 100644
index 00000000..9ce0f35a
--- /dev/null
+++ b/src/main/resources/db/testdata/V1.1__add_demo_data.sql
@@ -0,0 +1,2797 @@
+INSERT INTO public.tags (tag)
+VALUES ('Профілактика');
+INSERT INTO public.tags (tag)
+VALUES ('Комплекс');
+INSERT INTO public.tags (tag)
+VALUES ('Ковід');
+INSERT INTO public.tags (tag)
+VALUES ('Допомога');
+INSERT INTO public.tags (tag)
+VALUES ('Міокард');
+INSERT INTO public.tags (tag)
+VALUES ('ЕКГ');
+
+INSERT INTO public.directions (label, color, name)
+VALUES ('Covid-19', '#ef5350', 'covid-19');
+INSERT INTO public.directions (label, color, name)
+VALUES ('Офтальмологія', '#98ef50', 'ophthalmology');
+INSERT INTO public.directions (label, color, name)
+VALUES ('Хірургія', '#7aebbf', 'surgery');
+INSERT INTO public.directions (label, color, name)
+VALUES ('Терапія', '#ffee58', 'therapy');
+INSERT INTO public.directions (label, color, name)
+VALUES ('Вірусологія', '#da80e8', 'virology');
+INSERT INTO public.directions (label, color, name)
+VALUES ('Кардіологія', '#00ffff', 'cardiology');
+INSERT INTO public.directions (label, color, name)
+VALUES ('Педіатрія', '#993333', 'pediatrics');
+
+INSERT INTO public.post_types (name)
+VALUES ('Стаття');
+INSERT INTO public.post_types (name)
+VALUES ('Відео');
+INSERT INTO public.post_types (name)
+VALUES ('Допис');
+INSERT INTO public.post_types (name)
+VALUES ('Переклад');
+
+INSERT INTO public.regions (name)
+VALUES ('Автономна Республіка Крим');
+INSERT INTO public.regions (name)
+VALUES ('Вінницька область');
+INSERT INTO public.regions (name)
+VALUES ('Волинська область');
+INSERT INTO public.regions (name)
+VALUES ('Дніпропетровська область');
+INSERT INTO public.regions (name)
+VALUES ('Донецька область');
+INSERT INTO public.regions (name)
+VALUES ('Житомирська область');
+INSERT INTO public.regions (name)
+VALUES ('Закарпатська область');
+INSERT INTO public.regions (name)
+VALUES ('Запорізька область');
+INSERT INTO public.regions (name)
+VALUES ('Івано-Франківська область');
+INSERT INTO public.regions (name)
+VALUES ('Київська область');
+INSERT INTO public.regions (name)
+VALUES ('Кіровоградська область');
+INSERT INTO public.regions (name)
+VALUES ('Луганська область');
+INSERT INTO public.regions (name)
+VALUES ('Львівська область');
+INSERT INTO public.regions (name)
+VALUES ('Миколаївська область');
+INSERT INTO public.regions (name)
+VALUES ('Одеська область');
+INSERT INTO public.regions (name)
+VALUES ('Полтавська область');
+INSERT INTO public.regions (name)
+VALUES ('Рівненська область');
+INSERT INTO public.regions (name)
+VALUES ('Сумська область');
+INSERT INTO public.regions (name)
+VALUES ('Тернопільська область');
+INSERT INTO public.regions (name)
+VALUES ('Харківська область');
+INSERT INTO public.regions (name)
+VALUES ('Херсонська область');
+INSERT INTO public.regions (name)
+VALUES ('Хмельницька область');
+INSERT INTO public.regions (name)
+VALUES ('Черкаська область');
+INSERT INTO public.regions (name)
+VALUES ('Чернівецька область');
+INSERT INTO public.regions (name)
+VALUES ('Чернігівська область');
+
+INSERT INTO public.roles (role_name)
+VALUES ('Administrator');
+INSERT INTO public.roles (role_name)
+VALUES ('Moderator');
+INSERT INTO public.roles (role_name)
+VALUES ('Doctor');
+
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('TarzhemanSokolov585@mail.com', '$2y$10$CXUu2az9AJHT23fUcXkGd.x4m.ByDOCb6e0uU8teF/Dgq2lqeHfv2', 'ACTIVE',
+ 'Таржеман', 'Соколов', '+380631434712', '2021-02-16 03:56:37.444571', 'https://i.pravatar.cc/300?img=70', true,
+ 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('MiletiyChernyshov229@mail.com', '$2y$10$SvnpkOhhs4I6J7w3jLcvIe5mWakxJ3ADtquH5Tv0x70rmjPZifTSi', 'ACTIVE',
+ 'Милетий', 'Чернышов', '+380637931441', '2021-02-16 03:56:37.444571', 'https://i.pravatar.cc/300?img=68', true,
+ 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('NezdaUshakov899@mail.com', '$2y$10$MqU8B7EDd7aNo/CTmr0OKeIkRQHObRBEfxMbY2LfDbvZKmsliZ3ia', 'ACTIVE',
+ 'Незда', 'Ушаков', '+380637687420', '2021-02-16 03:56:37.444571', 'https://i.pravatar.cc/300?img=67', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('KukuriChapko624@mail.com', '$2y$10$FHxAyHKwM2AqUF582/FFhuuf.OzU6ECIpwTpMxLCeEyz0rht.hjcG', 'ACTIVE',
+ 'Кукури', 'Чапко', '+380631793743', '2021-02-16 03:56:37.444571', 'https://i.pravatar.cc/300?img=66', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('GigranAlekseev32@mail.com', '$2y$10$/m6y5AVzG9yxmthcQ7M1FOsrh8EqZmFvGZjoi7lDyy04eUqQ0gnqe', 'ACTIVE',
+ 'Гигран', 'Алексеев', '+380634724237', '2021-02-16 03:56:37.444571', 'https://i.pravatar.cc/300?img=65', true,
+ 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('PalanaLitvinova514@mail.com', '$2y$10$I2VwJytpzEZi2DPzLPJk.uhcd4WIi/Ek5dMkLjQcurEZWqI0MxTl6', 'ACTIVE',
+ 'Палана', 'Литвинова', '+380633484351', '2021-02-16 03:56:37.444571', 'https://i.pravatar.cc/300?img=44', true,
+ 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('regina@mail.com', '$2y$10$SxF6UMIS1cn7Wi76GwMBFedgGukB9pe3XeL8Qz9pRfUNw3BtD.CDG', 'ACTIVE', 'Регіна',
+ 'Регіненко', '+380956765669', '2021-02-16 03:56:37.394884', 'https://i.pravatar.cc/300?img=27', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('taras@mail.com', '$2y$10$dCSLVzPoFC7fAfFdgCFayui2u3Tt9Z6IXEZZkCKzuXFvqyWB3cmUO', 'ACTIVE', 'Тарас',
+ 'Шевченко', '+380956098369', '2021-02-16 03:56:37.368121', 'https://i.pravatar.cc/300?img=17', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('mykola@mail.com', '$2y$10$IaiLTkeqRVSuUtr4weOYmODGOlUp4aBdPQTjQun1klh9CMTsQ12Zu', 'ACTIVE', 'Микола',
+ 'Миколенко', '+380956412369', '2021-02-16 03:56:37.368121', 'https://i.pravatar.cc/300?img=15', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('masha@mail.com', '$2y$10$igRjDpb3m9EuDvPiGr.RLuuLyjB0M9Snx3yeGW25zprYceSnBNfMq', 'ACTIVE', 'Марія',
+ 'Марієнко', '+380956456969', '2021-02-16 03:56:37.368121', 'https://i.pravatar.cc/300?img=16', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('danylo@mail.com', '$2y$10$dhLh3iKYde/riLznRRU1duits0zbiAFQ46l5AVRhDddJtUBHm3OHW', 'ACTIVE', 'Данило',
+ 'Даниленко', '+380961233969', '2021-02-16 03:56:37.368121', 'https://i.pravatar.cc/300?img=13', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('stepan@mail.com', '$2y$10$CQdJOp/Jw5LmRoUt0W7wSO6lE4N0hM3k0gr1mCI8w8ZOp8ERZcjzO', 'ACTIVE', 'Степан',
+ 'Степанов', '+380969123969', '2021-02-16 03:56:37.368121', 'https://i.pravatar.cc/300?img=12', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('maryna@mail.com', '$2y$10$9R5cJzKJEsP4sjMkH7yHLe6miXbIfY7Jh3xHf8eC4h2jLYH6fGof2', 'ACTIVE', 'Марина',
+ 'Вовк', '+380939393939', '2021-02-16 03:56:37.332925', 'https://i.pravatar.cc/300?img=5', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('oleh@mail.com', '$2y$10$VSWtNZs6WLP5FvAjK.B/JOSLkkcTet9EBHD.PCBbcE1NyyFiVHuA6', 'ACTIVE', 'Олег',
+ 'Петренко', '+380939393939', '2021-02-16 03:56:37.332925', 'https://i.pravatar.cc/300?img=11', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('kateryna@mail.com', '$2y$10$oblwylAYFcVWCXINBCNH1egDuBSy5YGdiyMvN0wM8trelRuy45BU2', 'ACTIVE', 'Катерина',
+ 'Кравченко', '+380989898989', '2021-02-16 03:56:37.332925', 'https://i.pravatar.cc/300?img=9', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('dmytro@mail.com', '$2y$10$7BhpXBFMGobXWpNj31XyWeezGYlx.OxTKVOqy34Nl/qVd6.50j/LS', 'ACTIVE', 'Дмитро',
+ 'Степаненко', '+380444444444', '2021-02-16 03:56:37.332925', 'https://i.pravatar.cc/300?img=8', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('olena@mail.com', '$2y$10$EGlzdsCMezKEBDuXsXsGV.REQRsfWPzFecRhnOZjbLl/HTQMbZx7G', 'ACTIVE', 'Олена',
+ 'Шевченко', '+380939393939', '2021-02-16 03:56:37.332925', 'https://i.pravatar.cc/300?img=1', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('andrii@mail.com', '$2y$10$ZelYHG3iwVCJVvp0dimraerFaYdABop.SPBwUkW7RsiDMA9.h6XTa', 'ACTIVE', 'Андрій',
+ 'Петров', '+380505050505', '2021-02-16 03:56:37.332925', 'https://i.pravatar.cc/300?img=7', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('ivan@mail.com', '$2y$10$ishgf6hBdlEQwE8Ld1ktkOOPsINMgE7CviFi1qxRaiOgvUdg3RCTy', 'ACTIVE', 'Іван', 'Іванов',
+ '+380969696969', '2021-02-16 03:56:37.332925', 'https://i.pravatar.cc/300?img=3', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('FekletinyaShashkova782@mail.com', '$2y$10$6PL9y4SFgNf014aGOAsM1u9CVA.9q08tPDDe/C8.E9WXl0B0oWk3G', 'ACTIVE',
+ 'Феклетинья', 'Шашкова', '+380639220084', '2021-02-16 03:56:37.444571', 'https://i.pravatar.cc/300?img=48',
+ true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('PamfiyTihomirov752@mail.com', '$2y$10$qoMjXIOaovHvpEHraY5pw.q.FwPaXm2PdpU83uM1GemK4dgPD6rSq', 'ACTIVE',
+ 'Памфий', 'Тихомиров', '+380635701294', '2021-02-16 03:56:37.444571', 'https://i.pravatar.cc/300?img=59', true,
+ 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('FadiStalin333@mail.com', '$2y$10$Qk.6cy.s7uTNKQGYFeF9/urECrBpZ4NtLEN9Hzjj0g7soVRzcGu1u', 'ACTIVE', 'Фади',
+ 'Сталин', '+380636962951', '2021-02-16 03:56:37.444571', 'https://i.pravatar.cc/300?img=58', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('ShtukaNovitskaya261@mail.com', '$2y$10$59GRRruj9n/T4wqElz.IEOXrhwJDoPaz8FdJQJuk4KM.iisikn0lW', 'ACTIVE',
+ 'Щука', 'Новицкая', '+380632405186', '2021-02-16 03:56:37.444571', 'https://i.pravatar.cc/300?img=26', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('platon@mail.com', '$2y$10$pZm26FgFAgGbMna/ut0vu.jtR0PZI9kRWCbF.6HshU8wQ32/rMpH2', 'ACTIVE', 'Платон',
+ 'Платоненко', '+380956761119', '2021-02-16 03:56:37.394884', 'https://i.pravatar.cc/300?img=57', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('terentiy@mail.com', '$2y$10$NhzfYhZemyRhR61aPJmtnO1WFv06y2ENyEctQCePx.Ymn6wL6P2h.', 'ACTIVE', 'Терентій',
+ 'Терентієнко', '+380956761119', '2021-02-16 03:56:37.394884', 'https://i.pravatar.cc/300?img=56', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('fedot@mail.com', '$2y$10$.oKUlohR31I8wni/Qi8nwu9cJti4P5ddg6oq6FIK4H7r/jmmK44sG', 'ACTIVE', 'Федот',
+ 'Федотенко', '+380956761119', '2021-02-16 03:56:37.394884', 'https://i.pravatar.cc/300?img=55', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('admin@mail.com', '$2y$10$GtQSp.P.EyAtCgUD2zWLW.01OBz409TGPl/Jo3U30Tig3YbbpIFv2', 'ACTIVE', 'Gregory',
+ 'House', '+380939393939', '2021-02-16 03:56:37.332925', null, true, 1);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('matviy@mail.com', '$2y$10$dGfbNZAFW5vAkr50kTJBEO3rUDWJuj8B4dfFkmOS/kBlnGqiKqLHS', 'ACTIVE', 'Матвій',
+ 'Матвійчук', '+380956098369', '2021-02-16 03:56:37.394884', 'https://i.pravatar.cc/300?img=54', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('nikon@mail.com', '$2y$10$EdUEHquCl7OyAqTtfoT1suL1QYZ/68yH36TNWOFnFj/gU.9TjvZAS', 'ACTIVE', 'Нікон',
+ 'Ніконенко', '+380956412369', '2021-02-16 03:56:37.394884', 'https://i.pravatar.cc/300?img=53', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('zhan@mail.com', '$2y$10$Dx6cNJ3AGW9xzin3xYLpKuQbDO85WM7zy8t.CIJ7JZJFUY3R.8UKe', 'ACTIVE', 'Жан', 'Жанко',
+ '+380956456969', '2021-02-16 03:56:37.394884', 'https://i.pravatar.cc/300?img=51', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('nazar@mail.com', '$2y$10$4jMtf0eEjVaV0bJWLEb2OOpzEI8md27557Ei/z9eVqugk4Ueg3LLm', 'ACTIVE', 'Назар',
+ 'Назаренко', '+380961456969', '2021-02-16 03:56:37.394884', 'https://i.pravatar.cc/300?img=52', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('petro@mail.com', '$2y$10$MAU64Cv9xZ629f3oTiTJZeY5LbkV1KrVzQ9BeHE0wymMlSqHjUovS', 'ACTIVE', 'Петро',
+ 'Петренко', '+380961456969', '2021-02-16 03:56:37.368121', 'https://i.pravatar.cc/300?img=14', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('tetyana@mail.com', '$2y$10$bwaU77GtjK3HfMZjti5Gx.Q.SkqerM0V2.XzxN6AlOLGmI90dsPTu', 'ACTIVE', 'Тетяна',
+ 'Коваленко', '+380444444444', '2021-02-16 03:56:37.332925', 'https://i.pravatar.cc/300?img=10', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('zahar@mail.com', '$2y$10$hVu0ysEa3BNNi4ZAzcvMxe2A0qb5szLLM2Md/XltMIg54jrVbJ1Ay', 'ACTIVE', 'Захар',
+ 'Захаренко', '+380961233969', '2021-02-16 03:56:37.394884', 'https://i.pravatar.cc/300?img=33', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('eva@mail.com', '$2y$10$9whP9V3MfAs/G9imeF9g4e6UMVotHZzp6cqo9bMleSNXNbwPESbm.', 'ACTIVE', 'Єва', 'Євенко',
+ '+380969123969', '2021-02-16 03:56:37.394884', 'https://i.pravatar.cc/300?img=20', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('bohdan@mail.com', '$2y$10$DYodORfhp4RQl/5mW5XUfO4suMshfRW7611eKSnb/4AVdrKwUb6wS', 'ACTIVE', 'Богдан',
+ 'Хмельницький', '+380956761119', '2021-02-16 03:56:37.368121', 'https://i.pravatar.cc/300?img=18', true, 3);
+INSERT INTO public.users (email, password, status, first_name, last_name, phone, created_at, avatar, enabled,
+ role_id)
+VALUES ('lesia@mail.com', '$2y$10$TeNyf4iiE7xy0HFHmtRRLu2Q7BH4ceYjYudZpIUJ13qjhvapdjjHe', 'ACTIVE', 'Леся',
+ 'Українка', '+380956765669', '2021-02-16 03:56:37.368121', 'https://i.pravatar.cc/300?img=19', true, 3);
+
+INSERT INTO public.charities (body, author_id, created_at, modified_at)
+VALUES ('Lorem ipsum - 50шт. Ut enim - 10шт.', 2, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925');
+INSERT INTO public.charities (body, author_id, created_at, modified_at)
+VALUES ('Ut enim - 5шт. ipsum - 20шт.', 4, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925');
+INSERT INTO public.charities (body, author_id, created_at, modified_at)
+VALUES ('Lorem - 500шт. Ut enim - 100шт.', 6, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925');
+INSERT INTO public.charities (body, author_id, created_at, modified_at)
+VALUES ('Ut enim - 10шт. Excepteur sint - 200шт.', 7, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925');
+
+INSERT INTO public.cities (name, region_id)
+VALUES ('Авдіївка', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Алмазна', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Алупка', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Алушта', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Алчевськ', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Амвросіївка', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ананьїв', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Андрушівка', 6);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Антрацит', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Апостолове', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Армянськ', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Арциз', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Балаклія', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Балта', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бар', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Баранівка', 6);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Барвінкове', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Батурин', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бахмач', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бахмут', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бахчисарай', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Баштанка', 14);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Белз', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бердичів', 6);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бердянськ', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Берегове', 7);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бережани', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Березань', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Березівка', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Березне', 17);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Берестечко', 3);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Берислав', 21);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бершадь', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бібрка', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Біла Церква', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Білгород-Дністровський', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Білицьке', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Білогірськ', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Білозерське', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Білопілля', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Біляївка', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Благовіщенське', 11);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бобринець', 11);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бобровиця', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Богодухів', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Богуслав', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Боково-Хрустальне', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Болград', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Болехів', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Борзна', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Борислав', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бориспіль', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Борщів', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Боярка', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бровари', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Броди', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Брянка', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бунге', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Буринь', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бурштин', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Буськ', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Буча', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Бучач', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Валки', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вараш', 17);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Василівка', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Васильків', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ватутіне', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вашківці', 24);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Великі Мости', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Верхівцеве', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Верхньодніпровськ', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вижниця', 24);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вилкове', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Винники', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Виноградів', 7);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вишгород', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вишневе', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вільногірськ', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вільнянськ', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вінниця', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вовчанськ', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вознесенівка', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вознесенськ', 14);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Волноваха', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Володимир-Волинський', 3);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Волочиськ', 22);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ворожба', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вуглегірськ', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Вугледар', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Гадяч', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Гайворон', 11);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Гайсин', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Галич', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Генічеськ', 21);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Герца', 24);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Гірник', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Гірське', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Глиняни', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Глобине', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Глухів', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Гнівань', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Гола Пристань', 21);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Голубівка', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Горішні Плавні', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Горлівка', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Городенка', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Городище', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Городня', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Городок', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Городок', 22);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Горохів', 3);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Гребінка', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Гуляйполе', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Дебальцеве', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Деражня', 22);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Дергачі', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Джанкой', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Дніпро', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Дніпрорудне', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Добромиль', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Добропілля', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Довжанськ', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Докучаєвськ', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Долина', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Долинська', 11);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Донецьк', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Дрогобич', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Дружба', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Дружківка', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Дубляни', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Дубно', 17);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Дубровиця', 17);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Дунаївці', 22);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Енергодар', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Євпаторія', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Єнакієве', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Жашків', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Жданівка', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Жидачів', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Житомир', 6);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Жмеринка', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Жовква', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Жовті Води', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Заводське', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Залізне', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Заліщики', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Запоріжжя', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Заставна', 24);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Збараж', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Зборів', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Звенигородка', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Здолбунів', 17);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Зеленодольськ', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Зимогір''я', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Зіньків', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Зміїв', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Знам''янка', 11);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Золоте', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Золотоноша', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Золочів', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Зоринськ', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Зугрес', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Івано-Франківськ', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ізмаїл', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ізюм', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ізяслав', 22);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Іллінці', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Іловайськ', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Інкерман', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ірміно', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ірпінь', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Іршава', 7);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ічня', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кагарлик', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кадіївка', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Калинівка', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Калуш', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кальміуське', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Камінь-Каширський', 3);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кам''янець-Подільський', 22);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кам''янка', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Камянка-Бузька', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кам''янка-Дніпровська', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кам''янське', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Канів', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Карлівка', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Каховка', 21);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Керч', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Київ', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кипуче', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ківерці', 3);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кілія', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кіцмань', 24);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кобеляки', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ковель', 3);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кодима', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Козятин', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Коломия', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Комарно', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Конотоп', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Копичинці', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Корець', 17);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Коростень', 6);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Коростишів', 6);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Корсунь-Шевченківський', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Корюківка', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Косів', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Костопіль', 17);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Костянтинівка', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Краматорськ', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Красилів', 22);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Красногорівка', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Красноград', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Красноперекопськ (Яни Капу)', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кременець', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кременчук', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кремінна', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кривий Ріг', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кролевець', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Кропивницький', 11);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Куп''янськ', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Курахове', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ладижин', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ланівці', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Лебедин', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Лиман', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Липовець', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Лисичанськ', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Лозова', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Лохвиця', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Лубни', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Луганськ', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Лутугине', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Луцьк', 3);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Львів', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Любомль', 3);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Люботин', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Макіївка', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Мала Виска', 11);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Малин', 6);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Марганець', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Маріуполь', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Мар''їнка', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Мелітополь', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Мена', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Мерефа', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Миколаїв', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Миколаїв', 14);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Миколаївка', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Миргород', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Мирноград', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Миронівка', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Міусинськ', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Могилів-Подільський', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Молодогвардійськ', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Молочанськ', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Монастириська', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Монастирище', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Моршин', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Моспине', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Мостиська', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Мукачево', 7);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Надвірна', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Немирів', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Нетішин', 22);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ніжин', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Нікополь', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Нова Каховка', 21);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Нова Одеса', 14);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новгород-Сіверський', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новий Буг', 14);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новий Калинів', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новий Розділ', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новоазовськ', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Нововолинськ', 3);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новоград-Волинський', 6);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новогродівка', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новодністровськ', 24);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новодружеськ', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новомиргород', 11);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новомосковськ', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новоселиця', 24);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новоукраїнка', 11);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Новояворівськ', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Носівка', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Обухів', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Овруч', 6);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Одеса', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Олевськ', 6);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Олександрівськ', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Олександрія', 11);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Олешки', 21);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Оріхів', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Остер', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Острог', 17);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Охтирка', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Очаків', 14);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Павлоград', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Первомайськ', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Первомайськ', 14);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Первомайський', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Перевальськ', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Перемишляни', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Перечин', 7);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Перещепине', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Переяслав', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Першотравенськ', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Петрово-Красносілля', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Пирятин', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Південне', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Підгайці', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Підгородне', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Погребище', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Подільськ', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Покров', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Покровськ', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Пологи', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Полонне', 22);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Полтава', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Помічна', 11);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Попасна', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Почаїв', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Привілля', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Прилуки', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Приморськ', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Прип''ять', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Пустомити', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Путивль', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('П''ятихатки', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Рава-Руська', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Радехів', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Радивилів', 17);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Радомишль', 6);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Рахів', 7);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Рені', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Решетилівка', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ржищів', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Рівне', 17);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ровеньки', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Рогатин', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Родинське', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Рожище', 3);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Роздільна', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ромни', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Рубіжне', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Рудки', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Саки', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Самбір', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сарни', 17);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Свалява', 7);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сватове', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Світловодськ', 11);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Світлодарськ', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Святогірськ', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Севастополь', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Селидове', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Семенівка', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Середина-Буда', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сєвєродонецьк', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Синельникове', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сіверськ', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сімферополь', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Скадовськ', 21);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Скалат', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сквира', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сколе', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Славута', 22);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Славутич', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Слов''янськ', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сміла', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Снігурівка', 14);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сніжне', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сновськ', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Снятин', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сокаль', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сокиряни', 24);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Соледар', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сорокине', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Соснівка', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Старий Крим', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Старий Самбір', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Старобільськ', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Старокостянтинів', 22);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Стебник', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Сторожинець', 24);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Стрий', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Судак', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Судова Вишня', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Суми', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Суходільськ', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Таврійськ', 21);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Тальне', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Тараща', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Татарбунари', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Теплодар', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Теребовля', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Тернівка', 4);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Тернопіль', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Тетіїв', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Тисмениця', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Тлумач', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Токмак', 8);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Торецьк', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Тростянець', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Трускавець', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Тульчин', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Турка', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Тячів', 7);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Угнів', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ужгород', 7);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Узин', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Українка', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Українськ', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Умань', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Устилуг', 3);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Фастів', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Феодосія', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Харків', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Харцизьк', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Херсон', 21);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Хирів', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Хмельницький', 22);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Хмільник', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ходорів', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Хорол', 16);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Хоростків', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Хотин', 24);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Хрестівка', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Христинівка', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Хрустальний', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Хуст', 7);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Часів Яр', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Червоноград', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Черкаси', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Чернівці', 24);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Чернігів', 25);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Чигирин', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Чистякове', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Чоп', 7);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Чорнобиль', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Чорноморськ', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Чортків', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Чугуїв', 20);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Чуднів', 6);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Шаргород', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Шахтарськ', 5);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Шепетівка', 22);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Шостка', 18);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Шпола', 23);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Шумськ', 19);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Щастя', 12);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Щолкіне', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Южне', 15);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Южноукраїнськ', 14);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Яворів', 13);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Яготин', 10);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ялта', 1);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ямпіль', 2);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Яремче', 9);
+INSERT INTO public.cities (name, region_id)
+VALUES ('Ясинувата', 5);
+
+INSERT INTO public.institutions (name, address, city_id)
+VALUES ('Адоніс', 'вул. Дніпровська набережна, 26К', 190);
+INSERT INTO public.institutions (name, address, city_id)
+VALUES ('Новий зір', 'вул. Коперника, 12Д', 190);
+INSERT INTO public.institutions (name, address, city_id)
+VALUES ('Інномед', 'ш. Хмельницьке, 96Г', 81);
+INSERT INTO public.institutions (name, address, city_id)
+VALUES ('Медікум', 'пр-т. Д. Яворницького, 59', 119);
+INSERT INTO public.institutions (name, address, city_id)
+VALUES ('Medical Idea', 'вул. Короленка, 54', 55);
+
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар-спеціаліст',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 12, 3, 1, 0, 3, 3);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Кандидат медичних наук',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 13, 1, 1, 0, 3, 3);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Кандидат медичних наук',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 14, 5, 1, 0, 3, 3);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар-спеціаліст',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 15, 2, 1, 0, 3, 3);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар вищої категорії',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 16, 2, 1, 0, 2, 2);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар вищої категорії',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 17, 1, 1, 0, 2, 2);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар вищої категорії',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 18, 5, 1, 0, 2, 2);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар-спеціаліст',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 19, 2, 1, 0, 2, 2);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар-спеціаліст',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 20, 3, 1, 0, 2, 2);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Кандидат медичних наук',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 21, 1, 1, 0, 2, 2);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Кандидат медичних наук',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 22, 5, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар-спеціаліст',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 23, 2, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар вищої категорії',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 24, 2, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар вищої категорії',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 25, 1, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар вищої категорії',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 26, 1, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар вищої категорії',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 27, 1, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Кандидат медичних наук',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 32, 5, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар-спеціаліст',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 33, 5, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар вищої категорії',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 1, 1, 1, 0, 5, 5);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар-спеціаліст',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 2, 1, 1, 0, 4, 4);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Кандидат медичних наук',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 3, 2, 1, 0, 3, 3);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар-спеціаліст',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 4, 1, 1, 0, 3, 3);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Кандидат медичних наук',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 28, 5, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Кандидат медичних наук',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 29, 5, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар вищої категорії',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 7, 5, 1, 0, 3, 3);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар-спеціаліст',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 8, 3, 1, 0, 3, 3);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар-спеціаліст',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 34, 5, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар вищої категорії',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 35, 5, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Кандидат медичних наук',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 5, 3, 1, 0, 3, 3);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Кандидат медичних наук',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 6, 4, 1, 0, 4, 4);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар вищої категорії',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 10, 5, 1, 0, 14, 14);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар-спеціаліст',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 11, 2, 1, 0, 2, 2);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Кандидат медичних наук',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 30, 5, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Кандидат медичних наук',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 31, 5, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар вищої категорії',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 36, 5, 1, 0, 1, 1);
+INSERT INTO public.doctors (qualification, bio, user_id, institution_id, promotion_scale, promotion_level,
+ published_posts, rating)
+VALUES ('Лікар вищої категорії',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 37, 5, 1, 0, 1, 1);
+
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (1, 1);
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (1, 2);
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (1, 5);
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (2, 2);
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (2, 5);
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (3, 1);
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (3, 2);
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (4, 1);
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (4, 5);
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (5, 3);
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (6, 4);
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (7, 1);
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (7, 5);
+INSERT INTO public.doctors_institutions (doctor_id, institution_id)
+VALUES (8, 3);
+
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (1, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (1, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (1, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (2, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (2, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (2, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (3, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (3, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (3, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (4, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (4, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (4, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (5, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (5, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (5, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (6, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (6, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (6, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (7, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (7, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (7, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (8, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (8, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (8, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (9, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (10, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (11, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (12, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (13, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (14, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (15, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (16, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (17, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (18, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (19, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (20, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (21, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (22, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (23, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (24, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (25, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (26, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (27, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (28, 1);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (29, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (30, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (31, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (32, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (33, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (34, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (35, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (36, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (9, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (10, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (11, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (12, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (13, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (14, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (15, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (16, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (17, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (18, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (19, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (20, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (21, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (22, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (23, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (24, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (25, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (26, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (27, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (28, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (29, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (30, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (31, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (32, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (33, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (34, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (35, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (36, 2);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (9, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (10, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (11, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (12, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (13, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (14, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (15, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (16, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (17, 3);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (18, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (19, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (20, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (21, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (22, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (23, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (24, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (25, 4);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (26, 7);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (27, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (28, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (29, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (30, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (31, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (32, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (33, 6);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (34, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (35, 5);
+INSERT INTO public.doctors_directions (doctor_id, direction_id)
+VALUES (36, 5);
+
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (2, 1, 'Fermentum iaculis',
+ 'Fermentum iaculis eu non diam phasellus vestibulum lorem sed. Et pharetra pharetra massa massa ultricies. Malesuada proin libero nunc consequat interdum varius sit. Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam. Risus ultricies tristique nulla aliquet enim tortor at. Diam quis enim lobortis scelerisque fermentum. Tempor commodo ullamcorper a lacus vestibulum. Erat nam at lectus urna. Dui id ornare arcu odio ut sem nulla pharetra.',
+ 'PUBLISHED', true, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (5, 1, 'Integer eget aliquet',
+ 'Integer eget aliquet nibh praesent tristique magna sit amet purus. Dolor purus non enim praesent elementum facilisis leo. Porttitor eget dolor morbi non. Urna cursus eget nunc scelerisque viverra. Imperdiet massa tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada. Fermentum et sollicitudin ac orci phasellus.',
+ 'MODERATION_SECOND_SIGN', false, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (4, 4, 'Ultrices sagittis orci',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Tempus quam pellentesque nec nam aliquam sem. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend.',
+ 'ARCHIVED', false, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (6, 2, 'Massa eget egestas',
+ 'Massa eget egestas purus viverra accumsan. Porta non pulvinar neque laoreet suspendisse interdum consectetur. Vitae suscipit tellus mauris a diam. Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (1, 1, 'Est ullamcorper eget',
+ 'Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam. Risus ultricies tristique nulla aliquet enim tortor at. Diam quis enim lobortis scelerisque fermentum. Tempor commodo ullamcorper a lacus vestibulum. Erat nam at lectus urna.',
+ 'MODERATION_FIRST_SIGN', true, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (4, 3, 'Sit amet consectetur',
+ 'Varius vel pharetra vel turpis nunc eget. Nisl tincidunt eget nullam non nisi est sit amet facilisis. Integer eget aliquet nibh praesent tristique magna sit amet purus. Dolor purus non enim praesent elementum facilisis leo.',
+ 'ARCHIVED', false, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (1, 2, 'Proin nibh nisl condimentum',
+ 'Ullamcorper malesuada proin libero nunc consequat. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Leo in vitae turpis massa sed. Ultrices eros in cursus turpis.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (7, 2, 'Tempus quam pellentesque',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Tempus quam pellentesque nec nam aliquam sem. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend. Nullam vehicula ipsum a arcu cursus vitae congue mauris rhoncus.',
+ 'DRAFT', false, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (7, 2, 'Tempus quam pellentesque', 'Proin nibh nisl condimentum id venenatis a condimentum vitae.', 'DRAFT',
+ false, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (1, 2, 'Ultrices eros in cursus', 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.332925', '2021-02-16 03:56:37.332925', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (2, 1, 'Fermentum iaculis',
+ 'Aenean non lobortis arcu. Sed ac enim in metus tincidunt vestibulum ut feugiat purus. Fusce eu velit auctor, facilisis urna sit amet, venenatis magna. Mauris lacinia ultricies pharetra. Phasellus vulputate sodales nulla, quis maximus risus pulvinar viverra. Cras et erat id tellus congue rhoncus nec nec ipsum. Mauris ultrices, neque quis lobortis hendrerit, turpis ipsum porttitor tortor, eget dignissim ante sapien sed sapien. Maecenas quis purus rutrum, tempor neque ut, imperdiet enim. Aenean bibendum dui ac ligula ultricies, vitae pulvinar massa tincidunt.',
+ 'PUBLISHED', false, '2019-11-25 13:42:34.609474', '2019-11-26 13:42:34.609474', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (1, 1, 'Fermentum iaculis',
+ 'Duis lacus nisl, dictum at auctor et, dignissim ac diam. Morbi laoreet sit amet ante quis vehicula. Proin sodales sem ac lacus sodales, id pellentesque nibh tempus. Phasellus porttitor, leo ac pulvinar malesuada, est mauris dignissim nibh, ac interdum enim lorem quis justo. Nam porttitor vitae odio ut posuere. In hac habitasse platea dictumst. Interdum et malesuada fames ac ante ipsum primis in faucibus. Etiam ultricies lacus in dapibus egestas. Quisque at neque condimentum, auctor ante consectetur, ullamcorper ex. Cras dolor diam, imperdiet sit amet dui eu, ultricies dapibus velit. Duis odio dolor, sagittis a libero sit amet, tincidunt gravida quam. Nunc congue ultrices tortor vitae hendrerit. Proin aliquam posuere leo, nec feugiat diam. Nunc efficitur porttitor auctor. Morbi bibendum, risus in dapibus mattis, nunc massa malesuada massa, scelerisque pharetra purus lorem sit amet velit.',
+ 'PUBLISHED', false, '2019-10-25 12:42:34.609474', '2019-11-26 13:44:34.609474', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (3, 1, 'Fermentum iaculis',
+ 'Vestibulum lacinia efficitur felis eget dapibus. Curabitur ut ante ante. Etiam tincidunt enim nunc, non tempus tortor mollis vitae. Sed bibendum risus quis faucibus pharetra. Praesent at lacus nibh. Donec mollis pharetra dolor quis commodo. Nunc eget dui luctus, volutpat velit vel, egestas enim. Morbi semper congue ante, ut tincidunt urna efficitur at. Nunc vulputate est sed mi hendrerit porttitor. Nulla ut nibh vitae augue malesuada commodo vitae vitae magna. Fusce sollicitudin faucibus nisl, ac sollicitudin orci tincidunt ut. Donec aliquet faucibus elit, quis consectetur tortor pulvinar et. Nunc facilisis ante ante, vitae viverra ligula semper non.',
+ 'PUBLISHED', true, '2019-11-20 14:42:34.609474', '2019-12-26 13:45:34.609474', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (4, 1, 'Fermentum iaculis',
+ 'Ut posuere accumsan diam, non vestibulum mauris aliquet non. Cras sed nisl id orci imperdiet pellentesque. Duis facilisis porttitor varius. Mauris quis leo facilisis, scelerisque massa non, ornare turpis. Donec ultricies eget massa vitae pellentesque. Nunc rhoncus faucibus hendrerit. Pellentesque et maximus leo, ac posuere nunc. Cras vitae tincidunt nibh. Ut non erat vel felis congue iaculis.',
+ 'PUBLISHED', true, '2020-01-20 14:42:34.609474', '2020-02-26 13:45:34.609474', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (5, 1, 'Fermentum iaculis',
+ 'Suspendisse vel ex venenatis, euismod augue at, auctor velit. Sed fringilla, arcu in pulvinar condimentum, urna nulla iaculis felis, in ornare orci turpis non nibh. Pellentesque turpis ante, hendrerit sed tempor elementum, tristique quis justo. Ut non dignissim orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut vel augue nec magna cursus bibendum at eu eros. Phasellus dui ligula, accumsan sit amet tincidunt nec, ornare vel metus. Proin justo mauris, ullamcorper ut euismod malesuada, iaculis a lectus. Aliquam maximus laoreet justo vel viverra. Curabitur at lacus nisl. Nunc tincidunt faucibus dolor eu mollis. Mauris id sem id lorem luctus pretium nec sit amet turpis. Maecenas eu leo sit amet metus commodo aliquet sit amet vitae lectus. Cras finibus luctus urna a ullamcorper.',
+ 'PUBLISHED', true, '2020-02-20 14:42:34.609474', '2020-03-26 13:45:34.609474', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'Ninth therapy post',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 'PUBLISHED', true, '2020-12-14 11:59:53.000000', '2020-12-14 11:59:53.000000', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (6, 1, 'Fermentum iaculis',
+ 'Quisque sollicitudin orci sollicitudin sapien finibus tempus. Nulla sapien urna, viverra quis enim posuere, consectetur laoreet elit. Nulla a pretium diam. Nulla facilisi. Sed ipsum ante, dictum non justo sit amet, commodo ultricies dolor. Etiam sed nunc vel justo tincidunt varius. Etiam in pretium lectus. Donec porttitor lobortis sem, eget consequat metus accumsan ac. Ut ex dolor, efficitur sit amet sodales in, vulputate quis tortor. Nunc sit amet nisl tortor. Sed finibus feugiat quam, eget tincidunt turpis vestibulum id. Mauris maximus ex leo, a egestas mauris sollicitudin in. Aenean ut arcu pellentesque eros efficitur posuere. Nam lobortis accumsan suscipit. Sed velit est, aliquam nec odio in, sodales facilisis ex.',
+ 'PUBLISHED', true, '2020-03-20 14:42:34.609474', '2020-04-26 13:45:34.609474', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (7, 1, 'Fermentum iaculis',
+ 'Cras at est ex. Aliquam erat volutpat. Donec ultricies dolor nec justo euismod pretium. Donec elementum vestibulum feugiat. Fusce ullamcorper sapien sit amet venenatis convallis. Sed sagittis interdum sapien ac interdum. Praesent porttitor condimentum lacus, ac aliquam dui pulvinar accumsan.',
+ 'PUBLISHED', true, '2020-04-20 14:42:34.609474', '2020-05-26 13:45:34.609474', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (8, 1, 'Fermentum iaculis',
+ 'Praesent nec maximus sem. Ut imperdiet, libero sit amet porta vulputate, dolor erat pretium neque, in efficitur eros enim in enim. In non pretium urna. Suspendisse quis ante ut erat pulvinar accumsan. Integer molestie ex eget libero tincidunt, sit amet ullamcorper mauris fermentum. Donec porta posuere ornare. Etiam congue quis lacus id volutpat. Integer scelerisque a dolor non tristique. Sed nisl sapien, tincidunt sit amet posuere ut, bibendum at velit. Proin eget risus in risus accumsan accumsan pharetra rutrum leo. Vivamus porta lectus leo, vel tincidunt libero rhoncus vitae. Sed et dolor nec tellus ornare bibendum at vel mi. Donec pellentesque placerat fringilla.',
+ 'PUBLISHED', true, '2020-05-20 14:42:34.609474', '2020-06-26 13:45:34.609474', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'Fermentum iaculis',
+ 'Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Proin orci lectus, sodales sed varius non, fringilla non metus. Nam tincidunt libero eu tincidunt lacinia. Sed scelerisque metus at purus pellentesque, eu elementum mauris tempor. Mauris metus mauris, convallis in porttitor sit amet, fermentum vel ipsum. Sed hendrerit volutpat eros, quis commodo ligula aliquet vitae. Nullam gravida quam et ligula facilisis, a volutpat sapien viverra. Integer non porta enim, in blandit leo. Etiam tempor elit lacus, ut venenatis massa rhoncus at. Etiam eu massa rutrum, aliquet arcu at, lobortis ligula. In sit amet nisi nec ex congue lobortis vitae at risus. Praesent elementum accumsan magna, eget auctor ex scelerisque non. Fusce posuere, metus varius malesuada varius, sem velit varius mauris, eget scelerisque mi turpis sit amet dui. Cras pellentesque pulvinar tincidunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
+ 'PUBLISHED', true, '2020-07-20 14:42:34.609474', '2020-08-26 13:45:34.609474', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'First therapy post',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 'PUBLISHED', true, '2020-12-06 11:59:53.000000', '2020-12-06 11:59:53.000000', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'Second therapy post',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 'PUBLISHED', true, '2020-12-07 11:59:53.000000', '2020-12-07 11:59:53.000000', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'Third therapy post',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 'PUBLISHED', true, '2020-12-08 11:59:53.000000', '2020-12-08 11:59:53.000000', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'Fourth therapy post',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 'PUBLISHED', true, '2020-12-09 11:59:53.000000', '2020-12-09 11:59:53.000000', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'Fifth therapy post',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 'PUBLISHED', true, '2020-12-10 11:59:53.000000', '2020-12-10 11:59:53.000000', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'Sixth therapy post',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 'PUBLISHED', true, '2020-12-11 11:59:53.000000', '2020-12-11 11:59:53.000000', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'Seventh therapy post',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 'PUBLISHED', true, '2020-12-12 11:59:53.000000', '2020-12-12 11:59:53.000000', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'Eighth therapy post',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 'PUBLISHED', true, '2020-12-13 11:59:53.000000', '2020-12-13 11:59:53.000000', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'Tenth therapy post',
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
+ 'PUBLISHED', true, '2020-12-15 11:59:53.000000', '2020-12-15 11:59:53.000000', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'Fermentum iaculis',
+ 'Duis finibus risus et hendrerit fringilla. Donec varius nisi massa, eu facilisis velit iaculis id. Sed porta lectus eget lectus auctor, at iaculis risus consequat. Morbi lacinia pretium est, pulvinar porttitor lorem facilisis ut. Etiam in nisi justo. Vivamus luctus efficitur mauris, ut placerat lorem imperdiet a. Phasellus condimentum ante quis leo tempor semper. Nam sit amet faucibus orci, et egestas tortor. Maecenas ornare a lorem nec mattis. Etiam ac dapibus quam. Proin consequat laoreet rutrum. Cras et congue ligula.',
+ 'PUBLISHED', true, '2020-06-20 14:42:34.609474', '2020-07-26 13:45:34.609474', 'Fermentum iaculis');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (1, 1, 'Fermentum iaculis',
+ 'Fermentum iaculis eu non diam phasellus vestibulum lorem sed. Et pharetra pharetra massa massa ultricies. Malesuada proin libero nunc consequat interdum varius sit. Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam. Risus ultricies tristique nulla aliquet enim tortor at. Diam quis enim lobortis scelerisque fermentum. Tempor commodo ullamcorper a lacus vestibulum. Erat nam at lectus urna. Dui id ornare arcu odio ut sem nulla pharetra.',
+ 'PUBLISHED', true, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Fermentum iaculis eu non diam phasellus vestibulum lorem sed.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (2, 1, 'Integer eget aliquet',
+ 'Integer eget aliquet nibh praesent tristique magna sit amet purus. Dolor purus non enim praesent elementum facilisis leo. Porttitor eget dolor morbi non. Urna cursus eget nunc scelerisque viverra. Imperdiet massa tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada. Fermentum et sollicitudin ac orci phasellus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Integer eget aliquet nibh praesent tristique magna sit amet purus.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (3, 1, 'Ultrices sagittis orci',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Tempus quam pellentesque nec nam aliquam sem. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ultrices sagittis orci a scelerisque purus semper eget.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (4, 1, 'Massa eget egestas',
+ 'Massa eget egestas purus viverra accumsan. Porta non pulvinar neque laoreet suspendisse interdum consectetur. Vitae suscipit tellus mauris a diam. Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Massa eget egestas purus viverra accumsan. Porta non pulvinar');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (5, 1, 'Est ullamcorper eget',
+ 'Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam. Risus ultricies tristique nulla aliquet enim tortor at. Diam quis enim lobortis scelerisque fermentum. Tempor commodo ullamcorper a lacus vestibulum. Erat nam at lectus urna.',
+ 'PUBLISHED', true, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (6, 1, 'Sit amet consectetur',
+ 'Varius vel pharetra vel turpis nunc eget. Nisl tincidunt eget nullam non nisi est sit amet facilisis. Integer eget aliquet nibh praesent tristique magna sit amet purus. Dolor purus non enim praesent elementum facilisis leo.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Varius vel pharetra vel turpis nunc eget. Nisl tincidunt eget nullam non nisi est sit amet facilisis.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (7, 1, 'Proin nibh nisl condimentum',
+ 'Ullamcorper malesuada proin libero nunc consequat. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Leo in vitae turpis massa sed. Ultrices eros in cursus turpis.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ullamcorper malesuada proin libero nunc consequat.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (8, 1, 'Tempus quam pellentesque',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Tempus quam pellentesque nec nam aliquam sem. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend. Nullam vehicula ipsum a arcu cursus vitae congue mauris rhoncus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'Tempus quam pellentesque', 'Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Proin nibh nisl condimentum id venenatis a condimentum vitae.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (11, 1, 'Ultrices eros in cursus', 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (12, 1, 'Fermentum iaculis',
+ 'Fermentum iaculis eu non diam phasellus vestibulum lorem sed. Et pharetra pharetra massa massa ultricies. Malesuada proin libero nunc consequat interdum varius sit. Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam. Risus ultricies tristique nulla aliquet enim tortor at. Diam quis enim lobortis scelerisque fermentum. Tempor commodo ullamcorper a lacus vestibulum. Erat nam at lectus urna. Dui id ornare arcu odio ut sem nulla pharetra.',
+ 'PUBLISHED', true, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Fermentum iaculis eu non diam phasellus vestibulum lorem sed.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (13, 1, 'Integer eget aliquet',
+ 'Integer eget aliquet nibh praesent tristique magna sit amet purus. Dolor purus non enim praesent elementum facilisis leo. Porttitor eget dolor morbi non. Urna cursus eget nunc scelerisque viverra. Imperdiet massa tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada. Fermentum et sollicitudin ac orci phasellus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Integer eget aliquet nibh praesent tristique magna sit amet purus.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (14, 1, 'Ultrices sagittis orci',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Tempus quam pellentesque nec nam aliquam sem. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ultrices sagittis orci a scelerisque purus semper eget.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (15, 1, 'Massa eget egestas',
+ 'Massa eget egestas purus viverra accumsan. Porta non pulvinar neque laoreet suspendisse interdum consectetur. Vitae suscipit tellus mauris a diam. Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Massa eget egestas purus viverra accumsan. Porta non pulvinar');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (16, 1, 'Est ullamcorper eget',
+ 'Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam. Risus ultricies tristique nulla aliquet enim tortor at. Diam quis enim lobortis scelerisque fermentum. Tempor commodo ullamcorper a lacus vestibulum. Erat nam at lectus urna.',
+ 'PUBLISHED', true, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (17, 1, 'Sit amet consectetur',
+ 'Varius vel pharetra vel turpis nunc eget. Nisl tincidunt eget nullam non nisi est sit amet facilisis. Integer eget aliquet nibh praesent tristique magna sit amet purus. Dolor purus non enim praesent elementum facilisis leo.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Varius vel pharetra vel turpis nunc eget. Nisl tincidunt eget nullam non nisi est sit amet facilisis.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (18, 1, 'Proin nibh nisl condimentum',
+ 'Ullamcorper malesuada proin libero nunc consequat. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Leo in vitae turpis massa sed. Ultrices eros in cursus turpis.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ullamcorper malesuada proin libero nunc consequat.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (19, 1, 'Tempus quam pellentesque',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Tempus quam pellentesque nec nam aliquam sem. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend. Nullam vehicula ipsum a arcu cursus vitae congue mauris rhoncus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (20, 1, 'Tempus quam pellentesque', 'Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Proin nibh nisl condimentum id venenatis a condimentum vitae.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (21, 1, 'Ultrices eros in cursus', 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (22, 1, 'Fermentum iaculis',
+ 'Fermentum iaculis eu non diam phasellus vestibulum lorem sed. Et pharetra pharetra massa massa ultricies. Malesuada proin libero nunc consequat interdum varius sit. Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam. Risus ultricies tristique nulla aliquet enim tortor at. Diam quis enim lobortis scelerisque fermentum. Tempor commodo ullamcorper a lacus vestibulum. Erat nam at lectus urna. Dui id ornare arcu odio ut sem nulla pharetra.',
+ 'PUBLISHED', true, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Fermentum iaculis eu non diam phasellus vestibulum lorem sed.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (23, 1, 'Integer eget aliquet',
+ 'Integer eget aliquet nibh praesent tristique magna sit amet purus. Dolor purus non enim praesent elementum facilisis leo. Porttitor eget dolor morbi non. Urna cursus eget nunc scelerisque viverra. Imperdiet massa tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada. Fermentum et sollicitudin ac orci phasellus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Integer eget aliquet nibh praesent tristique magna sit amet purus.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (24, 1, 'Ultrices sagittis orci',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Tempus quam pellentesque nec nam aliquam sem. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ultrices sagittis orci a scelerisque purus semper eget.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (25, 1, 'Massa eget egestas',
+ 'Massa eget egestas purus viverra accumsan. Porta non pulvinar neque laoreet suspendisse interdum consectetur. Vitae suscipit tellus mauris a diam. Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Massa eget egestas purus viverra accumsan. Porta non pulvinar');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (26, 1, 'Est ullamcorper eget',
+ 'Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam. Risus ultricies tristique nulla aliquet enim tortor at. Diam quis enim lobortis scelerisque fermentum. Tempor commodo ullamcorper a lacus vestibulum. Erat nam at lectus urna.',
+ 'PUBLISHED', true, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (27, 1, 'Sit amet consectetur',
+ 'Varius vel pharetra vel turpis nunc eget. Nisl tincidunt eget nullam non nisi est sit amet facilisis. Integer eget aliquet nibh praesent tristique magna sit amet purus. Dolor purus non enim praesent elementum facilisis leo.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Varius vel pharetra vel turpis nunc eget. Nisl tincidunt eget nullam non nisi est sit amet facilisis.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (28, 1, 'Proin nibh nisl condimentum',
+ 'Ullamcorper malesuada proin libero nunc consequat. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Leo in vitae turpis massa sed. Ultrices eros in cursus turpis.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ullamcorper malesuada proin libero nunc consequat.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (29, 1, 'Tempus quam pellentesque',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Tempus quam pellentesque nec nam aliquam sem. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend. Nullam vehicula ipsum a arcu cursus vitae congue mauris rhoncus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (30, 1, 'Tempus quam pellentesque', 'Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Proin nibh nisl condimentum id venenatis a condimentum vitae.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (31, 1, 'Ultrices eros in cursus', 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (32, 1, 'Tempus quam pellentesque', 'Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Proin nibh nisl condimentum id venenatis a condimentum vitae.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (33, 1, 'Ultrices eros in cursus', 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (34, 1, 'Tempus quam pellentesque', 'Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Proin nibh nisl condimentum id venenatis a condimentum vitae.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (35, 1, 'Ultrices eros in cursus', 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (36, 1, 'Tempus quam pellentesque', 'Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Proin nibh nisl condimentum id venenatis a condimentum vitae.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (37, 1, 'Ultrices eros in cursus', 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (11, 1, 'Fermentum iaculis',
+ 'Fermentum iaculis eu non diam phasellus vestibulum lorem sed. Et pharetra pharetra massa massa ultricies. Malesuada proin libero nunc consequat interdum varius sit. Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam. Risus ultricies tristique nulla aliquet enim tortor at. Diam quis enim lobortis scelerisque fermentum. Tempor commodo ullamcorper a lacus vestibulum. Erat nam at lectus urna. Dui id ornare arcu odio ut sem nulla pharetra.',
+ 'PUBLISHED', true, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Fermentum iaculis eu non diam phasellus vestibulum lorem sed.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (10, 1, 'Integer eget aliquet',
+ 'Integer eget aliquet nibh praesent tristique magna sit amet purus. Dolor purus non enim praesent elementum facilisis leo. Porttitor eget dolor morbi non. Urna cursus eget nunc scelerisque viverra. Imperdiet massa tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada. Fermentum et sollicitudin ac orci phasellus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Integer eget aliquet nibh praesent tristique magna sit amet purus.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (8, 1, 'Ultrices sagittis orci',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Tempus quam pellentesque nec nam aliquam sem. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ultrices sagittis orci a scelerisque purus semper eget.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (7, 1, 'Massa eget egestas',
+ 'Massa eget egestas purus viverra accumsan. Porta non pulvinar neque laoreet suspendisse interdum consectetur. Vitae suscipit tellus mauris a diam. Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Massa eget egestas purus viverra accumsan. Porta non pulvinar');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (6, 1, 'Est ullamcorper eget',
+ 'Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam. Risus ultricies tristique nulla aliquet enim tortor at. Diam quis enim lobortis scelerisque fermentum. Tempor commodo ullamcorper a lacus vestibulum. Erat nam at lectus urna.',
+ 'PUBLISHED', true, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (5, 1, 'Sit amet consectetur',
+ 'Varius vel pharetra vel turpis nunc eget. Nisl tincidunt eget nullam non nisi est sit amet facilisis. Integer eget aliquet nibh praesent tristique magna sit amet purus. Dolor purus non enim praesent elementum facilisis leo.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Varius vel pharetra vel turpis nunc eget. Nisl tincidunt eget nullam non nisi est sit amet facilisis.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (4, 1, 'Proin nibh nisl condimentum',
+ 'Ullamcorper malesuada proin libero nunc consequat. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Leo in vitae turpis massa sed. Ultrices eros in cursus turpis.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ullamcorper malesuada proin libero nunc consequat.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (3, 1, 'Tempus quam pellentesque',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Tempus quam pellentesque nec nam aliquam sem. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend. Nullam vehicula ipsum a arcu cursus vitae congue mauris rhoncus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (2, 1, 'Tempus quam pellentesque', 'Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Proin nibh nisl condimentum id venenatis a condimentum vitae.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (1, 1, 'Ultrices eros in cursus', 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (21, 1, 'Fermentum iaculis',
+ 'Fermentum iaculis eu non diam phasellus vestibulum lorem sed. Et pharetra pharetra massa massa ultricies. Malesuada proin libero nunc consequat interdum varius sit. Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam. Risus ultricies tristique nulla aliquet enim tortor at. Diam quis enim lobortis scelerisque fermentum. Tempor commodo ullamcorper a lacus vestibulum. Erat nam at lectus urna. Dui id ornare arcu odio ut sem nulla pharetra.',
+ 'PUBLISHED', true, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Fermentum iaculis eu non diam phasellus vestibulum lorem sed.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (20, 1, 'Integer eget aliquet',
+ 'Integer eget aliquet nibh praesent tristique magna sit amet purus. Dolor purus non enim praesent elementum facilisis leo. Porttitor eget dolor morbi non. Urna cursus eget nunc scelerisque viverra. Imperdiet massa tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada. Fermentum et sollicitudin ac orci phasellus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Integer eget aliquet nibh praesent tristique magna sit amet purus.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (19, 1, 'Ultrices sagittis orci',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Tempus quam pellentesque nec nam aliquam sem. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ultrices sagittis orci a scelerisque purus semper eget.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (18, 1, 'Massa eget egestas',
+ 'Massa eget egestas purus viverra accumsan. Porta non pulvinar neque laoreet suspendisse interdum consectetur. Vitae suscipit tellus mauris a diam. Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Massa eget egestas purus viverra accumsan. Porta non pulvinar');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (17, 1, 'Est ullamcorper eget',
+ 'Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam. Risus ultricies tristique nulla aliquet enim tortor at. Diam quis enim lobortis scelerisque fermentum. Tempor commodo ullamcorper a lacus vestibulum. Erat nam at lectus urna.',
+ 'PUBLISHED', true, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Mauris cursus mattis molestie a. Est ullamcorper eget nulla facilisi etiam dignissim diam');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (16, 1, 'Sit amet consectetur',
+ 'Varius vel pharetra vel turpis nunc eget. Nisl tincidunt eget nullam non nisi est sit amet facilisis. Integer eget aliquet nibh praesent tristique magna sit amet purus. Dolor purus non enim praesent elementum facilisis leo.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Varius vel pharetra vel turpis nunc eget. Nisl tincidunt eget nullam non nisi est sit amet facilisis.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (15, 1, 'Proin nibh nisl condimentum',
+ 'Ullamcorper malesuada proin libero nunc consequat. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Leo in vitae turpis massa sed. Ultrices eros in cursus turpis.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ullamcorper malesuada proin libero nunc consequat.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (14, 1, 'Tempus quam pellentesque',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Tempus quam pellentesque nec nam aliquam sem. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend. Nullam vehicula ipsum a arcu cursus vitae congue mauris rhoncus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (13, 1, 'Tempus quam pellentesque', 'Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Proin nibh nisl condimentum id venenatis a condimentum vitae.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (12, 1, 'Ultrices eros in cursus', 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (15, 1, 'Proin nibh nisl condimentum',
+ 'Ullamcorper malesuada proin libero nunc consequat. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Leo in vitae turpis massa sed. Ultrices eros in cursus turpis.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ullamcorper malesuada proin libero nunc consequat.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (14, 1, 'Tempus quam pellentesque',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at. Arcu bibendum at varius vel pharetra vel turpis nunc eget. Tempus quam pellentesque nec nam aliquam sem. Sed egestas egestas fringilla phasellus faucibus scelerisque eleifend. Nullam vehicula ipsum a arcu cursus vitae congue mauris rhoncus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Ultrices sagittis orci a scelerisque purus semper eget. Arcu non odio euismod lacinia at');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (13, 1, 'Tempus quam pellentesque', 'Proin nibh nisl condimentum id venenatis a condimentum vitae.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Proin nibh nisl condimentum id venenatis a condimentum vitae.');
+INSERT INTO public.posts (author_id, type_id, title, content, status, important, created_at, modified_at,
+ preview)
+VALUES (12, 1, 'Ultrices eros in cursus', 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.',
+ 'PUBLISHED', false, '2021-02-16 03:56:37.700332', '2021-02-16 03:56:37.700332',
+ 'Dolor sit amet consectetur adipiscing elit ut aliquam purus.');
+
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (1, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (1, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (1, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (2, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (2, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (2, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (3, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (3, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (3, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (4, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (4, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (4, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (5, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (5, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (5, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (6, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (6, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (6, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (7, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (7, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (7, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (8, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (8, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (8, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (9, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (10, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (11, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (12, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (13, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (14, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (15, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (16, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (17, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (18, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (19, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (20, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (21, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (22, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (23, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (24, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (25, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (26, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (27, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (28, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (29, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (9, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (10, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (11, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (12, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (13, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (14, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (15, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (16, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (17, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (18, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (19, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (20, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (21, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (22, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (23, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (24, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (25, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (26, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (27, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (28, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (29, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (9, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (10, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (11, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (12, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (13, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (14, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (15, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (16, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (17, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (18, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (19, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (20, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (21, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (22, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (23, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (24, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (25, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (26, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (27, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (28, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (29, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (30, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (30, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (30, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (31, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (31, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (31, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (32, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (32, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (32, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (33, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (33, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (33, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (34, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (34, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (34, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (35, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (35, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (35, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (36, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (36, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (36, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (37, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (37, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (37, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (38, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (38, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (38, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (39, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (39, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (39, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (40, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (40, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (40, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (41, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (41, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (41, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (42, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (42, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (42, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (43, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (43, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (43, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (44, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (44, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (44, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (45, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (45, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (45, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (46, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (46, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (46, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (47, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (47, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (47, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (48, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (48, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (48, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (49, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (49, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (49, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (50, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (50, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (50, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (51, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (51, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (51, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (52, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (52, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (52, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (53, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (53, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (53, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (54, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (54, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (54, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (55, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (55, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (55, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (56, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (56, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (56, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (57, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (57, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (57, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (58, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (58, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (58, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (59, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (59, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (59, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (60, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (60, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (60, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (61, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (61, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (61, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (62, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (62, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (62, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (63, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (63, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (63, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (64, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (64, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (64, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (65, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (65, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (65, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (66, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (66, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (66, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (67, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (67, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (67, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (68, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (68, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (68, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (69, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (69, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (69, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (70, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (70, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (70, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (71, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (71, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (71, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (72, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (72, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (72, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (73, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (73, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (73, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (74, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (74, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (74, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (75, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (75, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (75, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (76, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (76, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (76, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (77, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (77, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (77, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (78, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (78, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (78, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (79, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (79, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (79, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (80, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (80, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (80, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (81, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (81, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (81, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (82, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (82, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (82, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (83, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (83, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (83, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (84, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (84, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (84, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (85, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (85, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (85, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (86, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (86, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (86, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (87, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (87, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (87, 7);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (88, 1);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (88, 2);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (88, 3);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (89, 4);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (89, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (89, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (90, 5);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (90, 6);
+INSERT INTO public.posts_directions (post_id, direction_id)
+VALUES (90, 7);
+
+
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (1, 1);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (1, 2);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (1, 4);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (1, 6);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (2, 1);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (2, 2);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (3, 1);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (3, 4);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (4, 2);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (4, 3);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (4, 4);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (4, 5);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (5, 1);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (6, 2);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (6, 4);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (6, 1);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (6, 3);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (7, 4);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (7, 5);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (8, 1);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (8, 3);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (8, 4);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (9, 2);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (9, 4);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (10, 1);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (10, 3);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (10, 5);
+INSERT INTO public.posts_tags (post_id, tag_id)
+VALUES (10, 6);
+
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'ivan@mail.com', '1', 1);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'andrii@mail.com', '2', 2);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'olena@mail.com', '3', 3);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'dmytro@mail.com', '4', 4);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'kateryna@mail.com', '5', 5);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'oleh@mail.com', '6', 6);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'tetyana@mail.com', '7', 7);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'maryna@mail.com', '8', 8);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'admin@mail.com', '9', 9);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'stepan@mail.com', '10', 10);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'danylo@mail.com', '11', 11);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'petro@mail.com', '12', 12);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'masha@mail.com', '13', 13);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'mykola@mail.com', '14', 14);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'taras@mail.com', '15', 15);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'lesia@mail.com', '16', 16);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'bohdan@mail.com', '17', 17);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'eva@mail.com', '18', 18);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'zahar@mail.com', '19', 19);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'nazar@mail.com', '20', 20);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'zhan@mail.com', '21', 21);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'nikon@mail.com', '22', 22);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'matviy@mail.com', '23', 23);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'regina@mail.com', '24', 24);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'fedot@mail.com', '25', 25);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'terentiy@mail.com', '26', 26);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'platon@mail.com', '27', 27);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'ShtukaNovitskaya261@mail.com', '28', 28);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'FadiStalin333@mail.com', '29', 29);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'PamfiyTihomirov752@mail.com', '30', 30);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'FekletinyaShashkova782@mail.com', '31', 31);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'PalanaLitvinova514@mail.com', '32', 32);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'GigranAlekseev32@mail.com', '33', 33);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'KukuriChapko624@mail.com', '34', 34);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'NezdaUshakov899@mail.com', '35', 35);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'MiletiyChernyshov229@mail.com', '36', 36);
+INSERT INTO public.providers (provider_name, email, user_id_by_provider, user_id)
+VALUES ('LOCAL', 'TarzhemanSokolov585@mail.com', '37', 37);
+
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (1, 'SAVE_OWN_PUBLICATION');
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (1, 'SAVE_TAG');
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (2, 'SAVE_OWN_PUBLICATION');
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (2, 'SAVE_TAG');
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (3, 'SAVE_OWN_PUBLICATION');
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (3, 'SAVE_TAG');
diff --git a/src/main/resources/db/testdata/V1.2__after_migrate.sql b/src/main/resources/db/testdata/V1.2__after_migrate.sql
new file mode 100644
index 00000000..e8a3a8fe
--- /dev/null
+++ b/src/main/resources/db/testdata/V1.2__after_migrate.sql
@@ -0,0 +1,9 @@
+UPDATE DOCTORS D
+SET PUBLISHED_POSTS=(
+ SELECT COUNT(P.POST_ID)
+ FROM POSTS P
+ WHERE P.AUTHOR_ID=D.USER_ID
+ AND STATUS='PUBLISHED'
+);
+
+UPDATE DOCTORS SET RATING=PUBLISHED_POSTS * PROMOTION_SCALE;
\ No newline at end of file
diff --git a/src/main/resources/db/testdata/V1.3__add_role_permission.sql b/src/main/resources/db/testdata/V1.3__add_role_permission.sql
new file mode 100644
index 00000000..2cfa8cc9
--- /dev/null
+++ b/src/main/resources/db/testdata/V1.3__add_role_permission.sql
@@ -0,0 +1,2 @@
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (1, 'DELETE_POST');
\ No newline at end of file
diff --git a/src/main/resources/db/testdata/V1.4__refactor_providers_table.sql b/src/main/resources/db/testdata/V1.4__refactor_providers_table.sql
new file mode 100644
index 00000000..4e0e5196
--- /dev/null
+++ b/src/main/resources/db/testdata/V1.4__refactor_providers_table.sql
@@ -0,0 +1,39 @@
+update providers set user_id=1,user_id_by_provider=1 where email='TarzhemanSokolov585@mail.com';
+update providers set user_id=2,user_id_by_provider=2 where email='MiletiyChernyshov229@mail.com';
+update providers set user_id=3,user_id_by_provider=3 where email='NezdaUshakov899@mail.com';
+update providers set user_id=4,user_id_by_provider=4 where email='KukuriChapko624@mail.com';
+update providers set user_id=5,user_id_by_provider=5 where email='GigranAlekseev32@mail.com';
+update providers set user_id=6,user_id_by_provider=6 where email='PalanaLitvinova514@mail.com';
+update providers set user_id=7,user_id_by_provider=7 where email='regina@mail.com';
+update providers set user_id=8,user_id_by_provider=8 where email='taras@mail.com';
+update providers set user_id=9,user_id_by_provider=9 where email='mykola@mail.com';
+update providers set user_id=10,user_id_by_provider=10 where email='masha@mail.com';
+update providers set user_id=11,user_id_by_provider=11 where email='danylo@mail.com';
+update providers set user_id=12,user_id_by_provider=12 where email='stepan@mail.com';
+update providers set user_id=13,user_id_by_provider=13 where email='maryna@mail.com';
+update providers set user_id=14,user_id_by_provider=14 where email='oleh@mail.com';
+update providers set user_id=15,user_id_by_provider=15 where email='kateryna@mail.com';
+update providers set user_id=16,user_id_by_provider=16 where email='dmytro@mail.com';
+update providers set user_id=17,user_id_by_provider=17 where email='olena@mail.com';
+update providers set user_id=18,user_id_by_provider=18 where email='andrii@mail.com';
+update providers set user_id=19,user_id_by_provider=19 where email='ivan@mail.com';
+update providers set user_id=20,user_id_by_provider=20 where email='FekletinyaShashkova782@mail.com';
+update providers set user_id=21,user_id_by_provider=21 where email='PamfiyTihomirov752@mail.com';
+update providers set user_id=22,user_id_by_provider=22 where email='FadiStalin333@mail.com';
+update providers set user_id=23,user_id_by_provider=23 where email='ShtukaNovitskaya261@mail.com';
+update providers set user_id=24,user_id_by_provider=24 where email='platon@mail.com';
+update providers set user_id=25,user_id_by_provider=25 where email='terentiy@mail.com';
+update providers set user_id=26,user_id_by_provider=26 where email='fedot@mail.com';
+update providers set user_id=27,user_id_by_provider=27 where email='admin@mail.com';
+update providers set user_id=28,user_id_by_provider=28 where email='matviy@mail.com';
+update providers set user_id=29,user_id_by_provider=29 where email='nikon@mail.com';
+update providers set user_id=30,user_id_by_provider=30 where email='zhan@mail.com';
+update providers set user_id=31,user_id_by_provider=31 where email='nazar@mail.com';
+update providers set user_id=32,user_id_by_provider=32 where email='petro@mail.com';
+update providers set user_id=33,user_id_by_provider=33 where email='tetyana@mail.com';
+update providers set user_id=34,user_id_by_provider=34 where email='zahar@mail.com';
+update providers set user_id=35,user_id_by_provider=35 where email='eva@mail.com';
+update providers set user_id=36,user_id_by_provider=36 where email='bohdan@mail.com';
+update providers set user_id=37,user_id_by_provider=37 where email='lesia@mail.com';
+
+
diff --git a/src/main/resources/db/testdata/V1.5__trim_bio_field_in_doctors_table.sql b/src/main/resources/db/testdata/V1.5__trim_bio_field_in_doctors_table.sql
new file mode 100644
index 00000000..1c7d6fa3
--- /dev/null
+++ b/src/main/resources/db/testdata/V1.5__trim_bio_field_in_doctors_table.sql
@@ -0,0 +1,4 @@
+UPDATE DOCTORS SET BIO='Lorem ipsum dolor sit amet, consectetur adipiscing' WHERE DOCTOR_ID>=1 AND DOCTOR_ID<=9;
+UPDATE DOCTORS SET BIO='Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna a.' WHERE DOCTOR_ID>=10 AND DOCTOR_ID<=18;
+UPDATE DOCTORS SET BIO='Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam q.' WHERE DOCTOR_ID>=19 AND DOCTOR_ID<=27;
+UPDATE DOCTORS SET BIO='Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat duis.' WHERE DOCTOR_ID>=28 AND DOCTOR_ID<=36;
\ No newline at end of file
diff --git a/src/main/resources/db/testdata/V10.1__set_all_posts_unimportant.sql b/src/main/resources/db/testdata/V10.1__set_all_posts_unimportant.sql
new file mode 100644
index 00000000..d26ff593
--- /dev/null
+++ b/src/main/resources/db/testdata/V10.1__set_all_posts_unimportant.sql
@@ -0,0 +1 @@
+UPDATE POSTS SET IMPORTANT = FALSE WHERE POST_ID>0;
\ No newline at end of file
diff --git a/src/main/resources/db/testdata/V10.2__add_set_importance_permission.sql b/src/main/resources/db/testdata/V10.2__add_set_importance_permission.sql
new file mode 100644
index 00000000..1c7468cf
--- /dev/null
+++ b/src/main/resources/db/testdata/V10.2__add_set_importance_permission.sql
@@ -0,0 +1,2 @@
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (1, 'SET_IMPORTANCE');
\ No newline at end of file
diff --git a/src/main/resources/db/testdata/V2.1__add__origins_demo_data.sql b/src/main/resources/db/testdata/V2.1__add__origins_demo_data.sql
new file mode 100644
index 00000000..409d0e44
--- /dev/null
+++ b/src/main/resources/db/testdata/V2.1__add__origins_demo_data.sql
@@ -0,0 +1,6 @@
+INSERT INTO public.origins (name, parameters)
+VALUES ('Думка експерта', null);
+INSERT INTO public.origins (name, parameters)
+VALUES ('Медитека', null);
+INSERT INTO public.origins (name, parameters)
+VALUES ('Переклад', null);
\ No newline at end of file
diff --git a/src/main/resources/db/testdata/V3.1__add_posts_origins_demo_data.sql b/src/main/resources/db/testdata/V3.1__add_posts_origins_demo_data.sql
new file mode 100644
index 00000000..22e4ecab
--- /dev/null
+++ b/src/main/resources/db/testdata/V3.1__add_posts_origins_demo_data.sql
@@ -0,0 +1,180 @@
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (1,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (2,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (3,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (4,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (5,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (6,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (7,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (8,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (9,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (10,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (11,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (12,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (13,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (14,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (15,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (16,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (17,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (18,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (19,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (20,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (21,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (22,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (23,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (24,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (25,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (26,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (27,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (28,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (29,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (30,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (31,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (32,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (33,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (34,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (35,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (36,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (37,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (38,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (39,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (40,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (41,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (42,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (43,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (44,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (45,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (46,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (47,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (48,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (49,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (50,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (51,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (52,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (53,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (54,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (55,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (56,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (57,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (58,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (59,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (60,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (61,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (62,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (63,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (64,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (65,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (66,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (67,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (68,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (69,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (70,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (71,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (72,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (73,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (74,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (75,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (76,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (77,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (78,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (79,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (80,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (81,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (82,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (83,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (84,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (85,2);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (86,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (87,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (88,3);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (89,1);
+INSERT INTO public.posts_origins(post_id, origin_id)
+VALUES (90,2);
\ No newline at end of file
diff --git a/src/main/resources/db/testdata/V3.2__add_role_permission.sql b/src/main/resources/db/testdata/V3.2__add_role_permission.sql
new file mode 100644
index 00000000..bf23c0bc
--- /dev/null
+++ b/src/main/resources/db/testdata/V3.2__add_role_permission.sql
@@ -0,0 +1,14 @@
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (1, 'DELETE_POST');
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (2, 'DELETE_POST');
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (3, 'DELETE_OWN_POST');
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (1, 'UPDATE_POST');
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (2, 'UPDATE_POST');
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (3, 'UPDATE_OWN_POST');
+INSERT INTO public.role_permission (role_id, permissions)
+VALUES (1, 'SAVE_PUBLICATION');
\ No newline at end of file
diff --git a/src/main/resources/db/testdata/V9.1__add_doctors_social_network_demo_data.sql b/src/main/resources/db/testdata/V9.1__add_doctors_social_network_demo_data.sql
new file mode 100644
index 00000000..3a2f0c3c
--- /dev/null
+++ b/src/main/resources/db/testdata/V9.1__add_doctors_social_network_demo_data.sql
@@ -0,0 +1,4 @@
+UPDATE DOCTORS SET SOCIAL_NETWORK='https://www.instagram.com' WHERE DOCTOR_ID>=1 AND DOCTOR_ID<9;
+UPDATE DOCTORS SET SOCIAL_NETWORK='https://www.linkedin.com/' WHERE DOCTOR_ID>8 AND DOCTOR_ID<15;
+UPDATE DOCTORS SET SOCIAL_NETWORK='https://www.facebook.com' WHERE DOCTOR_ID>14 AND DOCTOR_ID<27;
+UPDATE DOCTORS SET SOCIAL_NETWORK='https://www.youtube.com' WHERE DOCTOR_ID>26 AND DOCTOR_ID<=36;
\ No newline at end of file
diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml
new file mode 100644
index 00000000..79e8b9b5
--- /dev/null
+++ b/src/main/resources/logback-spring.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+ %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
+
+
+
+
+
+
+
+
+
+
+
+
+ ${LOG_DIR}/${LOG_FILE}.log
+
+ %d %p %C{1.} [%t] %m%n
+
+
+
+ ${LOG_DIR}/archived/${LOG_FILE}-%d{yyyy-MM-dd}.%i.gz
+
+
+ 10MB
+
+
+ 30
+ 3GB
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/template/verificationMail.html b/src/main/resources/template/verificationMail.html
new file mode 100644
index 00000000..a7f170b9
--- /dev/null
+++ b/src/main/resources/template/verificationMail.html
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+