Nexus-Engine/
├── docker-compose.yml # Profili: csharp, frontend
├── Makefile # up-csharp, down, db-shell, logs-csharp
├── AGENTS.md # Guida per agent AI
├── .gitignore
├── Phase1.md / Phase2.md / Phase3.md / Phase4.md
├── project-structure.md # Questo file
├── README.md
├── nexus_e2e_test.py # Test E2E Selenium (Edge headless)
│
├── backend-csharp/ # ▲ C# ASP.NET Core 9 — Clean Architecture
│ ├── Program.cs # Punto d'ingresso + DI composition root
│ ├── NexusEngine.Api.csproj
│ ├── Dockerfile / .dockerignore
│ ├── appsettings.json
│ ├── appsettings.Development.json
│ ├── NexusEngine.Api.http
│ ├── Properties/
│ │ └── launchSettings.json
│ │
│ ├── Controllers/ # 🟢 Presentation Layer
│ │ ├── AccountsController.cs # POST/GET /api/accounts, deposit, replay
│ │ └── OrdersController.cs # POST/GET/DELETE /api/orders
│ │
│ ├── Hubs/ # 🆕 SignalR (Phase 4)
│ │ └── NexusHub.cs # Endpoint /hubs/nexus
│ │
│ ├── Application/ # 🔵 Application Layer (CQRS)
│ │ ├── Abstractions/
│ │ │ ├── INexusUnitOfWork.cs # Contratto UoW (DbSet<Account, Order, ...>)
│ │ │ └── IOrderBookService.cs # Contratto Order Book in-memory
│ │ │
│ │ ├── Common/
│ │ │ └── OptimisticConcurrencyHelper.cs # Rilevamento errore Postgres 23505
│ │ │
│ │ ├── Accounts/
│ │ │ ├── Commands/
│ │ │ │ ├── CreateAccount/
│ │ │ │ │ ├── CreateAccountCommand.cs
│ │ │ │ │ └── CreateAccountHandler.cs
│ │ │ │ └── DepositFunds/
│ │ │ │ ├── DepositFundsCommand.cs
│ │ │ │ └── DepositFundsHandler.cs # Retry ottimistico (max 3)
│ │ │ └── Queries/
│ │ │ ├── GetAccount/
│ │ │ │ ├── GetAccountQuery.cs
│ │ │ │ └── GetAccountHandler.cs # Inline AccountDto
│ │ │ └── ReplayAccount/
│ │ │ ├── ReplayAccountQuery.cs
│ │ │ └── ReplayAccountHandler.cs # Inline ReplayAccountDto
│ │ │
│ │ └── Orders/
│ │ ├── Commands/
│ │ │ ├── PlaceOrder/
│ │ │ │ ├── PlaceOrderCommand.cs
│ │ │ │ └── PlaceOrderHandler.cs # Matching engine + retry + notifiche
│ │ │ └── CancelOrder/
│ │ │ ├── CancelOrderCommand.cs
│ │ │ └── CancelOrderHandler.cs # Rimuove da OrderBook
│ │ ├── Queries/
│ │ │ └── GetOrders/
│ │ │ ├── GetOrdersQuery.cs
│ │ │ ├── GetOrdersHandler.cs
│ │ │ └── OrderDto.cs
│ │ ├── Validation/
│ │ │ ├── IOrderValidationStrategy.cs # Interfaccia Strategy
│ │ │ ├── AccountExistsValidation.cs # 1°: null check
│ │ │ ├── AccountActiveValidation.cs # 2°: status check
│ │ │ └── SufficientBalanceValidation.cs # 3°: saldo check
│ │ └── Notifications/ # 🆕 MediatR notifications (Phase 4)
│ │ ├── TradeExecutedNotification.cs
│ │ ├── OrderBookChangedNotification.cs
│ │ └── BalanceChangedNotification.cs
│ │
│ ├── Domain/ # 🟡 Domain Layer (entità pure)
│ │ ├── Entities/
│ │ │ ├── Account.cs # balance, reserved_balance, status
│ │ │ ├── DomainEvent.cs # Append-only event store
│ │ │ ├── IdempotencyKey.cs # Chiave idempotenza
│ │ │ ├── Order.cs # Proiezione ordine
│ │ │ └── Transaction.cs # Ledger contabile
│ │ └── OrderBook/ # Matching Engine (dominio puro)
│ │ ├── Trade.cs # Record trade eseguito
│ │ ├── MatchResult.cs # Risultato match (trades + ordini residuali)
│ │ └── OrderBook.cs # Engine: price-time priority FIFO
│ │
│ ├── Infrastructure/ # 🟣 Infrastructure Layer
│ │ ├── Idempotency/
│ │ │ └── IdempotencyFilter.cs # Action Filter (X-Idempotency-Key)
│ │ ├── OrderBook/
│ │ │ ├── OrderBookService.cs # Singleton thread-safe con lock
│ │ │ └── OrderBookRecoveryService.cs # IHostedService: ricarica ordini all'avvio
│ │ ├── Notifications/ # 🆕 Handlers SignalR (Phase 4)
│ │ │ ├── TradeExecutedNotificationHandler.cs
│ │ │ ├── OrderBookChangedNotificationHandler.cs
│ │ │ └── BalanceChangedNotificationHandler.cs
│ │ ├── Persistence/
│ │ │ ├── NexusDbContext.cs # EF Core DbContext
│ │ │ ├── NexusUnitOfWork.cs # Implementazione UoW
│ │ │ └── Configurations/ # Fluent API (snake_case)
│ │ │ ├── AccountConfiguration.cs
│ │ │ ├── DomainEventConfiguration.cs
│ │ │ ├── IdempotencyKeyConfiguration.cs
│ │ │ ├── OrderConfiguration.cs
│ │ │ └── TransactionConfiguration.cs
│ │ └── Migrations/ # 4 migration EF Core
│ │ ├── 20260516202232_InitialSchema.cs (+ .Designer)
│ │ ├── 20260517115412_AddAccountBalanceConstraints.cs (+ .Designer)
│ │ ├── 20260525074915_AddOrderSymbolAndRemainingQuantity.cs (+ .Designer)
│ │ ├── 20260525075743_FixOrderColumnNames.cs (+ .Designer)
│ │ └── NexusDbContextModelSnapshot.cs
│ │
│ └── bin/ / obj/
│
├── backend-csharp.Tests/ # 🧪 Progetto test xUnit
│ ├── NexusEngine.Tests.csproj
│ ├── Domain/
│ │ └── OrderBook/
│ │ └── OrderBookTests.cs # 12 test: match, add, remove, FIFO, rifiuto
│ └── Application/ # 🆕 Test handler notifiche (Phase 4)
│ └── Notifications/
│ └── NotificationHandlerTests.cs # 8 test: TradeExecuted, OrderBookChanged, BalanceChanged
│
└── frontend/ # Vite 8 + React (TypeScript strict)
├── Dockerfile
├── nginx.conf
├── package.json
├── vite.config.ts
├── tsconfig.json / tsconfig.app.json / tsconfig.node.json
├── eslint.config.js
├── index.html
├── public/
│ ├── favicon.svg
│ └── icons.svg
├── node_modules/
└── src/
├── main.tsx
├── index.css # CSS variables dark theme
├── App.tsx
├── App.css
├── api/ # 🆕 API layer (Phase 4)
│ └── nexusApi.ts # createAccount, deposit, placeOrder, etc.
├── components/ # 🆕 Componenti dashboard (Phase 4)
│ └── NexusDashboard.tsx # Order book, trades, balance, forms, guide sidebar
├── hooks/ # 🆕 SignalR hook (Phase 4)
│ └── useNexusHub.ts # Connessione WebSocket, eventi trade/orderbook/balance
└── assets/
├── hero.png
├── react.svg
└── vite.svg