Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
1fa10c2
Add GEMINI_API_KEY to CI workflow
AilinVara Nov 22, 2025
6cfddf8
feat: relacion de usuarios con suscripcion
rioslucas1 Nov 21, 2025
166a90a
fix: los usuarios pueden pagar con cuenta de prueba y se guarda su em…
rioslucas1 Nov 21, 2025
32de3ea
ft/register-brand hecho
JulianKer Nov 21, 2025
2da22a7
ft/registrar-marca hecho & sube imagen al bucket
JulianKer Nov 21, 2025
e49b233
fix: arreglo docker compose e inyecto varialbes para probar con docker
rioslucas1 Nov 21, 2025
853d4f0
dejo documentacion para rutas de suscripcion
rioslucas1 Nov 21, 2025
6aeaa1c
Refactor de tests de brand
AilinVara Nov 22, 2025
c804bdf
Merge remote-tracking branch 'origin/ft/sugerencias-ia' into ft/suger…
AilinVara Nov 22, 2025
b8ba975
Refactor de tests de brand
AilinVara Nov 22, 2025
4502a3d
Merge remote-tracking branch 'origin/ft/sugerencias-ia' into ft/suger…
AilinVara Nov 22, 2025
4caf93b
Refactor de tests de brand
AilinVara Nov 22, 2025
a7fc303
Merge remote-tracking branch 'origin/ft/sugerencias-ia' into ft/suger…
AilinVara Nov 22, 2025
7a7dddc
feat: relacion de usuarios con suscripcion
rioslucas1 Nov 21, 2025
f4f3a52
Merge remote-tracking branch 'origin/ft/sugerencias-ia' into ft/suger…
AilinVara Nov 23, 2025
5f9e95e
fix error de merge
AilinVara Nov 23, 2025
df7726d
refactor de test de fash
AilinVara Nov 23, 2025
b581c88
ft/notificaciones hecho.
GermanSchmuker Nov 23, 2025
7d90f92
merge notifications
GermanSchmuker Nov 23, 2025
7f08ddd
WIP: Guardando cambios pendientes antes de la transferencia a ft/suge…
AilinVara Nov 23, 2025
f096a8b
Merge branch 'develop' into ft/sugerencias-ia
AilinVara Nov 23, 2025
c8bec4f
Agrego get de avatar custom para combinaciones
camilamarendazzo Nov 23, 2025
7512396
fix notifications
GermanSchmuker Nov 23, 2025
2c3e14d
refactor - favoritas order by createdAt desc
GermanSchmuker Nov 23, 2025
6337d52
fix merge
GermanSchmuker Nov 23, 2025
f69f9a1
Agrego use case de refresh token
camilamarendazzo Nov 23, 2025
f0df493
Fix token duplicado
camilamarendazzo Nov 24, 2025
4fd86a2
Merge branch 'refresh-token' into develop
camilamarendazzo Nov 24, 2025
fd49c6d
refactor de TODO el editar prenda. Obtengo recomendatiosn (clima, oca…
JulianKer Nov 24, 2025
0556540
pull refresh token de cami.
JulianKer Nov 24, 2025
9ebbad7
fix test
JulianKer Nov 24, 2025
c2d88e8
refactor CREAR prenda hecho, ya anda.
JulianKer Nov 24, 2025
3ef26c3
fix brand en session del front + fix eliminar prenda (no traía garmen…
JulianKer Nov 24, 2025
7b89d9f
fix error de nuevo costructor para user entity
JulianKer Nov 24, 2025
421ba0c
feat:traer informacion desde el mail vinculado a jwt
rioslucas1 Nov 24, 2025
e14fd11
Se sumo la logica de jwt para mantener unicamente lo relacionado al u…
rioslucas1 Nov 24, 2025
d4ae1c2
fix: arreglo bug de la ruta para devolver planes en el front
rioslucas1 Nov 24, 2025
b8cbcba
fix planes free-monthly user y brand
JulianKer Nov 24, 2025
376010f
Merge develop into feat/planes-rol-usuario
rioslucas1 Nov 24, 2025
cb486e6
fix: agregados mocks faltantes en CombinePrendasTest
rioslucas1 Nov 24, 2025
0104a9e
Merge pull request #37 from Outfit-Lab-TPI/feat/planes-rol-usuario
rioslucas1 Nov 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.outfitlab.project.domain.exceptions;

public class ClimaNotFoundException extends RuntimeException {
public ClimaNotFoundException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.outfitlab.project.domain.exceptions;

public class ColorNotFoundException extends RuntimeException {
public ColorNotFoundException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.outfitlab.project.domain.exceptions;

public class OcasionNotFoundException extends RuntimeException {
public OcasionNotFoundException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.outfitlab.project.domain.interfaces.repositories;

import com.outfitlab.project.domain.model.ClimaModel;

import java.util.List;

public interface ClimaRepository {
List<ClimaModel> findAllClimas();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.outfitlab.project.domain.interfaces.repositories;

import com.outfitlab.project.domain.model.ColorModel;

import java.util.List;

public interface ColorRepository {
List<ColorModel> findAllColores();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

import com.outfitlab.project.domain.exceptions.FashnApiException;
import com.outfitlab.project.domain.exceptions.PredictionFailedException;
import org.springframework.security.core.userdetails.UserDetails;

public interface FashnRepository {

String combine(String garmentUrl, String category, String avatarType) throws FashnApiException;
String combine(String garmentUrl, String category, String avatarType, UserDetails user) throws FashnApiException;

String combineSecondGarment(String garmentUrl, String category, String avatarCombinedUrl) throws FashnApiException;

String pollStatus(String id) throws FashnApiException, PredictionFailedException;

String combineTopAndBottom(String top, String bottom, String avatarType) throws PredictionFailedException, FashnApiException;
String combineTopAndBottom(String top, String bottom, String avatarType, UserDetails user) throws PredictionFailedException, FashnApiException;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.outfitlab.project.domain.interfaces.repositories;

import com.outfitlab.project.domain.exceptions.GarmentNotFoundException;
import com.outfitlab.project.domain.model.ColorModel;
import com.outfitlab.project.domain.model.PrendaModel;
import com.outfitlab.project.domain.model.dto.PageDTO;
import com.outfitlab.project.domain.model.ClimaModel;
Expand All @@ -18,6 +19,7 @@ public interface GarmentRepository {

void createGarment(
String name,
String garmentCode,
String type,
String color,
String brandCode,
Expand All @@ -38,4 +40,5 @@ void createGarment(

List<OcasionModel> findAllOcasiones();

List<ColorModel> findAllColores();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.outfitlab.project.domain.interfaces.repositories;

import com.outfitlab.project.domain.model.OcasionModel;

import java.util.List;

public interface OcacionRepository {
List<OcasionModel> findAllOcasiones();
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
public interface SubscriptionRepository {

List<SubscriptionModel> getAllSubscriptions();

SubscriptionModel getByPlanCode(String planCode);

List<SubscriptionModel> findByPlanType(String planType);
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@ public interface UserRepository {
Page<UserWithBrandsDTO> getAllBrandsWithUserRelated(int page);

List<UserModel> findAllWithRoleUserAndAdmin();

List<UserWithBrandsDTO> getNotApprovedBrands();
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public class SubscriptionModel {

private boolean isPopular;

private String planType;
private Integer maxGarments;
private boolean hasAnalytics;
private boolean hasAdvancedReports;

public String getName() {
return name;
}
Expand Down Expand Up @@ -109,7 +114,36 @@ public boolean isPopular() {
public void setPopular(boolean popular) {
isPopular = popular;
}
}

public String getPlanType() {
return planType;
}

public void setPlanType(String planType) {
this.planType = planType;
}

public Integer getMaxGarments() {
return maxGarments;
}

public void setMaxGarments(Integer maxGarments) {
this.maxGarments = maxGarments;
}

public boolean isHasAnalytics() {
return hasAnalytics;
}

public void setHasAnalytics(boolean hasAnalytics) {
this.hasAnalytics = hasAnalytics;
}

public boolean isHasAdvancedReports() {
return hasAdvancedReports;
}

public void setHasAdvancedReports(boolean hasAdvancedReports) {
this.hasAdvancedReports = hasAdvancedReports;
}
}
20 changes: 20 additions & 0 deletions src/main/java/com/outfitlab/project/domain/model/UserModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,26 @@ public UserModel(String name, String lastName, String email, Role role, boolean
this.brand = brand;
}

public UserModel(String name, String lastName, String email, String satulation, String secondName, Integer years, String password,
LocalDateTime createdAt, LocalDateTime updatedAt, Role role, boolean verified, boolean status,
String verificationToken, String userImageUrl, BrandModel brandModel) {
this.name = name;
this.lastName = lastName;
this.email = email;
this.satulation = satulation;
this.secondName = secondName;
this.years = years;
this.hashedPassword = password;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
this.role = role;
this.verified = verified;
this.status = status;
this.verificationToken = verificationToken;
this.userImg = userImageUrl;
this.brand = brandModel;
}

/*
* public String getPassword() {
* return "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,28 @@ public class UserSubscriptionModel {
private Long id;
private String userEmail;
private String planCode;

// Contadores de uso
private int combinationsUsed; // Total creadas en el período
private int favoritesCount; // Favoritos actuales en BD
private int modelsGenerated; // Total generados en el período

private int combinationsUsed; // Total creadas en el período
private int favoritesCount; // Favoritos actuales en BD
private int modelsGenerated; // Total generados en el período
private int downloadsCount; // Total descargas 2D
private int garmentsUploaded; // Total prendas subidas (marcas)

// Límites del plan (denormalizados para performance)
private Integer maxCombinations; // null = ilimitado
private Integer maxFavorites; // null = ilimitado
private Integer maxModels; // null = ilimitado

private Integer maxCombinations; // null = ilimitado
private Integer maxFavorites; // null = ilimitado
private Integer maxModels; // null = ilimitado
private Integer maxDownloads; // null = ilimitado
private Integer maxGarments; // null = ilimitado (para marcas)

// Metadata
private LocalDateTime subscriptionStart;
private LocalDateTime subscriptionEnd;
private String status; // ACTIVE, CANCELLED, EXPIRED
private String status; // ACTIVE, CANCELLED, EXPIRED
private LocalDateTime createdAt;
private LocalDateTime updatedAt;

public UserSubscriptionModel() {}
public UserSubscriptionModel() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ public class GarmentDTO {
private String marcaNombre;
private String evento;
private String color;
private String clima;

public GarmentDTO(String nombre, String tipo, String imagenUrl, String garmentCode, String marcaNombre, String color) {
public GarmentDTO(String nombre, String tipo, String imagenUrl, String garmentCode, String marcaNombre, String color, String clima) {
this.nombre = nombre;
this.tipo = tipo;
this.imagenUrl = imagenUrl;
this.garmentCode = garmentCode;
this.marcaNombre = marcaNombre;
this.color = color;
this.clima = clima;
}

public String getGarmentCode() {
Expand Down Expand Up @@ -72,6 +74,13 @@ public String getColor() {
public void setColor(String color) {
this.color = color;
}
public String getClima() {
return clima;
}

public void setClima(String clima) {
this.clima = clima;
}

public static GarmentDTO convertModelToDTO(PrendaModel prendaModel) {
return new GarmentDTO(
Expand All @@ -80,7 +89,8 @@ public static GarmentDTO convertModelToDTO(PrendaModel prendaModel) {
prendaModel.getImagenUrl(),
prendaModel.getGarmentCode(),
prendaModel.getMarca().getNombre(),
prendaModel.getColor().getNombre()
prendaModel.getColor().getNombre(),
prendaModel.getClimaAdecuado().getNombre()
);
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,43 @@
package com.outfitlab.project.domain.model.dto;

import com.outfitlab.project.domain.model.ClimaModel;
import com.outfitlab.project.domain.model.ColorModel;
import com.outfitlab.project.domain.model.OcasionModel;
import java.util.List;

public class RecommendationCategoriesDTO {

private List<ClimaModel> climas;
private List<OcasionModel> ocasiones;
private List<ColorModel> colores;

public RecommendationCategoriesDTO(List<ClimaModel> climas, List<OcasionModel> ocasiones) {
public RecommendationCategoriesDTO(List<ClimaModel> climas, List<OcasionModel> ocasiones, List<ColorModel> colores) {
this.climas = climas;
this.ocasiones = ocasiones;
this.colores = colores;
}

public List<ClimaModel> getClimas() { return climas; }
public void setClimas(List<ClimaModel> climas) { this.climas = climas; }
public List<OcasionModel> getOcasiones() { return ocasiones; }
public void setOcasiones(List<OcasionModel> ocasiones) { this.ocasiones = ocasiones; }
public List<ClimaModel> getClimas() {
return climas;
}

public void setClimas(List<ClimaModel> climas) {
this.climas = climas;
}

public List<OcasionModel> getOcasiones() {
return ocasiones;
}

public void setOcasiones(List<OcasionModel> ocasiones) {
this.ocasiones = ocasiones;
}

public List<ColorModel> getColores() {
return colores;
}

public void setColores(List<ColorModel> colores) {
this.colores = colores;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.outfitlab.project.domain.useCases.brand;

import com.outfitlab.project.domain.interfaces.repositories.UserRepository;
import com.outfitlab.project.domain.model.dto.UserWithBrandsDTO;

import java.util.List;

public class GetNotificationsNewBrands {

private final UserRepository userRepository;

public GetNotificationsNewBrands(UserRepository userRepository) {
this.userRepository = userRepository;
}

public List<UserWithBrandsDTO> execute(){
return this.userRepository.getNotApprovedBrands();
}
}
Loading