Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/BusNGoBackendApplication.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/BusNGoBackendApplication.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/BusNGoBackendApplication.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,39 @@
+package mk.ukim.finki.busngobackend
+
+import org.springframework.boot.autoconfigure.SpringBootApplication
+import org.springframework.boot.runApplication
+import org.springframework.context.annotation.Bean
+import org.springframework.context.event.ApplicationEventMulticaster
+import org.springframework.context.event.SimpleApplicationEventMulticaster
+import org.springframework.core.task.SimpleAsyncTaskExecutor
+import org.springframework.scheduling.annotation.EnableAsync
+import org.springframework.scheduling.annotation.EnableScheduling
+import org.springframework.security.crypto.password.NoOpPasswordEncoder
+import org.springframework.security.crypto.password.PasswordEncoder
+
+@SpringBootApplication
+@EnableAsync
+@EnableScheduling
+class BusNGoBackendApplication
+
+fun main(args: Array<String>) {
+    runApplication<BusNGoBackendApplication>(*args)
+}
+
+@Bean
+fun encoder(): PasswordEncoder = NoOpPasswordEncoder.getInstance()
+//    object : PasswordEncoder {
+//        override fun encode(rawPassword: CharSequence?): String = rawPassword.toString()
+//
+//        override fun matches(
+//            rawPassword: CharSequence?,
+//            encodedPassword: String?,
+//        ): Boolean = rawPassword != null && rawPassword.toString() == encodedPassword
+//    }
+
+@Bean
+fun asyncEventPublisher(): ApplicationEventMulticaster {
+    val publisher = SimpleApplicationEventMulticaster()
+    publisher.setTaskExecutor(SimpleAsyncTaskExecutor())
+    return publisher
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/AdminController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/AdminController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/AdminController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,40 @@
+package mk.ukim.finki.busngobackend.api
+
+import mk.ukim.finki.busngobackend.service.AdminService
+import org.springframework.web.bind.annotation.*
+
+@RestController
+@RequestMapping("/api/admin")
+class AdminController(
+    private val adminService: AdminService,
+) {
+    @GetMapping("/average-time-between-stations")
+    fun getAvgTimeBetweenStations() = adminService.getAverageTimeBetweenStations()
+
+    @GetMapping("/fines-by-line")
+    fun getFinesByLine() = adminService.getFinesByLine()
+
+    @GetMapping("/commutes-by-hour")
+    fun getCommutesByHour() = adminService.getCommutesByHour()
+
+    @GetMapping("/commutes-by-line")
+    fun getCommutesByLine() = adminService.getCommutesByLine()
+
+    @GetMapping("/number-of-passengers-per-line-and-station")
+    fun getNumberOfPassengersPerLineAndStation() = adminService.getNumberOfPassengersByLineAndStation()
+
+    @GetMapping("/ticket-sales")
+    fun getTicketSales() = adminService.getTicketSales()
+
+    @GetMapping("/total-income")
+    fun getTotalIncome() = adminService.getTotalIncome()
+
+    @GetMapping("/all-users")
+    fun getAllUsers() = adminService.getAllUsers()
+
+    @PostMapping("/update-roles/{id}")
+    fun updateRolesForUser(
+        @PathVariable id: Long,
+        @RequestBody roles: List<String>,
+    ) = adminService.updateRolesForUser(id, roles)
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/AuthController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/AuthController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/AuthController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,29 @@
+package mk.ukim.finki.busngobackend.api
+
+import mk.ukim.finki.busngobackend.api.requests.AuthRequest
+import mk.ukim.finki.busngobackend.api.requests.RegisterRequest
+import mk.ukim.finki.busngobackend.api.responses.AuthResponse
+import mk.ukim.finki.busngobackend.service.AuthService
+import org.springframework.web.bind.annotation.*
+
+@RestController
+@RequestMapping("/api/auth")
+class AuthController(
+    private val authService: AuthService,
+) {
+    @GetMapping()
+    fun isAuthenticated() = authService.isAuthenticated()
+
+    @PostMapping("/register")
+    fun register(
+        @RequestBody registerRequest: RegisterRequest,
+    ): AuthResponse = authService.register(registerRequest)
+
+    @PostMapping()
+    fun authenticate(
+        @RequestBody authRequest: AuthRequest,
+    ): AuthResponse = authService.authenticate(authRequest)
+
+    @GetMapping("/is-driver-free")
+    fun isDriverFree() = this.authService.isDriverFree()
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/BusController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/BusController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/BusController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,18 @@
+package mk.ukim.finki.busngobackend.api
+
+import mk.ukim.finki.busngobackend.service.BusService
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/buses")
+class BusController(
+    private val busService: BusService,
+) {
+    @GetMapping("")
+    fun getAllBuses() = busService.findAll()
+
+    @GetMapping("/free")
+    fun getAllFrees() = busService.findAllFree()
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/ChatController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/ChatController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/ChatController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,26 @@
+package mk.ukim.finki.busngobackend.api
+
+import org.springframework.messaging.handler.annotation.MessageMapping
+import org.springframework.messaging.handler.annotation.Payload
+import org.springframework.messaging.handler.annotation.SendTo
+import org.springframework.messaging.simp.SimpMessageHeaderAccessor
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+class ChatController {
+    @MessageMapping("/chat.sendMessage")
+    @SendTo("/topic/public")
+    fun sendMessage(
+        @Payload message: String,
+    ): String = message
+
+    @MessageMapping("/chat.addUser")
+    @SendTo("/topic/public")
+    fun addUser(
+        @Payload message: String,
+        headerAccessor: SimpMessageHeaderAccessor,
+    ): String {
+        headerAccessor.sessionAttributes?.put("username", message)
+        return message
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/CommuteController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/CommuteController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/CommuteController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,23 @@
+package mk.ukim.finki.busngobackend.api
+
+import mk.ukim.finki.busngobackend.api.requests.StartCommuteRequest
+import mk.ukim.finki.busngobackend.service.CommuteService
+import org.springframework.web.bind.annotation.PutMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/commutes")
+class CommuteController(
+    private val commuteService: CommuteService,
+) {
+    @PutMapping("/start")
+    fun startCommute(
+        @RequestBody request: StartCommuteRequest,
+    ) = commuteService.start(request)
+
+    // subscribe to the topic for that station
+    // receive the incoming route instances
+    // choose one as target and start commute
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/ControlsController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/ControlsController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/ControlsController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,23 @@
+package mk.ukim.finki.busngobackend.api
+
+import mk.ukim.finki.busngobackend.service.ControlService
+import org.springframework.web.bind.annotation.*
+
+@RestController
+@RequestMapping("/api/controls")
+class ControlsController(
+    private val controlService: ControlService,
+) {
+    @GetMapping()
+    fun getControls() = controlService.getAllByConductor()
+
+    @PutMapping("/start")
+    fun start(
+        @RequestBody routeInstanceId: Long,
+    ) = controlService.start(routeInstanceId)
+
+    @GetMapping("/{controlId}/fines")
+    fun getFines(
+        @PathVariable controlId: Long,
+    ) = controlService.getFines(controlId)
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/DummyDataPopulatorController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/DummyDataPopulatorController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/DummyDataPopulatorController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,21 @@
+package mk.ukim.finki.busngobackend.api
+
+import mk.ukim.finki.busngobackend.simulator.DummyDataPopulator
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/dummy")
+class DummyDataPopulatorController(
+    private val dummyDataPopulator: DummyDataPopulator,
+) {
+    @GetMapping("/route-instances")
+    fun populateRouteInstances() = dummyDataPopulator.populateRouteInstances()
+
+    @GetMapping("/commutes")
+    fun populateCommutes() = dummyDataPopulator.populateCommutes()
+
+    @GetMapping("/fines")
+    fun populateFines() = dummyDataPopulator.populateFines()
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/FineController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/FineController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/FineController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,19 @@
+package mk.ukim.finki.busngobackend.api
+
+import mk.ukim.finki.busngobackend.api.requests.FineRequest
+import mk.ukim.finki.busngobackend.service.FineService
+import org.springframework.web.bind.annotation.PutMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/fines")
+class FineController(
+    private val fineService: FineService,
+) {
+    @PutMapping()
+    fun createFine(
+        @RequestBody request: FineRequest,
+    ) = fineService.createFine(request)
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/LineController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/LineController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/LineController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,28 @@
+package mk.ukim.finki.busngobackend.api
+
+import mk.ukim.finki.busngobackend.service.DirectionService
+import mk.ukim.finki.busngobackend.service.LineService
+import mk.ukim.finki.busngobackend.service.StationService
+import org.springframework.web.bind.annotation.*
+
+@RestController
+@RequestMapping("/api/lines")
+class LineController(
+    private val lineService: LineService,
+    private val directionService: DirectionService,
+    private val stationService: StationService,
+) {
+    @GetMapping("")
+    fun getLines() = lineService.findAllLines()
+
+    @GetMapping("/{id}/directions")
+    fun getLineDirections(
+        @PathVariable("id") lineId: Int,
+    ) = directionService.findDirectionsByLineId(lineId)
+
+    @GetMapping("/{lineId}/stations")
+    fun getLineStations(
+        @PathVariable("lineId") lineId: Int,
+        @RequestParam("directionId", required = false) directionId: Long,
+    ) = stationService.findStationsByLineIdAndDirectionId(lineId, directionId)
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/RouteInstanceController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/RouteInstanceController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/RouteInstanceController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,34 @@
+package mk.ukim.finki.busngobackend.api
+
+import mk.ukim.finki.busngobackend.api.requests.StartRouteInstanceRequest
+import mk.ukim.finki.busngobackend.service.RouteInstanceService
+import org.springframework.web.bind.annotation.*
+
+@RestController
+@RequestMapping("/api/route-instances")
+class RouteInstanceController(
+    private val routeInstanceService: RouteInstanceService,
+) {
+    @PostMapping("/start")
+    fun start(
+        @RequestBody request: StartRouteInstanceRequest,
+    ) = routeInstanceService.start(request)
+
+    @PatchMapping("/stop")
+    fun stop(
+        @RequestBody id: Long,
+    ) = routeInstanceService.stop(id)
+
+    @GetMapping("/{id}")
+    fun getById(
+        @PathVariable id: Long,
+    ) = this.routeInstanceService.getById(id)
+
+    @GetMapping("/station/{stationId}")
+    fun getForStation(
+        @PathVariable stationId: Long,
+    ) = routeInstanceService.getForStation(stationId)
+
+    @GetMapping()
+    fun getAll() = routeInstanceService.getAll()
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/StationController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/StationController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/StationController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,15 @@
+package mk.ukim.finki.busngobackend.api
+
+import mk.ukim.finki.busngobackend.service.StationService
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/stations")
+class StationController(
+    private val stationService: StationService,
+) {
+    @GetMapping()
+    fun getAllStations() = stationService.getAll()
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/TicketController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/TicketController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/TicketController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,25 @@
+package mk.ukim.finki.busngobackend.api
+
+import mk.ukim.finki.busngobackend.api.requests.TicketBuyRequest
+import mk.ukim.finki.busngobackend.api.responses.TicketResponse
+import mk.ukim.finki.busngobackend.service.BiletService
+import org.springframework.web.bind.annotation.*
+
+@RestController
+@RequestMapping("/api/tickets")
+class TicketController(
+    private val biletService: BiletService,
+) {
+    @GetMapping()
+    fun getTicketsByUser(): List<TicketResponse> = this.biletService.getTicketsByUser()
+
+    @PostMapping("/buy")
+    fun buyTicket(
+        @RequestBody request: TicketBuyRequest,
+    ): TicketResponse = this.biletService.buyTicket(request)
+
+    @PatchMapping("/activate/{id}")
+    fun activateTicket(
+        @PathVariable id: Long,
+    ): TicketResponse = this.biletService.activateTicket(id)
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/TicketTypeController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/TicketTypeController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/TicketTypeController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+package mk.ukim.finki.busngobackend.api
+
+import mk.ukim.finki.busngobackend.domain.entities.Tipbilet
+import mk.ukim.finki.busngobackend.repository.TipbiletRepository
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/ticket-types")
+class TicketTypeController(
+    private val tipbiletRepository: TipbiletRepository,
+) {
+    @GetMapping()
+    fun getTicketTypes(): List<Tipbilet> = tipbiletRepository.findAll()
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/UserController.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/UserController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/UserController.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,19 @@
+package mk.ukim.finki.busngobackend.api
+
+import mk.ukim.finki.busngobackend.api.responses.UserResponse
+import mk.ukim.finki.busngobackend.service.KorisnikService
+import org.springframework.web.bind.annotation.GetMapping
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/users")
+class UserController(
+    private val korisnikService: KorisnikService,
+) {
+    @GetMapping()
+    fun getAuthenticatedUser(): UserResponse = korisnikService.getAuthenticatedUser()
+
+    @GetMapping("/passengers")
+    fun getAllPassengers() = korisnikService.getAllPassengers()
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/AuthRequest.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/AuthRequest.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/AuthRequest.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.api.requests
+
+data class AuthRequest(
+    val email: String,
+    val password: String,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/FineRequest.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/FineRequest.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/FineRequest.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,12 @@
+package mk.ukim.finki.busngobackend.api.requests
+
+data class FineRequest(
+    var iznos: Double,
+    var plateno: Boolean,
+    var dokument: String,
+    val kontrolaId: Long,
+    var telefon: String?,
+    var ime: String?,
+    var adresa: String?,
+    var patnikId: Long?,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/RegisterRequest.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/RegisterRequest.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/RegisterRequest.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,10 @@
+package mk.ukim.finki.busngobackend.api.requests
+
+data class RegisterRequest(
+    val email: String,
+    val password: String,
+    val confirmPassword: String,
+    val name: String,
+    val address: String,
+    val phoneNumber: String,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/StartCommuteRequest.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/StartCommuteRequest.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/StartCommuteRequest.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,7 @@
+package mk.ukim.finki.busngobackend.api.requests
+
+data class StartCommuteRequest(
+    val ticketId: Long,
+    val routeInstanceId: Long,
+    val stationId: Long,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/StartRouteInstanceRequest.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/StartRouteInstanceRequest.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/StartRouteInstanceRequest.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,7 @@
+package mk.ukim.finki.busngobackend.api.requests
+
+data class StartRouteInstanceRequest(
+    val lineId: Int,
+    val directionId: Long,
+    val busId: Long,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/TicketBuyRequest.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/TicketBuyRequest.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/requests/TicketBuyRequest.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,5 @@
+package mk.ukim.finki.busngobackend.api.requests
+
+data class TicketBuyRequest(
+    val type: Long,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/AdminUsersResponse.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/AdminUsersResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/AdminUsersResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,10 @@
+package mk.ukim.finki.busngobackend.api.responses
+
+data class AdminUsersResponse(
+    val email: String,
+    val name: String,
+    val address: String,
+    val phoneNumber: String,
+    val id: Long,
+    val roles: List<String>,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/AuthResponse.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/AuthResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/AuthResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,5 @@
+package mk.ukim.finki.busngobackend.api.responses
+
+data class AuthResponse(
+    val token: String,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/CommuteResponse.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/CommuteResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/CommuteResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,14 @@
+package mk.ukim.finki.busngobackend.api.responses
+
+import mk.ukim.finki.busngobackend.domain.entities.PostojkaNaLinija
+import java.time.LocalDateTime
+
+data class CommuteResponse(
+    val commuter: UserResponse,
+    val ticket: TicketResponse,
+    val stationStart: PostojkaNaLinija,
+    val status: String,
+    val startDate: LocalDateTime,
+    val endDate: LocalDateTime?,
+    val id: Long,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/ControlResponse.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/ControlResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/ControlResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,10 @@
+package mk.ukim.finki.busngobackend.api.responses
+
+import java.sql.Timestamp
+
+data class ControlResponse(
+    var id: Long,
+    val dateCreated: Timestamp,
+    val kondukter: UserResponse,
+    val instancaNaLinija: RouteInstanceResponse,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/FineResponse.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/FineResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/FineResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,18 @@
+package mk.ukim.finki.busngobackend.api.responses
+
+import java.sql.Timestamp
+
+data class FineResponse(
+    var id: Long,
+    var iznos: Double,
+    var plateno: Boolean,
+    val dateCreated: Timestamp,
+    var datePayed: Timestamp?,
+    var dokument: String,
+    val kondukter: UserResponse,
+    val kontrola: ControlResponse,
+    val patnik: UserResponse?,
+    var telefon: String?,
+    var ime: String?,
+    var adresa: String?,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/RouteInstanceResponse.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/RouteInstanceResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/RouteInstanceResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+package mk.ukim.finki.busngobackend.api.responses
+
+import mk.ukim.finki.busngobackend.domain.entities.Avtobus
+import mk.ukim.finki.busngobackend.domain.entities.Linija
+import mk.ukim.finki.busngobackend.domain.entities.Pravec
+import java.time.LocalDateTime
+
+data class RouteInstanceResponse(
+    val id: Long,
+    val bus: Avtobus,
+    val direction: Pravec,
+    val line: Linija,
+    val driver: UserResponse,
+    val start: LocalDateTime,
+    val end: LocalDateTime?,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/TicketResponse.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/TicketResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/TicketResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,12 @@
+package mk.ukim.finki.busngobackend.api.responses
+
+import mk.ukim.finki.busngobackend.domain.entities.Tipbilet
+import java.time.LocalDateTime
+
+data class TicketResponse(
+    var id: Long,
+    var datumKupuvanje: LocalDateTime,
+    var datumAktivacija: LocalDateTime?,
+    var status: String,
+    var tip: Tipbilet,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/UserResponse.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/UserResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/api/responses/UserResponse.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+package mk.ukim.finki.busngobackend.api.responses
+
+data class UserResponse(
+    val email: String,
+    val name: String,
+    val address: String,
+    val phoneNumber: String,
+    val id: Long,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/ApplicationConfig.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/ApplicationConfig.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/ApplicationConfig.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,33 @@
+package mk.ukim.finki.busngobackend.config
+
+import mk.ukim.finki.busngobackend.encoder
+import mk.ukim.finki.busngobackend.repository.KorisnikRepository
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.security.authentication.AuthenticationManager
+import org.springframework.security.authentication.AuthenticationProvider
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider
+import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration
+import org.springframework.security.core.userdetails.UserDetailsService
+
+@Configuration
+class ApplicationConfig(
+    private val korisnikRepository: KorisnikRepository,
+) {
+    @Bean
+    fun userDetailsService(): UserDetailsService =
+        UserDetailsService { email ->
+            korisnikRepository.findByEmail(email)
+        }
+
+    @Bean
+    fun authenticationProvider(korisnikRepository: KorisnikRepository): AuthenticationProvider {
+        val provider = DaoAuthenticationProvider()
+        provider.setUserDetailsService(userDetailsService())
+        provider.setPasswordEncoder(encoder())
+        return provider
+    }
+
+    @Bean
+    fun authenticationManager(config: AuthenticationConfiguration): AuthenticationManager = config.authenticationManager
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/JwtAuthFilter.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/JwtAuthFilter.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/JwtAuthFilter.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,57 @@
+package mk.ukim.finki.busngobackend.config
+
+import jakarta.servlet.FilterChain
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
+import org.springframework.security.core.context.SecurityContextHolder
+import org.springframework.security.core.userdetails.UserDetails
+import org.springframework.security.core.userdetails.UserDetailsService
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource
+import org.springframework.stereotype.Component
+import org.springframework.web.filter.OncePerRequestFilter
+
+@Component
+class JwtAuthFilter(
+    private val jwtService: JwtService,
+    private val userDetailsService: UserDetailsService,
+) : OncePerRequestFilter() {
+    override fun doFilterInternal(
+        request: HttpServletRequest,
+        response: HttpServletResponse,
+        filterChain: FilterChain,
+    ) {
+        val authHeader: String? = request.getHeader("Authorization")
+
+        if (authHeader == null || authHeader.doesNotContainBearer()) {
+            filterChain.doFilter(request, response)
+            return
+        }
+
+        val jwt = authHeader.extractTokenValue()
+        val email = jwtService.extractUsername(jwt)
+
+        if (email != null && SecurityContextHolder.getContext().authentication == null) {
+            val userDetails = this.userDetailsService.loadUserByUsername(email)
+
+            if (jwtService.isTokenValid(jwt, userDetails)) {
+                updateContext(userDetails, request)
+            }
+            filterChain.doFilter(request, response)
+        }
+    }
+
+    private fun updateContext(
+        userDetails: UserDetails,
+        request: HttpServletRequest,
+    ) {
+        val authToken = UsernamePasswordAuthenticationToken(userDetails, null, userDetails.authorities)
+        authToken.details = WebAuthenticationDetailsSource().buildDetails(request)
+
+        SecurityContextHolder.getContext().authentication = authToken
+    }
+
+    private fun String?.doesNotContainBearer(): Boolean = this == null || !this.startsWith("Bearer ")
+
+    private fun String?.extractTokenValue(): String = this!!.substringAfter("Bearer ")
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/JwtService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/JwtService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/JwtService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,64 @@
+package mk.ukim.finki.busngobackend.config
+
+import io.jsonwebtoken.Claims
+import io.jsonwebtoken.Jwts
+import io.jsonwebtoken.security.Keys
+import org.springframework.security.core.userdetails.UserDetails
+import org.springframework.stereotype.Service
+import java.security.Key
+import java.util.Date
+
+@Service
+class JwtService {
+    private val secretKey =
+        Keys.hmacShaKeyFor(
+            "hu55nfa3pRrBRV4DIlvKVDMrg7jnqla9".toByteArray(),
+        )
+
+    fun extractUsername(token: String): String? = extractClaim(token, Claims::getSubject)
+
+    fun <T> extractClaim(
+        token: String,
+        claimsResolver: (Claims) -> T,
+    ): T {
+        val claims = extractAllClaims(token)
+        return claimsResolver(claims)
+    }
+
+    fun generateToken(
+        extraClaims: Map<String, Any> = emptyMap(),
+        userDetails: UserDetails,
+    ): String =
+        Jwts
+            .builder()
+            .claims()
+            .subject(userDetails.username)
+            .issuedAt(Date(System.currentTimeMillis()))
+            .expiration(Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
+            .add(extraClaims)
+            .and()
+            .signWith(getSignInKey())
+            .compact()
+
+    fun isTokenValid(
+        token: String,
+        userDetails: UserDetails,
+    ): Boolean {
+        val username = extractUsername(token)
+        return username == userDetails.username && !isTokenExpired(token)
+    }
+
+    private fun isTokenExpired(token: String): Boolean = extractExpiration(token).before(Date())
+
+    private fun extractExpiration(token: String): Date = extractClaim(token, Claims::getExpiration)
+
+    private fun extractAllClaims(token: String): Claims =
+        Jwts
+            .parser()
+            .verifyWith(secretKey)
+            .build()
+            .parseSignedClaims(token)
+            .payload
+
+    private fun getSignInKey(): Key = secretKey
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/SecurityConfig.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/SecurityConfig.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/SecurityConfig.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,54 @@
+package mk.ukim.finki.busngobackend.config
+
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+import org.springframework.http.HttpMethod
+import org.springframework.security.authentication.AuthenticationProvider
+import org.springframework.security.config.annotation.web.builders.HttpSecurity
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
+import org.springframework.security.config.http.SessionCreationPolicy
+import org.springframework.security.web.DefaultSecurityFilterChain
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
+
+@Configuration
+@EnableWebSecurity
+class SecurityConfig(
+    private val jwtAuthFilter: JwtAuthFilter,
+    private val authenticationProvider: AuthenticationProvider,
+) {
+    @Bean
+    fun securityFilterChain(
+        http: HttpSecurity,
+        jwtAuthFilter: JwtAuthFilter,
+    ): DefaultSecurityFilterChain =
+        http
+            .csrf {
+                it.disable()
+            }.authorizeHttpRequests {
+                it
+                    .requestMatchers("/api/booking/populate")
+                    .permitAll()
+                    .requestMatchers("/api/booking/**")
+                    .authenticated()
+                    .requestMatchers(HttpMethod.GET, "/api/city/**")
+                    .permitAll()
+                    .requestMatchers("/api/city/**")
+                    .authenticated()
+                    .requestMatchers(HttpMethod.POST, "/api/properties/**")
+                    .authenticated()
+                    .requestMatchers(HttpMethod.GET, "/api/properties/{id}/for-review")
+                    .authenticated()
+                    .requestMatchers(HttpMethod.POST, "/api/property-image/{id}/save-file")
+                    .permitAll()
+                    .requestMatchers(HttpMethod.POST, "/api/property-image/**")
+                    .authenticated()
+                    .requestMatchers(HttpMethod.POST, "/api/reviews/**")
+                    .authenticated()
+                    .anyRequest()
+                    .permitAll()
+            }.sessionManagement {
+                it.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+            }.authenticationProvider(authenticationProvider)
+            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter::class.java)
+            .build()
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/WebSocketConfig.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/WebSocketConfig.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/config/WebSocketConfig.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,20 @@
+package mk.ukim.finki.busngobackend.config
+
+import org.springframework.context.annotation.Configuration
+import org.springframework.messaging.simp.config.MessageBrokerRegistry
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
+
+@Configuration
+@EnableWebSocketMessageBroker
+class WebSocketConfig : WebSocketMessageBrokerConfigurer {
+    override fun registerStompEndpoints(registry: StompEndpointRegistry) {
+        registry.addEndpoint("/ws").setAllowedOrigins("http://localhost:4200", "http://localhost:4200/").withSockJS()
+    }
+
+    override fun configureMessageBroker(registry: MessageBrokerRegistry) {
+        registry.setApplicationDestinationPrefixes("/app")
+        registry.enableSimpleBroker("/topic")
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Avtobus.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Avtobus.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Avtobus.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,15 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.Entity
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+
+@Entity
+data class Avtobus(
+    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    var registracija: String,
+    var seriskiBroj: String,
+    var brojSedishta: Short?,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Bilet.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Bilet.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Bilet.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,19 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.*
+import mk.ukim.finki.busngobackend.domain.enums.BiletEnum
+import java.sql.Timestamp
+
+@Entity
+data class Bilet(
+    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    var datumKupuvanje: Timestamp,
+    var datumAktivacija: Timestamp?,
+    @Enumerated(EnumType.STRING)
+    var status: BiletEnum,
+    @ManyToOne
+    var patnik: Patnik,
+    @ManyToOne
+    var tip: Tipbilet,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/InstancaNaLinija.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/InstancaNaLinija.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/InstancaNaLinija.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,20 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.*
+import java.sql.Timestamp
+
+@Entity
+data class InstancaNaLinija(
+    @GeneratedValue(strategy = GenerationType.IDENTITY) @Id
+    var id: Long,
+    var startDate: Timestamp,
+    var endDate: Timestamp?,
+    @ManyToOne
+    var vozac: Vozac,
+    @ManyToOne
+    var avtobus: Avtobus,
+    @ManyToOne
+    var linija: Linija,
+    @ManyToOne
+    var pravec: Pravec,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/InstancaNaLinijaPostojkaNaLinija.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/InstancaNaLinijaPostojkaNaLinija.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/InstancaNaLinijaPostojkaNaLinija.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,20 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.Entity
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import jakarta.persistence.ManyToOne
+import java.sql.Timestamp
+
+@Entity
+data class InstancaNaLinijaPostojkaNaLinija(
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    @ManyToOne
+    var postojkaNaLinija: PostojkaNaLinija,
+    @ManyToOne
+    var instancaNaLinija: InstancaNaLinija,
+    var timestamp: Timestamp,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Kazna.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Kazna.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Kazna.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,19 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.*
+import java.sql.Timestamp
+
+@Entity
+data class Kazna(
+    @GeneratedValue(strategy = GenerationType.IDENTITY) @Id
+    var id: Long,
+    var iznos: Double,
+    var plateno: Boolean,
+    val dateCreated: Timestamp,
+    var datePayed: Timestamp?,
+    var dokument: String,
+    @ManyToOne
+    val kondukter: Kondukter,
+    @ManyToOne
+    val kontrola: Kontrola,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/KaznaZaNeregistriran.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/KaznaZaNeregistriran.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/KaznaZaNeregistriran.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,14 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.*
+
+@Entity
+data class KaznaZaNeregistriran(
+    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    @OneToOne
+    val kazna: Kazna,
+    var telefon: String,
+    var ime: String,
+    var adresa: String,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/KaznaZaRegistriran.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/KaznaZaRegistriran.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/KaznaZaRegistriran.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,13 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.*
+
+@Entity
+data class KaznaZaRegistriran(
+    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    @OneToOne
+    val kazna: Kazna,
+    @ManyToOne
+    val patnik: Patnik,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Kondukter.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Kondukter.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Kondukter.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,12 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.*
+
+@Entity
+data class Kondukter(
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    @OneToOne
+    var vraboten: Vraboten,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Kontrola.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Kontrola.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Kontrola.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,15 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.*
+import java.sql.Timestamp
+
+@Entity
+data class Kontrola(
+    @GeneratedValue(strategy = GenerationType.IDENTITY) @Id
+    var id: Long,
+    val dateCreated: Timestamp,
+    @ManyToOne
+    val kondukter: Kondukter,
+    @ManyToOne
+    val instancaNaLinija: InstancaNaLinija,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Korisnik.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Korisnik.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Korisnik.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,38 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.*
+import org.springframework.security.core.GrantedAuthority
+import org.springframework.security.core.userdetails.UserDetails
+
+@Entity
+class Korisnik(
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    val ime: String,
+    val adresa: String,
+    val telefon: String,
+    var email: String,
+    @Column(name = "is_admin")
+    var admin: Boolean,
+    var lozinka: String,
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "korisnik")
+    var roles: List<KorisnikRole>?,
+) : UserDetails {
+    constructor() : this(0, "", "", "", "", false, "", emptyList()) {
+    }
+
+    override fun getAuthorities(): MutableCollection<out GrantedAuthority> = roles?.map { it.role!! }?.toMutableList() ?: mutableListOf()
+
+    override fun getPassword(): String = lozinka
+
+    override fun getUsername(): String = email
+
+    override fun isAccountNonExpired(): Boolean = true
+
+    override fun isAccountNonLocked(): Boolean = true
+
+    override fun isCredentialsNonExpired(): Boolean = true
+
+    override fun isEnabled(): Boolean = true
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/KorisnikRole.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/KorisnikRole.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/KorisnikRole.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,20 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.Entity
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import jakarta.persistence.ManyToOne
+
+@Entity
+data class KorisnikRole(
+    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    @ManyToOne
+    val korisnik: Korisnik?,
+    @ManyToOne
+    val role: Role?,
+) {
+    constructor() : this(0, null, null) {
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Linija.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Linija.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Linija.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,13 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.Entity
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+
+@Entity
+data class Linija(
+    @GeneratedValue(strategy = GenerationType.IDENTITY) @Id
+    var id: Int,
+    var ime: String,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/LinijaPravec.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/LinijaPravec.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/LinijaPravec.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,17 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.Entity
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import jakarta.persistence.ManyToOne
+
+@Entity
+data class LinijaPravec(
+    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    @ManyToOne
+    val linija: Linija,
+    @ManyToOne
+    val pravec: Pravec,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Patnik.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Patnik.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Patnik.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,11 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.*
+
+@Entity
+data class Patnik(
+    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    @OneToOne(fetch = FetchType.EAGER)
+    var korisnik: Korisnik,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Postojka.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Postojka.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Postojka.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.Entity
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+
+@Entity
+data class Postojka(
+    @GeneratedValue(strategy = GenerationType.IDENTITY) @Id
+    var id: Int,
+    var ime: String,
+    var lat: Double,
+    var lon: Double,
+    var opis: String,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/PostojkaNaLinija.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/PostojkaNaLinija.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/PostojkaNaLinija.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,20 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.Entity
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import jakarta.persistence.ManyToOne
+
+@Entity
+data class PostojkaNaLinija(
+    @GeneratedValue(strategy = GenerationType.IDENTITY) @Id
+    var id: Long,
+    var redenBroj: Short,
+    @ManyToOne
+    val linija: Linija,
+    @ManyToOne
+    val postojka: Postojka,
+    @ManyToOne
+    val pravec: Pravec,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Pravec.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Pravec.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Pravec.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,14 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.Entity
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+
+@Entity
+data class Pravec(
+    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    var pravec: String,
+    var opis: String,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Role.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Role.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Role.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,18 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.Entity
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import org.springframework.security.core.GrantedAuthority
+
+@Entity
+class Role : GrantedAuthority {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long = 0
+    var name: String = ""
+    var description: String = ""
+
+    override fun getAuthority(): String = name
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/SeSimnuvaNa.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/SeSimnuvaNa.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/SeSimnuvaNa.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,18 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.Entity
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import jakarta.persistence.OneToOne
+
+@Entity
+data class SeSimnuvaNa(
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    @OneToOne
+    val vozenje: Vozenje,
+    @OneToOne
+    val postojkaNaLinija: PostojkaNaLinija,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Tipbilet.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Tipbilet.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Tipbilet.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,15 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.Entity
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+
+@Entity
+data class Tipbilet(
+    @GeneratedValue(strategy = GenerationType.IDENTITY) @Id
+    var id: Long,
+    var trajnost: Long,
+    var cena: Float,
+    var ime: String,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Vozac.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Vozac.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Vozac.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,15 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.Entity
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import jakarta.persistence.OneToOne
+
+@Entity
+data class Vozac(
+    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    @OneToOne
+    var vraboten: Vraboten,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Vozenje.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Vozenje.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Vozenje.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,23 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.*
+import mk.ukim.finki.busngobackend.domain.enums.VozenjeStatus
+import java.sql.Timestamp
+
+@Entity
+data class Vozenje(
+    @GeneratedValue(strategy = GenerationType.IDENTITY) @Id
+    var id: Long,
+    var startDate: Timestamp,
+    var endDate: Timestamp?,
+    @Enumerated(EnumType.STRING)
+    var status: VozenjeStatus,
+    @ManyToOne
+    var patnik: Patnik,
+    @ManyToOne
+    var postojkaNaLinijaStart: PostojkaNaLinija,
+    @ManyToOne
+    var instancaNaLinija: InstancaNaLinija,
+    @ManyToOne
+    var bilet: Bilet,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Vraboten.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Vraboten.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/entities/Vraboten.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,19 @@
+package mk.ukim.finki.busngobackend.domain.entities
+
+import jakarta.persistence.Entity
+import jakarta.persistence.FetchType
+import jakarta.persistence.GeneratedValue
+import jakarta.persistence.GenerationType
+import jakarta.persistence.Id
+import java.sql.Date
+
+@Entity
+data class Vraboten(
+    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+    var id: Long,
+    @jakarta.persistence.OneToOne(fetch = FetchType.EAGER)
+    var korisnik: Korisnik,
+    var plata: Double,
+    val datumNaVrabotuvanje: Date,
+    var datumPrekinVrabotuvanje: Date?,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/enums/BiletEnum.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/enums/BiletEnum.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/enums/BiletEnum.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,7 @@
+package mk.ukim.finki.busngobackend.domain.enums
+
+enum class BiletEnum {
+    INACTIVE,
+    ACTIVE,
+    EXPIRED,
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/enums/RoleEnum.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/enums/RoleEnum.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/enums/RoleEnum.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,10 @@
+package mk.ukim.finki.busngobackend.domain.enums
+
+enum class RoleEnum {
+    ROLE_ADMIN,
+    ROLE_DRIVER,
+    ROLE_CONDUCTOR,
+    ROLE_PASSENGER,
+}
+
+fun RoleEnum.toId(): Long = this.ordinal + 1L
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/enums/VozenjeStatus.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/enums/VozenjeStatus.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/enums/VozenjeStatus.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.domain.enums
+
+enum class VozenjeStatus {
+    ACTIVE,
+    FINISHED,
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/helpers/RouteInstanceOnStation.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/helpers/RouteInstanceOnStation.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/helpers/RouteInstanceOnStation.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,11 @@
+package mk.ukim.finki.busngobackend.domain.helpers
+
+import mk.ukim.finki.busngobackend.domain.entities.InstancaNaLinija
+import mk.ukim.finki.busngobackend.domain.entities.PostojkaNaLinija
+import java.sql.Timestamp
+
+data class RouteInstanceOnStation(
+    val instance: InstancaNaLinija,
+    val station: PostojkaNaLinija,
+    val timestamp: Timestamp,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/AverageTimeBetweenStations.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/AverageTimeBetweenStations.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/AverageTimeBetweenStations.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,20 @@
+package mk.ukim.finki.busngobackend.domain.views
+
+import jakarta.persistence.*
+import mk.ukim.finki.busngobackend.domain.entities.PostojkaNaLinija
+
+@Entity
+@Table(name = "avg_time_diffs")
+data class AverageTimeBetweenStations(
+    @Column(name = "id")
+    @Id
+    val id: Long,
+    @ManyToOne
+    @JoinColumn(name = "start_station_id")
+    val startStation: PostojkaNaLinija,
+    @ManyToOne
+    @JoinColumn(name = "end_station_id")
+    val endStation: PostojkaNaLinija,
+    @Column(name = "avg_time_diff_seconds")
+    val timeInSeconds: Double,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/CommutesByHour.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/CommutesByHour.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/CommutesByHour.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,18 @@
+package mk.ukim.finki.busngobackend.domain.views
+
+import jakarta.persistence.*
+import mk.ukim.finki.busngobackend.domain.entities.Linija
+
+@Entity
+@Table(name = "most_busy_part_of_the_day")
+data class CommutesByHour(
+    @Id
+    val id: Long,
+    @ManyToOne
+    @JoinColumn(name = "linija_id")
+    val line: Linija,
+    @Column(name = "interval_1h")
+    val interval: String,
+    @Column(name = "broj_pati")
+    val numberOfCommutes: Long,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/CommutesByLine.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/CommutesByLine.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/CommutesByLine.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+package mk.ukim.finki.busngobackend.domain.views
+
+import jakarta.persistence.*
+import mk.ukim.finki.busngobackend.domain.entities.Linija
+
+@Entity
+@Table(name = "commutes_by_line")
+data class CommutesByLine(
+    @Id
+    val id: Long,
+    @ManyToOne
+    @JoinColumn(name = "linija_id")
+    val line: Linija,
+    @Column(name = "count")
+    val commutesPerLine: Long,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/FinesByLine.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/FinesByLine.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/FinesByLine.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+package mk.ukim.finki.busngobackend.domain.views
+
+import jakarta.persistence.*
+import mk.ukim.finki.busngobackend.domain.entities.Linija
+
+@Entity
+@Table(name = "kazna_po_linija")
+data class FinesByLine(
+    @Id
+    val id: Long,
+    @JoinColumn(name = "line_id")
+    @ManyToOne
+    val line: Linija,
+    @Column(name = "count")
+    val count: Long,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/NumberOfPassengersByLineAndStation.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/NumberOfPassengersByLineAndStation.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/NumberOfPassengersByLineAndStation.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,20 @@
+package mk.ukim.finki.busngobackend.domain.views
+
+import jakarta.persistence.*
+import mk.ukim.finki.busngobackend.domain.entities.Linija
+import mk.ukim.finki.busngobackend.domain.entities.Postojka
+
+@Entity
+@Table(name = "number_passengers_per_line_and_station")
+data class NumberOfPassengersByLineAndStation(
+    @Id
+    val id: Long,
+    @ManyToOne
+    @JoinColumn(name = "line_id")
+    val line: Linija,
+    @ManyToOne
+    @JoinColumn(name = "station_id")
+    val station: Postojka,
+    @Column(name = "count")
+    val passengersByLineAndStation: Long,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/TicketSales.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/TicketSales.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/TicketSales.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,18 @@
+package mk.ukim.finki.busngobackend.domain.views
+
+import jakarta.persistence.*
+import mk.ukim.finki.busngobackend.domain.entities.Tipbilet
+
+@Entity
+@Table(name = "ticket_sales")
+data class TicketSales(
+    @Id
+    val id: Long,
+    @ManyToOne
+    @JoinColumn(name = "tip_id")
+    val type: Tipbilet,
+    @Column(name = "interval_1h")
+    val interval: String,
+    @Column(name = "broj_pati")
+    val numberOfSales: Long,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/TotalIncome.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/TotalIncome.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/domain/views/TotalIncome.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,21 @@
+package mk.ukim.finki.busngobackend.domain.views
+
+import jakarta.persistence.Column
+import jakarta.persistence.Entity
+import jakarta.persistence.Id
+import jakarta.persistence.Table
+
+@Entity
+@Table(name = "total_income")
+class TotalIncome(
+    @Id
+    val id: Long,
+    @Column(name = "year")
+    val year: String,
+    @Column(name = "fines_income")
+    val finesIncome: Double,
+    @Column(name = "ticket_income")
+    val ticketIncome: Double,
+    @Column(name = "total_income")
+    val totalIncome: Double,
+)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/events/RouteInstanceOnStationEvent.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/events/RouteInstanceOnStationEvent.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/events/RouteInstanceOnStationEvent.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,8 @@
+package mk.ukim.finki.busngobackend.events
+
+import mk.ukim.finki.busngobackend.domain.helpers.RouteInstanceOnStation
+import org.springframework.context.ApplicationEvent
+
+class RouteInstanceOnStationEvent(
+    source: RouteInstanceOnStation,
+) : ApplicationEvent(source)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/events/StartRouteEvent.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/events/StartRouteEvent.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/events/StartRouteEvent.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,8 @@
+package mk.ukim.finki.busngobackend.events
+
+import mk.ukim.finki.busngobackend.domain.entities.InstancaNaLinija
+import org.springframework.context.ApplicationEvent
+
+class StartRouteEvent(
+    source: InstancaNaLinija,
+) : ApplicationEvent(source)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/events/StopRouteInstanceEvent.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/events/StopRouteInstanceEvent.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/events/StopRouteInstanceEvent.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,8 @@
+package mk.ukim.finki.busngobackend.events
+
+import mk.ukim.finki.busngobackend.domain.entities.InstancaNaLinija
+import org.springframework.context.ApplicationEvent
+
+class StopRouteInstanceEvent(
+    source: InstancaNaLinija,
+) : ApplicationEvent(source)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/listener/RouteEventListener.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/listener/RouteEventListener.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/listener/RouteEventListener.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,56 @@
+package mk.ukim.finki.busngobackend.listener
+
+import mk.ukim.finki.busngobackend.domain.entities.InstancaNaLinija
+import mk.ukim.finki.busngobackend.domain.helpers.RouteInstanceOnStation
+import mk.ukim.finki.busngobackend.events.RouteInstanceOnStationEvent
+import mk.ukim.finki.busngobackend.events.StartRouteEvent
+import mk.ukim.finki.busngobackend.events.StopRouteInstanceEvent
+import mk.ukim.finki.busngobackend.service.RouteInstanceOnStationService
+import mk.ukim.finki.busngobackend.service.RouteInstanceService
+import mk.ukim.finki.busngobackend.service.StationService
+import mk.ukim.finki.busngobackend.service.WebSocketService
+import mk.ukim.finki.busngobackend.simulator.RouteInstanceSimulator
+import org.springframework.context.ApplicationEventPublisher
+import org.springframework.context.event.EventListener
+import org.springframework.scheduling.annotation.Async
+import org.springframework.stereotype.Component
+
+@Component
+class RouteEventListener(
+    private val stationService: StationService,
+    private val simulator: RouteInstanceSimulator,
+    private val eventPublisher: ApplicationEventPublisher,
+    private val routeInstanceService: RouteInstanceService,
+    private val routeInstanceOnStationService: RouteInstanceOnStationService,
+    private val webSocketService: WebSocketService,
+) {
+    @Async
+    @EventListener
+    fun startRouteEvent(event: StartRouteEvent) {
+        println(event)
+        println(event)
+        val instance = event.source as InstancaNaLinija
+        val line = instance.linija
+        val direction = instance.pravec
+        val stations = stationService.findStationsByLineIdAndDirectionId(line.id, direction.id)
+
+        simulator.simulate(instance, stations)
+    }
+
+    @Async
+    @EventListener
+    fun routeInstanceOnStation(event: RouteInstanceOnStationEvent) {
+        println("------------------------------------------------")
+        println(event)
+        val source = event.source as RouteInstanceOnStation
+        routeInstanceOnStationService.create(source.instance.id, source.station.id, source.timestamp)
+        // todo: publish event to the websocket so that the user gets notified
+        webSocketService.sendMessage("routes", "Updated routes")
+    }
+
+    @EventListener
+    fun stopRouteEvent(event: StopRouteInstanceEvent) {
+        val instance = event.source as InstancaNaLinija
+        routeInstanceService.stop(instance.id)
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/listener/WebSocketEventListener.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/listener/WebSocketEventListener.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/listener/WebSocketEventListener.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,15 @@
+package mk.ukim.finki.busngobackend.listener
+
+import org.springframework.context.event.EventListener
+import org.springframework.messaging.simp.stomp.StompHeaderAccessor
+import org.springframework.stereotype.Component
+import org.springframework.web.socket.messaging.SessionDisconnectEvent
+
+@Component
+class WebSocketEventListener {
+    @EventListener
+    fun handleWebSocketDisconnectListener(event: SessionDisconnectEvent) {
+        val headerAccessor = StompHeaderAccessor.wrap(event.message)
+        val username = headerAccessor.sessionAttributes?.get("username")
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/mapper/ClassToDtoMapper.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/mapper/ClassToDtoMapper.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/mapper/ClassToDtoMapper.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,85 @@
+package mk.ukim.finki.busngobackend.mapper
+
+import mk.ukim.finki.busngobackend.api.responses.*
+import mk.ukim.finki.busngobackend.domain.entities.*
+import org.springframework.stereotype.Service
+
+@Service
+class ClassToDtoMapper {
+    fun toUserResponse(user: Korisnik): UserResponse =
+        UserResponse(
+            id = user.id,
+            email = user.email,
+            phoneNumber = user.telefon,
+            address = user.adresa,
+            name = user.ime,
+        )
+
+    fun toTicketResponse(it: Bilet) =
+        TicketResponse(
+            id = it.id,
+            tip = it.tip,
+            datumKupuvanje = it.datumKupuvanje.toLocalDateTime(),
+            status = it.status.name,
+            datumAktivacija = it.datumAktivacija?.toLocalDateTime(),
+        )
+
+    fun toRouteInstanceResponse(it: InstancaNaLinija) =
+        RouteInstanceResponse(
+            line = it.linija,
+            bus = it.avtobus,
+            start = it.startDate.toLocalDateTime(),
+            driver = toUserResponse(it.vozac.vraboten.korisnik),
+            direction = it.pravec,
+            end = it.endDate?.toLocalDateTime(),
+            id = it.id,
+        )
+
+    fun toCommuteResponse(it: Vozenje) =
+        CommuteResponse(
+            status = it.status.name,
+            endDate = it.endDate?.toLocalDateTime(),
+            startDate = it.startDate.toLocalDateTime(),
+            commuter = this.toUserResponse(it.patnik.korisnik),
+            stationStart = it.postojkaNaLinijaStart,
+            ticket = this.toTicketResponse(it.bilet),
+            id = it.id,
+        )
+
+    fun toControlResponse(kontrola: Kontrola) =
+        ControlResponse(
+            id = kontrola.id,
+            instancaNaLinija = this.toRouteInstanceResponse(kontrola.instancaNaLinija),
+            kondukter = this.toUserResponse(kontrola.kondukter.vraboten.korisnik),
+            dateCreated = kontrola.dateCreated,
+        )
+
+    fun toFineResponse(
+        kazna: Kazna,
+        kzr: KaznaZaRegistriran?,
+        kzn: KaznaZaNeregistriran?,
+    ) = FineResponse(
+        dokument = kazna.dokument,
+        kontrola = this.toControlResponse(kazna.kontrola),
+        plateno = kazna.plateno,
+        iznos = kazna.iznos,
+        id = kazna.id,
+        kondukter = this.toUserResponse(kazna.kondukter.vraboten.korisnik),
+        datePayed = kazna.datePayed,
+        dateCreated = kazna.dateCreated,
+        adresa = kzn?.adresa,
+        patnik = kzr?.patnik?.let { this.toUserResponse(it.korisnik) },
+        ime = kzn?.ime,
+        telefon = kzn?.telefon,
+    )
+
+    fun toAdminUsersResponse(user: Korisnik): AdminUsersResponse =
+        AdminUsersResponse(
+            id = user.id,
+            email = user.email,
+            phoneNumber = user.telefon,
+            address = user.adresa,
+            name = user.ime,
+            roles = user.roles!!.map { it.role!!.name },
+        )
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/AvgTimeDIffsRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/AvgTimeDIffsRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/AvgTimeDIffsRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.views.AverageTimeBetweenStations
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface AvgTimeDIffsRepository : JpaRepository<AverageTimeBetweenStations, Long>
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/AvtobusRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/AvtobusRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/AvtobusRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,21 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Avtobus
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.data.jpa.repository.Query
+
+interface AvtobusRepository : JpaRepository<Avtobus, Long> {
+    @Query(
+        nativeQuery = true,
+        value =
+            "select a.id, a.registracija, a.seriski_broj, a.broj_sedishta " +
+                "from project.avtobus a " +
+                "where not exists( " +
+                "select 1 " +
+                "from project.avtobus a1 " +
+                "join project.instanca_na_linija inl on inl.avtobus_id = a1.id " +
+                "where a1.id = a.id and " +
+                "inl.end_date is null)",
+    )
+    fun findAllFreeBuses(): List<Avtobus>
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/BiletRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/BiletRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/BiletRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,14 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Bilet
+import mk.ukim.finki.busngobackend.domain.entities.Patnik
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface BiletRepository : JpaRepository<Bilet, Long> {
+    fun findAllByPatnik(patnik: Patnik): List<Bilet>
+
+    fun findByIdAndPatnik(
+        id: Long,
+        patnik: Patnik,
+    ): Bilet?
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/CommutesByHourRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/CommutesByHourRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/CommutesByHourRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.views.CommutesByHour
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface CommutesByHourRepository : JpaRepository<CommutesByHour, Long>
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/CommutesByLineRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/CommutesByLineRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/CommutesByLineRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.views.CommutesByLine
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface CommutesByLineRepository : JpaRepository<CommutesByLine, Long>
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/FinesByLineRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/FinesByLineRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/FinesByLineRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.views.FinesByLine
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface FinesByLineRepository : JpaRepository<FinesByLine, Long>
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/InstancaNaLinijaPostojkaNaLinijaRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/InstancaNaLinijaPostojkaNaLinijaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/InstancaNaLinijaPostojkaNaLinijaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,21 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.InstancaNaLinijaPostojkaNaLinija
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.data.jpa.repository.Query
+import java.sql.Timestamp
+
+interface InstancaNaLinijaPostojkaNaLinijaRepository : JpaRepository<InstancaNaLinijaPostojkaNaLinija, Long> {
+    @Query(
+        nativeQuery = true,
+        value = """
+            select id, instanca_na_linija_id, postojka_na_linija_id, timestamp from project.instanca_na_linija_postojka_na_linija where id = (
+            select id from project.instanca_na_linija_postojka_na_linija where instanca_na_linija_id = ?1 order by EXTRACT(epoch FROM (timestamp - ?2)) limit 1
+            )
+        """,
+    )
+    fun findByInstancaNaLinijaAndTimestampNearestTo(
+        instancaNaLinija: Long,
+        startDate: Timestamp,
+    ): InstancaNaLinijaPostojkaNaLinija?
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/InstancaNaLinijaRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/InstancaNaLinijaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/InstancaNaLinijaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,38 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.InstancaNaLinija
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.data.jpa.repository.Query
+
+interface InstancaNaLinijaRepository : JpaRepository<InstancaNaLinija, Long> {
+    @Query(
+        value = "select count(id) > 0 from project.instanca_na_linija inl where inl.vozac_id=:vozac and inl.end_date is null",
+        nativeQuery = true,
+    )
+    fun existsByVozacAndEndDateIsNull(vozac: Long): Boolean
+
+    @Query(
+        value =
+            """
+            select distinct inl.id
+from project.instanca_na_linija inl
+         join project.instanca_na_linija_postojka_na_linija inlpnl on inl.id = inlpnl.instanca_na_linija_id
+where end_date is null
+  and linija_id in (
+    select distinct(pnl.linija_id)
+    from project.postojka_na_linija pnl
+    where postojka_id = ?1
+)
+except
+select inl.id
+from project.postojka_na_linija pnl
+         join project.instanca_na_linija inl on inl.linija_id = pnl.linija_id and inl.pravec_id = pnl.pravec_id
+join project.instanca_na_linija_postojka_na_linija inlpnl on inl.id = inlpnl.instanca_na_linija_id and pnl.id = inlpnl.postojka_na_linija_id
+where inl.end_date is null and postojka_id = ?1;
+        """,
+        nativeQuery = true,
+    )
+    fun findIncomingRouteInstancesForStation(stationId: Int): List<Long>
+
+    fun findAllByEndDateIsNull(): List<InstancaNaLinija>
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KaznaRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KaznaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KaznaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Kazna
+import mk.ukim.finki.busngobackend.domain.entities.Kontrola
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface KaznaRepository : JpaRepository<Kazna, Long> {
+    fun findAllByKontrola(kontrola: Kontrola): List<Kazna>
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KaznaZaNeregistriranRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KaznaZaNeregistriranRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KaznaZaNeregistriranRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Kazna
+import mk.ukim.finki.busngobackend.domain.entities.KaznaZaNeregistriran
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface KaznaZaNeregistriranRepository : JpaRepository<KaznaZaNeregistriran, Long> {
+    fun findAllByKaznaIn(kazni: List<Kazna>): List<KaznaZaNeregistriran>
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KaznaZaRegistriranRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KaznaZaRegistriranRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KaznaZaRegistriranRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Kazna
+import mk.ukim.finki.busngobackend.domain.entities.KaznaZaRegistriran
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface KaznaZaRegistriranRepository : JpaRepository<KaznaZaRegistriran, Long> {
+    fun findAllByKaznaIn(kazni: List<Kazna>): List<KaznaZaRegistriran>
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KondukterRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KondukterRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KondukterRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Kondukter
+import mk.ukim.finki.busngobackend.domain.entities.Vraboten
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface KondukterRepository : JpaRepository<Kondukter, Long> {
+    fun findByVraboten(vraboten: Vraboten): Kondukter?
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KontrolaRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KontrolaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KontrolaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Kondukter
+import mk.ukim.finki.busngobackend.domain.entities.Kontrola
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface KontrolaRepository : JpaRepository<Kontrola, Long> {
+    fun findAllByKondukterOrderByDateCreatedDesc(kondukter: Kondukter): List<Kontrola>
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KorisnikRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KorisnikRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KorisnikRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,8 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Korisnik
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface KorisnikRepository : JpaRepository<Korisnik, Long> {
+    fun findByEmail(email: String): Korisnik?
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KorisnikRoleRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KorisnikRoleRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/KorisnikRoleRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Korisnik
+import mk.ukim.finki.busngobackend.domain.entities.KorisnikRole
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface KorisnikRoleRepository : JpaRepository<KorisnikRole, Long> {
+    fun findAllByKorisnik(user: Korisnik): List<KorisnikRole>
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/LinijaPravecRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/LinijaPravecRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/LinijaPravecRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,15 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Linija
+import mk.ukim.finki.busngobackend.domain.entities.LinijaPravec
+import mk.ukim.finki.busngobackend.domain.entities.Pravec
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface LinijaPravecRepository : JpaRepository<LinijaPravec, Long> {
+    fun findAllByLinija(linija: Linija): List<LinijaPravec>
+
+    fun existsByLinijaAndPravec(
+        linija: Linija,
+        pravec: Pravec,
+    ): Boolean
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/LinijaRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/LinijaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/LinijaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Linija
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface LinijaRepository : JpaRepository<Linija, Int>
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/NumberOfPassengersByLineAndStationRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/NumberOfPassengersByLineAndStationRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/NumberOfPassengersByLineAndStationRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.views.NumberOfPassengersByLineAndStation
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface NumberOfPassengersByLineAndStationRepository : JpaRepository<NumberOfPassengersByLineAndStation, Long>
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/PatnikRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/PatnikRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/PatnikRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Korisnik
+import mk.ukim.finki.busngobackend.domain.entities.Patnik
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface PatnikRepository : JpaRepository<Patnik, Long> {
+    fun findByKorisnik(korisnik: Korisnik): Patnik?
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/PostojkaNaLinijaRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/PostojkaNaLinijaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/PostojkaNaLinijaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,42 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Linija
+import mk.ukim.finki.busngobackend.domain.entities.Postojka
+import mk.ukim.finki.busngobackend.domain.entities.PostojkaNaLinija
+import mk.ukim.finki.busngobackend.domain.entities.Pravec
+import mk.ukim.finki.busngobackend.domain.views.AverageTimeBetweenStations
+import org.springframework.data.jpa.repository.JpaRepository
+import org.springframework.data.jpa.repository.Query
+
+interface PostojkaNaLinijaRepository : JpaRepository<PostojkaNaLinija, Long> {
+    fun findByLinija(linija: Linija): List<PostojkaNaLinija>
+
+    fun findByLinijaAndPravec(
+        linija: Linija,
+        pravec: Pravec,
+    ): List<PostojkaNaLinija>
+
+    fun existsByLinijaAndPostojka(
+        linija: Linija,
+        postojkaStart: Postojka,
+    ): Boolean
+
+    fun findByLinijaAndPostojka(
+        linija: Linija,
+        postojkaStart: Postojka,
+    ): PostojkaNaLinija?
+
+    fun findByLinijaAndPostojkaAndPravec(
+        linija: Linija,
+        postojkaStart: Postojka,
+        pravec: Pravec,
+    ): PostojkaNaLinija?
+
+    @Query(
+        nativeQuery = true,
+        value = """
+            select id, start_station_id, end_station_id, avg_time_diff_seconds from project.avg_time_diffs
+        """,
+    )
+    fun getAverageTimeBetweenStations(): List<AverageTimeBetweenStations>
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/PostojkaRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/PostojkaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/PostojkaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Postojka
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface PostojkaRepository : JpaRepository<Postojka, Long>
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/PravecRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/PravecRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/PravecRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Pravec
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface PravecRepository : JpaRepository<Pravec, Long>
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/RoleRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/RoleRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/RoleRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,8 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Role
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface RoleRepository : JpaRepository<Role, Long> {
+    fun findAllByNameLikeIgnoreCase(name: String): List<Role>
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/SeSimnuvaNaRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/SeSimnuvaNaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/SeSimnuvaNaRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.SeSimnuvaNa
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface SeSimnuvaNaRepository : JpaRepository<SeSimnuvaNa, Long>
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/TicketSalesRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/TicketSalesRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/TicketSalesRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.views.TicketSales
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface TicketSalesRepository : JpaRepository<TicketSales, Long>
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/TipbiletRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/TipbiletRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/TipbiletRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Tipbilet
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface TipbiletRepository : JpaRepository<Tipbilet, Long>
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/TotalIncomeRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/TotalIncomeRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/TotalIncomeRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.views.TotalIncome
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface TotalIncomeRepository : JpaRepository<TotalIncome, Long>
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/VozacRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/VozacRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/VozacRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Vozac
+import mk.ukim.finki.busngobackend.domain.entities.Vraboten
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface VozacRepository : JpaRepository<Vozac, Long> {
+    fun findByVraboten(vraboten: Vraboten): Vozac?
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/VozenjeRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/VozenjeRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/VozenjeRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,6 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Vozenje
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface VozenjeRepository : JpaRepository<Vozenje, Long>
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/VrabotenRepository.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/VrabotenRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/repository/VrabotenRepository.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,9 @@
+package mk.ukim.finki.busngobackend.repository
+
+import mk.ukim.finki.busngobackend.domain.entities.Korisnik
+import mk.ukim.finki.busngobackend.domain.entities.Vraboten
+import org.springframework.data.jpa.repository.JpaRepository
+
+interface VrabotenRepository : JpaRepository<Vraboten, Long> {
+    fun findByKorisnik(korisnik: Korisnik): Vraboten?
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/AdminService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/AdminService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/AdminService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,91 @@
+package mk.ukim.finki.busngobackend.service
+
+import mk.ukim.finki.busngobackend.api.responses.AdminUsersResponse
+import mk.ukim.finki.busngobackend.domain.entities.KorisnikRole
+import mk.ukim.finki.busngobackend.domain.enums.RoleEnum
+import mk.ukim.finki.busngobackend.domain.views.*
+import mk.ukim.finki.busngobackend.repository.*
+import mk.ukim.finki.busngobackend.service.exceptions.NotFoundException
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.stereotype.Service
+
+@Service
+class AdminService(
+    private val avgTimeDIffsRepository: AvgTimeDIffsRepository,
+    private val finesByLineRepository: FinesByLineRepository,
+    private val commutesByHourRepository: CommutesByHourRepository,
+    private val commutesByLineRepository: CommutesByLineRepository,
+    private val numberOfPassengersByLineAndStationRepository: NumberOfPassengersByLineAndStationRepository,
+    private val ticketSalesRepository: TicketSalesRepository,
+    private val totalIncomeRepository: TotalIncomeRepository,
+    private val korisnikService: KorisnikService,
+    private val korisnikRepository: KorisnikRepository,
+    private val roleRepository: RoleRepository,
+    private val korisnikRoleRepository: KorisnikRoleRepository,
+    private val authService: AuthService,
+) {
+    fun getAverageTimeBetweenStations(): List<AverageTimeBetweenStations> {
+        authService.hasAuthority(RoleEnum.ROLE_ADMIN)
+        return avgTimeDIffsRepository.findAll()
+    }
+
+    fun getFinesByLine(): List<FinesByLine> {
+        authService.hasAuthority(RoleEnum.ROLE_ADMIN)
+        return finesByLineRepository.findAll()
+    }
+
+    fun getCommutesByHour(): List<CommutesByHour> {
+        authService.hasAuthority(RoleEnum.ROLE_ADMIN)
+        return commutesByHourRepository.findAll()
+    }
+
+    fun getCommutesByLine(): List<CommutesByLine> {
+        authService.hasAuthority(RoleEnum.ROLE_ADMIN)
+        return commutesByLineRepository.findAll()
+    }
+
+    fun getNumberOfPassengersByLineAndStation(): List<NumberOfPassengersByLineAndStation> {
+        authService.hasAuthority(RoleEnum.ROLE_ADMIN)
+        return numberOfPassengersByLineAndStationRepository.findAll()
+    }
+
+    fun getTicketSales(): List<TicketSales> {
+        authService.hasAuthority(RoleEnum.ROLE_ADMIN)
+        return ticketSalesRepository.findAll()
+    }
+
+    fun getTotalIncome(): List<TotalIncome> {
+        authService.hasAuthority(RoleEnum.ROLE_ADMIN)
+        return totalIncomeRepository.findAll()
+    }
+
+    fun getAllUsers(): List<AdminUsersResponse> {
+        authService.hasAuthority(RoleEnum.ROLE_ADMIN)
+        return korisnikService.getAllUsers()
+    }
+
+    fun updateRolesForUser(
+        id: Long,
+        roleNames: List<String>,
+    ): List<AdminUsersResponse> {
+        authService.hasAuthority(RoleEnum.ROLE_ADMIN)
+        val user = korisnikRepository.findByIdOrNull(id) ?: throw NotFoundException("User not found")
+        val roles = roleNames.flatMap { role -> roleRepository.findAllByNameLikeIgnoreCase(role) }
+
+        val allByKorisnik = korisnikRoleRepository.findAllByKorisnik(user)
+
+        val rolesToDelete = allByKorisnik.filter { it.role !in roles }
+        val rolesToAdd =
+            roles.filter { it !in allByKorisnik.map { r -> r.role } }.map {
+                KorisnikRole(
+                    id = 0L,
+                    korisnik = user,
+                    role = it,
+                )
+            }
+
+        korisnikRoleRepository.deleteAll(rolesToDelete)
+        korisnikRoleRepository.saveAll(rolesToAdd)
+        return getAllUsers()
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/AuthService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/AuthService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/AuthService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,157 @@
+package mk.ukim.finki.busngobackend.service
+
+import mk.ukim.finki.busngobackend.api.requests.AuthRequest
+import mk.ukim.finki.busngobackend.api.requests.RegisterRequest
+import mk.ukim.finki.busngobackend.api.responses.AuthResponse
+import mk.ukim.finki.busngobackend.config.JwtService
+import mk.ukim.finki.busngobackend.domain.entities.*
+import mk.ukim.finki.busngobackend.domain.enums.RoleEnum
+import mk.ukim.finki.busngobackend.domain.enums.toId
+import mk.ukim.finki.busngobackend.repository.*
+import mk.ukim.finki.busngobackend.service.exceptions.NotFoundException
+import mk.ukim.finki.busngobackend.service.exceptions.UnauthorizedAccessException
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.security.authentication.AuthenticationManager
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
+import org.springframework.security.core.GrantedAuthority
+import org.springframework.security.core.context.SecurityContext
+import org.springframework.security.core.context.SecurityContextHolder
+import org.springframework.security.core.userdetails.UserDetailsService
+import org.springframework.stereotype.Service
+
+@Service
+class AuthService(
+    private val authenticationManager: AuthenticationManager,
+    private val userDetailsService: UserDetailsService,
+    private val jwtService: JwtService,
+    private val korisnikRepository: KorisnikRepository,
+    private val korisnikRoleRepository: KorisnikRoleRepository,
+    private val roleRepository: RoleRepository,
+    private val instancaNaLinijaRepository: InstancaNaLinijaRepository,
+    private val vrabotenRepository: VrabotenRepository,
+    private val vozacRepository: VozacRepository,
+    private val kondukterRepository: KondukterRepository,
+    private val patnikRepository: PatnikRepository,
+) {
+    fun getSecurityContext(): SecurityContext = SecurityContextHolder.getContext()
+
+    fun getAuthenticatedUser(): Korisnik = userDetailsService.loadUserByUsername(getSecurityContext().authentication.name) as Korisnik
+
+    fun hasAuthority(authority: RoleEnum): Boolean =
+        getAuthenticatedUser().authorities.contains(roleRepository.findByIdOrNull(authority.toId()) as GrantedAuthority)
+
+    fun isAuthenticated(): Boolean {
+        if (getSecurityContext().authentication == null) {
+            throw UnauthorizedAccessException("User is not authenticated")
+        }
+        return true
+    }
+
+    fun register(registerRequest: RegisterRequest): AuthResponse {
+        if (this.korisnikRepository.findByEmail(registerRequest.email) != null) {
+            throw RuntimeException("Invalid credentials")
+        }
+        if (registerRequest.password != registerRequest.confirmPassword) {
+            throw RuntimeException("Passwords do not match")
+        }
+
+        val roles = this.roleRepository.findAllByNameLikeIgnoreCase("role_passenger")
+
+        val user =
+            this.korisnikRepository.save(
+                Korisnik(
+                    email = registerRequest.email,
+                    lozinka = registerRequest.password,
+                    ime = registerRequest.name,
+                    id = 0L,
+                    adresa = registerRequest.address,
+                    admin = false,
+                    telefon = registerRequest.phoneNumber,
+                    roles = null,
+                ),
+            )
+
+        val newRoles =
+            roles.map {
+                this.korisnikRoleRepository.save(
+                    KorisnikRole(
+                        id = 0,
+                        role = it,
+                        korisnik = user,
+                    ),
+                )
+            }
+
+        user.roles = newRoles
+
+        val korisnik = this.korisnikRepository.save(user)
+        val patnik =
+            this.patnikRepository.save(
+                Patnik(
+                    id = 0L,
+                    korisnik = korisnik,
+                ),
+            )
+
+        return this.authenticate(AuthRequest(user.email, user.lozinka))
+    }
+
+    fun authenticate(authRequest: AuthRequest): AuthResponse {
+        authenticationManager.authenticate(
+            UsernamePasswordAuthenticationToken(
+                authRequest.email,
+                authRequest.password,
+            ),
+        )
+
+        val user = userDetailsService.loadUserByUsername(authRequest.email)
+
+        val token = jwtService.generateToken(userDetails = user)
+
+        return AuthResponse(token)
+    }
+
+    fun isDriverFree(): Boolean {
+        if (!this.hasAuthority(RoleEnum.ROLE_DRIVER)) throw UnauthorizedAccessException("User is not authorized")
+        val korisnik = this.userDetailsService.loadUserByUsername(this.getSecurityContext().authentication.name) as Korisnik
+        val vraboten = this.vrabotenRepository.findByKorisnik(korisnik) ?: throw NotFoundException("Vraboten not found")
+        val vozac = this.vozacRepository.findByVraboten(vraboten) ?: throw NotFoundException("Vozac not found")
+
+        return !this.instancaNaLinijaRepository.existsByVozacAndEndDateIsNull(vozac.id)
+    }
+
+    fun getConductor(): Kondukter {
+        if (!this.isAuthenticated() || !this.hasAuthority(RoleEnum.ROLE_CONDUCTOR)) {
+            throw UnauthorizedAccessException("Unauthorized access")
+        }
+
+        val korisnik = this.getAuthenticatedUser()
+        val vraboten = vrabotenRepository.findByKorisnik(korisnik) ?: throw NotFoundException("Korisnik")
+        val kondukter = kondukterRepository.findByVraboten(vraboten) ?: throw NotFoundException("Kondukter")
+
+        return kondukter
+    }
+
+    fun getDriver(): Vozac {
+        if (!this.isAuthenticated() || !this.hasAuthority(RoleEnum.ROLE_DRIVER)) {
+            throw UnauthorizedAccessException("Unauthorized access")
+        }
+
+        val korisnik = this.getAuthenticatedUser()
+        val vraboten = vrabotenRepository.findByKorisnik(korisnik) ?: throw NotFoundException("Korisnik")
+        val vozac = vozacRepository.findByVraboten(vraboten) ?: throw NotFoundException("Vozac")
+
+        return vozac
+    }
+
+    fun getPassenger(): Patnik {
+        if (!this.isAuthenticated() || !this.hasAuthority(RoleEnum.ROLE_PASSENGER)) {
+            throw UnauthorizedAccessException("Unauthorized access")
+        }
+
+        val korisnik = this.getAuthenticatedUser()
+        val patnik = patnikRepository.findByKorisnik(korisnik) ?: throw NotFoundException("Patnik")
+
+        return patnik
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/BiletService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/BiletService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/BiletService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,65 @@
+package mk.ukim.finki.busngobackend.service
+
+import mk.ukim.finki.busngobackend.api.requests.TicketBuyRequest
+import mk.ukim.finki.busngobackend.api.responses.TicketResponse
+import mk.ukim.finki.busngobackend.domain.entities.Bilet
+import mk.ukim.finki.busngobackend.domain.enums.BiletEnum
+import mk.ukim.finki.busngobackend.mapper.ClassToDtoMapper
+import mk.ukim.finki.busngobackend.repository.BiletRepository
+import mk.ukim.finki.busngobackend.repository.PatnikRepository
+import mk.ukim.finki.busngobackend.repository.TipbiletRepository
+import mk.ukim.finki.busngobackend.service.exceptions.NotFoundException
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.stereotype.Service
+import java.sql.Timestamp
+import java.time.LocalDateTime
+
+@Service
+class BiletService(
+    private val mapper: ClassToDtoMapper,
+    private val biletRepository: BiletRepository,
+    private val korisnikService: KorisnikService,
+    private val patnikRepository: PatnikRepository,
+    private val tipbiletRepository: TipbiletRepository,
+) {
+    fun getTicketsByUser(): List<TicketResponse> {
+        val user = korisnikService.getUser()
+        val patnik =
+            patnikRepository.findByKorisnik(user) ?: throw NotFoundException("Patnik not found")
+
+        return biletRepository.findAllByPatnik(patnik).map { mapper.toTicketResponse(it) }
+    }
+
+    fun buyTicket(request: TicketBuyRequest): TicketResponse {
+        val user = korisnikService.getUser()
+        val patnik =
+            patnikRepository.findByKorisnik(user) ?: throw NotFoundException("Patnik not found")
+        val type = tipbiletRepository.findByIdOrNull(request.type) ?: throw NotFoundException("Type not found")
+
+        val ticket =
+            biletRepository.save(
+                Bilet(
+                    id = 0L,
+                    status = BiletEnum.INACTIVE,
+                    tip = type,
+                    datumKupuvanje = Timestamp.valueOf(LocalDateTime.now()),
+                    patnik = patnik,
+                    datumAktivacija = null,
+                ),
+            )
+
+        return mapper.toTicketResponse(ticket)
+    }
+
+    fun activateTicket(id: Long): TicketResponse {
+        val user = korisnikService.getUser()
+        val patnik =
+            patnikRepository.findByKorisnik(user) ?: throw NotFoundException("Patnik not found")
+
+        val ticket = biletRepository.findByIdAndPatnik(id, patnik) ?: throw NotFoundException("Ticket not found")
+
+        ticket.status = BiletEnum.ACTIVE
+        ticket.datumAktivacija = Timestamp.valueOf(LocalDateTime.now())
+        return mapper.toTicketResponse(biletRepository.save(ticket))
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/BusService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/BusService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/BusService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,14 @@
+package mk.ukim.finki.busngobackend.service
+
+import mk.ukim.finki.busngobackend.domain.entities.Avtobus
+import mk.ukim.finki.busngobackend.repository.AvtobusRepository
+import org.springframework.stereotype.Service
+
+@Service
+class BusService(
+    private val avtobusRepository: AvtobusRepository,
+) {
+    fun findAll() = avtobusRepository.findAll()
+
+    fun findAllFree(): List<Avtobus> = this.avtobusRepository.findAllFreeBuses()
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/CommuteService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/CommuteService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/CommuteService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,66 @@
+package mk.ukim.finki.busngobackend.service
+
+import jakarta.transaction.Transactional
+import mk.ukim.finki.busngobackend.api.requests.StartCommuteRequest
+import mk.ukim.finki.busngobackend.api.responses.CommuteResponse
+import mk.ukim.finki.busngobackend.domain.entities.Vozenje
+import mk.ukim.finki.busngobackend.domain.enums.BiletEnum
+import mk.ukim.finki.busngobackend.domain.enums.RoleEnum
+import mk.ukim.finki.busngobackend.domain.enums.VozenjeStatus
+import mk.ukim.finki.busngobackend.mapper.ClassToDtoMapper
+import mk.ukim.finki.busngobackend.repository.*
+import mk.ukim.finki.busngobackend.service.exceptions.NotFoundException
+import mk.ukim.finki.busngobackend.service.exceptions.UnauthorizedAccessException
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.stereotype.Service
+import java.sql.Timestamp
+import java.time.LocalDateTime
+
+@Service
+class CommuteService(
+    private val linijaRepository: LinijaRepository,
+    private val postojkaRepository: PostojkaRepository,
+    private val postojkaNaLinijaRepository: PostojkaNaLinijaRepository,
+    private val biletRepository: BiletRepository,
+    private val authService: AuthService,
+    private val patnikRepository: PatnikRepository,
+    private val instancaNaLinijaRepository: InstancaNaLinijaRepository,
+    private val vozenjeRepository: VozenjeRepository,
+    private val dtoMapper: ClassToDtoMapper,
+) {
+    @Transactional
+    fun start(request: StartCommuteRequest): CommuteResponse {
+        if (!this.authService.hasAuthority(RoleEnum.ROLE_PASSENGER)) throw UnauthorizedAccessException("Unauthorised role")
+        val korisnik = this.authService.getAuthenticatedUser()
+        val patnik = patnikRepository.findByKorisnik(korisnik) ?: throw NotFoundException("Korisnik")
+
+        var bilet = biletRepository.findByIdAndPatnik(request.ticketId, patnik) ?: throw NotFoundException("Bilet")
+
+        val instancaNaLinija =
+            instancaNaLinijaRepository.findByIdOrNull(request.routeInstanceId) ?: throw NotFoundException("RouteInstanceId")
+        val postojka = postojkaRepository.findByIdOrNull(request.stationId) ?: throw NotFoundException("StationId")
+
+        val postojkaNaLinijaStart =
+            postojkaNaLinijaRepository.findByLinijaAndPostojkaAndPravec(instancaNaLinija.linija, postojka, instancaNaLinija.pravec)
+                ?: throw NotFoundException("Station not found")
+
+        if (bilet.status == BiletEnum.INACTIVE) {
+            bilet.status = BiletEnum.ACTIVE
+            bilet.datumAktivacija = Timestamp.valueOf(LocalDateTime.now())
+            bilet = biletRepository.save(bilet)
+        }
+
+        val vozenje =
+            Vozenje(
+                id = 0L,
+                startDate = Timestamp.valueOf(LocalDateTime.now()),
+                endDate = null,
+                status = VozenjeStatus.ACTIVE,
+                patnik = patnik,
+                postojkaNaLinijaStart = postojkaNaLinijaStart,
+                instancaNaLinija = instancaNaLinija,
+                bilet = bilet,
+            )
+        return vozenjeRepository.save(vozenje).let { dtoMapper.toCommuteResponse(it) }
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/ControlService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/ControlService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/ControlService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,61 @@
+package mk.ukim.finki.busngobackend.service
+
+import mk.ukim.finki.busngobackend.api.responses.ControlResponse
+import mk.ukim.finki.busngobackend.api.responses.FineResponse
+import mk.ukim.finki.busngobackend.domain.entities.Kontrola
+import mk.ukim.finki.busngobackend.mapper.ClassToDtoMapper
+import mk.ukim.finki.busngobackend.repository.*
+import mk.ukim.finki.busngobackend.service.exceptions.NotFoundException
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.stereotype.Service
+import java.sql.Timestamp
+import java.time.LocalDateTime
+
+@Service
+class ControlService(
+    private val kontrolaRepository: KontrolaRepository,
+    private val dtoMapper: ClassToDtoMapper,
+    private val authService: AuthService,
+    private val instancaNaLinijaRepository: InstancaNaLinijaRepository,
+    private val kaznaRepository: KaznaRepository,
+    private val kaznaZaRegistriranRepository: KaznaZaRegistriranRepository,
+    private val kaznaZaNeregistriranRepository: KaznaZaNeregistriranRepository,
+) {
+    fun getAllByConductor(): List<ControlResponse> {
+        val kondukter = authService.getConductor()
+
+        return kontrolaRepository
+            .findAllByKondukterOrderByDateCreatedDesc(
+                kondukter,
+            ).map { kontrola -> dtoMapper.toControlResponse(kontrola) }
+    }
+
+    fun start(routeInstanceId: Long): ControlResponse {
+        val instancaNaLinija =
+            instancaNaLinijaRepository.findByIdOrNull(routeInstanceId) ?: throw NotFoundException("Route instance")
+        val kontrola =
+            kontrolaRepository.save(
+                Kontrola(
+                    id = 0L,
+                    kondukter = authService.getConductor(),
+                    dateCreated = Timestamp.valueOf(LocalDateTime.now()),
+                    instancaNaLinija = instancaNaLinija,
+                ),
+            )
+        return kontrola.let { dtoMapper.toControlResponse(it) }
+    }
+
+    fun getFines(controlId: Long): List<FineResponse> {
+        val kondukter = authService.getConductor()
+        val kontrola = kontrolaRepository.findByIdOrNull(controlId) ?: throw NotFoundException("Control not found")
+
+        val kazni = kaznaRepository.findAllByKontrola(kontrola)
+
+        val kzrs = kaznaZaRegistriranRepository.findAllByKaznaIn(kazni)
+        val kzns = kaznaZaNeregistriranRepository.findAllByKaznaIn(kazni)
+
+        return kzrs
+            .map { dtoMapper.toFineResponse(kazna = it.kazna, kzr = it, kzn = null) }
+            .plus(kzns.map { dtoMapper.toFineResponse(kazna = it.kazna, kzr = null, kzn = it) })
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/DirectionService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/DirectionService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/DirectionService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,21 @@
+package mk.ukim.finki.busngobackend.service
+
+import mk.ukim.finki.busngobackend.domain.entities.LinijaPravec
+import mk.ukim.finki.busngobackend.repository.LinijaPravecRepository
+import mk.ukim.finki.busngobackend.repository.LinijaRepository
+import mk.ukim.finki.busngobackend.repository.PravecRepository
+import mk.ukim.finki.busngobackend.service.exceptions.NotFoundException
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.stereotype.Service
+
+@Service
+class DirectionService(
+    private val pravecRepository: PravecRepository,
+    private val linijaPravecRepository: LinijaPravecRepository,
+    private val linijaRepository: LinijaRepository,
+) {
+    fun findDirectionsByLineId(lineId: Int): List<LinijaPravec> {
+        val linija = linijaRepository.findByIdOrNull(lineId) ?: throw NotFoundException("Line not found")
+        return linijaPravecRepository.findAllByLinija(linija)
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/FineService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/FineService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/FineService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,81 @@
+package mk.ukim.finki.busngobackend.service
+
+import jakarta.transaction.Transactional
+import mk.ukim.finki.busngobackend.api.requests.FineRequest
+import mk.ukim.finki.busngobackend.api.responses.FineResponse
+import mk.ukim.finki.busngobackend.domain.entities.Kazna
+import mk.ukim.finki.busngobackend.domain.entities.KaznaZaNeregistriran
+import mk.ukim.finki.busngobackend.domain.entities.KaznaZaRegistriran
+import mk.ukim.finki.busngobackend.mapper.ClassToDtoMapper
+import mk.ukim.finki.busngobackend.repository.*
+import mk.ukim.finki.busngobackend.service.exceptions.NotFoundException
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.stereotype.Service
+import java.sql.Timestamp
+import java.time.LocalDateTime
+
+@Service
+class FineService(
+    private val kaznaRepository: KaznaRepository,
+    private val authService: AuthService,
+    private val kontrolaRepository: KontrolaRepository,
+    private val dtoMapper: ClassToDtoMapper,
+    private val kaznaZaRegistriranRepository: KaznaZaRegistriranRepository,
+    private val kaznaZaNeregistriranRepository: KaznaZaNeregistriranRepository,
+    private val korisnikRepository: KorisnikRepository,
+    private val patnikRepository: PatnikRepository,
+) {
+    @Transactional
+    fun createFine(request: FineRequest): FineResponse {
+        val kontrola = kontrolaRepository.findByIdOrNull(request.kontrolaId) ?: throw NotFoundException("Kontrola")
+        val now = Timestamp.valueOf(LocalDateTime.now())
+        val kazna =
+            kaznaRepository.save(
+                Kazna(
+                    dateCreated = now,
+                    id = 0L,
+                    kondukter = authService.getConductor(),
+                    datePayed =
+                        if (request.plateno) {
+                            now
+                        } else {
+                            null
+                        },
+                    iznos = request.iznos,
+                    dokument = request.dokument,
+                    kontrola = kontrola,
+                    plateno = request.plateno,
+                ),
+            )
+
+        if (request.patnikId != null) {
+            val korisnik = korisnikRepository.findByIdOrNull(request.patnikId!!) ?: throw NotFoundException("Korisnik")
+            val patnik = patnikRepository.findByKorisnik(korisnik) ?: throw NotFoundException("Patnik")
+            val kzr =
+                kaznaZaRegistriranRepository.save(
+                    KaznaZaRegistriran(
+                        patnik = patnik,
+                        id = 0L,
+                        kazna = kazna,
+                    ),
+                )
+            return kzr.let { dtoMapper.toFineResponse(kazna = kazna, kzr = kzr, kzn = null) }
+        }
+
+        if (request.adresa != null && request.ime != null && request.telefon != null) {
+            val kzn =
+                kaznaZaNeregistriranRepository.save(
+                    KaznaZaNeregistriran(
+                        id = 0L,
+                        kazna = kazna,
+                        ime = request.ime!!,
+                        telefon = request.telefon!!,
+                        adresa = request.adresa!!,
+                    ),
+                )
+
+            return kzn.let { dtoMapper.toFineResponse(kazna = kazna, kzn = kzn, kzr = null) }
+        }
+        return dtoMapper.toFineResponse(kazna = kazna, kzr = null, kzn = null)
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/KorisnikService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/KorisnikService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/KorisnikService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,36 @@
+package mk.ukim.finki.busngobackend.service
+
+import mk.ukim.finki.busngobackend.api.responses.UserResponse
+import mk.ukim.finki.busngobackend.domain.entities.Korisnik
+import mk.ukim.finki.busngobackend.mapper.ClassToDtoMapper
+import mk.ukim.finki.busngobackend.repository.KorisnikRepository
+import mk.ukim.finki.busngobackend.repository.PatnikRepository
+import mk.ukim.finki.busngobackend.service.exceptions.UnauthorizedAccessException
+import org.springframework.stereotype.Service
+
+@Service
+class KorisnikService(
+    private val korisnikRepository: KorisnikRepository,
+    private val authService: AuthService,
+    private val mapper: ClassToDtoMapper,
+    private val patnikRepository: PatnikRepository,
+    private val classToDtoMapper: ClassToDtoMapper,
+) {
+    fun getAuthenticatedUser(): UserResponse {
+        val user =
+            authService.getSecurityContext().authentication?.let { auth ->
+                korisnikRepository.findByEmail(auth.name)
+            }
+
+        return user?.let { mapper.toUserResponse(it) } ?: throw UnauthorizedAccessException("Unauthorized access")
+    }
+
+    fun getUser(): Korisnik =
+        authService.getSecurityContext().authentication?.let { auth ->
+            korisnikRepository.findByEmail(auth.name)
+        } ?: throw UnauthorizedAccessException("Unauthorized access")
+
+    fun getAllPassengers(): List<UserResponse> = patnikRepository.findAll().map { classToDtoMapper.toUserResponse(it.korisnik) }
+
+    fun getAllUsers() = korisnikRepository.findAll().map { classToDtoMapper.toAdminUsersResponse(it) }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/LineService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/LineService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/LineService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,14 @@
+package mk.ukim.finki.busngobackend.service
+
+import mk.ukim.finki.busngobackend.domain.entities.Linija
+import mk.ukim.finki.busngobackend.mapper.ClassToDtoMapper
+import mk.ukim.finki.busngobackend.repository.LinijaRepository
+import org.springframework.stereotype.Service
+
+@Service
+class LineService(
+    private val linijaRepository: LinijaRepository,
+    private val dtoMapper: ClassToDtoMapper,
+) {
+    fun findAllLines(): List<Linija> = this.linijaRepository.findAll()
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/MaterializedViewService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/MaterializedViewService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/MaterializedViewService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,34 @@
+package mk.ukim.finki.busngobackend.service
+
+import org.springframework.jdbc.core.JdbcTemplate
+import org.springframework.stereotype.Service
+import org.springframework.transaction.annotation.Transactional
+
+@Service
+class MaterializedViewService(
+    private val jdbcTemplate: JdbcTemplate,
+) {
+    @Transactional
+    fun refreshAverageTimeDiffs() {
+        val sql = "REFRESH MATERIALIZED VIEW CONCURRENTLY project.avg_time_diffs;"
+        jdbcTemplate.execute(sql)
+    }
+
+    @Transactional
+    fun refreshCommutesByHour() {
+        val sql = "refresh materialized view concurrently project.most_busy_part_of_the_day;"
+        jdbcTemplate.execute(sql)
+    }
+
+    @Transactional
+    fun refreshFinesPerLine() {
+        val sql = "refresh materialized view concurrently project.kazna_po_linija;"
+        jdbcTemplate.execute(sql)
+    }
+
+    @Transactional
+    fun refreshTotalIncome() {
+        val sql = "refresh materialized view concurrently project.total_income;"
+        jdbcTemplate.execute(sql)
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/RouteInstanceOnStationService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/RouteInstanceOnStationService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/RouteInstanceOnStationService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,35 @@
+package mk.ukim.finki.busngobackend.service
+
+import mk.ukim.finki.busngobackend.domain.entities.InstancaNaLinijaPostojkaNaLinija
+import mk.ukim.finki.busngobackend.repository.InstancaNaLinijaPostojkaNaLinijaRepository
+import mk.ukim.finki.busngobackend.repository.InstancaNaLinijaRepository
+import mk.ukim.finki.busngobackend.repository.PostojkaNaLinijaRepository
+import mk.ukim.finki.busngobackend.service.exceptions.NotFoundException
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.stereotype.Service
+import java.sql.Timestamp
+
+@Service
+class RouteInstanceOnStationService(
+    private val instancaNaLinijaPostojkaNaLinijaRepository: InstancaNaLinijaPostojkaNaLinijaRepository,
+    private val instancaNaLinijaRepository: InstancaNaLinijaRepository,
+    private val postojkaNaLinijaRepository: PostojkaNaLinijaRepository,
+) {
+    fun create(
+        routeInstanceId: Long,
+        lineStationId: Long,
+        timestamp: Timestamp,
+    ): InstancaNaLinijaPostojkaNaLinija {
+        val routeInstance =
+            instancaNaLinijaRepository.findByIdOrNull(routeInstanceId) ?: throw NotFoundException("Route instance not found")
+        val lineStation = postojkaNaLinijaRepository.findByIdOrNull(lineStationId) ?: throw NotFoundException("Line station not found")
+        return instancaNaLinijaPostojkaNaLinijaRepository.save(
+            InstancaNaLinijaPostojkaNaLinija(
+                instancaNaLinija = routeInstance,
+                postojkaNaLinija = lineStation,
+                timestamp = timestamp,
+                id = 0L,
+            ),
+        )
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/RouteInstanceService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/RouteInstanceService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/RouteInstanceService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,96 @@
+package mk.ukim.finki.busngobackend.service
+
+import mk.ukim.finki.busngobackend.api.requests.StartRouteInstanceRequest
+import mk.ukim.finki.busngobackend.api.responses.RouteInstanceResponse
+import mk.ukim.finki.busngobackend.domain.entities.InstancaNaLinija
+import mk.ukim.finki.busngobackend.domain.enums.RoleEnum
+import mk.ukim.finki.busngobackend.events.StartRouteEvent
+import mk.ukim.finki.busngobackend.mapper.ClassToDtoMapper
+import mk.ukim.finki.busngobackend.repository.*
+import mk.ukim.finki.busngobackend.service.exceptions.NotFoundException
+import mk.ukim.finki.busngobackend.service.exceptions.UnauthorizedAccessException
+import org.springframework.context.ApplicationEventPublisher
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.stereotype.Service
+import java.sql.Timestamp
+import java.time.LocalDateTime
+
+@Service
+class RouteInstanceService(
+    private val instancaNaLinijaRepository: InstancaNaLinijaRepository,
+    private val linijaRepository: LinijaRepository,
+    private val pravecRepository: PravecRepository,
+    private val linijaPravecRepository: LinijaPravecRepository,
+    private val avtobusRepository: AvtobusRepository,
+    private val authService: AuthService,
+    private val vrabotenRepository: VrabotenRepository,
+    private val vozacRepository: VozacRepository,
+    private val dtoMapper: ClassToDtoMapper,
+    private val publisher: ApplicationEventPublisher,
+    private val postojkaRepository: PostojkaRepository,
+) {
+    fun start(request: StartRouteInstanceRequest): RouteInstanceResponse {
+        if (!authService.isAuthenticated() || !authService.hasAuthority(RoleEnum.ROLE_DRIVER)) {
+            throw UnauthorizedAccessException("Unauthorized access")
+        }
+
+        val korisnik = authService.getAuthenticatedUser()
+        val vraboten = vrabotenRepository.findByKorisnik(korisnik) ?: throw NotFoundException("Korisnik")
+        val vozac = vozacRepository.findByVraboten(vraboten) ?: throw NotFoundException("Vraboten")
+
+        val linija = linijaRepository.findByIdOrNull(request.lineId) ?: throw NotFoundException("Line not found")
+        val pravec =
+            pravecRepository.findByIdOrNull(request.directionId) ?: throw NotFoundException("Direction not found")
+
+        if (!linijaPravecRepository.existsByLinijaAndPravec(linija, pravec)) {
+            throw NotFoundException("Line does not has the specified direction")
+        }
+
+        val avtobus = avtobusRepository.findByIdOrNull(request.busId) ?: throw NotFoundException("Bus Not Found")
+
+        val instanca =
+            InstancaNaLinija(
+                id = 0L,
+                startDate = Timestamp.valueOf(LocalDateTime.now()),
+                linija = linija,
+                pravec = pravec,
+                avtobus = avtobus,
+                vozac = vozac,
+                endDate = null,
+            )
+
+        return instancaNaLinijaRepository
+            .save(instanca)
+            .let {
+                publisher.publishEvent(StartRouteEvent(it))
+                dtoMapper.toRouteInstanceResponse(it)
+            }
+    }
+
+    fun findById(id: Long): InstancaNaLinija = instancaNaLinijaRepository.findByIdOrNull(id) ?: throw NotFoundException("id not found")
+
+    fun stop(id: Long): RouteInstanceResponse {
+        val instance = this.findById(id)
+        if (instance.endDate != null) throw UnauthorizedAccessException("Unauthorized access")
+        instance.endDate = Timestamp.valueOf(LocalDateTime.now())
+        return instancaNaLinijaRepository.save(instance).let { dtoMapper.toRouteInstanceResponse(it) }
+    }
+
+    fun getById(id: Long): RouteInstanceResponse {
+        val ri = this.findById(id)
+        val korisnik = this.authService.getAuthenticatedUser()
+        if (korisnik.id != ri.vozac.vraboten.korisnik.id) throw UnauthorizedAccessException("Unauthorized access")
+        return dtoMapper.toRouteInstanceResponse(this.findById(id))
+    }
+
+    fun getForStation(stationId: Long): List<RouteInstanceResponse> {
+        val station = postojkaRepository.findByIdOrNull(stationId) ?: throw NotFoundException("Station not found")
+        // find all route instances heading to the given station
+        val routeInstanceIds = instancaNaLinijaRepository.findIncomingRouteInstancesForStation(station.id)
+        val routeInstances = instancaNaLinijaRepository.findAllById(routeInstanceIds)
+        return routeInstances.map { dtoMapper.toRouteInstanceResponse(it) }
+    }
+
+    fun getAll(): List<RouteInstanceResponse> =
+        instancaNaLinijaRepository.findAllByEndDateIsNull().map { dtoMapper.toRouteInstanceResponse(it) }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/StationService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/StationService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/StationService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,40 @@
+package mk.ukim.finki.busngobackend.service
+
+import mk.ukim.finki.busngobackend.domain.entities.Postojka
+import mk.ukim.finki.busngobackend.domain.entities.PostojkaNaLinija
+import mk.ukim.finki.busngobackend.repository.LinijaRepository
+import mk.ukim.finki.busngobackend.repository.PostojkaNaLinijaRepository
+import mk.ukim.finki.busngobackend.repository.PostojkaRepository
+import mk.ukim.finki.busngobackend.repository.PravecRepository
+import mk.ukim.finki.busngobackend.service.exceptions.NotFoundException
+import org.springframework.data.repository.findByIdOrNull
+import org.springframework.stereotype.Service
+
+@Service
+class StationService(
+    private val postojkaRepository: PostojkaRepository,
+    private val postojkaNaLinijaRepository: PostojkaNaLinijaRepository,
+    private val linijaRepository: LinijaRepository,
+    private val pravecRepository: PravecRepository,
+) {
+    fun findStationsByLineId(lineId: Int): List<PostojkaNaLinija> {
+        val linija = linijaRepository.findByIdOrNull(lineId) ?: throw NotFoundException("Linija not found")
+        return this.postojkaNaLinijaRepository.findByLinija(linija)
+    }
+
+    fun findStationsByLineIdAndDirectionId(
+        lineId: Int,
+        directionId: Long?,
+    ): List<PostojkaNaLinija> {
+        if (directionId == null) {
+            return this.findStationsByLineId(lineId)
+        }
+
+        val linija = linijaRepository.findByIdOrNull(lineId) ?: throw NotFoundException("Linija not found")
+        val pravec = pravecRepository.findByIdOrNull(directionId) ?: throw NotFoundException("Pravec not found")
+
+        return postojkaNaLinijaRepository.findByLinijaAndPravec(linija, pravec)
+    }
+
+    fun getAll(): List<Postojka> = this.postojkaRepository.findAll()
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/WebSocketService.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/WebSocketService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/WebSocketService.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,16 @@
+package mk.ukim.finki.busngobackend.service
+
+import org.springframework.messaging.simp.SimpMessagingTemplate
+import org.springframework.stereotype.Service
+
+@Service
+class WebSocketService(
+    private val messagingTemplate: SimpMessagingTemplate,
+) {
+    fun sendMessage(
+        topicSuffix: String,
+        message: String,
+    ) {
+        messagingTemplate.convertAndSend("/topic/$topicSuffix", message)
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/exceptions/NotFoundException.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/exceptions/NotFoundException.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/exceptions/NotFoundException.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,5 @@
+package mk.ukim.finki.busngobackend.service.exceptions
+
+class NotFoundException(
+    message: String,
+) : RuntimeException(message)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/exceptions/UnauthorizedAccessException.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/exceptions/UnauthorizedAccessException.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/service/exceptions/UnauthorizedAccessException.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,5 @@
+package mk.ukim.finki.busngobackend.service.exceptions
+
+class UnauthorizedAccessException(
+    s: String,
+) : RuntimeException(s)
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/simulator/DummyDataPopulator.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/simulator/DummyDataPopulator.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/simulator/DummyDataPopulator.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,208 @@
+package mk.ukim.finki.busngobackend.simulator
+
+import mk.ukim.finki.busngobackend.domain.entities.*
+import mk.ukim.finki.busngobackend.domain.enums.BiletEnum
+import mk.ukim.finki.busngobackend.domain.enums.VozenjeStatus
+import mk.ukim.finki.busngobackend.repository.*
+import org.springframework.stereotype.Service
+import java.sql.Timestamp
+import java.time.LocalDateTime
+import java.time.ZoneId
+import java.util.concurrent.ThreadLocalRandom
+
+@Service
+class DummyDataPopulator(
+    private val linijaRepository: LinijaRepository,
+    private val vozacRepository: VozacRepository,
+    private val avtobusRepository: AvtobusRepository,
+    private val linijaPravecRepository: LinijaPravecRepository,
+    private val postojkaNaLinijaRepository: PostojkaNaLinijaRepository,
+    private val instancaNaLinijaRepository: InstancaNaLinijaRepository,
+    private val instancaNaLinijaPostojkaNaLinijaRepository: InstancaNaLinijaPostojkaNaLinijaRepository,
+    private val vozenjeRepository: VozenjeRepository,
+    private val patnikRepository: PatnikRepository,
+    private val biletRepository: BiletRepository,
+    private val tipbiletRepository: TipbiletRepository,
+    private val kaznaRepository: KaznaRepository,
+    private val kontrolaRepository: KontrolaRepository,
+    private val kondukterRepository: KondukterRepository,
+    private val kaznaZaNeregistriranRepository: KaznaZaNeregistriranRepository,
+) {
+    fun populateFines() {
+        val routeInstances = instancaNaLinijaRepository.findAll()
+        val kondukters = kondukterRepository.findAll()
+
+        routeInstances.forEach { inl ->
+            run {
+                val kondukter = kondukters.random()
+                val kontrola =
+                    kontrolaRepository.save(
+                        Kontrola(
+                            id = 0L,
+                            instancaNaLinija = inl,
+                            dateCreated = getRandomTimestamp(inl.startDate.toLocalDateTime(), inl.endDate!!.toLocalDateTime()),
+                            kondukter = kondukter,
+                        ),
+                    )
+                for (i in 0..5) {
+                    val kazna =
+                        kaznaRepository.save(
+                            Kazna(
+                                id = 0L,
+                                iznos = 1000.0,
+                                dokument = "DOC " + LocalDateTime.now().toString(),
+                                kontrola = kontrola,
+                                dateCreated = getRandomTimestamp(kontrola.dateCreated.toLocalDateTime(), inl.endDate!!.toLocalDateTime()),
+                                datePayed = getRandomTimestamp(kontrola.dateCreated.toLocalDateTime(), inl.endDate!!.toLocalDateTime()),
+                                kondukter = kondukter,
+                                plateno = true,
+                            ),
+                        )
+
+                    kaznaZaNeregistriranRepository.save(
+                        KaznaZaNeregistriran(
+                            id = 0L,
+                            kazna = kazna,
+                            ime = "Test Ime" + LocalDateTime.now().toString(),
+                            adresa = "Test Adres" + LocalDateTime.now().toString(),
+                            telefon = "+38975123456",
+                        ),
+                    )
+                }
+            }
+        }
+    }
+
+    fun populateCommutes() {
+        val routeInstances = instancaNaLinijaRepository.findAll()
+        routeInstances.forEach { instancaNaLinija ->
+            run {
+                val patnik = patnikRepository.findAll().random()
+                val startDate =
+                    getRandomTimestamp(
+                        instancaNaLinija.startDate.toLocalDateTime(),
+                        instancaNaLinija.endDate!!.toLocalDateTime(),
+                    )
+                val bilet =
+                    biletRepository.findAll().randomOrNull() ?: biletRepository.save(
+                        Bilet(
+                            id = 0L,
+                            datumKupuvanje = startDate,
+                            datumAktivacija = startDate,
+                            status = BiletEnum.ACTIVE,
+                            patnik = patnik,
+                            tip = tipbiletRepository.findAll().random(),
+                        ),
+                    )
+                val postojkaNaLinijaStart =
+                    instancaNaLinijaPostojkaNaLinijaRepository.findByInstancaNaLinijaAndTimestampNearestTo(
+                        instancaNaLinija.id,
+                        startDate,
+                    )
+                vozenjeRepository.save(
+                    Vozenje(
+                        id = 0L,
+                        startDate = startDate,
+                        instancaNaLinija = instancaNaLinija,
+                        postojkaNaLinijaStart =
+                            postojkaNaLinijaStart?.postojkaNaLinija
+                                ?: postojkaNaLinijaRepository.findByLinija(instancaNaLinija.linija).random(),
+                        patnik = patnik,
+                        endDate = instancaNaLinija.endDate,
+                        bilet = bilet,
+                        status = VozenjeStatus.FINISHED,
+                    ),
+                )
+            }
+        }
+    }
+
+    fun populateRouteInstances() {
+        val lines = linijaRepository.findAll()
+        val drivers = vozacRepository.findAll()
+        val buses = avtobusRepository.findAll()
+
+        lines.forEach { randomLine ->
+            run {
+                val directionsForRandomLine = linijaPravecRepository.findAllByLinija(randomLine).map { it.pravec }
+                for (i in 0..10) {
+                    val randomDirection = directionsForRandomLine.random()
+                    val startDate =
+                        getRandomTimestamp(
+                            start = LocalDateTime.of(2020, 1, 1, 0, 0),
+                            end = LocalDateTime.now(),
+                        )
+
+                    val instance =
+                        instancaNaLinijaRepository.save(
+                            InstancaNaLinija(
+                                startDate = startDate,
+                                endDate = null,
+                                id = 0L,
+                                vozac = drivers.random(),
+                                linija = randomLine,
+                                avtobus = buses.random(),
+                                pravec = randomDirection,
+                            ),
+                        )
+
+                    val stationsForRandomLine =
+                        postojkaNaLinijaRepository
+                            .findByLinijaAndPravec(
+                                randomLine,
+                                randomDirection,
+                            ).sortedBy { it.redenBroj }
+                    var lastTime = Timestamp.valueOf(LocalDateTime.now())
+                    stationsForRandomLine.forEach { station ->
+                        run {
+                            if (station.redenBroj.toInt() == 1) {
+                                val start = instance.startDate.toLocalDateTime().plusMinutes(1)
+                                lastTime = getRandomTimestamp(start = start, end = start.plusMinutes(12))
+                            } else {
+                                val start = lastTime.toLocalDateTime().plusMinutes(1)
+                                lastTime = getRandomTimestamp(start = start, end = start.plusMinutes(12))
+                            }
+                            instancaNaLinijaPostojkaNaLinijaRepository.save(
+                                InstancaNaLinijaPostojkaNaLinija(
+                                    id = 0L,
+                                    instancaNaLinija = instance,
+                                    postojkaNaLinija = station,
+                                    timestamp = lastTime,
+                                ),
+                            )
+                        }
+                    }
+                    instance.endDate = lastTime
+                    instancaNaLinijaRepository.save(instance)
+                }
+            }
+        }
+    }
+
+    private fun getRandomTimestamp(
+        start: LocalDateTime,
+        end: LocalDateTime,
+    ): Timestamp {
+        // Define the start time (January 1, 2020, 00:00:00)
+//        val start = LocalDateTime.of(2020, 1, 1, 0, 0)
+        // Get the current time
+//        val end = LocalDateTime.now()
+
+        // Convert LocalDateTime to milliseconds since epoch
+        val startMillis = start.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
+        val endMillis = end.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
+
+        // Generate a random time between startMillis and endMillis
+        val randomMillis = ThreadLocalRandom.current().nextLong(startMillis, endMillis)
+
+        // Convert milliseconds back to LocalDateTime
+        val randomLocalDateTime =
+            LocalDateTime.ofInstant(
+                java.time.Instant.ofEpochMilli(randomMillis),
+                ZoneId.systemDefault(),
+            )
+
+        // Convert LocalDateTime to Timestamp
+        return Timestamp.valueOf(randomLocalDateTime)
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/simulator/RouteInstanceSimulator.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/simulator/RouteInstanceSimulator.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/simulator/RouteInstanceSimulator.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,43 @@
+package mk.ukim.finki.busngobackend.simulator
+
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.runBlocking
+import mk.ukim.finki.busngobackend.domain.entities.InstancaNaLinija
+import mk.ukim.finki.busngobackend.domain.entities.PostojkaNaLinija
+import mk.ukim.finki.busngobackend.domain.helpers.RouteInstanceOnStation
+import mk.ukim.finki.busngobackend.events.RouteInstanceOnStationEvent
+import mk.ukim.finki.busngobackend.events.StopRouteInstanceEvent
+import org.springframework.context.ApplicationEventPublisher
+import org.springframework.scheduling.annotation.Async
+import org.springframework.stereotype.Component
+import java.sql.Timestamp
+import java.time.LocalDateTime
+
+@Component
+class RouteInstanceSimulator(
+    private val eventPublisher: ApplicationEventPublisher,
+) {
+    @Async
+    fun simulate(
+        instance: InstancaNaLinija,
+        stations: List<PostojkaNaLinija>,
+    ) {
+        runBlocking {
+            stations.forEach { station ->
+                delay(1000 * 20)
+                eventPublisher.publishEvent(
+                    RouteInstanceOnStationEvent(
+                        RouteInstanceOnStation(
+                            instance,
+                            station,
+                            Timestamp.valueOf(
+                                LocalDateTime.now(),
+                            ),
+                        ),
+                    ),
+                )
+            }
+        }
+        eventPublisher.publishEvent(StopRouteInstanceEvent(instance))
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/tasks/RefreshMaterializedViews.kt
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/tasks/RefreshMaterializedViews.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/kotlin/mk/ukim/finki/busngobackend/tasks/RefreshMaterializedViews.kt	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,18 @@
+package mk.ukim.finki.busngobackend.tasks
+
+import mk.ukim.finki.busngobackend.service.MaterializedViewService
+import org.springframework.scheduling.annotation.Scheduled
+import org.springframework.stereotype.Service
+
+@Service
+class RefreshMaterializedViews(
+    private val materializedViewService: MaterializedViewService,
+) {
+    @Scheduled(fixedRateString = "\${materialized.view.refresh.rate}")
+    fun refreshMaterializedViewTask() {
+        materializedViewService.refreshAverageTimeDiffs()
+        materializedViewService.refreshCommutesByHour()
+        materializedViewService.refreshFinesPerLine()
+        materializedViewService.refreshTotalIncome()
+    }
+}
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/application.properties
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/application.properties	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/application.properties	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,23 @@
+spring.application.name=bus-n-go-backend
+spring.datasource.url=jdbc:postgresql://localhost:5432/db_202324z_va_prj_busngo
+spring.datasource.username=db_202324z_va_prj_busngo_owner
+spring.datasource.password=d9f924580e7
+#spring.datasource.url=jdbc:postgresql://localhost:5432/bus_go
+#spring.datasource.username=postgres
+#spring.datasource.password=admin
+spring.datasource.driver-class-name=org.postgresql.Driver
+
+
+spring.datasource.hikari.connection-timeout=20000
+spring.datasource.hikari.maximum-pool-size=5
+
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
+spring.jpa.properties.hibernate.jdbc.non_contextual_creation=true
+spring.jpa.properties.hibernate.default_schema=project
+
+spring.jpa.hibernate.ddl-auto=validate
+spring.jpa.show-sql=true
+
+materialized.view.refresh.rate=43200000
+ #43200000 #12 hours
+spring.flyway.default-schema=project
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/R__materialized_views.sql
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/R__materialized_views.sql	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/R__materialized_views.sql	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,156 @@
+set search_path = project;
+
+drop materialized view if exists avg_time_diffs;
+CREATE MATERIALIZED VIEW avg_time_diffs AS
+WITH ordered_instanca AS (SELECT ilpl.instanca_na_linija_id,
+                                 ilpl.postojka_na_linija_id,
+                                 pnl.reden_broj,
+                                 ilpl.timestamp
+                          FROM project.instanca_na_linija_postojka_na_linija ilpl
+                                   JOIN
+                               project.postojka_na_linija pnl ON ilpl.postojka_na_linija_id = pnl.id
+                          ORDER BY ilpl.instanca_na_linija_id,
+                                   pnl.reden_broj),
+     time_differences AS (SELECT o1.instanca_na_linija_id,
+                                 o1.postojka_na_linija_id                          AS start_station_id,
+                                 o1.timestamp                                      AS start_time,
+                                 o2.postojka_na_linija_id                          AS end_station_id,
+                                 o2.timestamp                                      AS end_time,
+                                 EXTRACT(EPOCH FROM (o2.timestamp - o1.timestamp)) AS time_diff
+                          FROM ordered_instanca o1
+                                   JOIN
+                               ordered_instanca o2 ON o1.instanca_na_linija_id = o2.instanca_na_linija_id
+                          WHERE o1.reden_broj + 1 = o2.reden_broj)
+SELECT
+    row_number() over () as id,
+    start_station_id,
+       end_station_id,
+       AVG(time_diff)::double precision AS avg_time_diff_seconds
+FROM time_differences
+GROUP BY start_station_id,
+         end_station_id
+ORDER BY start_station_id,
+         end_station_id;
+
+create unique index avg_time_diffs_index on avg_time_diffs (id);
+
+drop materialized view if exists kazna_po_linija;
+create materialized view kazna_po_linija as
+select row_number() over () as id, l.id as line_id, count(l.id)
+from project.linija l
+         left join project.instanca_na_linija inl on l.id = inl.linija_id
+         left join project.kontrola k on inl.id = k.instanca_na_linija_id
+         left join project.kazna kaz on k.id = kaz.kontrola_id
+where extract(year from kaz.date_created) = extract(year from now())
+group by l.id
+order by count(l.id) desc;
+
+create unique index index_kazna_po_linija on kazna_po_linija(id);
+
+drop materialized view if exists most_busy_part_of_the_day;
+create materialized view most_busy_part_of_the_day as
+select row_number() over () as id, id as linija_id, interval_1h, count(id || '-' || interval_1h) broj_pati
+from (select li.id,
+             (to_char(extract(hour from v.start_date), '00') || ':00 -' || to_char(extract(hour from (v.start_date
+                 + '1 hours'::interval))::int, '00') || ':00') as interval_1h
+      from project.linija li
+               left join project.instanca_na_linija inl on li.id = inl.linija_id
+               left join project.vozenje v on inl.id = v.instanca_na_linija_id
+      where v.start_date between (make_date(extract(year from (now()))::int, 1, 1)) and (make_date(extract(year from (now()))::int, 12, 31))) as hours
+group by id, interval_1h
+order by interval_1h desc;
+
+create unique index index_most_busy_part_of_the_day on most_busy_part_of_the_day(id);
+
+drop materialized view if exists commutes_by_line;
+create materialized view commutes_by_line as
+select row_number() over () as id, l.id as linija_id, count(v.id)
+from project.linija l
+         left join project.instanca_na_linija inl on l.id = inl.linija_id
+         left join project.vozenje v on inl.id = v.instanca_na_linija_id
+where v.start_date between date_trunc('year', now()) and date_trunc('month', date_trunc('year', now())+ interval '7 months')
+group by l.id;
+
+
+drop materialized view if exists number_passengers_per_line_and_station;
+create materialized view number_passengers_per_line_and_station as
+select row_number() over () as id, p.id as station_id, l.id as line_id, count(p.id)
+from project.postojka p
+         join project.postojka_na_linija pnl on p.id = pnl.postojka_id
+         join project.vozenje v on pnl.id = v.postojka_na_linija_start_id
+         join project.patnik pat on v.patnik_id = pat.id
+         join project.linija l on pnl.linija_id = l.id
+where v.start_date between (make_date(extract(year from (now() - '1 years'::interval))::int, 4, 1)) and (make_date(extract(year from (now() - '1 years'::interval))::int, 6, 30))
+group by p.id, l.id
+order by count(p.id) desc;
+
+
+drop materialized view if exists ticket_sales;
+create materialized view ticket_sales as
+select row_number() over () as id, filtered.tip_id, filtered.interval_1h, filtered.broj_pati
+from (select filter.tip_id, interval_1h, count(tip_id || '-' || interval_1h) broj_pati
+      from (select *,
+                   (to_char(extract(hour from b.datum_kupuvanje), '00') || ':00 -' ||
+                    to_char(extract(hour from (b.datum_kupuvanje + '1 hours'::interval))::int, '00') ||
+                    ':00') as interval_1h
+            from project.tipbilet t
+                     left join project.bilet b on t.id = b.tip_id
+--     where  b.datum_kupuvanje between (make_date(extract(year from (now() - '1 years'::interval))::int, 1, 1)) and (make_date(extract(year from (now() - '1 years'::interval))::int, 12, 31))
+
+           ) as filter
+      group by filter.tip_id, interval_1h) filtered
+where broj_pati = (select max(filtered.broj_pati)
+                   from (select filter.tip_id, interval_1h, count(tip_id || '-' || interval_1h) broj_pati
+                         from (select *,
+                                      (to_char(extract(hour from b.datum_kupuvanje), '00') || ':00 -' ||
+                                       to_char(extract(hour from (b.datum_kupuvanje + '1 hours'::interval))::int,
+                                               '00') ||
+                                       ':00') as interval_1h
+                               from project.tipbilet t
+                                        left join project.bilet b on t.id = b.tip_id
+--     where  b.datum_kupuvanje between (make_date(extract(year from (now() - '1 years'::interval))::int, 1, 1)) and (make_date(extract(year from (now() - '1 years'::interval))::int, 12, 31))
+
+                              ) as filter
+                         group by filter.tip_id, interval_1h) filtered)
+  and tip_id in (select id
+                 from tipbilet
+                 where ime in ('Hourly', 'Daily'));
+
+
+
+drop materialized view if exists total_income;
+create materialized view total_income as
+WITH kazna_sum AS (
+    SELECT
+        EXTRACT(YEAR FROM k.date_payed) AS year,
+        SUM(k.iznos) AS sum_kz
+    FROM
+        project.kazna k
+    WHERE
+        k.plateno = TRUE
+    GROUP BY
+        EXTRACT(YEAR FROM k.date_payed)
+),
+     bilet_sum AS (
+         SELECT
+             EXTRACT(YEAR FROM b.datum_kupuvanje) AS year,
+             SUM(tb.cena) AS sum_b
+         FROM
+             project.bilet b
+                 JOIN tipbilet tb ON tb.id = b.tip_id
+         GROUP BY
+             EXTRACT(YEAR FROM b.datum_kupuvanje)
+     )
+SELECT
+    row_number() over () as id,
+    COALESCE(k.year, b.year)::text AS year,
+    COALESCE(sum_kz, 0) as fines_income,
+    COALESCE(sum_b, 0) as ticket_income,
+    COALESCE(sum_kz, 0) + COALESCE(sum_b, 0) AS total_income
+FROM
+    kazna_sum k
+        FULL OUTER JOIN bilet_sum b ON k.year = b.year
+ORDER BY
+    year desc;
+
+create unique index index_total_income on total_income(id);
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/R__triggers_for_start_commute.sql
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/R__triggers_for_start_commute.sql	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/R__triggers_for_start_commute.sql	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,49 @@
+set search_path = project;
+
+create or replace function check_expiry_date() returns trigger
+as
+    $$
+    begin
+        if exists(
+            select 1
+            from project.vozenje v
+            where v.patnik_id = new.patnik_id and v.end_date is null
+        ) then
+            update project.vozenje set end_date = now(), status = 'FINISHED' where id in (select v.id
+                                                                                  from project.vozenje v
+                                                                                  where v.patnik_id = new.patnik_id and v.end_date is null);
+        end if;
+
+        if exists(
+            select 1
+            from project.bilet
+            where id = new.bilet_id and datum_aktivacija is null
+        ) then
+            update project.bilet set datum_aktivacija = now(), status = 'ACTIVE' where id = new.bilet_id;
+        end if;
+
+        if exists(
+            select 1
+            from project.bilet b
+            join project.tipbilet tb on b.tip_id = tb.id
+            where b.id = new.bilet_id and ((b.datum_aktivacija + (tb.trajnost || ' milliseconds')::interval) < now())
+        ) then
+            update project.bilet set status = 'EXPIRED' where id = new.bilet_id;
+            end if;
+
+        if exists(
+            select 1
+            from project.bilet b
+                     join project.tipbilet tb on b.tip_id = tb.id
+            where b.id = new.bilet_id and ((b.datum_aktivacija + (tb.trajnost || ' milliseconds')::interval) < now())
+        ) then
+            RAISE exception 'Ticket is expired';
+        end if;
+        return new;
+    end;
+    $$ language plpgsql;
+
+create or replace trigger check_validity_of_ticket
+    before insert on vozenje
+    for each row
+    execute function check_expiry_date();
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/V1.1__data_init.sql
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/V1.1__data_init.sql	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/V1.1__data_init.sql	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,269 @@
+set search_path = project;
+
+INSERT INTO Korisnik (is_admin, adresa, email, ime, lozinka, telefon) VALUES
+                                                                          (true, 'Bulevar Partizanski Odredi 45, Skopje', 'admin@example.com', 'Nikola Stojanovski', 'admin_password', '070123456'),
+                                                                          (false, 'Ulica Makedonija 12, Skopje', 'user1@example.com', 'Elena Petrovska', 'user1_password', '071234567'),
+                                                                          (false, 'Bulevar Sveti Kliment Ohridski 23, Skopje', 'user2@example.com', 'Marija Trajkovska', 'user2_password', '072345678'),
+                                                                          (false, 'Ulica Vasil Glavinov 10, Skopje', 'user3@example.com', 'Ivana Risteska', 'user3_password', '073456789'),
+                                                                          (false, 'Bulevar Krste Misirkov 56, Skopje', 'user4@example.com', 'Stefan Dimitrovski', 'user4_password', '074567890');
+INSERT INTO Role (description, name) VALUES
+                                         ('Administrator with full access rights', 'ROLE_ADMIN'),
+                                         ('Driver responsible for operating the bus', 'ROLE_DRIVER'),
+                                         ('Conductor responsible for checking tickets', 'ROLE_CONDUCTOR'),
+                                         ('Commuter using the public transport services', 'ROLE_PASSENGER');
+-- Nikola Stojanovski (Admin)
+INSERT INTO Korisnik_Role (korisnik_id, role_id) VALUES
+    (1, 2),
+    (1, 3),
+    (1, 4),
+    (1, 1); -- Admin role
+
+-- Elena Petrovska (Commuter)
+INSERT INTO Korisnik_Role (korisnik_id, role_id) VALUES
+    (2, 4); -- Commuter role
+
+-- Marija Trajkovska (Driver)
+INSERT INTO Korisnik_Role (korisnik_id, role_id) VALUES
+    (3, 2); -- Driver role
+
+-- Ivana Risteska (Conductor)
+INSERT INTO Korisnik_Role (korisnik_id, role_id) VALUES
+    (4, 3); -- Conductor role
+
+-- Stefan Dimitrovski (Commuter)
+INSERT INTO Korisnik_Role (korisnik_id, role_id) VALUES
+    (5, 4); -- Commuter role
+
+-- Elena Petrovska (Commuter)
+INSERT INTO Patnik (korisnik_id) VALUES
+    (2);
+
+-- Stefan Dimitrovski (Commuter)
+INSERT INTO Patnik (korisnik_id) VALUES
+    (5);
+
+-- Nikola Stojanovski (Admin)
+INSERT INTO Patnik (korisnik_id) VALUES
+    (1); -- Assuming Nikola Stojanovski has vraboten_id 1
+
+-- Nikola Stojanovski (Admin)
+INSERT INTO Vraboten (datum_na_vrabotuvanje, datum_prekin_vrabotuvanje, plata, korisnik_id) VALUES
+    ('2020-01-01', NULL, 60000, 1);
+
+-- Marija Trajkovska (Driver)
+INSERT INTO Vraboten (datum_na_vrabotuvanje, datum_prekin_vrabotuvanje, plata, korisnik_id) VALUES
+    ('2021-05-15', NULL, 35000, 3);
+
+-- Ivana Risteska (Conductor)
+INSERT INTO Vraboten (datum_na_vrabotuvanje, datum_prekin_vrabotuvanje, plata, korisnik_id) VALUES
+    ('2022-03-20', NULL, 30000, 4);
+
+-- Marija Trajkovska (Driver)
+INSERT INTO Vozac (vraboten_id) VALUES
+    (2); -- Assuming Marija Trajkovska has vraboten_id 2
+
+-- Nikola Stojanovski (Admin)
+INSERT INTO Vozac (vraboten_id) VALUES
+    (1); -- Assuming Nikola Stojanovski has vraboten_id 1
+
+-- Insert employees into the Kondukter table
+
+-- Ivana Risteska (Conductor)
+INSERT INTO Kondukter (vraboten_id) VALUES
+    (3); -- Assuming Ivana Risteska has vraboten_id 3
+
+-- Nikola Stojanovski (Admin)
+INSERT INTO Kondukter (vraboten_id) VALUES
+    (1); -- Assuming Nikola Stojanovski has vraboten_id 1
+
+INSERT INTO Avtobus (broj_sedishta, registracija, seriski_broj) VALUES
+                                                                    (50, 'SK-1234-AB', 'SN-000001'),
+                                                                    (45, 'SK-2345-BC', 'SN-000002'),
+                                                                    (50, 'SK-3456-CD', 'SN-000003'),
+                                                                    (40, 'SK-4567-DE', 'SN-000004'),
+                                                                    (50, 'SK-5678-EF', 'SN-000005'),
+                                                                    (55, 'SK-6789-FG', 'SN-000006'),
+                                                                    (50, 'SK-7890-GH', 'SN-000007'),
+                                                                    (45, 'SK-8901-HI', 'SN-000008'),
+                                                                    (50, 'SK-9012-IJ', 'SN-000009'),
+                                                                    (40, 'SK-0123-JK', 'SN-000010'),
+                                                                    (50, 'SK-1234-KL', 'SN-000011'),
+                                                                    (55, 'SK-2345-LM', 'SN-000012'),
+                                                                    (50, 'SK-3456-MN', 'SN-000013'),
+                                                                    (45, 'SK-4567-NO', 'SN-000014'),
+                                                                    (50, 'SK-5678-OP', 'SN-000015'),
+                                                                    (40, 'SK-6789-PQ', 'SN-000016'),
+                                                                    (50, 'SK-7890-QR', 'SN-000017'),
+                                                                    (55, 'SK-8901-RS', 'SN-000018'),
+                                                                    (50, 'SK-9012-ST', 'SN-000019'),
+                                                                    (45, 'SK-0123-TU', 'SN-000020');
+
+INSERT INTO Linija (ime) VALUES
+                                     ('Line 1'),
+                                     ('Line 2'),
+                                     ('Line 3'),
+                                     ('Line 4'),
+                                     ('Line 5'),
+                                     ('Line 6'),
+                                     ('Line 7'),
+                                     ('Line 8'),
+                                     ('Line 9'),
+                                     ('Line 10');
+
+INSERT INTO Pravec (pravec, opis) VALUES
+                                      ('Skopje - Tetovo', 'Skopje to Tetovo'),
+                                      ('Tetovo - Skopje', 'Tetovo to Skopje'),
+                                      ('Skopje - Ohrid', 'Skopje to Ohrid'),
+                                      ('Ohrid - Skopje', 'Ohrid to Skopje'),
+                                      ('Skopje - Bitola', 'Skopje to Bitola'),
+                                      ('Bitola - Skopje', 'Bitola to Skopje'),
+                                      ('Skopje - Kumanovo', 'Skopje to Kumanovo'),
+                                      ('Kumanovo - Skopje', 'Kumanovo to Skopje'),
+                                      ('Skopje - Strumica', 'Skopje to Strumica'),
+                                      ('Strumica - Skopje', 'Strumica to Skopje'),
+                                      ('Skopje - Veles', 'Skopje to Veles'),
+                                      ('Veles - Skopje', 'Veles to Skopje'),
+                                      ('Skopje - Prilep', 'Skopje to Prilep'),
+                                      ('Prilep - Skopje', 'Prilep to Skopje'),
+                                      ('Skopje - Gostivar', 'Skopje to Gostivar'),
+                                      ('Gostivar - Skopje', 'Gostivar to Skopje'),
+                                      ('Skopje - Stip', 'Skopje to Stip'),
+                                      ('Stip - Skopje', 'Stip to Skopje'),
+                                      ('Skopje - Kavadarci', 'Skopje to Kavadarci'),
+                                      ('Kavadarci - Skopje', 'Kavadarci to Skopje');
+
+-- Line 1: Skopje - Tetovo
+INSERT INTO linija_pravec (pravec_id, linija_id) VALUES
+                                                     (1, 1), -- Skopje to Tetovo
+                                                     (2, 1); -- Tetovo to Skopje
+
+-- Line 2: Skopje - Ohrid
+INSERT INTO linija_pravec (pravec_id, linija_id) VALUES
+                                                     (3, 2), -- Skopje to Ohrid
+                                                     (4, 2); -- Ohrid to Skopje
+
+-- Line 3: Skopje - Bitola
+INSERT INTO linija_pravec (pravec_id, linija_id) VALUES
+                                                     (5, 3), -- Skopje to Bitola
+                                                     (6, 3); -- Bitola to Skopje
+
+-- Line 4: Skopje - Kumanovo
+INSERT INTO linija_pravec (pravec_id, linija_id) VALUES
+                                                     (7, 4), -- Skopje to Kumanovo
+                                                     (8, 4); -- Kumanovo to Skopje
+
+-- Line 5: Skopje - Strumica
+INSERT INTO linija_pravec (pravec_id, linija_id) VALUES
+                                                     (9, 5), -- Skopje to Strumica
+                                                     (10, 5); -- Strumica to Skopje
+
+-- Line 6: Skopje - Veles
+INSERT INTO linija_pravec (pravec_id, linija_id) VALUES
+                                                     (11, 6), -- Skopje to Veles
+                                                     (12, 6); -- Veles to Skopje
+
+-- Line 7: Skopje - Prilep
+INSERT INTO linija_pravec (pravec_id, linija_id) VALUES
+                                                     (13, 7), -- Skopje to Prilep
+                                                     (14, 7); -- Prilep to Skopje
+
+-- Line 8: Skopje - Gostivar
+INSERT INTO linija_pravec (pravec_id, linija_id) VALUES
+                                                     (15, 8), -- Skopje to Gostivar
+                                                     (16, 8); -- Gostivar to Skopje
+
+-- Line 9: Skopje - Stip
+INSERT INTO linija_pravec (pravec_id, linija_id) VALUES
+                                                     (17, 9), -- Skopje to Stip
+                                                     (18, 9); -- Stip to Skopje
+
+-- Line 10: Skopje - Kavadarci
+INSERT INTO linija_pravec (pravec_id, linija_id) VALUES
+                                                     (19, 10), -- Skopje to Kavadarci
+                                                     (20, 10); -- Kavadarci to Skopje
+
+INSERT INTO Instanca_Na_Linija (linija_id, avtobus_id, start_date, end_date, vozac_id)
+VALUES
+-- Line 1: Skopje - Tetovo
+(1, 1, '2024-06-24 08:00:00', '2024-06-24 09:00:00', 1),
+(1, 1, '2024-06-24 09:00:00', '2024-06-24 10:00:00', 1),
+(1, 1, '2024-06-24 10:00:00', '2024-06-24 11:00:00', 1),
+(1, 1, '2024-06-24 11:00:00', '2024-06-24 12:00:00', 1),
+(1, 1, '2024-06-24 12:00:00', '2024-06-24 13:00:00', 1);
+
+
+-- Insert stops from Skopje to Tetovo
+INSERT INTO Postojka (lat, lon, ime, opis) VALUES
+                                               (41.9981, 21.4254, 'Skopje', 'Capital city of North Macedonia'),
+                                               (41.9643, 21.6228, 'Gazi Baba', 'Municipality near Skopje'),
+                                               (42.0264, 21.5957, 'Tetovo', 'City in western North Macedonia');
+
+-- Insert stops from Tetovo to Skopje
+INSERT INTO Postojka (lat, lon, ime, opis) VALUES
+                                               (42.0264, 21.5957, 'Tetovo', 'City in western North Macedonia'),
+                                               (41.9643, 21.6228, 'Gazi Baba', 'Municipality near Skopje'),
+                                               (41.9981, 21.4254, 'Skopje', 'Capital city of North Macedonia');
+
+-- Additional stops for Skopje to Tetovo
+INSERT INTO Postojka (lat, lon, ime, opis) VALUES
+                                               (41.9808, 21.4631, 'Butel', 'Municipality in Skopje'),
+                                               (42.0035, 21.4701, 'Kisela Voda', 'Municipality in Skopje'),
+                                               (41.9866, 21.5666, 'Gostivar', 'City in western North Macedonia'),
+                                               (41.9764, 21.6060, 'Zelino', 'Village near Tetovo'),
+                                               (41.9939, 21.6481, 'Tetovo Bus Station', 'Central bus station in Tetovo'),
+                                               (41.9861, 21.5705, 'Gostivar Train Station', 'Train station in Gostivar'),
+                                               (42.0081, 21.4500, 'Skopje University', 'University campus in Skopje'),
+                                               (42.0070, 21.4421, 'Kapishtec', 'Neighborhood in Skopje'),
+                                               (41.9794, 21.4604, 'Skopje City Mall', 'Shopping mall in Skopje');
+
+-- Additional stops for Tetovo to Skopje
+INSERT INTO Postojka (lat, lon, ime, opis) VALUES
+                                               (41.9839, 21.4647, 'Butel', 'Municipality in Skopje'),
+                                               (41.9934, 21.4752, 'Kisela Voda', 'Municipality in Skopje'),
+                                               (41.9901, 21.5804, 'Gostivar', 'City in western North Macedonia'),
+                                               (41.9798, 21.6093, 'Zelino', 'Village near Tetovo'),
+                                               (41.9997, 21.6543, 'Tetovo Bus Station', 'Central bus station in Tetovo'),
+                                               (41.9930, 21.5741, 'Gostivar Train Station', 'Train station in Gostivar'),
+                                               (42.0132, 21.4578, 'Skopje University', 'University campus in Skopje'),
+                                               (42.0111, 21.4491, 'Kapishtec', 'Neighborhood in Skopje'),
+                                               (41.9822, 21.4679, 'Skopje City Mall', 'Shopping mall in Skopje');
+
+-- Insert stops for Line 1 (Skopje - Tetovo)
+INSERT INTO Postojka_Na_Linija (linija_id, postojka_id, reden_broj, pravec_id) VALUES
+                                                                        (1, 1, 1, 1),   -- Skopje
+                                                                        (1, 2, 2, 1),   -- Gazi Baba
+                                                                        (1, 8, 3, 1),   -- Skopje University
+                                                                        (1, 7, 4, 1),   -- Kapishtec
+                                                                        (1, 3, 5, 1),   -- Tetovo
+                                                                        (1, 6, 6, 1),   -- Gostivar Train Station
+                                                                        (1, 5, 7, 1),   -- Gostivar
+                                                                        (1, 4, 8, 1),   -- Zelino
+                                                                        (1, 9, 9, 1),   -- Tetovo Bus Station
+                                                                        (1, 10, 10, 1); -- Butel
+
+-- Insert stops for Line 1 (Tetovo to Skopje)
+INSERT INTO Postojka_Na_Linija (linija_id, postojka_id, reden_broj, pravec_id) VALUES
+                                                                        (1, 10, 1, 2),   -- Butel
+                                                                        (1, 9, 2, 2),    -- Tetovo Bus Station
+                                                                        (1, 4, 3, 2),    -- Zelino
+                                                                        (1, 5, 4, 2),    -- Gostivar
+                                                                        (1, 6, 5, 2),    -- Gostivar Train Station
+                                                                        (1, 3, 6, 2),    -- Tetovo
+                                                                        (1, 7, 7, 2),    -- Kapishtec
+                                                                        (1, 8, 8, 2),    -- Skopje University
+                                                                        (1, 2, 9, 2),    -- Gazi Baba
+                                                                        (1, 1, 10, 2);   -- Skopje
+
+
+-- Insert ticket types
+INSERT INTO TipBilet (cena, trajnost, ime) VALUES
+                                               (50.00, 3600000, 'Hourly'),    -- Hourly ticket (1 hour = 3,600,000 milliseconds)
+                                               (150.00, 86400000, 'Daily'),   -- Daily ticket (1 day = 86,400,000 milliseconds)
+                                               (1000.00, 2592000000, 'Monthly'),  -- Monthly ticket (30 days = 2,592,000,000 milliseconds)
+                                               (10000.00, 31536000000, 'Yearly'); -- Yearly ticket (365 days = 31,536,000,000 milliseconds)
+
+-- Add tickets for commuter with patnik_id 1
+INSERT INTO Bilet (datum_kupuvanje, patnik_id, tip_id, status) VALUES
+                                                                   ('2024-06-24 10:00:00', 1, 1, 'INACTIVE'),  -- Hourly ticket (ID 1)
+                                                                   ('2024-06-23 15:00:00', 1, 2, 'ACTIVE');    -- Daily ticket (ID 2)
+
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/V1.2__additional_data.sql
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/V1.2__additional_data.sql	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/V1.2__additional_data.sql	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,126 @@
+set search_path = project;
+
+-- Insert stops from Skopje to Ohrid
+INSERT INTO Postojka (lat, lon, ime, opis) VALUES
+                                               (41.9981, 21.4254, 'Skopje', 'Capital city of North Macedonia'),
+                                               (41.8770, 21.0720, 'Tetovo', 'City in western North Macedonia'),
+                                               (41.7150, 20.9620, 'Gostivar', 'City in western North Macedonia'),
+                                               (41.5886, 20.6305, 'Kicevo', 'City in western North Macedonia'),
+                                               (41.5120, 20.2690, 'Struga', 'City in southwestern North Macedonia'),
+                                               (41.1136, 20.8016, 'Ohrid', 'City in southwestern North Macedonia');
+-- Insert stops for Line 2 (Skopje - Ohrid)
+INSERT INTO Postojka_Na_Linija (linija_id, postojka_id, reden_broj, pravec_id) VALUES
+                                                                                   (2, 25, 1, 3),  -- Skopje
+                                                                                   (2, 26, 2, 3),  -- Tetovo
+                                                                                   (2, 27, 3, 3),  -- Gostivar
+                                                                                   (2, 28, 4, 3),  -- Kicevo
+                                                                                   (2, 29, 5, 3),  -- Struga
+                                                                                   (2, 30, 6, 3);  -- Ohrid
+
+-- Insert stops from Ohrid to Skopje
+INSERT INTO Postojka (lat, lon, ime, opis) VALUES
+                                               (41.1136, 20.8016, 'Ohrid', 'City in southwestern North Macedonia'),
+                                               (41.5910, 20.6520, 'Debarca', 'Municipality near Ohrid'),
+                                               (41.6340, 20.8940, 'Makedonski Brod', 'Town in central North Macedonia'),
+                                               (41.6980, 21.1290, 'Samokov', 'Village in western North Macedonia'),
+                                               (41.7820, 21.3340, 'Tetovo', 'City in western North Macedonia'),
+                                               (41.9981, 21.4254, 'Skopje', 'Capital city of North Macedonia');
+-- Insert stops for Line 2 (Ohrid - Skopje)
+INSERT INTO Postojka_Na_Linija (linija_id, postojka_id, reden_broj, pravec_id) VALUES
+                                                                                   (2, 31, 1, 4),  -- Ohrid
+                                                                                   (2, 32, 2, 4),  -- Debarca
+                                                                                   (2, 33, 3, 4),  -- Makedonski Brod
+                                                                                   (2, 34, 4, 4),  -- Samokov
+                                                                                   (2, 35, 5, 4),  -- Tetovo
+                                                                                   (2, 36, 6, 4);  -- Skopje
+-- Insert stops from Skopje to Bitola
+INSERT INTO Postojka (lat, lon, ime, opis) VALUES
+                                               (41.9981, 21.4254, 'Skopje', 'Capital city of North Macedonia'),    -- id 37
+                                               (41.9202, 21.5511, 'Veles', 'City in central North Macedonia'),     -- id 38
+                                               (41.7361, 21.7744, 'Prilep', 'City in southern North Macedonia'),   -- id 39
+                                               (41.6130, 21.5523, 'Krushevo', 'Town in southern North Macedonia'), -- id 40
+                                               (41.4442, 21.2761, 'Bitola', 'City in southwestern North Macedonia'); -- id 41
+-- Insert stops for Line 3 (Skopje - Bitola)
+INSERT INTO Postojka_Na_Linija (linija_id, postojka_id, reden_broj, pravec_id) VALUES
+                                                                                   (3, 37, 1, 5),  -- Skopje
+                                                                                   (3, 38, 2, 5),  -- Veles
+                                                                                   (3, 39, 3, 5),  -- Prilep
+                                                                                   (3, 40, 4, 5),  -- Krushevo
+                                                                                   (3, 41, 5, 5);  -- Bitola
+-- Insert stops from Bitola to Skopje
+INSERT INTO Postojka (lat, lon, ime, opis) VALUES
+                                               (41.4442, 21.2761, 'Bitola', 'City in southwestern North Macedonia'), -- id 42
+                                               (41.6130, 21.5523, 'Krushevo', 'Town in southern North Macedonia'),   -- id 43
+                                               (41.7361, 21.7744, 'Prilep', 'City in southern North Macedonia'),     -- id 44
+                                               (41.9202, 21.5511, 'Veles', 'City in central North Macedonia'),       -- id 45
+                                               (41.9981, 21.4254, 'Skopje', 'Capital city of North Macedonia');      -- id 46
+-- Insert stops for Line 3 (Bitola - Skopje)
+INSERT INTO Postojka_Na_Linija (linija_id, postojka_id, reden_broj, pravec_id) VALUES
+                                                                                   (3, 42, 1, 6),  -- Bitola
+                                                                                   (3, 43, 2, 6),  -- Krushevo
+                                                                                   (3, 44, 3, 6),  -- Prilep
+                                                                                   (3, 45, 4, 6),  -- Veles
+                                                                                   (3, 46, 5, 6);  -- Skopje
+
+-- Insert stops from Skopje to Kumanovo
+INSERT INTO Postojka (lat, lon, ime, opis) VALUES
+                                               (41.9981, 21.4254, 'Skopje', 'Capital city of North Macedonia'),       -- id 47
+                                               (41.9945, 21.5770, 'Butel', 'Municipality in Skopje'),                 -- id 48
+                                               (42.0153, 21.7000, 'Aracinovo', 'Village near Skopje'),                -- id 49
+                                               (42.0892, 21.7184, 'Lipkovo', 'Village in northeastern North Macedonia'), -- id 50
+                                               (42.1322, 21.7144, 'Kumanovo', 'City in northeastern North Macedonia'); -- id 51
+
+-- Insert stops for Line 4 (Skopje - Kumanovo)
+INSERT INTO Postojka_Na_Linija (linija_id, postojka_id, reden_broj, pravec_id) VALUES
+                                                                                   (4, 47, 1, 7),  -- Skopje
+                                                                                   (4, 48, 2, 7),  -- Butel
+                                                                                   (4, 49, 3, 7),  -- Aracinovo
+                                                                                   (4, 50, 4, 7),  -- Lipkovo
+                                                                                   (4, 51, 5, 7);  -- Kumanovo
+-- Insert stops from Kumanovo to Skopje
+INSERT INTO Postojka (lat, lon, ime, opis) VALUES
+                                               (42.1322, 21.7144, 'Kumanovo', 'City in northeastern North Macedonia'), -- id 52
+                                               (42.0892, 21.7184, 'Lipkovo', 'Village in northeastern North Macedonia'), -- id 53
+                                               (42.0153, 21.7000, 'Aracinovo', 'Village near Skopje'),                -- id 54
+                                               (41.9945, 21.5770, 'Butel', 'Municipality in Skopje'),                 -- id 55
+                                               (41.9981, 21.4254, 'Skopje', 'Capital city of North Macedonia');       -- id 56
+-- Insert stops for Line 4 (Kumanovo - Skopje)
+INSERT INTO Postojka_Na_Linija (linija_id, postojka_id, reden_broj, pravec_id) VALUES
+                                                                                   (4, 52, 1, 8),  -- Kumanovo
+                                                                                   (4, 53, 2, 8),  -- Lipkovo
+                                                                                   (4, 54, 3, 8),  -- Aracinovo
+                                                                                   (4, 55, 4, 8),  -- Butel
+                                                                                   (4, 56, 5, 8);  -- Skopje
+-- Insert stops from Skopje to Strumica
+INSERT INTO Postojka (lat, lon, ime, opis) VALUES
+                                               (41.9981, 21.4254, 'Skopje', 'Capital city of North Macedonia'),               -- id 57
+                                               (41.8833, 21.5065, 'Katlanovo', 'Village near Skopje'),                        -- id 58
+                                               (41.7466, 21.3600, 'Veles Rest Area', 'Rest area near Veles'),                 -- id 59
+                                               (41.6165, 22.1796, 'Demir Kapija', 'Town in central North Macedonia'),         -- id 60
+                                               (41.3472, 22.5533, 'Radovish', 'Town in southeastern North Macedonia'),        -- id 61
+                                               (41.4378, 22.6431, 'Strumica', 'City in southeastern North Macedonia');        -- id 62
+-- Insert stops for Line 5 (Skopje - Strumica)
+INSERT INTO Postojka_Na_Linija (linija_id, postojka_id, reden_broj, pravec_id) VALUES
+                                                                                   (5, 57, 1, 9),  -- Skopje
+                                                                                   (5, 58, 2, 9),  -- Katlanovo
+                                                                                   (5, 59, 3, 9),  -- Veles Rest Area
+                                                                                   (5, 60, 4, 9),  -- Demir Kapija
+                                                                                   (5, 61, 5, 9),  -- Radovish
+                                                                                   (5, 62, 6, 9);  -- Strumica
+-- Insert stops from Strumica to Skopje
+INSERT INTO Postojka (lat, lon, ime, opis) VALUES
+                                               (41.4380, 22.6429, 'Strumica', 'City in southeastern North Macedonia'),       -- id 63
+                                               (41.3480, 22.5525, 'Radovish Park', 'Park in Radovish'),                      -- id 64
+                                               (41.6170, 22.1802, 'Demir Kapija South', 'Southern part of Demir Kapija'),    -- id 65
+                                               (41.7470, 21.3610, 'Veles South Rest Area', 'Rest area south of Veles'),      -- id 66
+                                               (41.8840, 21.5070, 'Katlanovo East', 'Eastern part of Katlanovo'),            -- id 67
+                                               (41.9985, 21.4260, 'Skopje Center', 'Center of Skopje');                      -- id 68
+-- Insert stops for Line 5 (Strumica - Skopje)
+INSERT INTO Postojka_Na_Linija (linija_id, postojka_id, reden_broj, pravec_id) VALUES
+                                                                                   (5, 63, 1, 10),  -- Strumica
+                                                                                   (5, 64, 2, 10),  -- Radovish Park
+                                                                                   (5, 65, 3, 10),  -- Demir Kapija South
+                                                                                   (5, 66, 4, 10),  -- Veles South Rest Area
+                                                                                   (5, 67, 5, 10),  -- Katlanovo East
+                                                                                   (5, 68, 6, 10);  -- Skopje Center
+
Index: bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/V1__init_db.sql
===================================================================
--- bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/V1__init_db.sql	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
+++ bus-n-go-pavel-216049/bus-n-go-backend/src/main/resources/db/migration/V1__init_db.sql	(revision baf4cc4b66f1d62e9dc9c2e71bcc078c9c3956a3)
@@ -0,0 +1,238 @@
+set search_path = project;
+
+drop table if exists Se_simnuva_na;
+drop table if exists KaznaZaRegistriran;
+drop table if exists KaznaZaNeregistriran;
+drop table if exists Kazna;
+drop table if exists Kontroli;
+drop table if exists Vozenje;
+drop table if exists Bilet;
+drop table if exists TipBilet;
+drop table if exists PostojkaNaLinija;
+drop table if exists Postojka;
+drop table if exists Mesto;
+drop table if exists InstancaNaLinija;
+drop table if exists Linija;
+drop table if exists Avtobus;
+drop table if exists Kondukter;
+drop table if exists Vozac;
+drop table if exists Vraboten;
+drop table if exists Patnik;
+drop table if exists KorisnikRole;
+drop table if exists Korisnik;
+drop table if exists Role;
+
+create table Korisnik(
+                         is_admin boolean,
+                         id bigserial primary key,
+                         adresa character varying(255),
+                         email character varying(255),
+                         ime character varying(255),
+                         lozinka character varying(255),
+                         telefon character varying(255)
+);
+
+create table Role (
+                      id bigserial primary key,
+                      description character varying(255),
+                      name character varying(255)
+);
+
+create table Korisnik_Role (
+                               id bigserial primary key,
+                               korisnik_id bigint,
+                               role_id bigint,
+                               foreign key (role_id) references role (id),
+                               foreign key (korisnik_id) references korisnik (id)
+);
+
+create table Patnik(
+                       id bigserial primary key,
+                       korisnik_id bigint,
+                       foreign key (korisnik_id) references korisnik (id)
+);
+--	*k_id referencira od Korisnik(k_id)
+
+
+create table Vraboten(
+                         datum_na_vrabotuvanje date,
+                         datum_prekin_vrabotuvanje date,
+                         plata double precision,
+                         id bigserial primary key,
+                         korisnik_id bigint,
+                         foreign key (korisnik_id) references korisnik (id)
+);
+--	*k_id referencira od Korisnik(k_id)
+
+
+create table Vozac(
+                      id bigserial primary key,
+                      vraboten_id bigint,
+                      foreign key (vraboten_id) references vraboten (id)
+);
+--	*k_id referencira od Korisnik(k_id)
+
+create table Kondukter(
+                          id bigserial primary key,
+                          vraboten_id bigint,
+                          foreign key (vraboten_id) references vraboten (id)
+);
+--	*k_id referencira od Korisnik(k_id)
+
+create table Avtobus(
+                        broj_sedishta smallint,
+                        id bigserial primary key,
+                        registracija character varying(255),
+                        seriski_broj character varying(255)
+);
+
+create table Linija(
+                       id serial primary key,
+                       ime character varying(255)
+);
+
+create table Pravec (
+                      id bigserial primary key,
+                      pravec character varying(255),
+                      opis character varying(255)
+);
+
+create table linija_pravec (
+                      id bigserial primary key,
+                      pravec_id bigint,
+                      linija_id integer,
+                      foreign key (pravec_id) references Pravec (id),
+                      foreign key (linija_id) references Linija (id)
+);
+
+create table Instanca_Na_Linija (
+                                  linija_id integer,
+                                  pravec_id bigint,
+                                  avtobus_id bigint,
+                                  end_date timestamp(6) without time zone,
+                                  id bigserial primary key,
+                                  start_date timestamp(6) without time zone,
+                                  vozac_id bigint,
+                                  foreign key (avtobus_id) references avtobus (id),
+                                  foreign key (linija_id) references linija (id),
+                                  foreign key (vozac_id) references vozac (id)
+);
+--	*k_id referencira od Korisnik(k_id)
+--	^a_registracija referncira od Avtobus(a_registracija)
+--	#li_id referencira od Linija(li_id)
+
+create table Postojka (
+                          id serial primary key,
+                          lat double precision,
+                          lon double precision,
+                          ime character varying(255),
+                          opis character varying(255)
+);
+--*m_id referncira od Mesto(m_id)
+
+
+create table Postojka_Na_Linija (
+                                  linija_id integer,
+                                  postojka_id integer,
+                                  pravec_id bigint,
+                                  reden_broj smallint,
+                                  id bigserial primary key,
+                                  foreign key (postojka_id) references postojka (id),
+                                  foreign key (linija_id) references linija (id)
+);
+--	*li_id referencira od Linija(li_id)
+--	^p_id referencira od Postojka(p_id)
+
+create table instanca_na_linija_postojka_na_linija (
+                                  id bigserial primary key,
+                                  instanca_na_linija_id bigint not null,
+                                  postojka_na_linija_id bigint not null,
+                                  timestamp timestamp not null,
+                                  foreign key (instanca_na_linija_id) references instanca_na_linija(id),
+                                  foreign key (postojka_na_linija_id) references postojka_na_linija(id)
+);
+
+create table TipBilet (
+                          cena real,
+                          id bigserial primary key,
+                          trajnost bigint,
+                          ime character varying(255)
+);
+
+
+
+create table Bilet (
+                       datum_kupuvanje timestamp(6) without time zone,
+                       datum_aktivacija timestamp(6) without time zone,
+                       id bigserial primary key,
+                       patnik_id bigint,
+                       tip_id bigint,
+                       status character varying(255),
+                       foreign key (patnik_id) references patnik (id),
+                       foreign key (tip_id) references tipbilet (id)
+);
+
+
+create table Vozenje (
+                         bilet_id bigint,
+                         end_date timestamp(6) without time zone,
+                         id bigserial primary key,
+                         instanca_na_linija_id bigint,
+                         patnik_id bigint,
+                         postojka_na_linija_start_id bigint,
+                         start_date timestamp(6) without time zone,
+                         status character varying(255),
+                         foreign key (patnik_id) references patnik (id),
+                         foreign key (bilet_id) references bilet (id),
+                         foreign key (instanca_na_linija_id) references instanca_na_linija (id),
+                         foreign key (postojka_na_linija_start_id) references postojka_na_linija (id)
+);
+
+
+create table Kontrola (
+                          date_created timestamp(6) without time zone,
+                          id bigserial primary key,
+                          instanca_na_linija_id bigint,
+                          kondukter_id bigint,
+                          foreign key (instanca_na_linija_id) references instanca_na_linija (id),
+                          foreign key (kondukter_id) references kondukter (id)
+);
+
+create table Kazna (
+                       iznos double precision,
+                       plateno boolean,
+                       date_created timestamp(6) without time zone,
+                       date_payed timestamp(6) without time zone,
+                       id bigserial primary key,
+                       kondukter_id bigint,
+                       kontrola_id bigint,
+                       dokument character varying(255),
+                       foreign key (kondukter_id) references Kondukter (id),
+                       foreign key (kontrola_id) references kontrola (id)
+);
+
+
+create table Kazna_Za_Registriran(
+                                   id bigserial primary key,
+                                   kazna_id bigint,
+                                   patnik_id bigint,
+                                   foreign key (patnik_id) references patnik (id),
+                                   foreign key (kazna_id) references kazna (id)
+);
+
+create table kazna_za_neregistriran(
+                                     id bigserial primary key,
+                                     kazna_id bigint,
+                                     adresa character varying(255),
+                                     ime character varying(255),
+                                     telefon character varying(255),
+                                     foreign key (kazna_id) references kazna (id)
+);
+
+create table se_simnuva_na (
+                               id bigserial primary key,
+                               postojka_na_linija_id bigint,
+                               vozenje_id bigint,
+                               foreign key (vozenje_id) references vozenje (id),
+                               foreign key (postojka_na_linija_id) references postojka_na_linija (id)
+);
