Skip to content

Commit

Permalink
Merge branch 'main' into add-build-deploy
Browse files Browse the repository at this point in the history
  • Loading branch information
andersstandal committed Jun 26, 2024
2 parents 652cf0e + 2579210 commit c55a680
Show file tree
Hide file tree
Showing 24 changed files with 354 additions and 94 deletions.
1 change: 0 additions & 1 deletion backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ WORKDIR /app

# Copy the built jar file from the build stage
COPY --from=build /home/gradle/src/build/libs/*.jar /app/backend.jar
COPY config.properties /app/
COPY application.properties /app/

# Specify the command to run the application
Expand Down
2 changes: 2 additions & 0 deletions backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ Set up as follows:
Working directory: <root of project>/backend
Use classpath of module: spire-kk.backend.main

Set the environment variable `AIRTABLE_ACCESS_TOKEN` in `Run -> Edit Configurations...`. You can get the value from one of your teammates.

## Run the application

To set up an IntelliJ project, New Project from existing sources -> <root directory
Expand Down
4 changes: 2 additions & 2 deletions backend/src/main/kotlin/no/bekk/AirTableController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class AirTableController {
install(Auth) {
bearer {
loadTokens {
BearerTokens(accessToken, "")
BearerTokens(airtableAccessToken, "")
}
}
}
Expand Down Expand Up @@ -82,7 +82,7 @@ class AirTableController {
}
val response: HttpResponse = client.get(url) {
headers {
append("Authorization", "Bearer $accessToken")
append("Authorization", "Bearer $airtableAccessToken")
}
}
val responseBody = response.bodyAsText()
Expand Down
5 changes: 1 addition & 4 deletions backend/src/main/kotlin/no/bekk/Application.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package no.bekk

import no.bekk.plugins.*
import io.ktor.server.application.*
import org.flywaydb.core.Flyway
import java.io.FileInputStream
import java.util.*

Expand All @@ -12,9 +11,7 @@ fun loadConfig(filePath: String): Properties {
return props
}

val props = loadConfig("config.properties")
val accessToken = props.getProperty("accessToken")

val airtableAccessToken = System.getenv("AIRTABLE_ACCESS_TOKEN")
val applicationProperties = loadConfig("application.properties")
val metadataAddress = applicationProperties.getProperty("metadataAddress")
val metodeverkAddress = applicationProperties.getProperty("metodeverkAddress")
Expand Down
102 changes: 96 additions & 6 deletions backend/src/main/kotlin/no/bekk/database/DatabaseRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import no.bekk.configuration.getDatabaseConnection
import java.sql.Connection
import java.sql.SQLException
import no.bekk.plugins.Answer
import no.bekk.plugins.Comment
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.Table

Expand Down Expand Up @@ -32,7 +33,7 @@ class DatabaseRepository {
try {
connection.use { conn ->
val statement = conn.prepareStatement(
"SELECT id, actor, question, question_id, answer, updated, team FROM questions"
"SELECT id, actor, question, question_id, answer, updated, team, comment FROM questions"
)
val resultSet = statement.executeQuery()
while (resultSet.next()) {
Expand All @@ -49,7 +50,7 @@ class DatabaseRepository {
questionId = questionId,
Svar = answer,
updated = updated?.toString() ?: "",
team = team
team = team,
)
)
}
Expand Down Expand Up @@ -112,9 +113,9 @@ class DatabaseRepository {
val resultSet = result.executeQuery()

if (resultSet.next()) {
updateRow(conn, answer)
updateAnswerRow(conn, answer)
} else {
insertRow(conn, answer)
insertAnswerRow(conn, answer)
}

}
Expand All @@ -124,7 +125,7 @@ class DatabaseRepository {
}
}

private fun insertRow(conn: Connection, answer: Answer): Int {
private fun insertAnswerRow(conn: Connection, answer: Answer): Int {
val sqlStatement =
"INSERT INTO questions (actor, question, question_id, answer, team) VALUES (?, ?, ?, ?, ?)"

Expand All @@ -138,7 +139,7 @@ class DatabaseRepository {
}
}

private fun updateRow(conn: Connection, answer: Answer): Int {
private fun updateAnswerRow(conn: Connection, answer: Answer): Int {
val sqlStatement =
"UPDATE questions SET actor = ?, question = ?, question_id = ?, answer = ?, team = ?, updated = CURRENT_TIMESTAMP WHERE question_id = ? AND team = ?"

Expand All @@ -151,9 +152,98 @@ class DatabaseRepository {
statement.setString(6, answer.questionId)
statement.setString(7, answer.team)


return statement.executeUpdate()
}
}

fun getCommentsByTeamIdFromDatabase(teamId: String): MutableList<Comment> {
val connection = getDatabaseConnection()
val comments = mutableListOf<Comment>()
try {
connection.use { conn ->
val statement = conn.prepareStatement(
"SELECT id, actor, question_id, comment, updated, team FROM comments WHERE team = ?"
)
statement.setString(1, teamId)
val resultSet = statement.executeQuery()
while (resultSet.next()) {
val actor = resultSet.getString("actor")
val questionId = resultSet.getString("question_id")
val comment = resultSet.getString("comment")
val updated = resultSet.getObject("updated", java.time.LocalDateTime::class.java)
val team = resultSet.getString("team")
comments.add(
Comment(
actor = actor,
questionId = questionId,
comment = comment,
updated = updated?.toString() ?: "",
team = team,
)
)
}
}
} catch (e: SQLException) {
e.printStackTrace()
throw RuntimeException("Error fetching comments from database", e)
}
return comments
}

fun getCommentFromDatabase(comment: Comment) {
val connection = getDatabaseConnection()
try {
connection.use { conn ->

val result = conn.prepareStatement(
"SELECT question_id, team FROM comments WHERE question_id = ? AND team = ? "
)

result.setString(1, comment.questionId)
result.setString(2, comment.team)
val resultSet = result.executeQuery()

if (resultSet.next()) {
updateCommentRow(conn, comment)
} else {
insertCommentRow(conn, comment)
}

}

} catch (e: SQLException) {
e.printStackTrace()
}
}

private fun insertCommentRow(conn: Connection, comment: Comment): Int {
val sqlStatement =
"INSERT INTO comments (actor, question_id, comment, team) VALUES (?, ?, ?, ?)"

conn.prepareStatement(sqlStatement).use { statement ->
statement.setString(1, comment.actor)
statement.setString(2, comment.questionId)
statement.setString(3, comment.comment)
statement.setString(4, comment.team)
return statement.executeUpdate()
}
}

private fun updateCommentRow(conn: Connection, comment: Comment): Int {
val sqlStatement =
"UPDATE comments SET actor = ?, question_id = ?, team = ?, comment = ?, updated = CURRENT_TIMESTAMP WHERE question_id = ? AND team = ?"

conn.prepareStatement(sqlStatement).use { statement ->
statement.setString(1, comment.actor)
statement.setString(2, comment.questionId)
statement.setString(3, comment.team)
statement.setString(4, comment.comment)
statement.setString(5, comment.questionId)
statement.setString(6, comment.team)


return statement.executeUpdate()
}
}
}
47 changes: 41 additions & 6 deletions backend/src/main/kotlin/no/bekk/plugins/Routing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ fun Application.configureRouting() {
call.respondText("Velkommen til Kartverket Kontrollere!")
}
}

routing {
get("/health") {
call.respondText("Health OK", ContentType.Text.Plain)
}
}

routing {
get("/metodeverk") {
val data = airTableController.fetchDataFromMetodeverk()
Expand All @@ -47,13 +54,11 @@ fun Application.configureRouting() {
val data = airTableController.fetchDataFromAlle()
call.respondText(data.records.toString())
}

}

routing {
get("/{teamid}/kontrollere") {
val teamid = call.parameters["teamid"]

if (teamid != null) {
val data = airTableController.fetchDataFromMetodeverk()
val meta = airTableController.fetchDataFromMetadata()
Expand All @@ -68,7 +73,6 @@ fun Application.configureRouting() {
}
}


routing {
get("/answers") {
var answers = mutableListOf<Answer>()
Expand Down Expand Up @@ -97,8 +101,6 @@ fun Application.configureRouting() {
}
}



routing {
post("/answer") {
val answerRequestJson = call.receiveText()
Expand All @@ -116,8 +118,41 @@ fun Application.configureRouting() {
}
}

routing {
post("/comments") {
val commentRequestJson = call.receiveText()
val commentRequest = Json.decodeFromString<Comment>(commentRequestJson)
val comment = Comment(
questionId = commentRequest.questionId,
comment = commentRequest.comment,
team = commentRequest.team,
updated = "",
actor = commentRequest.actor,
)
databaseRepository.getCommentFromDatabase(comment)
call.respondText("Comment was successfully submitted.")
}
}

routing {
get("/comments/{teamId}") {
val teamId = call.parameters["teamId"]
var comments: MutableList<Comment>
if (teamId != null) {
comments = databaseRepository.getCommentsByTeamIdFromDatabase(teamId)
val commentsJson = Json.encodeToString(comments)
call.respondText(commentsJson, contentType = ContentType.Application.Json)
} else {
call.respond(HttpStatusCode.BadRequest, "Team id not found")
}
}
}

}

@Serializable
data class Answer(val actor: String, val questionId: String, val question: String, val Svar: String? = null,
val updated: String, val team: String?)

@Serializable
data class Answer(val actor: String, val questionId: String, val question: String, val Svar: String, val updated: String, val team: String?)
data class Comment(val actor: String, val questionId: String, val comment: String, val team: String?, val updated: String)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CREATE TABLE IF NOT EXISTS comments
(
id SERIAL PRIMARY KEY,
actor VARCHAR(255),
question_id VARCHAR(255),
comment VARCHAR(255),
team VARCHAR(255),
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE questions
ADD COLUMN comment VARCHAR(255)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE questions
DROP COLUMN comment;
4 changes: 2 additions & 2 deletions frontend/beCompliant/index.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>BeCompliant</title>
<title>Regelrett</title>
</head>
<body>
<div id="root"></div>
Expand Down
14 changes: 11 additions & 3 deletions frontend/beCompliant/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/beCompliant/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"dependencies": {
"@kvib/react": "^4.3.0",
"framer-motion": "^11.2.6",
"material-symbols": "^0.20.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.23.1"
Expand Down
2 changes: 1 addition & 1 deletion frontend/beCompliant/src/components/MobileFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const MobileFilter = ({

{tableMetadata?.fields.map((metaColumn, index) => (
<TableFilter
key={index}
key={metaColumn.name}
filterName={metaColumn.name}
filterOptions={metaColumn.options}
activeFilters={activeFilters}
Expand Down
Loading

0 comments on commit c55a680

Please sign in to comment.