Skip to content
Tomer Naydnov
← All workEARLIER ENGINEERING / SOURCE STUDY

THE RULES BEHIND THE SOFTWARE

Trading System

A multi-store marketplace with delegated permissions, composable basket rules and checkout recovery.

ENGINEERING / EXPLAINED

WHO CAN ACT?

Creator→Owner→Manager
Revoking an owner also revokes their descendant appointments.

WHICH RULES APPLY?

ProductAND / ORCategory→Basket policy
Discounts compose separately with MAX or PLUS.

WHAT IF A STEP FAILS?

01Reserve02Payment03Supply04Orders
↶ Compensating cancellation after a failed external step

Code-native explanation of the implementation. Illustrative data.

CONTEXT
University coursework
MY ROLE
Developer · domain modeling & application architecture
TIMELINE
May 2024 - Jul 2024
EVIDENCE
Source reviewed · illustrative diagrams

AT A GLANCE

The rules behind a purchase

A purchase crosses several kinds of rules: who may manage a store, which baskets are allowed, how discounts combine, and what happens if payment or supply fails. I built this university Java project around explicit domain objects and service contracts for those boundaries.

My contribution +

I developed marketplace behavior from the university specification, working across permissions, purchase rules, checkout and application integration.

WHAT THE SYSTEM HANDLES

The interesting parts.

01

Browse and buy across stores

Guests and registered subscribers search a shared marketplace and keep one cart containing separate store baskets.

Implementation details
  • Search combines exact case-insensitive product-name matches with category matches across active stores.
  • The storefront offers an inclusive minimum/maximum price filter; store pages expose product details and add-to-cart actions.
  • Cart quantities are validated, zero removes an item, and successful checkout groups the resulting order records by store.
02

Delegate authority, then revoke its consequences

A store creator can nominate owners; owners and creators can send manager nominations with selected permissions. The nominee responds through the message center.

Implementation details
  • Owner and manager nominations are explicit messages with accept/decline responses, rather than an immediate role dropdown update.
  • Eight named permissions cover inventory, discounts/policies, manager permissions, history, products, staff information and subscription removal; enforcement differs by operation.
  • The store keeps forward and reverse nomination relationships. Ownership withdrawal walks the nomination graph and removes the owner and descendant appointments.
  • Only the creator can close or reopen a store; staff receive corresponding messages and live notifications.
03

Compose purchase rules and discounts

Store managers with the relevant permission can build rules around product quantities, categories and basket price, then combine them into larger expressions.

Implementation details
  • Simple conditions evaluate product/category quantities or basket value against minimum and maximum bounds.
  • AND, OR and XOR conditions combine two existing conditions; a conditional policy class implements implication.
  • Percentage discounts apply to a product, category or basket. MAX chooses the larger discount; PLUS adds two discounts.
  • Recursive DTOs and nested policy/discount boxes let the Vaadin interface display the resulting expression structure. The visible Exactly option is not actually enforced by SimpleCondition and is excluded from the verified feature claim.
04

Treat checkout failure as part of the workflow

The domain reserves stock before purchase, validates store policies and coordinates payment with supply adapters. Failure paths restore stock and attempt compensating cancellations.

Implementation details
  • Per-inventory synchronized reservation reduces available quantities and tracks reserved quantities separately.
  • A later store failure triggers release of earlier store reservations; policy rejection releases that store reservation.
  • Payment and supply have separate handshake, action and cancellation interfaces. Supply failure attempts cancellation of the completed payment and any earlier supply transactions.
  • Source tests use mocks to assert two store-specific orders after success and restored stock/no orders after payment or supply failure. No fresh passing-test or live-provider claim is made.
  • Purchase history, read/unread messages, targeted Vaadin push notifications and dated account suspension support the surrounding operations.

STRUCTURE & JUDGMENT

How the parts fit.

Vaadin views + presenters

Storefront, store management, cart, messages and administration

→ Application services

Application services

UserService / StoreService / OrderService / AdminService

→ Marketplace domain / Payment + supply interfaces / BCrypt + JWT helpers

Marketplace domain

Facades, role graph, inventory reservation and composite rules

→ In-memory repositories / Targeted notification broadcaster

In-memory repositories

Users, active/deactivated stores, orders and suspensions

Payment + supply interfaces

HTTP adapters and local validating stand-ins; mocks in tests

Targeted notification broadcaster

One registered listener per username; Vaadin @Push

→ Vaadin views + presenters

BCrypt + JWT helpers

Service-level identity checks, with documented deployment gaps

  • Java 17
  • Spring Boot 3.3.1
  • Vaadin 24.3 / server-driven UI
  • In-memory domain repositories
  • BCrypt + JJWT
  • Vaadin Push
  • Maven
  • JUnit 4 / JUnit 5
  • Mockito

Represent delegated authority as a graph

Store records nominationGraph and reverseNominationMap alongside per-store subscriber states and manager permissions. waiveOwnership performs a breadth-first traversal and removes all collected appointments.

WHY IT MATTERSRevocation has consequences beyond the selected person. Explicit relationships make that cascade visible through a common domain rule. This benefit is inferred from the code, not an author quotation. The graph, role map, permission map and user-facing store-role map must remain consistent. The audit found stale graph-link and declined-nomination bookkeeping edges; this is a modeling decision, not proof of complete authorization correctness.

Build policy expressions from reusable components

Condition and Discount interfaces have simple and composite implementations. Store composition methods replace two top-level components with a composite; recursive DTO conversion feeds nested UI boxes.

WHY IT MATTERSProduct-specific requirements can be expressed using the same evaluation machinery instead of one bespoke checkout branch per promotion. The structure also gives the UI something concrete to explain. Expression semantics, labels and numeric edge cases must agree. Exact-value and conditional-policy wording gaps are documented; no claim of a complete production promotion engine.

Separate external actions and make compensation explicit

OrderService depends on PaymentGateway and SupplySystem interfaces. It checks availability, performs payment, requests supply, records per-store orders, and attempts payment/supply cancellation on a later supply failure. Unit tests substitute Mockito adapters and inspect inventory and order state.

WHY IT MATTERSThe interesting boundary is what happens after the first external step succeeds and the next fails. The implementation addresses that path directly. This is best-effort compensation, not an atomic distributed transaction: cancellation return values are ignored, no durable retry/outbox is present, and the current application startup does not wire the adapters. The test-injected domain path and deployable checkout are separate evidence levels.

Scope, limitations & what I would revisit

  • Source-only audit at the pinned revision. No application startup, current build/test result, deployed usage, real transaction or performance measurement was demonstrated.
  • Runtime user, store, order and admin repositories are in-memory collections. JPA annotations and H2/MySQL dependencies exist, but UserRepository implements JpaRepository with empty/null/no-op methods, and facades instantiate these repositories directly. Do not claim durable MySQL storage.
  • Payment and supply adapters are implemented, but the current Spring startup does not populate OrderService.paymentGateway/supplySystem. The only source calls to their setters are in tests. The JSON initialization utility constructs a separate service graph and does not install its parsed adapters either. Do not present current default startup as working end-to-end checkout.
  • The payment page parses its total from a URL parameter and OrderService accepts the supplied purchasePrice without recomputing it from a trusted reservation. External cancellation results are ignored, and HttpUtils has no configured connection/read timeout. This is an academic integration design, not production payment integrity or durable transaction recovery.
  • Security is partial: BCrypt registration and signed expiring JWTs are real, but Spring HTTP security permits all paths and disables CSRF. JWT validation checks the signature, expiry and subject without consulting current login/token state; logout clears stored state but does not revoke an issued token. Cookies are explicitly non-Secure. Avoid production-secure authentication claims.
  • Several presenters are ordinary singleton Spring components holding mutable view, product-list, total or store fields, and MessagesList keeps a static message list. The source does not establish isolated simultaneous user interfaces. The broadcaster also retains one listener per username, with no stored/removable registration in MainLayoutView.
  • Policy and reservation edges remain: SimpleCondition ignores its exact amount field, PolicyCondition text reverses its implemented implication, conditional discounts return an error when their condition is false, and reservation expiry is scheduled for 60 minutes despite its 10-minute message. These prevent claiming every visible rule or timing guarantee works as labeled.
  • The repository contains substantial unit, acceptance and parallel-test source, but presence is not a passing result or concurrency guarantee. One parallel purchase test submits mismatched username/token pairs and accepts zero successful reservations, and some test files are entirely commented out.