Skip to content
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
1 change: 0 additions & 1 deletion HELP.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@ For further reference, please consider the following sections:
These additional references should also help you:

* [Gradle Build Scans – insights for your project's build](https://scans.gradle.com#gradle)

77 changes: 49 additions & 28 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,53 +1,74 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.4.3'
id 'io.spring.dependency-management' version '1.1.7'
id 'io.freefair.lombok' version '8.13.1'
id 'java'
id 'org.springframework.boot' version '3.4.3'
id 'io.spring.dependency-management' version '1.1.7'
id 'io.freefair.lombok' version '8.13.1'
id 'com.diffplug.spotless' version '7.0.4'
}

group = 'io.autoinvestor'

java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}

repositories {
mavenCentral()
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

implementation 'com.google.cloud:google-cloud-pubsub:1.123.0'
implementation "com.google.cloud:spring-cloud-gcp-starter-pubsub:6.1.1"
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'org.springframework.integration:spring-integration-core'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation("jakarta.validation:jakarta.validation-api:3.0.2")
implementation 'com.google.cloud:google-cloud-pubsub:1.123.0'
implementation "com.google.cloud:spring-cloud-gcp-starter-pubsub:6.1.1"
implementation 'com.fasterxml.jackson.core:jackson-databind'
implementation 'org.springframework.integration:spring-integration-core'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation("jakarta.validation:jakarta.validation-api:3.0.2")

testImplementation 'org.springframework.boot:spring-boot-testcontainers'
testImplementation 'org.testcontainers:testcontainers'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:gcloud'
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
testImplementation 'org.testcontainers:testcontainers'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:gcloud'

compileOnly 'org.projectlombok:lombok:1.18.38'
annotationProcessor 'org.projectlombok:lombok:1.18.38'
compileOnly 'org.projectlombok:lombok:1.18.38'
annotationProcessor 'org.projectlombok:lombok:1.18.38'

testCompileOnly 'org.projectlombok:lombok:1.18.38'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.38'
testCompileOnly 'org.projectlombok:lombok:1.18.38'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.38'
}

tasks.named('test') {
useJUnitPlatform()
useJUnitPlatform()
}

tasks.withType(JavaCompile).configureEach {
options.compilerArgs << '-parameters'
options.compilerArgs << '-parameters'
}

bootBuildImage {
publish = false
publish = false
}

spotless {
java {
googleJavaFormat('1.22.0').aosp()
removeUnusedImports()
trimTrailingWhitespace()
leadingTabsToSpaces()
endWithNewline()
importOrder '', 'java', 'javax', 'org', 'com'
target 'src/**/*.java'
}

format 'misc', {
target '*.gradle', '*.md', '.gitignore'
leadingTabsToSpaces()
trimTrailingWhitespace()
endWithNewline()
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
package io.autoinvestor.application.HoldingDeleteUseCase;

public record HoldingDeleteCommand(
String userId,
String assetId
) {
}
public record HoldingDeleteCommand(String userId, String assetId) {}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
import io.autoinvestor.domain.model.WalletId;
import io.autoinvestor.exceptions.UserWithoutPortfolio;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class HoldingDeleteCommandHandler {
Expand All @@ -22,13 +23,15 @@ public class HoldingDeleteCommandHandler {
private final HoldingsReadModel holdingsReadModel;
private final EventPublisher eventPublisher;

public void handle (HoldingDeleteCommand command) {
public void handle(HoldingDeleteCommand command) {
String walletId = this.usersWalletReadModel.getWalletId(command.userId());
if (walletId == null) {
throw UserWithoutPortfolio.with(command.userId());
}
Wallet wallet = this.eventStore.get(WalletId.of(walletId))
.orElseThrow(() -> UserWithoutPortfolio.with(command.userId()));
Wallet wallet =
this.eventStore
.get(WalletId.of(walletId))
.orElseThrow(() -> UserWithoutPortfolio.with(command.userId()));
wallet.deleteHolding(command.userId(), command.assetId());
List<Event<?>> events = wallet.getUncommittedEvents();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@

public interface HoldingsReadModel {
void add(HoldingsReadModelDTO dto);

void update(HoldingsReadModelDTO dto);

boolean delete(String userId, String assetId);

List<HoldingsReadModelDTO> getHoldings(String userId);

boolean assetAlreadyExists(String userIs, String assetId);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
package io.autoinvestor.application;

public record HoldingsReadModelDTO(
String userId,
String assetId,
Integer amount,
Integer boughtPrice
) {
}
String userId, String assetId, Integer amount, Integer boughtPrice) {}
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
package io.autoinvestor.application.NewHoldingUseCase;

public record NewHoldingCommand(
String assetId,
String userId,
Integer amount,
Integer boughtPrice
) {
}
String assetId, String userId, Integer amount, Integer boughtPrice) {}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
import io.autoinvestor.exceptions.AssetAlreadyExists;
import io.autoinvestor.exceptions.UserWithoutPortfolio;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class NewHoldingCommandHandler {
Expand All @@ -34,22 +35,32 @@ public void handle(NewHoldingCommand command) {
if (this.holdingsReadModel.assetAlreadyExists(command.userId(), command.assetId())) {
throw AssetAlreadyExists.with(command.userId(), command.assetId());
}
Wallet wallet = this.eventStore.get(WalletId.of(walletId))
.orElseThrow(() -> UserWithoutPortfolio.with(command.userId()));
Wallet wallet =
this.eventStore
.get(WalletId.of(walletId))
.orElseThrow(() -> UserWithoutPortfolio.with(command.userId()));

wallet.createHolding(command.userId(), command.assetId(), command.amount(), command.boughtPrice());
wallet.createHolding(
command.userId(), command.assetId(), command.amount(), command.boughtPrice());

List<Event<?>> events = wallet.getUncommittedEvents();

this.eventStore.save(wallet);

HoldingsReadModelDTO dto = new HoldingsReadModelDTO(
wallet.getState().getUserId().value(),
command.assetId(),
wallet.getState().getHoldings().get(AssetId.of(command.assetId())).amount().value(),
wallet.getState().getHoldings().get(AssetId.of(command.assetId())).boughtPrice().value()

);
HoldingsReadModelDTO dto =
new HoldingsReadModelDTO(
wallet.getState().getUserId().value(),
command.assetId(),
wallet.getState()
.getHoldings()
.get(AssetId.of(command.assetId()))
.amount()
.value(),
wallet.getState()
.getHoldings()
.get(AssetId.of(command.assetId()))
.boughtPrice()
.value());
this.holdingsReadModel.add(dto);

this.eventPublisher.publish(events);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
package io.autoinvestor.application.QueryHoldingsUseCase;

public record GetHoldingsQuery(
String userId
) {}
public record GetHoldingsQuery(String userId) {}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
import io.autoinvestor.application.HoldingsReadModel;
import io.autoinvestor.application.HoldingsReadModelDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class GetHoldingsQueryHandler {

private final HoldingsReadModel readModel;

public List<HoldingsReadModelDTO> handle (GetHoldingsQuery query) {
public List<HoldingsReadModelDTO> handle(GetHoldingsQuery query) {
return this.readModel.getHoldings(query.userId());
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
package io.autoinvestor.application.UptdateHoldingUseCase;

public record UpdateHoldingCommand(
String userId,
String assetId,
Integer amount,
Integer boughtPrice
) {
}
String userId, String assetId, Integer amount, Integer boughtPrice) {}
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@
import io.autoinvestor.application.HoldingsReadModel;
import io.autoinvestor.application.HoldingsReadModelDTO;
import io.autoinvestor.application.UsersWalletReadModel;
import io.autoinvestor.domain.events.Event;
import io.autoinvestor.domain.events.EventPublisher;
import io.autoinvestor.domain.events.WalletEventStoreRepository;
import io.autoinvestor.domain.model.AssetId;
import io.autoinvestor.domain.events.Event;
import io.autoinvestor.domain.model.Wallet;
import io.autoinvestor.domain.events.WalletEventStoreRepository;
import io.autoinvestor.domain.model.WalletId;
import io.autoinvestor.exceptions.UserWithoutPortfolio;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class UpdateHoldingCommandHandler {
Expand All @@ -24,27 +25,38 @@ public class UpdateHoldingCommandHandler {
private final WalletEventStoreRepository eventStore;
private final EventPublisher eventPublisher;

public void handle (UpdateHoldingCommand command) {
public void handle(UpdateHoldingCommand command) {
String walletId = this.usersWalletReadModel.getWalletId(command.userId());
if (walletId == null) {
throw UserWithoutPortfolio.with(command.userId());
}

Wallet wallet = this.eventStore.get(WalletId.of(walletId))
.orElseThrow(() -> UserWithoutPortfolio.with(command.userId()));
Wallet wallet =
this.eventStore
.get(WalletId.of(walletId))
.orElseThrow(() -> UserWithoutPortfolio.with(command.userId()));

wallet.updateHolding(command.userId(), command.assetId(), command.amount(), command.boughtPrice());
wallet.updateHolding(
command.userId(), command.assetId(), command.amount(), command.boughtPrice());

List<Event<?>> events = wallet.getUncommittedEvents();

this.eventStore.save(wallet);

HoldingsReadModelDTO dto = new HoldingsReadModelDTO(
wallet.getState().getUserId().value(),
command.assetId(),
wallet.getState().getHoldings().get(AssetId.of(command.assetId())).amount().value(),
wallet.getState().getHoldings().get(AssetId.of(command.assetId())).boughtPrice().value()
);
HoldingsReadModelDTO dto =
new HoldingsReadModelDTO(
wallet.getState().getUserId().value(),
command.assetId(),
wallet.getState()
.getHoldings()
.get(AssetId.of(command.assetId()))
.amount()
.value(),
wallet.getState()
.getHoldings()
.get(AssetId.of(command.assetId()))
.boughtPrice()
.value());
this.holdingsReadModel.update(dto);

this.eventPublisher.publish(events);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

public interface UsersWalletReadModel {
void add(UsersWalletReadModelDTO dto);

String getWalletId(String userId);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
package io.autoinvestor.application;

public record UsersWalletReadModelDTO(
String walletId,
String userId
) {
}
public record UsersWalletReadModelDTO(String walletId, String userId) {}
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
package io.autoinvestor.application.WalletCreatedUseCase;

public record WalletCreateCommand(
String userId
) {}
public record WalletCreateCommand(String userId) {}
Loading