Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorder packages and add custom Guard usage for validations #13

Merged
merged 1 commit into from
Mar 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
92 changes: 0 additions & 92 deletions server/src/main/java/io/myfinbox/account/Account.java

This file was deleted.

15 changes: 8 additions & 7 deletions server/src/main/java/io/myfinbox/account/AccountCreated.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
package io.myfinbox.account;

import io.myfinbox.account.Account.AccountIdentifier;
import io.myfinbox.account.Account.EmailAddress;
import io.myfinbox.shared.DomainEvent;
import lombok.Builder;

import static java.util.Objects.requireNonNull;
import java.util.UUID;

import static io.myfinbox.shared.Guards.notBlank;
import static io.myfinbox.shared.Guards.notNull;

/**
* Represents an event indicating that an account has been created.
*/
@Builder
public record AccountCreated(AccountIdentifier accountIdentifier,
EmailAddress emailAddress,
public record AccountCreated(UUID accountId,
String emailAddress,
String firstName,
String lastName) implements DomainEvent {

public AccountCreated {
requireNonNull(accountIdentifier, "accountIdentifier cannot be null");
requireNonNull(emailAddress, "emailAddress cannot be null");
notNull(accountId, "accountIdentifier cannot be null");
notBlank(emailAddress, "emailAddress cannot be blank");
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.myfinbox.account.web;
package io.myfinbox.account.adapter.web;

import io.myfinbox.account.CreateAccountUseCase;
import io.myfinbox.account.CreateAccountUseCase.CreateAccountCommand;
import io.myfinbox.account.application.CreateAccountUseCase;
import io.myfinbox.account.application.CreateAccountUseCase.CreateAccountCommand;
import io.myfinbox.shared.AccountCreateResource;
import io.myfinbox.shared.ApiFailureHandler;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.myfinbox.account.web;
package io.myfinbox.account.adapter.web;

import io.myfinbox.shared.AccountCreateResource;
import io.myfinbox.shared.ApiErrorResponse;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.myfinbox.account;
package io.myfinbox.account.application;

import io.myfinbox.account.domain.Account;
import io.myfinbox.account.domain.Accounts;
import io.myfinbox.shared.Failure;
import io.myfinbox.shared.Failure.FieldViolation;
import io.vavr.collection.Seq;
Expand All @@ -12,7 +14,7 @@

import java.util.regex.Pattern;

import static io.myfinbox.account.CreateAccountUseCase.CreateAccountCommand.*;
import static io.myfinbox.account.application.CreateAccountUseCase.CreateAccountCommand.*;
import static io.vavr.API.Invalid;
import static io.vavr.API.Valid;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.myfinbox.account;
package io.myfinbox.account.application;

import io.myfinbox.account.domain.Account;
import io.myfinbox.shared.Failure;
import io.vavr.control.Either;
import lombok.Builder;
Expand Down
81 changes: 81 additions & 0 deletions server/src/main/java/io/myfinbox/account/domain/Account.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package io.myfinbox.account.domain;

import io.myfinbox.account.AccountCreated;
import jakarta.persistence.*;
import lombok.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.AbstractAggregateRoot;

import java.io.Serializable;
import java.time.Instant;
import java.util.UUID;
import java.util.regex.Pattern;

import static io.myfinbox.shared.Guards.*;
import static lombok.AccessLevel.PRIVATE;

@Entity
@Table(name = "accounts")
@Getter
@ToString
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor(access = PRIVATE, force = true)
public class Account extends AbstractAggregateRoot<Account> {

public static final int MAX_LENGTH = 255;

public static final String patternRFC5322 = "^[\\w!#$%&'*+/=?`{|}~^-]+(?:\\.[\\w!#$%&'*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$";
static final Pattern pattern = Pattern.compile(patternRFC5322);

private @EmbeddedId AccountIdentifier id;
private @Embedded EmailAddress emailAddress;
private String firstName;
private String lastName;
private Instant creationDate;

@Builder
public Account(String firstName, String lastName, EmailAddress emailAddress) {
this.emailAddress = notNull(emailAddress, "emailAddress cannot be null");

if (!StringUtils.isBlank(firstName)) {
this.firstName = doesNotOverflow(firstName.trim(), MAX_LENGTH, "firstName overflow, max length allowed '%d'".formatted(MAX_LENGTH));
}

if (!StringUtils.isBlank(lastName)) {
this.lastName = doesNotOverflow(lastName.trim(), MAX_LENGTH, "lastName overflow, max length allowed '%d'".formatted(MAX_LENGTH));
}

this.id = new AccountIdentifier(UUID.randomUUID());
this.creationDate = Instant.now();

registerEvent(new AccountCreated(this.id.id(), this.emailAddress.emailAddress(), firstName, lastName));
}

@Embeddable
public record AccountIdentifier(UUID id) implements Serializable {

public AccountIdentifier {
notNull(id, "id cannot be null");
}

@Override
public String toString() {
return id.toString();
}
}

@Embeddable
public record EmailAddress(String emailAddress) implements Serializable {

public EmailAddress {
notBlank(emailAddress, "emailAddress cannot be blank");
doesNotOverflow(emailAddress.trim(), MAX_LENGTH, "emailAddress max length must be '%d'".formatted(MAX_LENGTH));
matches(emailAddress, pattern, "emailAddress must match '%s'".formatted(patternRFC5322));
}

@Override
public String toString() {
return emailAddress;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.myfinbox.account;
package io.myfinbox.account.domain;

import io.myfinbox.account.Account.AccountIdentifier;
import io.myfinbox.account.Account.EmailAddress;
import io.myfinbox.account.domain.Account.AccountIdentifier;
import io.myfinbox.account.domain.Account.EmailAddress;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package io.myfinbox.expense.messaging;
package io.myfinbox.expense.adapter.messaging;

import io.myfinbox.account.AccountCreated;
import io.myfinbox.expense.AccountIdentifier;
import io.myfinbox.expense.CategoryService;
import io.myfinbox.expense.application.CategoryService;
import io.myfinbox.expense.domain.AccountIdentifier;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.modulith.events.ApplicationModuleListener;
Expand All @@ -26,7 +26,7 @@ class AccountEventsListener {
@ApplicationModuleListener
public void on(AccountCreated event) {
log.debug("Handle account create event {}", event);
var either = categoryService.createDefault(new AccountIdentifier(event.accountIdentifier().id()));
var either = categoryService.createDefault(new AccountIdentifier(event.accountId()));

if (either.isLeft()) {
log.error("Failed to create default categories for account: {}, failure: {}", event, either.getLeft());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package io.myfinbox.expense.web;
package io.myfinbox.expense.adapter.web;

import io.myfinbox.expense.CreateExpenseUseCase;
import io.myfinbox.expense.Expense;
import io.myfinbox.expense.ExpenseCommand;
import io.myfinbox.expense.application.CreateExpenseUseCase;
import io.myfinbox.expense.application.ExpenseCommand;
import io.myfinbox.expense.domain.Expense;
import io.myfinbox.shared.ApiFailureHandler;
import io.myfinbox.shared.ExpenseResource;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.myfinbox.expense.web;
package io.myfinbox.expense.adapter.web;

import io.myfinbox.shared.ApiErrorResponse;
import io.myfinbox.shared.ExpenseResource;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.myfinbox.expense;
package io.myfinbox.expense.application;

import io.myfinbox.expense.domain.AccountIdentifier;
import io.myfinbox.expense.domain.Category;
import io.myfinbox.shared.Failure;
import io.vavr.control.Either;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package io.myfinbox.expense;
package io.myfinbox.expense.application;

import io.myfinbox.expense.Category.CategoryIdentifier;
import io.myfinbox.expense.domain.AccountIdentifier;
import io.myfinbox.expense.domain.Categories;
import io.myfinbox.expense.domain.Category.CategoryIdentifier;
import io.myfinbox.expense.domain.Expense;
import io.myfinbox.expense.domain.Expenses;
import io.myfinbox.shared.Failure;
import io.myfinbox.shared.PaymentType;
import io.vavr.control.Either;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.myfinbox.expense;
package io.myfinbox.expense.application;

import io.myfinbox.expense.domain.Expense;
import io.myfinbox.shared.Failure;
import io.vavr.control.Either;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package io.myfinbox.expense;
package io.myfinbox.expense.application;

import io.myfinbox.expense.domain.AccountIdentifier;
import io.myfinbox.expense.domain.Categories;
import io.myfinbox.expense.domain.Category;
import io.myfinbox.expense.domain.DefaultCategories;
import io.myfinbox.shared.Failure;
import io.vavr.control.Either;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.myfinbox.expense;
package io.myfinbox.expense.application;

import lombok.Builder;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.myfinbox.expense;
package io.myfinbox.expense.application;

import io.myfinbox.shared.Failure.FieldViolation;
import io.myfinbox.shared.PaymentType;
Expand All @@ -10,7 +10,7 @@
import java.util.Currency;
import java.util.UUID;

import static io.myfinbox.expense.ExpenseCommand.*;
import static io.myfinbox.expense.application.ExpenseCommand.*;
import static io.vavr.API.Invalid;
import static io.vavr.API.Valid;
import static java.math.BigDecimal.ZERO;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package io.myfinbox.expense;
package io.myfinbox.expense.domain;

import jakarta.persistence.Embeddable;

import java.io.Serializable;
import java.util.UUID;

import static java.util.Objects.requireNonNull;
import static io.myfinbox.shared.Guards.notNull;

@Embeddable
public record AccountIdentifier(UUID id) implements Serializable {

public AccountIdentifier {
requireNonNull(id, "id cannot be null");
notNull(id, "id cannot be null");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.myfinbox.expense;
package io.myfinbox.expense.domain;

import io.myfinbox.expense.Category.CategoryIdentifier;
import io.myfinbox.expense.domain.Category.CategoryIdentifier;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

Expand Down
Loading
Loading