diff --git a/Dockerfile b/Dockerfile
index 74fbcfb..d19c01a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,24 +1,28 @@
-FROM maven:3.9-eclipse-temurin-21 AS build
-
+FROM maven:3.9-eclipse-temurin-17 AS build
WORKDIR /app
-COPY . .
-# Compilar la aplicación sin ejecutar tests
-RUN mvn package -DskipTests
+# Copy project dependencies
+COPY pom.xml .
+COPY src ./src
-FROM registry.access.redhat.com/ubi8/openjdk-21-runtime:latest
+# Build the project
+RUN mvn clean package -DskipTests
+FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
-COPY --from=build /app/target/quarkus-app /app/
-# Puerto que expondrá la aplicación
+# Create uploads directory
+RUN mkdir -p /app/uploads
+
+# Copy built jar
+COPY --from=build /app/target/*.jar app.jar
+
+# Copy initial images
+COPY uploads /app/uploads
+
+# Setting environment variables
+ENV SPRING_PROFILES_ACTIVE=prod
+
EXPOSE 8080
-# Variables de entorno para configuración de DB y perfil
-ENV QUARKUS_PROFILE="prod" \
- QUARKUS_DATASOURCE_USERNAME=${DB_USERNAME} \
- QUARKUS_DATASOURCE_PASSWORD=${DB_PASSWORD} \
- QUARKUS_DATASOURCE_JDBC_URL=jdbc:postgresql://${POSTGRESSHOST}:${POSTGRESSPORT}/${POSTGRESSDATABASE}
-
-# Comando para iniciar la aplicación
-CMD ["java", "-Dquarkus.profile=${QUARKUS_PROFILE}", "-jar", "quarkus-run.jar"]
\ No newline at end of file
+ENTRYPOINT ["java", "-jar", "app.jar"]
\ No newline at end of file
diff --git a/README.md b/README.md
index 79cd792..5d0913b 100644
--- a/README.md
+++ b/README.md
@@ -1,93 +1,65 @@
-# gym-backend
+# Gym Backend (Spring Boot)
-This project uses Quarkus, the Supersonic Subatomic Java Framework.
+A Spring Boot backend application for a gym management system. This application provides RESTful APIs for managing users, gym classes and bookings.
-If you want to learn more about Quarkus, please visit its website: .
+## Requirements
-## Running the application in dev mode
+- Java 17 or higher
+- Maven 3.8+
+- PostgreSQL
-You can run your application in dev mode that enables live coding using:
+## Getting Started
-```shell script
-./mvnw quarkus:dev
+### Running Locally
+
+1. Clone the repository
+2. Configure PostgreSQL database (default credentials in application.properties)
+3. Run the application:
+
+```bash
+mvn spring-boot:run
```
-> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at .
+The application will start at http://localhost:8080
-## Packaging and running the application
+### Using Docker
-The application can be packaged using:
+1. Build the Docker image:
-```shell script
-./mvnw package
+```bash
+docker build -t gym-backend .
```
-It produces the `quarkus-run.jar` file in the `target/quarkus-app/` directory.
-Be aware that it’s not an _über-jar_ as the dependencies are copied into the `target/quarkus-app/lib/` directory.
+2. Run the container:
-The application is now runnable using `java -jar target/quarkus-app/quarkus-run.jar`.
-
-If you want to build an _über-jar_, execute the following command:
-
-```shell script
-./mvnw package -Dquarkus.package.jar.type=uber-jar
+```bash
+docker run -p 8080:8080 gym-backend
```
-The application, packaged as an _über-jar_, is now runnable using `java -jar target/*-runner.jar`.
+## API Endpoints
-## Creating a native executable
+### Users
-You can create a native executable using:
+- `GET /api/users`: Get all users
+- `GET /api/users/{id}`: Get user by ID
+- `POST /api/users`: Create new user
+- `PUT /api/users/{id}`: Update user
-```shell script
-./mvnw package -Dnative
-```
+### Gym Classes
-Or, if you don't have GraalVM installed, you can run the native executable build in a container using:
+- `GET /api/classes`: Get all classes
+- `GET /api/classes/{id}`: Get class by ID
+- `POST /api/classes`: Create new class
+- `PUT /api/classes/{id}`: Update class
+- `DELETE /api/classes/{id}`: Delete class
-```shell script
-./mvnw package -Dnative -Dquarkus.native.container-build=true
-```
+### Bookings
-You can then execute your native executable with: `./target/gym-backend-1.0.0-SNAPSHOT-runner`
+- `GET /api/bookings`: Get all bookings
+- `GET /api/bookings/user/{userId}`: Get bookings by user ID
+- `POST /api/bookings`: Create new booking
+- `PUT /api/bookings/{id}/cancel`: Cancel booking
-If you want to learn more about building native executables, please consult .
+### File Upload
-## Related Guides
-
-- Picocli ([guide](https://quarkus.io/guides/picocli)): Develop command line applications with Picocli
-- RESTEasy Classic Multipart ([guide](https://quarkus.io/guides/rest-json#multipart-support)): Multipart support for RESTEasy Classic
-- Hibernate ORM with Panache ([guide](https://quarkus.io/guides/hibernate-orm-panache)): Simplify your persistence code for Hibernate ORM via the active record or the repository pattern
-- SmallRye JWT ([guide](https://quarkus.io/guides/security-jwt)): Secure your applications with JSON Web Token
-- JDBC Driver - PostgreSQL ([guide](https://quarkus.io/guides/datasource)): Connect to the PostgreSQL database via JDBC
-
-## Provided Code
-
-### Hibernate ORM
-
-Create your first JPA entity
-
-[Related guide section...](https://quarkus.io/guides/hibernate-orm)
-
-[Related Hibernate with Panache section...](https://quarkus.io/guides/hibernate-orm-panache)
-
-
-### Picocli Example
-
-Hello and goodbye are civilization fundamentals. Let's not forget it with this example picocli application by changing the command and parameters.
-
-[Related guide section...](https://quarkus.io/guides/picocli#command-line-application-with-multiple-commands)
-
-Also for picocli applications the dev mode is supported. When running dev mode, the picocli application is executed and on press of the Enter key, is restarted.
-
-As picocli applications will often require arguments to be passed on the commandline, this is also possible in dev mode via:
-
-```shell script
-./mvnw quarkus:dev -Dquarkus.args='Quarky'
-```
-
-### RESTEasy JAX-RS
-
-Easily start your RESTful Web Services
-
-[Related guide section...](https://quarkus.io/guides/getting-started#the-jax-rs-resources)
+- `POST /api/upload`: Upload files (for profile pictures and class images)
\ No newline at end of file
diff --git a/mvnw b/mvnw
deleted file mode 100755
index 5e9618c..0000000
--- a/mvnw
+++ /dev/null
@@ -1,332 +0,0 @@
-#!/bin/sh
-# ----------------------------------------------------------------------------
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ----------------------------------------------------------------------------
-
-# ----------------------------------------------------------------------------
-# Apache Maven Wrapper startup batch script, version 3.3.2
-#
-# Required ENV vars:
-# ------------------
-# JAVA_HOME - location of a JDK home dir
-#
-# Optional ENV vars
-# -----------------
-# MAVEN_OPTS - parameters passed to the Java VM when running Maven
-# e.g. to debug Maven itself, use
-# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-# ----------------------------------------------------------------------------
-
-if [ -z "$MAVEN_SKIP_RC" ]; then
-
- if [ -f /usr/local/etc/mavenrc ]; then
- . /usr/local/etc/mavenrc
- fi
-
- if [ -f /etc/mavenrc ]; then
- . /etc/mavenrc
- fi
-
- if [ -f "$HOME/.mavenrc" ]; then
- . "$HOME/.mavenrc"
- fi
-
-fi
-
-# OS specific support. $var _must_ be set to either true or false.
-cygwin=false
-darwin=false
-mingw=false
-case "$(uname)" in
-CYGWIN*) cygwin=true ;;
-MINGW*) mingw=true ;;
-Darwin*)
- darwin=true
- # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
- # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
- if [ -z "$JAVA_HOME" ]; then
- if [ -x "/usr/libexec/java_home" ]; then
- JAVA_HOME="$(/usr/libexec/java_home)"
- export JAVA_HOME
- else
- JAVA_HOME="/Library/Java/Home"
- export JAVA_HOME
- fi
- fi
- ;;
-esac
-
-if [ -z "$JAVA_HOME" ]; then
- if [ -r /etc/gentoo-release ]; then
- JAVA_HOME=$(java-config --jre-home)
- fi
-fi
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched
-if $cygwin; then
- [ -n "$JAVA_HOME" ] \
- && JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
- [ -n "$CLASSPATH" ] \
- && CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
-fi
-
-# For Mingw, ensure paths are in UNIX format before anything is touched
-if $mingw; then
- [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] \
- && JAVA_HOME="$(
- cd "$JAVA_HOME" || (
- echo "cannot cd into $JAVA_HOME." >&2
- exit 1
- )
- pwd
- )"
-fi
-
-if [ -z "$JAVA_HOME" ]; then
- javaExecutable="$(which javac)"
- if [ -n "$javaExecutable" ] && ! [ "$(expr "$javaExecutable" : '\([^ ]*\)')" = "no" ]; then
- # readlink(1) is not available as standard on Solaris 10.
- readLink=$(which readlink)
- if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
- if $darwin; then
- javaHome="$(dirname "$javaExecutable")"
- javaExecutable="$(cd "$javaHome" && pwd -P)/javac"
- else
- javaExecutable="$(readlink -f "$javaExecutable")"
- fi
- javaHome="$(dirname "$javaExecutable")"
- javaHome=$(expr "$javaHome" : '\(.*\)/bin')
- JAVA_HOME="$javaHome"
- export JAVA_HOME
- fi
- fi
-fi
-
-if [ -z "$JAVACMD" ]; then
- if [ -n "$JAVA_HOME" ]; then
- if [ -x "$JAVA_HOME/jre/sh/java" ]; then
- # IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
- else
- JAVACMD="$JAVA_HOME/bin/java"
- fi
- else
- JAVACMD="$(
- \unset -f command 2>/dev/null
- \command -v java
- )"
- fi
-fi
-
-if [ ! -x "$JAVACMD" ]; then
- echo "Error: JAVA_HOME is not defined correctly." >&2
- echo " We cannot execute $JAVACMD" >&2
- exit 1
-fi
-
-if [ -z "$JAVA_HOME" ]; then
- echo "Warning: JAVA_HOME environment variable is not set." >&2
-fi
-
-# traverses directory structure from process work directory to filesystem root
-# first directory with .mvn subdirectory is considered project base directory
-find_maven_basedir() {
- if [ -z "$1" ]; then
- echo "Path not specified to find_maven_basedir" >&2
- return 1
- fi
-
- basedir="$1"
- wdir="$1"
- while [ "$wdir" != '/' ]; do
- if [ -d "$wdir"/.mvn ]; then
- basedir=$wdir
- break
- fi
- # workaround for JBEAP-8937 (on Solaris 10/Sparc)
- if [ -d "${wdir}" ]; then
- wdir=$(
- cd "$wdir/.." || exit 1
- pwd
- )
- fi
- # end of workaround
- done
- printf '%s' "$(
- cd "$basedir" || exit 1
- pwd
- )"
-}
-
-# concatenates all lines of a file
-concat_lines() {
- if [ -f "$1" ]; then
- # Remove \r in case we run on Windows within Git Bash
- # and check out the repository with auto CRLF management
- # enabled. Otherwise, we may read lines that are delimited with
- # \r\n and produce $'-Xarg\r' rather than -Xarg due to word
- # splitting rules.
- tr -s '\r\n' ' ' <"$1"
- fi
-}
-
-log() {
- if [ "$MVNW_VERBOSE" = true ]; then
- printf '%s\n' "$1"
- fi
-}
-
-BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
-if [ -z "$BASE_DIR" ]; then
- exit 1
-fi
-
-MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
-export MAVEN_PROJECTBASEDIR
-log "$MAVEN_PROJECTBASEDIR"
-
-##########################################################################################
-# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-# This allows using the maven wrapper in projects that prohibit checking in binary data.
-##########################################################################################
-wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
-if [ -r "$wrapperJarPath" ]; then
- log "Found $wrapperJarPath"
-else
- log "Couldn't find $wrapperJarPath, downloading it ..."
-
- if [ -n "$MVNW_REPOURL" ]; then
- wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
- else
- wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
- fi
- while IFS="=" read -r key value; do
- # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
- safeValue=$(echo "$value" | tr -d '\r')
- case "$key" in wrapperUrl)
- wrapperUrl="$safeValue"
- break
- ;;
- esac
- done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
- log "Downloading from: $wrapperUrl"
-
- if $cygwin; then
- wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
- fi
-
- if command -v wget >/dev/null; then
- log "Found wget ... using wget"
- [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
- else
- wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
- fi
- elif command -v curl >/dev/null; then
- log "Found curl ... using curl"
- [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
- if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
- else
- curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
- fi
- else
- log "Falling back to using Java to download"
- javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
- javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
- # For Cygwin, switch paths to Windows format before running javac
- if $cygwin; then
- javaSource=$(cygpath --path --windows "$javaSource")
- javaClass=$(cygpath --path --windows "$javaClass")
- fi
- if [ -e "$javaSource" ]; then
- if [ ! -e "$javaClass" ]; then
- log " - Compiling MavenWrapperDownloader.java ..."
- ("$JAVA_HOME/bin/javac" "$javaSource")
- fi
- if [ -e "$javaClass" ]; then
- log " - Running MavenWrapperDownloader.java ..."
- ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
- fi
- fi
- fi
-fi
-##########################################################################################
-# End of extension
-##########################################################################################
-
-# If specified, validate the SHA-256 sum of the Maven wrapper jar file
-wrapperSha256Sum=""
-while IFS="=" read -r key value; do
- case "$key" in wrapperSha256Sum)
- wrapperSha256Sum=$value
- break
- ;;
- esac
-done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
-if [ -n "$wrapperSha256Sum" ]; then
- wrapperSha256Result=false
- if command -v sha256sum >/dev/null; then
- if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c >/dev/null 2>&1; then
- wrapperSha256Result=true
- fi
- elif command -v shasum >/dev/null; then
- if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c >/dev/null 2>&1; then
- wrapperSha256Result=true
- fi
- else
- echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
- echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." >&2
- exit 1
- fi
- if [ $wrapperSha256Result = false ]; then
- echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
- echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
- echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
- exit 1
- fi
-fi
-
-MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin; then
- [ -n "$JAVA_HOME" ] \
- && JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
- [ -n "$CLASSPATH" ] \
- && CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
- [ -n "$MAVEN_PROJECTBASEDIR" ] \
- && MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
-fi
-
-# Provide a "standardized" way to retrieve the CLI args that will
-# work with both Windows and non-Windows executions.
-MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
-export MAVEN_CMD_LINE_ARGS
-
-WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-# shellcheck disable=SC2086 # safe args
-exec "$JAVACMD" \
- $MAVEN_OPTS \
- $MAVEN_DEBUG_OPTS \
- -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
- ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
deleted file mode 100755
index 4136715..0000000
--- a/mvnw.cmd
+++ /dev/null
@@ -1,206 +0,0 @@
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. You may obtain a copy of the License at
-@REM
-@REM http://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Apache Maven Wrapper startup batch script, version 3.3.2
-@REM
-@REM Required ENV vars:
-@REM JAVA_HOME - location of a JDK home dir
-@REM
-@REM Optional ENV vars
-@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
-@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
-@REM e.g. to debug Maven itself, use
-@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-@REM ----------------------------------------------------------------------------
-
-@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
-@echo off
-@REM set title of command window
-title %0
-@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
-@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
-
-@REM set %HOME% to equivalent of $HOME
-if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
-
-@REM Execute a user defined script before this one
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
-@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
-if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
-:skipRcPre
-
-@setlocal
-
-set ERROR_CODE=0
-
-@REM To isolate internal variables from possible post scripts, we use another setlocal
-@setlocal
-
-@REM ==== START VALIDATION ====
-if not "%JAVA_HOME%" == "" goto OkJHome
-
-echo. >&2
-echo Error: JAVA_HOME not found in your environment. >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo. >&2
-goto error
-
-:OkJHome
-if exist "%JAVA_HOME%\bin\java.exe" goto init
-
-echo. >&2
-echo Error: JAVA_HOME is set to an invalid directory. >&2
-echo JAVA_HOME = "%JAVA_HOME%" >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo. >&2
-goto error
-
-@REM ==== END VALIDATION ====
-
-:init
-
-@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
-@REM Fallback to current working directory if not found.
-
-set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
-IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
-
-set EXEC_DIR=%CD%
-set WDIR=%EXEC_DIR%
-:findBaseDir
-IF EXIST "%WDIR%"\.mvn goto baseDirFound
-cd ..
-IF "%WDIR%"=="%CD%" goto baseDirNotFound
-set WDIR=%CD%
-goto findBaseDir
-
-:baseDirFound
-set MAVEN_PROJECTBASEDIR=%WDIR%
-cd "%EXEC_DIR%"
-goto endDetectBaseDir
-
-:baseDirNotFound
-set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
-cd "%EXEC_DIR%"
-
-:endDetectBaseDir
-
-IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
-
-@setlocal EnableExtensions EnableDelayedExpansion
-for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
-@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
-
-:endReadAdditionalConfig
-
-SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
-set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
-set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
-
-FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
-)
-
-@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
-@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
-if exist %WRAPPER_JAR% (
- if "%MVNW_VERBOSE%" == "true" (
- echo Found %WRAPPER_JAR%
- )
-) else (
- if not "%MVNW_REPOURL%" == "" (
- SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar"
- )
- if "%MVNW_VERBOSE%" == "true" (
- echo Couldn't find %WRAPPER_JAR%, downloading it ...
- echo Downloading from: %WRAPPER_URL%
- )
-
- powershell -Command "&{"^
- "$webclient = new-object System.Net.WebClient;"^
- "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
- "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
- "}"^
- "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
- "}"
- if "%MVNW_VERBOSE%" == "true" (
- echo Finished downloading %WRAPPER_JAR%
- )
-)
-@REM End of extension
-
-@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
-SET WRAPPER_SHA_256_SUM=""
-FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
- IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
-)
-IF NOT %WRAPPER_SHA_256_SUM%=="" (
- powershell -Command "&{"^
- "Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash;"^
- "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
- "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
- " Write-Error 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
- " Write-Error 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
- " Write-Error 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
- " exit 1;"^
- "}"^
- "}"
- if ERRORLEVEL 1 goto error
-)
-
-@REM Provide a "standardized" way to retrieve the CLI args that will
-@REM work with both Windows and non-Windows executions.
-set MAVEN_CMD_LINE_ARGS=%*
-
-%MAVEN_JAVA_EXE% ^
- %JVM_CONFIG_MAVEN_PROPS% ^
- %MAVEN_OPTS% ^
- %MAVEN_DEBUG_OPTS% ^
- -classpath %WRAPPER_JAR% ^
- "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
- %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
-if ERRORLEVEL 1 goto error
-goto end
-
-:error
-set ERROR_CODE=1
-
-:end
-@endlocal & set ERROR_CODE=%ERROR_CODE%
-
-if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
-@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
-if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
-:skipRcPost
-
-@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%"=="on" pause
-
-if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
-
-cmd /C exit /B %ERROR_CODE%
diff --git a/pom.xml b/pom.xml
index 32ca934..07744fd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,81 +1,48 @@
-
4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.4
+
+
com.valposystems
gym-backend
- 1.0.0-SNAPSHOT
-
+ 0.0.1-SNAPSHOT
+ gym-backend
+ Gym backend application
- 3.11.0
- 11
- UTF-8
- UTF-8
- quarkus-bom
- io.quarkus.platform
- 3.6.3
- true
- 3.2.2
+ 17
-
-
-
-
- ${quarkus.platform.group-id}
- ${quarkus.platform.artifact-id}
- ${quarkus.platform.version}
- pom
- import
-
-
-
-
- io.quarkus
- quarkus-arc
+ org.springframework.boot
+ spring-boot-starter-data-jpa
- io.quarkus
- quarkus-resteasy
+ org.springframework.boot
+ spring-boot-starter-web
- io.quarkus
- quarkus-resteasy-jackson
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+ org.postgresql
+ postgresql
+ runtime
- io.quarkus
- quarkus-hibernate-orm-panache
+ org.projectlombok
+ lombok
+ true
- io.quarkus
- quarkus-jdbc-postgresql
-
-
- io.quarkus
- quarkus-resteasy-multipart
-
-
- io.quarkus
- quarkus-picocli
-
-
- io.quarkus
- quarkus-resteasy-jaxb
-
-
- io.quarkus
- quarkus-undertow
-
-
- io.quarkus
- quarkus-junit5
- test
-
-
- io.rest-assured
- rest-assured
+ org.springframework.boot
+ spring-boot-starter-test
test
@@ -83,52 +50,18 @@
- ${quarkus.platform.group-id}
- quarkus-maven-plugin
- ${quarkus.platform.version}
- true
-
-
-
- build
- generate-code
- generate-code-tests
-
-
-
-
-
- maven-compiler-plugin
- ${compiler-plugin.version}
+ org.springframework.boot
+ spring-boot-maven-plugin
- true
-
-
-
- maven-surefire-plugin
- ${surefire-plugin.version}
-
-
- org.jboss.logmanager.LogManager
- ${maven.home}
-
+
+
+ org.projectlombok
+ lombok
+
+
-
-
- native
-
-
- native
-
-
-
- false
- native
-
-
-
\ No newline at end of file
diff --git a/src/main/docker/Dockerfile.jvm b/src/main/docker/Dockerfile.jvm
deleted file mode 100644
index b12475f..0000000
--- a/src/main/docker/Dockerfile.jvm
+++ /dev/null
@@ -1,98 +0,0 @@
-####
-# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
-#
-# Before building the container image run:
-#
-# ./mvnw package
-#
-# Then, build the image with:
-#
-# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/gym-backend-jvm .
-#
-# Then run the container using:
-#
-# docker run -i --rm -p 8080:8080 quarkus/gym-backend-jvm
-#
-# If you want to include the debug port into your docker image
-# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
-# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
-# when running the container
-#
-# Then run the container using :
-#
-# docker run -i --rm -p 8080:8080 quarkus/gym-backend-jvm
-#
-# This image uses the `run-java.sh` script to run the application.
-# This scripts computes the command line to execute your Java application, and
-# includes memory/GC tuning.
-# You can configure the behavior using the following environment properties:
-# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") - Be aware that this will override
-# the default JVM options, use `JAVA_OPTS_APPEND` to append options
-# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
-# in JAVA_OPTS (example: "-Dsome.property=foo")
-# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
-# used to calculate a default maximal heap memory based on a containers restriction.
-# If used in a container without any memory constraints for the container then this
-# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
-# of the container available memory as set here. The default is `50` which means 50%
-# of the available memory is used as an upper boundary. You can skip this mechanism by
-# setting this value to `0` in which case no `-Xmx` option is added.
-# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
-# is used to calculate a default initial heap memory based on the maximum heap memory.
-# If used in a container without any memory constraints for the container then this
-# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
-# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
-# is used as the initial heap size. You can skip this mechanism by setting this value
-# to `0` in which case no `-Xms` option is added (example: "25")
-# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
-# This is used to calculate the maximum value of the initial heap memory. If used in
-# a container without any memory constraints for the container then this option has
-# no effect. If there is a memory constraint then `-Xms` is limited to the value set
-# here. The default is 4096MB which means the calculated value of `-Xms` never will
-# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
-# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
-# when things are happening. This option, if set to true, will set
-# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
-# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
-# true").
-# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
-# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
-# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
-# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
-# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
-# (example: "20")
-# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
-# (example: "40")
-# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
-# (example: "4")
-# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
-# previous GC times. (example: "90")
-# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
-# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
-# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
-# contain the necessary JRE command-line options to specify the required GC, which
-# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
-# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
-# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
-# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
-# accessed directly. (example: "foo.example.com,bar.example.com")
-#
-###
-FROM registry.access.redhat.com/ubi9/openjdk-21:1.21
-
-ENV LANGUAGE='en_US:en'
-
-
-# We make four distinct layers so if there are application changes the library layers can be re-used
-COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/
-COPY --chown=185 target/quarkus-app/*.jar /deployments/
-COPY --chown=185 target/quarkus-app/app/ /deployments/app/
-COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/
-
-EXPOSE 8080
-USER 185
-ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
-ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
-
-ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
-
diff --git a/src/main/docker/Dockerfile.legacy-jar b/src/main/docker/Dockerfile.legacy-jar
deleted file mode 100644
index c25dcff..0000000
--- a/src/main/docker/Dockerfile.legacy-jar
+++ /dev/null
@@ -1,94 +0,0 @@
-####
-# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
-#
-# Before building the container image run:
-#
-# ./mvnw package -Dquarkus.package.jar.type=legacy-jar
-#
-# Then, build the image with:
-#
-# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/gym-backend-legacy-jar .
-#
-# Then run the container using:
-#
-# docker run -i --rm -p 8080:8080 quarkus/gym-backend-legacy-jar
-#
-# If you want to include the debug port into your docker image
-# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
-# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
-# when running the container
-#
-# Then run the container using :
-#
-# docker run -i --rm -p 8080:8080 quarkus/gym-backend-legacy-jar
-#
-# This image uses the `run-java.sh` script to run the application.
-# This scripts computes the command line to execute your Java application, and
-# includes memory/GC tuning.
-# You can configure the behavior using the following environment properties:
-# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") - Be aware that this will override
-# the default JVM options, use `JAVA_OPTS_APPEND` to append options
-# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
-# in JAVA_OPTS (example: "-Dsome.property=foo")
-# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
-# used to calculate a default maximal heap memory based on a containers restriction.
-# If used in a container without any memory constraints for the container then this
-# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
-# of the container available memory as set here. The default is `50` which means 50%
-# of the available memory is used as an upper boundary. You can skip this mechanism by
-# setting this value to `0` in which case no `-Xmx` option is added.
-# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
-# is used to calculate a default initial heap memory based on the maximum heap memory.
-# If used in a container without any memory constraints for the container then this
-# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
-# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
-# is used as the initial heap size. You can skip this mechanism by setting this value
-# to `0` in which case no `-Xms` option is added (example: "25")
-# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
-# This is used to calculate the maximum value of the initial heap memory. If used in
-# a container without any memory constraints for the container then this option has
-# no effect. If there is a memory constraint then `-Xms` is limited to the value set
-# here. The default is 4096MB which means the calculated value of `-Xms` never will
-# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
-# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
-# when things are happening. This option, if set to true, will set
-# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
-# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
-# true").
-# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
-# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
-# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
-# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
-# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
-# (example: "20")
-# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
-# (example: "40")
-# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
-# (example: "4")
-# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
-# previous GC times. (example: "90")
-# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
-# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
-# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
-# contain the necessary JRE command-line options to specify the required GC, which
-# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
-# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
-# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
-# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
-# accessed directly. (example: "foo.example.com,bar.example.com")
-#
-###
-FROM registry.access.redhat.com/ubi9/openjdk-21:1.21
-
-ENV LANGUAGE='en_US:en'
-
-
-COPY target/lib/* /deployments/lib/
-COPY target/*-runner.jar /deployments/quarkus-run.jar
-
-EXPOSE 8080
-USER 185
-ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
-ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
-
-ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
diff --git a/src/main/docker/Dockerfile.native b/src/main/docker/Dockerfile.native
deleted file mode 100644
index 21e034b..0000000
--- a/src/main/docker/Dockerfile.native
+++ /dev/null
@@ -1,29 +0,0 @@
-####
-# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
-#
-# Before building the container image run:
-#
-# ./mvnw package -Dnative
-#
-# Then, build the image with:
-#
-# docker build -f src/main/docker/Dockerfile.native -t quarkus/gym-backend .
-#
-# Then run the container using:
-#
-# docker run -i --rm -p 8080:8080 quarkus/gym-backend
-#
-# The ` registry.access.redhat.com/ubi8/ubi-minimal:8.10` base image is based on UBI 9.
-# To use UBI 8, switch to `quay.io/ubi8/ubi-minimal:8.10`.
-###
-FROM registry.access.redhat.com/ubi8/ubi-minimal:8.10
-WORKDIR /work/
-RUN chown 1001 /work \
- && chmod "g+rwX" /work \
- && chown 1001:root /work
-COPY --chown=1001:root --chmod=0755 target/*-runner /work/application
-
-EXPOSE 8080
-USER 1001
-
-ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
diff --git a/src/main/docker/Dockerfile.native-micro b/src/main/docker/Dockerfile.native-micro
deleted file mode 100644
index d21bde5..0000000
--- a/src/main/docker/Dockerfile.native-micro
+++ /dev/null
@@ -1,32 +0,0 @@
-####
-# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
-# It uses a micro base image, tuned for Quarkus native executables.
-# It reduces the size of the resulting container image.
-# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image.
-#
-# Before building the container image run:
-#
-# ./mvnw package -Dnative
-#
-# Then, build the image with:
-#
-# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/gym-backend .
-#
-# Then run the container using:
-#
-# docker run -i --rm -p 8080:8080 quarkus/gym-backend
-#
-# The `quay.io/quarkus/quarkus-micro-image:2.0` base image is based on UBI 9.
-# To use UBI 8, switch to `quay.io/quarkus/quarkus-micro-image:2.0`.
-###
-FROM quay.io/quarkus/quarkus-micro-image:2.0
-WORKDIR /work/
-RUN chown 1001 /work \
- && chmod "g+rwX" /work \
- && chown 1001:root /work
-COPY --chown=1001:root --chmod=0755 target/*-runner /work/application
-
-EXPOSE 8080
-USER 1001
-
-ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
diff --git a/src/main/java/com/valposystems/GymApplication.java b/src/main/java/com/valposystems/GymApplication.java
index 083020d..0150da1 100644
--- a/src/main/java/com/valposystems/GymApplication.java
+++ b/src/main/java/com/valposystems/GymApplication.java
@@ -1,18 +1,34 @@
package com.valposystems;
-import io.quarkus.runtime.Quarkus;
-import io.quarkus.runtime.QuarkusApplication;
-import io.quarkus.runtime.annotations.QuarkusMain;
-import jakarta.enterprise.context.ApplicationScoped;
-import org.jboss.logging.Logger;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
-@QuarkusMain
+import java.util.Arrays;
+
+@SpringBootApplication
public class GymApplication {
-
- private static final Logger LOG = Logger.getLogger(GymApplication.class);
-
- public static void main(String... args) {
- LOG.info("Iniciando aplicación Gym Backend...");
- Quarkus.run(args);
+
+ public static void main(String[] args) {
+ SpringApplication.run(GymApplication.class, args);
+ }
+
+ @Bean
+ public CorsFilter corsFilter() {
+ CorsConfiguration corsConfiguration = new CorsConfiguration();
+ corsConfiguration.setAllowCredentials(true);
+ corsConfiguration.setAllowedOrigins(Arrays.asList("*"));
+ corsConfiguration.setAllowedHeaders(Arrays.asList("Origin", "Access-Control-Allow-Origin", "Content-Type",
+ "Accept", "Authorization", "Origin, Accept", "X-Requested-With",
+ "Access-Control-Request-Method", "Access-Control-Request-Headers"));
+ corsConfiguration.setExposedHeaders(Arrays.asList("Origin", "Content-Type", "Accept", "Authorization",
+ "Access-Control-Allow-Origin", "Access-Control-Allow-Origin", "Access-Control-Allow-Credentials", "Content-Disposition"));
+ corsConfiguration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
+ UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
+ urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
+ return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/controller/BookingController.java b/src/main/java/com/valposystems/controller/BookingController.java
new file mode 100644
index 0000000..d361fe8
--- /dev/null
+++ b/src/main/java/com/valposystems/controller/BookingController.java
@@ -0,0 +1,83 @@
+package com.valposystems.controller;
+
+import com.valposystems.dto.BookingDTO;
+import com.valposystems.service.BookingService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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("/api/bookings")
+@CrossOrigin
+public class BookingController {
+
+ private static final Logger logger = LoggerFactory.getLogger(BookingController.class);
+
+ private final BookingService bookingService;
+
+ @Autowired
+ public BookingController(BookingService bookingService) {
+ this.bookingService = bookingService;
+ }
+
+ @GetMapping
+ public ResponseEntity> getAllBookings() {
+ try {
+ List bookings = bookingService.getAllBookings();
+ return ResponseEntity.ok(bookings);
+ } catch (Exception e) {
+ logger.error("Error getting bookings", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(null);
+ }
+ }
+
+ @GetMapping("/user/{userId}")
+ public ResponseEntity> getBookingsByUserId(@PathVariable Long userId) {
+ try {
+ List bookings = bookingService.getBookingsByUserId(userId);
+ return ResponseEntity.ok(bookings);
+ } catch (Exception e) {
+ logger.error("Error getting bookings for user: {}", userId, e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(null);
+ }
+ }
+
+ @PostMapping
+ public ResponseEntity> createBooking(@RequestBody BookingDTO dto) {
+ try {
+ BookingDTO created = bookingService.createBooking(dto);
+ if (created == null) {
+ return ResponseEntity.status(HttpStatus.CONFLICT)
+ .body("{\"message\": \"No spots available or the user/class doesn't exist\"}");
+ }
+ return ResponseEntity.status(HttpStatus.CREATED).body(created);
+ } catch (Exception e) {
+ logger.error("Error creating booking", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body("{\"error\": \"" + e.getMessage() + "\"}");
+ }
+ }
+
+ @PutMapping("/{id}/cancel")
+ public ResponseEntity> cancelBooking(@PathVariable Long id) {
+ try {
+ BookingDTO cancelled = bookingService.cancelBooking(id);
+ if (cancelled == null) {
+ return ResponseEntity.status(HttpStatus.NOT_FOUND)
+ .body("{\"message\": \"The booking doesn't exist or isn't in confirmed state\"}");
+ }
+ return ResponseEntity.ok(cancelled);
+ } catch (Exception e) {
+ logger.error("Error cancelling booking with ID: {}", id, e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body("{\"error\": \"" + e.getMessage() + "\"}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/controller/GymClassController.java b/src/main/java/com/valposystems/controller/GymClassController.java
new file mode 100644
index 0000000..5936056
--- /dev/null
+++ b/src/main/java/com/valposystems/controller/GymClassController.java
@@ -0,0 +1,96 @@
+package com.valposystems.controller;
+
+import com.valposystems.dto.GymClassDTO;
+import com.valposystems.service.GymClassService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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("/api/classes")
+@CrossOrigin
+public class GymClassController {
+
+ private static final Logger logger = LoggerFactory.getLogger(GymClassController.class);
+
+ private final GymClassService gymClassService;
+
+ @Autowired
+ public GymClassController(GymClassService gymClassService) {
+ this.gymClassService = gymClassService;
+ }
+
+ @GetMapping
+ public ResponseEntity> getAllClasses() {
+ try {
+ List classes = gymClassService.getAllClasses();
+ return ResponseEntity.ok(classes);
+ } catch (Exception e) {
+ logger.error("Error getting classes", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(null);
+ }
+ }
+
+ @GetMapping("/{id}")
+ public ResponseEntity getClassById(@PathVariable Long id) {
+ try {
+ GymClassDTO gymClass = gymClassService.getClassById(id);
+ if (gymClass == null) {
+ return ResponseEntity.notFound().build();
+ }
+ return ResponseEntity.ok(gymClass);
+ } catch (Exception e) {
+ logger.error("Error getting class with ID: {}", id, e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(null);
+ }
+ }
+
+ @PostMapping
+ public ResponseEntity createClass(@RequestBody GymClassDTO dto) {
+ try {
+ GymClassDTO created = gymClassService.createClass(dto);
+ return ResponseEntity.status(HttpStatus.CREATED).body(created);
+ } catch (Exception e) {
+ logger.error("Error creating class", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(null);
+ }
+ }
+
+ @PutMapping("/{id}")
+ public ResponseEntity updateClass(@PathVariable Long id, @RequestBody GymClassDTO dto) {
+ try {
+ GymClassDTO updated = gymClassService.updateClass(id, dto);
+ if (updated == null) {
+ return ResponseEntity.notFound().build();
+ }
+ return ResponseEntity.ok(updated);
+ } catch (Exception e) {
+ logger.error("Error updating class with ID: {}", id, e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(null);
+ }
+ }
+
+ @DeleteMapping("/{id}")
+ public ResponseEntity deleteClass(@PathVariable Long id) {
+ try {
+ boolean deleted = gymClassService.deleteClass(id);
+ if (!deleted) {
+ return ResponseEntity.notFound().build();
+ }
+ return ResponseEntity.noContent().build();
+ } catch (Exception e) {
+ logger.error("Error deleting class with ID: {}", id, e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .build();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/controller/UploadController.java b/src/main/java/com/valposystems/controller/UploadController.java
new file mode 100644
index 0000000..4178894
--- /dev/null
+++ b/src/main/java/com/valposystems/controller/UploadController.java
@@ -0,0 +1,76 @@
+package com.valposystems.controller;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.UUID;
+
+@RestController
+@RequestMapping("/api/upload")
+@CrossOrigin
+public class UploadController {
+
+ private static final Logger logger = LoggerFactory.getLogger(UploadController.class);
+
+ @Value("${app.upload.dir:uploads}")
+ private String uploadDir;
+
+ @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+ public ResponseEntity> uploadFile(@RequestParam("file") MultipartFile file) {
+ try {
+ logger.info("Receiving file upload request");
+
+ if (file.isEmpty()) {
+ logger.warn("No file provided");
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST)
+ .body("{\"error\":\"No file uploaded\"}");
+ }
+
+ // Create directory if it doesn't exist
+ File directory = new File(uploadDir);
+ if (!directory.exists()) {
+ directory.mkdirs();
+ logger.info("Upload directory created: {}", directory.getAbsolutePath());
+ }
+
+ // Get file extension
+ String originalFilename = file.getOriginalFilename();
+ String extension = "";
+ if (originalFilename != null && originalFilename.contains(".")) {
+ extension = originalFilename.substring(originalFilename.lastIndexOf("."));
+ } else {
+ extension = ".jpg";
+ }
+
+ // Generate unique filename
+ String fileName = UUID.randomUUID().toString() + extension;
+ Path filePath = Paths.get(uploadDir, fileName);
+
+ logger.info("Saving file as: {}", filePath);
+
+ // Save file
+ Files.copy(file.getInputStream(), filePath);
+
+ // Return file URL
+ String fileUrl = "/uploads/" + fileName;
+ logger.info("File uploaded successfully. URL: {}", fileUrl);
+ return ResponseEntity.ok("{\"url\":\"" + fileUrl + "\"}");
+
+ } catch (IOException e) {
+ logger.error("Error uploading file", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body("{\"error\":\"" + e.getMessage() + "\"}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/controller/UserController.java b/src/main/java/com/valposystems/controller/UserController.java
new file mode 100644
index 0000000..e2bf7af
--- /dev/null
+++ b/src/main/java/com/valposystems/controller/UserController.java
@@ -0,0 +1,89 @@
+package com.valposystems.controller;
+
+import com.valposystems.dto.UserDTO;
+import com.valposystems.service.UserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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("/api/users")
+@CrossOrigin
+public class UserController {
+
+ private static final Logger logger = LoggerFactory.getLogger(UserController.class);
+
+ private final UserService userService;
+
+ @Autowired
+ public UserController(UserService userService) {
+ this.userService = userService;
+ }
+
+ @GetMapping
+ public ResponseEntity> getAllUsers() {
+ try {
+ logger.info("Getting all users");
+ List users = userService.getAllUsers();
+ return ResponseEntity.ok(users);
+ } catch (Exception e) {
+ logger.error("Error getting users", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(null);
+ }
+ }
+
+ @GetMapping("/{id}")
+ public ResponseEntity getUserById(@PathVariable Long id) {
+ try {
+ logger.info("Getting user with ID: {}", id);
+ UserDTO user = userService.getUserById(id);
+ if (user == null) {
+ return ResponseEntity.notFound().build();
+ }
+ return ResponseEntity.ok(user);
+ } catch (Exception e) {
+ logger.error("Error getting user with ID: {}", id, e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(null);
+ }
+ }
+
+ @PostMapping
+ public ResponseEntity> createUser(@RequestBody UserDTO dto) {
+ try {
+ logger.info("Creating new user: {}", dto.getEmail());
+ UserDTO created = userService.createUser(dto);
+ if (created == null) {
+ return ResponseEntity.status(HttpStatus.CONFLICT)
+ .body("{\"message\": \"A user with that email already exists\"}");
+ }
+ return ResponseEntity.status(HttpStatus.CREATED).body(created);
+ } catch (Exception e) {
+ logger.error("Error creating user", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body("{\"error\": \"" + e.getMessage() + "\"}");
+ }
+ }
+
+ @PutMapping("/{id}")
+ public ResponseEntity updateUser(@PathVariable Long id, @RequestBody UserDTO dto) {
+ try {
+ logger.info("Updating user with ID: {}", id);
+ UserDTO updated = userService.updateUser(id, dto);
+ if (updated == null) {
+ return ResponseEntity.notFound().build();
+ }
+ return ResponseEntity.ok(updated);
+ } catch (Exception e) {
+ logger.error("Error updating user with ID: {}", id, e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body(null);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/dto/BookingDTO.java b/src/main/java/com/valposystems/dto/BookingDTO.java
index c00b5c3..9e8da0a 100644
--- a/src/main/java/com/valposystems/dto/BookingDTO.java
+++ b/src/main/java/com/valposystems/dto/BookingDTO.java
@@ -1,31 +1,34 @@
package com.valposystems.dto;
import com.valposystems.model.Booking;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
public class BookingDTO {
- public Long id;
- public Long userId;
- public String userName;
- public Long classId;
- public String className;
- public LocalDateTime bookingDate;
- public String status;
-
- public BookingDTO() {
- }
+ private Long id;
+ private Long userId;
+ private String userName;
+ private Long classId;
+ private String className;
+ private LocalDateTime bookingDate;
+ private String status;
public static BookingDTO from(Booking booking) {
BookingDTO dto = new BookingDTO();
- dto.id = booking.id;
- dto.userId = booking.user.id;
- dto.userName = booking.user.name;
- dto.classId = booking.gymClass.id;
- dto.className = booking.gymClass.name;
- dto.bookingDate = booking.bookingDate;
- dto.status = booking.status;
+ dto.setId(booking.getId());
+ dto.setUserId(booking.getUser().getId());
+ dto.setUserName(booking.getUser().getName());
+ dto.setClassId(booking.getGymClass().getId());
+ dto.setClassName(booking.getGymClass().getName());
+ dto.setBookingDate(booking.getBookingDate());
+ dto.setStatus(booking.getStatus());
return dto;
}
}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/dto/GymClassDTO.java b/src/main/java/com/valposystems/dto/GymClassDTO.java
index 3d45d88..fa36b56 100644
--- a/src/main/java/com/valposystems/dto/GymClassDTO.java
+++ b/src/main/java/com/valposystems/dto/GymClassDTO.java
@@ -1,37 +1,40 @@
package com.valposystems.dto;
-
import com.valposystems.model.GymClass;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
import java.time.LocalDateTime;
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
public class GymClassDTO {
- public Long id;
- public String name;
- public String description;
- public String instructor;
- public LocalDateTime startTime;
- public LocalDateTime endTime;
- public int maxCapacity;
- public int currentBookings;
- public String category;
- public String imageUrl;
-
- public GymClassDTO() {
- }
+ private Long id;
+ private String name;
+ private String description;
+ private String instructor;
+ private LocalDateTime startTime;
+ private LocalDateTime endTime;
+ private int maxCapacity;
+ private int currentBookings;
+ private String category;
+ private String imageUrl;
public static GymClassDTO from(GymClass gymClass) {
GymClassDTO dto = new GymClassDTO();
- dto.id = gymClass.id;
- dto.name = gymClass.name;
- dto.description = gymClass.description;
- dto.instructor = gymClass.instructor;
- dto.startTime = gymClass.startTime;
- dto.endTime = gymClass.endTime;
- dto.maxCapacity = gymClass.maxCapacity;
- dto.currentBookings = gymClass.currentBookings;
- dto.category = gymClass.category;
- dto.imageUrl = gymClass.imageUrl;
+ dto.setId(gymClass.getId());
+ dto.setName(gymClass.getName());
+ dto.setDescription(gymClass.getDescription());
+ dto.setInstructor(gymClass.getInstructor());
+ dto.setStartTime(gymClass.getStartTime());
+ dto.setEndTime(gymClass.getEndTime());
+ dto.setMaxCapacity(gymClass.getMaxCapacity());
+ dto.setCurrentBookings(gymClass.getCurrentBookings());
+ dto.setCategory(gymClass.getCategory());
+ dto.setImageUrl(gymClass.getImageUrl());
return dto;
}
}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/dto/UserDTO.java b/src/main/java/com/valposystems/dto/UserDTO.java
index de04bbb..7941bf7 100644
--- a/src/main/java/com/valposystems/dto/UserDTO.java
+++ b/src/main/java/com/valposystems/dto/UserDTO.java
@@ -1,25 +1,28 @@
package com.valposystems.dto;
import com.valposystems.model.User;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
public class UserDTO {
- public Long id;
- public String name;
- public String email;
- public String profilePicUrl;
- public boolean notificationsEnabled;
-
- public UserDTO() {
- }
+ private Long id;
+ private String name;
+ private String email;
+ private String profilePicUrl;
+ private boolean notificationsEnabled;
public static UserDTO from(User user) {
UserDTO dto = new UserDTO();
- dto.id = user.id;
- dto.name = user.name;
- dto.email = user.email;
- dto.profilePicUrl = user.profilePicUrl;
- dto.notificationsEnabled = user.notificationsEnabled;
+ dto.setId(user.getId());
+ dto.setName(user.getName());
+ dto.setEmail(user.getEmail());
+ dto.setProfilePicUrl(user.getProfilePicUrl());
+ dto.setNotificationsEnabled(user.isNotificationsEnabled());
return dto;
}
}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/model/Booking.java b/src/main/java/com/valposystems/model/Booking.java
index a0ccc1e..231a6ba 100644
--- a/src/main/java/com/valposystems/model/Booking.java
+++ b/src/main/java/com/valposystems/model/Booking.java
@@ -1,30 +1,33 @@
package com.valposystems.model;
-import io.quarkus.hibernate.orm.panache.PanacheEntity;
-import jakarta.persistence.Entity;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
import java.time.LocalDateTime;
@Entity
@Table(name = "bookings")
-public class Booking extends PanacheEntity {
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Booking {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
@ManyToOne
- public User user;
+ private User user;
@ManyToOne
- public GymClass gymClass;
+ private GymClass gymClass;
- public LocalDateTime bookingDate;
+ private LocalDateTime bookingDate;
- public String status; // 'confirmed', 'cancelled', 'pending'
+ private String status; // 'confirmed', 'cancelled', 'pending'
- // Constructor vacío requerido por JPA
- public Booking() {
- }
-
- // Constructor para inicialización más sencilla
public Booking(User user, GymClass gymClass, LocalDateTime bookingDate, String status) {
this.user = user;
this.gymClass = gymClass;
diff --git a/src/main/java/com/valposystems/model/GymClass.java b/src/main/java/com/valposystems/model/GymClass.java
index 5060c05..b0a339c 100644
--- a/src/main/java/com/valposystems/model/GymClass.java
+++ b/src/main/java/com/valposystems/model/GymClass.java
@@ -1,41 +1,45 @@
package com.valposystems.model;
-import io.quarkus.hibernate.orm.panache.PanacheEntity;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.Table;
+
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
import java.time.LocalDateTime;
@Entity
@Table(name = "gym_classes")
-public class GymClass extends PanacheEntity {
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class GymClass {
- public String name;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
- public String description;
+ private String name;
- public String instructor;
+ private String description;
- public LocalDateTime startTime;
+ private String instructor;
- public LocalDateTime endTime;
+ private LocalDateTime startTime;
- public int maxCapacity;
+ private LocalDateTime endTime;
- public int currentBookings;
+ private int maxCapacity;
- public String category;
+ private int currentBookings;
- public String imageUrl;
+ private String category;
- // Constructor vacío requerido por JPA
- public GymClass() {
- }
+ private String imageUrl;
- // Constructor para inicialización más sencilla
public GymClass(String name, String description, String instructor,
- LocalDateTime startTime, LocalDateTime endTime,
- int maxCapacity, int currentBookings,
- String category, String imageUrl) {
+ LocalDateTime startTime, LocalDateTime endTime,
+ int maxCapacity, int currentBookings,
+ String category, String imageUrl) {
this.name = name;
this.description = description;
this.instructor = instructor;
diff --git a/src/main/java/com/valposystems/model/User.java b/src/main/java/com/valposystems/model/User.java
index 13a5a50..dc4d11f 100644
--- a/src/main/java/com/valposystems/model/User.java
+++ b/src/main/java/com/valposystems/model/User.java
@@ -1,30 +1,32 @@
package com.valposystems.model;
-import io.quarkus.hibernate.orm.panache.PanacheEntity;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.Table;
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
@Entity
@Table(name = "users")
-public class User extends PanacheEntity {
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class User {
- public String name;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ private String name;
@Column(unique = true)
- public String email;
+ private String email;
- public String password;
+ private String password;
- public String profilePicUrl;
+ private String profilePicUrl;
- public boolean notificationsEnabled;
+ private boolean notificationsEnabled;
- // Constructor vacío requerido por JPA
- public User() {
- }
-
- // Constructor para inicialización más sencilla
public User(String name, String email, String password, String profilePicUrl, boolean notificationsEnabled) {
this.name = name;
this.email = email;
diff --git a/src/main/java/com/valposystems/repository/BookingRepository.java b/src/main/java/com/valposystems/repository/BookingRepository.java
new file mode 100644
index 0000000..d400555
--- /dev/null
+++ b/src/main/java/com/valposystems/repository/BookingRepository.java
@@ -0,0 +1,12 @@
+package com.valposystems.repository;
+
+import com.valposystems.model.Booking;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface BookingRepository extends JpaRepository {
+ List findByUserId(Long userId);
+}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/repository/GymClassRepository.java b/src/main/java/com/valposystems/repository/GymClassRepository.java
new file mode 100644
index 0000000..7d76d4f
--- /dev/null
+++ b/src/main/java/com/valposystems/repository/GymClassRepository.java
@@ -0,0 +1,9 @@
+package com.valposystems.repository;
+
+import com.valposystems.model.GymClass;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface GymClassRepository extends JpaRepository {
+}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/repository/UserRepository.java b/src/main/java/com/valposystems/repository/UserRepository.java
new file mode 100644
index 0000000..a781b69
--- /dev/null
+++ b/src/main/java/com/valposystems/repository/UserRepository.java
@@ -0,0 +1,13 @@
+package com.valposystems.repository;
+
+import com.valposystems.model.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface UserRepository extends JpaRepository {
+ boolean existsByEmail(String email);
+ Optional findByEmail(String email);
+}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/resource/BookingResource.java b/src/main/java/com/valposystems/resource/BookingResource.java
deleted file mode 100644
index 1b11830..0000000
--- a/src/main/java/com/valposystems/resource/BookingResource.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.valposystems.resource;
-
-import com.valposystems.dto.BookingDTO;
-import com.valposystems.service.BookingService;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.transaction.Transactional;
-import jakarta.ws.rs.*;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import java.util.List;
-
-@ApplicationScoped
-@Path("/api/bookings")
-@Produces(MediaType.APPLICATION_JSON)
-@Consumes(MediaType.APPLICATION_JSON)
-public class BookingResource {
-
- @Inject
- BookingService bookingService;
-
- @GET
- @Transactional
- public Response getAllBookings() {
- try {
- List bookings = bookingService.getAllBookings();
- return Response.ok(bookings).build();
- } catch (Exception e) {
- return Response.serverError().entity("Error: " + e.getMessage()).build();
- }
- }
-
- @GET
- @Path("/user/{userId}")
- @Transactional
- public Response getBookingsByUserId(@PathParam("userId") Long userId) {
- try {
- List bookings = bookingService.getBookingsByUserId(userId);
- return Response.ok(bookings).build();
- } catch (Exception e) {
- return Response.serverError().entity("Error: " + e.getMessage()).build();
- }
- }
-
- @POST
- @Transactional
- public Response createBooking(BookingDTO dto) {
- try {
- BookingDTO created = bookingService.createBooking(dto);
- if (created == null) {
- return Response.status(Response.Status.CONFLICT)
- .entity("{\"message\": \"No hay plazas disponibles o el usuario/clase no existe\"}").build();
- }
- return Response.status(Response.Status.CREATED).entity(created).build();
- } catch (Exception e) {
- return Response.serverError().entity("Error: " + e.getMessage()).build();
- }
- }
-
- @PUT
- @Path("/{id}/cancel")
- @Transactional
- public Response cancelBooking(@PathParam("id") Long id) {
- try {
- BookingDTO cancelled = bookingService.cancelBooking(id);
- if (cancelled == null) {
- return Response.status(Response.Status.NOT_FOUND)
- .entity("{\"message\": \"La reserva no existe o no está en estado confirmado\"}").build();
- }
- return Response.ok(cancelled).build();
- } catch (Exception e) {
- return Response.serverError().entity("Error: " + e.getMessage()).build();
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/resource/GymClassResource.java b/src/main/java/com/valposystems/resource/GymClassResource.java
deleted file mode 100644
index 3450bea..0000000
--- a/src/main/java/com/valposystems/resource/GymClassResource.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package com.valposystems.resource;
-
-import com.valposystems.dto.GymClassDTO;
-import com.valposystems.service.GymClassService;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.transaction.Transactional;
-import jakarta.ws.rs.*;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import java.util.List;
-
-@ApplicationScoped
-@Path("/api/classes")
-@Produces(MediaType.APPLICATION_JSON)
-@Consumes(MediaType.APPLICATION_JSON)
-public class GymClassResource {
-
- @Inject
- GymClassService gymClassService;
-
- @GET
- @Transactional
- public Response getAllClasses() {
- try {
- List classes = gymClassService.getAllClasses();
- return Response.ok(classes).build();
- } catch (Exception e) {
- return Response.serverError().entity("Error: " + e.getMessage()).build();
- }
- }
-
- @GET
- @Path("/{id}")
- @Transactional
- public Response getClassById(@PathParam("id") Long id) {
- try {
- GymClassDTO gymClass = gymClassService.getClassById(id);
- if (gymClass == null) {
- return Response.status(Response.Status.NOT_FOUND).build();
- }
- return Response.ok(gymClass).build();
- } catch (Exception e) {
- return Response.serverError().entity("Error: " + e.getMessage()).build();
- }
- }
-
- @POST
- @Transactional
- public Response createClass(GymClassDTO dto) {
- try {
- GymClassDTO created = gymClassService.createClass(dto);
- return Response.status(Response.Status.CREATED).entity(created).build();
- } catch (Exception e) {
- return Response.serverError().entity("Error: " + e.getMessage()).build();
- }
- }
-
- @PUT
- @Path("/{id}")
- @Transactional
- public Response updateClass(@PathParam("id") Long id, GymClassDTO dto) {
- try {
- GymClassDTO updated = gymClassService.updateClass(id, dto);
- if (updated == null) {
- return Response.status(Response.Status.NOT_FOUND).build();
- }
- return Response.ok(updated).build();
- } catch (Exception e) {
- return Response.serverError().entity("Error: " + e.getMessage()).build();
- }
- }
-
- @DELETE
- @Path("/{id}")
- @Transactional
- public Response deleteClass(@PathParam("id") Long id) {
- try {
- boolean deleted = gymClassService.deleteClass(id);
- if (!deleted) {
- return Response.status(Response.Status.NOT_FOUND).build();
- }
- return Response.noContent().build();
- } catch (Exception e) {
- return Response.serverError().entity("Error: " + e.getMessage()).build();
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/resource/UploadResource.java b/src/main/java/com/valposystems/resource/UploadResource.java
deleted file mode 100644
index df0e99d..0000000
--- a/src/main/java/com/valposystems/resource/UploadResource.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package com.valposystems.resource;
-
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.MultivaluedMap;
-import jakarta.ws.rs.core.Response;
-import org.jboss.logging.Logger;
-import org.jboss.resteasy.plugins.providers.multipart.InputPart;
-import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-@ApplicationScoped
-@Path("/api/upload")
-public class UploadResource {
-
- private static final Logger LOG = Logger.getLogger(UploadResource.class);
- private static final String UPLOAD_DIR = "uploads";
-
- @POST
- @Consumes(MediaType.MULTIPART_FORM_DATA)
- @Produces(MediaType.APPLICATION_JSON)
- public Response uploadFile(MultipartFormDataInput input) {
- try {
- LOG.info("Recibiendo solicitud de carga de archivo");
-
- // Obtener los InputPart del mapa (no directamente InputStream)
- Map> formDataMap = input.getFormDataMap();
- List inputParts = formDataMap.get("file");
-
- if (inputParts == null || inputParts.isEmpty()) {
- LOG.warn("No se ha proporcionado ningún archivo");
- return Response.status(Response.Status.BAD_REQUEST)
- .entity("{\"error\":\"No file uploaded\"}").build();
- }
-
- // Obtener el InputPart y convertirlo a InputStream
- InputPart inputPart = inputParts.get(0);
- InputStream fileInputStream = inputPart.getBody(InputStream.class, null);
-
- // Crear directorio si no existe
- File directory = new File(UPLOAD_DIR);
- if (!directory.exists()) {
- directory.mkdirs();
- LOG.info("Directorio de subida creado: " + directory.getAbsolutePath());
- }
-
- // Obtener información del archivo
- MultivaluedMap headers = inputPart.getHeaders();
- String fileName = UUID.randomUUID().toString() + getFileExtension(headers);
- String filePath = UPLOAD_DIR + "/" + fileName;
-
- LOG.info("Guardando archivo como: " + filePath);
-
- // Guardar archivo
- Files.copy(
- fileInputStream,
- Paths.get(filePath),
- StandardCopyOption.REPLACE_EXISTING
- );
-
- // Devolver URL del archivo subido
- String fileUrl = "/uploads/" + fileName;
- LOG.info("Archivo subido exitosamente. URL: " + fileUrl);
- return Response.ok("{\"url\":\"" + fileUrl + "\"}").build();
-
- } catch (IOException e) {
- LOG.error("Error al subir archivo", e);
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
- .entity("{\"error\":\"" + e.getMessage() + "\"}").build();
- }
- }
-
- private String getFileExtension(MultivaluedMap headers) {
- String contentDisposition = headers.getFirst("Content-Disposition");
- if (contentDisposition != null) {
- for (String part : contentDisposition.split(";")) {
- if (part.trim().startsWith("filename")) {
- String fileName = part.substring(part.indexOf('=') + 1).trim().replace("\"", "");
- int dot = fileName.lastIndexOf('.');
- if (dot > 0) {
- return fileName.substring(dot);
- }
- break;
- }
- }
- }
- return ".jpg";
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/resource/UserResource.java b/src/main/java/com/valposystems/resource/UserResource.java
deleted file mode 100644
index 3272e45..0000000
--- a/src/main/java/com/valposystems/resource/UserResource.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package com.valposystems.resource;
-
-import com.valposystems.dto.UserDTO;
-import com.valposystems.service.UserService;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.transaction.Transactional;
-import jakarta.ws.rs.*;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import org.jboss.logging.Logger;
-import java.util.List;
-
-@ApplicationScoped
-@Path("/api/users")
-@Produces(MediaType.APPLICATION_JSON)
-@Consumes(MediaType.APPLICATION_JSON)
-public class UserResource {
-
- private static final Logger LOG = Logger.getLogger(UserResource.class);
-
- @Inject
- UserService userService;
-
- @GET
- @Transactional
- public Response getAllUsers() {
- try {
- LOG.info("Obteniendo todos los usuarios");
- List users = userService.getAllUsers();
- return Response.ok(users).build();
- } catch (Exception e) {
- LOG.error("Error al obtener usuarios", e);
- return Response.serverError().entity("Error: " + e.getMessage()).build();
- }
- }
-
- @GET
- @Path("/{id}")
- @Transactional
- public Response getUserById(@PathParam("id") Long id) {
- try {
- LOG.info("Obteniendo usuario con ID: " + id);
- UserDTO user = userService.getUserById(id);
- if (user == null) {
- return Response.status(Response.Status.NOT_FOUND).build();
- }
- return Response.ok(user).build();
- } catch (Exception e) {
- LOG.error("Error al obtener usuario con ID: " + id, e);
- return Response.serverError().entity("Error: " + e.getMessage()).build();
- }
- }
-
- @POST
- @Transactional
- public Response createUser(UserDTO dto) {
- try {
- LOG.info("Creando nuevo usuario: " + dto.email);
- UserDTO created = userService.createUser(dto);
- if (created == null) {
- return Response.status(Response.Status.CONFLICT)
- .entity("{\"message\": \"Ya existe un usuario con ese email\"}").build();
- }
- return Response.status(Response.Status.CREATED).entity(created).build();
- } catch (Exception e) {
- LOG.error("Error al crear usuario", e);
- return Response.serverError().entity("Error: " + e.getMessage()).build();
- }
- }
-
- @PUT
- @Path("/{id}")
- @Transactional
- public Response updateUser(@PathParam("id") Long id, UserDTO dto) {
- try {
- LOG.info("Actualizando usuario con ID: " + id);
- UserDTO updated = userService.updateUser(id, dto);
- if (updated == null) {
- return Response.status(Response.Status.NOT_FOUND).build();
- }
- return Response.ok(updated).build();
- } catch (Exception e) {
- LOG.error("Error al actualizar usuario con ID: " + id, e);
- return Response.serverError().entity("Error: " + e.getMessage()).build();
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/service/BookingService.java b/src/main/java/com/valposystems/service/BookingService.java
index 0e405c5..eb32f3d 100644
--- a/src/main/java/com/valposystems/service/BookingService.java
+++ b/src/main/java/com/valposystems/service/BookingService.java
@@ -4,76 +4,97 @@ import com.valposystems.dto.BookingDTO;
import com.valposystems.model.Booking;
import com.valposystems.model.GymClass;
import com.valposystems.model.User;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.transaction.Transactional;
+import com.valposystems.repository.BookingRepository;
+import com.valposystems.repository.GymClassRepository;
+import com.valposystems.repository.UserRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
-@ApplicationScoped
+@Service
public class BookingService {
-
+
+ private final BookingRepository bookingRepository;
+ private final UserRepository userRepository;
+ private final GymClassRepository gymClassRepository;
+
+ @Autowired
+ public BookingService(
+ BookingRepository bookingRepository,
+ UserRepository userRepository,
+ GymClassRepository gymClassRepository) {
+ this.bookingRepository = bookingRepository;
+ this.userRepository = userRepository;
+ this.gymClassRepository = gymClassRepository;
+ }
+
public List getAllBookings() {
- return Booking.listAll().stream()
- .map(b -> BookingDTO.from((Booking) b))
+ return bookingRepository.findAll().stream()
+ .map(BookingDTO::from)
.collect(Collectors.toList());
}
-
+
public List getBookingsByUserId(Long userId) {
- List bookings = Booking.list("user.id", userId);
- return bookings.stream()
- .map(booking -> BookingDTO.from(booking))
+ return bookingRepository.findByUserId(userId).stream()
+ .map(BookingDTO::from)
.collect(Collectors.toList());
}
-
+
@Transactional
public BookingDTO createBooking(BookingDTO dto) {
- User user = User.findById(dto.userId);
- GymClass gymClass = GymClass.findById(dto.classId);
-
+ User user = userRepository.findById(dto.getUserId()).orElse(null);
+ GymClass gymClass = gymClassRepository.findById(dto.getClassId()).orElse(null);
+
if (user == null || gymClass == null) {
return null;
}
-
- // Verificar disponibilidad
- if (gymClass.currentBookings >= gymClass.maxCapacity) {
+
+ // Check availability
+ if (gymClass.getCurrentBookings() >= gymClass.getMaxCapacity()) {
return null;
}
-
- // Crear la reserva
+
+ // Create booking
Booking booking = new Booking();
- booking.user = user;
- booking.gymClass = gymClass;
- booking.bookingDate = LocalDateTime.now();
- booking.status = "confirmed";
-
- // Actualizar contador de la clase
- gymClass.currentBookings++;
-
- booking.persist();
-
+ booking.setUser(user);
+ booking.setGymClass(gymClass);
+ booking.setBookingDate(LocalDateTime.now());
+ booking.setStatus("confirmed");
+
+ // Update class counter
+ gymClass.setCurrentBookings(gymClass.getCurrentBookings() + 1);
+ gymClassRepository.save(gymClass);
+
+ booking = bookingRepository.save(booking);
+
return BookingDTO.from(booking);
}
-
+
@Transactional
public BookingDTO cancelBooking(Long id) {
- Booking booking = Booking.findById(id);
+ Booking booking = bookingRepository.findById(id).orElse(null);
if (booking == null) {
return null;
}
-
- // Solo se pueden cancelar reservas confirmadas
- if (!booking.status.equals("confirmed")) {
+
+ // Only confirmed bookings can be cancelled
+ if (!"confirmed".equals(booking.getStatus())) {
return null;
}
-
- booking.status = "cancelled";
-
- // Actualizar contador de la clase
- GymClass gymClass = booking.gymClass;
- gymClass.currentBookings--;
-
+
+ booking.setStatus("cancelled");
+
+ // Update class counter
+ GymClass gymClass = booking.getGymClass();
+ gymClass.setCurrentBookings(gymClass.getCurrentBookings() - 1);
+ gymClassRepository.save(gymClass);
+
+ booking = bookingRepository.save(booking);
+
return BookingDTO.from(booking);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/service/GymClassService.java b/src/main/java/com/valposystems/service/GymClassService.java
index b5e8ecb..921328f 100644
--- a/src/main/java/com/valposystems/service/GymClassService.java
+++ b/src/main/java/com/valposystems/service/GymClassService.java
@@ -2,75 +2,78 @@ package com.valposystems.service;
import com.valposystems.dto.GymClassDTO;
import com.valposystems.model.GymClass;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.transaction.Transactional;
+import com.valposystems.repository.GymClassRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
-@ApplicationScoped
+@Service
public class GymClassService {
-
+
+ private final GymClassRepository gymClassRepository;
+
+ @Autowired
+ public GymClassService(GymClassRepository gymClassRepository) {
+ this.gymClassRepository = gymClassRepository;
+ }
+
public List getAllClasses() {
- return GymClass.listAll().stream()
- .map(c -> GymClassDTO.from((GymClass) c))
+ return gymClassRepository.findAll().stream()
+ .map(GymClassDTO::from)
.collect(Collectors.toList());
}
-
+
public GymClassDTO getClassById(Long id) {
- GymClass gymClass = GymClass.findById(id);
- if (gymClass == null) {
- return null;
- }
- return GymClassDTO.from(gymClass);
+ return gymClassRepository.findById(id)
+ .map(GymClassDTO::from)
+ .orElse(null);
}
-
+
@Transactional
public GymClassDTO createClass(GymClassDTO dto) {
GymClass gymClass = new GymClass();
- gymClass.name = dto.name;
- gymClass.description = dto.description;
- gymClass.instructor = dto.instructor;
- gymClass.startTime = dto.startTime;
- gymClass.endTime = dto.endTime;
- gymClass.maxCapacity = dto.maxCapacity;
- gymClass.currentBookings = dto.currentBookings;
- gymClass.category = dto.category;
- gymClass.imageUrl = dto.imageUrl;
-
- gymClass.persist();
-
+ gymClass.setName(dto.getName());
+ gymClass.setDescription(dto.getDescription());
+ gymClass.setInstructor(dto.getInstructor());
+ gymClass.setStartTime(dto.getStartTime());
+ gymClass.setEndTime(dto.getEndTime());
+ gymClass.setMaxCapacity(dto.getMaxCapacity());
+ gymClass.setCurrentBookings(dto.getCurrentBookings());
+ gymClass.setCategory(dto.getCategory());
+ gymClass.setImageUrl(dto.getImageUrl());
+
+ gymClass = gymClassRepository.save(gymClass);
+
return GymClassDTO.from(gymClass);
}
-
+
@Transactional
public GymClassDTO updateClass(Long id, GymClassDTO dto) {
- GymClass gymClass = GymClass.findById(id);
- if (gymClass == null) {
- return null;
- }
-
- gymClass.name = dto.name;
- gymClass.description = dto.description;
- gymClass.instructor = dto.instructor;
- gymClass.startTime = dto.startTime;
- gymClass.endTime = dto.endTime;
- gymClass.maxCapacity = dto.maxCapacity;
- gymClass.currentBookings = dto.currentBookings;
- gymClass.category = dto.category;
- gymClass.imageUrl = dto.imageUrl;
-
- return GymClassDTO.from(gymClass);
+ return gymClassRepository.findById(id)
+ .map(gymClass -> {
+ gymClass.setName(dto.getName());
+ gymClass.setDescription(dto.getDescription());
+ gymClass.setInstructor(dto.getInstructor());
+ gymClass.setStartTime(dto.getStartTime());
+ gymClass.setEndTime(dto.getEndTime());
+ gymClass.setMaxCapacity(dto.getMaxCapacity());
+ gymClass.setCurrentBookings(dto.getCurrentBookings());
+ gymClass.setCategory(dto.getCategory());
+ gymClass.setImageUrl(dto.getImageUrl());
+ return GymClassDTO.from(gymClassRepository.save(gymClass));
+ })
+ .orElse(null);
}
-
+
@Transactional
public boolean deleteClass(Long id) {
- GymClass gymClass = GymClass.findById(id);
- if (gymClass == null) {
- return false;
+ if (gymClassRepository.existsById(id)) {
+ gymClassRepository.deleteById(id);
+ return true;
}
-
- gymClass.delete();
- return true;
+ return false;
}
}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/service/UserService.java b/src/main/java/com/valposystems/service/UserService.java
index 4686682..744c0ae 100644
--- a/src/main/java/com/valposystems/service/UserService.java
+++ b/src/main/java/com/valposystems/service/UserService.java
@@ -2,59 +2,64 @@ package com.valposystems.service;
import com.valposystems.dto.UserDTO;
import com.valposystems.model.User;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.transaction.Transactional;
+import com.valposystems.repository.UserRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
-@ApplicationScoped
+@Service
public class UserService {
-
+
+ private final UserRepository userRepository;
+
+ @Autowired
+ public UserService(UserRepository userRepository) {
+ this.userRepository = userRepository;
+ }
+
public List getAllUsers() {
- return User.listAll().stream()
- .map(u -> UserDTO.from((User) u))
+ return userRepository.findAll().stream()
+ .map(UserDTO::from)
.collect(Collectors.toList());
}
-
+
public UserDTO getUserById(Long id) {
- User user = User.findById(id);
- if (user == null) {
- return null;
- }
- return UserDTO.from(user);
+ return userRepository.findById(id)
+ .map(UserDTO::from)
+ .orElse(null);
}
-
+
@Transactional
public UserDTO createUser(UserDTO dto) {
- // Verificar si ya existe un usuario con ese email
- if (User.count("email", dto.email) > 0) {
+ // Check if a user with that email already exists
+ if (userRepository.existsByEmail(dto.getEmail())) {
return null;
}
-
+
User user = new User();
- user.name = dto.name;
- user.email = dto.email;
- user.password = "password123"; // En una app real, esto se encriptaría
- user.profilePicUrl = dto.profilePicUrl;
- user.notificationsEnabled = dto.notificationsEnabled;
-
- user.persist();
-
+ user.setName(dto.getName());
+ user.setEmail(dto.getEmail());
+ user.setPassword("password123"); // In a real app, this would be encrypted
+ user.setProfilePicUrl(dto.getProfilePicUrl());
+ user.setNotificationsEnabled(dto.isNotificationsEnabled());
+
+ user = userRepository.save(user);
+
return UserDTO.from(user);
}
-
+
@Transactional
public UserDTO updateUser(Long id, UserDTO dto) {
- User user = User.findById(id);
- if (user == null) {
- return null;
- }
-
- user.name = dto.name;
- user.profilePicUrl = dto.profilePicUrl;
- user.notificationsEnabled = dto.notificationsEnabled;
-
- return UserDTO.from(user);
+ return userRepository.findById(id)
+ .map(user -> {
+ user.setName(dto.getName());
+ user.setProfilePicUrl(dto.getProfilePicUrl());
+ user.setNotificationsEnabled(dto.isNotificationsEnabled());
+ return UserDTO.from(userRepository.save(user));
+ })
+ .orElse(null);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/valposystems/util/DataLoader.java b/src/main/java/com/valposystems/util/DataLoader.java
index 02ce684..1d61839 100644
--- a/src/main/java/com/valposystems/util/DataLoader.java
+++ b/src/main/java/com/valposystems/util/DataLoader.java
@@ -2,108 +2,121 @@ package com.valposystems.util;
import com.valposystems.model.GymClass;
import com.valposystems.model.User;
-import io.quarkus.runtime.StartupEvent;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.enterprise.event.Observes;
-import jakarta.transaction.Transactional;
-import org.jboss.logging.Logger;
+import com.valposystems.repository.GymClassRepository;
+import com.valposystems.repository.UserRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
-@ApplicationScoped
-public class DataLoader {
+@Component
+public class DataLoader implements CommandLineRunner {
- private static final Logger LOG = Logger.getLogger(DataLoader.class);
-
+ private static final Logger logger = LoggerFactory.getLogger(DataLoader.class);
+
+ private final UserRepository userRepository;
+ private final GymClassRepository gymClassRepository;
+
+ @Autowired
+ public DataLoader(UserRepository userRepository, GymClassRepository gymClassRepository) {
+ this.userRepository = userRepository;
+ this.gymClassRepository = gymClassRepository;
+ }
+
+ @Override
@Transactional
- public void loadData(@Observes StartupEvent evt) {
- LOG.info("Verificando si es necesario cargar datos iniciales...");
+ public void run(String... args) {
+ logger.info("Checking if initial data needs to be loaded...");
- // Verificar si ya hay datos
- if (GymClass.count() > 0 || User.count() > 0) {
- LOG.info("Ya existen datos en la base de datos, no se cargarán datos iniciales");
+ // Check if data already exists
+ if (gymClassRepository.count() > 0 || userRepository.count() > 0) {
+ logger.info("Data already exists in the database, will not load initial data");
return;
}
- LOG.info("Cargando datos iniciales...");
-
- // Crear usuario demo
+ logger.info("Loading initial data...");
+
+ // Create demo user
User demoUser = new User(
- "Usuario Demo",
- "usuario@ejemplo.com",
+ "Demo User",
+ "user@example.com",
"password123",
"/uploads/default-avatar.jpg",
true
);
- demoUser.persist();
- LOG.info("Usuario demo creado con ID: " + demoUser.id);
-
- // Crear clases de ejemplo
+ userRepository.save(demoUser);
+ logger.info("Demo user created with ID: {}", demoUser.getId());
+
+ // Create example classes
GymClass yoga = new GymClass(
"Yoga",
- "Clase de yoga para todos los niveles",
+ "Yoga class for all levels",
"María López",
LocalDateTime.now().plusDays(1).withHour(8).withMinute(0),
LocalDateTime.now().plusDays(1).withHour(9).withMinute(0),
15,
8,
- "Mente y Cuerpo",
+ "Mind and Body",
"/uploads/yoga.png"
);
- yoga.persist();
-
+ gymClassRepository.save(yoga);
+
GymClass spinning = new GymClass(
"Spinning",
- "Clase de alta intensidad de ciclismo estático",
+ "High intensity static cycling class",
"Juan Pérez",
LocalDateTime.now().plusDays(1).withHour(10).withMinute(0),
LocalDateTime.now().plusDays(1).withHour(11).withMinute(0),
20,
15,
- "Cardiovascular",
+ "Cardio",
"/uploads/spinning.png"
);
- spinning.persist();
-
+ gymClassRepository.save(spinning);
+
GymClass pilates = new GymClass(
"Pilates",
- "Fortalecimiento de core y flexibilidad",
+ "Core strength and flexibility",
"Ana García",
LocalDateTime.now().plusDays(1).withHour(16).withMinute(0),
LocalDateTime.now().plusDays(1).withHour(17).withMinute(0),
12,
5,
- "Mente y Cuerpo",
+ "Mind and Body",
"/uploads/pilates.png"
);
- pilates.persist();
-
+ gymClassRepository.save(pilates);
+
GymClass zumba = new GymClass(
"Zumba",
- "Baile y ejercicio cardiovascular",
+ "Dance and cardiovascular exercise",
"Carlos Martínez",
LocalDateTime.now().plusDays(2).withHour(18).withMinute(0),
LocalDateTime.now().plusDays(2).withHour(19).withMinute(0),
25,
18,
- "Baile",
+ "Dance",
"/uploads/zumba.png"
);
- zumba.persist();
-
+ gymClassRepository.save(zumba);
+
GymClass crossfit = new GymClass(
"CrossFit",
- "Entrenamiento funcional de alta intensidad",
+ "High intensity functional training",
"Roberto Sánchez",
LocalDateTime.now().plusDays(2).withHour(9).withMinute(0),
LocalDateTime.now().plusDays(2).withHour(10).withMinute(0),
15,
12,
- "Fuerza",
+ "Strength",
"/uploads/crossfit.png"
);
- crossfit.persist();
+ gymClassRepository.save(crossfit);
- LOG.info("Se han cargado " + GymClass.count() + " clases de ejemplo");
+ logger.info("Loaded {} example classes", gymClassRepository.count());
}
}
\ No newline at end of file
diff --git a/src/main/resources/META-INF/beans.xml b/src/main/resources/META-INF/beans.xml
deleted file mode 100644
index f90fd8b..0000000
--- a/src/main/resources/META-INF/beans.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
new file mode 100644
index 0000000..0d9a804
--- /dev/null
+++ b/src/main/resources/application-prod.properties
@@ -0,0 +1,13 @@
+# Production profile configuration
+spring.datasource.url=${SPRING_DATASOURCE_URL:jdbc:postgresql://db:5432/gymdb}
+spring.datasource.username=${SPRING_DATASOURCE_USERNAME:postgres}
+spring.datasource.password=${SPRING_DATASOURCE_PASSWORD:postgres}
+spring.datasource.driver-class-name=org.postgresql.Driver
+
+# JPA/Hibernate
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.show-sql=false
+
+# Server
+server.port=8080
+server.address=0.0.0.0
\ No newline at end of file
diff --git a/src/main/resources/application.prod.properties b/src/main/resources/application.prod.properties
deleted file mode 100644
index 6056ec7..0000000
--- a/src/main/resources/application.prod.properties
+++ /dev/null
@@ -1,40 +0,0 @@
-# Configuración de la base de datos
-quarkus.datasource.db-kind=postgresql
-quarkus.datasource.username=${DB_USERNAME}
-quarkus.datasource.password=${DB_PASSWORD}
-quarkus.datasource.jdbc.url=jdbc:postgresql://${POSTGRESSHOST}:${POSTGRESSPORT}/{POSTGRESSDATABASE}
-
-# Configuración de Hibernate ORM
-quarkus.hibernate-orm.database.generation=update
-quarkus.hibernate-orm.log.sql=true
-quarkus.hibernate-orm.jdbc.statement-batch-size=20
-
-# Configuración CORS para permitir peticiones desde nuestra app Ionic
-quarkus.http.cors=true
-quarkus.http.cors.origins=*
-quarkus.http.cors.methods=GET,POST,PUT,DELETE,OPTIONS
-quarkus.http.cors.headers=Content-Type,Authorization
-quarkus.http.cors.exposed-headers=Content-Disposition
-quarkus.http.cors.access-control-max-age=24H
-
-# Configuración para archivos estáticos
-quarkus.http.body.uploads-directory=uploads
-quarkus.http.body.handle-file-uploads=true
-quarkus.http.static.path=/uploads
-quarkus.http.static.dir=uploads
-
-# Configuración de logging
-quarkus.log.console.enable=true
-quarkus.log.console.format=%d{HH:mm:ss} %-5p [%c{2.}] (%t) %s%e%n
-quarkus.log.console.level=INFO
-quarkus.log.category."org.hibernate".level=INFO
-quarkus.log.category."io.quarkus.arc".level=INFO
-
-# Configuración de JSON binding
-quarkus.jackson.write-dates-as-timestamps=false
-quarkus.jackson.fail-on-unknown-properties=false
-
-# Configuración CDI
-quarkus.arc.remove-unused-beans=false
-
-# Server host
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 973f661..3415bb9 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,41 +1,41 @@
-# Configuración de la base de datos
-quarkus.datasource.db-kind=postgresql
-quarkus.datasource.username=postgres
-quarkus.datasource.password=postgres
-quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/gymdb
+# Database Configuration
+spring.datasource.url=jdbc:postgresql://localhost:5432/gymdb
+spring.datasource.username=postgres
+spring.datasource.password=postgres
+spring.datasource.driver-class-name=org.postgresql.Driver
-# Configuración de Hibernate ORM
-quarkus.hibernate-orm.database.generation=update
-quarkus.hibernate-orm.log.sql=true
-quarkus.hibernate-orm.jdbc.statement-batch-size=20
+# JPA / Hibernate
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.show-sql=true
+spring.jpa.properties.hibernate.format_sql=true
+spring.jpa.properties.hibernate.jdbc.batch_size=20
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
-# Configuración CORS para permitir peticiones desde nuestra app Ionic
-quarkus.http.cors=true
-quarkus.http.cors.origins=*
-quarkus.http.cors.methods=GET,POST,PUT,DELETE,OPTIONS
-quarkus.http.cors.headers=Content-Type,Authorization
-quarkus.http.cors.exposed-headers=Content-Disposition
-quarkus.http.cors.access-control-max-age=24H
+# Web
+spring.servlet.multipart.max-file-size=10MB
+spring.servlet.multipart.max-request-size=10MB
-# Configuración para archivos estáticos
-quarkus.http.body.uploads-directory=uploads
-quarkus.http.body.handle-file-uploads=true
-quarkus.http.static.path=/uploads
-quarkus.http.static.dir=uploads
+# File storage
+app.upload.dir=uploads
+spring.web.resources.static-locations=file:uploads/
-# Configuración de logging
-quarkus.log.console.enable=true
-quarkus.log.console.format=%d{HH:mm:ss} %-5p [%c{2.}] (%t) %s%e%n
-quarkus.log.console.level=INFO
-quarkus.log.category."org.hibernate".level=INFO
-quarkus.log.category."io.quarkus.arc".level=INFO
+# Jackson JSON
+spring.jackson.serialization.write-dates-as-timestamps=false
+spring.jackson.deserialization.fail-on-unknown-properties=false
-# Configuración de JSON binding
-quarkus.jackson.write-dates-as-timestamps=false
-quarkus.jackson.fail-on-unknown-properties=false
+# Logging
+logging.level.root=INFO
+logging.level.org.hibernate=INFO
+logging.level.org.springframework.web=INFO
+logging.pattern.console=%d{HH:mm:ss} %-5level [%logger{36}] - %msg%n
-# Configuración CDI
-quarkus.arc.remove-unused-beans=false
+# Server
+server.port=8080
+server.address=0.0.0.0
-# Server host
-quarkus.http.host=0.0.0.0
\ No newline at end of file
+# CORS
+spring.web.cors.allowed-origins=*
+spring.web.cors.allowed-methods=GET,POST,PUT,DELETE,OPTIONS
+spring.web.cors.allowed-headers=Content-Type,Authorization
+spring.web.cors.exposed-headers=Content-Disposition
+spring.web.cors.max-age=3600
\ No newline at end of file
diff --git a/src/main/resources/import.sql b/src/main/resources/import.sql
deleted file mode 100644
index 16aa523..0000000
--- a/src/main/resources/import.sql
+++ /dev/null
@@ -1,6 +0,0 @@
--- This file allow to write SQL commands that will be emitted in test and dev.
--- The commands are commented as their support depends of the database
--- insert into myentity (id, field) values(1, 'field-1');
--- insert into myentity (id, field) values(2, 'field-2');
--- insert into myentity (id, field) values(3, 'field-3');
--- alter sequence myentity_seq restart with 4;
\ No newline at end of file
diff --git a/src/test/java/com/valposystems/GreetingResourceIT.java b/src/test/java/com/valposystems/GreetingResourceIT.java
deleted file mode 100644
index 9c86a97..0000000
--- a/src/test/java/com/valposystems/GreetingResourceIT.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.valposystems;
-
-import io.quarkus.test.junit.QuarkusIntegrationTest;
-
-@QuarkusIntegrationTest
-class GreetingResourceIT extends GreetingResourceTest {
- // Execute the same tests but in packaged mode.
-}
diff --git a/src/test/java/com/valposystems/GreetingResourceTest.java b/src/test/java/com/valposystems/GreetingResourceTest.java
deleted file mode 100644
index 564c692..0000000
--- a/src/test/java/com/valposystems/GreetingResourceTest.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.valposystems;
-
-import io.quarkus.test.junit.QuarkusTest;
-import org.junit.jupiter.api.Test;
-
-import static io.restassured.RestAssured.given;
-import static org.hamcrest.CoreMatchers.is;
-
-@QuarkusTest
-class GreetingResourceTest {
- @Test
- void testHelloEndpoint() {
- given()
- .when().get("/hello")
- .then()
- .statusCode(200)
- .body(is("Hello RESTEasy"));
- }
-
-}
\ No newline at end of file