first barebones project structure

This commit is contained in:
2025-10-01 18:27:57 +02:00
parent 66f9d8e22a
commit 5c588c24ba
13 changed files with 258 additions and 35 deletions

38
pom.xml
View File

@@ -31,25 +31,43 @@
<java.version>25</java.version>
</properties>
<dependencies>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-jdbc</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-jpa</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>annotationProcessor</scope>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>

View File

@@ -2,8 +2,6 @@ package de.pnreichmuth.timekeep_backend;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class TimekeepBackendApplication {

View File

@@ -0,0 +1,21 @@
package de.pnreichmuth.timekeep_backend;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.security.config.annotation.web.builders.HttpSecurity;
//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
//import org.springframework.security.web.SecurityFilterChain;
//
//
//@Configuration
////@EnableWebSecurity
//public class TimekeepBackendSecurityConfig {
// @Bean
// public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// http.authorizeHttpRequests((authorize) ->
// authorize.
// anyRequest().authenticated());
// return http.build();
// }
//
//}

View File

@@ -1,23 +0,0 @@
package de.pnreichmuth.timekeep_backend;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
public class TimekeepRestController {
public TimekeepRestController() {
}
@GetMapping("/time/test")
public Testclass timeEndpoint(){
return new Testclass("TEST",1);
}
@GetMapping("/time")
public Date getTime(){
return new Date();
}
}

View File

@@ -0,0 +1,34 @@
package de.pnreichmuth.timekeep_backend.controllers;
import de.pnreichmuth.timekeep_backend.entities.Team;
import de.pnreichmuth.timekeep_backend.repositories.TeamRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/teams")
public class TeamRestController {
@Autowired
private TeamRepository teamRepository;
@PostMapping("createTeam")
public Team createTeam(){
Team team = new Team();
teamRepository.save(team);
return team;
}
@GetMapping("all")
public List<Team> findAllTeams(){
return teamRepository.findAll();
}
@DeleteMapping("all")
public void deleteAllTeams(){
teamRepository.deleteAll();
}
}

View File

@@ -0,0 +1,20 @@
package de.pnreichmuth.timekeep_backend.entities;
import jakarta.persistence.*;
import lombok.*;
import java.util.UUID;
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Racer{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
private String name;
private Boolean isFirstSemester;
private String phoneNumber;
}

View File

@@ -0,0 +1,22 @@
package de.pnreichmuth.timekeep_backend.entities;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Getter;
import java.util.UUID;
@Entity
@Getter
public class Station {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
private String name;
private String location;
private String passwordHash;
}

View File

@@ -0,0 +1,71 @@
package de.pnreichmuth.timekeep_backend.entities;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;
@Entity
@Getter
public class Team {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
@Setter
private String teamName;
private boolean firstSemesterTeam;
@OneToMany(cascade = CascadeType.ALL)
private Map<String, Racer> members;
@OneToMany(cascade = CascadeType.ALL)
private Map<String, Station> passedStations;
public Team(){
this.teamName = "Team-" + UUID.randomUUID();
this.firstSemesterTeam = true;
this.members = new HashMap<>(4);
this.passedStations = new HashMap<>();
}
/**
* Treat this team as a team of first semester students, if at least 50% of its members are in the first semester
*/
private void checkFirstSemesterTeam(){
long erstiCount = members.entrySet().stream()
.filter(
e -> e.getValue().getIsFirstSemester()
).count();
double percentFirstSemester = erstiCount /(double)members.size();
this.firstSemesterTeam = percentFirstSemester >= 0.5;
}
/**
* Adds a new member to the team and checks whether the team still qualifies as a first semester team
* @param newMember the Racer object to be added to the team
*/
public void addMember(Racer newMember){
this.members.put(newMember.getName(), newMember);
this.checkFirstSemesterTeam();
}
/**
* Removes a member from the team by name
* @param name the name of the member to be removed
*/
public void removeMember(String name){
this.members.remove(name);
this.checkFirstSemesterTeam();
}
}

View File

@@ -0,0 +1,14 @@
package de.pnreichmuth.timekeep_backend.repositories;
import de.pnreichmuth.timekeep_backend.entities.Racer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.UUID;
@Repository
public interface RacerRepository extends JpaRepository<Racer, UUID> {
Racer findByName(String name);
List<Racer> findAllByName(String name);
}

View File

@@ -0,0 +1,14 @@
package de.pnreichmuth.timekeep_backend.repositories;
import de.pnreichmuth.timekeep_backend.entities.Station;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.UUID;
@Repository
public interface StationRepository extends JpaRepository<Station, UUID> {
public Station findByLocation(String location);
public Station findByName(String name);
public Station findByPasswordHash(String passwordHash);
}

View File

@@ -0,0 +1,17 @@
package de.pnreichmuth.timekeep_backend.repositories;
import de.pnreichmuth.timekeep_backend.entities.Station;
import de.pnreichmuth.timekeep_backend.entities.Team;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.UUID;
@Repository
public interface TeamRepository extends JpaRepository<Team, UUID> {
Team getTeamById(UUID id);
Team getTeamByTeamName(String name);
List<Team> getTeamsByFirstSemesterTeamIsTrue();
List<Team> getTeamsByPassedStationsContains(Station station);
}

View File

@@ -1 +1,7 @@
spring.application.name=timekeep-backend
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/jpa
spring.datasource.username=myuser
spring.datasource.password=secret
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql= true

View File

@@ -0,0 +1,11 @@
services:
mysql:
container_name: 'jpa-mysql'
image: 'mysql:latest'
environment:
- 'MYSQL_DATABASE=jpa'
- 'MYSQL_PASSWORD=secret'
- 'MYSQL_ROOT_PASSWORD=verysecret'
- 'MYSQL_USER=myuser'
ports:
- '3306:3306'