From d2688a197bd680580699f05e8194f9180e4832fa Mon Sep 17 00:00:00 2001 From: Kostya Date: Tue, 18 Aug 2026 06:52:47 +0000 Subject: Add XML schema validation, split build scripts by module, rename BuyMenuCommand to PlaceOrderMenuCommand Introduces XMLValidatorV1 and deserializer/adapter classes for events, ledgers, markets, users, and trading mechanisms. Replaces the monolithic build.bat/run.sh scripts with per-module tools (_util.sh, build.sh, package.sh, test.sh) that compile in dependency order. --- .../src/main/java/market/guess/ui/console/App.java | 6 +- .../guess/ui/console/command/BuyMenuCommand.java | 77 --------------------- .../ui/console/command/LoadFileMenuCommand.java | 2 +- .../ui/console/command/PlaceOrderMenuCommand.java | 78 ++++++++++++++++++++++ 4 files changed, 83 insertions(+), 80 deletions(-) delete mode 100644 ui-console/src/main/java/market/guess/ui/console/command/BuyMenuCommand.java create mode 100644 ui-console/src/main/java/market/guess/ui/console/command/PlaceOrderMenuCommand.java (limited to 'ui-console/src/main') diff --git a/ui-console/src/main/java/market/guess/ui/console/App.java b/ui-console/src/main/java/market/guess/ui/console/App.java index 5ee5aaf..047bad1 100644 --- a/ui-console/src/main/java/market/guess/ui/console/App.java +++ b/ui-console/src/main/java/market/guess/ui/console/App.java @@ -9,6 +9,7 @@ import market.guess.service.catalog.infrastructure.MarketContext; import market.guess.service.catalog.infrastructure.mapper.v1.EventMapperV1; import market.guess.service.catalog.infrastructure.provider.Loader; import market.guess.service.catalog.infrastructure.provider.v1.XMLLoaderV1; +import market.guess.service.catalog.infrastructure.provider.v1.XMLValidatorV1; import market.guess.service.catalog.infrastructure.repository.EventRepository; import market.guess.service.catalog.infrastructure.repository.InMemoryEventRepository; import market.guess.service.catalog.infrastructure.repository.InMemoryUserRepository; @@ -22,12 +23,12 @@ import market.guess.service.risk.LocalRiskEngine; import market.guess.service.risk.RiskEngine; import market.guess.service.settlement.LocalSettlementContext; import market.guess.service.settlement.SettlementContext; -import market.guess.ui.console.command.BuyMenuCommand; import market.guess.ui.console.command.EventDetailsMenuCommand; import market.guess.ui.console.command.ExitMenuCommand; import market.guess.ui.console.command.ListEventsMenuCommand; import market.guess.ui.console.command.LoadFileMenuCommand; import market.guess.ui.console.command.LoadMarketStateMenuCommand; +import market.guess.ui.console.command.PlaceOrderMenuCommand; import market.guess.ui.console.command.SaveMarketStateMenuCommand; import market.guess.ui.console.command.SettleEventMenuCommand; import market.guess.ui.console.io.InputProcessor; @@ -43,6 +44,7 @@ public class App { pico.addComponent(MarketContext.class); pico.addComponent(EventMapperV1.class); pico.addComponent(Loader.class, XMLLoaderV1.class); + pico.addComponent(XMLValidatorV1.class); pico.addComponent(GuessMarketContext.class, LocalGuessMarketContext.class); pico.addComponent(CatalogContext.class, LocalCatalogContext.class); pico.addComponent(LedgerContext.class); @@ -56,7 +58,7 @@ public class App { pico.addComponent(LoadFileMenuCommand.class); pico.addComponent(ListEventsMenuCommand.class); pico.addComponent(ExitMenuCommand.class); - pico.addComponent(BuyMenuCommand.class); + pico.addComponent(PlaceOrderMenuCommand.class); pico.addComponent(SettleEventMenuCommand.class); pico.addComponent(EventDetailsMenuCommand.class); pico.addComponent(LoadMarketStateMenuCommand.class); diff --git a/ui-console/src/main/java/market/guess/ui/console/command/BuyMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/BuyMenuCommand.java deleted file mode 100644 index bee2351..0000000 --- a/ui-console/src/main/java/market/guess/ui/console/command/BuyMenuCommand.java +++ /dev/null @@ -1,77 +0,0 @@ -package market.guess.ui.console.command; - -import java.math.BigDecimal; -import market.guess.api.CatalogContext; -import market.guess.api.GuessMarketContext; -import market.guess.model.event.EventStatus; -import market.guess.ui.console.io.InputProcessor; - -public final class BuyMenuCommand implements MenuCommand { - private final GuessMarketContext context; - private final CatalogContext catalog; - private final InputProcessor io; - - public BuyMenuCommand(GuessMarketContext context, CatalogContext catalog, InputProcessor io) { - super(); - this.context = context; - this.catalog = catalog; - this.io = io; - } - - @Override - public int getIndex() { - return 4; - } - - @Override - public String getName() { - return "Buy share(s) in an event"; - } - - @Override - public void execute() { - var result = catalog.getAllEvents(); - - if (!result.isSuccess()) { - io.println("Failed to list events"); - return; - } - - var events = result.getData(); - var active = events.stream().filter(event -> event.status() == EventStatus.ACTIVE).toList(); - - if (active.isEmpty()) { - io.println("There are currently no active events to trade on."); - return; - } - - var pick = io.readSelect("Pick an event: ", active, event -> "%s".formatted(event.name())); - - var result2 = catalog.getEvent(pick.key()); - var event = result2.getData(); - if (event == null) { - io.println("That event is no longer available."); - return; - } - - io.printState(event.state()); - - var market = - io.readSelect( - "Choose a market: ", - event.state().markets(), - o -> "%s [value %s, %s shares helds]".formatted(o.name(), o.price(), o.volume())); - - var amount = io.readInt("How many shares? ", 1, Integer.MAX_VALUE); - - var buyResult = - context.placeOrder( - "Tester", event.summary().key(), market.key(), new BigDecimal(market.price()), amount); - if (buyResult.isSuccess()) { - io.printReceipt(buyResult.getData()); - return; - } - io.newLine(); - io.println("Purchase declined: %s".formatted(buyResult.getMessage())); - } -} diff --git a/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java index 024f1f7..11ec478 100644 --- a/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java +++ b/ui-console/src/main/java/market/guess/ui/console/command/LoadFileMenuCommand.java @@ -35,6 +35,6 @@ public final class LoadFileMenuCommand implements MenuCommand { return; } - io.println("The file was not loaded, %s ".formatted(result.getMessage())); + io.println("The file was not loaded, %s ".formatted(result.getDetails())); } } diff --git a/ui-console/src/main/java/market/guess/ui/console/command/PlaceOrderMenuCommand.java b/ui-console/src/main/java/market/guess/ui/console/command/PlaceOrderMenuCommand.java new file mode 100644 index 0000000..6c2e674 --- /dev/null +++ b/ui-console/src/main/java/market/guess/ui/console/command/PlaceOrderMenuCommand.java @@ -0,0 +1,78 @@ +package market.guess.ui.console.command; + +import java.math.BigDecimal; +import market.guess.api.CatalogContext; +import market.guess.api.GuessMarketContext; +import market.guess.model.event.EventStatus; +import market.guess.ui.console.io.InputProcessor; + +public final class PlaceOrderMenuCommand implements MenuCommand { + private final GuessMarketContext context; + private final CatalogContext catalog; + private final InputProcessor io; + + public PlaceOrderMenuCommand( + GuessMarketContext context, CatalogContext catalog, InputProcessor io) { + super(); + this.context = context; + this.catalog = catalog; + this.io = io; + } + + @Override + public int getIndex() { + return 4; + } + + @Override + public String getName() { + return "Create a but order on an event"; + } + + @Override + public void execute() { + var result = catalog.getAllEvents(); + + if (!result.isSuccess()) { + io.println("Failed to list events"); + return; + } + + var events = result.getData(); + var active = events.stream().filter(event -> event.status() == EventStatus.ACTIVE).toList(); + + if (active.isEmpty()) { + io.println("There are currently no active events to trade on."); + return; + } + + var pick = io.readSelect("Pick an event: ", active, event -> "%s".formatted(event.name())); + + var result2 = catalog.getEvent(pick.key()); + var event = result2.getData(); + if (event == null) { + io.println("That event is no longer available."); + return; + } + + io.printState(event.state()); + + var market = + io.readSelect( + "Choose a market: ", + event.state().markets(), + o -> "%s [value %s, %s shares helds]".formatted(o.name(), o.price(), o.volume())); + + var amount = io.readInt("How many shares? ", 1, Integer.MAX_VALUE); + + var buyResult = + context.placeOrder( + "Tester", event.summary().key(), market.key(), new BigDecimal(market.price()), amount); + if (buyResult.isSuccess()) { + io.printReceipt(buyResult.getData()); + return; + } + io.newLine(); + io.println("Purchase declined: %s".formatted(buyResult.getMessage())); + } +} -- cgit v1.2.3