athrainsky 8 månader sedan
förälder
incheckning
d61e294941

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 1099
hs_err_pid10560.log


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 538
hs_err_pid6636.log


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 493
hs_err_pid7416.log


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 0 - 1108
hs_err_pid8924.log


+ 45 - 39
pom.xml

@@ -18,10 +18,6 @@
 		<kotlin.version>1.8.22</kotlin.version>
 	</properties>
 	<dependencies>
-		<dependency>
-			<groupId>org.springframework.boot</groupId>
-			<artifactId>spring-boot-starter-data-jpa</artifactId>
-		</dependency>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-web</artifactId>
@@ -38,26 +34,17 @@
 			<groupId>org.jetbrains.kotlin</groupId>
 			<artifactId>kotlin-stdlib</artifactId>
 		</dependency>
-		<dependency>
-			<groupId>com.mysql</groupId>
-			<artifactId>mysql-connector-j</artifactId>
-			<scope>runtime</scope>
-		</dependency>
-		<dependency>
-			<groupId>org.projectlombok</groupId>
-			<artifactId>lombok</artifactId>
-			<optional>true</optional>
-		</dependency>
+
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-test</artifactId>
 			<scope>test</scope>
 		</dependency>
-        <dependency>
-            <groupId>jakarta.validation</groupId>
-            <artifactId>jakarta.validation-api</artifactId>
-            <version>3.0.2</version>
-        </dependency>
+		<dependency>
+			<groupId>org.springframework.security</groupId>
+			<artifactId>spring-security-core</artifactId>
+			<version>6.1.5</version>
+		</dependency>
 		<dependency>
 			<groupId>org.springframework.security</groupId>
 			<artifactId>spring-security-config</artifactId>
@@ -68,21 +55,54 @@
 			<artifactId>spring-security-web</artifactId>
 			<version>6.1.5</version>
 		</dependency>
+		<dependency>
+			<groupId>jakarta.persistence</groupId>
+			<artifactId>jakarta.persistence-api</artifactId>
+			<version>3.1.0</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.data</groupId>
+			<artifactId>spring-data-commons</artifactId>
+			<version>3.2.0-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.data</groupId>
+			<artifactId>spring-data-jpa</artifactId>
+			<version>3.2.0-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-data-jpa</artifactId>
+		</dependency>
 		<dependency>
 			<groupId>net.sf.supercsv</groupId>
 			<artifactId>super-csv</artifactId>
 			<version>2.4.0</version>
 		</dependency>
+		<dependency>
+			<groupId>com.mysql</groupId>
+			<artifactId>mysql-connector-j</artifactId>
+			<scope>runtime</scope>
+		</dependency>
         <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-csv</artifactId>
-            <version>1.1</version>
+            <groupId>com.jayway.jsonpath</groupId>
+            <artifactId>json-path</artifactId>
         </dependency>
 		<dependency>
-			<groupId>com.opencsv</groupId>
-			<artifactId>opencsv</artifactId>
-			<version>5.7.1</version>
+			<groupId>io.swagger.core.v3</groupId>
+			<artifactId>swagger-annotations-jakarta</artifactId>
+			<version>2.2.15</version>
 		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-csv</artifactId>
+			<version>1.8</version>
+		</dependency>
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+            <version>1.5.13</version>
+        </dependency>
     </dependencies>
 
 	<build>
@@ -92,14 +112,6 @@
 			<plugin>
 				<groupId>org.springframework.boot</groupId>
 				<artifactId>spring-boot-maven-plugin</artifactId>
-				<configuration>
-					<excludes>
-						<exclude>
-							<groupId>org.projectlombok</groupId>
-							<artifactId>lombok</artifactId>
-						</exclude>
-					</excludes>
-				</configuration>
 			</plugin>
 			<plugin>
 				<groupId>org.jetbrains.kotlin</groupId>
@@ -110,7 +122,6 @@
 					</args>
 					<compilerPlugins>
 						<plugin>spring</plugin>
-						<plugin>jpa</plugin>
 					</compilerPlugins>
 				</configuration>
 				<dependencies>
@@ -119,11 +130,6 @@
 						<artifactId>kotlin-maven-allopen</artifactId>
 						<version>${kotlin.version}</version>
 					</dependency>
-					<dependency>
-						<groupId>org.jetbrains.kotlin</groupId>
-						<artifactId>kotlin-maven-noarg</artifactId>
-						<version>${kotlin.version}</version>
-					</dependency>
 				</dependencies>
 			</plugin>
 		</plugins>

+ 2 - 0
qc.txt

@@ -15,3 +15,5 @@ noted:
 - hanya user admin yang bisa melakukan fitur maintenance
 - bikin controller baru /maintenance
 
+csv?
+warning kalo tablename salah/kosong

+ 4 - 1
src/main/kotlin/com/swagger/rest/configuration/CorsFilter.kt

@@ -18,8 +18,11 @@ class CorsFilter : Filter {
         val request = p0 as HttpServletRequest
         response.setHeader("Access-Control-Allow-Origin", "*")
         response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
+        response.setHeader("Access-Control-Request-Headers", "Content-Description,content-disposition")
+        response.setHeader("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate")
         response.setHeader("Access-Control-Max-Age", "3600")
-        response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, xsrf-token")
+        response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, api_key")
+        response.setHeader("Content-Type", "application/json")
         response.addHeader("Access-Control-Expose-Headers", "xsrf-token")
         if ("OPTIONS" == request.method) {
             response.status = HttpServletResponse.SC_OK

+ 2 - 2
src/main/kotlin/com/swagger/rest/controllers/BugController.kt

@@ -344,7 +344,7 @@ class BugController(
         if (!Objects.equals(bugInput.goodday_url.trim(), bugData.goodday_url.trim())) {//col += "goodday_url,"
             col += 5
         }
-        if (!Objects.equals(bugInput.image_url.trim(), bugData.image_url.trim())) {//col += "image_url,"
+        if (!Objects.equals(bugInput.image_url!!.trim(), bugData.image_url.trim())) {//col += "image_url,"
             col += 6
         }
         if (!Objects.equals(
@@ -410,7 +410,7 @@ class BugController(
                             saveBug.dev = dev
                             saveBug.platform = foundPlat
                             saveBug.goodday_url = bugInput.goodday_url.trim()
-                            saveBug.image_url = bugInput.image_url.trim()
+                            saveBug.image_url = bugInput.image_url!!.trim()
                             saveBug.level = Enum.Level.valueOf(bugInput.level.uppercase()).ordinal
                             saveBug.status = Enum.Status.valueOf(bugInput.status.uppercase()).ordinal
                             saveBug.dev_status = Enum.Dev_Status.valueOf(bugInput.dev_status.uppercase()).ordinal

+ 87 - 115
src/main/kotlin/com/swagger/rest/controllers/MaintenanceController.kt

@@ -6,19 +6,18 @@ import com.swagger.rest.models.Enum
 import com.swagger.rest.repositories.*
 import com.swagger.rest.services.*
 import jakarta.servlet.http.HttpServletResponse
+import org.springframework.http.HttpHeaders
 import org.springframework.http.HttpStatus
+import org.springframework.http.MediaType
 import org.springframework.http.ResponseEntity
-import org.springframework.security.core.context.SecurityContextHolder
 import org.springframework.web.bind.annotation.*
 import org.springframework.web.multipart.MultipartFile
-import org.supercsv.io.CsvBeanWriter
-import org.supercsv.io.ICsvBeanWriter
-import org.supercsv.prefs.CsvPreference
 import java.io.IOException
 import java.text.SimpleDateFormat
 import java.util.*
 import kotlin.Any
 import kotlin.Boolean
+import kotlin.ByteArray
 import kotlin.RuntimeException
 import kotlin.String
 import kotlin.Throws
@@ -44,123 +43,100 @@ class MaintenanceController(
     private val bugService: BugService
 ) {
 
-    @GetMapping("/maintenance")
+    @GetMapping("/maintenance", produces = ["text/csv;charset=utf8;"])
     @Throws(IOException::class)
-    fun exportToCSV(response: HttpServletResponse, @RequestParam tableName: String) {
-        val userId = userRepository.getUserByUsername(SecurityContextHolder.getContext().authentication.name)
-        val valid = memberRepository.validAdmin(userId.id.toString())
+    fun exportToCSV(response: HttpServletResponse, @RequestParam tableName: String): ResponseEntity<*> {
+//        val userId = userRepository.getUserByUsername(SecurityContextHolder.getContext().authentication.name)
+//        val valid = memberRepository.validAdmin(userId.id.toString())
         val tableList = listOf("project", "platform", "user", "project_member", "bug", "comment")
 //        if (valid == 0) {
 //            ResponseEntity<Any>(HttpStatus.FORBIDDEN)
 //        } else {
         if (!tableList.contains(tableName) || tableName.isEmpty()) {
-            ResponseEntity<Any>(HttpStatus.BAD_REQUEST)
+            return ResponseEntity<Any>(HttpStatus.BAD_REQUEST)
         } else {
-
             val list = when (tableName) {
-                "user" -> userRepository.findAll()
+                "user" -> userRepository.findAll().map {
+                    "${it.id},\"${it.username}\",\"${it.password}\",\"${it.name}\""
+                }
+
                 "project" -> projectRepository.findAll().map {
-                    ProjectOutput(
-                        id = it.id, name = it.name, description = it.description, owner = it.owner!!.id.toString()
-                    )
+                    "${it.id},\"${it.name}\",\"${it.description}\",${it.owner!!.id}"
                 }
 
                 "platform" -> platformRepository.findAll().map {
-                    PlatformOutput(
-                        id = it.id, name = it.name, project = it.project!!.id.toString()
-                    )
+                    "${it.id},\"${it.name}\",${it.project!!.id}"
                 }
 
                 "project_member" -> memberRepository.findAll().map {
-                    MemberOutput(
-                        id = it.id,
-                        project = it.project!!.id.toString(),
-                        user = it.user!!.id.toString(),
-                        role = Enum.Member.values()[it.role].ordinal.toString()
-                    )
+                    "${it.id},${it.role},${it.project!!.id},${it.user!!.id}"
                 }
 
                 "bug" -> bugRepository.findAll().map {
-                    BugOutput(
-                        id = it.id,
-                        created = SimpleDateFormat("dd-MMM-yy HH:mm:ss").format(it.created),
-                        description = it.description,
-                        qc = it.qc!!.id.toString(),
-                        dev = it.dev!!.id.toString(),
-                        platform = it.platform!!.id.toString(),
-                        goodday_url = it.goodday_url,
-                        image_url = it.image_url,
-                        level = Enum.Level.values()[it.level].ordinal.toString(),
-                        status = Enum.Status.values()[it.status].ordinal.toString(),
-                        dev_status = Enum.Dev_Status.values()[it.dev_status].ordinal.toString()
-                    )
+                    "${it.id},${SimpleDateFormat("dd-MMM-yy HH:mm:ss").format(it.created)},\"${it.description}\",${it.dev_status},\"${it.goodday_url}\",\"${it.image_url}\",${it.level},${it.status},${it.dev!!.id},${it.platform!!.id},${it.qc!!.id}"
                 }
 
                 "comment" -> commentRepository.findAll().map {
-                    CommentOutput(
-                        id = it.id,
-                        bug = it.bug!!.id.toString(),
-                        creator = it.creator!!.id.toString(),
-                        created = SimpleDateFormat("dd-MMM-yy HH:mm:ss").format(it.created),
-                        content = it.content
-                    )
+                    "${it.id},\"${it.content}\",${SimpleDateFormat("dd-MMM-yy HH:mm:ss").format(it.created)},${it.bug!!.id},${it.creator!!.id}"
                 }
 
                 else -> listOf()
             }
             val csvHeader = when (tableName) {
-                "user" -> arrayOf("User ID", "Username", "Password", "Name")
-                "project" -> arrayOf("Project ID", "Description", "Name", "Owner")
-                "platform" -> arrayOf("Platform ID", "Name", "Project")
-                "project_member" -> arrayOf("Member ID", "Role", "Project", "User")
-                "comment" -> arrayOf("Bug ID", "Content", "Created", "Bug", "Creator")
-                "bug" -> arrayOf(
-                    "Bug ID",
-                    "created",
-                    "Description",
-                    "Dev Status",
-                    "Goodday Url",
-                    "Image Url",
-                    "Level",
-                    "Status",
-                    "Dev",
-                    "Platform",
-                    "Qc"
+                "user" -> listOf("User ID,\"Username\",\"Password\",\"Name\"")
+                "project" -> listOf("Project ID,\"Description\",\"Name\",Owner")
+                "platform" -> listOf("Platform ID,\"Name\",Project")
+                "project_member" -> listOf("Member ID,Role,Project,User")
+                "comment" -> listOf("Bug ID,\"Content\",Created,Bug,Creator")
+                "bug" -> listOf(
+                    "Bug ID,Created,\"Description\",Dev Status,\"Goodday Url\",\"Image Url\",Level,Status,Dev,Platform,Qc"
                 )
 
-                else -> arrayOf()
+                else -> listOf()
             }
-            val nameMapping = when (tableName) {
-                "user" -> arrayOf("id", "username", "password", "name")
-                "project" -> arrayOf("id", "description", "name", "owner")
-                "platform" -> arrayOf("id", "name", "project")
-                "project_member" -> arrayOf("id", "role", "project", "user")
-                "comment" -> arrayOf("id", "content", "created", "bug", "creator")
-                "bug" -> arrayOf(
-                    "id",
-                    "created",
-                    "description",
-                    "dev_status",
-                    "goodday_url",
-                    "image_url",
-                    "level",
-                    "status",
-                    "dev",
-                    "platform",
-                    "qc"
-                )
 
-                else -> arrayOf()
-            }
-            val csvWriter: ICsvBeanWriter = CsvBeanWriter(response.writer, CsvPreference.STANDARD_PREFERENCE)
-            csvWriter.writeHeader(*csvHeader)
-            for (table in list) {
-                csvWriter.write(table, *nameMapping)
-            }
-            csvWriter.close()
+            val csvContent = StringBuilder()
+            csvContent.append("${csvHeader.joinToString("")}\n")
+            csvContent.append(list.joinToString("\n"))
+            val headers = HttpHeaders()
+//            headers.contentType = MediaType.APPLICATION_OCTET_STREAM
+//            headers.setContentDispositionFormData("attachment", "$tableName.csv")
+//            val fileName  = String(tableName.toByteArray(), charset("ISO8859-1"))
+//            headers["content-disposition"] = "attachment;filename=$fileName.csv"
+//            response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=$tableName.csv")
+            response.contentType = MediaType.APPLICATION_OCTET_STREAM.toString()
+//            response.addHeade
+            response.addHeader(
+                HttpHeaders.CONTENT_DISPOSITION,
+                "attachment; filename=$tableName.csv"
+            )
+            response.outputStream.write(String(csvContent).toByteArray())
+            response.outputStream.flush()
+            response.outputStream.close()
+
+            return ResponseEntity("ok", HttpStatus.OK)
+//            return ResponseEntity(csvContent, headers, HttpStatus.OK)
+
+//            val cacheResultHandler = CacheDataManager()
+//            val inputStream: InputStream
+//            val byteArray: ByteArray
+//            val httpHeaders = HttpHeaders()
+//            val inputStreamResource: InputStreamResource = cacheResultHandler.exportCacheResults(response)
+//            httpHeaders[HttpHeaders.CONTENT_DISPOSITION] = "attachment; filename=$tableName.csv"
+            //convert inputStream to bytes
+//            inputStream = inputStreamResource.inputStream
+//            val buffer = ByteArrayOutputStream()
+//            var nRead: Int
+//            val data = ByteArray(1024)
+//            while ((inputStream.read(data, 0, data.size).also { nRead = it }) != -1) {
+//                buffer.write(data, 0, nRead)
 //            }
+//            buffer.flush()
+//            byteArray = buffer.toByteArray()
+//            httpHeaders.contentLength = byteArray.size.toLong()
+//            return ResponseEntity(byteArray, httpHeaders, HttpStatus.OK)
         }
-        //todo multi / zip download?
+//        return ResponseEntity<Any>(HttpStatus.INTERNAL_SERVER_ERROR)
     }
 
     @ResponseStatus(HttpStatus.BAD_REQUEST)
@@ -170,8 +146,8 @@ class MaintenanceController(
     fun import(
         @RequestParam file: MultipartFile, @RequestParam tableName: String, @RequestParam overwrite: Boolean
     ): ResponseEntity<Any> {
-        val userId = userRepository.getUserByUsername(SecurityContextHolder.getContext().authentication.name)
-        val valid = memberRepository.validAdmin(userId.id.toString())
+//        val userId = userRepository.getUserByUsername(SecurityContextHolder.getContext().authentication.name)
+//        val valid = memberRepository.validAdmin(userId.id.toString())
         val tableList = listOf("project", "platform", "user", "project_member", "bug", "comment")
 //        if (valid == 0) {
 //            ResponseEntity<Any>(HttpStatus.FORBIDDEN)
@@ -227,7 +203,6 @@ class MaintenanceController(
                 else -> listOf()
             }
             mapData.removeIf { p -> existing.contains(p["id"].toString().toLong()) && !overwrite }
-
             val check = when (tableName) {
                 "project" -> mapData.forEach {
                     val projectIn = ProjectInput()
@@ -303,7 +278,7 @@ class MaintenanceController(
                             .any { it.ordinal == bugInput.statusOrdinal }
                     ) Enum.Status.values()[bugInput.statusOrdinal!!].name else throw Error()
                     bugInput.goodday_url = m["goodday_url"].toString()
-                    bugInput.image_url = m["image_url"].toString()
+                    bugInput.image_url = m["image_url"].toString().drop(1).dropLast(1)
                     bugInput.platformId = m["platform"].toString().toLong()
                     bugInput.platform = platformRepository.findById(bugInput.platformId).orElseThrow { Error() }.name
                     bugInput.dev = m["dev"].toString().toLong()
@@ -317,7 +292,7 @@ class MaintenanceController(
         }
         val project = Project()
         val platform = Platform()
-        var user = User()
+        val user = User()
         val member = ProjectMember()
         val comment = Comment()
         val bug = Bug()
@@ -325,21 +300,25 @@ class MaintenanceController(
             val unit = when (tableName) {
                 "project" -> mapData.forEach {
                     project.id = it["id"].toString().toLong()
-                    project.name = it["name"].toString()
-                    project.description = it["description"].toString()
+                    project.name = it["name"].toString().dropLast(1).drop(1)
+                    project.description = it["description"].toString().dropLast(1).drop(1)
                     project.owner = userRepository.findById(it["owner"].toString().toLong()).get()
+                    projectRepository.save(project)
                 }
 
                 "user" -> mapData.forEach {
-                    user = jacksonObjectMapper().readValue(
-                        jacksonObjectMapper().writeValueAsString(it), User::class.java
-                    )
+                    user.id = it["id"].toString().toLong()
+                    user.name = it["name"].toString().dropLast(1).drop(1)
+                    user.password = it["password"].toString().dropLast(1).drop(1)
+                    user.username = it["username"].toString().dropLast(1).drop(1)
+                    userRepository.save(user)
                 }
 
                 "platform" -> mapData.forEach {
                     platform.id = it["id"].toString().toLong()
-                    platform.name = it["name"].toString()
+                    platform.name = it["name"].toString().dropLast(1).drop(1)
                     platform.project = projectRepository.findById(it["project"].toString().toLong()).get()
+                    platformRepository.save(platform)
                 }
 
                 "project_member" -> mapData.forEach {
@@ -347,47 +326,40 @@ class MaintenanceController(
                     member.role = Enum.Member.values()[Integer.parseInt(it["role"].toString())].ordinal
                     member.project = projectRepository.findById(it["project"].toString().toLong()).get()
                     member.user = userRepository.findById(it["user"].toString().toLong()).get()
+                    memberRepository.save(member)
                 }
 
                 "comment" -> mapData.forEach {
                     comment.id = it["id"].toString().toLong()
-                    comment.content = it["content"].toString()
+                    comment.content = it["content"].toString().dropLast(1).drop(1)
                     comment.created =
                         SimpleDateFormat("dd-MMM-yy HH:mm:ss", Locale.ENGLISH).parse(it["created"].toString())
                     comment.bug = bugRepository.findById(it["bug"].toString().toLong()).get()
                     comment.creator = userRepository.findById(it["creator"].toString().toLong()).get()
+                    commentRepository.save(comment)
                 }
 
                 "bug" -> mapData.forEach {
                     bug.id = it["id"].toString().toLong()
                     bug.created = SimpleDateFormat("dd-MMM-yy HH:mm:ss", Locale.ENGLISH).parse(it["created"].toString())
-                    bug.description = it["description"].toString()
+                    bug.description = it["description"].toString().dropLast(1).drop(1)
                     bug.dev_status = Enum.Dev_Status.values()[Integer.parseInt(it["dev_status"].toString())].ordinal
-                    bug.goodday_url = it["goodday_url"].toString()
-                    bug.image_url = it["image_url"].toString()
+                    bug.goodday_url = it["goodday_url"].toString().dropLast(1).drop(1)
+                    bug.image_url = it["image_url"].toString().dropLast(1).drop(1)
                     bug.level = Enum.Level.values()[Integer.parseInt(it["level"].toString())].ordinal
                     bug.status = Enum.Status.values()[Integer.parseInt(it["status"].toString())].ordinal
                     bug.dev = userRepository.findById(it["dev"].toString().toLong()).get()
                     bug.platform = platformRepository.findById(it["platform"].toString().toLong()).get()
                     bug.qc = userRepository.findById(it["qc"].toString().toLong()).get()
+                    bugRepository.save(bug)
                 }
 
                 else -> Unit
             }
         }
-        if (found == 0) {
-            when (tableName) {
-                "project" -> projectRepository.save(project)
-                "platform" -> platformRepository.save(platform)
-                "project_member" -> memberRepository.save(member)
-                "user" -> userRepository.save(user)
-                "comment" -> commentRepository.save(comment)
-                "bug" -> bugRepository.save(bug)
-                else -> Unit
-            }
-        }
         return if (found == 0) ResponseEntity<Any>(HttpStatus.OK) else ResponseEntity<Any>(HttpStatus.BAD_REQUEST)
     }
+
 }
 
 

+ 1 - 1
src/main/kotlin/com/swagger/rest/models/BugInput.kt

@@ -14,7 +14,7 @@ class BugInput {
 
     var goodday_url: String = ""
 
-    var image_url: String = ""
+    var image_url: String? = ""
 
     var level: String = ""
 

+ 9 - 10
src/main/kotlin/com/swagger/rest/models/User.kt

@@ -7,41 +7,40 @@ import jakarta.persistence.*
 
 @Entity
 @Table(name = "user")
-class User(
+class User {
 
     @Id
     @Column(name = "user_id", updatable = false, nullable = false)
     @GeneratedValue(strategy = GenerationType.IDENTITY)
-    var id: Long = 0,
+    var id: Long = 0
 
     @Column(name = "username", length = 100)
-    var username: String = "",
+    var username: String = ""
 
     @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
     @Column(name = "password", length = 100)
-    var password: String = "",
+    var password: String = ""
 
     @Column(name = "name", length = 255)
-    var name: String = "",
+    var name: String = ""
 
     @OneToMany(mappedBy = "user", cascade = [CascadeType.ALL])
     @JsonIgnore
-    var user_id: List<ProjectMember> = mutableListOf(),
+    var user_id: List<ProjectMember> = mutableListOf()
 
     @OneToMany(mappedBy = "owner", cascade = [CascadeType.ALL])
     @JsonIgnore
-    var owner: List<Project> = mutableListOf(),
+    var owner: List<Project> = mutableListOf()
 
     @OneToMany(mappedBy = "qc", cascade = [CascadeType.ALL])
     @JsonIgnore
-    var qc: List<Bug> = mutableListOf(),
+    var qc: List<Bug> = mutableListOf()
 
     @OneToMany(mappedBy = "dev", cascade = [CascadeType.ALL])
     @JsonIgnore
-    var dev: List<Bug> = mutableListOf(),
+    var dev: List<Bug> = mutableListOf()
 
     @OneToMany(mappedBy = "creator", cascade = [CascadeType.ALL])
     @JsonIgnore
     var creator: List<Comment> = mutableListOf()
-) {
 }

+ 3 - 0
src/main/kotlin/com/swagger/rest/repositories/BugRepository.kt

@@ -18,4 +18,7 @@ interface BugRepository : JpaRepository<Bug, Long>, JpaSpecificationExecutor<Bug
     @Query("SELECT bug_id FROM bug", nativeQuery = true)
     fun getId():List<Long>
 
+    @Query("SELECT COUNT(0) FROM bug WHERE bug_id like %?1%", nativeQuery = true)
+    fun countBug(id: Long): Int
+
 }

+ 10 - 5
src/main/kotlin/com/swagger/rest/services/BugService.kt

@@ -31,7 +31,7 @@ class BugService {
     @Autowired
     private val platformRepository: PlatformRepository? = null
 
-    private fun regex(input: String): Boolean {
+    private fun regex(input: String?): Boolean {
 //      "(http:\\/\\/|https:\\/\\/)?(www.)?([a-zA-Z0-9]+).[a-zA-Z0-9]*.[a-z]{3}.?([a-z]+)?"
 //      "^(http:\\/\\/|https:\\/\\/)?(www.)?([a-zA-Z0-9]+).[a-zA-Z0-9]*.[a-z]{3}.?([a-z]+)?\$"
 //      "(https:\/\/www\.|http:\/\/www\.|https:\/\/|http:\/\/)?[a-zA-Z0-9]{2,}(\.[a-zA-Z0-9]{2,})(\.[a-zA-Z0-9]{2,})?"
@@ -41,7 +41,7 @@ class BugService {
 
         val regex = "(http://|https://)?(www.)?([a-zA-Z0-9]+).[a-zA-Z0-9]*.[a-z]{3}.?([a-z]+)?"
         val pattern = Pattern.compile(regex, Pattern.MULTILINE)
-        val matcher = pattern.matcher(input)
+        val matcher = pattern.matcher(input!!)
         var ret = false
         while (matcher.find()) {
             ret = true
@@ -59,7 +59,7 @@ class BugService {
             save.dev = userRepository.findById(bugInput.dev).get()
             save.platform = platformRepository!!.findPlatform(userId.id.toString(), bugInput.platform)
             save.goodday_url = bugInput.goodday_url.trim()
-            save.image_url = bugInput.image_url.trim()
+            save.image_url = bugInput.image_url!!.trim()
             save.level = Enum.Level.valueOf(bugInput.level.uppercase()).ordinal
             save.status = Enum.Status.valueOf(bugInput.status.uppercase()).ordinal
             save.dev_status = Enum.Dev_Status.valueOf(bugInput.dev_status.uppercase()).ordinal
@@ -84,8 +84,13 @@ class BugService {
                 memberRepository!!.validRoleByPlatform(bugInput.qc.toString(), bugInput.platform, 0.toString())
             val countDev =
                 memberRepository.validRoleByPlatform(bugInput.dev.toString(), bugInput.platform, 1.toString())
+//            if (bugInput.image_url == "") {
+//                bugInput.image_url = null.toString()
+//            }
             return if (countPlat > 0) {
-                if (!regex(bugInput.goodday_url.trim()) || (bugInput.image_url.isNotEmpty() && !regex(bugInput.image_url.trim()))) {
+                if (!regex(bugInput.goodday_url.trim())) {
+                    HttpStatus.BAD_REQUEST
+                } else if (bugInput.image_url !== "" && !regex(bugInput.image_url!!.trim())) {
                     HttpStatus.BAD_REQUEST
                 } else if (!enumValues<Enum.Level>().any {
                         it.name == bugInput.level.uppercase()
@@ -97,7 +102,7 @@ class BugService {
                     HttpStatus.BAD_REQUEST
                 } else if (bugInput.description.length > 500) {
                     HttpStatus.PAYLOAD_TOO_LARGE
-                } else if (!(countQc == 0 || countDev == 0)) {
+                } else if (countQc == 0 || countDev == 0) {
                     HttpStatus.FORBIDDEN
                 } else if (found > 0) {
                     HttpStatus.CONFLICT

+ 15 - 13
src/main/kotlin/com/swagger/rest/services/CommentService.kt

@@ -1,11 +1,15 @@
 package com.swagger.rest.services
 
+import com.swagger.rest.models.Bug
 import com.swagger.rest.models.Comment
 import com.swagger.rest.models.CommentInput
 import com.swagger.rest.repositories.BugRepository
 import com.swagger.rest.repositories.CommentRepository
 import com.swagger.rest.repositories.UserRepository
+import jakarta.persistence.criteria.Predicate
 import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.data.jpa.domain.Specification
+import org.springframework.data.repository.findByIdOrNull
 import org.springframework.http.HttpStatus
 import org.springframework.security.core.context.SecurityContextHolder
 import org.springframework.stereotype.Service
@@ -24,32 +28,30 @@ class CommentService {
     private val bugRepository: BugRepository? = null
 
     fun saveComment(id: Long? = null, commentInput: CommentInput): Comment? {
-        try {
+        return try {
             val save = Comment()
             save.bug = bugRepository!!.findById(id!!).get()
             save.creator = userRepository!!.getUserByUsername(SecurityContextHolder.getContext().authentication.name)
             save.created = Date()
             save.content = commentInput.content.trim()
-            return commentRepository!!.save(save)
+            commentRepository!!.save(save)
         } catch (e: Exception) {
             e.printStackTrace()
-            return null
+            null
         }
     }
 
     fun validate(id: Long? = null, commentInput: CommentInput): HttpStatus? {
         try {
-            val bug = bugRepository!!.findById(id!!)
-            return if (bug.isPresent) {
-                if (commentInput.content.isEmpty()) {
-                    HttpStatus.BAD_REQUEST
-                } else if (commentInput.content.length > 500) {
-                    HttpStatus.PAYLOAD_TOO_LARGE
-                } else {
-                    HttpStatus.OK
-                }
-            } else {
+            val bug = bugRepository!!.countBug(id!!)
+            return if (bug == 0) {
                 HttpStatus.NOT_FOUND
+            } else if (commentInput.content.isEmpty()) {
+                HttpStatus.BAD_REQUEST
+            } else if (commentInput.content.length > 500) {
+                HttpStatus.PAYLOAD_TOO_LARGE
+            } else {
+                HttpStatus.OK
             }
         } catch (e: Exception) {
             e.printStackTrace()

+ 3 - 3
src/main/kotlin/com/swagger/rest/services/MemberService.kt

@@ -26,15 +26,15 @@ class MemberService {
     private val memberRepository: MemberRepository? = null
 
     fun saveMember(id: Long? = null, memberInput: MemberInput): ProjectMember? {
-        try {
+        return try {
             val save = ProjectMember()
             save.project = projectRepository!!.findById(id!!).get()
             save.user = userRepository!!.findById(memberInput.user_id!!.toLong()).get()
             save.role = Enum.Member.valueOf(memberInput.role!!.uppercase()).ordinal
-            return memberRepository!!.save(save)
+            memberRepository!!.save(save)
         } catch (e: Exception) {
             e.printStackTrace()
-            return null
+            null
         }
     }
 

+ 6 - 6
src/main/kotlin/com/swagger/rest/services/PlatformService.kt

@@ -27,26 +27,26 @@ class PlatformService {
     private val memberRepository: MemberRepository? = null
 
     fun savePlatform(platformInput: PlatformInput): Platform? {
-        try {
+        return try {
             val save = Platform()
             save.name = platformInput.name!!.trim()
             save.project = projectRepository!!.findByName(platformInput.project_name)
-            return platformRepository!!.save(save)
+            platformRepository!!.save(save)
         } catch (e: Exception) {
             e.printStackTrace()
-            return null
+            null
         }
     }
 
     fun updatePlatform(id:Long, platformInput: PlatformInput): Platform? {
-        try {
+        return try {
             val save = platformRepository!!.findById(id).get()
             save.name = platformInput.name!!.trim()
             save.project = projectRepository!!.findByName(platformInput.project_name)
-            return platformRepository.save(save)
+            platformRepository.save(save)
         } catch (e: Exception) {
             e.printStackTrace()
-            return null
+            null
         }
     }
 

+ 6 - 6
src/main/kotlin/com/swagger/rest/services/ProjectService.kt

@@ -19,27 +19,27 @@ class ProjectService {
     private val userRepository: UserRepository? = null
 
     fun saveProject(projectInput: ProjectInput): Project? {
-        try {
+        return try {
             val save = Project()
             save.name = projectInput.name.trim()
             save.description = projectInput.description!!.trim()
             save.owner = userRepository!!.getUserByUsername(SecurityContextHolder.getContext().authentication.name)
-            return projectRepository!!.save(save)
+            projectRepository!!.save(save)
         } catch (e: Exception) {
             e.printStackTrace()
-            return null
+            null
         }
     }
 
     fun updateProject(id: Long, projectInput: ProjectInput): Project? {
-        try {
+        return try {
             val save = projectRepository!!.findById(id).get()
             save.name = projectInput.name.trim()
             save.description = projectInput.description!!.trim()
-            return projectRepository.save(save)
+            projectRepository.save(save)
         } catch (e: Exception) {
             e.printStackTrace()
-            return null
+            null
         }
     }
 

+ 9 - 9
src/main/kotlin/com/swagger/rest/services/UserService.kt

@@ -18,20 +18,20 @@ class UserService {
     private val userRepository: UserRepository? = null
 
     fun saveUser(userInput: UserInput): User? {
-        try {
+        return try {
             val save = User()
             save.username = userInput.username!!.trim()
             save.name = userInput.name!!
             save.password = passwordEncoder!!.encode(userInput.password)
-            return userRepository!!.save(save)
+            userRepository!!.save(save)
         } catch (e: Exception) {
             e.printStackTrace()
-            return null
+            null
         }
     }
 
     fun updateUser(id: Long, userInput: UserInput, update: Boolean, pass: Boolean): User? {
-        try {
+        return try {
             val save = userRepository!!.findById(id).get()
             if (!pass) {
                 save.username = userInput.username!!.trim()
@@ -40,17 +40,17 @@ class UserService {
             if (!update) {
                 save.password = passwordEncoder!!.encode(userInput.newPassword)
             }
-            return userRepository.save(save)
+            userRepository.save(save)
         } catch (e: Exception) {
             e.printStackTrace()
-            return null
+            null
         }
     }
 
     fun validate(userInput: UserInput): HttpStatus? {
-        try {
+        return try {
             val found = userRepository!!.findByUsername(userInput.username!!).size
-            return if (userInput.username!!.isBlank()) {
+            if (userInput.username!!.isBlank()) {
                 HttpStatus.BAD_REQUEST
             } else if (userInput.username!!.length > 100 || userInput.password!!.length > 100 || userInput.name!!.length > 255) {
                 HttpStatus.PAYLOAD_TOO_LARGE
@@ -61,7 +61,7 @@ class UserService {
             }
         } catch (e: Exception) {
             e.printStackTrace()
-            return HttpStatus.INTERNAL_SERVER_ERROR
+            HttpStatus.INTERNAL_SERVER_ERROR
         }
     }
 

+ 3 - 2
src/main/resources/application.properties

@@ -1,4 +1,5 @@
 spring.jpa.hibernate.ddl-auto=update
-spring.datasource.url=jdbc:mysql://localhost:3306/swagger
+spring.datasource.url=jdbc:mysql://localhost:3306/swagger2
 spring.datasource.username=root
-spring.datasource.password=root
+spring.datasource.password=root
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect

+ 2 - 0
src/tmp/uploads/meh.csv

@@ -0,0 +1,2 @@
+a,b,c
+1,2,3

+ 2 - 1
swagger3 project.yml

@@ -773,7 +773,8 @@ paths:
           description: export success
           content:
             text/csv:
-              example: string
+              schema:
+                type: object
         400:
           $ref: '#/components/responses/400'
         401: