Projects upload with docker working

This commit is contained in:
Dennis Eckerskorn 2025-05-12 23:16:40 +02:00
commit 77bbe52f7a
203 changed files with 33940 additions and 0 deletions

5
docker/Dockerfile-api Normal file
View File

@ -0,0 +1,5 @@
FROM eclipse-temurin:21-jdk-alpine
WORKDIR /app
COPY target/memberflow-api-1.0-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

18
docker/Dockerfile-front Normal file
View File

@ -0,0 +1,18 @@
# Etapa 1: build React
FROM node:18-alpine as build
WORKDIR /app
COPY memberflow-frontend/package*.json ./
RUN npm install
COPY memberflow-frontend/ .
RUN npm run build
# Etapa 2: servir con nginx
FROM nginx:alpine
WORKDIR /usr/share/nginx/html
COPY --from=build /app/build .
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80

51
docker/docker-compose.yml Normal file
View File

@ -0,0 +1,51 @@
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql-db
restart: always
environment:
MYSQL_ROOT_PASSWORD: 1234
MYSQL_DATABASE: mf_db
ports:
- "3307:3306"
volumes:
- mysql_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-p1234"]
interval: 10s
timeout: 5s
retries: 5
backend:
build:
context: ../memberflow-api
dockerfile: ../docker/Dockerfile-api
container_name: memberflow-backend
depends_on:
- mysql
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/mf_db?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: 1234
JWT_SECRET: c2VjdXJlc2VjdXJlc2VjdXJlc2VjdXJlMTIzNDU2
JWT_EXPIRATION: 7200000
frontend:
build:
context: ..
dockerfile: docker/Dockerfile-front
container_name: memberflow-frontend
depends_on:
- backend
ports:
- "3000:80"
volumes:
mysql_data:

975
docker/init.sql Normal file
View File

@ -0,0 +1,975 @@
CREATE DATABASE IF NOT EXISTS `mf_db` /*!40100 DEFAULT CHARACTER SET utf8mb3 */ /*!80016 DEFAULT ENCRYPTION='N' */;
USE `mf_db`;
-- MySQL dump 10.13 Distrib 8.0.41, for Win64 (x86_64)
--
-- Host: localhost Database: mf_db
-- ------------------------------------------------------
-- Server version 8.0.41
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `admins`
--
DROP TABLE IF EXISTS `admins`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `admins` (
`fk_user` int NOT NULL,
`id` int NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UKhp41pq62xgvtc2ybhg0ogn9k2` (`fk_user`),
CONSTRAINT `FK7atylq0pwosys9nu9m6i615yf` FOREIGN KEY (`fk_user`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `admins`
--
LOCK TABLES `admins` WRITE;
/*!40000 ALTER TABLE `admins` DISABLE KEYS */;
INSERT INTO `admins` VALUES (3,1),(52,2);
/*!40000 ALTER TABLE `admins` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `admins_seq`
--
DROP TABLE IF EXISTS `admins_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `admins_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `admins_seq`
--
LOCK TABLES `admins_seq` WRITE;
/*!40000 ALTER TABLE `admins_seq` DISABLE KEYS */;
INSERT INTO `admins_seq` VALUES (101);
/*!40000 ALTER TABLE `admins_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `assistance`
--
DROP TABLE IF EXISTS `assistance`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `assistance` (
`fk_student` int NOT NULL,
`fk_training_session` int NOT NULL,
`id` int NOT NULL,
`date_time` datetime(6) NOT NULL,
PRIMARY KEY (`id`),
KEY `FKhrljnnasyhhy0wacovapkhgll` (`fk_student`),
KEY `FKr5gxvfqh4k1jws31ymlw80nin` (`fk_training_session`),
CONSTRAINT `FKhrljnnasyhhy0wacovapkhgll` FOREIGN KEY (`fk_student`) REFERENCES `students` (`id`),
CONSTRAINT `FKr5gxvfqh4k1jws31ymlw80nin` FOREIGN KEY (`fk_training_session`) REFERENCES `training_sessions` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `assistance`
--
LOCK TABLES `assistance` WRITE;
/*!40000 ALTER TABLE `assistance` DISABLE KEYS */;
INSERT INTO `assistance` VALUES (2,302,352,'2025-05-11 14:19:43.234000');
/*!40000 ALTER TABLE `assistance` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `assistance_seq`
--
DROP TABLE IF EXISTS `assistance_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `assistance_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `assistance_seq`
--
LOCK TABLES `assistance_seq` WRITE;
/*!40000 ALTER TABLE `assistance_seq` DISABLE KEYS */;
INSERT INTO `assistance_seq` VALUES (451);
/*!40000 ALTER TABLE `assistance_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `invoice_lines`
--
DROP TABLE IF EXISTS `invoice_lines`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `invoice_lines` (
`fk_invoice` int NOT NULL,
`fk_product_service` int NOT NULL,
`id` int NOT NULL,
`quantity` int NOT NULL,
`subtotal` decimal(38,2) NOT NULL,
`unit_price` decimal(38,2) NOT NULL,
`description` text,
PRIMARY KEY (`id`),
KEY `FK16v42x9o42cpvobfprperyat1` (`fk_invoice`),
KEY `FKt49wl938ncng8h5i3ivhw2851` (`fk_product_service`),
CONSTRAINT `FK16v42x9o42cpvobfprperyat1` FOREIGN KEY (`fk_invoice`) REFERENCES `invoices` (`id`),
CONSTRAINT `FKt49wl938ncng8h5i3ivhw2851` FOREIGN KEY (`fk_product_service`) REFERENCES `products_services` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `invoice_lines`
--
LOCK TABLES `invoice_lines` WRITE;
/*!40000 ALTER TABLE `invoice_lines` DISABLE KEYS */;
INSERT INTO `invoice_lines` VALUES (1,1,1,1,50.00,50.00,NULL),(1,1,2,1,50.00,50.00,NULL);
/*!40000 ALTER TABLE `invoice_lines` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `invoice_lines_seq`
--
DROP TABLE IF EXISTS `invoice_lines_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `invoice_lines_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `invoice_lines_seq`
--
LOCK TABLES `invoice_lines_seq` WRITE;
/*!40000 ALTER TABLE `invoice_lines_seq` DISABLE KEYS */;
INSERT INTO `invoice_lines_seq` VALUES (101);
/*!40000 ALTER TABLE `invoice_lines_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `invoices`
--
DROP TABLE IF EXISTS `invoices`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `invoices` (
`fk_user` int NOT NULL,
`id` int NOT NULL,
`total` decimal(38,2) NOT NULL,
`date` datetime(6) NOT NULL,
`status` enum('ACTIVE','DELETED','INACTIVE','NOT_PAID','NOT_SENT','PAID','PENDING','SENT','SUSPENDED') NOT NULL,
PRIMARY KEY (`id`),
KEY `FKdhc51ih4oqto9ng00e4ioso7w` (`fk_user`),
CONSTRAINT `FKdhc51ih4oqto9ng00e4ioso7w` FOREIGN KEY (`fk_user`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `invoices`
--
LOCK TABLES `invoices` WRITE;
/*!40000 ALTER TABLE `invoices` DISABLE KEYS */;
INSERT INTO `invoices` VALUES (1,1,50.00,'2025-05-08 16:22:31.643179','PAID');
/*!40000 ALTER TABLE `invoices` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `invoices_seq`
--
DROP TABLE IF EXISTS `invoices_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `invoices_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `invoices_seq`
--
LOCK TABLES `invoices_seq` WRITE;
/*!40000 ALTER TABLE `invoices_seq` DISABLE KEYS */;
INSERT INTO `invoices_seq` VALUES (51);
/*!40000 ALTER TABLE `invoices_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `iva_type`
--
DROP TABLE IF EXISTS `iva_type`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `iva_type` (
`id` int NOT NULL,
`percentage` decimal(38,2) NOT NULL,
`description` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `iva_type`
--
LOCK TABLES `iva_type` WRITE;
/*!40000 ALTER TABLE `iva_type` DISABLE KEYS */;
INSERT INTO `iva_type` VALUES (1,21.00,'IVA General');
/*!40000 ALTER TABLE `iva_type` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `iva_type_seq`
--
DROP TABLE IF EXISTS `iva_type_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `iva_type_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `iva_type_seq`
--
LOCK TABLES `iva_type_seq` WRITE;
/*!40000 ALTER TABLE `iva_type_seq` DISABLE KEYS */;
INSERT INTO `iva_type_seq` VALUES (51);
/*!40000 ALTER TABLE `iva_type_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `memberships`
--
DROP TABLE IF EXISTS `memberships`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `memberships` (
`end_date` date NOT NULL,
`id` int NOT NULL,
`start_date` date NOT NULL,
`status` enum('ACTIVE','DELETED','INACTIVE','NOT_PAID','NOT_SENT','PAID','PENDING','SENT','SUSPENDED') NOT NULL,
`type` enum('ADVANCED','BASIC','NO_LIMIT','PREMIUM','TRIAL') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `memberships`
--
LOCK TABLES `memberships` WRITE;
/*!40000 ALTER TABLE `memberships` DISABLE KEYS */;
INSERT INTO `memberships` VALUES ('2025-06-09',1,'2025-05-09','ACTIVE','BASIC'),('2025-08-09',2,'2025-05-09','ACTIVE','ADVANCED'),('2025-11-09',3,'2025-05-09','ACTIVE','PREMIUM'),('2026-05-09',4,'2025-05-09','ACTIVE','NO_LIMIT'),('2025-05-31',52,'2025-05-14','ACTIVE','TRIAL');
/*!40000 ALTER TABLE `memberships` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `memberships_seq`
--
DROP TABLE IF EXISTS `memberships_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `memberships_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `memberships_seq`
--
LOCK TABLES `memberships_seq` WRITE;
/*!40000 ALTER TABLE `memberships_seq` DISABLE KEYS */;
INSERT INTO `memberships_seq` VALUES (151);
/*!40000 ALTER TABLE `memberships_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `notifications`
--
DROP TABLE IF EXISTS `notifications`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `notifications` (
`id` int NOT NULL,
`shipping_date` datetime(6) NOT NULL,
`type` varchar(100) DEFAULT NULL,
`title` varchar(200) NOT NULL,
`message` text,
`status` enum('ACTIVE','DELETED','INACTIVE','NOT_PAID','NOT_SENT','PAID','PENDING','SENT','SUSPENDED') DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `notifications`
--
LOCK TABLES `notifications` WRITE;
/*!40000 ALTER TABLE `notifications` DISABLE KEYS */;
INSERT INTO `notifications` VALUES (1,'2025-05-09 16:22:31.581882','Bienvenida','Bienvenido a MemberFlow','Gracias por registrarte','ACTIVE'),(2,'2025-05-09 22:00:00.000000','','Hola','Hola','ACTIVE');
/*!40000 ALTER TABLE `notifications` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `notifications_seq`
--
DROP TABLE IF EXISTS `notifications_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `notifications_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `notifications_seq`
--
LOCK TABLES `notifications_seq` WRITE;
/*!40000 ALTER TABLE `notifications_seq` DISABLE KEYS */;
INSERT INTO `notifications_seq` VALUES (101);
/*!40000 ALTER TABLE `notifications_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `payments`
--
DROP TABLE IF EXISTS `payments`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `payments` (
`amount` decimal(38,2) NOT NULL,
`fk_invoice` int NOT NULL,
`id` int NOT NULL,
`payment_date` datetime(6) NOT NULL,
`payment_method` enum('BANK_TRANSFER','CASH','CREDIT_CARD') NOT NULL,
`status` enum('ACTIVE','DELETED','INACTIVE','NOT_PAID','NOT_SENT','PAID','PENDING','SENT','SUSPENDED') NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UK3ktj4gndg7wyqu8wqoyqlxonw` (`fk_invoice`),
CONSTRAINT `FKdryjs8tgr3kyuopc9aiwn1a62` FOREIGN KEY (`fk_invoice`) REFERENCES `invoices` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `payments`
--
LOCK TABLES `payments` WRITE;
/*!40000 ALTER TABLE `payments` DISABLE KEYS */;
INSERT INTO `payments` VALUES (50.00,1,1,'2025-05-09 16:22:31.697527','CREDIT_CARD','PAID');
/*!40000 ALTER TABLE `payments` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `payments_seq`
--
DROP TABLE IF EXISTS `payments_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `payments_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `payments_seq`
--
LOCK TABLES `payments_seq` WRITE;
/*!40000 ALTER TABLE `payments_seq` DISABLE KEYS */;
INSERT INTO `payments_seq` VALUES (51);
/*!40000 ALTER TABLE `payments_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `permissions`
--
DROP TABLE IF EXISTS `permissions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `permissions` (
`id` int NOT NULL,
`name` enum('FULL_ACCESS','MANAGE_STUDENTS','VIEW_OWN_DATA') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `permissions`
--
LOCK TABLES `permissions` WRITE;
/*!40000 ALTER TABLE `permissions` DISABLE KEYS */;
INSERT INTO `permissions` VALUES (1,'FULL_ACCESS'),(2,'MANAGE_STUDENTS'),(3,'VIEW_OWN_DATA');
/*!40000 ALTER TABLE `permissions` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `permissions_seq`
--
DROP TABLE IF EXISTS `permissions_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `permissions_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `permissions_seq`
--
LOCK TABLES `permissions_seq` WRITE;
/*!40000 ALTER TABLE `permissions_seq` DISABLE KEYS */;
INSERT INTO `permissions_seq` VALUES (101);
/*!40000 ALTER TABLE `permissions_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `products_services`
--
DROP TABLE IF EXISTS `products_services`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `products_services` (
`fk_iva_type` int NOT NULL,
`id` int NOT NULL,
`price` decimal(38,2) NOT NULL,
`type` varchar(45) NOT NULL,
`name` varchar(100) NOT NULL,
`description` varchar(250) DEFAULT NULL,
`status` enum('ACTIVE','DELETED','INACTIVE','NOT_PAID','NOT_SENT','PAID','PENDING','SENT','SUSPENDED') NOT NULL,
PRIMARY KEY (`id`),
KEY `FKr8m24u7qbyvbd8sjiq7g3jik0` (`fk_iva_type`),
CONSTRAINT `FKr8m24u7qbyvbd8sjiq7g3jik0` FOREIGN KEY (`fk_iva_type`) REFERENCES `iva_type` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `products_services`
--
LOCK TABLES `products_services` WRITE;
/*!40000 ALTER TABLE `products_services` DISABLE KEYS */;
INSERT INTO `products_services` VALUES (1,1,50.00,'Servicio','Clase de JiuJitsu',NULL,'ACTIVE');
/*!40000 ALTER TABLE `products_services` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `products_services_seq`
--
DROP TABLE IF EXISTS `products_services_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `products_services_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `products_services_seq`
--
LOCK TABLES `products_services_seq` WRITE;
/*!40000 ALTER TABLE `products_services_seq` DISABLE KEYS */;
INSERT INTO `products_services_seq` VALUES (51);
/*!40000 ALTER TABLE `products_services_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `roles`
--
DROP TABLE IF EXISTS `roles`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `roles` (
`id` int NOT NULL,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `roles`
--
LOCK TABLES `roles` WRITE;
/*!40000 ALTER TABLE `roles` DISABLE KEYS */;
INSERT INTO `roles` VALUES (1,'ROLE_STUDENT'),(2,'ROLE_TEACHER'),(3,'ROLE_ADMIN');
/*!40000 ALTER TABLE `roles` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `roles_permissions`
--
DROP TABLE IF EXISTS `roles_permissions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `roles_permissions` (
`fk_permission` int NOT NULL,
`fk_role` int NOT NULL,
PRIMARY KEY (`fk_role`,`fk_permission`),
KEY `FKlboaow7qn1m64rwjr8ifl6w2d` (`fk_permission`),
CONSTRAINT `FKlboaow7qn1m64rwjr8ifl6w2d` FOREIGN KEY (`fk_permission`) REFERENCES `permissions` (`id`),
CONSTRAINT `FKo60viy4q37nhjd2xyl242anba` FOREIGN KEY (`fk_role`) REFERENCES `roles` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `roles_permissions`
--
LOCK TABLES `roles_permissions` WRITE;
/*!40000 ALTER TABLE `roles_permissions` DISABLE KEYS */;
INSERT INTO `roles_permissions` VALUES (1,3),(2,2),(3,1),(3,2);
/*!40000 ALTER TABLE `roles_permissions` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `roles_seq`
--
DROP TABLE IF EXISTS `roles_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `roles_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `roles_seq`
--
LOCK TABLES `roles_seq` WRITE;
/*!40000 ALTER TABLE `roles_seq` DISABLE KEYS */;
INSERT INTO `roles_seq` VALUES (101);
/*!40000 ALTER TABLE `roles_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `student_history`
--
DROP TABLE IF EXISTS `student_history`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `student_history` (
`event_date` date DEFAULT NULL,
`fk_student` int NOT NULL,
`id` int NOT NULL,
`description` varchar(255) DEFAULT NULL,
`event_type` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKfifyby18m8fetblwf5nfg33gx` (`fk_student`),
CONSTRAINT `FKfifyby18m8fetblwf5nfg33gx` FOREIGN KEY (`fk_student`) REFERENCES `students` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `student_history`
--
LOCK TABLES `student_history` WRITE;
/*!40000 ALTER TABLE `student_history` DISABLE KEYS */;
INSERT INTO `student_history` VALUES ('2025-05-09',1,1,'Primera clase','Clase de prueba');
/*!40000 ALTER TABLE `student_history` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `student_history_seq`
--
DROP TABLE IF EXISTS `student_history_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `student_history_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `student_history_seq`
--
LOCK TABLES `student_history_seq` WRITE;
/*!40000 ALTER TABLE `student_history_seq` DISABLE KEYS */;
INSERT INTO `student_history_seq` VALUES (51);
/*!40000 ALTER TABLE `student_history_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `students`
--
DROP TABLE IF EXISTS `students`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `students` (
`birthdate` date NOT NULL,
`fk_membership` int DEFAULT NULL,
`fk_user` int NOT NULL,
`id` int NOT NULL,
`dni` varchar(10) NOT NULL,
`belt` varchar(20) DEFAULT NULL,
`parent_name` varchar(50) DEFAULT NULL,
`medical_report` varchar(500) DEFAULT NULL,
`progress` text,
PRIMARY KEY (`id`),
UNIQUE KEY `UK3ci8o1dbwgn49fx4tkhk579fk` (`fk_user`),
UNIQUE KEY `UKoljr3bj7rsof5ys5e9v932g9l` (`dni`),
UNIQUE KEY `UKgjomxh7uemp64sjo69mkefqbh` (`fk_membership`),
CONSTRAINT `FKj3wyb55uh73yti619x84pfe7s` FOREIGN KEY (`fk_membership`) REFERENCES `memberships` (`id`),
CONSTRAINT `FKkqp52wo7o073loxihnbf133wq` FOREIGN KEY (`fk_user`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `students`
--
LOCK TABLES `students` WRITE;
/*!40000 ALTER TABLE `students` DISABLE KEYS */;
INSERT INTO `students` VALUES ('2005-05-20',1,1,1,'12345678A','Blanco','Padre Estudiante','Apto','Buena evolución'),('2025-05-10',3,103,2,'123456789','Blanco','','',NULL);
/*!40000 ALTER TABLE `students` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `students_groups`
--
DROP TABLE IF EXISTS `students_groups`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `students_groups` (
`fk_group` int NOT NULL,
`fk_student` int NOT NULL,
PRIMARY KEY (`fk_group`,`fk_student`),
KEY `FKqibb3ps0nfj4kkx6kd1qn7mkd` (`fk_student`),
CONSTRAINT `FKp6ck2q2xcptfj526ipa1ki56g` FOREIGN KEY (`fk_group`) REFERENCES `training_groups` (`id`),
CONSTRAINT `FKqibb3ps0nfj4kkx6kd1qn7mkd` FOREIGN KEY (`fk_student`) REFERENCES `students` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `students_groups`
--
LOCK TABLES `students_groups` WRITE;
/*!40000 ALTER TABLE `students_groups` DISABLE KEYS */;
INSERT INTO `students_groups` VALUES (452,2);
/*!40000 ALTER TABLE `students_groups` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `students_seq`
--
DROP TABLE IF EXISTS `students_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `students_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `students_seq`
--
LOCK TABLES `students_seq` WRITE;
/*!40000 ALTER TABLE `students_seq` DISABLE KEYS */;
INSERT INTO `students_seq` VALUES (101);
/*!40000 ALTER TABLE `students_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `teachers`
--
DROP TABLE IF EXISTS `teachers`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `teachers` (
`fk_user` int NOT NULL,
`id` int NOT NULL,
`discipline` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UK352b5808rcgb1un47hwig1gq2` (`fk_user`),
CONSTRAINT `FKeujs3kyjh75c0u93b731i9rua` FOREIGN KEY (`fk_user`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `teachers`
--
LOCK TABLES `teachers` WRITE;
/*!40000 ALTER TABLE `teachers` DISABLE KEYS */;
INSERT INTO `teachers` VALUES (2,1,'Jiu-Jitsu'),(102,2,'Jiujitsu');
/*!40000 ALTER TABLE `teachers` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `teachers_seq`
--
DROP TABLE IF EXISTS `teachers_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `teachers_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `teachers_seq`
--
LOCK TABLES `teachers_seq` WRITE;
/*!40000 ALTER TABLE `teachers_seq` DISABLE KEYS */;
INSERT INTO `teachers_seq` VALUES (101);
/*!40000 ALTER TABLE `teachers_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `training_groups`
--
DROP TABLE IF EXISTS `training_groups`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `training_groups` (
`fk_teacher` int NOT NULL,
`id` int NOT NULL,
`schedule` datetime(6) NOT NULL,
`level` varchar(45) DEFAULT NULL,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`id`),
KEY `FKhgbvfsm24yptkm76cbhtbv4s4` (`fk_teacher`),
CONSTRAINT `FKhgbvfsm24yptkm76cbhtbv4s4` FOREIGN KEY (`fk_teacher`) REFERENCES `teachers` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `training_groups`
--
LOCK TABLES `training_groups` WRITE;
/*!40000 ALTER TABLE `training_groups` DISABLE KEYS */;
INSERT INTO `training_groups` VALUES (2,452,'2025-10-22 12:35:00.000000','Avanzado','JiuJitsu');
/*!40000 ALTER TABLE `training_groups` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `training_groups_seq`
--
DROP TABLE IF EXISTS `training_groups_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `training_groups_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `training_groups_seq`
--
LOCK TABLES `training_groups_seq` WRITE;
/*!40000 ALTER TABLE `training_groups_seq` DISABLE KEYS */;
INSERT INTO `training_groups_seq` VALUES (551);
/*!40000 ALTER TABLE `training_groups_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `training_sessions`
--
DROP TABLE IF EXISTS `training_sessions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `training_sessions` (
`fk_group` int NOT NULL,
`id` int NOT NULL,
`date_time` datetime(6) NOT NULL,
`status` enum('ACTIVE','DELETED','INACTIVE','NOT_PAID','NOT_SENT','PAID','PENDING','SENT','SUSPENDED') NOT NULL,
PRIMARY KEY (`id`),
KEY `FKkjj30gdo7uua9ycvlriax2vep` (`fk_group`),
CONSTRAINT `FKkjj30gdo7uua9ycvlriax2vep` FOREIGN KEY (`fk_group`) REFERENCES `training_groups` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `training_sessions`
--
LOCK TABLES `training_sessions` WRITE;
/*!40000 ALTER TABLE `training_sessions` DISABLE KEYS */;
INSERT INTO `training_sessions` VALUES (452,302,'2025-10-22 12:35:00.000000','ACTIVE');
/*!40000 ALTER TABLE `training_sessions` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `training_sessions_seq`
--
DROP TABLE IF EXISTS `training_sessions_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `training_sessions_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `training_sessions_seq`
--
LOCK TABLES `training_sessions_seq` WRITE;
/*!40000 ALTER TABLE `training_sessions_seq` DISABLE KEYS */;
INSERT INTO `training_sessions_seq` VALUES (401);
/*!40000 ALTER TABLE `training_sessions_seq` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `users`
--
DROP TABLE IF EXISTS `users`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `users` (
`fk_role` int NOT NULL,
`id` int NOT NULL,
`register_date` datetime(6) NOT NULL,
`phone_number` varchar(30) NOT NULL,
`name` varchar(50) NOT NULL,
`surname` varchar(50) NOT NULL,
`address` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
`password` varchar(255) NOT NULL,
`status` enum('ACTIVE','DELETED','INACTIVE','NOT_PAID','NOT_SENT','PAID','PENDING','SENT','SUSPENDED') NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UKavh1b2ec82audum2lyjx2p1ws` (`email`),
KEY `FK5k6cr6ejda3jhunshjbx4nhai` (`fk_role`),
CONSTRAINT `FK5k6cr6ejda3jhunshjbx4nhai` FOREIGN KEY (`fk_role`) REFERENCES `roles` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `users`
--
LOCK TABLES `users` WRITE;
/*!40000 ALTER TABLE `users` DISABLE KEYS */;
INSERT INTO `users` VALUES (1,1,'2025-05-09 16:22:31.399041','600123456','Student','One','Calle Estudiante 123','student@example.com','$2a$10$G13aVWunAMLwQNDdca0BGuXeYxfH65TFriKHzpwU3OGZvR/6O.poO','ACTIVE'),(2,2,'2025-05-09 16:22:31.501044','611123456','Teacher','Uno','Calle Maestro 1','teacher@example.com','$2a$10$.0KMijc2nwqwJgUDiosN1.vzXHqiy9Ge6gzOiOKLwmOmiLa9yC85a','ACTIVE'),(3,3,'2025-05-09 16:22:31.568593','622123456','Admin','Root','Central','admin@example.com','$2a$10$u9k50gWu3eMG.KF1brVeC.O6UPob0DQgAdNxc.Y63AE1ZPkcwRVNy','ACTIVE'),(3,52,'2025-05-09 16:24:48.404428','675529497','Dennis','Eckerskorn','Carrer d\'Azorín, 30 Bajo','deckerskorn@mf.com','$2a$10$sg1Cy1AvimKBWEaZvGG3Ue.qdwclJre7VBvAHKrPTtY5dD9R4ZWqO','ACTIVE'),(2,102,'2025-05-10 19:07:22.957486','1234567','Steve','Newman','Pedreguer','steve@mm.com','$2a$10$iNJiV73bUopf0iiQvouqM.SWLPOnzCjRFPbilWLbHiRR7l6IivrAu','ACTIVE'),(1,103,'2025-05-10 19:09:09.423529','1234567','Miriam','Valiña','Carrer d\'Azorín, 30 Bajo','miriam@mf.com','$2a$10$ghObW0nZdg8qo.RRNgEZd.OrUC0vlebRjuaKeX5uEvH/6nwgqqtCa','ACTIVE');
/*!40000 ALTER TABLE `users` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `users_notifications`
--
DROP TABLE IF EXISTS `users_notifications`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `users_notifications` (
`fk_notification` int NOT NULL,
`fk_user` int NOT NULL,
PRIMARY KEY (`fk_notification`,`fk_user`),
KEY `FKr4iwf238qbl6oa8x16gj17jud` (`fk_user`),
CONSTRAINT `FK3sbul72qkfqxu2vgqk5fw2u` FOREIGN KEY (`fk_notification`) REFERENCES `notifications` (`id`),
CONSTRAINT `FKr4iwf238qbl6oa8x16gj17jud` FOREIGN KEY (`fk_user`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `users_notifications`
--
LOCK TABLES `users_notifications` WRITE;
/*!40000 ALTER TABLE `users_notifications` DISABLE KEYS */;
INSERT INTO `users_notifications` VALUES (1,1),(1,2),(1,3),(2,52);
/*!40000 ALTER TABLE `users_notifications` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `users_seq`
--
DROP TABLE IF EXISTS `users_seq`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `users_seq` (
`next_val` bigint DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `users_seq`
--
LOCK TABLES `users_seq` WRITE;
/*!40000 ALTER TABLE `users_seq` DISABLE KEYS */;
INSERT INTO `users_seq` VALUES (201);
/*!40000 ALTER TABLE `users_seq` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2025-05-12 21:57:25

10
docker/nginx.conf Normal file
View File

@ -0,0 +1,10 @@
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri /index.html;
}
}

38
memberflow-api/.gitignore vendored Normal file
View File

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

3
memberflow-api/.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="openjdk-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

60
memberflow-api/README.md Normal file
View File

@ -0,0 +1,60 @@
# MemberFlow-API
## Descripción del Proyecto
**MemberFlow-API** es el módulo de interfaz de usuario y controladores de la aplicación **MemberFlow**, diseñado para gestionar membresías, usuarios, clases y finanzas en un entorno organizacional. Este proyecto actúa como la capa de presentación y comunicación, exponiendo servicios RESTful que interactúan con el módulo de datos **MemberFlow-Data**.
El objetivo principal de **MemberFlow-API** es proporcionar una interfaz segura y eficiente para que los clientes (como aplicaciones web o móviles) puedan interactuar con la lógica de negocio y la base de datos subyacente.
---
## Características Principales
- **Controladores REST**: Exposición de endpoints para gestionar usuarios, roles, notificaciones, clases y finanzas.
- **Seguridad**: Implementación de autenticación basada en JWT (JSON Web Tokens).
- **Integración con MemberFlow-Data**: Uso del módulo de datos para acceder a la lógica de negocio y la persistencia.
- **Configuración Centralizada**: Uso de `application.properties` para gestionar parámetros clave como JWT y otros ajustes.
- **Ejecución con Spring Boot**: Aplicación basada en el framework Spring Boot para facilitar el desarrollo y despliegue.
- **Modularidad**: Integración con el módulo **MemberFlow-Data** para mantener una separación clara entre la lógica de negocio y la capa de presentación.
---
## Estructura del Proyecto
El proyecto está organizado en los siguientes paquetes y archivos principales:
### 1. **Configuración**
- **`application.properties`**: Archivo de configuración que incluye parámetros clave como JWT y ajustes de la aplicación.
- **`MemberFlowApplication`**: Clase principal para iniciar la aplicación Spring Boot.
### 2. **Controladores**
- **`AdminController`**: Gestiona las operaciones relacionadas con los administradores, como la creación y gestión de usuarios administrativos.
- **`AuthController`**: Maneja la autenticación y generación de tokens JWT para garantizar la seguridad de los endpoints.
- **`StudentController`**: Proporciona endpoints para gestionar estudiantes, incluyendo inscripción, actualización de datos y consultas.
- **`TeacherController`**: Gestiona las operaciones relacionadas con los profesores, como la asignación de grupos y la gestión de clases.
- **`UserController`**: Controlador genérico para operaciones relacionadas con usuarios, como la gestión de perfiles y roles.
### 3. **Seguridad**
- **`SecurityConfig`**: Configuración de seguridad para proteger los endpoints mediante autenticación JWT.
- **`JwtAuthFilter`**: Filtro para validar los tokens JWT en cada solicitud, asegurando que solo usuarios autenticados puedan acceder a los recursos protegidos.
- **`JwtUtil`**: Utilidad para generar y validar tokens JWT, incluyendo la configuración de tiempos de expiración y claves secretas.
### 4. **Recursos**
- **`application.properties`**: Archivo de configuración centralizado para parámetros clave de la aplicación.
---
## Configuración del Proyecto
### Requisitos Previos
1. **Java 17 o superior**
2. **Maven**
3. **Dependencia del módulo MemberFlow-Data**
### Ejecución del Proyecto
1. Clona el repositorio:
```bash
git clone https://github.com/tu-usuario/memberflow-api.git
cd memberflow-api

Binary file not shown.

137
memberflow-api/pom.xml Normal file
View File

@ -0,0 +1,137 @@
<?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>
<groupId>com.denniseckerskorn</groupId>
<artifactId>memberflow-api</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.denniseckerskorn</groupId>
<artifactId>memberflow-data</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.4.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>3.4.4</version>
</dependency>
<!-- Spring Boot Starter Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>3.4.4</version>
</dependency>
<!-- API principal -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<!-- Implementación -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<!-- Soporte para Jackson -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.15.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.15.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.1.Final</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>21</source>
<target>21</target>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>3.4.4</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,11 @@
package com.denniseckerskorn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MemberFlowApplication {
public static void main(String[] args) {
SpringApplication.run(MemberFlowApplication.class, args);
}
}

View File

@ -0,0 +1,71 @@
package com.denniseckerskorn.config;
import com.denniseckerskorn.security.CustomUserDetailsService;
import com.denniseckerskorn.security.JwtAuthFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@EnableMethodSecurity
@Configuration
public class SecurityConfig {
private final JwtAuthFilter jwtAuthFilter;
private final CustomUserDetailsService customUserDetailsService;
public SecurityConfig(JwtAuthFilter jwtAuthFilter, CustomUserDetailsService customUserDetailsService) {
this.jwtAuthFilter = jwtAuthFilter;
this.customUserDetailsService = customUserDetailsService;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
return config.getAuthenticationManager();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.cors(cors -> cors.configure(http))
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers(
"/api/v1/auth/**",
"/v3/api-docs/**",
"/swagger-ui/**",
"/swagger-ui.html"
).permitAll()
.requestMatchers("/api/v1/users/me").permitAll()
.requestMatchers("/api/v1/admins/**").hasAuthority("FULL_ACCESS")
.requestMatchers("/api/v1/teachers/**").hasAnyAuthority("FULL_ACCESS", "VIEW_OWN_DATA")
.requestMatchers("/api/v1/students/**").hasAnyAuthority("FULL_ACCESS", "MANAGE_STUDENTS", "VIEW_OWN_DATA")
.requestMatchers("/api/v1/users/**").hasAuthority("FULL_ACCESS")
.requestMatchers("/api/v1/notifications/**").hasAuthority("FULL_ACCESS")
.requestMatchers("/api/v1/studentHistories/**").hasAnyAuthority("FULL_ACCESS", "MANAGE_STUDENTS", "VIEW_OWN_DATA")
.requestMatchers("/api/v1/roles/**").hasAuthority("FULL_ACCESS")
.requestMatchers("/api/v1/permissions/**").hasAuthority("FULL_ACCESS")
.requestMatchers("/api/v1/memberships/**").hasAnyAuthority("FULL_ACCESS", "MANAGE_STUDENTS")
.requestMatchers("/api/v1/assistances/**").hasAnyAuthority("FULL_ACCESS", "MANAGE_STUDENTS")
.requestMatchers("/api/v1/training-sessions/**").hasAnyAuthority("FULL_ACCESS", "MANAGE_STUDENTS")
.requestMatchers("/api/v1/training-groups/**").hasAnyAuthority("FULL_ACCESS", "MANAGE_STUDENTS")
.anyRequest().authenticated()
)
.sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
}

View File

@ -0,0 +1,41 @@
package com.denniseckerskorn.config;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI customOpenAPI() {
final String securitySchemeName = "bearerAuth";
return new OpenAPI()
.info(new Info()
.title("MemberFlow API")
.version("1.0.0")
.description("""
Documentación de la API de MemberFlow.
**Usuarios de prueba:**
- Admin: admin@example.com / admin123
- Teacher: teacher@example.com / 123456789
- Student: student@example.com / 12345678
""")
)
.addSecurityItem(new SecurityRequirement().addList(securitySchemeName))
.components(new Components()
.addSecuritySchemes(securitySchemeName,
new SecurityScheme()
.name(securitySchemeName)
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")
.in(SecurityScheme.In.HEADER)
));
}
}

View File

@ -0,0 +1,17 @@
package com.denniseckerskorn.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true);
}
}

View File

@ -0,0 +1,58 @@
package com.denniseckerskorn.controllers;
import com.denniseckerskorn.dtos.LoginRequest;
import com.denniseckerskorn.entities.user_managment.users.User;
import com.denniseckerskorn.security.JwtUtil;
import com.denniseckerskorn.services.user_managment_services.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/v1/auth")
@Tag(name = "Authentication", description = "Operations related to user authentication")
public class AuthController {
private final AuthenticationManager authenticationManager;
private final JwtUtil jwtUtil;
private final UserService userService;
public AuthController(AuthenticationManager authenticationManager, JwtUtil jwtUtil, UserService userService) {
this.authenticationManager = authenticationManager;
this.jwtUtil = jwtUtil;
this.userService = userService;
}
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successful login"),
@ApiResponse(responseCode = "401", description = "Unauthorized"),
@ApiResponse(responseCode = "500", description = "Internal server error")
})
@Operation(summary = "User login", description = "Authenticate a user and return a JWT token")
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getEmail(), loginRequest.getPassword()
)
);
User user = userService.findByEmail(loginRequest.getEmail());
String authority = user.getRole().getPermissions().stream()
.map(p -> p.getPermissionName().name())
.findFirst()
.orElse("VIEW_OWN_DATA");
String token = jwtUtil.generateToken(user.getEmail(), authority);
return ResponseEntity.ok().body("{\"token\": \"" + token + "\"}");
}
}

View File

@ -0,0 +1,81 @@
package com.denniseckerskorn.controllers.class_management_controllers;
import com.denniseckerskorn.dtos.class_managment_dtos.AssistanceDTO;
import com.denniseckerskorn.entities.class_managment.Assistance;
import com.denniseckerskorn.services.class_managment_services.AssistanceService;
import com.denniseckerskorn.services.class_managment_services.TrainingSessionService;
import com.denniseckerskorn.services.user_managment_services.StudentService;
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.*;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/v1/assistances")
@Tag(name = "Assistance Management", description = "Operations related to assistance management")
public class AssistanceController {
private final AssistanceService assistanceService;
private final StudentService studentService;
private final TrainingSessionService trainingSessionService;
public AssistanceController(
AssistanceService assistanceService,
StudentService studentService,
TrainingSessionService trainingSessionService
) {
this.assistanceService = assistanceService;
this.studentService = studentService;
this.trainingSessionService = trainingSessionService;
}
@Operation(summary = "Create a new assistance record")
@PostMapping("/create")
public ResponseEntity<AssistanceDTO> create(@RequestBody AssistanceDTO dto) {
Assistance assistance = dto.toEntity(
studentService.findById(dto.getStudentId()),
trainingSessionService.findById(dto.getSessionId())
);
Assistance saved = assistanceService.save(assistance);
return ResponseEntity.ok(AssistanceDTO.fromEntity(saved));
}
@Operation(summary = "Update an existing assistance record", description = "Update an existing assistance record")
@PutMapping("/update")
public ResponseEntity<AssistanceDTO> update(@RequestBody AssistanceDTO dto) {
Assistance existing = assistanceService.findById(dto.getId());
existing.setDate(dto.getDate());
existing.setStudent(studentService.findById(dto.getStudentId()));
existing.setTrainingSession(trainingSessionService.findById(dto.getSessionId()));
Assistance updated = assistanceService.save(existing);
return ResponseEntity.ok(AssistanceDTO.fromEntity(updated));
}
@Operation(summary = "Get all assistance records", description = "Retrieve a list of all assistance records")
@GetMapping("/getAll")
public ResponseEntity<List<AssistanceDTO>> getAll() {
List<AssistanceDTO> list = assistanceService.findAll()
.stream()
.map(AssistanceDTO::fromEntity)
.collect(Collectors.toList());
return ResponseEntity.ok(list);
}
@Operation(summary = "Get assistance records by student ID", description = "Retrieve assistance records for a specific student")
@GetMapping("/getById/{id}")
public ResponseEntity<AssistanceDTO> getAssistanceById(@PathVariable Integer id) {
Assistance assistance = assistanceService.findById(id);
return ResponseEntity.ok(AssistanceDTO.fromEntity(assistance));
}
@Operation(summary = "Delete an assistance record by ID")
@DeleteMapping("/delete/{id}")
public ResponseEntity<Void> delete(@PathVariable Integer id) {
assistanceService.deleteById(id);
return ResponseEntity.noContent().build();
}
}

View File

@ -0,0 +1,76 @@
package com.denniseckerskorn.controllers.class_management_controllers;
import com.denniseckerskorn.dtos.class_managment_dtos.MembershipDTO;
import com.denniseckerskorn.entities.class_managment.Membership;
import com.denniseckerskorn.services.class_managment_services.MembershipService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.transaction.Transactional;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
/**
* MembershipController handles requests related to membership management.
* It provides endpoints for creating, retrieving, updating, and deleting memberships.
*/
@RestController
@RequestMapping("/api/v1/memberships")
@Tag(name = "Memberships", description = "Operations related to membership management")
public class MembershipController {
private final MembershipService membershipService;
public MembershipController(MembershipService membershipService) {
this.membershipService = membershipService;
}
@Operation(summary = "Create a new membership")
@PostMapping("/create")
public ResponseEntity<MembershipDTO> createMembership(@RequestBody MembershipDTO membershipDTO) {
Membership membership = membershipDTO.toEntity();
Membership savedMembership = membershipService.save(membership);
return ResponseEntity.status(HttpStatus.CREATED).body(MembershipDTO.fromEntity(savedMembership));
}
@Operation(summary = "Get all memberships", description = "Retrieve a list of all memberships")
@GetMapping("/getAll")
public ResponseEntity<List<MembershipDTO>> getAllMemberships() {
List<Membership> memberships = membershipService.findAll();
if (memberships.isEmpty()) return ResponseEntity.noContent().build();
List<MembershipDTO> dtos = memberships.stream()
.map(MembershipDTO::fromEntity)
.collect(Collectors.toList());
return ResponseEntity.ok(dtos);
}
@Operation(summary = "Get a membership by ID", description = "Retrieve a membership by its ID")
@GetMapping("/getById/{id}")
public ResponseEntity<MembershipDTO> getMembershipById(@PathVariable Integer id) {
Membership membership = membershipService.findById(id);
return ResponseEntity.ok(MembershipDTO.fromEntity(membership));
}
@Operation(summary = "Update a membership", description = "Update an existing membership")
@Transactional
@PutMapping("/update/{id}")
public ResponseEntity<MembershipDTO> updateMembership(@PathVariable Integer id, @RequestBody MembershipDTO dto) {
dto.setId(id);
Membership updated = membershipService.update(dto.toEntity());
return ResponseEntity.ok(MembershipDTO.fromEntity(updated));
}
@Operation(summary = "Delete a membership", description = "Delete a membership by its ID")
@Transactional
@DeleteMapping("/delete/{id}")
public ResponseEntity<String> deleteMembership(@PathVariable Integer id) {
membershipService.deleteById(id);
return ResponseEntity.ok("Membership deleted successfully");
}
}

View File

@ -0,0 +1,161 @@
package com.denniseckerskorn.controllers.class_management_controllers;
import com.denniseckerskorn.dtos.class_managment_dtos.TrainingGroupDTO;
import com.denniseckerskorn.entities.class_managment.TrainingGroup;
import com.denniseckerskorn.entities.class_managment.TrainingSession;
import com.denniseckerskorn.entities.user_managment.users.Student;
import com.denniseckerskorn.entities.user_managment.users.Teacher;
import com.denniseckerskorn.enums.StatusValues;
import com.denniseckerskorn.exceptions.EntityNotFoundException;
import com.denniseckerskorn.exceptions.InvalidDataException;
import com.denniseckerskorn.services.class_managment_services.TrainingGroupService;
import com.denniseckerskorn.services.class_managment_services.TrainingSessionService;
import com.denniseckerskorn.services.user_managment_services.StudentService;
import com.denniseckerskorn.services.user_managment_services.TeacherService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.transaction.Transactional;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Controller for managing training groups.
* Provides endpoints for creating, updating, retrieving, and deleting training groups.
*/
@RestController
@RequestMapping("/api/v1/training-groups")
@Tag(name = "Training Group Management", description = "Operations related to training group management")
public class TrainingGroupController {
private final TrainingGroupService trainingGroupService;
private final TeacherService teacherService;
private final StudentService studentService;
private final TrainingSessionService trainingSessionService;
public TrainingGroupController(TrainingGroupService trainingGroupService, TeacherService teacherService, StudentService studentService, TrainingSessionService trainingSessionService) {
this.trainingGroupService = trainingGroupService;
this.teacherService = teacherService;
this.studentService = studentService;
this.trainingSessionService = trainingSessionService;
}
@Operation(summary = "Create a training group with a teacher")
@PostMapping("/create")
public ResponseEntity<TrainingGroupDTO> createGroup(@RequestBody TrainingGroupDTO dto) {
Teacher teacher = teacherService.findById(dto.getTeacherId());
TrainingGroup group = new TrainingGroup();
group.setName(dto.getName());
group.setLevel(dto.getLevel());
group.setSchedule(dto.getSchedule());
group.setTeacher(teacher);
TrainingGroup createdGroup = trainingGroupService.save(group);
TrainingSession trainingSession = new TrainingSession();
trainingSession.setTrainingGroup(createdGroup);
trainingSession.setDate(createdGroup.getSchedule());
trainingSession.setStatus(StatusValues.ACTIVE);
trainingSessionService.save(trainingSession);
return ResponseEntity.status(HttpStatus.CREATED).body(new TrainingGroupDTO(createdGroup));
}
@Operation(summary = "Assign a student to a group")
@PutMapping("/assign-student")
public ResponseEntity<Void> assignStudent(@RequestParam Integer groupId, @RequestParam Integer studentId) {
TrainingGroup group = trainingGroupService.findById(groupId);
Student student = studentService.findById(studentId);
trainingGroupService.addStudentToGroup(group, student);
return ResponseEntity.ok().build();
}
@Operation(summary = "Remove a student from a group")
@PutMapping("/remove-student")
public ResponseEntity<Void> removeStudent(@RequestParam Integer groupId, @RequestParam Integer studentId) {
TrainingGroup group = trainingGroupService.findById(groupId);
Student student = studentService.findById(studentId);
trainingGroupService.removeStudentFromGroup(group, student);
return ResponseEntity.ok().build();
}
@Operation(summary = "Update an existing training group", description = "Update an existing training group with the specified ID")
@Transactional
@PutMapping("/update/{id}")
public ResponseEntity<TrainingGroupDTO> update(@PathVariable Integer id, @RequestBody TrainingGroupDTO dto) {
dto.setId(id);
Teacher teacher = teacherService.findById(dto.getTeacherId());
Set<Student> students = dto.getStudentIds().stream()
.map(studentService::findById)
.collect(Collectors.toSet());
TrainingGroup updated = trainingGroupService.update(dto.toEntity(teacher, students));
List<TrainingSession> sessions = updated.getTrainingSessions().stream().toList();
if (!sessions.isEmpty()) {
TrainingSession session = sessions.get(0);
session.setDate(updated.getSchedule());
trainingSessionService.save(session);
}
return ResponseEntity.ok(new TrainingGroupDTO(updated));
}
@Operation(summary = "Find a training group by ID", description = "Retrieve a training group with the specified ID")
@GetMapping("findById/{id}")
public ResponseEntity<TrainingGroupDTO> findGroupById(@PathVariable Integer id) {
return ResponseEntity.ok(new TrainingGroupDTO(trainingGroupService.findById(id)));
}
@Operation(summary = "Get all training groups", description = "Retrieve a list of all training groups")
@GetMapping("/getAll")
public ResponseEntity<List<TrainingGroupDTO>> getAll() {
return ResponseEntity.ok(
trainingGroupService.findAll().stream()
.map(TrainingGroupDTO::new)
.collect(Collectors.toList())
);
}
@Operation(summary = "Delete a training group by ID", description = "Delete a training group with the specified ID")
@Transactional
@DeleteMapping("/delete/{id}")
public ResponseEntity<Void> delete(@PathVariable Integer id) {
TrainingGroup group = trainingGroupService.findById(id);
if (group == null) {
throw new EntityNotFoundException("Group not found");
}
for (TrainingSession session : group.getTrainingSessions()) {
trainingSessionService.deleteAllAssistancesBySession(session.getId());
}
for (TrainingSession session : group.getTrainingSessions()) {
trainingSessionService.deleteById(session.getId());
}
Set<Student> students = group.getStudents();
if (students != null) {
for (Student student : students) {
student.getTrainingGroups().remove(group);
}
group.getStudents().clear();
}
trainingGroupService.update(group);
trainingGroupService.deleteById(id);
return ResponseEntity.noContent().build();
}
}

View File

@ -0,0 +1,51 @@
package com.denniseckerskorn.controllers.class_management_controllers;
import com.denniseckerskorn.dtos.class_managment_dtos.TrainingSessionDTO;
import com.denniseckerskorn.entities.class_managment.TrainingGroup;
import com.denniseckerskorn.entities.class_managment.TrainingSession;
import com.denniseckerskorn.services.class_managment_services.TrainingGroupService;
import com.denniseckerskorn.services.class_managment_services.TrainingSessionService;
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.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/v1/training-sessions")
@Tag(name = "Training Session Management", description = "Operations related to training session management")
public class TrainingSessionController {
private final TrainingSessionService trainingSessionService;
private final TrainingGroupService trainingGroupService;
public TrainingSessionController(TrainingSessionService trainingSessionService, TrainingGroupService trainingGroupService) {
this.trainingSessionService = trainingSessionService;
this.trainingGroupService = trainingGroupService;
}
@Operation(summary = "Find a training session by ID", description = "Retrieve a training session by its ID")
@GetMapping("findById/{id}")
public TrainingSessionDTO findTrainingSessionById(@PathVariable Integer id) {
return TrainingSessionDTO.fromEntity(trainingSessionService.findById(id));
}
@Operation(summary = "Get all training sessions", description = "Retrieve a list of all training sessions")
@GetMapping("/getAll")
public List<TrainingSessionDTO> getAll() {
return trainingSessionService.findAll()
.stream()
.map(TrainingSessionDTO::fromEntity)
.collect(Collectors.toList());
}
@Operation(summary = "Get all training sessions by group ID", description = "Retrieve a list of all training sessions by group ID")
@DeleteMapping("delete/{id}")
public void delete(@PathVariable Integer id) {
trainingSessionService.deleteById(id);
}
}

View File

@ -0,0 +1,122 @@
package com.denniseckerskorn.controllers.user_managment_controllers;
import com.denniseckerskorn.dtos.user_managment_dtos.AdminDTO;
import com.denniseckerskorn.dtos.user_managment_dtos.UserDTO;
import com.denniseckerskorn.entities.user_managment.users.Admin;
import com.denniseckerskorn.entities.user_managment.users.User;
import com.denniseckerskorn.exceptions.InvalidDataException;
import com.denniseckerskorn.services.user_managment_services.AdminService;
import com.denniseckerskorn.services.user_managment_services.RoleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/v1/admins")
@Tag(name = "Administrator Management", description = "Operations related to administrator management")
public class AdminController {
private final AdminService adminService;
private final RoleService roleService;
@Autowired
private PasswordEncoder passwordEncoder;
public AdminController(AdminService adminService, RoleService roleService) {
this.adminService = adminService;
this.roleService = roleService;
}
@Operation(summary = "Get all administrators")
@GetMapping("/getAll")
public ResponseEntity<List<AdminDTO>> getAllAdmins() {
List<Admin> admins = adminService.findAll();
List<AdminDTO> dtos = admins.stream()
.map(this::convertToDTO)
.collect(Collectors.toList());
return dtos.isEmpty() ? ResponseEntity.noContent().build() : ResponseEntity.ok(dtos);
}
@Operation(summary = "Get administrator by ID")
@GetMapping("/getById/{id}")
public ResponseEntity<AdminDTO> getById(@PathVariable Integer id) {
Admin admin = adminService.findById(id);
return ResponseEntity.ok(convertToDTO(admin));
}
@Operation(summary = "Create a new administrator")
@PostMapping("/create")
public ResponseEntity<AdminDTO> create(@RequestBody AdminDTO dto) {
Admin admin = convertToEntity(dto, true);
Admin saved = adminService.save(admin);
return ResponseEntity.status(201).body(convertToDTO(saved));
}
@Operation(summary = "Update an existing administrator")
@PutMapping("/update/{id}")
public ResponseEntity<AdminDTO> update(@PathVariable Integer id, @RequestBody AdminDTO dto) {
dto.setId(id);
Admin admin = convertToEntity(dto, false);
Admin updated = adminService.update(admin);
return ResponseEntity.ok(convertToDTO(updated));
}
@Operation(summary = "Delete an administrator by ID")
@DeleteMapping("/delete/{id}")
public ResponseEntity<String> delete(@PathVariable Integer id) {
adminService.deleteById(id);
return ResponseEntity.ok("Admin deleted");
}
// -------------------- Utils --------------------
private AdminDTO convertToDTO(Admin admin) {
return AdminDTO.fromEntity(admin);
}
private Admin convertToEntity(AdminDTO dto, boolean isCreate) {
if (dto == null || dto.getUser() == null) {
throw new InvalidDataException("Admin and User data are required");
}
Admin admin;
if (isCreate) {
admin = new Admin();
} else {
admin = adminService.findById(dto.getId());
if (admin == null) {
throw new InvalidDataException("Admin not found for update");
}
}
User user = dto.getUser().toEntity();
if (isCreate) {
if (dto.getUser().getPassword() == null || dto.getUser().getPassword().isBlank()) {
throw new InvalidDataException("Password is required for new admin");
}
user.setPassword(passwordEncoder.encode(dto.getUser().getPassword()));
user.setRegisterDate(user.getRegisterDate() != null ? user.getRegisterDate() : LocalDateTime.now());
} else {
if (dto.getUser().getPassword() != null && !dto.getUser().getPassword().isBlank()) {
user.setPassword(passwordEncoder.encode(dto.getUser().getPassword()));
}
}
if (dto.getUser().getRoleName() != null) {
user.setRole(roleService.findRoleByName(dto.getUser().getRoleName()));
}
admin.setUser(user);
return admin;
}
}

View File

@ -0,0 +1,127 @@
package com.denniseckerskorn.controllers.user_managment_controllers;
import com.denniseckerskorn.dtos.user_managment_dtos.NotificationDTO;
import com.denniseckerskorn.entities.user_managment.Notification;
import com.denniseckerskorn.entities.user_managment.users.User;
import com.denniseckerskorn.services.user_managment_services.NotificationService;
import com.denniseckerskorn.services.user_managment_services.UserService;
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.*;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/v1/notifications")
@Tag(name = "Notification Management", description = "Operations related to notifications")
public class NotificationController {
private final NotificationService notificationService;
private final UserService userService;
public NotificationController(NotificationService notificationService, UserService userService) {
this.notificationService = notificationService;
this.userService = userService;
}
@Operation(summary = "Get all notifications", description = "Retrieve a list of all notifications")
@GetMapping("/getAll")
public ResponseEntity<List<NotificationDTO>> getAll() {
List<Notification> notifications = notificationService.findAll();
if (notifications.isEmpty()) return ResponseEntity.noContent().build();
List<NotificationDTO> dtos = notifications.stream().map(this::toDTO).collect(Collectors.toList());
return ResponseEntity.ok(dtos);
}
@Operation(summary = "Get a notification by ID", description = "Retrieve a notification by its ID")
@GetMapping("/getById/{id}")
public ResponseEntity<NotificationDTO> getById(@PathVariable Integer id) {
Notification notification = notificationService.findById(id);
return ResponseEntity.ok(toDTO(notification));
}
@Operation(summary = "Create a new notification", description = "Create a new notification")
@PostMapping("/create")
public ResponseEntity<NotificationDTO> create(@RequestBody NotificationDTO dto) {
Notification notification = toEntity(dto, false);
Notification saved = notificationService.save(notification);
if (dto.getUserIds() != null) {
for (Integer userId : dto.getUserIds()) {
User user = userService.findById(userId);
notificationService.addNotificationToUser(saved, user);
}
}
return ResponseEntity.status(201).body(toDTO(saved));
}
@Operation(summary = "Update a notification by ID", description = "Update a notification by its ID")
@PutMapping("/update/{id}")
public ResponseEntity<NotificationDTO> update(@PathVariable Integer id, @RequestBody NotificationDTO dto) {
dto.setId(id);
Notification notification = toEntity(dto, false);
Notification updated = notificationService.update(notification);
Set<User> existingUsers = updated.getUsers();
if (existingUsers != null) {
for (User user : existingUsers) {
notificationService.removeNotificationFromUser(updated, user);
}
}
if (dto.getUserIds() != null) {
for (Integer userId : dto.getUserIds()) {
User user = userService.findById(userId);
notificationService.addNotificationToUser(updated, user);
}
}
return ResponseEntity.ok(toDTO(updated));
}
@Operation(summary = "Delete a notification by ID", description = "Delete a notification by its ID")
@DeleteMapping("/delete/{id}")
public ResponseEntity<String> delete(@PathVariable Integer id) {
notificationService.deleteById(id);
return ResponseEntity.ok("Notification deleted successfully.");
}
// -------------------- Mapping --------------------
private NotificationDTO toDTO(Notification notification) {
Set<Integer> userIds = notification.getUsers() != null
? notification.getUsers().stream().map(User::getId).collect(Collectors.toSet())
: null;
return new NotificationDTO(
notification.getId(),
notification.getTitle(),
notification.getMessage(),
notification.getShippingDate(),
notification.getType(),
notification.getStatus(),
userIds
);
}
private Notification toEntity(NotificationDTO dto, boolean includeUsers) {
Notification notification = (dto.getId() != null)
? notificationService.findById(dto.getId())
: new Notification();
notification.setTitle(dto.getTitle());
notification.setMessage(dto.getMessage());
notification.setShippingDate(dto.getShippingDate());
notification.setType(dto.getType());
notification.setStatus(dto.getStatus());
return notification;
}
}

View File

@ -0,0 +1,81 @@
package com.denniseckerskorn.controllers.user_managment_controllers;
import com.denniseckerskorn.dtos.user_managment_dtos.PermissionDTO;
import com.denniseckerskorn.entities.user_managment.Permission;
import com.denniseckerskorn.services.user_managment_services.PermissionService;
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.*;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/v1/permissions")
@Tag(name = "Permission Management", description = "Operations related to permissions")
public class PermissionController {
private final PermissionService permissionService;
public PermissionController(PermissionService permissionService) {
this.permissionService = permissionService;
}
@Operation(summary = "Get all permissions", description = "Retrieve a list of all permissions")
@GetMapping("/getAll")
public ResponseEntity<List<PermissionDTO>> getAll() {
List<Permission> permissions = permissionService.findAll();
if (permissions.isEmpty()) return ResponseEntity.noContent().build();
List<PermissionDTO> dtos = permissions.stream()
.map(this::toDTO)
.collect(Collectors.toList());
return ResponseEntity.ok(dtos);
}
@Operation(summary = "Get permission by ID", description = "Retrieve a permission by its ID")
@GetMapping("/getById/{id}")
public ResponseEntity<PermissionDTO> getById(@PathVariable Integer id) {
Permission permission = permissionService.findById(id);
return ResponseEntity.ok(toDTO(permission));
}
@Operation(summary = "Create a new permission", description = "Create a new permission")
@PostMapping("/create")
public ResponseEntity<PermissionDTO> create(@RequestBody PermissionDTO dto) {
Permission permission = toEntity(dto);
Permission saved = permissionService.save(permission);
return ResponseEntity.status(201).body(toDTO(saved));
}
@Operation(summary = "Update an existing permission", description = "Update an existing permission")
@PutMapping("/update/{id}")
public ResponseEntity<PermissionDTO> update(@PathVariable Integer id, @RequestBody PermissionDTO dto) {
dto.setId(id);
Permission updated = permissionService.update(toEntity(dto));
return ResponseEntity.ok(toDTO(updated));
}
@Operation(summary = "Delete a permission", description = "Delete a permission by its ID")
@DeleteMapping("/delete/{id}")
public ResponseEntity<String> delete(@PathVariable Integer id) {
permissionService.deleteById(id);
return ResponseEntity.ok("Permission deleted successfully.");
}
// -------------------- Mapping --------------------
private PermissionDTO toDTO(Permission permission) {
return new PermissionDTO(permission.getId(), permission.getPermissionName());
}
private Permission toEntity(PermissionDTO dto) {
Permission permission = (dto.getId() != null)
? permissionService.findById(dto.getId())
: new Permission();
permission.setPermissionName(dto.getPermissionName());
return permission;
}
}

View File

@ -0,0 +1,116 @@
package com.denniseckerskorn.controllers.user_managment_controllers;
import com.denniseckerskorn.dtos.user_managment_dtos.RoleDTO;
import com.denniseckerskorn.entities.user_managment.Permission;
import com.denniseckerskorn.entities.user_managment.Role;
import com.denniseckerskorn.services.user_managment_services.PermissionService;
import com.denniseckerskorn.services.user_managment_services.RoleService;
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.*;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/v1/roles")
@Tag(name = "Role Management", description = "Operations related to roles")
public class RoleController {
private final RoleService roleService;
private final PermissionService permissionService;
public RoleController(RoleService roleService, PermissionService permissionService) {
this.roleService = roleService;
this.permissionService = permissionService;
}
@Operation(summary = "Get all roles", description = "Retrieve a list of all roles")
@GetMapping("/getAll")
public ResponseEntity<List<RoleDTO>> getAll() {
List<Role> roles = roleService.findAll();
if (roles.isEmpty()) return ResponseEntity.noContent().build();
List<RoleDTO> dtos = roles.stream().map(this::toDTO).collect(Collectors.toList());
return ResponseEntity.ok(dtos);
}
@Operation(summary = "Get role by ID", description = "Retrieve a role by its ID")
@GetMapping("/getById/{id}")
public ResponseEntity<RoleDTO> getById(@PathVariable Integer id) {
Role role = roleService.findById(id);
return ResponseEntity.ok(toDTO(role));
}
@Operation(summary = "Create a new role", description = "Create a new role")
@PostMapping("/create")
public ResponseEntity<RoleDTO> create(@RequestBody RoleDTO dto) {
Role role = new Role();
role.setName(dto.getName());
Role saved = roleService.save(role);
if (dto.getPermissionIds() != null) {
for (Integer pid : dto.getPermissionIds()) {
Permission perm = permissionService.findById(pid);
roleService.addPermissionToRole(saved, perm);
}
}
return ResponseEntity.status(201).body(toDTO(saved));
}
@Operation(summary = "Update a role", description = "Update an existing role")
@PutMapping("/update/{id}")
public ResponseEntity<RoleDTO> update(@PathVariable Integer id, @RequestBody RoleDTO dto) {
dto.setId(id);
Role role = roleService.findById(id);
role.setName(dto.getName());
Role updated = roleService.update(role);
if (dto.getPermissionIds() != null) {
for (Integer pid : dto.getPermissionIds()) {
Permission perm = permissionService.findById(pid);
roleService.addPermissionToRole(updated, perm);
}
}
return ResponseEntity.ok(toDTO(updated));
}
@Operation(summary = "Delete a role", description = "Delete a role by its ID")
@DeleteMapping("/delete/{id}")
public ResponseEntity<String> delete(@PathVariable Integer id) {
roleService.deleteById(id);
return ResponseEntity.ok("Role deleted successfully.");
}
@Operation(summary = "Add permission to role", description = "Add a permission to a role")
@PostMapping("/permissions/add/{roleId}/{permissionId}")
public ResponseEntity<String> addPermissionToRole(@PathVariable Integer roleId, @PathVariable Integer permissionId) {
Role role = roleService.findById(roleId);
Permission permission = permissionService.findById(permissionId);
roleService.addPermissionToRole(role, permission);
return ResponseEntity.ok("Permission added to role.");
}
@Operation(summary = "Remove permission from role", description = "Remove a permission from a role")
@DeleteMapping("/permissions/remove/{permissionId}/{roleId}")
public ResponseEntity<String> removePermissionFromRole(@PathVariable Integer roleId, @PathVariable Integer permissionId) {
Role role = roleService.findById(roleId);
Permission permission = permissionService.findById(permissionId);
roleService.removePermissionFromRole(role, permission);
return ResponseEntity.ok("Permission removed from role.");
}
// -------------------- Mapping --------------------
private RoleDTO toDTO(Role role) {
Set<Integer> permissionIds = role.getPermissions().stream()
.map(Permission::getId)
.collect(Collectors.toSet());
return new RoleDTO(role.getId(), role.getName(), permissionIds);
}
}

View File

@ -0,0 +1,275 @@
package com.denniseckerskorn.controllers.user_managment_controllers;
import com.denniseckerskorn.dtos.class_managment_dtos.AssistanceDTO;
import com.denniseckerskorn.dtos.user_managment_dtos.StudentDTO;
import com.denniseckerskorn.dtos.user_managment_dtos.StudentRegisterDTO;
import com.denniseckerskorn.entities.class_managment.Assistance;
import com.denniseckerskorn.entities.class_managment.Membership;
import com.denniseckerskorn.entities.class_managment.TrainingGroup;
import com.denniseckerskorn.entities.class_managment.TrainingSession;
import com.denniseckerskorn.entities.user_managment.Role;
import com.denniseckerskorn.entities.user_managment.StudentHistory;
import com.denniseckerskorn.entities.user_managment.users.Student;
import com.denniseckerskorn.entities.user_managment.users.User;
import com.denniseckerskorn.enums.StatusValues;
import com.denniseckerskorn.exceptions.InvalidDataException;
import com.denniseckerskorn.services.class_managment_services.MembershipService;
import com.denniseckerskorn.services.class_managment_services.TrainingSessionService;
import com.denniseckerskorn.services.user_managment_services.RoleService;
import com.denniseckerskorn.services.user_managment_services.StudentService;
import com.denniseckerskorn.services.user_managment_services.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.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/v1/students")
@Tag(name = "Student Management", description = "Operations related to student management")
public class StudentController {
private final StudentService studentService;
private final RoleService roleService;
private final UserService userService;
private final MembershipService membershipService;
private final TrainingSessionService trainingSessionService;
@Autowired
private PasswordEncoder passwordEncoder;
public StudentController(StudentService studentService, RoleService roleService, UserService userService, MembershipService membershipService, TrainingSessionService trainingSessionService) {
this.studentService = studentService;
this.roleService = roleService;
this.userService = userService;
this.membershipService = membershipService;
this.trainingSessionService = trainingSessionService;
}
@Operation(summary = "Register a new Student", description = "Registers a new student with the provided details.")
@PostMapping("/register")
public ResponseEntity<StudentDTO> registerStudent(@RequestBody @Valid StudentRegisterDTO studentRegisterDTO) {
User user = new User();
user.setName(studentRegisterDTO.getName());
user.setSurname(studentRegisterDTO.getSurname());
user.setEmail(studentRegisterDTO.getEmail());
user.setPassword(passwordEncoder.encode(studentRegisterDTO.getPassword())); // Encriptar
user.setPhoneNumber(studentRegisterDTO.getPhoneNumber());
user.setAddress(studentRegisterDTO.getAddress());
user.setStatus(StatusValues.valueOf(studentRegisterDTO.getStatus()));
user.setRegisterDate(LocalDateTime.now());
Role role = roleService.findRoleByName(studentRegisterDTO.getRoleName());
user.setRole(role);
User createdUser = userService.save(user);
Student student = new Student();
student.setUser(createdUser);
student.setDni(studentRegisterDTO.getDni());
student.setBirthdate(studentRegisterDTO.getBirthdate());
student.setBelt(studentRegisterDTO.getBelt());
student.setProgress(studentRegisterDTO.getProgress());
student.setMedicalReport(studentRegisterDTO.getMedicalReport());
student.setParentName(studentRegisterDTO.getParentName());
if (studentService.existsByDni(student.getDni())) {
throw new InvalidDataException("A student with this DNI already exists");
}
if (studentRegisterDTO.getMembershipId() != null) {
Membership membership = membershipService.findById(studentRegisterDTO.getMembershipId());
if (membership == null) {
throw new InvalidDataException("Membership not found with id: " + studentRegisterDTO.getMembershipId());
}
student.setMembership(membership);
}
Student createdStudent = studentService.save(student);
StudentDTO response = StudentDTO.fromEntity(studentService.findById(createdStudent.getId()));
return ResponseEntity.status(HttpStatus.CREATED).body(response);
}
@Operation(summary = "Get all Students", description = "Retrieves a list of all students.")
@GetMapping("/getAll")
public ResponseEntity<List<StudentDTO>> getAllStudents() {
List<Student> students = studentService.findAll();
if (students.isEmpty()) return ResponseEntity.noContent().build();
List<StudentDTO> dtos = students.stream()
.map(this::convertToDTO)
.collect(Collectors.toList());
return ResponseEntity.ok(dtos);
}
@Operation(summary = "Create a new Student", description = "Creates a new student with the provided details.")
@PostMapping("/create")
public ResponseEntity<StudentDTO> createStudent(@RequestBody StudentDTO dto) {
Student student = convertToEntity(dto, true);
Student saved = studentService.save(student);
return ResponseEntity.status(HttpStatus.CREATED).body(convertToDTO(saved));
}
@Operation(summary = "Update an existing Student", description = "Updates the details of an existing student.")
@PutMapping("/update/{id}")
public ResponseEntity<StudentDTO> updateStudent(@PathVariable Integer id, @RequestBody StudentDTO dto) {
dto.setId(id);
Student student = convertToEntity(dto, false);
Student updated = studentService.update(student);
return ResponseEntity.ok(convertToDTO(updated));
}
@Operation(summary = "Find a Student by ID", description = "Retrieves a student by their ID.")
@GetMapping("/findById/{id}")
public ResponseEntity<StudentDTO> getStudentById(@PathVariable Integer id) {
Student student = studentService.findById(id);
return ResponseEntity.ok(convertToDTO(student));
}
@Operation(summary = "Delete a Student", description = "Deletes a student by their ID.")
@DeleteMapping("/delete/{id}")
public ResponseEntity<String> deleteStudent(@PathVariable Integer id) {
studentService.deleteById(id);
return ResponseEntity.ok("Student deleted successfully");
}
@Operation(summary = "Add a Student History", description = "Adds a history record to a student by their ID.")
@PostMapping("/addStudentHistory/{id}")
public ResponseEntity<String> addStudentHistory(@PathVariable Integer id, @RequestBody StudentHistory history) {
Student student = studentService.findById(id);
studentService.addStudentHistoryToStudent(student, history);
return ResponseEntity.ok("Student history added successfully");
}
@Operation(summary = "Remove a Student History", description = "Removes a history record from a student.")
@DeleteMapping("/removeStudentHistory/{id}")
public ResponseEntity<String> removeStudentHistory(@PathVariable Integer id) {
studentService.deleteStudentHistory(id);
return ResponseEntity.ok("Student history removed successfully");
}
@Operation(summary = "Add a Membership to a Student", description = "Adds a membership to a student by their ID.")
@PostMapping("/addMembershipToStudent/{id}")
public ResponseEntity<String> addMembershipToStudent(@PathVariable Integer id, @RequestBody Membership membership) {
Student student = studentService.findById(id);
studentService.addStudentToMembership(student, membership);
return ResponseEntity.ok("Membership added to student successfully");
}
@Operation(summary = "Remove a Membership from a Student", description = "Removes a membership from a student by their ID.")
@DeleteMapping("/removeMembershipFromStudent/{id}")
public ResponseEntity<String> removeMembershipFromStudent(@PathVariable Integer id) {
studentService.deleteStudentMembership(id);
return ResponseEntity.ok("Membership removed from student successfully");
}
@Operation(summary = "Add an Assistance to a Student", description = "Adds an assistance record to a student by their ID.")
@PostMapping("/addAssistanceToStudent/{id}")
public ResponseEntity<String> addAssistanceToStudent(@PathVariable Integer id, @RequestBody AssistanceDTO assistanceDTO) {
Student student = studentService.findById(id);
TrainingSession session = trainingSessionService.findById(assistanceDTO.getSessionId());
Assistance assistance = assistanceDTO.toEntity(student, session);
studentService.addAssistanceToStudent(student, assistance);
return ResponseEntity.ok("Assistance added to student successfully");
}
@Operation(summary = "Remove an Assistance from a Student", description = "Removes an assistance record from a student by their ID.")
@DeleteMapping("/deleteAssistanceFromStudent/{id}")
public ResponseEntity<String> deleteAssistanceFromStudent(@PathVariable Integer studentId, @PathVariable Integer assistanceId) {
studentService.deleteSingleAssistanceFromStudent(studentId, assistanceId);
return ResponseEntity.ok("Assistance removed from student successfully");
}
@Operation(summary = "Add a Training Group to a Student", description = "Adds a training group to a student by their ID.")
@PostMapping("/addGroupToStudent/{id}")
public ResponseEntity<String> addGroupToStudent(@PathVariable Integer id, @RequestBody TrainingGroup group) {
studentService.addGroupToStudent(id, group);
return ResponseEntity.ok("Training group added to student successfully");
}
@Operation(summary = "Update a student's membership")
@PutMapping("/updateMembership/{studentId}")
public ResponseEntity<Void> updateMembership(
@PathVariable Integer studentId,
@RequestParam Integer membershipId) {
Student student = studentService.findById(studentId);
Membership membership = membershipService.findById(membershipId);
student.setMembership(membership);
studentService.update(student);
return ResponseEntity.ok().build();
}
/* ----------------- Mapping Methods ------------------ */
private StudentDTO convertToDTO(Student student) {
return StudentDTO.fromEntity(student);
}
private Student convertToEntity(StudentDTO dto, boolean isCreate) {
if (dto == null || dto.getUser() == null) {
throw new InvalidDataException("User data is required");
}
User user;
if (isCreate) {
user = new User();
user.setRegisterDate(dto.getUser().getRegisterDate() != null ? dto.getUser().getRegisterDate() : LocalDateTime.now());
} else {
Student existing = studentService.findById(dto.getId());
user = existing.getUser();
}
user.setName(dto.getUser().getName());
user.setSurname(dto.getUser().getSurname());
user.setEmail(dto.getUser().getEmail());
user.setPhoneNumber(dto.getUser().getPhoneNumber());
user.setAddress(dto.getUser().getAddress());
user.setStatus(dto.getUser().getStatus());
if (dto.getUser().getRoleName() != null) {
user.setRole(roleService.findRoleByName(dto.getUser().getRoleName()));
}
if (isCreate) {
if (dto.getUser().getPassword() == null || dto.getUser().getPassword().isBlank()) {
throw new InvalidDataException("Password is required for new student");
}
user.setPassword(passwordEncoder.encode(dto.getUser().getPassword()));
} else {
if (dto.getUser().getPassword() != null && !dto.getUser().getPassword().isBlank()) {
user.setPassword(passwordEncoder.encode(dto.getUser().getPassword()));
}
}
Student student = isCreate ? new Student() : studentService.findById(dto.getId());
student.setUser(user);
student.setDni(dto.getDni());
student.setBirthdate(dto.getBirthdate());
student.setBelt(dto.getBelt());
student.setProgress(dto.getProgress());
student.setMedicalReport(dto.getMedicalReport());
student.setParentName(dto.getParentName());
return student;
}
}

View File

@ -0,0 +1,98 @@
package com.denniseckerskorn.controllers.user_managment_controllers;
import com.denniseckerskorn.dtos.user_managment_dtos.StudentHistoryDTO;
import com.denniseckerskorn.entities.user_managment.StudentHistory;
import com.denniseckerskorn.entities.user_managment.users.Student;
import com.denniseckerskorn.services.user_managment_services.StudentHistoryService;
import com.denniseckerskorn.services.user_managment_services.StudentService;
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.*;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/v1/student-history")
@Tag(name = "Student History Management", description = "Operations related to student history")
public class StudentHistoryController {
private final StudentHistoryService studentHistoryService;
private final StudentService studentService;
public StudentHistoryController(StudentHistoryService studentHistoryService, StudentService studentService) {
this.studentHistoryService = studentHistoryService;
this.studentService = studentService;
}
@Operation(summary = "Get all student histories", description = "Retrieve a list of all student histories")
@GetMapping("/getAll")
public ResponseEntity<List<StudentHistoryDTO>> getAll() {
List<StudentHistory> histories = studentHistoryService.findAll();
if (histories.isEmpty()) return ResponseEntity.noContent().build();
List<StudentHistoryDTO> dtos = histories.stream().map(this::toDTO).collect(Collectors.toList());
return ResponseEntity.ok(dtos);
}
@Operation(summary = "find student history by ID", description = "Retrieve a student history by its ID")
@GetMapping("/findById/{id}")
public ResponseEntity<StudentHistoryDTO> findById(@PathVariable Integer id) {
StudentHistory history = studentHistoryService.findById(id);
return ResponseEntity.ok(toDTO(history));
}
@Operation(summary = "Create a new student history", description = "Create a new student history")
@PostMapping("/create")
public ResponseEntity<StudentHistoryDTO> create(@RequestBody StudentHistoryDTO dto) {
StudentHistory history = toEntity(dto, false);
StudentHistory saved = studentHistoryService.save(history);
return ResponseEntity.status(201).body(toDTO(saved));
}
@Operation(summary = "Update an existing student history", description = "Update an existing student history")
@PutMapping("/update/{id}")
public ResponseEntity<StudentHistoryDTO> update(@PathVariable Integer id, @RequestBody StudentHistoryDTO dto) {
dto.setId(id);
StudentHistory history = toEntity(dto, true);
StudentHistory updated = studentHistoryService.update(history);
return ResponseEntity.ok(toDTO(updated));
}
@Operation(summary = "Delete a student history", description = "Delete a student history by its ID")
@DeleteMapping("/delete/{id}")
public ResponseEntity<String> delete(@PathVariable Integer id) {
studentHistoryService.deleteById(id);
return ResponseEntity.ok("Student history deleted successfully.");
}
// -------------------- Mapping --------------------
private StudentHistoryDTO toDTO(StudentHistory history) {
return new StudentHistoryDTO(
history.getId(),
history.getStudent() != null ? history.getStudent().getId() : null,
history.getEventDate(),
history.getEventType(),
history.getDescription()
);
}
private StudentHistory toEntity(StudentHistoryDTO dto, boolean includeExistingStudent) {
StudentHistory history = (dto.getId() != null)
? studentHistoryService.findById(dto.getId())
: new StudentHistory();
history.setEventDate(dto.getEventDate());
history.setEventType(dto.getEventType());
history.setDescription(dto.getDescription());
if (!includeExistingStudent && dto.getStudentId() != null) {
Student student = studentService.findById(dto.getStudentId());
history.setStudent(student);
}
return history;
}
}

View File

@ -0,0 +1,137 @@
package com.denniseckerskorn.controllers.user_managment_controllers;
import com.denniseckerskorn.dtos.user_managment_dtos.TeacherDTO;
import com.denniseckerskorn.entities.user_managment.users.Teacher;
import com.denniseckerskorn.entities.user_managment.users.User;
import com.denniseckerskorn.exceptions.InvalidDataException;
import com.denniseckerskorn.services.user_managment_services.RoleService;
import com.denniseckerskorn.services.user_managment_services.TeacherService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/v1/teachers")
@Tag(name = "Teacher Management", description = "Operations related to teachers")
public class TeacherController {
private final TeacherService teacherService;
private final RoleService roleService;
@Autowired
private PasswordEncoder passwordEncoder;
public TeacherController(TeacherService teacherService, RoleService roleService) {
this.teacherService = teacherService;
this.roleService = roleService;
}
@Operation(summary = "Get all teachers", description = "Retrieve a list of all teachers")
@GetMapping("/getAll")
public ResponseEntity<List<TeacherDTO>> getAllTeachers() {
List<Teacher> teachers = teacherService.findAll();
if (teachers.isEmpty()) {
return ResponseEntity.noContent().build();
}
List<TeacherDTO> dtos = teachers.stream()
.map(this::convertToDTO)
.collect(Collectors.toList());
return ResponseEntity.ok(dtos);
}
@Operation(summary = "Create a new teacher", description = "Create a new teacher")
@PostMapping("/create")
public ResponseEntity<TeacherDTO> createTeacher(@RequestBody TeacherDTO dto) {
Teacher teacher = convertToEntity(dto, true);
Teacher saved = teacherService.save(teacher);
return ResponseEntity.status(HttpStatus.CREATED).body(convertToDTO(saved));
}
@Operation(summary = "Find a teacher by ID", description = "Retrieve a teacher by their ID")
@GetMapping("/findById/{id}")
public ResponseEntity<TeacherDTO> findById(@PathVariable Integer id) {
Teacher teacher = teacherService.findById(id);
if (teacher == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(convertToDTO(teacher));
}
@Operation(summary = "Update a teacher", description = "Update an existing teacher")
@PutMapping("/update/{id}")
public ResponseEntity<TeacherDTO> updateTeacher(@PathVariable Integer id, @RequestBody TeacherDTO dto) {
dto.setId(id);
Teacher teacher = convertToEntity(dto, false);
Teacher updated = teacherService.update(teacher);
return ResponseEntity.ok(convertToDTO(updated));
}
@Operation(summary = "Delete a teacher", description = "Delete a teacher by their ID")
@DeleteMapping("/delete/{id}")
public ResponseEntity<String> deleteTeacher(@PathVariable Integer id) {
teacherService.deleteById(id);
return ResponseEntity.ok("Teacher deleted successfully");
}
// ----------------- Mapping ------------------
private TeacherDTO convertToDTO(Teacher teacher) {
return TeacherDTO.fromEntity(teacher);
}
private Teacher convertToEntity(TeacherDTO dto, boolean isCreate) {
if (dto == null || dto.getUser() == null) {
throw new InvalidDataException("User data is required");
}
User user;
if (isCreate) {
user = new User();
user.setRegisterDate(dto.getUser().getRegisterDate() != null ? dto.getUser().getRegisterDate() : LocalDateTime.now());
} else {
Teacher existing = teacherService.findById(dto.getId());
user = existing.getUser();
}
user.setName(dto.getUser().getName());
user.setSurname(dto.getUser().getSurname());
user.setEmail(dto.getUser().getEmail());
user.setPhoneNumber(dto.getUser().getPhoneNumber());
user.setAddress(dto.getUser().getAddress());
user.setStatus(dto.getUser().getStatus());
if (dto.getUser().getRoleName() != null) {
user.setRole(roleService.findRoleByName(dto.getUser().getRoleName()));
}
if (isCreate) {
if (dto.getUser().getPassword() == null || dto.getUser().getPassword().isBlank()) {
throw new InvalidDataException("Password is required for new teacher");
}
user.setPassword(passwordEncoder.encode(dto.getUser().getPassword()));
} else {
if (dto.getUser().getPassword() != null && !dto.getUser().getPassword().isBlank()) {
user.setPassword(passwordEncoder.encode(dto.getUser().getPassword()));
}
}
Teacher teacher = isCreate ? new Teacher() : teacherService.findById(dto.getId());
teacher.setUser(user);
teacher.setDiscipline(dto.getDiscipline());
return teacher;
}
}

View File

@ -0,0 +1,203 @@
package com.denniseckerskorn.controllers.user_managment_controllers;
import com.denniseckerskorn.dtos.user_managment_dtos.NotificationMiniDTO;
import com.denniseckerskorn.dtos.user_managment_dtos.StudentMiniDTO;
import com.denniseckerskorn.dtos.user_managment_dtos.StudentHistoryMiniDTO;
import com.denniseckerskorn.dtos.user_managment_dtos.UserDTO;
import com.denniseckerskorn.entities.user_managment.Notification;
import com.denniseckerskorn.entities.user_managment.users.Student;
import com.denniseckerskorn.entities.user_managment.users.User;
import com.denniseckerskorn.exceptions.InvalidDataException;
import com.denniseckerskorn.security.JwtUtil;
import com.denniseckerskorn.services.user_managment_services.RoleService;
import com.denniseckerskorn.services.user_managment_services.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* UserController is responsible for handling user-related operations such as creating, updating,
* deleting, and retrieving user information.
*/
@RestController
@RequestMapping("/api/v1/users")
@Tag(name = "Users", description = "Operations related to user management")
public class UserController {
private final UserService userService;
private final RoleService roleService;
private final JwtUtil jwtUtil;
@Autowired
private PasswordEncoder passwordEncoder;
public UserController(UserService userService, RoleService roleService, JwtUtil jwtUtil) {
this.userService = userService;
this.roleService = roleService;
this.jwtUtil = jwtUtil;
}
@Operation(summary = "Get all users", description = "Retrieve a list of all users")
@GetMapping("/getAll")
public ResponseEntity<List<UserDTO>> getAllUsers() {
List<User> users = userService.findAll();
if (users.isEmpty()) {
return ResponseEntity.noContent().build();
}
List<UserDTO> userDTOs = users.stream()
.map(this::convertToDTO)
.collect(Collectors.toList());
return ResponseEntity.ok(userDTOs);
}
@Operation(summary = "Find a User by ID", description = "Retrieve a user by their ID")
@GetMapping("/getById/{id}")
public ResponseEntity<UserDTO> getUserById(@PathVariable Integer id) {
User user = userService.findById(id);
return ResponseEntity.ok(convertToDTO(user));
}
@Operation( summary = "Find a User by email", description = "Retrieve a user by their email")
@PostMapping("/create")
public ResponseEntity<UserDTO> createUser(@RequestBody UserDTO userDTO) {
User user = convertToEntity(userDTO, true);
User saved = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED).body(convertToDTO(saved));
}
@Operation(summary = "Update a user by ID", description = "Update an existing user")
@PutMapping("/update/{id}")
public ResponseEntity<UserDTO> updateUser(@PathVariable Integer id, @RequestBody UserDTO userDTO) {
userDTO.setId(id);
User user = convertToEntity(userDTO, false);
User updated = userService.update(user);
return ResponseEntity.ok(convertToDTO(updated));
}
@Operation(summary = "Update a user by email", description = "Update an existing user")
@DeleteMapping("/delete/{id}")
public ResponseEntity<String> deleteUser(@PathVariable Integer id) {
userService.deleteById(id);
return ResponseEntity.ok("User deleted successfully");
}
@Operation(summary = "Get current user", description = "Retrieve the currently authenticated user")
@GetMapping("/me")
public ResponseEntity<UserDTO> getCurrentUser(HttpServletRequest request) {
String token = extractTokenFromRequest(request);
String email = jwtUtil.extractUsername(token);
User user = userService.findByEmail(email);
return ResponseEntity.ok(convertToDTO(user));
}
// ------------------ UTILS ------------------
private String extractTokenFromRequest(HttpServletRequest request) {
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
throw new InvalidDataException("Missing or invalid Authorization header");
}
return authHeader.substring(7); // Remove "Bearer "
}
private UserDTO convertToDTO(User user) {
UserDTO dto = new UserDTO(
user.getId(),
user.getName(),
user.getSurname(),
user.getEmail(),
null,
user.getPhoneNumber(),
user.getAddress(),
user.getRegisterDate(),
user.getRole() != null ? user.getRole().getName() : null,
user.getStatus()
);
if (user.getNotifications() != null && !user.getNotifications().isEmpty()) {
Set<NotificationMiniDTO> notificationDTOs = user.getNotifications().stream()
.map(this::convertNotificationToMiniDTO)
.collect(Collectors.toSet());
dto.setNotifications(notificationDTOs);
}
if (user.getStudent() != null) {
Student student = user.getStudent();
StudentMiniDTO studentMiniDTO = new StudentMiniDTO();
studentMiniDTO.setId(student.getId());
if (student.getHistories() != null && !student.getHistories().isEmpty()) {
Set<StudentHistoryMiniDTO> historyDTOs = student.getHistories().stream()
.map(h -> new StudentHistoryMiniDTO(
h.getId(),
h.getEventDate(),
h.getEventType(),
h.getDescription()
))
.collect(Collectors.toSet());
studentMiniDTO.setHistories(historyDTOs);
}
dto.setStudent(studentMiniDTO);
}
return dto;
}
private NotificationMiniDTO convertNotificationToMiniDTO(Notification notification) {
return new NotificationMiniDTO(
notification.getId(),
notification.getTitle(),
notification.getMessage(),
notification.getShippingDate(),
notification.getType()
);
}
private User convertToEntity(UserDTO dto, boolean isCreate) {
User user;
if (isCreate) {
user = new User();
user.setRegisterDate(dto.getRegisterDate() != null ? dto.getRegisterDate() : LocalDateTime.now());
} else {
user = userService.findById(dto.getId());
}
user.setName(dto.getName());
user.setSurname(dto.getSurname());
user.setEmail(dto.getEmail());
user.setPhoneNumber(dto.getPhoneNumber());
user.setAddress(dto.getAddress());
user.setStatus(dto.getStatus());
if (dto.getRoleName() != null) {
user.setRole(roleService.findRoleByName(dto.getRoleName()));
}
if (isCreate) {
if (dto.getPassword() == null || dto.getPassword().isBlank()) {
throw new InvalidDataException("Password is required when creating a user.");
}
user.setPassword(passwordEncoder.encode(dto.getPassword()));
} else {
if (dto.getPassword() != null && !dto.getPassword().isBlank()) {
user.setPassword(passwordEncoder.encode(dto.getPassword()));
}
}
return user;
}
}

View File

@ -0,0 +1,25 @@
package com.denniseckerskorn.dtos;
public class LoginRequest {
private String email;
private String password;
public LoginRequest() {
}
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;
}
}

View File

@ -0,0 +1,76 @@
package com.denniseckerskorn.dtos.class_managment_dtos;
import com.denniseckerskorn.entities.class_managment.Assistance;
import com.denniseckerskorn.entities.class_managment.TrainingSession;
import com.denniseckerskorn.entities.user_managment.users.Student;
import java.time.LocalDateTime;
public class AssistanceDTO {
private Integer id;
private Integer studentId;
private Integer sessionId;
private LocalDateTime date;
public AssistanceDTO() {
}
public AssistanceDTO(Integer id, Integer studentId, Integer sessionId, LocalDateTime date) {
this.id = id;
this.studentId = studentId;
this.sessionId = sessionId;
this.date = date;
}
public static AssistanceDTO fromEntity(Assistance assistance) {
return new AssistanceDTO(
assistance.getId(),
assistance.getStudent() != null ? assistance.getStudent().getId() : null,
assistance.getTrainingSession() != null ? assistance.getTrainingSession().getId() : null,
assistance.getDate()
);
}
public Assistance toEntity(Student student, TrainingSession session) {
Assistance assistance = new Assistance();
assistance.setId(this.id);
assistance.setStudent(student);
assistance.setTrainingSession(session);
assistance.setDate(this.date);
return assistance;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getStudentId() {
return studentId;
}
public void setStudentId(Integer studentId) {
this.studentId = studentId;
}
public Integer getSessionId() {
return sessionId;
}
public void setSessionId(Integer sessionId) {
this.sessionId = sessionId;
}
public LocalDateTime getDate() {
return date;
}
public void setDate(LocalDateTime date) {
this.date = date;
}
}

View File

@ -0,0 +1,88 @@
package com.denniseckerskorn.dtos.class_managment_dtos;
import com.denniseckerskorn.entities.class_managment.Membership;
import com.denniseckerskorn.enums.MembershipTypeValues;
import com.denniseckerskorn.enums.StatusValues;
import java.time.LocalDate;
public class MembershipDTO {
private Integer id;
private LocalDate startDate;
private LocalDate endDate;
private MembershipTypeValues type;
private StatusValues status;
public MembershipDTO() {
}
public MembershipDTO(Integer id, LocalDate startDate, LocalDate endDate, MembershipTypeValues type, StatusValues status) {
this.id = id;
this.startDate = startDate;
this.endDate = endDate;
this.type = type;
this.status = status;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public LocalDate getStartDate() {
return startDate;
}
public void setStartDate(LocalDate startDate) {
this.startDate = startDate;
}
public LocalDate getEndDate() {
return endDate;
}
public void setEndDate(LocalDate endDate) {
this.endDate = endDate;
}
public MembershipTypeValues getType() {
return type;
}
public void setType(MembershipTypeValues type) {
this.type = type;
}
public StatusValues getStatus() {
return status;
}
public void setStatus(StatusValues status) {
this.status = status;
}
public static MembershipDTO fromEntity(Membership membership) {
MembershipDTO dto = new MembershipDTO();
dto.setId(membership.getId());
dto.setStartDate(membership.getStartDate());
dto.setEndDate(membership.getEndDate());
dto.setType(membership.getType());
dto.setStatus(membership.getStatus());
return dto;
}
public Membership toEntity() {
Membership membership = new Membership();
membership.setId(this.id);
membership.setStartDate(this.startDate);
membership.setEndDate(this.endDate);
membership.setType(this.type);
membership.setStatus(this.status);
return membership;
}
}

View File

@ -0,0 +1,109 @@
package com.denniseckerskorn.dtos.class_managment_dtos;
import com.denniseckerskorn.entities.class_managment.TrainingGroup;
import com.denniseckerskorn.entities.user_managment.users.Student;
import com.denniseckerskorn.entities.user_managment.users.Teacher;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDateTime;
import java.util.Set;
import java.util.stream.Collectors;
public class TrainingGroupDTO {
private Integer id;
private String name;
private String level;
private LocalDateTime schedule;
private Integer teacherId;
private Set<Integer> studentIds;
public TrainingGroupDTO() {
}
public TrainingGroupDTO(TrainingGroup group) {
this.id = group.getId();
this.name = group.getName();
this.level = group.getLevel();
this.schedule = group.getSchedule();
this.teacherId = group.getTeacher() != null ? group.getTeacher().getId() : null;
this.studentIds = group.getStudents().stream().map(Student::getId).collect(Collectors.toSet());
}
public TrainingGroup toEntity(Teacher teacher, Set<Student> students) {
TrainingGroup group = new TrainingGroup();
group.setId(this.id);
group.setName(this.name);
group.setLevel(this.level);
group.setSchedule(this.schedule);
group.setTeacher(teacher);
group.setStudents(students);
return group;
}
public static TrainingGroupDTO fromEntity(TrainingGroup group) {
if (group == null) return null;
TrainingGroupDTO dto = new TrainingGroupDTO();
dto.setId(group.getId());
dto.setName(group.getName());
dto.setLevel(group.getLevel());
dto.setSchedule(group.getSchedule());
dto.setTeacherId(group.getTeacher() != null ? group.getTeacher().getId() : null);
dto.setStudentIds(group.getStudents() != null
? group.getStudents().stream().map(Student::getId).collect(Collectors.toSet())
: null);
return dto;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLevel() {
return level;
}
public void setLevel(String level) {
this.level = level;
}
public LocalDateTime getSchedule() {
return schedule;
}
public void setSchedule(LocalDateTime schedule) {
this.schedule = schedule;
}
public Integer getTeacherId() {
return teacherId;
}
public void setTeacherId(Integer teacherId) {
this.teacherId = teacherId;
}
public Set<Integer> getStudentIds() {
return studentIds;
}
public void setStudentIds(Set<Integer> studentIds) {
this.studentIds = studentIds;
}
}

View File

@ -0,0 +1,71 @@
package com.denniseckerskorn.dtos.class_managment_dtos;
import com.denniseckerskorn.dtos.class_managment_dtos.TrainingGroupDTO;
import com.denniseckerskorn.entities.class_managment.TrainingSession;
import com.denniseckerskorn.enums.StatusValues;
import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
public class TrainingSessionDTO {
private Integer id;
@NotNull
private Integer trainingGroupId;
private LocalDateTime date;
@NotNull
private StatusValues status;
public Integer getId() {
return id;
}
public Integer getTrainingGroupId() {
return trainingGroupId;
}
public LocalDateTime getDate() {
return date;
}
public StatusValues getStatus() {
return status;
}
public void setId(Integer id) {
this.id = id;
}
public void setTrainingGroupId(Integer trainingGroupId) {
this.trainingGroupId = trainingGroupId;
}
public void setDate(LocalDateTime date) {
this.date = date;
}
public void setStatus(StatusValues status) {
this.status = status;
}
public static TrainingSessionDTO fromEntity(TrainingSession session) {
TrainingSessionDTO dto = new TrainingSessionDTO();
dto.setId(session.getId());
dto.setTrainingGroupId(session.getTrainingGroup().getId());
dto.setDate(session.getDate());
dto.setStatus(session.getStatus());
return dto;
}
public TrainingSession toEntity() {
TrainingSession session = new TrainingSession();
session.setId(this.id);
session.setDate(this.date);
session.setStatus(this.status);
return session;
}
}

View File

@ -0,0 +1,54 @@
package com.denniseckerskorn.dtos.user_managment_dtos;
import com.denniseckerskorn.entities.user_managment.users.Admin;
public class AdminDTO {
private Integer id;
private UserDTO user;
public AdminDTO() {
}
public AdminDTO(Integer id, UserDTO user) {
this.id = id;
this.user = user;
}
public Integer getId() {
return id;
}
public UserDTO getUser() {
return user;
}
public void setId(Integer id) {
this.id = id;
}
public void setUser(UserDTO user) {
this.user = user;
}
// ------------ Métodos de conversión ------------
public static AdminDTO fromEntity(Admin admin) {
if (admin == null || admin.getUser() == null) {
return null;
}
return new AdminDTO(
admin.getId(),
UserDTO.fromEntity(admin.getUser())
);
}
public Admin toEntity() {
Admin admin = new Admin();
admin.setId(this.id);
if (this.user != null) {
admin.setUser(this.user.toEntity());
}
return admin;
}
}

View File

@ -0,0 +1,84 @@
package com.denniseckerskorn.dtos.user_managment_dtos;
import com.denniseckerskorn.enums.StatusValues;
import java.time.LocalDateTime;
import java.util.Set;
public class NotificationDTO {
private Integer id;
private String title;
private String message;
private LocalDateTime shippingDate;
private String type;
private StatusValues status;
private Set<Integer> userIds;
public NotificationDTO() {}
public NotificationDTO(Integer id, String title, String message, LocalDateTime shippingDate, String type, StatusValues status, Set<Integer> userIds) {
this.id = id;
this.title = title;
this.message = message;
this.shippingDate = shippingDate;
this.type = type;
this.status = status;
this.userIds = userIds;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public LocalDateTime getShippingDate() {
return shippingDate;
}
public void setShippingDate(LocalDateTime shippingDate) {
this.shippingDate = shippingDate;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public StatusValues getStatus() {
return status;
}
public void setStatus(StatusValues status) {
this.status = status;
}
public Set<Integer> getUserIds() {
return userIds;
}
public void setUserIds(Set<Integer> userIds) {
this.userIds = userIds;
}
}

View File

@ -0,0 +1,63 @@
package com.denniseckerskorn.dtos.user_managment_dtos;
import java.time.LocalDateTime;
public class NotificationMiniDTO {
private Integer id;
private String title;
private String message;
private LocalDateTime shippingDate;
private String type;
public NotificationMiniDTO() {
}
public NotificationMiniDTO(Integer id, String title, String message, LocalDateTime shippingDate, String type) {
this.id = id;
this.title = title;
this.message = message;
this.shippingDate = shippingDate;
this.type = type;
}
// Getters y setters
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public LocalDateTime getShippingDate() {
return shippingDate;
}
public void setShippingDate(LocalDateTime shippingDate) {
this.shippingDate = shippingDate;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

View File

@ -0,0 +1,32 @@
package com.denniseckerskorn.dtos.user_managment_dtos;
import com.denniseckerskorn.enums.PermissionValues;
public class PermissionDTO {
private Integer id;
private PermissionValues permissionName;
public PermissionDTO() {
}
public PermissionDTO(Integer id, PermissionValues permissionName) {
this.id = id;
this.permissionName = permissionName;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public PermissionValues getPermissionName() {
return permissionName;
}
public void setPermissionName(PermissionValues permissionName) {
this.permissionName = permissionName;
}
}

View File

@ -0,0 +1,42 @@
package com.denniseckerskorn.dtos.user_managment_dtos;
import java.util.Set;
public class RoleDTO {
private Integer id;
private String name;
private Set<Integer> permissionIds;
public RoleDTO() {
}
public RoleDTO(Integer id, String name, Set<Integer> permissionIds) {
this.id = id;
this.name = name;
this.permissionIds = permissionIds;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Integer> getPermissionIds() {
return permissionIds;
}
public void setPermissionIds(Set<Integer> permissionIds) {
this.permissionIds = permissionIds;
}
}

View File

@ -0,0 +1,217 @@
package com.denniseckerskorn.dtos.user_managment_dtos;
import com.denniseckerskorn.dtos.class_managment_dtos.AssistanceDTO;
import com.denniseckerskorn.dtos.class_managment_dtos.MembershipDTO;
import com.denniseckerskorn.dtos.class_managment_dtos.TrainingGroupDTO;
import com.denniseckerskorn.dtos.class_managment_dtos.TrainingSessionDTO;
import com.denniseckerskorn.entities.class_managment.Assistance;
import com.denniseckerskorn.entities.class_managment.TrainingSession;
import com.denniseckerskorn.entities.user_managment.users.Student;
import java.time.LocalDate;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class StudentDTO {
private Integer id;
private UserDTO user;
private String dni;
private LocalDate birthdate;
private String belt;
private String progress;
private String medicalReport;
private String parentName;
private Integer membershipId;
private List<AssistanceDTO> assistances;
private List<TrainingGroupDTO> trainingGroups;
private List<TrainingSessionDTO> trainingSessions;
private MembershipDTO membership;
public StudentDTO() {
}
public StudentDTO(Integer id, UserDTO user, String dni, LocalDate birthdate, String belt, String progress,
String medicalReport, String parentName, Integer membershipId,
List<AssistanceDTO> assistances, List<TrainingGroupDTO> trainingGroups, List<TrainingSessionDTO> trainingSessions) {
this.id = id;
this.user = user;
this.dni = dni;
this.birthdate = birthdate;
this.belt = belt;
this.progress = progress;
this.medicalReport = medicalReport;
this.parentName = parentName;
this.membershipId = membershipId;
this.assistances = assistances;
this.trainingGroups = trainingGroups;
this.trainingSessions = trainingSessions;
}
public static StudentDTO fromEntity(Student student) {
if (student == null || student.getUser() == null) {
return null;
}
List<AssistanceDTO> assistanceDTOs = student.getAssistances().stream()
.map(AssistanceDTO::fromEntity)
.collect(Collectors.toList());
List<TrainingGroupDTO> groupDTOs = student.getTrainingGroups().stream()
.map(TrainingGroupDTO::fromEntity)
.collect(Collectors.toList());
Set<TrainingSession> allSessions = student.getAssistances().stream()
.map(Assistance::getTrainingSession)
.collect(Collectors.toSet());
List<TrainingSessionDTO> sessionDTOs = allSessions.stream()
.map(TrainingSessionDTO::fromEntity)
.collect(Collectors.toList());
return new StudentDTO(
student.getId(),
UserDTO.fromEntity(student.getUser()),
student.getDni(),
student.getBirthdate(),
student.getBelt(),
student.getProgress(),
student.getMedicalReport(),
student.getParentName(),
student.getMembership() != null ? student.getMembership().getId() : null,
assistanceDTOs,
groupDTOs,
sessionDTOs
).withMembership(student.getMembership() != null ? MembershipDTO.fromEntity(student.getMembership()) : null);
}
public StudentDTO withMembership(MembershipDTO membership) {
this.membership = membership;
return this;
}
public Student toEntity() {
Student student = new Student();
student.setId(this.id);
if (this.user != null) {
student.setUser(this.user.toEntity());
}
student.setDni(this.dni);
student.setBirthdate(this.birthdate);
student.setBelt(this.belt);
student.setProgress(this.progress);
student.setMedicalReport(this.medicalReport);
student.setParentName(this.parentName);
return student;
}
// Getters y Setters...
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public UserDTO getUser() {
return user;
}
public void setUser(UserDTO user) {
this.user = user;
}
public String getDni() {
return dni;
}
public void setDni(String dni) {
this.dni = dni;
}
public LocalDate getBirthdate() {
return birthdate;
}
public void setBirthdate(LocalDate birthdate) {
this.birthdate = birthdate;
}
public String getBelt() {
return belt;
}
public void setBelt(String belt) {
this.belt = belt;
}
public String getProgress() {
return progress;
}
public void setProgress(String progress) {
this.progress = progress;
}
public String getMedicalReport() {
return medicalReport;
}
public void setMedicalReport(String medicalReport) {
this.medicalReport = medicalReport;
}
public String getParentName() {
return parentName;
}
public void setParentName(String parentName) {
this.parentName = parentName;
}
public Integer getMembershipId() {
return membershipId;
}
public void setMembershipId(Integer membershipId) {
this.membershipId = membershipId;
}
public List<AssistanceDTO> getAssistances() {
return assistances;
}
public void setAssistances(List<AssistanceDTO> assistances) {
this.assistances = assistances;
}
public List<TrainingGroupDTO> getTrainingGroups() {
return trainingGroups;
}
public void setTrainingGroups(List<TrainingGroupDTO> trainingGroups) {
this.trainingGroups = trainingGroups;
}
public List<TrainingSessionDTO> getTrainingSessions() {
return trainingSessions;
}
public void setTrainingSessions(List<TrainingSessionDTO> trainingSessions) {
this.trainingSessions = trainingSessions;
}
public MembershipDTO getMembership() {
return membership;
}
public void setMembership(MembershipDTO membership) {
this.membership = membership;
}
}

View File

@ -0,0 +1,62 @@
package com.denniseckerskorn.dtos.user_managment_dtos;
import java.time.LocalDate;
public class StudentHistoryDTO {
private Integer id;
private Integer studentId;
private LocalDate eventDate;
private String eventType;
private String description;
public StudentHistoryDTO() {
}
public StudentHistoryDTO(Integer id, Integer studentId, LocalDate eventDate, String eventType, String description) {
this.id = id;
this.studentId = studentId;
this.eventDate = eventDate;
this.eventType = eventType;
this.description = description;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getStudentId() {
return studentId;
}
public void setStudentId(Integer studentId) {
this.studentId = studentId;
}
public LocalDate getEventDate() {
return eventDate;
}
public void setEventDate(LocalDate eventDate) {
this.eventDate = eventDate;
}
public String getEventType() {
return eventType;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@ -0,0 +1,53 @@
package com.denniseckerskorn.dtos.user_managment_dtos;
import java.time.LocalDate;
public class StudentHistoryMiniDTO {
private Integer id;
private LocalDate eventDate;
private String eventType;
private String description;
public StudentHistoryMiniDTO() {
}
public StudentHistoryMiniDTO(Integer id, LocalDate eventDate, String eventType, String description) {
this.id = id;
this.eventDate = eventDate;
this.eventType = eventType;
this.description = description;
}
// Getters y setters
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public LocalDate getEventDate() {
return eventDate;
}
public void setEventDate(LocalDate eventDate) {
this.eventDate = eventDate;
}
public String getEventType() {
return eventType;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@ -0,0 +1,26 @@
package com.denniseckerskorn.dtos.user_managment_dtos;
import java.util.Set;
public class StudentMiniDTO {
private Integer id;
private Set<StudentHistoryMiniDTO> histories; // 🔥 mini DTO
public StudentMiniDTO() {}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Set<StudentHistoryMiniDTO> getHistories() {
return histories;
}
public void setHistories(Set<StudentHistoryMiniDTO> histories) {
this.histories = histories;
}
}

View File

@ -0,0 +1,125 @@
package com.denniseckerskorn.dtos.user_managment_dtos;
import java.time.LocalDate;
import com.fasterxml.jackson.annotation.JsonFormat;
public class StudentRegisterDTO {
// Datos de usuario
private String name;
private String surname;
private String email;
private String password;
private String phoneNumber;
private String address;
private String roleName; // ejemplo: "ROLE_STUDENT"
private String status; // ejemplo: "ACTIVE"
// Datos de estudiante
private String dni;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private LocalDate birthdate;
private String belt;
private String progress;
private String medicalReport;
private String parentName;
private Integer membershipId;
// --- Getters y Setters ---
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
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 getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDni() {
return dni;
}
public void setDni(String dni) {
this.dni = dni;
}
public LocalDate getBirthdate() {
return birthdate;
}
public void setBirthdate(LocalDate birthdate) {
this.birthdate = birthdate;
}
public String getBelt() {
return belt;
}
public void setBelt(String belt) {
this.belt = belt;
}
public String getProgress() {
return progress;
}
public void setProgress(String progress) {
this.progress = progress;
}
public String getMedicalReport() {
return medicalReport;
}
public void setMedicalReport(String medicalReport) {
this.medicalReport = medicalReport;
}
public String getParentName() {
return parentName;
}
public void setParentName(String parentName) {
this.parentName = parentName;
}
public Integer getMembershipId() {
return membershipId;
}
public void setMembershipId(Integer membershipId) {
this.membershipId = membershipId;
}
}

View File

@ -0,0 +1,67 @@
package com.denniseckerskorn.dtos.user_managment_dtos;
import com.denniseckerskorn.entities.user_managment.users.Teacher;
public class TeacherDTO {
private Integer id;
private UserDTO user;
private String discipline;
public TeacherDTO() {
}
public TeacherDTO(Integer id, UserDTO user, String discipline) {
this.id = id;
this.user = user;
this.discipline = discipline;
}
// Getters y Setters
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public UserDTO getUser() {
return user;
}
public void setUser(UserDTO user) {
this.user = user;
}
public String getDiscipline() {
return discipline;
}
public void setDiscipline(String discipline) {
this.discipline = discipline;
}
public static TeacherDTO fromEntity(Teacher teacher) {
if (teacher == null || teacher.getUser() == null) {
return null;
}
return new TeacherDTO(
teacher.getId(),
UserDTO.fromEntity(teacher.getUser()),
teacher.getDiscipline()
);
}
public Teacher toEntity() {
Teacher teacher = new Teacher();
teacher.setId(this.id);
if (this.user != null) {
teacher.setUser(this.user.toEntity());
}
teacher.setDiscipline(this.discipline);
return teacher;
}
}

View File

@ -0,0 +1,173 @@
package com.denniseckerskorn.dtos.user_managment_dtos;
import com.denniseckerskorn.entities.user_managment.users.User;
import com.denniseckerskorn.enums.StatusValues;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDateTime;
import java.util.Set;
public class UserDTO {
private Integer id;
private String name;
private String surname;
private String email;
private String password;
private String phoneNumber;
private String address;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime registerDate;
private String roleName;
private StatusValues status;
// 🔥 Nuevos campos para el perfil completo
private Set<NotificationMiniDTO> notifications;
private StudentMiniDTO student;
public UserDTO() {
}
public UserDTO(Integer id, String name, String surname, String email, String password, String phoneNumber,
String address, LocalDateTime registerDate, String roleName, StatusValues status) {
this.id = id;
this.name = name;
this.surname = surname;
this.email = email;
this.password = password;
this.phoneNumber = phoneNumber;
this.address = address;
this.registerDate = registerDate;
this.roleName = roleName;
this.status = status;
}
// Getters y Setters
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
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 getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public LocalDateTime getRegisterDate() {
return registerDate;
}
public void setRegisterDate(LocalDateTime registerDate) {
this.registerDate = registerDate;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public StatusValues getStatus() {
return status;
}
public void setStatus(StatusValues status) {
this.status = status;
}
public Set<NotificationMiniDTO> getNotifications() {
return notifications;
}
public void setNotifications(Set<NotificationMiniDTO> notifications) {
this.notifications = notifications;
}
public StudentMiniDTO getStudent() {
return student;
}
public void setStudent(StudentMiniDTO student) {
this.student = student;
}
// Conversión (opcional)
public static UserDTO fromEntity(User user) {
if (user == null) return null;
return new UserDTO(
user.getId(),
user.getName(),
user.getSurname(),
user.getEmail(),
null,
user.getPhoneNumber(),
user.getAddress(),
user.getRegisterDate(),
user.getRole() != null ? user.getRole().getName() : null,
user.getStatus()
);
}
public User toEntity() {
User user = new User();
user.setId(this.id);
user.setName(this.name);
user.setSurname(this.surname);
user.setEmail(this.email);
user.setPassword(this.password);
user.setPhoneNumber(this.phoneNumber);
user.setAddress(this.address);
user.setRegisterDate(this.registerDate);
user.setStatus(this.status);
return user;
}
}

View File

@ -0,0 +1,166 @@
package com.denniseckerskorn.exceptions;
import com.denniseckerskorn.security.core.AuthenticationException;
import org.hibernate.PropertyValueException;
import org.hibernate.exception.ConstraintViolationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.TypeMismatchException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.*;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.PersistenceException;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import java.util.HashMap;
import java.util.Map;
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
// 🔹 Custom application exceptions
@ExceptionHandler(EntityNotFoundException.class)
public ResponseEntity<Object> handleEntityNotFound(EntityNotFoundException ex, WebRequest request) {
return buildErrorResponse("Entity not found: " + ex.getMessage(), HttpStatus.NOT_FOUND);
}
@ExceptionHandler(DuplicateEntityException.class)
public ResponseEntity<Object> handleDuplicateEntity(DuplicateEntityException ex, WebRequest request) {
return buildErrorResponse("Duplicate entity: " + ex.getMessage(), HttpStatus.CONFLICT);
}
@ExceptionHandler(BadRequestException.class)
public ResponseEntity<Object> handleBadRequest(BadRequestException ex, WebRequest request) {
return buildErrorResponse("Bad request: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(InvalidDataException.class)
public ResponseEntity<Object> handleInvalidData(InvalidDataException ex, WebRequest request) {
return buildErrorResponse("Invalid data: " + ex.getMessage(), HttpStatus.UNPROCESSABLE_ENTITY);
}
@ExceptionHandler(AuthenticationException.class)
public ResponseEntity<Object> handleAuthentication(AuthenticationException ex, WebRequest request) {
return buildErrorResponse("Unauthorized: " + ex.getMessage(), HttpStatus.UNAUTHORIZED);
}
// 🔹 Validation errors
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Object> handleValidationErrors(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors().forEach(err ->
errors.put(err.getField(), err.getDefaultMessage())
);
return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(MissingServletRequestParameterException.class)
public ResponseEntity<Object> handleMissingParams(MissingServletRequestParameterException ex) {
return buildErrorResponse("Missing required parameter: " + ex.getParameterName(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(MissingPathVariableException.class)
public ResponseEntity<Object> handleMissingPathVariable(MissingPathVariableException ex) {
return buildErrorResponse("Missing path variable: " + ex.getVariableName(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(MissingRequestHeaderException.class)
public ResponseEntity<Object> handleMissingHeader(MissingRequestHeaderException ex) {
return buildErrorResponse("Missing request header: " + ex.getHeaderName(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(ServletRequestBindingException.class)
public ResponseEntity<Object> handleServletBinding(ServletRequestBindingException ex) {
return buildErrorResponse("Request binding failed: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(NoResourceFoundException.class)
public ResponseEntity<Object> handleNoResourceFound(NoResourceFoundException ex, WebRequest request) {
return buildErrorResponse("Invalid resource path or missing ID in request URL.", HttpStatus.NOT_FOUND);
}
// 🔹 JPA / Hibernate exceptions
@ExceptionHandler(PropertyValueException.class)
public ResponseEntity<Object> handlePropertyValueException(PropertyValueException ex) {
return buildErrorResponse("Missing required field: " + ex.getPropertyName(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<Object> handleConstraintViolation(ConstraintViolationException ex) {
return buildErrorResponse("Database constraint violation: " + ex.getConstraintName(), HttpStatus.CONFLICT);
}
@ExceptionHandler(PersistenceException.class)
public ResponseEntity<Object> handlePersistenceException(PersistenceException ex) {
return buildErrorResponse("Persistence error: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(DataIntegrityViolationException.class)
public ResponseEntity<Object> handleDataIntegrityViolation(DataIntegrityViolationException ex) {
return buildErrorResponse("Data integrity violation: " + ex.getMostSpecificCause().getMessage(), HttpStatus.CONFLICT);
}
// 🔹 Java & Spring Core exceptions
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<Object> handleIllegalArgument(IllegalArgumentException ex) {
return buildErrorResponse("Illegal argument: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(IllegalStateException.class)
public ResponseEntity<Object> handleIllegalState(IllegalStateException ex) {
return buildErrorResponse("Illegal state: " + ex.getMessage(), HttpStatus.CONFLICT);
}
@ExceptionHandler(TypeMismatchException.class)
public ResponseEntity<Object> handleTypeMismatch(TypeMismatchException ex) {
return buildErrorResponse("Invalid parameter type: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<Object> handleInvalidJson(HttpMessageNotReadableException ex) {
return buildErrorResponse("Malformed JSON request body", HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(HttpMessageConversionException.class)
public ResponseEntity<Object> handleConversion(HttpMessageConversionException ex) {
return buildErrorResponse("Error converting request body: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
}
// 🔹 HTTP-related
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public ResponseEntity<Object> handleMethodNotSupported(HttpRequestMethodNotSupportedException ex) {
return buildErrorResponse("HTTP method not supported: " + ex.getMethod(), HttpStatus.METHOD_NOT_ALLOWED);
}
// 🔹 Fallback
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleAllUncaught(Exception ex, WebRequest request) {
logger.error("Unhandled exception", ex);
return buildErrorResponse("Internal server error", HttpStatus.INTERNAL_SERVER_ERROR);
}
private ResponseEntity<Object> buildErrorResponse(String message, HttpStatus status) {
Map<String, Object> error = new HashMap<>();
error.put("status", status.value());
error.put("error", status.getReasonPhrase());
error.put("message", message);
return new ResponseEntity<>(error, status);
}
}

View File

@ -0,0 +1,107 @@
package com.denniseckerskorn.security;
import com.denniseckerskorn.entities.user_managment.users.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
/**
* Custom implementation of UserDetails to represent user-specific data.
*/
public class CustomUserDetails implements UserDetails {
private final User user;
/**
* Constructor to initialize the CustomUserDetails with a User object.
*
* @param user the User object containing user information
*/
public CustomUserDetails(User user) {
this.user = user;
}
/**
* Returns the authorities granted to the user.
*
* @return a collection of GrantedAuthority objects representing user permissions
*/
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getRole().getPermissions().stream()
.map(p -> new SimpleGrantedAuthority(p.getPermissionName().toString()))
.collect(Collectors.toSet());
}
/**
* Returns the password of the user.
*
* @return the user's password
*/
@Override
public String getPassword() {
return user.getPassword();
}
/**
* Returns the username of the user.
*
* @return the user's email
*/
@Override
public String getUsername() {
return user.getEmail();
}
/**
* Returns the account's expiration status.
*
* @return true if the account is not expired, false otherwise
*/
@Override
public boolean isAccountNonExpired() {
return true;
}
/**
* Returns the account's lock status.
*
* @return true if the account is not locked, false otherwise
*/
@Override
public boolean isAccountNonLocked() {
return true;
}
/**
* Returns the credentials' expiration status.
*
* @return true if the credentials are not expired, false otherwise
*/
@Override
public boolean isCredentialsNonExpired() {
return true;
}
/**
* Returns the account's enabled status.
*
* @return true if the account is enabled, false otherwise
*/
@Override
public boolean isEnabled() {
return user.getStatus().name().equals("ACTIVE");
}
/**
* Returns the User object associated with this CustomUserDetails.
*
* @return the User object
*/
public User getUser() {
return user;
}
}

View File

@ -0,0 +1,41 @@
package com.denniseckerskorn.security;
import com.denniseckerskorn.entities.user_managment.users.User;
import com.denniseckerskorn.repositories.user_managment_repositories.UserRepository;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
/**
* Custom implementation of UserDetailsService to load user-specific data.
*/
@Service
public class CustomUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
/**
* Constructor to initialize the UserRepository.
*
* @param userRepository the UserRepository to be used for fetching user data
*/
public CustomUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
/**
* Loads user by username (email in this case).
*
* @param username the username (email) of the user to load
* @return UserDetails object containing user information
* @throws UsernameNotFoundException if the user is not found
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByEmail(username);
if (user == null) {
throw new UsernameNotFoundException("User not found with username: " + username);
}
return new CustomUserDetails(user);
}
}

View File

@ -0,0 +1,105 @@
package com.denniseckerskorn.security;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.JwtException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
/**
* JwtAuthFilter is a filter that checks for the presence of a JWT token in the request header.
* If a valid token is found, it sets the authentication in the security context.
*/
@Component
public class JwtAuthFilter extends OncePerRequestFilter {
private final JwtUtil jwtUtil;
private final CustomUserDetailsService customUserDetailsService;
/**
* Constructor to initialize JwtUtil and CustomUserDetailsService.
*
* @param jwtUtil the JWT utility class
* @param customUserDetailsService the custom user details service
*/
public JwtAuthFilter(JwtUtil jwtUtil, CustomUserDetailsService customUserDetailsService) {
this.jwtUtil = jwtUtil;
this.customUserDetailsService = customUserDetailsService;
}
/**
* This method is called for every request to check if the user is authenticated.
* It extracts the JWT token from the request header, validates it, and sets the authentication in the security context.
*
* @param request the HTTP request
* @param response the HTTP response
* @param filterChain the filter chain
* @throws ServletException if an error occurs during filtering
* @throws IOException if an I/O error occurs
*/
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
filterChain.doFilter(request, response);
return;
}
String token = authHeader.substring(7);
try {
String username = jwtUtil.extractUsername(token);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
var userDetails = customUserDetailsService.loadUserByUsername(username);
if (jwtUtil.validateToken(token)) {
var authToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities()
);
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
filterChain.doFilter(request, response);
} catch (ExpiredJwtException e) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
response.getWriter().write("{\"message\": \"Session expired. Please Login again\"}");
} catch (JwtException e) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
response.getWriter().write("{\"message\": \"Token is invalid or corrupt.\"}");
}
}
/**
* This method checks if the filter should not be applied to certain paths.
*
* @param request the HTTP request
* @return true if the filter should not be applied, false otherwise
* @throws ServletException if an error occurs during filtering
*/
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
String path = request.getServletPath();
return path.startsWith("/api/v1/auth")
|| path.startsWith("/v3/api-docs")
|| path.startsWith("/swagger-ui")
|| path.equals("/swagger-ui.html");
}
}

View File

@ -0,0 +1,95 @@
package com.denniseckerskorn.security;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.security.Key;
import java.util.Date;
/**
* Utility class for generating and validating JWT tokens.
*/
@Component
public class JwtUtil {
@Value("${jwt.secret}")
private String secretKey;
@Value("${jwt.expiration}")
private long expirationTime;
/**
* Generates a signing key using the secret key.
*
* @return the signing key
*/
private Key getSigningKey() {
return Keys.hmacShaKeyFor(secretKey.getBytes());
}
/**
* Generates a JWT token for the given username.
*
* @param username the username to include in the token
* @return the generated JWT token
*/
public String generateToken(String username, String authority) {
Date now = new Date();
Date expiryDate = new Date(now.getTime() + expirationTime);
return Jwts.builder()
.setSubject(username)
.claim("role", authority)
.setIssuedAt(now)
.setExpiration(expiryDate)
.signWith(getSigningKey(), SignatureAlgorithm.HS256)
.compact();
}
/**
* Extracts the username from the given JWT token.
*
* @param token the JWT token
* @return the username extracted from the token
*/
public String extractUsername(String token) {
return Jwts.parserBuilder()
.setSigningKey(getSigningKey())
.build()
.parseClaimsJws(token)
.getBody()
.getSubject();
}
/**
* Validates the given JWT token.
*
* @param token the JWT token to validate
* @return true if the token is valid, false otherwise
*/
public boolean validateToken(String token) {
try {
extractUsername(token);
return true;
} catch (JwtException e) {
return false;
}
}
/**
* Checks if the given JWT token is expired.
*
* @param token the JWT token to check
* @return true if the token is expired, false otherwise
*/
public Claims getAllClaimsFromToken(String token) throws ExpiredJwtException {
return Jwts.parserBuilder()
.setSigningKey(getSigningKey())
.build()
.parseClaimsJws(token)
.getBody();
}
}

View File

@ -0,0 +1,7 @@
package com.denniseckerskorn.security.core;
public class AuthenticationException extends RuntimeException {
public AuthenticationException(String message) {
super(message);
}
}

View File

@ -0,0 +1,7 @@
1. Comprobar seguridad y permisos en cada endpoint.
2. Comprobar o arreglar el tema de los ID automáticos y los DTOs.
3. Documentar los endpoints.
4. Crear javadoc de cada metodo.
5. Crear un README.md con la información del proyecto.
7. Comprobar como funciona logger en cada endpoint.
8. Mejorar excepciones y mensajes de error.

View File

@ -0,0 +1,24 @@
# Configuración de la base de datos
spring.datasource.url=jdbc:mysql://mysql:3306/mf_db?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Configuración de JPA/Hibernate
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.current_session_context_class=thread
jwt.secret=c2VjdXJlc2VjdXJlc2VjdXJlc2VjdXJlMTIzNDU2
jwt.expiration=7200000
#logging.level.org.springdoc=DEBUG
springdoc.api-docs.path=/v3/api-docs
springdoc.swagger-ui.url=/v3/api-docs
#logging.level.org.springframework.web=DEBUG
#logging.level.org.springframework.boot.autoconfigure=DEBUG
#spring.profiles.active=dev

38
memberflow-data/.gitignore vendored Normal file
View File

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

3
memberflow-data/.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="20" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

179
memberflow-data/README.md Normal file
View File

@ -0,0 +1,179 @@
# MemberFlow-Data
## Diagrama Entidad-Relación
A continuación, se presenta el diagrama entidad-relación que describe la estructura de la base de datos del proyecto **MemberFlow-Data**. **Nota**: El diagrama debe ser actualizado para reflejar los cambios recientes en las relaciones y el uso de composición en lugar de herencia.
![Diagrama Entidad-Relación](src/main/resources/mysql_db_init_script/DB_Diagram_MemberFlow.png)
---
## Descripción del Proyecto
**MemberFlow-Data** es el módulo de acceso a datos y servicios de la aplicación **MemberFlow**, un sistema diseñado para la gestión de membresías, usuarios, clases y finanzas en un entorno organizacional. Este proyecto actúa como la capa de persistencia y lógica de negocio, proporcionando las entidades, configuraciones y servicios necesarios para interactuar con la base de datos.
El proyecto está diseñado para trabajar en conjunto con otro módulo llamado **MemberFlow-API**, que será responsable de exponer los controladores, manejar excepciones y proporcionar la interfaz de interacción con la web y otros clientes.
Actualmente, el proyecto se encuentra en desarrollo y se prueba de manera local utilizando el módulo de `user_managment` hasta que se implemente la API y se pueda interactuar con una interfaz web.
---
## Estructura del Proyecto
El proyecto está organizado en paquetes que agrupan las entidades, configuraciones, servicios y excepciones. A continuación, se detalla la estructura principal:
### 1. **Configuraciones**
- **`HibernateConfig`**: Configuración de Hibernate para la conexión y manejo de la base de datos.
### 2. **Entidades**
Las entidades representan las tablas de la base de datos y están organizadas en diferentes dominios:
#### a) **Gestión de Clases (`class_managment`)**
- **`Assistance`**: Representa la asistencia de un estudiante a una sesión de entrenamiento.
- **`Membership`**: Define las membresías de los estudiantes, incluyendo detalles como tipo, duración y beneficios.
- **`TrainingGroup`**: Representa un grupo de entrenamiento al que pueden pertenecer varios estudiantes y que está liderado por un profesor.
- **`TrainingSession`**: Define una sesión de entrenamiento específica, asociada a un grupo y con un horario determinado.
#### b) **Gestión de Usuarios (`user_managment`)**
- **`User`**: Representa un usuario genérico del sistema. Está asociado a roles, notificaciones y facturas.
- **`Student`**: Es un usuario con atributos específicos relacionados con su rol de estudiante, como historial, membresías y grupos de entrenamiento.
- **`Teacher`**: Es un usuario con atributos específicos relacionados con su rol de profesor, como los grupos que lidera.
- **`Admin`**: Es un usuario con permisos administrativos específicos.
- **`Notification`**: Representa notificaciones enviadas a los usuarios.
- **`Role`**: Define los roles de los usuarios (e.g., ADMIN, TEACHER, STUDENT).
- **`Permission`**: Define los permisos asociados a los roles.
- **`StudentHistory`**: Registra el historial de actividades de los estudiantes.
#### c) **Gestión Financiera (`finance`)**
- **`Invoice`**: Representa una factura generada para un usuario.
- **`InvoiceLine`**: Detalla los elementos de una factura.
- **`Payment`**: Registra los pagos realizados por los usuarios.
- **`ProductService`**: Define productos o servicios ofrecidos por la organización.
- **`IVAType`**: Define los tipos de IVA aplicables.
---
## Relaciones entre Entidades
A continuación, se describen las relaciones principales entre las entidades:
### 1. **Relaciones en Gestión de Clases (`class_managment`)**
#### a) **`Membership``Student`**
- **Relación**: *Uno a Uno*.
- **Descripción**:
- Cada estudiante tiene una única membresía activa.
- Una membresía está asociada a un único estudiante.
#### b) **`TrainingGroup``TrainingSession`**
- **Relación**: *Uno a Muchos*.
- **Descripción**:
- Un grupo de entrenamiento puede tener múltiples sesiones asociadas.
- Cada sesión pertenece a un único grupo.
#### c) **`TrainingSession``Assistance`**
- **Relación**: *Uno a Muchos*.
- **Descripción**:
- Una sesión de entrenamiento puede registrar múltiples asistencias.
- Cada asistencia está asociada a un único estudiante y una única sesión.
#### d) **`TrainingGroup``Student`**
- **Relación**: *Muchos a Muchos*.
- **Descripción**:
- Un estudiante puede pertenecer a varios grupos de entrenamiento.
- Un grupo puede tener múltiples estudiantes inscritos.
---
### 2. **Relaciones en Gestión de Usuarios (`user_managment`)**
#### a) **`User``Role`**
- **Relación**: *Muchos a Uno*.
- **Descripción**:
- Cada usuario tiene un rol asignado.
- Un rol puede estar asociado a múltiples usuarios.
#### b) **`Role``Permission`**
- **Relación**: *Muchos a Muchos*.
- **Descripción**:
- Un rol puede tener múltiples permisos asociados.
- Un permiso puede estar asociado a múltiples roles.
#### c) **`Student``StudentHistory`**
- **Relación**: *Uno a Muchos*.
- **Descripción**:
- Cada estudiante tiene un historial único que registra sus actividades.
#### d) **`Notification``User`**
- **Relación**: *Muchos a Uno*.
- **Descripción**:
- Un usuario puede recibir múltiples notificaciones.
- Cada notificación está asociada a un único usuario.
#### e) **`User``Student`, `Teacher`, `Admin`**
- **Relación**: *Uno a Uno* (por composición).
- **Descripción**:
- Un usuario puede estar asociado a un estudiante, profesor o administrador.
- Estas relaciones permiten extender los atributos específicos de cada tipo de usuario sin usar herencia directa.
---
### 3. **Relaciones en Gestión Financiera (`finance`)**
#### a) **`Invoice``InvoiceLine`**
- **Relación**: *Uno a Muchos*.
- **Descripción**:
- Una factura puede contener múltiples líneas de detalle.
- Cada línea pertenece a una única factura.
#### b) **`Invoice``Payment`**
- **Relación**: *Uno a Muchos*.
- **Descripción**:
- Una factura puede estar asociada a múltiples pagos parciales.
- Cada pago pertenece a una única factura.
#### c) **`ProductService``InvoiceLine`**
- **Relación**: *Uno a Muchos*.
- **Descripción**:
- Un producto o servicio puede aparecer en múltiples líneas de factura.
- Cada línea de factura está asociada a un único producto o servicio.
#### d) **`ProductService``IVAType`**
- **Relación**: *Muchos a Uno*.
- **Descripción**:
- Un producto o servicio tiene un único tipo de IVA asociado.
- Un tipo de IVA puede aplicarse a múltiples productos o servicios.
---
## Servicios Implementados
### Servicios de Gestión de Clases
- **`MembershipService`**: Proporciona lógica para gestionar las membresías de los estudiantes, incluyendo creación, actualización y cancelación.
### Servicios de Gestión de Usuarios
- **`AdminService`**: Gestiona las operaciones relacionadas con los administradores del sistema.
- **`NotificationService`**: Maneja el envío y la gestión de notificaciones para los usuarios.
- **`PermissionService`**: Administra los permisos asociados a los roles de los usuarios.
- **`RoleService`**: Gestiona los roles de los usuarios, incluyendo asignación y modificación.
- **`StudentHistoryService`**: Proporciona lógica para registrar y consultar el historial de actividades de los estudiantes.
- **`StudentService`**: Gestiona las operaciones relacionadas con los estudiantes, como inscripción y actualización de datos.
- **`TeacherService`**: Administra las operaciones relacionadas con los profesores, incluyendo asignación de grupos.
- **`UserService`**: Proporciona lógica general para la gestión de usuarios, como autenticación y actualización de perfiles.
---
## Estado Actual del Proyecto
- **Pruebas Locales**: Actualmente, el proyecto se prueba utilizando el módulo de `user_managment` de manera local. Esto incluye la gestión de usuarios, roles, permisos y notificaciones.
- **Base de Datos**: La configuración de la base de datos está definida en el archivo `HibernateConfig`.
- **Servicios**: Los servicios implementados hasta ahora incluyen lógica básica para la gestión de usuarios y clases.
---
## Instalación y Ejecución
1. Clonar el repositorio:
```bash
git clone https://github.com/tu-usuario/memberflow-data.git
cd memberflow-data

67
memberflow-data/pom.xml Normal file
View File

@ -0,0 +1,67 @@
<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>
<groupId>com.denniseckerskorn</groupId>
<artifactId>memberflow-data</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- Spring Boot Starter Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>3.4.4</version>
</dependency>
<!-- Spring Boot Starter Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>3.4.4</version>
</dependency>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.4.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>3.4.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>3.4.4</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.19.0</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -0,0 +1,59 @@
package com.denniseckerskorn.config;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
public class HibernateConfig {
private final Environment env;
public HibernateConfig(Environment env) {
this.env = env;
}
@Bean
public DataSource dataSource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource);
emf.setPackagesToScan("com.denniseckerskorn.entities");
emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
Properties jpaProperties = new Properties();
jpaProperties.put("hibernate.dialect", env.getProperty("spring.jpa.database-platform"));
jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.hibernate.ddl-auto"));
jpaProperties.put("hibernate.show_sql", env.getProperty("spring.jpa.show-sql"));
jpaProperties.put("hibernate.current_session_context_class", env.getProperty("spring.jpa.properties.hibernate.current_session_context_class"));
emf.setJpaProperties(jpaProperties);
return emf;
}
@Bean
public PlatformTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf.getObject());
return transactionManager;
}
}

View File

@ -0,0 +1,86 @@
package com.denniseckerskorn.entities.class_managment;
import com.denniseckerskorn.entities.user_managment.users.Student;
import jakarta.persistence.*;
import java.time.LocalDateTime;
import java.util.Objects;
@Entity
@Table(name = "ASSISTANCE")
public class Assistance {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne
@JoinColumn(name = "fk_training_session", nullable = false)
private TrainingSession trainingSession;
@ManyToOne
@JoinColumn(name = "fk_student", nullable = false)
private Student student;
@Column(name = "date_time", nullable = false)
private LocalDateTime date;
public Assistance() {
}
public Integer getId() {
return id;
}
public TrainingSession getTrainingSession() {
return trainingSession;
}
public Student getStudent() {
return student;
}
public LocalDateTime getDate() {
return date;
}
public void setId(Integer id) {
this.id = id;
}
public void setTrainingSession(TrainingSession trainingSession) {
this.trainingSession = trainingSession;
}
public void setStudent(Student student) {
this.student = student;
}
public void setDate(LocalDateTime date) {
this.date = date;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Assistance that = (Assistance) o;
return Objects.equals(id, that.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "Assistance{" +
"id=" + id +
", trainingSessionId=" + (trainingSession != null ? trainingSession.getId() : "null") +
", studentId=" + (student != null ? student.getId() : "null") +
", date=" + date +
'}';
}
}

View File

@ -0,0 +1,108 @@
package com.denniseckerskorn.entities.class_managment;
import com.denniseckerskorn.entities.user_managment.users.Student;
import com.denniseckerskorn.enums.MembershipTypeValues;
import com.denniseckerskorn.enums.StatusValues;
import jakarta.persistence.*;
import java.time.LocalDate;
import java.util.Objects;
@Entity
@Table(name = "MEMBERSHIPS")
public class Membership {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Enumerated(EnumType.STRING)
@Column(name = "type", nullable = false, length = 50)
private MembershipTypeValues type;
@Column(name = "start_date", nullable = false)
private LocalDate startDate;
@Column(name = "end_date", nullable = false)
private LocalDate endDate;
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false, length = 20)
private StatusValues status;
@OneToOne(mappedBy = "membership")
private Student student;
public Integer getId() {
return id;
}
public MembershipTypeValues getType() {
return type;
}
public LocalDate getStartDate() {
return startDate;
}
public LocalDate getEndDate() {
return endDate;
}
public StatusValues getStatus() {
return status;
}
public Student getStudent() {
return student;
}
public void setId(Integer id) {
this.id = id;
}
public void setType(MembershipTypeValues type) {
this.type = type;
}
public void setStartDate(LocalDate startDate) {
this.startDate = startDate;
}
public void setEndDate(LocalDate endDate) {
this.endDate = endDate;
}
public void setStatus(StatusValues status) {
this.status = status;
}
public void setStudent(Student student) {
this.student = student;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Membership that = (Membership) o;
return Objects.equals(id, that.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "Membership{" +
"id=" + id +
", type='" + type + '\'' +
", startDate=" + startDate +
", endDate=" + endDate +
", status=" + status +
", student=" + (student != null ? student.getId() : "null") +
'}';
}
}

View File

@ -0,0 +1,122 @@
package com.denniseckerskorn.entities.class_managment;
import com.denniseckerskorn.entities.user_managment.users.Student;
import com.denniseckerskorn.entities.user_managment.users.Teacher;
import jakarta.persistence.*;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@Entity
@Table(name = "TRAINING_GROUPS")
public class TrainingGroup {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne
@JoinColumn(name = "fk_teacher", nullable = false)
private Teacher teacher;
@Column(name = "name", nullable = false, length = 45)
private String name;
@Column(name = "level", length = 45)
private String level;
@Column(name = "schedule", nullable = false)
private LocalDateTime schedule;
@OneToMany(mappedBy = "trainingGroup", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<TrainingSession> trainingSessions = new HashSet<>();
@ManyToMany(mappedBy = "trainingGroups")
private Set<Student> students = new HashSet<>();
public TrainingGroup() {
}
public Integer getId() {
return id;
}
public Teacher getTeacher() {
return teacher;
}
public String getName() {
return name;
}
public String getLevel() {
return level;
}
public LocalDateTime getSchedule() {
return schedule;
}
public Set<TrainingSession> getTrainingSessions() {
return trainingSessions;
}
public Set<Student> getStudents() {
return students;
}
public void setId(Integer id) {
this.id = id;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public void setName(String name) {
this.name = name;
}
public void setLevel(String level) {
this.level = level;
}
public void setSchedule(LocalDateTime schedule) {
this.schedule = schedule;
}
public void setTrainingSessions(Set<TrainingSession> trainingSessions) {
this.trainingSessions = trainingSessions;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TrainingGroup group = (TrainingGroup) o;
return Objects.equals(id, group.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "Group{" +
"id=" + id +
", teacherId=" + (teacher != null ? teacher.getId() : "null") +
", name='" + name + '\'' +
", level='" + (level != null ? level : "null") + '\'' +
", schedule='" + schedule + '\'' +
'}';
}
}

View File

@ -0,0 +1,102 @@
package com.denniseckerskorn.entities.class_managment;
import com.denniseckerskorn.enums.StatusValues;
import jakarta.persistence.*;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@Entity
@Table(name = "TRAINING_SESSIONS")
public class TrainingSession {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne
@JoinColumn(name = "fk_group", nullable = false)
private TrainingGroup trainingGroup;
@Column(name = "date_time")
private LocalDateTime date;
@Enumerated(EnumType.STRING)
@Column(name = "status", length = 50)
private StatusValues status;
//TODO: Control the assitances history, at the moment when group is removed, the assistances are removed too
@OneToMany(mappedBy = "trainingSession", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Assistance> assistances = new HashSet<>();
public TrainingSession() {
}
public Integer getId() {
return id;
}
public TrainingGroup getTrainingGroup() {
return trainingGroup;
}
public LocalDateTime getDate() {
return date;
}
public StatusValues getStatus() {
return status;
}
public Set<Assistance> getAssistances() {
return assistances;
}
public void setId(Integer id) {
this.id = id;
}
public void setTrainingGroup(TrainingGroup trainingGroup) {
this.trainingGroup = trainingGroup;
}
public void setDate(LocalDateTime date) {
this.date = date;
}
public void setStatus(StatusValues status) {
this.status = status;
}
public void setAssistances(Set<Assistance> assistances) {
this.assistances = assistances;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TrainingSession that = (TrainingSession) o;
return Objects.equals(id, that.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "TrainingSession{" +
"id=" + id +
", groupId=" + (trainingGroup != null ? trainingGroup.getId() : "null") +
", date=" + date +
", status=" + status +
'}';
}
}

View File

@ -0,0 +1,72 @@
package com.denniseckerskorn.entities.finance;
import jakarta.persistence.*;
import java.math.BigDecimal;
import java.util.Objects;
@Entity
@Table(name = "IVA_TYPE")
public class IVAType {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "percentage", nullable = false)
private BigDecimal percentage;
@Column(name = "description", length = 50)
private String description;
public IVAType() {
}
public Integer getId() {
return id;
}
public BigDecimal getPercentage() {
return percentage;
}
public String getDescription() {
return description;
}
public void setId(Integer id) {
this.id = id;
}
public void setPercentage(BigDecimal percentage) {
this.percentage = percentage;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
IVAType ivaType = (IVAType) o;
return Objects.equals(id, ivaType.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "IvaType{" +
"id=" + id +
", percentage=" + percentage +
", description='" + description + '\'' +
'}';
}
}

View File

@ -0,0 +1,127 @@
package com.denniseckerskorn.entities.finance;
import com.denniseckerskorn.entities.user_managment.users.User;
import com.denniseckerskorn.enums.StatusValues;
import jakarta.persistence.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@Entity
@Table(name = "INVOICES")
public class Invoice {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne
@JoinColumn(name = "fk_user", nullable = false)
private User user;
@Column(name = "date", nullable = false)
private LocalDateTime date;
@Column(name = "total", nullable = false)
private BigDecimal total;
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false)
private StatusValues status;
@OneToOne(mappedBy = "invoice", cascade = CascadeType.ALL, orphanRemoval = false)
private Payment payment;
@OneToMany(mappedBy = "invoice", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<InvoiceLine> invoiceLines = new HashSet<>();
public Invoice() {
}
public Integer getId() {
return id;
}
public User getUser() {
return user;
}
public LocalDateTime getDate() {
return date;
}
public BigDecimal getTotal() {
return total;
}
public StatusValues getStatus() {
return status;
}
public Payment getPayment() {
return payment;
}
public Set<InvoiceLine> getInvoiceLines() {
return invoiceLines;
}
public void setId(Integer id) {
this.id = id;
}
public void setUser(User user) {
this.user = user;
}
public void setDate(LocalDateTime date) {
this.date = date;
}
public void setTotal(BigDecimal total) {
this.total = total;
}
public void setStatus(StatusValues status) {
this.status = status;
}
public void setPayment(Payment payment) {
this.payment = payment;
}
public void setInvoiceLines(Set<InvoiceLine> invoiceLines) {
this.invoiceLines = invoiceLines;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Invoice invoice = (Invoice) o;
return Objects.equals(id, invoice.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "Invoice{" +
"id=" + id +
", userId=" + (user != null ? user.getId() : "null") +
", date=" + date +
", total=" + total +
", status='" + status + '\'' +
", paymentId=" + (payment != null ? payment.getId() : "null") +
", invoiceLines= [size hidden for lazy loading safety]" +
'}';
}
}

View File

@ -0,0 +1,122 @@
package com.denniseckerskorn.entities.finance;
import jakarta.persistence.*;
import java.math.BigDecimal;
import java.util.Objects;
@Entity
@Table(name = "INVOICE_LINES")
public class InvoiceLine {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne
@JoinColumn(name = "fk_invoice", nullable = false)
private Invoice invoice;
@ManyToOne
@JoinColumn(name = "fk_product_service", nullable = false)
private ProductService productService;
@Column(name = "description", columnDefinition = "TEXT")
private String description;
@Column(name = "quantity", nullable = false)
private Integer quantity;
@Column(name = "unit_price", nullable = false)
private BigDecimal unitPrice;
@Column(name = "subtotal", nullable = false)
private BigDecimal subtotal;
public InvoiceLine() {
}
public Integer getId() {
return id;
}
public Invoice getInvoice() {
return invoice;
}
public ProductService getProductService() {
return productService;
}
public String getDescription() {
return description;
}
public Integer getQuantity() {
return quantity;
}
public BigDecimal getUnitPrice() {
return unitPrice;
}
public BigDecimal getSubtotal() {
return subtotal;
}
public void setId(Integer id) {
this.id = id;
}
public void setInvoice(Invoice invoice) {
this.invoice = invoice;
}
public void setProductService(ProductService productService) {
this.productService = productService;
}
public void setDescription(String description) {
this.description = description;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public void setUnitPrice(BigDecimal unitPrice) {
this.unitPrice = unitPrice;
}
public void setSubtotal(BigDecimal subtotal) {
this.subtotal = subtotal;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InvoiceLine that = (InvoiceLine) o;
return Objects.equals(id, that.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "InvoiceLine{" +
"id=" + id +
", invoiceId=" + (invoice != null ? invoice.getId() : "null") +
", productServiceId=" + (productService != null ? productService.getId() : "null") +
", quantity=" + quantity +
", unitPrice=" + unitPrice +
", subtotal=" + subtotal +
", description='" + description + '\'' +
'}';
}
}

View File

@ -0,0 +1,114 @@
package com.denniseckerskorn.entities.finance;
import com.denniseckerskorn.enums.PaymentMethodValues;
import com.denniseckerskorn.enums.StatusValues;
import jakarta.persistence.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Objects;
@Entity
@Table(name = "PAYMENTS")
public class Payment {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToOne
@JoinColumn(name = "fk_invoice", nullable = false)
private Invoice invoice;
@Column(name = "payment_date", nullable = false)
private LocalDateTime paymentDate;
@Column(name = "amount", nullable = false)
private BigDecimal amount;
@Enumerated(EnumType.STRING)
@Column(name = "payment_method", nullable = false, length = 50)
private PaymentMethodValues paymentMethod;
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false, length = 20)
private StatusValues status;
public Payment() {
}
public Integer getId() {
return id;
}
public Invoice getInvoice() {
return invoice;
}
public LocalDateTime getPaymentDate() {
return paymentDate;
}
public BigDecimal getAmount() {
return amount;
}
public PaymentMethodValues getPaymentMethod() {
return paymentMethod;
}
public StatusValues getStatus() {
return status;
}
public void setId(Integer id) {
this.id = id;
}
public void setInvoice(Invoice invoice) {
this.invoice = invoice;
}
public void setPaymentDate(LocalDateTime paymentDate) {
this.paymentDate = paymentDate;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public void setPaymentMethod(PaymentMethodValues paymentMethod) {
this.paymentMethod = paymentMethod;
}
public void setStatus(StatusValues status) {
this.status = status;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Payment payment = (Payment) o;
return Objects.equals(id, payment.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "Payment{" +
"id=" + id +
", invoiceId=" + (invoice != null ? invoice.getId() : "null") +
", paymentDate=" + paymentDate +
", amount=" + amount +
", paymentMethod='" + paymentMethod + '\'' +
", status='" + status + '\'' +
'}';
}
}

View File

@ -0,0 +1,122 @@
package com.denniseckerskorn.entities.finance;
import com.denniseckerskorn.enums.StatusValues;
import jakarta.persistence.*;
import java.math.BigDecimal;
import java.util.Objects;
@Entity
@Table(name = "PRODUCTS_SERVICES")
public class ProductService {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne
@JoinColumn(name = "fk_iva_type", nullable = false)
private IVAType ivaType;
@Column(name = "name", nullable = false, length = 100)
private String name;
@Column(name = "description", length = 250)
private String description;
@Column(name = "price", nullable = false)
private BigDecimal price;
@Column(name = "type", nullable = false, length = 45)
private String type;
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false, length = 20)
private StatusValues status;
public ProductService() {
}
public Integer getId() {
return id;
}
public IVAType getIvaType() {
return ivaType;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public BigDecimal getPrice() {
return price;
}
public String getType() {
return type;
}
public StatusValues getStatus() {
return status;
}
public void setId(Integer id) {
this.id = id;
}
public void setIvaType(IVAType ivaType) {
this.ivaType = ivaType;
}
public void setName(String name) {
this.name = name;
}
public void setDescription(String description) {
this.description = description;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public void setType(String type) {
this.type = type;
}
public void setStatus(StatusValues status) {
this.status = status;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ProductService that = (ProductService) o;
return Objects.equals(id, that.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "ProductService{" +
"id=" + id +
", ivaTypeId=" + (ivaType != null ? ivaType.getId() : "null") +
", name='" + name + '\'' +
", price=" + price +
", type='" + type + '\'' +
", status='" + status + '\'' +
'}';
}
}

View File

@ -0,0 +1,151 @@
package com.denniseckerskorn.entities.user_managment;
import com.denniseckerskorn.entities.user_managment.users.User;
import com.denniseckerskorn.enums.StatusValues;
import jakarta.persistence.*;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@Entity
@Table(name = "NOTIFICATIONS")
public class Notification {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "title", length = 200, nullable = false)
private String title;
@Column(name = "message", columnDefinition = "TEXT")
private String message;
@Column(name = "shipping_date", nullable = false)
private LocalDateTime shippingDate;
@Column(length = 100)
private String type;
@Enumerated(EnumType.STRING)
@Column(length = 50)
private StatusValues status;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "USERS_NOTIFICATIONS",
joinColumns = @JoinColumn(name = "fk_notification"),
inverseJoinColumns = @JoinColumn(name = "fk_user"),
uniqueConstraints = @UniqueConstraint(
name = "uk_notification_user",
columnNames = {"fk_notification", "fk_user"}
)
)
private Set<User> users = new HashSet<>();
public Notification() {
}
public Integer getId() {
return id;
}
public Set<User> getUsers() {
return users;
}
public String getTitle() {
return title;
}
public String getMessage() {
return message;
}
public LocalDateTime getShippingDate() {
return shippingDate;
}
public String getType() {
return type;
}
public StatusValues getStatus() {
return status;
}
public void setId(Integer id) {
this.id = id;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public void setTitle(String title) {
this.title = title;
}
public void setMessage(String message) {
this.message = message;
}
public void setShippingDate(LocalDateTime shippingDate) {
this.shippingDate = shippingDate;
}
public void setType(String type) {
this.type = type;
}
public void setStatus(StatusValues status) {
this.status = status;
}
public void addUser(User user) {
if (this.users == null) {
this.users = new HashSet<>();
}
this.users.add(user);
if (user.getNotifications() == null) {
user.setNotifications(new HashSet<>());
}
user.getNotifications().add(this);
}
public void removeUser(User user) {
if (this.users != null) {
this.users.remove(user);
if (user.getNotifications() != null) {
user.getNotifications().remove(this);
}
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Notification that = (Notification) o;
return Objects.equals(id, that.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "Notifications{" +
"id=" + (id != null ? id : "null") +
", title='" + (title != null ? title : "null") + '\'' +
", message='" + (message != null ? message : "null") + '\'' +
", shippingDate=" + (shippingDate != null ? shippingDate : "null") +
", type='" + (type != null ? type : "null") + '\'' +
", status=" + (status != null ? status : "null") +
'}';
}
}

View File

@ -0,0 +1,83 @@
package com.denniseckerskorn.entities.user_managment;
import com.denniseckerskorn.enums.PermissionValues;
import jakarta.persistence.*;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@Entity
@Table(name = "PERMISSIONS")
public class Permission {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Enumerated(EnumType.STRING)
@Column(name = "name", nullable = false, length = 45)
private PermissionValues permissionName;
@ManyToMany(mappedBy = "permissions", fetch = FetchType.LAZY)
private Set<Role> roles = new HashSet<>();
public Permission() {
}
public Integer getId() {
return id;
}
public PermissionValues getPermissionName() {
return permissionName;
}
public Set<Role> getRoles() {
return roles;
}
public void setId(Integer id) {
this.id = id;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public void setPermissionName(PermissionValues permissionName) {
this.permissionName = permissionName;
}
public void addRole(Role role) {
this.roles.add(role);
role.getPermissions().add(this);
}
public void removeRole(Role role) {
this.roles.remove(role);
role.getPermissions().remove(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Permission that = (Permission) o;
return Objects.equals(id, that.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "Permission{" +
"id=" + id +
", privilegeName=" + permissionName +
'}';
}
}

View File

@ -0,0 +1,100 @@
package com.denniseckerskorn.entities.user_managment;
import jakarta.persistence.*;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@Entity
@Table(name = "ROLES")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(name = "name", nullable = false, length = 45)
private String name;
@ManyToMany(fetch = FetchType.LAZY)
@Fetch(FetchMode.JOIN)
@JoinTable(
name = "ROLES_PERMISSIONS",
joinColumns = @JoinColumn(name = "fk_role"),
inverseJoinColumns = @JoinColumn(name = "fk_permission"),
uniqueConstraints = @UniqueConstraint(
name = "uk_role_permission",
columnNames = {"fk_role", "fk_permission"}
)
)
private Set<Permission> permissions = new HashSet<>();
public Role() {
}
public Role(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public Set<Permission> getPermissions() {
return permissions;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setPermissions(Set<Permission> permissions) {
this.permissions = permissions;
}
public void addPermission(Permission permission) {
if (this.permissions == null) {
this.permissions = new HashSet<>();
}
this.permissions.add(permission);
}
public void removePermission(Permission permission) {
if (this.permissions != null) {
this.permissions.remove(permission);
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Role role = (Role) o;
return Objects.equals(id, role.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "Role{" +
"id=" + id +
", name='" + (name != null ? name : "null") + '\'' +
'}';
}
}

View File

@ -0,0 +1,98 @@
package com.denniseckerskorn.entities.user_managment;
import com.denniseckerskorn.entities.user_managment.users.Student;
import jakarta.persistence.*;
import java.time.LocalDate;
import java.util.Objects;
@Entity
@Table(name = "STUDENT_HISTORY")
public class StudentHistory {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne
@JoinColumn(name = "fk_student", nullable = false)
private Student student;
@Column(name = "event_date")
private LocalDate eventDate;
@Column(name = "event_type")
private String eventType;
@Column(name = "description")
private String description;
public StudentHistory() {
}
public Integer getId() {
return id;
}
public Student getStudent() {
return student;
}
public LocalDate getEventDate() {
return eventDate;
}
public String getEventType() {
return eventType;
}
public String getDescription() {
return description;
}
public void setId(Integer id) {
this.id = id;
}
public void setStudent(Student student) {
this.student = student;
}
public void setEventDate(LocalDate eventDate) {
this.eventDate = eventDate;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StudentHistory that = (StudentHistory) o;
return Objects.equals(id, that.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "StudentHistory{" +
"id=" + (id != null ? id : "null") +
", student=" + (student != null ? "Student{id=" + student.getId() + "}" : "null") +
", eventDate=" + (eventDate != null ? eventDate : "null") +
", eventType='" + (eventType != null ? eventType : "null") + '\'' +
", description='" + (description != null ? description : "null") + '\'' +
'}';
}
}

View File

@ -0,0 +1,59 @@
package com.denniseckerskorn.entities.user_managment.users;
import jakarta.persistence.*;
import java.util.Objects;
@Entity
@Table(name = "ADMINS")
public class Admin {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToOne
@JoinColumn(name = "fk_user", nullable = false, unique = true)
private User user;
public Admin() {
}
public Integer getId() {
return id;
}
public User getUser() {
return user;
}
public void setId(Integer id) {
this.id = id;
}
public void setUser(User user) {
this.user = user;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Admin admin = (Admin) o;
return Objects.equals(id, admin.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "Admin{" +
"id=" + id +
", userId=" + (user != null ? user.getId() : "null") +
", userEmail=" + (user != null ? user.getEmail() : "null") +
'}';
}
}

View File

@ -0,0 +1,185 @@
package com.denniseckerskorn.entities.user_managment.users;
import com.denniseckerskorn.entities.class_managment.Assistance;
import com.denniseckerskorn.entities.class_managment.TrainingGroup;
import com.denniseckerskorn.entities.class_managment.Membership;
import com.denniseckerskorn.entities.user_managment.StudentHistory;
import jakarta.persistence.*;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@Entity
@Table(name = "STUDENTS")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToOne
@JoinColumn(name = "fk_user", nullable = false, unique = true)
private User user;
@Column(name = "dni", nullable = false, length = 10, unique = true)
private String dni;
@Column(name = "birthdate", nullable = false)
private LocalDate birthdate;
@Column(name = "belt", length = 20)
private String belt;
@Column(name = "progress", columnDefinition = "TEXT")
private String progress;
@Column(name = "medical_report", length = 500)
private String medicalReport;
@Column(name = "parent_name", length = 50)
private String parentName;
@OneToMany(mappedBy = "student", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<StudentHistory> histories = new HashSet<>();
@OneToOne
@JoinColumn(name = "fk_membership")
private Membership membership;
@OneToMany(mappedBy = "student", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Assistance> assistances = new HashSet<>();
@ManyToMany
@JoinTable(name = "STUDENTS_GROUPS", joinColumns = @JoinColumn(name = "fk_student"), inverseJoinColumns = @JoinColumn(name = "fk_group"))
private Set<TrainingGroup> trainingGroups = new HashSet<>();
public Student() {
}
public Integer getId() {
return id;
}
public User getUser() {
return user;
}
public String getDni() {
return dni;
}
public LocalDate getBirthdate() {
return birthdate;
}
public Set<StudentHistory> getHistories() {
return histories;
}
public Membership getMembership() {
return membership;
}
public String getMedicalReport() {
return medicalReport;
}
public String getParentName() {
return parentName;
}
public String getBelt() {
return belt;
}
public String getProgress() {
return progress;
}
public Set<Assistance> getAssistances() {
return assistances;
}
public Set<TrainingGroup> getTrainingGroups() {
return trainingGroups;
}
public void setId(Integer id) {
this.id = id;
}
public void setUser(User user) {
this.user = user;
}
public void setMedicalReport(String medicalReport) {
this.medicalReport = medicalReport;
}
public void setParentName(String parentName) {
this.parentName = parentName;
}
public void setDni(String dni) {
this.dni = dni;
}
public void setBirthdate(LocalDate birthdate) {
this.birthdate = birthdate;
}
public void setBelt(String belt) {
this.belt = belt;
}
public void setProgress(String progress) {
this.progress = progress;
}
public void setHistories(Set<StudentHistory> histories) {
this.histories = histories;
}
public void setMembership(Membership membership) {
this.membership = membership;
}
public void setAssistances(Set<Assistance> assistances) {
this.assistances = assistances;
}
public void setTrainingGroups(Set<TrainingGroup> trainingGroups) {
this.trainingGroups = trainingGroups;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(id, student.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "Student{" +
"dni='" + (dni != null ? dni : "null") + '\'' +
", birthdate=" + (birthdate != null ? birthdate : "null") +
", belt='" + (belt != null ? belt : "null") + '\'' +
", progress='" + (progress != null ? progress : "null") + '\'' +
", medicalReport='" + (medicalReport != null ? medicalReport : "null") + '\'' +
", parentName='" + (parentName != null ? parentName : "null") + '\'' +
", membershipId=" + (membership != null ? membership.getId() : "null") +
//", trainingGroups=" + (trainingGroups != null ? trainingGroups.size() : "null") +
//", assistances=" + (assistances != null ? assistances.size() : "null") +
//", histories=" + (histories != null ? histories.size() : "null") +
'}';
}
}

View File

@ -0,0 +1,84 @@
package com.denniseckerskorn.entities.user_managment.users;
import com.denniseckerskorn.entities.class_managment.TrainingGroup;
import jakarta.persistence.*;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@Entity
@Table(name = "TEACHERS")
public class Teacher {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToOne
@JoinColumn(name = "fk_user", nullable = false, unique = true)
private User user;
@Column(name = "discipline", length = 50)
private String discipline;
@OneToMany(mappedBy = "teacher", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<TrainingGroup> trainingGroups = new HashSet<>();
public Teacher() {
}
public Integer getId() {
return id;
}
public User getUser() {
return user;
}
public String getDiscipline() {
return discipline;
}
public void setId(Integer id) {
this.id = id;
}
public void setUser(User user) {
this.user = user;
}
public Set<TrainingGroup> getTrainingGroups() {
return trainingGroups;
}
public void setDiscipline(String discipline) {
this.discipline = discipline;
}
public void setTrainingGroups(Set<TrainingGroup> trainingGroups) {
this.trainingGroups = trainingGroups;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Teacher teacher = (Teacher) o;
return Objects.equals(id, teacher.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "Teacher{" +
"discipline='" + (discipline != null ? discipline : "null") + '\'' +
", super=" + super.toString() +
'}';
}
}

View File

@ -0,0 +1,235 @@
package com.denniseckerskorn.entities.user_managment.users;
import com.denniseckerskorn.entities.finance.Invoice;
import com.denniseckerskorn.entities.user_managment.Notification;
import com.denniseckerskorn.entities.user_managment.Role;
import com.denniseckerskorn.enums.StatusValues;
import jakarta.persistence.*;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@Entity
@Table(name = "USERS")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
@JsonIgnore
private Student student;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
@JsonIgnore
private Teacher teacher;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
@JsonIgnore
private Admin admin;
@Column(name = "name", nullable = false, length = 50)
private String name;
@Column(name = "surname", nullable = false, length = 50)
private String surname;
@Column(name = "phone_number", nullable = false, length = 30)
private String phoneNumber;
@Column(name = "email", nullable = false, unique = true, length = 100)
private String email;
@Column(name = "password", nullable = false, length = 255)
private String password;
@Enumerated(EnumType.STRING)
@Column(name = "status", nullable = false, length = 20)
private StatusValues status;
@Column(name = "register_date", nullable = false)
private LocalDateTime registerDate;
@Column(name = "address", nullable = false, length = 100)
private String address;
@ManyToOne
@JoinColumn(name = "fk_role", nullable = false)
private Role role;
@ManyToMany(mappedBy = "users", fetch = FetchType.LAZY)
private Set<Notification> notifications = new HashSet<>();
@OneToMany(mappedBy = "user", cascade = CascadeType.PERSIST)
private Set<Invoice> invoices = new HashSet<>();
public User() {
}
public Integer getId() {
return id;
}
public Student getStudent() {
return student;
}
public Teacher getTeacher() {
return teacher;
}
public Admin getAdmin() {
return admin;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public StatusValues getStatus() {
return status;
}
public String getPhoneNumber() {
return phoneNumber;
}
public String getAddress() {
return address;
}
public LocalDateTime getRegisterDate() {
return registerDate;
}
public Role getRole() {
return role;
}
public Set<Notification> getNotifications() {
return notifications;
}
public Set<Invoice> getInvoices() {
return invoices;
}
public void setId(Integer id) {
this.id = id;
}
public void setStudent(Student student) {
this.student = student;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public void setAdmin(Admin admin) {
this.admin = admin;
}
public void setName(String name) {
this.name = name;
}
public void setSurname(String surname) {
this.surname = surname;
}
public void setEmail(String email) {
this.email = email;
}
public void setPassword(String password) {
this.password = password;
}
public void setStatus(StatusValues status) {
this.status = status;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public void setAddress(String address) {
this.address = address;
}
public void setRegisterDate(LocalDateTime registerDate) {
this.registerDate = registerDate;
}
public void setRole(Role role) {
this.role = role;
}
public void setNotifications(Set<Notification> notifications) {
this.notifications = notifications;
}
public void setInvoices(Set<Invoice> invoices) {
this.invoices = invoices;
}
public void addNotification(Notification notification) {
this.notifications.add(notification);
notification.getUsers().add(this);
}
public void removeNotification(Notification notification) {
this.notifications.remove(notification);
notification.getUsers().remove(this);
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(id, user.id);
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + (name != null ? name : "null") + '\'' +
", surname='" + (surname != null ? surname : "null") + '\'' +
", phoneNumber='" + (phoneNumber != null ? phoneNumber : "null") + '\'' +
", email='" + (email != null ? email : "null") + '\'' +
", password='******'" +
", status='" + (status != null ? status : "null") + '\'' +
", registerDate=" + (registerDate != null ? registerDate : "null") +
", address='" + (address != null ? address : "null") + '\'' +
", role=" + (role != null ? role.getName() : "null") +
", studentId=" + (student != null ? student.getId() : "null") +
", teacherId=" + (teacher != null ? teacher.getId() : "null") +
", adminId=" + (admin != null ? admin.getId() : "null") +
'}';
}
}

View File

@ -0,0 +1,9 @@
package com.denniseckerskorn.enums;
public enum MembershipTypeValues {
BASIC,
ADVANCED,
PREMIUM,
NO_LIMIT,
TRIAL,
}

View File

@ -0,0 +1,7 @@
package com.denniseckerskorn.enums;
public enum PaymentMethodValues {
CASH,
CREDIT_CARD,
BANK_TRANSFER
}

View File

@ -0,0 +1,7 @@
package com.denniseckerskorn.enums;
public enum PermissionValues {
FULL_ACCESS,
MANAGE_STUDENTS,
VIEW_OWN_DATA
}

View File

@ -0,0 +1,13 @@
package com.denniseckerskorn.enums;
public enum StatusValues {
ACTIVE,
INACTIVE,
SUSPENDED,
DELETED,
PAID,
NOT_PAID,
SENT,
NOT_SENT,
PENDING
}

View File

@ -0,0 +1,7 @@
package com.denniseckerskorn.exceptions;
public class BadRequestException extends RuntimeException {
public BadRequestException(String message) {
super(message);
}
}

View File

@ -0,0 +1,19 @@
package com.denniseckerskorn.exceptions;
public class DuplicateEntityException extends RuntimeException {
public DuplicateEntityException(String message) {
super(message);
}
public DuplicateEntityException(String message, Throwable cause) {
super(message, cause);
}
public DuplicateEntityException(Throwable cause) {
super(cause);
}
public DuplicateEntityException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -0,0 +1,20 @@
package com.denniseckerskorn.exceptions;
public class EntityNotFoundException extends RuntimeException {
public EntityNotFoundException(String message) {
super(message);
}
public EntityNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public EntityNotFoundException(Throwable cause) {
super(cause);
}
public EntityNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -0,0 +1,19 @@
package com.denniseckerskorn.exceptions;
public class InvalidDataException extends RuntimeException {
public InvalidDataException(String message) {
super(message);
}
public InvalidDataException(String message, Throwable cause) {
super(message, cause);
}
public InvalidDataException(Throwable cause) {
super(cause);
}
public InvalidDataException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -0,0 +1,20 @@
package com.denniseckerskorn.repositories.class_managment_repositories;
import com.denniseckerskorn.entities.class_managment.Assistance;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.time.LocalDateTime;
import java.util.List;
public interface AssistanceRepository extends JpaRepository<Assistance, Integer> {
Assistance findByTrainingSessionId(Integer trainingSessionId);
Assistance findByStudentId(Integer studentId);
@Query("SELECT a FROM Assistance a WHERE a.date BETWEEN :start AND :end")
List<Assistance> findAllByDateRange(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end);
Assistance findByTrainingSessionIdAndStudentId(Integer trainingSessionId, Integer studentId);
}

View File

@ -0,0 +1,21 @@
package com.denniseckerskorn.repositories.class_managment_repositories;
import com.denniseckerskorn.entities.class_managment.Membership;
import com.denniseckerskorn.enums.MembershipTypeValues;
import org.springframework.data.jpa.repository.JpaRepository;
import java.time.LocalDate;
public interface MembershipRepository extends JpaRepository<Membership, Integer> {
Membership findByType(MembershipTypeValues type);
Membership findByStartDate(LocalDate startDate);
Membership findByEndDate(LocalDate endDate);
Membership findByStatus(String status);
Membership findByStudentId(Integer studentId);
boolean existsByType(MembershipTypeValues type);
}

View File

@ -0,0 +1,7 @@
package com.denniseckerskorn.repositories.class_managment_repositories;
import com.denniseckerskorn.entities.class_managment.TrainingGroup;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TrainingGroupRepository extends JpaRepository<TrainingGroup, Integer> {
}

View File

@ -0,0 +1,16 @@
package com.denniseckerskorn.repositories.class_managment_repositories;
import com.denniseckerskorn.entities.class_managment.TrainingSession;
import org.springframework.data.jpa.repository.JpaRepository;
import java.time.LocalDateTime;
import java.util.List;
public interface TrainingSessionRepository extends JpaRepository<TrainingSession, Integer> {
TrainingSession findByDate(LocalDateTime date);
List<TrainingSession> findAllByDateBetween(LocalDateTime start, LocalDateTime end);
}

View File

@ -0,0 +1,11 @@
package com.denniseckerskorn.repositories.finance_repositories;
import com.denniseckerskorn.entities.finance.IVAType;
import org.springframework.data.jpa.repository.JpaRepository;
import java.math.BigDecimal;
public interface IVATypeRepository extends JpaRepository<IVAType, Integer> {
boolean existsByPercentage(BigDecimal percentage);
}

View File

@ -0,0 +1,7 @@
package com.denniseckerskorn.repositories.finance_repositories;
import com.denniseckerskorn.entities.finance.InvoiceLine;
import org.springframework.data.jpa.repository.JpaRepository;
public interface InvoiceLineRepository extends JpaRepository<InvoiceLine, Integer> {
}

View File

@ -0,0 +1,7 @@
package com.denniseckerskorn.repositories.finance_repositories;
import com.denniseckerskorn.entities.finance.Invoice;
import org.springframework.data.jpa.repository.JpaRepository;
public interface InvoiceRepository extends JpaRepository<Invoice, Integer> {
}

View File

@ -0,0 +1,8 @@
package com.denniseckerskorn.repositories.finance_repositories;
import com.denniseckerskorn.entities.finance.Payment;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PaymentRepository extends JpaRepository<Payment, Integer> {
boolean existsByInvoiceId(Integer invoiceId);
}

View File

@ -0,0 +1,10 @@
package com.denniseckerskorn.repositories.finance_repositories;
import com.denniseckerskorn.entities.finance.ProductService;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ProductServiceRepository extends JpaRepository<ProductService, Integer> {
boolean existsByName(String name);
boolean existsByIvaTypeId(Integer ivaTypeId);
}

View File

@ -0,0 +1,11 @@
package com.denniseckerskorn.repositories.user_managment_repositories;
import com.denniseckerskorn.entities.user_managment.users.Admin;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AdminRepository extends JpaRepository<Admin, Integer> {
boolean existsByUserEmail(String email);
Admin findByUserEmail(String email);
}

View File

@ -0,0 +1,12 @@
package com.denniseckerskorn.repositories.user_managment_repositories;
import com.denniseckerskorn.entities.user_managment.Notification;
import org.springframework.data.jpa.repository.JpaRepository;
import java.time.LocalDateTime;
import java.util.List;
public interface NotificationRepository extends JpaRepository<Notification, Integer> {
boolean existsByTitleAndShippingDate(String title, LocalDateTime shippingDate);
List<Notification> findNotificationsById(Integer id);
}

Some files were not shown because too many files have changed in this diff Show More