diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f24c79d
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
deleted file mode 100644
index 3704dc6..0000000
--- a/src/main/resources/application.properties
+++ /dev/null
@@ -1 +0,0 @@
-spring.application.name=Kotlin.SpringbootV2
diff --git a/.gitattributes b/thisgottawork/.gitattributes
similarity index 100%
rename from .gitattributes
rename to thisgottawork/.gitattributes
diff --git a/.gitignore b/thisgottawork/.gitignore
similarity index 100%
rename from .gitignore
rename to thisgottawork/.gitignore
diff --git a/.mvn/wrapper/maven-wrapper.properties b/thisgottawork/.mvn/wrapper/maven-wrapper.properties
similarity index 100%
rename from .mvn/wrapper/maven-wrapper.properties
rename to thisgottawork/.mvn/wrapper/maven-wrapper.properties
diff --git a/mvnw b/thisgottawork/mvnw
old mode 100755
new mode 100644
similarity index 100%
rename from mvnw
rename to thisgottawork/mvnw
diff --git a/mvnw.cmd b/thisgottawork/mvnw.cmd
similarity index 100%
rename from mvnw.cmd
rename to thisgottawork/mvnw.cmd
diff --git a/pom.xml b/thisgottawork/pom.xml
similarity index 64%
rename from pom.xml
rename to thisgottawork/pom.xml
index 163ad53..6fc6ec7 100644
--- a/pom.xml
+++ b/thisgottawork/pom.xml
@@ -8,11 +8,11 @@
3.4.4
- com.coded.spring
- Ordering
+ com.hooba
+ thisgottawork
0.0.1-SNAPSHOT
- Kotlin.SpringbootV2
- Kotlin.SpringbootV2
+ thisgottawork
+ Demo project for Spring Boot
@@ -31,6 +31,10 @@
1.9.25
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
org.springframework.boot
spring-boot-starter-web
@@ -48,6 +52,10 @@
kotlin-stdlib
+
+ org.postgresql
+ postgresql
+
org.springframework.boot
spring-boot-starter-test
@@ -58,8 +66,33 @@
kotlin-test-junit5
test
-
-
+
+ jakarta.platform
+ jakarta.jakartaee-api
+ 10.0.0
+
+
+ jakarta.platform
+ jakarta.jakartaee-web-api
+ 10.0.0
+
+
+ org.springframework.security
+ spring-security-crypto
+ 6.4.4
+
+
+ org.testng
+ testng
+ RELEASE
+ compile
+
+
+ org.springframework.security
+ spring-security-core
+ 6.4.4
+
+
${project.basedir}/src/main/kotlin
${project.basedir}/src/test/kotlin
diff --git a/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/HelloWorldController.kt b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/HelloWorldController.kt
new file mode 100644
index 0000000..23d7553
--- /dev/null
+++ b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/HelloWorldController.kt
@@ -0,0 +1,39 @@
+package com.hooba.thisgottawork
+
+import com.hooba.thisgottawork.users.UserEntity
+import com.hooba.thisgottawork.users.UserRepository
+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.RestController
+
+@RestController
+class HelloWorldController(
+ val usersRepository: UserRepository,
+){
+
+ @GetMapping("/home")
+ fun helloWorld() = "Welcome to online ordering!"
+
+
+ @PostMapping("/add-name")
+ fun sayMyName( @RequestBody request: SayMyNameRequest)
+ = usersRepository.save(
+ UserEntity(
+ id =request.id,
+ name = request.name,
+ age = request.age,
+ username = request.username,
+ password = request.password
+ )
+ )
+
+}
+
+data class SayMyNameRequest(
+ val id: Long?,
+ val name: String,
+ val age: Int,
+ val username: String,
+ val password: String
+)
diff --git a/src/main/kotlin/com/coded/spring/ordering/Application.kt b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/ThisgottaworkApplication.kt
similarity index 60%
rename from src/main/kotlin/com/coded/spring/ordering/Application.kt
rename to thisgottawork/src/main/kotlin/com/hooba/thisgottawork/ThisgottaworkApplication.kt
index 8554e49..78055b9 100644
--- a/src/main/kotlin/com/coded/spring/ordering/Application.kt
+++ b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/ThisgottaworkApplication.kt
@@ -1,11 +1,11 @@
-package com.coded.spring.ordering
+package com.hooba.thisgottawork
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
-class Application
+class ThisgottaworkApplication
fun main(args: Array) {
- runApplication(*args)
+ runApplication(*args)
}
diff --git a/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/authentication/CustomUserDetailsService.kt b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/authentication/CustomUserDetailsService.kt
new file mode 100644
index 0000000..559630c
--- /dev/null
+++ b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/authentication/CustomUserDetailsService.kt
@@ -0,0 +1,21 @@
+package com.hooba.thisgottawork.authentication
+
+
+import com.hooba.thisgottawork.users.UserRepository
+import org.springframework.security.core.userdetails.*
+import org.springframework.stereotype.Service
+
+@Service
+class CustomUserDetailsService(
+ private val usersRepository: UserRepository
+) : UserDetailsService {
+ override fun loadUserByUsername(username: String): UserDetails {
+ val user = usersRepository.findByUsername(username)
+ ?: throw UsernameNotFoundException("User not found")
+
+ return User.builder()
+ .username(user.username)
+ .password(user.password)
+ .build()
+ }
+}
\ No newline at end of file
diff --git a/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/authentication/SecurityConfig.kt b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/authentication/SecurityConfig.kt
new file mode 100644
index 0000000..0a1329d
--- /dev/null
+++ b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/authentication/SecurityConfig.kt
@@ -0,0 +1,34 @@
+//package com.hooba.thisgottawork.authentication
+//
+//import org.springframework.context.annotation.Bean
+//import org.springframework.context.annotation.Configuration
+//import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
+//import org.springframework.security.crypto.password.PasswordEncoder
+//
+//import org.springframework.security.config.annotation.web.builders.HttpSecurity
+//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
+//import org.springframework.security.core.userdetails.UserDetailsService
+//import org.springframework.security.web.SecurityFilterChain
+//
+//@Configuration
+//@EnableWebSecurity
+//class SecurityConfig(
+// private val userDetailsService: UserDetailsService
+//) {
+//
+// @Bean
+// fun passwordEncoder(): PasswordEncoder = BCryptPasswordEncoder()
+//
+// @Bean
+// fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
+// http.csrf { it.disable() }
+// .authorizeHttpRequests {
+// it.requestMatchers("/public/**").permitAll()
+// .anyRequest().authenticated()
+// }
+// .formLogin { it.defaultSuccessUrl("/hello", true) }
+// .userDetailsService(userDetailsService)
+// return http.build();
+// }
+//}
+
diff --git a/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/items/ItemsRepository.kt b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/items/ItemsRepository.kt
new file mode 100644
index 0000000..6263c26
--- /dev/null
+++ b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/items/ItemsRepository.kt
@@ -0,0 +1,28 @@
+package com.hooba.thisgottawork.items
+
+import com.fasterxml.jackson.annotation.JsonBackReference
+import com.hooba.thisgottawork.orders.OrderEntity
+import jakarta.inject.Named
+import jakarta.persistence.*
+import org.springframework.data.jpa.repository.JpaRepository
+
+@Named
+interface ItemsRepository: JpaRepository
+
+@Entity
+@Table(name = "items")
+data class ItemsEntity(
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ var id: Long? = null,
+
+ // maps each item to its parent order using the foreign key items.order_id → orders.id
+ @ManyToOne
+ @JoinColumn(name = "order_id")
+ @JsonBackReference
+ val order: OrderEntity,
+ val name: String,
+ val price: Double
+){
+ constructor() : this(null, OrderEntity(), "", 0.0)
+}
\ No newline at end of file
diff --git a/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/orders/OrderRepository.kt b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/orders/OrderRepository.kt
new file mode 100644
index 0000000..5958041
--- /dev/null
+++ b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/orders/OrderRepository.kt
@@ -0,0 +1,31 @@
+package com.hooba.thisgottawork.orders
+
+import com.fasterxml.jackson.annotation.JsonManagedReference
+import com.hooba.thisgottawork.items.ItemsEntity
+import com.hooba.thisgottawork.users.UserEntity
+import jakarta.persistence.*
+import org.springframework.data.jpa.repository.JpaRepository
+import java.time.LocalDateTime
+
+interface OrderRepository: JpaRepository
+
+@Entity
+@Table(name = "orders")
+ data class OrderEntity(
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ var id: Long? = null,
+
+ @ManyToOne
+ @JoinColumn(name = "user_id")
+ var user: UserEntity,
+
+ var restaurant: String,
+
+ @OneToMany(mappedBy = "order", fetch = FetchType.LAZY)
+ @JsonManagedReference
+ val items: List? = null,
+ var timeOrdered: LocalDateTime? = null
+){
+ constructor() : this(null, UserEntity(), "",null,null)
+}
\ No newline at end of file
diff --git a/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/orders/OrdersController.kt b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/orders/OrdersController.kt
new file mode 100644
index 0000000..a64c322
--- /dev/null
+++ b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/orders/OrdersController.kt
@@ -0,0 +1,41 @@
+package com.hooba.thisgottawork.orders
+
+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.RestController
+
+@RestController
+class OrdersController(
+ private val ordersService: OrdersService
+) {
+
+ @GetMapping("/orders")
+ fun getOrders() = ordersService.getOrders()
+
+ @PostMapping("/orders")
+ fun addOrder(@RequestBody request: OrderRequest) =
+ ordersService.addOrder(request)
+}
+
+
+
+// the DTO (Data Transfer Object) for our orders and items list
+data class RequestItem(
+ val name: String,
+ val price: Double
+)
+
+data class OrderRequest(
+ val userId: Long,
+ val restaurant: String,
+ val items: List
+)
+
+data class OrderResponseDTO(
+ val id: Long,
+ val username: String,
+ val restaurant: String,
+ val items: List,
+ val timeOrdered: String?
+)
\ No newline at end of file
diff --git a/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/orders/OrdersService.kt b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/orders/OrdersService.kt
new file mode 100644
index 0000000..e67c818
--- /dev/null
+++ b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/orders/OrdersService.kt
@@ -0,0 +1,45 @@
+package com.hooba.thisgottawork.orders
+
+import com.hooba.thisgottawork.items.ItemsEntity
+import com.hooba.thisgottawork.users.UserRepository
+import org.springframework.stereotype.Service
+
+
+@Service
+class OrdersService(
+ private val orderRepository: OrderRepository,
+ private var userRepository: UserRepository
+) {
+ fun getOrders(): List = orderRepository.findAll().filter { it.user != null }.sortedBy { it.timeOrdered }
+
+ fun addOrder(request: OrderRequest): OrderResponseDTO {
+ val user = userRepository.findById(request.userId).orElseThrow {
+ IllegalArgumentException("User with ID ${request.userId} not found")
+ }
+
+ val order = orderRepository.save(
+ OrderEntity(
+ user = user,
+ restaurant = request.restaurant
+ )
+ )
+
+ val items = request.items.map { item ->
+ ItemsEntity(
+ order = order,
+ name = item.name,
+ price = item.price
+ )
+ }
+
+ return OrderResponseDTO(
+ id = order.id!!,
+ username = user.username,
+ restaurant = order.restaurant,
+ timeOrdered = order.timeOrdered.toString(),
+ items = items.map {
+ RequestItem(name = it.name, price = it.price)
+ }
+ )
+ }
+}
\ No newline at end of file
diff --git a/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/users/UserRepository.kt b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/users/UserRepository.kt
new file mode 100644
index 0000000..014a59a
--- /dev/null
+++ b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/users/UserRepository.kt
@@ -0,0 +1,25 @@
+package com.hooba.thisgottawork.users
+
+import jakarta.persistence.*
+import org.springframework.data.jpa.repository.JpaRepository
+import jakarta.inject.Named
+
+@Named
+interface UserRepository : JpaRepository{
+ fun findByUsername(userName: String): UserEntity?
+ fun existsByUsername(username: String): Boolean
+}
+
+@Entity
+@Table(name = "users")
+data class UserEntity(
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ val id: Long? = null,
+ val name: String,
+ val age: Int,
+ val username: String,
+ val password: String
+){
+ constructor() : this(null, "",0,"", "")
+}
\ No newline at end of file
diff --git a/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/users/UsersController.kt b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/users/UsersController.kt
new file mode 100644
index 0000000..5bc12c1
--- /dev/null
+++ b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/users/UsersController.kt
@@ -0,0 +1,33 @@
+package com.hooba.thisgottawork.users
+
+import jakarta.validation.constraints.NotBlank
+import org.springframework.http.ResponseEntity
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RestController
+
+
+@RestController
+class UsersController(
+ private val usersService: UsersService
+) {
+
+ @PostMapping("register")
+ fun registerUser(@RequestBody request: CreateUserRequest): ResponseEntity {
+ return usersService.registerUser(request)
+
+ }
+}
+
+data class CreateUserRequest(
+ @field:NotBlank(message = "Username is required")
+ val name: String,
+
+ @field:NotBlank(message = "Password is required")
+ val age: Int,
+ @field:NotBlank(message = "Username is required")
+ val username: String,
+
+ @field:NotBlank(message = "Password is required")
+ val password: String
+)
\ No newline at end of file
diff --git a/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/users/UsersService.kt b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/users/UsersService.kt
new file mode 100644
index 0000000..ffab2ce
--- /dev/null
+++ b/thisgottawork/src/main/kotlin/com/hooba/thisgottawork/users/UsersService.kt
@@ -0,0 +1,26 @@
+package com.hooba.thisgottawork.users
+
+import org.springframework.http.HttpStatus
+import org.springframework.http.ResponseEntity
+import org.springframework.security.crypto.password.PasswordEncoder
+import org.springframework.stereotype.Service
+
+@Service
+class UsersService(
+ private val userRepository: UserRepository,
+// private val passwordEncoder: PasswordEncoder
+)
+ {
+ fun registerUser(request: CreateUserRequest): ResponseEntity {
+ if (userRepository.existsByUsername(request.username)) {
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST)
+ .body(mapOf("error" to "username ${request.username} already exists"))
+ }
+
+// val hashedPassword = passwordEncoder.encode(request.password)
+// val newUser = UserEntity(name =request.name, age =request.age, username = request.username, password = hashedPassword)
+// userRepository.save(newUser)
+
+ return ResponseEntity.ok().build()
+ }
+}
\ No newline at end of file
diff --git a/thisgottawork/src/main/resources/application.properties b/thisgottawork/src/main/resources/application.properties
new file mode 100644
index 0000000..d6c2fb5
--- /dev/null
+++ b/thisgottawork/src/main/resources/application.properties
@@ -0,0 +1,6 @@
+spring.application.name=thisgottawork
+server.port=8081
+spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
+spring.datasource.username=postgres
+spring.datasource.password=password
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
\ No newline at end of file
diff --git a/src/test/kotlin/com/coded/spring/ordering/ApplicationTests.kt b/thisgottawork/src/test/kotlin/com/hooba/thisgottawork/ThisgottaworkApplicationTests.kt
similarity index 67%
rename from src/test/kotlin/com/coded/spring/ordering/ApplicationTests.kt
rename to thisgottawork/src/test/kotlin/com/hooba/thisgottawork/ThisgottaworkApplicationTests.kt
index b2e2320..274778b 100644
--- a/src/test/kotlin/com/coded/spring/ordering/ApplicationTests.kt
+++ b/thisgottawork/src/test/kotlin/com/hooba/thisgottawork/ThisgottaworkApplicationTests.kt
@@ -1,10 +1,10 @@
-package com.coded.spring.ordering
+package com.hooba.thisgottawork
import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest
@SpringBootTest
-class ApplicationTests {
+class ThisgottaworkApplicationTests {
@Test
fun contextLoads() {