Backend project initialized #4
49
.gitea/README.md
Normal file
49
.gitea/README.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# Gitea Actions for Vibing Project
|
||||||
|
|
||||||
|
This directory contains Gitea Actions workflows for the Vibing project (both frontend and backend).
|
||||||
|
|
||||||
|
## Workflows
|
||||||
|
|
||||||
|
### Backend CI (`backend-ci.yml`)
|
||||||
|
|
||||||
|
Runs Maven tests on the backend project.
|
||||||
|
|
||||||
|
**Triggers:**
|
||||||
|
- Push to `main` or `develop` branches
|
||||||
|
- Pull requests to `main` or `develop` branches
|
||||||
|
- Only when changes are made to files in the `backend/` directory
|
||||||
|
|
||||||
|
**What it does:**
|
||||||
|
1. Checks out the code
|
||||||
|
2. Sets up Java 21 (Temurin distribution)
|
||||||
|
3. Caches Maven dependencies for faster builds
|
||||||
|
4. Runs `mvn test` in the backend directory
|
||||||
|
5. Uploads test results as artifacts (retained for 7 days)
|
||||||
|
|
||||||
|
**Requirements:**
|
||||||
|
- Java 21
|
||||||
|
- Maven
|
||||||
|
- Ubuntu runner
|
||||||
|
|
||||||
|
### Frontend CI (`frontend-ci.yml`)
|
||||||
|
|
||||||
|
Runs linting and builds the frontend project.
|
||||||
|
|
||||||
|
**Triggers:**
|
||||||
|
- Push to `main` or `develop` branches
|
||||||
|
- Pull requests to `main` or `develop` branches
|
||||||
|
- Only when changes are made to files in the `frontend/` directory
|
||||||
|
|
||||||
|
**What it does:**
|
||||||
|
1. Checks out the code
|
||||||
|
2. Sets up Node.js 18
|
||||||
|
3. Caches npm dependencies for faster builds
|
||||||
|
4. Installs dependencies with `npm ci`
|
||||||
|
5. Runs ESLint for code quality checks
|
||||||
|
6. Builds the project with `npm run build`
|
||||||
|
7. Uploads build artifacts (retained for 7 days)
|
||||||
|
|
||||||
|
**Requirements:**
|
||||||
|
- Node.js 18
|
||||||
|
- npm
|
||||||
|
- Ubuntu runner
|
||||||
44
.gitea/workflows/backend-ci.yml
Normal file
44
.gitea/workflows/backend-ci.yml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
name: Backend CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main, develop ]
|
||||||
|
paths:
|
||||||
|
- 'backend/**'
|
||||||
|
pull_request:
|
||||||
|
branches: [ main, develop ]
|
||||||
|
paths:
|
||||||
|
- 'backend/**'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Run Maven Tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up JDK 21
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
java-version: '21'
|
||||||
|
distribution: 'temurin'
|
||||||
|
cache: 'maven'
|
||||||
|
|
||||||
|
- name: Set up Maven
|
||||||
|
uses: stCarolas/setup-maven@v5
|
||||||
|
with:
|
||||||
|
maven-version: '3.6.3'
|
||||||
|
|
||||||
|
- name: Run Maven tests
|
||||||
|
working-directory: ./backend
|
||||||
|
run: mvn test
|
||||||
|
|
||||||
|
- name: Upload test results
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: backend-test-results
|
||||||
|
path: backend/target/surefire-reports/
|
||||||
|
retention-days: 7
|
||||||
99
backend/.gitignore
vendored
Normal file
99
backend/.gitignore
vendored
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
# Compiled class file
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# BlueJ files
|
||||||
|
*.ctxt
|
||||||
|
|
||||||
|
# Mobile Tools for Java (J2ME)
|
||||||
|
.mtj.tmp/
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.nar
|
||||||
|
*.ear
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
replay_pid*
|
||||||
|
|
||||||
|
# Maven
|
||||||
|
target/
|
||||||
|
pom.xml.tag
|
||||||
|
pom.xml.releaseBackup
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
pom.xml.next
|
||||||
|
release.properties
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
buildNumber.properties
|
||||||
|
.mvn/timing.properties
|
||||||
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
|
|
||||||
|
# IDE files
|
||||||
|
.idea/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
.vscode/
|
||||||
|
.settings/
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
|
||||||
|
# OS generated files
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Application specific
|
||||||
|
application-local.yml
|
||||||
|
application-prod.yml
|
||||||
|
*.db
|
||||||
|
*.sqlite
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs/
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage/
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
193
backend/README.md
Normal file
193
backend/README.md
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
# Vibing Backend
|
||||||
|
|
||||||
|
A REST API backend service built with Spring Boot, Java 21, and Maven for the Vibing application.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **RESTful API**: Complete CRUD operations for user management
|
||||||
|
- **Spring Boot 3.2.0**: Latest Spring Boot version with Java 21 support
|
||||||
|
- **JPA/Hibernate**: Database persistence with H2 in-memory database
|
||||||
|
- **Spring Security**: Basic security configuration (extensible for production)
|
||||||
|
- **API Documentation**: Swagger/OpenAPI 3 documentation
|
||||||
|
- **Validation**: Input validation using Bean Validation
|
||||||
|
- **Testing**: JUnit 5 test framework
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Java 21 or higher
|
||||||
|
- Maven 3.6 or higher
|
||||||
|
- IDE (IntelliJ IDEA, Eclipse, VS Code, etc.)
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### 1. Clone the Repository
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone <repository-url>
|
||||||
|
cd vibing/backend
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Build the Project
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mvn clean install
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Run the Application
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mvn spring-boot:run
|
||||||
|
```
|
||||||
|
|
||||||
|
The application will start on `http://localhost:8080`
|
||||||
|
|
||||||
|
## API Endpoints
|
||||||
|
|
||||||
|
### Base URL
|
||||||
|
- **API Base**: `http://localhost:8080/api`
|
||||||
|
- **Health Check**: `http://localhost:8080/api/health`
|
||||||
|
- **Swagger UI**: `http://localhost:8080/swagger-ui.html`
|
||||||
|
- **H2 Console**: `http://localhost:8080/h2-console`
|
||||||
|
|
||||||
|
### User Management Endpoints
|
||||||
|
|
||||||
|
| Method | Endpoint | Description |
|
||||||
|
|--------|----------|-------------|
|
||||||
|
| GET | `/api/users` | Get all users |
|
||||||
|
| GET | `/api/users/{id}` | Get user by ID |
|
||||||
|
| GET | `/api/users/username/{username}` | Get user by username |
|
||||||
|
| POST | `/api/users` | Create new user |
|
||||||
|
| PUT | `/api/users/{id}` | Update user |
|
||||||
|
| DELETE | `/api/users/{id}` | Delete user |
|
||||||
|
| GET | `/api/users/check-username/{username}` | Check username availability |
|
||||||
|
| GET | `/api/users/check-email/{email}` | Check email availability |
|
||||||
|
|
||||||
|
### Health Check Endpoints
|
||||||
|
|
||||||
|
| Method | Endpoint | Description |
|
||||||
|
|--------|----------|-------------|
|
||||||
|
| GET | `/api/health` | Application health status |
|
||||||
|
| GET | `/api/health/ping` | Simple ping endpoint |
|
||||||
|
|
||||||
|
## Database
|
||||||
|
|
||||||
|
The application uses H2 in-memory database for development:
|
||||||
|
|
||||||
|
- **URL**: `jdbc:h2:mem:testdb`
|
||||||
|
- **Username**: `sa`
|
||||||
|
- **Password**: `password`
|
||||||
|
- **Console**: `http://localhost:8080/h2-console`
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
├── main/
|
||||||
|
│ ├── java/com/vibing/backend/
|
||||||
|
│ │ ├── VibingBackendApplication.java # Main application class
|
||||||
|
│ │ ├── controller/ # REST controllers
|
||||||
|
│ │ │ ├── UserController.java
|
||||||
|
│ │ │ └── HealthController.java
|
||||||
|
│ │ ├── service/ # Business logic
|
||||||
|
│ │ │ └── UserService.java
|
||||||
|
│ │ ├── repository/ # Data access layer
|
||||||
|
│ │ │ └── UserRepository.java
|
||||||
|
│ │ ├── model/ # Entity classes
|
||||||
|
│ │ │ └── User.java
|
||||||
|
│ │ ├── config/ # Configuration classes
|
||||||
|
│ │ │ └── SecurityConfig.java
|
||||||
|
│ │ └── exception/ # Custom exceptions
|
||||||
|
│ └── resources/
|
||||||
|
│ └── application.yml # Application configuration
|
||||||
|
└── test/
|
||||||
|
└── java/com/vibing/backend/
|
||||||
|
└── VibingBackendApplicationTests.java
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The application configuration is in `src/main/resources/application.yml`:
|
||||||
|
|
||||||
|
- **Server Port**: 8080
|
||||||
|
- **Context Path**: `/api`
|
||||||
|
- **Database**: H2 in-memory
|
||||||
|
- **JPA**: Hibernate with create-drop DDL
|
||||||
|
- **Security**: Basic configuration (allows all user endpoints)
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Running Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mvn test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Building JAR
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mvn clean package
|
||||||
|
```
|
||||||
|
|
||||||
|
The JAR file will be created in the `target/` directory.
|
||||||
|
|
||||||
|
### Running JAR
|
||||||
|
|
||||||
|
```bash
|
||||||
|
java -jar target/vibing-backend-1.0.0.jar
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Documentation
|
||||||
|
|
||||||
|
Once the application is running, you can access:
|
||||||
|
|
||||||
|
- **Swagger UI**: `http://localhost:8080/swagger-ui.html`
|
||||||
|
- **OpenAPI JSON**: `http://localhost:8080/api-docs`
|
||||||
|
|
||||||
|
## Example API Usage
|
||||||
|
|
||||||
|
### Create a User
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:8080/api/users \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"username": "john_doe",
|
||||||
|
"email": "john@example.com",
|
||||||
|
"password": "password123",
|
||||||
|
"firstName": "John",
|
||||||
|
"lastName": "Doe"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Get All Users
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8080/api/users
|
||||||
|
```
|
||||||
|
|
||||||
|
### Get User by ID
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8080/api/users/1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
The current security configuration allows all requests to user endpoints for development purposes. For production:
|
||||||
|
|
||||||
|
1. Implement proper authentication (JWT, OAuth2, etc.)
|
||||||
|
2. Add role-based authorization
|
||||||
|
3. Configure CORS properly
|
||||||
|
4. Use HTTPS
|
||||||
|
5. Implement rate limiting
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
1. Create a feature branch
|
||||||
|
2. Make your changes
|
||||||
|
3. Add tests
|
||||||
|
4. Submit a pull request
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the MIT License.
|
||||||
116
backend/pom.xml
Normal file
116
backend/pom.xml
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||||
|
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.vibing</groupId>
|
||||||
|
<artifactId>vibing-backend</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<name>Vibing Backend</name>
|
||||||
|
<description>REST API backend service for Vibing application</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>21</java.version>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- Spring Boot Starters -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Database -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Development Tools -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Test Dependencies -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JSON Processing -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- API Documentation -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springdoc</groupId>
|
||||||
|
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||||
|
<version>2.2.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.11.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>21</source>
|
||||||
|
<target>21</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>3.1.2</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
35
backend/run.sh
Executable file
35
backend/run.sh
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Vibing Backend Run Script
|
||||||
|
echo "Starting Vibing Backend..."
|
||||||
|
|
||||||
|
# Check if Java 21 is available
|
||||||
|
if ! command -v java &> /dev/null; then
|
||||||
|
echo "Error: Java is not installed or not in PATH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check Java version
|
||||||
|
JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2 | cut -d'.' -f1)
|
||||||
|
if [ "$JAVA_VERSION" != "21" ]; then
|
||||||
|
echo "Warning: Java 21 is recommended. Current version: $JAVA_VERSION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if Maven is available
|
||||||
|
if ! command -v mvn &> /dev/null; then
|
||||||
|
echo "Error: Maven is not installed or not in PATH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Building and running the application..."
|
||||||
|
echo "The application will be available at:"
|
||||||
|
echo " - API Base: http://localhost:8080/api"
|
||||||
|
echo " - Health Check: http://localhost:8080/api/health"
|
||||||
|
echo " - Swagger UI: http://localhost:8080/swagger-ui.html"
|
||||||
|
echo " - H2 Console: http://localhost:8080/h2-console"
|
||||||
|
echo ""
|
||||||
|
echo "Press Ctrl+C to stop the application"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Run the application
|
||||||
|
mvn spring-boot:run
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.vibing.backend;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main Spring Boot application class for the Vibing backend service.
|
||||||
|
* This class serves as the entry point for the REST API backend.
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class VibingBackendApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(VibingBackendApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.vibing.backend.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Security configuration for the Vibing backend application.
|
||||||
|
* This is a basic configuration that can be extended for production use.
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class SecurityConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure security filter chain.
|
||||||
|
* For development purposes, this allows all requests.
|
||||||
|
* In production, you should implement proper authentication and authorization.
|
||||||
|
*
|
||||||
|
* @param http the HttpSecurity object
|
||||||
|
* @return SecurityFilterChain
|
||||||
|
* @throws Exception if configuration fails
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.csrf(AbstractHttpConfigurer::disable) // Disable CSRF for REST APIa
|
||||||
|
.authorizeHttpRequests(authz -> authz.anyRequest().permitAll())
|
||||||
|
.headers(headers -> headers.frameOptions().disable()); // Allow H2 console frames
|
||||||
|
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.vibing.backend.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Health check controller for monitoring the application status.
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/health")
|
||||||
|
@Tag(name = "Health Check", description = "APIs for checking application health")
|
||||||
|
public class HealthController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the health status of the application.
|
||||||
|
*
|
||||||
|
* @return ResponseEntity containing health information
|
||||||
|
*/
|
||||||
|
@GetMapping
|
||||||
|
@Operation(summary = "Health check", description = "Check if the application is running")
|
||||||
|
public ResponseEntity<Map<String, Object>> healthCheck() {
|
||||||
|
Map<String, Object> healthInfo = new HashMap<>();
|
||||||
|
healthInfo.put("status", "UP");
|
||||||
|
healthInfo.put("timestamp", LocalDateTime.now());
|
||||||
|
healthInfo.put("service", "Vibing Backend");
|
||||||
|
healthInfo.put("version", "1.0.0");
|
||||||
|
|
||||||
|
return ResponseEntity.ok(healthInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a simple ping response.
|
||||||
|
*
|
||||||
|
* @return ResponseEntity with "pong" message
|
||||||
|
*/
|
||||||
|
@GetMapping("/ping")
|
||||||
|
@Operation(summary = "Ping", description = "Simple ping endpoint")
|
||||||
|
public ResponseEntity<String> ping() {
|
||||||
|
return ResponseEntity.ok("pong");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
package com.vibing.backend.controller;
|
||||||
|
|
||||||
|
import com.vibing.backend.model.User;
|
||||||
|
import com.vibing.backend.service.UserService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
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;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST controller for User-related operations.
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/users")
|
||||||
|
@Tag(name = "User Management", description = "APIs for managing users")
|
||||||
|
@CrossOrigin(origins = "*") // Configure this properly for production
|
||||||
|
public class UserController {
|
||||||
|
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public UserController(UserService userService) {
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all users.
|
||||||
|
*
|
||||||
|
* @return ResponseEntity containing list of users
|
||||||
|
*/
|
||||||
|
@GetMapping
|
||||||
|
@Operation(summary = "Get all users", description = "Retrieve a list of all users")
|
||||||
|
public ResponseEntity<List<User>> getAllUsers() {
|
||||||
|
List<User> users = userService.getAllUsers();
|
||||||
|
return ResponseEntity.ok(users);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a user by ID.
|
||||||
|
*
|
||||||
|
* @param id the user ID
|
||||||
|
* @return ResponseEntity containing the user if found
|
||||||
|
*/
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
@Operation(summary = "Get user by ID", description = "Retrieve a specific user by their ID")
|
||||||
|
public ResponseEntity<User> getUserById(@PathVariable Long id) {
|
||||||
|
Optional<User> user = userService.getUserById(id);
|
||||||
|
return user.map(ResponseEntity::ok)
|
||||||
|
.orElse(ResponseEntity.notFound().build());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a user by username.
|
||||||
|
*
|
||||||
|
* @param username the username
|
||||||
|
* @return ResponseEntity containing the user if found
|
||||||
|
*/
|
||||||
|
@GetMapping("/username/{username}")
|
||||||
|
@Operation(summary = "Get user by username", description = "Retrieve a specific user by their username")
|
||||||
|
public ResponseEntity<User> getUserByUsername(@PathVariable String username) {
|
||||||
|
Optional<User> user = userService.getUserByUsername(username);
|
||||||
|
return user.map(ResponseEntity::ok)
|
||||||
|
.orElse(ResponseEntity.notFound().build());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new user.
|
||||||
|
*
|
||||||
|
* @param user the user to create
|
||||||
|
* @return ResponseEntity containing the created user
|
||||||
|
*/
|
||||||
|
@PostMapping
|
||||||
|
@Operation(summary = "Create a new user", description = "Create a new user account")
|
||||||
|
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
|
||||||
|
try {
|
||||||
|
User createdUser = userService.createUser(user);
|
||||||
|
return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
return ResponseEntity.badRequest().build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update an existing user.
|
||||||
|
*
|
||||||
|
* @param id the user ID
|
||||||
|
* @param user the updated user data
|
||||||
|
* @return ResponseEntity containing the updated user
|
||||||
|
*/
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
@Operation(summary = "Update user", description = "Update an existing user's information")
|
||||||
|
public ResponseEntity<User> updateUser(@PathVariable Long id, @Valid @RequestBody User user) {
|
||||||
|
Optional<User> updatedUser = userService.updateUser(id, user);
|
||||||
|
return updatedUser.map(ResponseEntity::ok)
|
||||||
|
.orElse(ResponseEntity.notFound().build());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a user by ID.
|
||||||
|
*
|
||||||
|
* @param id the user ID
|
||||||
|
* @return ResponseEntity indicating success or failure
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
@Operation(summary = "Delete user", description = "Delete a user by their ID")
|
||||||
|
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
|
||||||
|
boolean deleted = userService.deleteUser(id);
|
||||||
|
return deleted ? ResponseEntity.noContent().build() : ResponseEntity.notFound().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a username exists.
|
||||||
|
*
|
||||||
|
* @param username the username to check
|
||||||
|
* @return ResponseEntity with boolean indicating existence
|
||||||
|
*/
|
||||||
|
@GetMapping("/check-username/{username}")
|
||||||
|
@Operation(summary = "Check username availability", description = "Check if a username is already taken")
|
||||||
|
public ResponseEntity<Boolean> checkUsernameExists(@PathVariable String username) {
|
||||||
|
boolean exists = userService.userExistsByUsername(username);
|
||||||
|
return ResponseEntity.ok(exists);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an email exists.
|
||||||
|
*
|
||||||
|
* @param email the email to check
|
||||||
|
* @return ResponseEntity with boolean indicating existence
|
||||||
|
*/
|
||||||
|
@GetMapping("/check-email/{email}")
|
||||||
|
@Operation(summary = "Check email availability", description = "Check if an email is already registered")
|
||||||
|
public ResponseEntity<Boolean> checkEmailExists(@PathVariable String email) {
|
||||||
|
boolean exists = userService.userExistsByEmail(email);
|
||||||
|
return ResponseEntity.ok(exists);
|
||||||
|
}
|
||||||
|
}
|
||||||
144
backend/src/main/java/com/vibing/backend/model/User.java
Normal file
144
backend/src/main/java/com/vibing/backend/model/User.java
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
package com.vibing.backend.model;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import jakarta.validation.constraints.Email;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User entity representing a user in the Vibing application.
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name = "users")
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@NotBlank(message = "Username is required")
|
||||||
|
@Size(min = 3, max = 50, message = "Username must be between 3 and 50 characters")
|
||||||
|
@Column(unique = true, nullable = false)
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@NotBlank(message = "Email is required")
|
||||||
|
@Email(message = "Email should be valid")
|
||||||
|
@Column(unique = true, nullable = false)
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@NotBlank(message = "Password is required")
|
||||||
|
@Size(min = 6, message = "Password must be at least 6 characters")
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@Column(name = "first_name")
|
||||||
|
private String firstName;
|
||||||
|
|
||||||
|
@Column(name = "last_name")
|
||||||
|
private String lastName;
|
||||||
|
|
||||||
|
@Column(name = "created_at")
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@Column(name = "updated_at")
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
|
@PrePersist
|
||||||
|
protected void onCreate() {
|
||||||
|
createdAt = LocalDateTime.now();
|
||||||
|
updatedAt = LocalDateTime.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreUpdate
|
||||||
|
protected void onUpdate() {
|
||||||
|
updatedAt = LocalDateTime.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
public User() {}
|
||||||
|
|
||||||
|
public User(String username, String email, String password) {
|
||||||
|
this.username = username;
|
||||||
|
this.email = email;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedAt(LocalDateTime createdAt) {
|
||||||
|
this.createdAt = createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getUpdatedAt() {
|
||||||
|
return updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||||
|
this.updatedAt = updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "User{" +
|
||||||
|
"id=" + id +
|
||||||
|
", username='" + username + '\'' +
|
||||||
|
", email='" + email + '\'' +
|
||||||
|
", firstName='" + firstName + '\'' +
|
||||||
|
", lastName='" + lastName + '\'' +
|
||||||
|
", createdAt=" + createdAt +
|
||||||
|
", updatedAt=" + updatedAt +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.vibing.backend.repository;
|
||||||
|
|
||||||
|
import com.vibing.backend.model.User;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repository interface for User entity operations.
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public interface UserRepository extends JpaRepository<User, Long> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a user by username.
|
||||||
|
*
|
||||||
|
* @param username the username to search for
|
||||||
|
* @return Optional containing the user if found
|
||||||
|
*/
|
||||||
|
Optional<User> findByUsername(String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a user by email.
|
||||||
|
*
|
||||||
|
* @param email the email to search for
|
||||||
|
* @return Optional containing the user if found
|
||||||
|
*/
|
||||||
|
Optional<User> findByEmail(String email);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a user exists by username.
|
||||||
|
*
|
||||||
|
* @param username the username to check
|
||||||
|
* @return true if user exists, false otherwise
|
||||||
|
*/
|
||||||
|
boolean existsByUsername(String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a user exists by email.
|
||||||
|
*
|
||||||
|
* @param email the email to check
|
||||||
|
* @return true if user exists, false otherwise
|
||||||
|
*/
|
||||||
|
boolean existsByEmail(String email);
|
||||||
|
}
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
package com.vibing.backend.service;
|
||||||
|
|
||||||
|
import com.vibing.backend.model.User;
|
||||||
|
import com.vibing.backend.repository.UserRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service class for User-related business operations.
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class UserService {
|
||||||
|
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public UserService(UserRepository userRepository) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all users.
|
||||||
|
*
|
||||||
|
* @return List of all users
|
||||||
|
*/
|
||||||
|
public List<User> getAllUsers() {
|
||||||
|
return userRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a user by ID.
|
||||||
|
*
|
||||||
|
* @param id the user ID
|
||||||
|
* @return Optional containing the user if found
|
||||||
|
*/
|
||||||
|
public Optional<User> getUserById(Long id) {
|
||||||
|
return userRepository.findById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a user by username.
|
||||||
|
*
|
||||||
|
* @param username the username
|
||||||
|
* @return Optional containing the user if found
|
||||||
|
*/
|
||||||
|
public Optional<User> getUserByUsername(String username) {
|
||||||
|
return userRepository.findByUsername(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a user by email.
|
||||||
|
*
|
||||||
|
* @param email the email
|
||||||
|
* @return Optional containing the user if found
|
||||||
|
*/
|
||||||
|
public Optional<User> getUserByEmail(String email) {
|
||||||
|
return userRepository.findByEmail(email);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new user.
|
||||||
|
*
|
||||||
|
* @param user the user to create
|
||||||
|
* @return the created user
|
||||||
|
*/
|
||||||
|
public User createUser(User user) {
|
||||||
|
// Check if username already exists
|
||||||
|
if (userRepository.existsByUsername(user.getUsername())) {
|
||||||
|
throw new RuntimeException("Username already exists: " + user.getUsername());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if email already exists
|
||||||
|
if (userRepository.existsByEmail(user.getEmail())) {
|
||||||
|
throw new RuntimeException("Email already exists: " + user.getEmail());
|
||||||
|
}
|
||||||
|
|
||||||
|
return userRepository.save(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update an existing user.
|
||||||
|
*
|
||||||
|
* @param id the user ID
|
||||||
|
* @param user the updated user data
|
||||||
|
* @return Optional containing the updated user if found
|
||||||
|
*/
|
||||||
|
public Optional<User> updateUser(Long id, User user) {
|
||||||
|
return userRepository.findById(id)
|
||||||
|
.map(existingUser -> {
|
||||||
|
existingUser.setUsername(user.getUsername());
|
||||||
|
existingUser.setEmail(user.getEmail());
|
||||||
|
existingUser.setFirstName(user.getFirstName());
|
||||||
|
existingUser.setLastName(user.getLastName());
|
||||||
|
return userRepository.save(existingUser);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a user by ID.
|
||||||
|
*
|
||||||
|
* @param id the user ID
|
||||||
|
* @return true if user was deleted, false if not found
|
||||||
|
*/
|
||||||
|
public boolean deleteUser(Long id) {
|
||||||
|
if (userRepository.existsById(id)) {
|
||||||
|
userRepository.deleteById(id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a user exists by username.
|
||||||
|
*
|
||||||
|
* @param username the username to check
|
||||||
|
* @return true if user exists, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean userExistsByUsername(String username) {
|
||||||
|
return userRepository.existsByUsername(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a user exists by email.
|
||||||
|
*
|
||||||
|
* @param email the email to check
|
||||||
|
* @return true if user exists, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean userExistsByEmail(String email) {
|
||||||
|
return userRepository.existsByEmail(email);
|
||||||
|
}
|
||||||
|
}
|
||||||
62
backend/src/main/resources/application.yml
Normal file
62
backend/src/main/resources/application.yml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
servlet:
|
||||||
|
context-path: /api
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: vibing-backend
|
||||||
|
|
||||||
|
# Database Configuration
|
||||||
|
datasource:
|
||||||
|
url: jdbc:h2:mem:testdb
|
||||||
|
driver-class-name: org.h2.Driver
|
||||||
|
username: sa
|
||||||
|
password: password
|
||||||
|
|
||||||
|
# JPA Configuration
|
||||||
|
jpa:
|
||||||
|
database-platform: org.hibernate.dialect.H2Dialect
|
||||||
|
hibernate:
|
||||||
|
ddl-auto: create-drop
|
||||||
|
show-sql: true
|
||||||
|
properties:
|
||||||
|
hibernate:
|
||||||
|
format_sql: true
|
||||||
|
|
||||||
|
# H2 Console (for development)
|
||||||
|
h2:
|
||||||
|
console:
|
||||||
|
enabled: true
|
||||||
|
path: /h2-console
|
||||||
|
|
||||||
|
# Jackson Configuration
|
||||||
|
jackson:
|
||||||
|
default-property-inclusion: non_null
|
||||||
|
serialization:
|
||||||
|
write-dates-as-timestamps: false
|
||||||
|
deserialization:
|
||||||
|
fail-on-unknown-properties: false
|
||||||
|
|
||||||
|
# Logging Configuration
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
com.vibing.backend: DEBUG
|
||||||
|
org.springframework.security: DEBUG
|
||||||
|
org.springframework.web: DEBUG
|
||||||
|
pattern:
|
||||||
|
console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n"
|
||||||
|
|
||||||
|
# API Documentation
|
||||||
|
springdoc:
|
||||||
|
api-docs:
|
||||||
|
path: /api-docs
|
||||||
|
swagger-ui:
|
||||||
|
path: /swagger-ui.html
|
||||||
|
operations-sorter: method
|
||||||
|
|
||||||
|
# Security Configuration
|
||||||
|
security:
|
||||||
|
jwt:
|
||||||
|
secret: your-secret-key-here-change-in-production
|
||||||
|
expiration: 86400000 # 24 hours in milliseconds
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.vibing.backend;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic test class for the Vibing Backend application.
|
||||||
|
*/
|
||||||
|
@SpringBootTest
|
||||||
|
class VibingBackendApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
// This test verifies that the Spring application context loads successfully
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user