diff --git a/docs/diagrams/DatabaseModels.png b/docs/diagrams/DatabaseModels.png new file mode 100644 index 0000000..c4173b4 Binary files /dev/null and b/docs/diagrams/DatabaseModels.png differ diff --git a/docs/diagrams/database_models.puml b/docs/diagrams/database_models.puml new file mode 100644 index 0000000..efcf8f9 --- /dev/null +++ b/docs/diagrams/database_models.puml @@ -0,0 +1,133 @@ +@startuml DatabaseModels + +hide circle + +skinparam linetype ortho + +entity "Event" as e { + + id: ulid + + name: string + + description: string + + location: string + + startDate: date + + endDate: date + + style_id: ulid + + day_ids: ulid[] + + sponsor_ids: ulid[] + + session_ids: ulid[] + + timeslotSize_ids: ulid[] + -- + url: string + -- + + created_at: timestamp + + updated_at: timestamp +} + +entity "style" as s { + + id: ulid + + name: string + + description: string + + color: string + + textColor: string + + image: string + + event_ids: ulid[] + -- + + created_at: timestamp + + updated_at: timestamp +} + +entity "day" as d { + + id: ulid + + date: date + + note: string + + event_id: ulid + + room_ids: ulid[] + -- + + created_at: timestamp + + updated_at: timestamp +} + +entity "room" as r { + + id: ulid + + name: string + + description: string + + day_ids: ulid[] + + timeslot_ids: ulid[] + -- + + created_at: timestamp + + updated_at: timestamp +} + +entity "timeslot" as t { + + id: ulid + + start: time + + end: time + + room_id: ulid + + session_ids: ulid[] + + isBreak: boolean + + isBlocking: boolean + + isNoBlockingBreak: boolean + + timeslotSize_id: ulid + -- + + created_at: timestamp + + updated_at: timestamp +} + +entity "timeslotSize" as ts { + + id: ulid + + name: string + + minutes: number + + timeslot_ids: ulid[] + -- + + created_at: timestamp + + updated_at: timestamp +} + +entity "sponsor" as sp { + + id: ulid + + title: string + + description: string + + url: string + + image: string + + event_id: ulid + -- + + created_at: timestamp + + updated_at: timestamp +} + +entity "session" as se { + + id: ulid + + name: string + + description: string + + timeslot_ids: ulid[] + + event_id: ulid + + speaker_ids: ulid[] + -- + + created_at: timestamp + + updated_at: timestamp +} + +entity "speaker" as spk { + + id: ulid + + name: string + + description: string + + url: string + + image: string + + session_ids: ulid[] + -- + + created_at: timestamp + + updated_at: timestamp +} + +e }o--|| s +e ||--|{ d +r }|--|{ d +r ||--|{ t +t }o--|| ts +e ||--|{ sp +e }|--|{ ts +e ||--|{ se +se ||--|{ spk +se |o--|| t + +@enduml \ No newline at end of file diff --git a/packages/backend/pom.xml b/packages/backend/pom.xml index 450be94..d313a18 100644 --- a/packages/backend/pom.xml +++ b/packages/backend/pom.xml @@ -26,6 +26,7 @@ 0.2.6 4.20.0 1.0.0 + 2.1.214 6.4.0 @@ -73,6 +74,11 @@ jackson-databind-nullable ${jackson-databind-nullable.version} + + com.h2database + h2 + ${h2.version} + @@ -116,6 +122,10 @@ org.springframework.boot spring-boot-starter-data-jpa + + com.h2database + h2 + diff --git a/packages/backend/src/main/kotlin/de/mayflower/backend/controller/RoomController.kt b/packages/backend/src/main/kotlin/de/mayflower/backend/controller/RoomController.kt new file mode 100644 index 0000000..b4c4765 --- /dev/null +++ b/packages/backend/src/main/kotlin/de/mayflower/backend/controller/RoomController.kt @@ -0,0 +1,35 @@ +package de.mayflower.backend.controller + +import de.mayflower.backend.entity.RoomEntity +import de.mayflower.backend.repository.RoomRepository +import de.mayflower.backend.stubs.api.RoomsControllerDelegate +import de.mayflower.backend.stubs.model.Room +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.stereotype.Component + +@Component("roomsControllerDelegate") +class RoomController(private val roomRepository: RoomRepository) : RoomsControllerDelegate { + + override fun getRooms(): ResponseEntity> { + val roomsEntityList = this.roomRepository.findAll() + + val rooms = roomsEntityList.map { Room(it.id, it.name) } + + return ResponseEntity(rooms, HttpStatus.OK) + } + + override fun createRoom(room: Room?): ResponseEntity { + + if(room === null) { + return ResponseEntity(HttpStatus.BAD_REQUEST) + } + + val roomEntity = RoomEntity(room.name, "description") + + this.roomRepository.save(roomEntity) + + return ResponseEntity(room, HttpStatus.CREATED) + } +} \ No newline at end of file diff --git a/packages/backend/src/main/kotlin/de/mayflower/backend/entity/DayEntity.kt b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/DayEntity.kt new file mode 100644 index 0000000..c42c1aa --- /dev/null +++ b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/DayEntity.kt @@ -0,0 +1,29 @@ +package de.mayflower.backend.entity + +import jakarta.persistence.* +import jakarta.validation.constraints.* +import org.hibernate.annotations.GenericGenerator +import java.util.Date + +@Entity +@Table(name = "day") +class DayEntity( + @NotNull + val date: Date, + + @NotNull + val note: String, + + @ManyToOne(cascade = [CascadeType.ALL]) + val event: EventEntity = EventEntity(), + + @ManyToMany(cascade = [CascadeType.ALL]) + val rooms: MutableSet = mutableSetOf() +) { + @Id + @GenericGenerator(name = "ulid_generator", strategy = "de.mayflower.backend.helper.UlidGenerator") + @GeneratedValue(generator = "ulid_generator") + val id: String = String() + + constructor() : this(Date(), String()) +} diff --git a/packages/backend/src/main/kotlin/de/mayflower/backend/entity/EventEntity.kt b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/EventEntity.kt new file mode 100644 index 0000000..cfac391 --- /dev/null +++ b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/EventEntity.kt @@ -0,0 +1,60 @@ +package de.mayflower.backend.entity + +import jakarta.persistence.* +import jakarta.validation.constraints.* +import org.hibernate.annotations.GenericGenerator +import java.util.Date + +@Entity +@Table(name = "event") +class EventEntity( + @NotNull + @NotBlank + var name: String, + + @NotNull + var description: String, + + @NotNull + var location: String, + + @NotNull + var startDate: Date, + + @NotNull + var endDate: Date, + + var url: String, + + @ManyToOne(cascade = [CascadeType.ALL]) + var style: Style = Style(), + + @OneToMany( + //mappedBy = "event", + cascade = [CascadeType.ALL]) + var days: MutableSet = mutableSetOf(), + + @OneToMany( + //mappedBy = "event", + cascade = [CascadeType.ALL]) + var sponsors: MutableSet = mutableSetOf(), + + @OneToMany( + mappedBy = "event", + cascade = [CascadeType.ALL]) + var sessions: MutableSet = mutableSetOf(), + + @OneToMany( + //mappedBy = "event", + cascade = [CascadeType.ALL]) + var timeSlotSizes: MutableSet = mutableSetOf(), + +) { + @Id + @GenericGenerator(name = "ulid_generator", strategy = "de.mayflower.backend.helper.UlidGenerator") + @GeneratedValue(generator = "ulid_generator") + val id: String = String() + + constructor() : this(String(), String(), String(), Date(), Date(), String()) + +} \ No newline at end of file diff --git a/packages/backend/src/main/kotlin/de/mayflower/backend/entity/RoomEntity.kt b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/RoomEntity.kt index 1dc60d2..b9b29aa 100644 --- a/packages/backend/src/main/kotlin/de/mayflower/backend/entity/RoomEntity.kt +++ b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/RoomEntity.kt @@ -1,22 +1,31 @@ package de.mayflower.backend.entity import jakarta.persistence.* +import jakarta.validation.constraints.NotNull import org.hibernate.annotations.GenericGenerator @Entity @Table(name = "room") class RoomEntity( - val name: String, + @NotNull + var name: String, + + var description: String, + + @ManyToMany( + //mappedBy = "room", + cascade = [CascadeType.ALL]) + val days: MutableSet = mutableSetOf(), @OneToMany( mappedBy = "room", cascade = [CascadeType.ALL]) - val sessions: MutableSet = mutableSetOf() + val timeslots: MutableSet = mutableSetOf() ) { @Id @GenericGenerator(name = "ulid_generator", strategy = "de.mayflower.backend.helper.UlidGenerator") @GeneratedValue(generator = "ulid_generator") val id: String = String() - constructor() : this(String()) + constructor() : this(String(), String()) } \ No newline at end of file diff --git a/packages/backend/src/main/kotlin/de/mayflower/backend/entity/SessionEntity.kt b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/SessionEntity.kt index 7cc5b4e..e7c90d5 100644 --- a/packages/backend/src/main/kotlin/de/mayflower/backend/entity/SessionEntity.kt +++ b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/SessionEntity.kt @@ -13,24 +13,24 @@ class SessionEntity( var name: String, @NotNull - @NotBlank - var abstract: String, - - @NotNull - var start_timestamp: Long, + var description: String, - @NotNull - var end_timestamp: Long, + @OneToMany( + mappedBy = "session", + cascade = [CascadeType.ALL]) + var timeslots: MutableSet = mutableSetOf(), @ManyToOne(cascade = [CascadeType.ALL]) - var room: RoomEntity = RoomEntity(), + var event: EventEntity = EventEntity(), - var description: String = String() + @ManyToMany( + cascade = [CascadeType.ALL]) + var speakers: MutableSet = mutableSetOf(), ) { @Id @GenericGenerator(name = "ulid_generator", strategy = "de.mayflower.backend.helper.UlidGenerator") @GeneratedValue(generator = "ulid_generator") val id: String = String() - constructor() : this(String(), String(), -1, -1) + constructor() : this(String(), String()) } \ No newline at end of file diff --git a/packages/backend/src/main/kotlin/de/mayflower/backend/entity/SpeakerEntity.kt b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/SpeakerEntity.kt new file mode 100644 index 0000000..775932c --- /dev/null +++ b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/SpeakerEntity.kt @@ -0,0 +1,31 @@ +package de.mayflower.backend.entity + +import jakarta.persistence.* +import jakarta.validation.constraints.* +import org.hibernate.annotations.GenericGenerator + +@Entity +@Table(name = "speaker") +class SpeakerEntity( + @NotNull + val name: String, + + @NotNull + val description: String, + + @NotNull + val url: String, + + @NotNull + val image: String, + + @ManyToMany(cascade = [CascadeType.ALL]) + val sessions: MutableSet = mutableSetOf() +) { + @Id + @GenericGenerator(name = "ulid_generator", strategy = "de.mayflower.backend.helper.UlidGenerator") + @GeneratedValue(generator = "ulid_generator") + val id: String = String() + + constructor() : this(String(), String(), String(), String(), mutableSetOf()) +} diff --git a/packages/backend/src/main/kotlin/de/mayflower/backend/entity/SponsorEntity.kt b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/SponsorEntity.kt new file mode 100644 index 0000000..1dc5e6b --- /dev/null +++ b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/SponsorEntity.kt @@ -0,0 +1,29 @@ +package de.mayflower.backend.entity + +import jakarta.persistence.* +import jakarta.validation.constraints.NotNull +import org.hibernate.annotations.GenericGenerator + +@Entity +@Table(name = "sponsor") +class SponsorEntity( + @NotNull + var title: String, + + var description: String, + + var url: String, + + var image: String, + + @ManyToOne(cascade = [CascadeType.ALL]) + var event: EventEntity = EventEntity(), + +) { + @Id + @GenericGenerator(name = "ulid_generator", strategy = "de.mayflower.backend.helper.UlidGenerator") + @GeneratedValue(generator = "ulid_generator") + val id: String = String() + + constructor() : this(String(), String(), String(), String()) +} diff --git a/packages/backend/src/main/kotlin/de/mayflower/backend/entity/Style.kt b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/Style.kt new file mode 100644 index 0000000..96802d9 --- /dev/null +++ b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/Style.kt @@ -0,0 +1,38 @@ +package de.mayflower.backend.entity + +import jakarta.persistence.* +import jakarta.validation.constraints.* +import org.hibernate.annotations.GenericGenerator + +@Entity +@Table(name = "style") +class Style( + @NotNull + @NotBlank + var name: String, + + @NotNull + var description: String, + + @NotNull + @NotBlank + var color: String, + + @NotNull + @NotBlank + var textColor: String, + + var image: String, + + @OneToMany( + //mappedBy = "event", + cascade = [CascadeType.ALL]) + var events: MutableSet = mutableSetOf(), +) { + @Id + @GenericGenerator(name = "ulid_generator", strategy = "de.mayflower.backend.helper.UlidGenerator") + @GeneratedValue(generator = "ulid_generator") + val id: String = String() + + constructor() : this(String(), String(), String(), String(), String()) +} \ No newline at end of file diff --git a/packages/backend/src/main/kotlin/de/mayflower/backend/entity/TimeslotEntity.kt b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/TimeslotEntity.kt new file mode 100644 index 0000000..d67ed38 --- /dev/null +++ b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/TimeslotEntity.kt @@ -0,0 +1,54 @@ +package de.mayflower.backend.entity + +import jakarta.persistence.* +import jakarta.validation.constraints.NotNull +import org.hibernate.annotations.GenericGenerator +import java.sql.Time +import java.time.LocalTime + +@Entity +@Table(name = "timeslot") +class TimeslotEntity( + @NotNull + val start: Time, + + @NotNull + val end: Time, + + @ManyToOne(cascade = [CascadeType.ALL]) + val room: RoomEntity = RoomEntity(), + + @ManyToOne( + //mappedBy = "timeslot", + cascade = [CascadeType.ALL] + ) + val session: SessionEntity = SessionEntity(), + + @NotNull + val isBreak: Boolean, + + @NotNull + val isBlocking: Boolean, + + @NotNull + val isNoBlockingBreak: Boolean, + + @ManyToOne(cascade = [CascadeType.ALL]) + val timeslotSize: TimeslotSizeEntity = TimeslotSizeEntity() +) { + @Id + @GenericGenerator(name = "ulid_generator", strategy = "de.mayflower.backend.helper.UlidGenerator") + @GeneratedValue(generator = "ulid_generator") + val id: String = String() + + constructor() : this( + Time.valueOf(LocalTime.now()), + Time.valueOf(LocalTime.now()), + RoomEntity(), + SessionEntity(), + false, + false, + false, + TimeslotSizeEntity() + ) +} diff --git a/packages/backend/src/main/kotlin/de/mayflower/backend/entity/TimeslotSizeEntity.kt b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/TimeslotSizeEntity.kt new file mode 100644 index 0000000..5bfe89b --- /dev/null +++ b/packages/backend/src/main/kotlin/de/mayflower/backend/entity/TimeslotSizeEntity.kt @@ -0,0 +1,30 @@ +package de.mayflower.backend.entity + +import jakarta.persistence.* +import jakarta.validation.constraints.* +import org.hibernate.annotations.GenericGenerator +import org.hibernate.validator.constraints.UUID +import java.util.Date + +@Entity +@Table(name = "timeslotSize") +class TimeslotSizeEntity( + @NotNull + val name: String, + + @NotNull + val minutes: Number, + + @OneToMany( + mappedBy = "timeslotSize", + cascade = [CascadeType.ALL] + ) + val timeslots: MutableSet = mutableSetOf() +) { + @Id + @GenericGenerator(name = "ulid_generator", strategy = "de.mayflower.backend.helper.UlidGenerator") + @GeneratedValue(generator = "ulid_generator") + val id: String = String() + + constructor() : this(String(), 0, mutableSetOf()) +} diff --git a/packages/backend/src/main/resources/application.yml b/packages/backend/src/main/resources/application.yml index 0f26beb..40ad067 100644 --- a/packages/backend/src/main/resources/application.yml +++ b/packages/backend/src/main/resources/application.yml @@ -3,16 +3,14 @@ spring: profiles: default: local - devtools.add-properties: false # database-connection datasource: - driver-class-name: org.postgresql.Driver + driver-class-name: org.h2.Driver # jpa jpa: hibernate: - ddl-auto: none + ddl-auto: update properties: - hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect hibernate.format_sql: true # liquibase liquibase: @@ -23,10 +21,11 @@ spring: spring.config.activate.on-profile: local spring: - devtools.add-properties: true # database-connection datasource: - url: jdbc:postgresql://localhost:5432/otto + url: jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 + username: backend + password: backend liquibase.contexts: fixtures --- spring.config.activate.on-profile: docker diff --git a/packages/backend/src/main/resources/application1.yml b/packages/backend/src/main/resources/application1.yml new file mode 100644 index 0000000..0f26beb --- /dev/null +++ b/packages/backend/src/main/resources/application1.yml @@ -0,0 +1,32 @@ +--- +# default profile +spring: + profiles: + default: local + devtools.add-properties: false + # database-connection + datasource: + driver-class-name: org.postgresql.Driver + # jpa + jpa: + hibernate: + ddl-auto: none + properties: + hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect + hibernate.format_sql: true + # liquibase + liquibase: + enabled: true + change-log: 'classpath:db-changelog.yml' + drop-first: false +--- +spring.config.activate.on-profile: local + +spring: + devtools.add-properties: true + # database-connection + datasource: + url: jdbc:postgresql://localhost:5432/otto + liquibase.contexts: fixtures +--- +spring.config.activate.on-profile: docker diff --git a/packages/backend/src/main/resources/changesets/changeset-1.yml b/packages/backend/src/main/resources/changesets/changeset-1.yml index 0be6ac1..ad12121 100644 --- a/packages/backend/src/main/resources/changesets/changeset-1.yml +++ b/packages/backend/src/main/resources/changesets/changeset-1.yml @@ -8,36 +8,36 @@ databaseChangeLog: columns: - column: name: id - type: char(128) + type: varchar(128) constraints: primaryKey: true nullable: false - column: name: name - type: char(128) + type: varchar(128) - createTable: tableName: session columns: - column: name: id - type: char(128) + type: varchar(128) constraints: primaryKey: true nullable: false - column: name: room_id - type: char(128) + type: varchar(128) - column: name: name - type: char(128) + type: varchar(128) constraints: nullable: false - column: name: description - type: char(256) + type: varchar(256) - column: name: abstract - type: char(1024) + type: varchar(1024) constraints: nullable: false - column: diff --git a/packages/backend/src/test/resources/application.yml b/packages/backend/src/test/resources/application.yml new file mode 100644 index 0000000..fd0d5e4 --- /dev/null +++ b/packages/backend/src/test/resources/application.yml @@ -0,0 +1,31 @@ +--- +# default profile +spring: + profiles: + default: local + # database-connection + datasource: + driver-class-name: org.h2.Driver + # jpa + jpa: + hibernate: + ddl-auto: none + properties: + hibernate.format_sql: true + # liquibase + liquibase: + enabled: true + change-log: 'classpath:db-changelog.yml' + drop-first: false +--- +spring.config.activate.on-profile: local + +spring: + # database-connection + datasource: + url: jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 + username: backend + password: backend + liquibase.contexts: fixtures +--- +spring.config.activate.on-profile: docker