Skip to content
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package space.yurisi.universecorev2.model.profile;

import org.jetbrains.annotations.NotNull;
import space.yurisi.universecorev2.model.user.UserId;

import java.util.UUID;

public record Profile(
@NotNull UserId id,
@NotNull UUID mcUuid,
@NotNull String name
) {
public Profile withName(String newName) {
return new Profile(id, mcUuid, newName);
}
}
10 changes: 10 additions & 0 deletions src/main/java/space/yurisi/universecorev2/model/user/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package space.yurisi.universecorev2.model.user;

import org.jetbrains.annotations.NotNull;
import space.yurisi.universecorev2.model.wallet.WalletId;

public record User(
@NotNull UserId id,
@NotNull WalletId walletId
) {
}
10 changes: 10 additions & 0 deletions src/main/java/space/yurisi/universecorev2/model/user/UserId.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package space.yurisi.universecorev2.model.user;

import org.jetbrains.annotations.NotNull;

import java.util.UUID;

public record UserId(
@NotNull UUID value
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package space.yurisi.universecorev2.model.wallet;

/**
* 金額を表すための値オブジェクト
*/
public record Balance(long value) {
public final static long MAX = 1_000_000_000L;

/**
* 用途に応じて {@link Balance#maybe(long)} か {@link Balance#must(long)} を代わりに使用してください
* @see Balance#must(long)
* @see Balance#maybe(long)
*/
public Balance {
if (isOutOfRange(value)) {
throw new IllegalArgumentException("値が範囲外です");
}
}

private static boolean isOutOfRange(long value) {
return (value < 0 || MAX < value);
}

public static Balance must(long value) {
return new Balance(value);
}

public static BalanceResult maybe(long value) {
if (isOutOfRange(value)) {
return new BalanceResult.Err();
}

return new BalanceResult.Ok(new Balance(value));
}

public BalanceResult add(TransactionDelta delta) {
return maybe(value + delta.value());
}


public BalanceResult subtract(TransactionDelta delta) {
return maybe(value - delta.value());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package space.yurisi.universecorev2.model.wallet;

public sealed interface BalanceResult {
record Ok(Balance balance) implements BalanceResult {}
record Err() implements BalanceResult {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package space.yurisi.universecorev2.model.wallet;

import org.jetbrains.annotations.NotNull;
import space.yurisi.universecorev2.model.user.UserId;

import java.util.Date;

public record History(
@NotNull WalletId id,
@NotNull Long delta,
@NotNull String reason,
@NotNull Date timestamp
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package space.yurisi.universecorev2.model.wallet;

import java.util.Optional;

/**
* 0より大きい金額を表すための値オブジェクト
*/
public record TransactionDelta(long value) {
/**
* 用途に応じて {@link TransactionDelta#maybe(long)} か {@link TransactionDelta#must(long)} を代わりに使用すること
* @see TransactionDelta#must(long)
* @see TransactionDelta#maybe(long)
*/
public TransactionDelta {
if (value <= 0) {
throw new IllegalArgumentException("取引量は0以上である必要があります");
}
}

/**
* 範囲に収まる保証がある場合に{@link TransactionDelta}を得る
*/
public static TransactionDelta must(long value) {
return new TransactionDelta(value);
}

/**
* 範囲に収まる保証がないときでも安全に{@link TransactionDelta}を得る
*/
public static Optional<TransactionDelta> maybe(long value) {
if (value <= 0) {
return Optional.empty();
}

return Optional.of(new TransactionDelta(value));
}
}
30 changes: 30 additions & 0 deletions src/main/java/space/yurisi/universecorev2/model/wallet/Wallet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package space.yurisi.universecorev2.model.wallet;

import org.jetbrains.annotations.NotNull;
import space.yurisi.universecorev2.model.user.UserId;

import java.util.UUID;

/**
* ユーザーの所持金を表すレコード
* @param id
* @param balance
*/
public record Wallet(
@NotNull WalletId id,
@NotNull Balance balance
) {
public WalletResult withdraw(TransactionDelta delta) {
return switch (balance.subtract(delta)) {
case BalanceResult.Ok(Balance newBalance) -> new WalletResult.Ok(new Wallet(id, newBalance));
case BalanceResult.Err() -> new WalletResult.Err("残高不足");
};
}

public WalletResult deposit(TransactionDelta delta) {
return switch (balance.add(delta)) {
case BalanceResult.Ok(Balance newBalance) -> new WalletResult.Ok(new Wallet(id, newBalance));
case BalanceResult.Err() -> new WalletResult.Err("上限超過");
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package space.yurisi.universecorev2.model.wallet;

import org.jetbrains.annotations.NotNull;

import java.util.UUID;

public record WalletId(
@NotNull UUID value
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package space.yurisi.universecorev2.model.wallet;

public sealed interface WalletResult {
record Ok(Wallet wallet) implements WalletResult {}
record Err(String reason) implements WalletResult {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package space.yurisi.universecorev2.repository;

import org.jetbrains.annotations.NotNull;
import space.yurisi.universecorev2.model.profile.Profile;
import space.yurisi.universecorev2.model.user.UserId;

import java.util.Optional;
import java.util.UUID;

public interface ProfileRepository {
void create(@NotNull Profile user);
Optional<Profile> findByMinecraftId(@NotNull UserId id);
Optional<Profile> findByMinecraftId(@NotNull UUID mcUuid);
void update(@NotNull Profile user);
void delete(@NotNull UserId id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package space.yurisi.universecorev2.repository;

import space.yurisi.universecorev2.model.user.UserId;
import space.yurisi.universecorev2.model.wallet.History;

import java.util.Date;

public interface WalletHistoryRepository {
void create(History history);
History[] findLatestWithLimit(UserId userId, Date since, int limit);
History[] findAfterWithLimit(UserId userId, Date since, int limit);
History[] findBeforeWithLimit(UserId userId, Date until, int limit);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package space.yurisi.universecorev2.repository;

import org.jetbrains.annotations.NotNull;
import space.yurisi.universecorev2.model.user.UserId;
import space.yurisi.universecorev2.model.wallet.Wallet;

import java.util.Optional;

public interface WalletRepository {
void create(@NotNull Wallet user);
Optional<Wallet> find(@NotNull UserId id);
void update(@NotNull Wallet wallet);
void delete(@NotNull UserId id);
}