From 9fabf30406215f817e9d141a8e3aea3697516b56 Mon Sep 17 00:00:00 2001 From: Don Strawsburg Date: Tue, 2 Dec 2025 17:18:26 -0500 Subject: [PATCH] getting ready for docker deployment --- docker-compose.yaml | 63 +++ .../ballistic/controllers/UserController.java | 50 ++ .../group/goforward/ballistic/model/User.java | 436 ++++++------------ .../ballistic/services/UsersService.java | 16 + .../services/impl/UsersServiceImpl.java | 37 ++ 5 files changed, 305 insertions(+), 297 deletions(-) create mode 100644 docker-compose.yaml create mode 100644 src/main/java/group/goforward/ballistic/controllers/UserController.java create mode 100644 src/main/java/group/goforward/ballistic/services/UsersService.java create mode 100644 src/main/java/group/goforward/ballistic/services/impl/UsersServiceImpl.java diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..3495250 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,63 @@ +version: '3.8' + +services: + # --- 1. Spring API Service (Backend) --- + spring-api: + build: + context: ./backend # Path to your Spring project's root folder + dockerfile: Dockerfile # Assumes you have a Dockerfile in ./backend + container_name: spring-api + ports: + - "8080:8080" # Map host port 8080 to container port 8080 + environment: + # These environment variables link the API to the database service defined below + - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/mydatabase + - SPRING_DATASOURCE_USERNAME=myuser + - SPRING_DATASOURCE_PASSWORD=mypassword + depends_on: + - db + networks: + - app-network + + # --- 2. Next.js App Service (Frontend) --- + nextjs-app: + build: + context: ./frontend # Path to your Next.js project's root folder + dockerfile: Dockerfile # Assumes you have a Dockerfile in ./frontend + container_name: nextjs-app + ports: + - "3000:3000" # Map host port 3000 to container port 3000 + environment: + # This variable is crucial: Next.js needs the URL for the Spring API + # Use the Docker internal service name 'spring-api' and its port 8080 + - NEXT_PUBLIC_API_URL=http://spring-api:8080 + # For local testing, you might need the host IP for Next.js to call back + # - NEXT_PUBLIC_API_URL_LOCAL=http://localhost:8080 + depends_on: + - spring-api + networks: + - app-network + + # --- 3. PostgreSQL Database Service (Example Dependency) --- + db: + image: postgres:15-alpine # Lightweight and stable PostgreSQL image + container_name: postgres-db + environment: + - POSTGRES_DB=mydatabase + - POSTGRES_USER=myuser + - POSTGRES_PASSWORD=mypassword + volumes: + - postgres_data:/var/lib/postgresql/data # Persist the database data + ports: + - "5432:5432" # Optional: Map DB port for external access (e.g., DBeaver) + networks: + - app-network + +# --- Docker Volume for Persistent Data --- +volumes: + postgres_data: + +# --- Docker Network for Inter-Container Communication --- +networks: + app-network: + driver: bridge \ No newline at end of file diff --git a/src/main/java/group/goforward/ballistic/controllers/UserController.java b/src/main/java/group/goforward/ballistic/controllers/UserController.java new file mode 100644 index 0000000..b28ecc3 --- /dev/null +++ b/src/main/java/group/goforward/ballistic/controllers/UserController.java @@ -0,0 +1,50 @@ +package group.goforward.ballistic.controllers; + +import group.goforward.ballistic.model.User; +import group.goforward.ballistic.repos.UserRepository; +import group.goforward.ballistic.services.UsersService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +@RestController +@RequestMapping() +public class UserController { + @Autowired + private UserRepository repo; + @Autowired + private UsersService usersService; + + @GetMapping("/api/getAllUsers") + public ResponseEntity> getAllUsers() { + List data = repo.findAll(); + return ResponseEntity.ok(data); + } + + + @GetMapping("/api/getAllUsersById/{id}") + public ResponseEntity getAllStatesById(@PathVariable Integer id) { + return repo.findById(id) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + @PostMapping("/api/addUser") + public ResponseEntity createUser(@RequestBody User item) { + User created = usersService.save(item); + return ResponseEntity.status(HttpStatus.CREATED).body(created); + } + + @DeleteMapping("/api/deleteUser/{id}") + public ResponseEntity deleteItem(@PathVariable Integer id) { + return usersService.findById(id) + .map(item -> { + usersService.deleteById(id); + return ResponseEntity.noContent().build(); + }) + .orElse(ResponseEntity.notFound().build()); + } +} diff --git a/src/main/java/group/goforward/ballistic/model/User.java b/src/main/java/group/goforward/ballistic/model/User.java index ac49425..225798c 100644 --- a/src/main/java/group/goforward/ballistic/model/User.java +++ b/src/main/java/group/goforward/ballistic/model/User.java @@ -1,298 +1,140 @@ -package group.goforward.ballistic.model; - -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; -import org.hibernate.annotations.ColumnDefault; - -import java.time.Instant; -import java.time.LocalDate; -import java.util.UUID; - -@Entity -@Table(name = "users") -public class User { - @Id - @Column(name = "id", nullable = false, length = 21) - private String id; - - @Column(name = "name", length = Integer.MAX_VALUE) - private String name; - - @Column(name = "username", length = 50) - private String username; - - @Column(name = "email", nullable = false) - private String email; - - @Column(name = "first_name", length = 50) - private String firstName; - - @Column(name = "last_name", length = 50) - private String lastName; - - @Column(name = "full_name", length = 50) - private String fullName; - - @Column(name = "profile_picture") - private String profilePicture; - - @Column(name = "image", length = Integer.MAX_VALUE) - private String image; - - @Column(name = "date_of_birth") - private LocalDate dateOfBirth; - - @Column(name = "phone_number", length = 20) - private String phoneNumber; - - @ColumnDefault("CURRENT_TIMESTAMP") - @Column(name = "created_at") - private Instant createdAt; - - @ColumnDefault("CURRENT_TIMESTAMP") - @Column(name = "updated_at") - private Instant updatedAt; - - @ColumnDefault("false") - @Column(name = "is_admin") - private Boolean isAdmin; - - @Column(name = "last_login") - private Instant lastLogin; - - @ColumnDefault("false") - @Column(name = "email_verified", nullable = false) - private Boolean emailVerified = false; - - @ColumnDefault("'public'") - @Column(name = "build_privacy_setting", length = Integer.MAX_VALUE) - private String buildPrivacySetting; - - @ColumnDefault("gen_random_uuid()") - @Column(name = "uuid") - private UUID uuid; - - @Column(name = "discord_id") - private String discordId; - - @Column(name = "hashed_password") - private String hashedPassword; - - @Column(name = "avatar") - private String avatar; - - @Column(name = "stripe_subscription_id", length = 191) - private String stripeSubscriptionId; - - @Column(name = "stripe_price_id", length = 191) - private String stripePriceId; - - @Column(name = "stripe_customer_id", length = 191) - private String stripeCustomerId; - - @Column(name = "stripe_current_period_end") - private Instant stripeCurrentPeriodEnd; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getFullName() { - return fullName; - } - - public void setFullName(String fullName) { - this.fullName = fullName; - } - - public String getProfilePicture() { - return profilePicture; - } - - public void setProfilePicture(String profilePicture) { - this.profilePicture = profilePicture; - } - - public String getImage() { - return image; - } - - public void setImage(String image) { - this.image = image; - } - - public LocalDate getDateOfBirth() { - return dateOfBirth; - } - - public void setDateOfBirth(LocalDate dateOfBirth) { - this.dateOfBirth = dateOfBirth; - } - - public String getPhoneNumber() { - return phoneNumber; - } - - public void setPhoneNumber(String phoneNumber) { - this.phoneNumber = phoneNumber; - } - - public Instant getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Instant createdAt) { - this.createdAt = createdAt; - } - - public Instant getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(Instant updatedAt) { - this.updatedAt = updatedAt; - } - - public Boolean getIsAdmin() { - return isAdmin; - } - - public void setIsAdmin(Boolean isAdmin) { - this.isAdmin = isAdmin; - } - - public Instant getLastLogin() { - return lastLogin; - } - - public void setLastLogin(Instant lastLogin) { - this.lastLogin = lastLogin; - } - - public Boolean getEmailVerified() { - return emailVerified; - } - - public void setEmailVerified(Boolean emailVerified) { - this.emailVerified = emailVerified; - } - - public String getBuildPrivacySetting() { - return buildPrivacySetting; - } - - public void setBuildPrivacySetting(String buildPrivacySetting) { - this.buildPrivacySetting = buildPrivacySetting; - } - - public UUID getUuid() { - return uuid; - } - - public void setUuid(UUID uuid) { - this.uuid = uuid; - } - - public String getDiscordId() { - return discordId; - } - - public void setDiscordId(String discordId) { - this.discordId = discordId; - } - - public String getHashedPassword() { - return hashedPassword; - } - - public void setHashedPassword(String hashedPassword) { - this.hashedPassword = hashedPassword; - } - - public String getAvatar() { - return avatar; - } - - public void setAvatar(String avatar) { - this.avatar = avatar; - } - - public String getStripeSubscriptionId() { - return stripeSubscriptionId; - } - - public void setStripeSubscriptionId(String stripeSubscriptionId) { - this.stripeSubscriptionId = stripeSubscriptionId; - } - - public String getStripePriceId() { - return stripePriceId; - } - - public void setStripePriceId(String stripePriceId) { - this.stripePriceId = stripePriceId; - } - - public String getStripeCustomerId() { - return stripeCustomerId; - } - - public void setStripeCustomerId(String stripeCustomerId) { - this.stripeCustomerId = stripeCustomerId; - } - - public Instant getStripeCurrentPeriodEnd() { - return stripeCurrentPeriodEnd; - } - - public void setStripeCurrentPeriodEnd(Instant stripeCurrentPeriodEnd) { - this.stripeCurrentPeriodEnd = stripeCurrentPeriodEnd; - } - +package group.goforward.ballistic.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.validation.constraints.NotNull; +import org.hibernate.annotations.ColumnDefault; + +import java.time.OffsetDateTime; +import java.util.UUID; + +@Entity +@Table(name = "users") +public class User { + @Id + @NotNull + @Column(name = "id", nullable = false) + private Integer id; + + @NotNull + @ColumnDefault("gen_random_uuid()") + @Column(name = "uuid", nullable = false) + private UUID uuid; + + @NotNull + @Column(name = "email", nullable = false, length = Integer.MAX_VALUE) + private String email; + + @NotNull + @Column(name = "password_hash", nullable = false, length = Integer.MAX_VALUE) + private String passwordHash; + + @Column(name = "display_name", length = Integer.MAX_VALUE) + private String displayName; + + @NotNull + @ColumnDefault("'USER'") + @Column(name = "role", nullable = false, length = Integer.MAX_VALUE) + private String role; + + @NotNull + @ColumnDefault("true") + @Column(name = "is_active", nullable = false) + private Boolean isActive = false; + + @NotNull + @ColumnDefault("now()") + @Column(name = "created_at", nullable = false) + private OffsetDateTime createdAt; + + @NotNull + @ColumnDefault("now()") + @Column(name = "updated_at", nullable = false) + private OffsetDateTime updatedAt; + + @Column(name = "deleted_at") + private OffsetDateTime deletedAt; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public UUID getUuid() { + return uuid; + } + + public void setUuid(UUID uuid) { + this.uuid = uuid; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPasswordHash() { + return passwordHash; + } + + public void setPasswordHash(String passwordHash) { + this.passwordHash = passwordHash; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public Boolean getIsActive() { + return isActive; + } + + public void setIsActive(Boolean isActive) { + this.isActive = isActive; + } + + public OffsetDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(OffsetDateTime createdAt) { + this.createdAt = createdAt; + } + + public OffsetDateTime getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(OffsetDateTime updatedAt) { + this.updatedAt = updatedAt; + } + + public OffsetDateTime getDeletedAt() { + return deletedAt; + } + + public void setDeletedAt(OffsetDateTime deletedAt) { + this.deletedAt = deletedAt; + } + } \ No newline at end of file diff --git a/src/main/java/group/goforward/ballistic/services/UsersService.java b/src/main/java/group/goforward/ballistic/services/UsersService.java new file mode 100644 index 0000000..59ebe13 --- /dev/null +++ b/src/main/java/group/goforward/ballistic/services/UsersService.java @@ -0,0 +1,16 @@ +package group.goforward.ballistic.services; + +import group.goforward.ballistic.model.User; + +import java.util.List; +import java.util.Optional; + +public interface UsersService { + + List findAll(); + + Optional findById(Integer id); + + User save(User item); + void deleteById(Integer id); +} diff --git a/src/main/java/group/goforward/ballistic/services/impl/UsersServiceImpl.java b/src/main/java/group/goforward/ballistic/services/impl/UsersServiceImpl.java new file mode 100644 index 0000000..a3b1cf8 --- /dev/null +++ b/src/main/java/group/goforward/ballistic/services/impl/UsersServiceImpl.java @@ -0,0 +1,37 @@ +package group.goforward.ballistic.services.impl; + +import group.goforward.ballistic.model.User; +import group.goforward.ballistic.repos.UserRepository; +import group.goforward.ballistic.services.UsersService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class UsersServiceImpl implements UsersService { + + @Autowired + private UserRepository repo; + + @Override + public List findAll() { + return repo.findAll(); + } + + @Override + public Optional findById(Integer id) { + return repo.findById(id); + } + + @Override + public User save(User item) { + return null; + } + + @Override + public void deleteById(Integer id) { + deleteById(id); + } +}