Skip to content

Commit e14fd11

Browse files
committed
Se sumo la logica de jwt para mantener unicamente lo relacionado al usuario, validacion de limite por planes, nuevos planes para las marcas, queda pendiente arreglar la ruta get y poder upgradear una marca
1 parent 421ba0c commit e14fd11

25 files changed

+619
-264
lines changed

src/main/java/com/outfitlab/project/domain/interfaces/repositories/SubscriptionRepository.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
public interface SubscriptionRepository {
88

99
List<SubscriptionModel> getAllSubscriptions();
10-
10+
1111
SubscriptionModel getByPlanCode(String planCode);
12+
13+
List<SubscriptionModel> findByPlanType(String planType);
1214
}

src/main/java/com/outfitlab/project/domain/model/SubscriptionModel.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ public class SubscriptionModel {
2222

2323
private boolean isPopular;
2424

25+
private String planType;
26+
private Integer maxGarments;
27+
private boolean hasAnalytics;
28+
private boolean hasAdvancedReports;
29+
2530
public String getName() {
2631
return name;
2732
}
@@ -109,7 +114,36 @@ public boolean isPopular() {
109114
public void setPopular(boolean popular) {
110115
isPopular = popular;
111116
}
112-
}
113117

118+
public String getPlanType() {
119+
return planType;
120+
}
121+
122+
public void setPlanType(String planType) {
123+
this.planType = planType;
124+
}
125+
126+
public Integer getMaxGarments() {
127+
return maxGarments;
128+
}
129+
130+
public void setMaxGarments(Integer maxGarments) {
131+
this.maxGarments = maxGarments;
132+
}
133+
134+
public boolean isHasAnalytics() {
135+
return hasAnalytics;
136+
}
137+
138+
public void setHasAnalytics(boolean hasAnalytics) {
139+
this.hasAnalytics = hasAnalytics;
140+
}
114141

142+
public boolean isHasAdvancedReports() {
143+
return hasAdvancedReports;
144+
}
115145

146+
public void setHasAdvancedReports(boolean hasAdvancedReports) {
147+
this.hasAdvancedReports = hasAdvancedReports;
148+
}
149+
}

src/main/java/com/outfitlab/project/domain/model/UserSubscriptionModel.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,28 @@ public class UserSubscriptionModel {
1111
private Long id;
1212
private String userEmail;
1313
private String planCode;
14-
14+
1515
// Contadores de uso
16-
private int combinationsUsed; // Total creadas en el período
17-
private int favoritesCount; // Favoritos actuales en BD
18-
private int modelsGenerated; // Total generados en el período
19-
16+
private int combinationsUsed; // Total creadas en el período
17+
private int favoritesCount; // Favoritos actuales en BD
18+
private int modelsGenerated; // Total generados en el período
19+
private int downloadsCount; // Total descargas 2D
20+
private int garmentsUploaded; // Total prendas subidas (marcas)
21+
2022
// Límites del plan (denormalizados para performance)
21-
private Integer maxCombinations; // null = ilimitado
22-
private Integer maxFavorites; // null = ilimitado
23-
private Integer maxModels; // null = ilimitado
24-
23+
private Integer maxCombinations; // null = ilimitado
24+
private Integer maxFavorites; // null = ilimitado
25+
private Integer maxModels; // null = ilimitado
26+
private Integer maxDownloads; // null = ilimitado
27+
private Integer maxGarments; // null = ilimitado (para marcas)
28+
2529
// Metadata
2630
private LocalDateTime subscriptionStart;
2731
private LocalDateTime subscriptionEnd;
28-
private String status; // ACTIVE, CANCELLED, EXPIRED
32+
private String status; // ACTIVE, CANCELLED, EXPIRED
2933
private LocalDateTime createdAt;
3034
private LocalDateTime updatedAt;
3135

32-
public UserSubscriptionModel() {}
36+
public UserSubscriptionModel() {
37+
}
3338
}
Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,75 @@
11
package com.outfitlab.project.domain.useCases.fashn;
22

33
import com.outfitlab.project.domain.exceptions.FashnApiException;
4+
import com.outfitlab.project.domain.exceptions.PlanLimitExceededException;
45
import com.outfitlab.project.domain.exceptions.PredictionFailedException;
6+
import com.outfitlab.project.domain.exceptions.SubscriptionNotFoundException;
57
import com.outfitlab.project.domain.interfaces.repositories.FashnRepository;
68
import com.outfitlab.project.domain.model.dto.CombineRequestDTO;
9+
import com.outfitlab.project.domain.useCases.subscription.CheckUserPlanLimit;
10+
import com.outfitlab.project.domain.useCases.subscription.IncrementUsageCounter;
711

812
public class CombinePrendas {
913

1014
private final String TOPS = "tops";
1115
private final String BOTTOMS = "bottoms";
1216
private final FashnRepository iFashnRepository;
17+
private final CheckUserPlanLimit checkUserPlanLimit;
18+
private final IncrementUsageCounter incrementUsageCounter;
1319

14-
public CombinePrendas(FashnRepository iFashnRepository) {
20+
public CombinePrendas(FashnRepository iFashnRepository,
21+
CheckUserPlanLimit checkUserPlanLimit,
22+
IncrementUsageCounter incrementUsageCounter) {
1523
this.iFashnRepository = iFashnRepository;
24+
this.checkUserPlanLimit = checkUserPlanLimit;
25+
this.incrementUsageCounter = incrementUsageCounter;
1626
}
1727

18-
public String execute(CombineRequestDTO request) throws FashnApiException, PredictionFailedException {
28+
public String execute(CombineRequestDTO request, String userEmail)
29+
throws FashnApiException, PredictionFailedException, PlanLimitExceededException,
30+
SubscriptionNotFoundException {
1931
System.out.println(request.toString());
32+
33+
// Validar límite de combinaciones
34+
checkUserPlanLimit.execute(userEmail, "combinations");
35+
2036
checkRequestCombine(request.getTop(), request.getBottom());
2137

22-
if (isOnlyTop(request.getTop(), request.getBottom())) return combine(request.getTop(), TOPS, request.getAvatarType());
23-
if (isOnlyBotton(request.getBottom(), request.getTop())) return combine(request.getBottom(), BOTTOMS, request.getAvatarType());
38+
String result;
39+
if (isOnlyTop(request.getTop(), request.getBottom())) {
40+
result = combine(request.getTop(), TOPS, request.getAvatarType());
41+
} else if (isOnlyBotton(request.getBottom(), request.getTop())) {
42+
result = combine(request.getBottom(), BOTTOMS, request.getAvatarType());
43+
} else {
44+
result = combineTopAndBottom(request.getTop(), request.getBottom(), request.getAvatarType());
45+
}
46+
47+
// Incrementar contador de combinaciones después de éxito
48+
incrementUsageCounter.execute(userEmail, "combinations");
2449

25-
return combineTopAndBottom(request.getTop(), request.getBottom(), request.getAvatarType());
50+
return result;
2651
}
2752

2853
private boolean isOnlyTop(String top, String bottom) {
2954
return top != null && (bottom == null || bottom.isBlank());
3055
}
3156

3257
private void checkRequestCombine(String top, String bottom) throws FashnApiException {
33-
if ((top == null || top.isBlank()) && (bottom == null || bottom.isBlank())) throw new FashnApiException("Debe proporcionarse al menos una prenda (superior o inferior).");
58+
if ((top == null || top.isBlank()) && (bottom == null || bottom.isBlank()))
59+
throw new FashnApiException("Debe proporcionarse al menos una prenda (superior o inferior).");
3460
}
3561

3662
private boolean isOnlyBotton(String bottom, String top) {
3763
return bottom != null && (top == null || top.isBlank());
3864
}
3965

40-
private String combine(String garmentUrl, String category, String avatarType) throws FashnApiException, PredictionFailedException {
66+
private String combine(String garmentUrl, String category, String avatarType)
67+
throws FashnApiException, PredictionFailedException {
4168
return this.iFashnRepository.pollStatus(this.iFashnRepository.combine(garmentUrl, category, avatarType));
4269
}
4370

44-
private String combineTopAndBottom(String top, String bottom, String avatarType) throws FashnApiException, PredictionFailedException {
71+
private String combineTopAndBottom(String top, String bottom, String avatarType)
72+
throws FashnApiException, PredictionFailedException {
4573
return this.iFashnRepository.combineTopAndBottom(top, bottom, avatarType);
4674
}
4775
}

src/main/java/com/outfitlab/project/domain/useCases/subscription/AssignFreePlanToUser.java

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,19 @@
1212
public class AssignFreePlanToUser {
1313
private final UserSubscriptionRepository userSubscriptionRepository;
1414
private final SubscriptionRepository subscriptionRepository;
15-
private static final String FREE_PLAN_CODE = "free-monthly";
16-
15+
private static final String USER_FREE_PLAN_CODE = "user-free-monthly";
16+
private static final String BRAND_FREE_PLAN_CODE = "brand-free-monthly";
17+
1718
public AssignFreePlanToUser(UserSubscriptionRepository userSubscriptionRepository,
18-
SubscriptionRepository subscriptionRepository) {
19+
SubscriptionRepository subscriptionRepository) {
1920
this.userSubscriptionRepository = userSubscriptionRepository;
2021
this.subscriptionRepository = subscriptionRepository;
2122
}
22-
23-
public void execute(String userEmail) {
24-
SubscriptionModel freePlan =
25-
subscriptionRepository.getByPlanCode(FREE_PLAN_CODE);
26-
23+
24+
public void execute(String userEmail, boolean isBrand) {
25+
String planCode = isBrand ? BRAND_FREE_PLAN_CODE : USER_FREE_PLAN_CODE;
26+
SubscriptionModel freePlan = subscriptionRepository.getByPlanCode(planCode);
27+
2728
UserSubscriptionModel userSubscription = new UserSubscriptionModel();
2829
userSubscription.setUserEmail(userEmail);
2930
userSubscription.setPlanCode(freePlan.getPlanCode());
@@ -32,26 +33,26 @@ public void execute(String userEmail) {
3233
userSubscription.setMaxModels(parseLimitFromFeature(freePlan.getFeature3()));
3334
userSubscription.setStatus("ACTIVE");
3435
userSubscription.setSubscriptionStart(LocalDateTime.now());
35-
36+
3637
userSubscriptionRepository.save(userSubscription);
3738
}
38-
39+
3940
private Integer parseLimitFromFeature(String feature) {
4041
if (feature == null) {
4142
return null;
4243
}
43-
44-
if (feature.toLowerCase().contains("ilimitado") ||
45-
feature.toLowerCase().contains("ilimitada")) {
44+
45+
if (feature.toLowerCase().contains("ilimitado") ||
46+
feature.toLowerCase().contains("ilimitada")) {
4647
return null;
4748
}
48-
49+
4950
Pattern pattern = Pattern.compile("\\d+");
5051
Matcher matcher = pattern.matcher(feature);
5152
if (matcher.find()) {
5253
return Integer.parseInt(matcher.group());
5354
}
54-
55+
5556
return null;
5657
}
5758
}

src/main/java/com/outfitlab/project/domain/useCases/subscription/CheckUserPlanLimit.java

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,43 +7,51 @@
77

88
public class CheckUserPlanLimit {
99
private final UserSubscriptionRepository userSubscriptionRepository;
10-
10+
1111
public CheckUserPlanLimit(UserSubscriptionRepository userSubscriptionRepository) {
1212
this.userSubscriptionRepository = userSubscriptionRepository;
1313
}
14-
15-
public void execute(String userEmail, String limitType)
14+
15+
public void execute(String userEmail, String limitType)
1616
throws PlanLimitExceededException, SubscriptionNotFoundException {
17-
UserSubscriptionModel subscription =
18-
userSubscriptionRepository.findByUserEmail(userEmail);
19-
20-
switch(limitType) {
17+
UserSubscriptionModel subscription = userSubscriptionRepository.findByUserEmail(userEmail);
18+
19+
switch (limitType) {
2120
case "combinations":
22-
checkLimit(subscription.getCombinationsUsed(),
23-
subscription.getMaxCombinations(),
24-
"combinaciones diarias");
21+
checkLimit(subscription.getCombinationsUsed(),
22+
subscription.getMaxCombinations(),
23+
"combinaciones diarias");
2524
break;
2625
case "favorites":
27-
checkLimit(subscription.getFavoritesCount(),
28-
subscription.getMaxFavorites(),
29-
"favoritos");
26+
checkLimit(subscription.getFavoritesCount(),
27+
subscription.getMaxFavorites(),
28+
"favoritos");
3029
break;
3130
case "3d_models":
32-
checkLimit(subscription.getModelsGenerated(),
33-
subscription.getMaxModels(),
34-
"modelos 3D");
31+
checkLimit(subscription.getModelsGenerated(),
32+
subscription.getMaxModels(),
33+
"modelos 3D");
34+
break;
35+
case "downloads":
36+
checkLimit(subscription.getDownloadsCount(),
37+
subscription.getMaxDownloads(),
38+
"descargas 2D");
3539
break;
3640
}
3741
}
38-
39-
private void checkLimit(int current, Integer max, String feature)
42+
43+
private void checkLimit(int current, Integer max, String feature)
4044
throws PlanLimitExceededException {
41-
if (max != null && current >= max) {
45+
// Si max es null o -1, es ilimitado
46+
if (max == null || max == -1) {
47+
return;
48+
}
49+
50+
if (current >= max) {
4251
throw new PlanLimitExceededException(
43-
"Has alcanzado el límite de " + feature +
44-
" para tu plan. Actualiza a PRO para acceso ilimitado.",
45-
feature, current, max
46-
);
52+
"Has alcanzado el límite de " + feature +
53+
" para tu plan. Actualiza a PRO para acceso ilimitado.",
54+
feature, current, max);
4755
}
4856
}
4957
}
Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,34 @@
11
package com.outfitlab.project.domain.useCases.subscription;
22

3-
import com.outfitlab.project.domain.model.SubscriptionModel;
3+
import com.outfitlab.project.domain.interfaces.repositories.UserRepository;
44
import com.outfitlab.project.domain.interfaces.repositories.SubscriptionRepository;
5+
import com.outfitlab.project.domain.model.SubscriptionModel;
6+
import com.outfitlab.project.domain.model.UserModel;
7+
import com.outfitlab.project.domain.exceptions.UserNotFoundException;
58

69
import java.util.List;
710

811
public class GetAllSubscription {
912

1013
private final SubscriptionRepository subscriptionRepository;
11-
public GetAllSubscription(SubscriptionRepository subscriptionRepository){
12-
this.subscriptionRepository = subscriptionRepository;
13-
}
14+
private final UserRepository userRepository;
1415

15-
public List<SubscriptionModel> execute(){
16-
return subscriptionRepository.getAllSubscriptions();
16+
public GetAllSubscription(SubscriptionRepository subscriptionRepository, UserRepository userRepository) {
17+
this.subscriptionRepository = subscriptionRepository;
18+
this.userRepository = userRepository;
1719
}
1820

21+
public List<SubscriptionModel> execute(String userEmail) {
22+
if (userEmail == null || userEmail.isEmpty()) {
23+
return subscriptionRepository.findByPlanType("USER");
24+
}
1925

26+
try {
27+
UserModel user = userRepository.findUserByEmail(userEmail);
28+
String planType = (user.getBrand() != null) ? "BRAND" : "USER";
29+
return subscriptionRepository.findByPlanType(planType);
30+
} catch (UserNotFoundException e) {
31+
return subscriptionRepository.findByPlanType("USER");
32+
}
33+
}
2034
}

src/main/java/com/outfitlab/project/infrastructure/config/FashnConfig.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.outfitlab.project.domain.interfaces.repositories.FashnRepository;
44
import com.outfitlab.project.domain.useCases.fashn.CombinePrendas;
5+
import com.outfitlab.project.domain.useCases.subscription.CheckUserPlanLimit;
6+
import com.outfitlab.project.domain.useCases.subscription.IncrementUsageCounter;
57
import com.outfitlab.project.infrastructure.repositories.FashnRepositoryImpl;
68
import org.springframework.context.annotation.Bean;
79
import org.springframework.context.annotation.Configuration;
@@ -16,7 +18,9 @@ public FashnRepository fashnRepositoryImpl(RestTemplate restTemplate) {
1618
}
1719

1820
@Bean
19-
public CombinePrendas combinePrendas(FashnRepository iFashnRepository){
20-
return new CombinePrendas(iFashnRepository);
21+
public CombinePrendas combinePrendas(FashnRepository iFashnRepository,
22+
CheckUserPlanLimit checkUserPlanLimit,
23+
IncrementUsageCounter incrementUsageCounter) {
24+
return new CombinePrendas(iFashnRepository, checkUserPlanLimit, incrementUsageCounter);
2125
}
2226
}

src/main/java/com/outfitlab/project/infrastructure/config/SubscriptionConfig.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ public UserSubscriptionRepository userSubscriptionRepository(UserSubscriptionJpa
4242
}
4343

4444
@Bean
45-
public GetAllSubscription getAllsubscription(SubscriptionRepository subscriptionRepository) {
46-
return new GetAllSubscription(subscriptionRepository);
45+
public GetAllSubscription getAllsubscription(SubscriptionRepository subscriptionRepository,
46+
UserRepository userRepository) {
47+
return new GetAllSubscription(subscriptionRepository, userRepository);
4748
}
4849

4950
@Bean

0 commit comments

Comments
 (0)