Skip to content

Commit

Permalink
feat: add user uid work
Browse files Browse the repository at this point in the history
  • Loading branch information
edikgoose committed Dec 8, 2023
1 parent a0bbe14 commit 3884ff2
Show file tree
Hide file tree
Showing 19 changed files with 94 additions and 147 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,33 @@ package poga.parking.parkingservice.controller

import io.github.oshai.kotlinlogging.KotlinLogging
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
import io.swagger.v3.oas.annotations.enums.ParameterIn.PATH
import io.swagger.v3.oas.annotations.media.Schema
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.beans.factory.annotation.Autowired
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.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import poga.parking.parkingservice.controller.model.input.UserAuthInputDto
import poga.parking.parkingservice.controller.model.input.UserInputDto
import poga.parking.parkingservice.controller.model.ouput.StatisticsOutputDto
import poga.parking.parkingservice.controller.model.ouput.UserOutputDto
import poga.parking.parkingservice.service.StatisticsService
import poga.parking.parkingservice.service.UserService
import poga.parking.parkingservice.support.toHttpStatusCode
import poga.parking.parkingservice.support.withLogging

@RestController
@RequestMapping("user")
@Tag(name = "API for user registration and auth")
@Tag(name = "API for user manipulation")
class UserController(
@Autowired val userService: UserService
@Autowired val userService: UserService,
@Autowired val statisticsService: StatisticsService
) {
@PostMapping("/signup")
@Operation(summary = "Register user")
Expand All @@ -31,20 +39,41 @@ class UserController(
)
}.withLogging(endpoint = REGISTER_USER_ENDPOINT, logger = logger)

@PostMapping("/signin")
@Operation(summary = "Authenticate user")
fun authenticateUser(userAuthInputDto: UserAuthInputDto): ResponseEntity<UserOutputDto> = {
@GetMapping("/price/{uid}")
@Operation(summary = "Get price for uid")
@Parameter(
name = "uid",
`in` = PATH,
schema = Schema(type = "string"),
description = "uid пользователя",
example = "1234567890",
required = true
)
fun getPrice(@PathVariable uid: String): ResponseEntity<Double> = {
ResponseEntity(
userService.authenticateUser(userAuthInputDto),
userService.getPrice(uid),
HttpStatus.OK.toHttpStatusCode(),
)
}.withLogging(endpoint = GET_PRICE_ENDPOINT, logger = logger)

@GetMapping("/statistics/{uid}")
@Operation(summary = "Get statistics of user with uid")
fun totalStatistics(
@PathVariable uid: String,
@RequestParam bookedNow: Boolean
): ResponseEntity<List<StatisticsOutputDto>> = {
ResponseEntity(
statisticsService.totalStatistics(uid = uid, bookedNow = bookedNow),
HttpStatus.OK.toHttpStatusCode()
)
}.withLogging(endpoint = AUTH_USER_ENDPOINT, logger = logger)
}.withLogging(endpoint = GET_TOTAL_STATS_ENDPOINT, logger = logger)

companion object {
private val logger = KotlinLogging.logger { }

private const val USERS_ENDPOINT = "/user"
private const val REGISTER_USER_ENDPOINT = "$USERS_ENDPOINT/signup"
private const val AUTH_USER_ENDPOINT = "$USERS_ENDPOINT/signin"
private const val GET_PRICE_ENDPOINT = "$USERS_ENDPOINT/price/{uid}"
private const val GET_TOTAL_STATS_ENDPOINT = "$USERS_ENDPOINT/statistics/{uid}"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.RestControllerAdvice
import poga.parking.parkingservice.controller.PlaceController
import poga.parking.parkingservice.controller.StatisticsController
import poga.parking.parkingservice.controller.UserController
import poga.parking.parkingservice.controller.model.ouput.ErrorResponse
import poga.parking.parkingservice.exception.InternalServerErrorException
import poga.parking.parkingservice.exception.InvalidCreditsException
import poga.parking.parkingservice.exception.NotFoundErrorException
import poga.parking.parkingservice.exception.ParkingPlaceAlreadyOccupiedException

@RestControllerAdvice(basePackageClasses = [PlaceController::class, StatisticsController::class])
@RestControllerAdvice(basePackageClasses = [PlaceController::class, UserController::class])
class ExceptionHandlerAdvice {

@ExceptionHandler(InternalServerErrorException::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package poga.parking.parkingservice.controller.model.input
data class BookPlaceDto(
val carBrand: String,
val carPlate: String,
val email: String,
val uid: String,
val placeNumber: String
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package poga.parking.parkingservice.controller.model.input

data class UserInputDto(
val firstName: String,
val secondName: String,
val phoneNumber: String,
val email: String,
val password: String
val uid: String,
val firstName: String?,
val secondName: String?,
val phoneNumber: String?,
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package poga.parking.parkingservice.controller.model.ouput

data class UserOutputDto(
val id: Long,
val firstName: String,
val secondName: String,
val phoneNumber: String,
val uid: String,
val firstName: String?,
val secondName: String?,
val phoneNumber: String?,
val email: String
)
29 changes: 9 additions & 20 deletions src/main/kotlin/poga/parking/parkingservice/entity/User.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,27 @@ import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.EnumType
import jakarta.persistence.Enumerated
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import jakarta.persistence.SequenceGenerator
import jakarta.persistence.Table
import poga.parking.parkingservice.enumeration.UserType

@Entity
@Table(name = "user", schema = "public")
data class User(
@Id
@GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "user_generator"
)
@SequenceGenerator(name = "user_generator", sequenceName = "user_id_seq", allocationSize = 1)
var id: Long? = null,
var id: String,

@Column(name = "first_name", nullable = false)
var firstName: String,
@Column(name = "first_name")
var firstName: String?,

@Column(name = "second_name", nullable = false)
var secondName: String,
@Column(name = "second_name")
var secondName: String?,

@Column(name = "phone_number", unique = true, nullable = false)
var phoneNumber: String,
@Column(name = "phone_number")
var phoneNumber: String?,

@Column(name = "email")
var email: String? = null,

@Column(name = "password")
var password: String?,
@Column(name = "email", nullable = false)
var email: String,

@Column(name = "type", nullable = false)
@Enumerated(EnumType.STRING)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,4 @@ import org.springframework.stereotype.Repository
import poga.parking.parkingservice.entity.User

@Repository
interface UserRepository : JpaRepository<User, Long> {

fun findByEmail(email: String): User?

fun findByEmailAndPassword(email: String, password: String): User?
}
interface UserRepository : JpaRepository<User, String>
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ class PlaceService(
fun bookPlace(bookPlaceDto: BookPlaceDto): BookedPlaceOutputDto {
val user = bookPlaceDto
.let { dto ->
userRepository.findByEmail(dto.email)
?: throw NotFoundErrorException("User with email ${dto.email} not found")
userRepository.findById(dto.uid).getOrNull()
?: throw NotFoundErrorException("User with id(${dto.uid}) not found")
}.also {
it.type = userTypeService.userType(it)
userRepository.save(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ class StatisticsService(

@Timed
fun totalStatistics(
phoneNumber: String,
uid: String,
bookedNow: Boolean
): List<StatisticsOutputDto> =
statisticsRepository
.findAll()
.filter { it.user?.phoneNumber == phoneNumber }
.filter { it.user?.id == uid }
.filter { !bookedNow || (bookedNow && it.departureDate == null) }
.map { it.toStatisticsOutputDto() }
}
23 changes: 16 additions & 7 deletions src/main/kotlin/poga/parking/parkingservice/service/UserService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,33 @@ package poga.parking.parkingservice.service

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import poga.parking.parkingservice.controller.model.input.UserAuthInputDto
import poga.parking.parkingservice.configuration.properties.PriceListProperties
import poga.parking.parkingservice.controller.model.input.UserInputDto
import poga.parking.parkingservice.controller.model.ouput.UserOutputDto
import poga.parking.parkingservice.exception.InvalidCreditsException
import poga.parking.parkingservice.enumeration.UserType
import poga.parking.parkingservice.exception.NotFoundErrorException
import poga.parking.parkingservice.repository.UserRepository
import poga.parking.parkingservice.support.toUser
import poga.parking.parkingservice.support.toUserOutputDto

@Service
class UserService(
@Autowired private val userRepository: UserRepository
@Autowired private val userRepository: UserRepository,
@Autowired private val userTypeService: UserTypeService,
@Autowired private val priceListProperties: PriceListProperties,
) {
fun registerUser(userInputDto: UserInputDto): UserOutputDto =
userRepository.save(userInputDto.toUser()).toUserOutputDto()

fun authenticateUser(userAuthInputDto: UserAuthInputDto): UserOutputDto {
return userRepository
.findByEmailAndPassword(userAuthInputDto.email, userAuthInputDto.password)?.toUserOutputDto()
?: throw InvalidCreditsException("No user with such email and password")
fun getPrice(uid: String): Double {
return userRepository.findById(uid)
.map { userTypeService.userType(it).getPrice() }
.orElseThrow { NotFoundErrorException("No user with such uid($uid)") }
}

fun UserType.getPrice(): Double =
priceListProperties.priceRates
.filter { priceRate -> priceRate.type == this }
.map { priceRate -> priceRate.price }
.first()
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ class UserTypeService {
* @return type of user in system
*/
fun userType(user: User): UserType = when {
user.email == null -> UserType.GUEST
user.email!!.endsWith("@innopolis.university") -> UserType.STUDENT
user.email!!.endsWith("@innopolis.ru") -> UserType.STAFF
user.email.endsWith("@innopolis.university") -> UserType.STUDENT
user.email.endsWith("@innopolis.ru") -> UserType.STAFF
else -> UserType.GUEST
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class MoneyService(

fun getPriceList(): PriceList = priceListProperties.toPriceList()

private fun UserType.getPrice(): Double =
fun UserType.getPrice(): Double =
priceListProperties.priceRates
.filter { priceRate -> priceRate.type == this }
.map { priceRate -> priceRate.price }
Expand Down
11 changes: 5 additions & 6 deletions src/main/kotlin/poga/parking/parkingservice/support/Mapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,19 @@ fun UserStatistics.toStatisticsOutputDto(): StatisticsOutputDto =

fun UserInputDto.toUser(): User =
User(
id = null,
id = this.uid,
email = this.email,
firstName = this.firstName,
secondName = this.secondName,
phoneNumber = this.phoneNumber,
email = this.email,
password = this.password,
type = GUEST,
)

fun User.toUserOutputDto(): UserOutputDto =
UserOutputDto(
id = this.id ?: throw InternalServerErrorException("id in user cannot be null"),
uid = this.id,
email = this.email,
firstName = this.firstName,
secondName = this.secondName,
phoneNumber = this.phoneNumber,
email = this.email ?: throw InternalServerErrorException("email cannot be null")
phoneNumber = this.phoneNumber
)
2 changes: 1 addition & 1 deletion src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ spring:
liquibase:
enabled: true
change-log: classpath:liquibase/db.changelog-master.xml
drop-first: false
drop-first: ${DB_DROP_FIRST:false}
datasource:
driver-class-name: org.postgresql.Driver
url: ${DB_URL:jdbc:postgresql://localhost:5421/parking-service}
Expand Down
1 change: 0 additions & 1 deletion src/main/resources/liquibase/db.changelog-master.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@
<include file="liquibase/parking-place-table.xml"/>
<include file="liquibase/user-transaction-statistics-table.xml"/>
<include file="liquibase/user-statistics-table.xml"/>
<include file="liquibase/user-add-password.xml"/>
</databaseChangeLog>
17 changes: 0 additions & 17 deletions src/main/resources/liquibase/user-add-password.xml

This file was deleted.

2 changes: 1 addition & 1 deletion src/main/resources/liquibase/user-statistics-table.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<column name="id" type="BIGINT" defaultValueSequenceNext="user_statistics_id_seq" >
<constraints nullable="false" primaryKey="true" primaryKeyName="user_statistics__id_idx"/>
</column>
<column name="user_id" type="BIGINT" remarks="id пользователя">
<column name="user_id" type="TEXT" remarks="id пользователя">
<constraints nullable="false" referencedTableName="user" referencedColumnNames="id"
foreignKeyName="user_statistics_id_idx"/>
</column>
Expand Down
Loading

0 comments on commit 3884ff2

Please sign in to comment.