getting ready for docker deployment

This commit is contained in:
2025-12-02 17:18:26 -05:00
parent 346ccc3813
commit 9fabf30406
5 changed files with 305 additions and 297 deletions

63
docker-compose.yaml Normal file
View File

@@ -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

View File

@@ -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<List<User>> getAllUsers() {
List<User> data = repo.findAll();
return ResponseEntity.ok(data);
}
@GetMapping("/api/getAllUsersById/{id}")
public ResponseEntity<User> getAllStatesById(@PathVariable Integer id) {
return repo.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping("/api/addUser")
public ResponseEntity<User> createUser(@RequestBody User item) {
User created = usersService.save(item);
return ResponseEntity.status(HttpStatus.CREATED).body(created);
}
@DeleteMapping("/api/deleteUser/{id}")
public ResponseEntity<Void> deleteItem(@PathVariable Integer id) {
return usersService.findById(id)
.map(item -> {
usersService.deleteById(id);
return ResponseEntity.noContent().<Void>build();
})
.orElse(ResponseEntity.notFound().build());
}
}

View File

@@ -4,233 +4,67 @@ import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.Table; import jakarta.persistence.Table;
import jakarta.validation.constraints.NotNull;
import org.hibernate.annotations.ColumnDefault; import org.hibernate.annotations.ColumnDefault;
import java.time.Instant; import java.time.OffsetDateTime;
import java.time.LocalDate;
import java.util.UUID; import java.util.UUID;
@Entity @Entity
@Table(name = "users") @Table(name = "users")
public class User { public class User {
@Id @Id
@Column(name = "id", nullable = false, length = 21) @NotNull
private String id; @Column(name = "id", nullable = false)
private Integer 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;
@NotNull
@ColumnDefault("gen_random_uuid()") @ColumnDefault("gen_random_uuid()")
@Column(name = "uuid") @Column(name = "uuid", nullable = false)
private UUID uuid; private UUID uuid;
@Column(name = "discord_id") @NotNull
private String discordId; @Column(name = "email", nullable = false, length = Integer.MAX_VALUE)
private String email;
@Column(name = "hashed_password") @NotNull
private String hashedPassword; @Column(name = "password_hash", nullable = false, length = Integer.MAX_VALUE)
private String passwordHash;
@Column(name = "avatar") @Column(name = "display_name", length = Integer.MAX_VALUE)
private String avatar; private String displayName;
@Column(name = "stripe_subscription_id", length = 191) @NotNull
private String stripeSubscriptionId; @ColumnDefault("'USER'")
@Column(name = "role", nullable = false, length = Integer.MAX_VALUE)
private String role;
@Column(name = "stripe_price_id", length = 191) @NotNull
private String stripePriceId; @ColumnDefault("true")
@Column(name = "is_active", nullable = false)
private Boolean isActive = false;
@Column(name = "stripe_customer_id", length = 191) @NotNull
private String stripeCustomerId; @ColumnDefault("now()")
@Column(name = "created_at", nullable = false)
private OffsetDateTime createdAt;
@Column(name = "stripe_current_period_end") @NotNull
private Instant stripeCurrentPeriodEnd; @ColumnDefault("now()")
@Column(name = "updated_at", nullable = false)
private OffsetDateTime updatedAt;
public String getId() { @Column(name = "deleted_at")
private OffsetDateTime deletedAt;
public Integer getId() {
return id; return id;
} }
public void setId(String id) { public void setId(Integer id) {
this.id = 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() { public UUID getUuid() {
return uuid; return uuid;
} }
@@ -239,60 +73,68 @@ public class User {
this.uuid = uuid; this.uuid = uuid;
} }
public String getDiscordId() { public String getEmail() {
return discordId; return email;
} }
public void setDiscordId(String discordId) { public void setEmail(String email) {
this.discordId = discordId; this.email = email;
} }
public String getHashedPassword() { public String getPasswordHash() {
return hashedPassword; return passwordHash;
} }
public void setHashedPassword(String hashedPassword) { public void setPasswordHash(String passwordHash) {
this.hashedPassword = hashedPassword; this.passwordHash = passwordHash;
} }
public String getAvatar() { public String getDisplayName() {
return avatar; return displayName;
} }
public void setAvatar(String avatar) { public void setDisplayName(String displayName) {
this.avatar = avatar; this.displayName = displayName;
} }
public String getStripeSubscriptionId() { public String getRole() {
return stripeSubscriptionId; return role;
} }
public void setStripeSubscriptionId(String stripeSubscriptionId) { public void setRole(String role) {
this.stripeSubscriptionId = stripeSubscriptionId; this.role = role;
} }
public String getStripePriceId() { public Boolean getIsActive() {
return stripePriceId; return isActive;
} }
public void setStripePriceId(String stripePriceId) { public void setIsActive(Boolean isActive) {
this.stripePriceId = stripePriceId; this.isActive = isActive;
} }
public String getStripeCustomerId() { public OffsetDateTime getCreatedAt() {
return stripeCustomerId; return createdAt;
} }
public void setStripeCustomerId(String stripeCustomerId) { public void setCreatedAt(OffsetDateTime createdAt) {
this.stripeCustomerId = stripeCustomerId; this.createdAt = createdAt;
} }
public Instant getStripeCurrentPeriodEnd() { public OffsetDateTime getUpdatedAt() {
return stripeCurrentPeriodEnd; return updatedAt;
} }
public void setStripeCurrentPeriodEnd(Instant stripeCurrentPeriodEnd) { public void setUpdatedAt(OffsetDateTime updatedAt) {
this.stripeCurrentPeriodEnd = stripeCurrentPeriodEnd; this.updatedAt = updatedAt;
}
public OffsetDateTime getDeletedAt() {
return deletedAt;
}
public void setDeletedAt(OffsetDateTime deletedAt) {
this.deletedAt = deletedAt;
} }
} }

View File

@@ -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<User> findAll();
Optional<User> findById(Integer id);
User save(User item);
void deleteById(Integer id);
}

View File

@@ -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<User> findAll() {
return repo.findAll();
}
@Override
public Optional<User> findById(Integer id) {
return repo.findById(id);
}
@Override
public User save(User item) {
return null;
}
@Override
public void deleteById(Integer id) {
deleteById(id);
}
}