| 3 | | The prototype is a Go command-line application in `server/` that works against |
| 4 | | the `project` schema in PostgreSQL. It implements all seven use cases from |
| 5 | | [UseCaseModel](../P3-UseCaseModel/UseCaseModel.md) — the rubric requires at least three — with |
| 6 | | every database access shown as real, executed SQL. An auxiliary program in |
| 7 | | `bots/` simulates a live market so prices move while the prototype is running. |
| | 3 | The prototype is a Go command-line application in |
| | 4 | [https://github.com/StefanTrsunov/bp/tree/main/server server/] that works against the `project` |
| | 5 | schema in PostgreSQL. It implements all seven use cases from |
| | 6 | [https://github.com/StefanTrsunov/bp/blob/main/docs/P3-UseCaseModel/UseCaseModel.md UseCaseModel] |
| | 7 | – the rubric requires at least three – with every database access shown as real, executed SQL. |
| | 8 | An auxiliary program in [https://github.com/StefanTrsunov/bp/tree/main/bots bots/] simulates a |
| | 9 | live market so prices move while the prototype is running. |
| 13 | | || Page || Use-case || Source || |
| 14 | | || [UseCase0001Implementation](UseCase0001Implementation.md) || Register a new account || `server/auth.go` || |
| 15 | | || [UseCase0002Implementation](UseCase0002Implementation.md) || Log in || `server/auth.go` || |
| 16 | | || [UseCase0003Implementation](UseCase0003Implementation.md) || Deposit virtual funds || `server/account.go` || |
| 17 | | || [UseCase0004Implementation](UseCase0004Implementation.md) || Place market BUY order || `server/trade.go` || |
| 18 | | || [UseCase0005Implementation](UseCase0005Implementation.md) || Place market SELL order || `server/trade.go` || |
| 19 | | || [UseCase0006Implementation](UseCase0006Implementation.md) || View portfolio and history || `server/portfolio.go` || |
| 20 | | || [UseCase0007Implementation](UseCase0007Implementation.md) || Manage watchlist || `server/watchlist.go` || |
| | 18 | == Implemented use-cases == |
| 22 | | Each page mirrors its P3 use-case page and adds the actual SQL emitted by the Go |
| 23 | | code plus a screenshot of the corresponding run against the live database. |
| | 20 | ||=Page=||=Use-case=||=Source=|| |
| | 21 | ||[https://github.com/StefanTrsunov/bp/blob/main/docs/P4-Prototype/UseCase0001Implementation.md UseCase0001Implementation]||Register a new account||[https://github.com/StefanTrsunov/bp/blob/main/server/auth.go server/auth.go]|| |
| | 22 | ||[https://github.com/StefanTrsunov/bp/blob/main/docs/P4-Prototype/UseCase0002Implementation.md UseCase0002Implementation]||Log in||[https://github.com/StefanTrsunov/bp/blob/main/server/auth.go server/auth.go]|| |
| | 23 | ||[https://github.com/StefanTrsunov/bp/blob/main/docs/P4-Prototype/UseCase0003Implementation.md UseCase0003Implementation]||Deposit virtual funds||[https://github.com/StefanTrsunov/bp/blob/main/server/account.go server/account.go]|| |
| | 24 | ||[https://github.com/StefanTrsunov/bp/blob/main/docs/P4-Prototype/UseCase0004Implementation.md UseCase0004Implementation]||Place market BUY order||[https://github.com/StefanTrsunov/bp/blob/main/server/trade.go server/trade.go]|| |
| | 25 | ||[https://github.com/StefanTrsunov/bp/blob/main/docs/P4-Prototype/UseCase0005Implementation.md UseCase0005Implementation]||Place market SELL order||[https://github.com/StefanTrsunov/bp/blob/main/server/trade.go server/trade.go]|| |
| | 26 | ||[https://github.com/StefanTrsunov/bp/blob/main/docs/P4-Prototype/UseCase0006Implementation.md UseCase0006Implementation]||View portfolio and history||[https://github.com/StefanTrsunov/bp/blob/main/server/portfolio.go server/portfolio.go]|| |
| | 27 | ||[https://github.com/StefanTrsunov/bp/blob/main/docs/P4-Prototype/UseCase0007Implementation.md UseCase0007Implementation]||Manage watchlist||[https://github.com/StefanTrsunov/bp/blob/main/server/watchlist.go server/watchlist.go]|| |
| 27 | | - **The current price is never stored as a column.** It is always the price of |
| 28 | | the most recent row in `market_trades`, read through the `v_latest_prices` |
| 29 | | view. Both the user's own fills and the bot's simulated trades feed the same |
| 30 | | table, so there is exactly one definition of "the price". |
| 31 | | - **Money movements are transactional.** Buying touches five tables — `orders`, |
| 32 | | `users`, `holdings`, `transactions`, `market_trades` — inside one transaction. |
| 33 | | A failed balance check rolls the whole thing back: after a rejected purchase |
| 34 | | there is no order row, no ledger entry and no holding. This is verified in the |
| 35 | | failure-path tests in [BuildInstructions](BuildInstructions.md). |
| 36 | | - **Constraints do real work.** `UNIQUE (user_id, crypto_id)` on `holdings` is |
| 37 | | what makes the `INSERT … ON CONFLICT DO UPDATE` upsert possible, so the |
| 38 | | weighted-average entry price is recomputed by the database in one statement |
| 39 | | instead of by a read-modify-write in application code. |
| 40 | | - **No identifiers are ever typed.** Markets are listed with their prices before |
| 41 | | any choice is made, and everything else is selected by symbol. |
| | 34 | == What the prototype demonstrates about the database design == |
| 43 | | == Known limitations |
| | 36 | * '''The current price is never stored as a column.''' It is always the price of the most recent |
| | 37 | row in `market_trades`, read through the `v_latest_prices` view. Both the user's own fills and |
| | 38 | the bot's simulated trades feed the same table, so there is exactly one definition of "the |
| | 39 | price". |
| | 40 | * '''Money movements are transactional.''' Buying touches five tables – `orders`, `users`, |
| | 41 | `holdings`, `transactions`, `market_trades` – inside one transaction. A failed balance check |
| | 42 | rolls the whole thing back: after a rejected purchase there is no order row, no ledger entry |
| | 43 | and no holding. This is verified in the failure-path tests in |
| | 44 | [https://github.com/StefanTrsunov/bp/blob/main/docs/P4-Prototype/BuildInstructions.md BuildInstructions]. |
| | 45 | * '''Constraints do real work.''' `UNIQUE (user_id, crypto_id)` on `holdings` is what makes the |
| | 46 | `INSERT … ON CONFLICT DO UPDATE` upsert possible, so the weighted-average entry price is |
| | 47 | recomputed by the database in one statement instead of by a read-modify-write in application |
| | 48 | code. |
| | 49 | * '''No identifiers are ever typed.''' Markets are listed with their prices before any choice is |
| | 50 | made, and everything else is selected by symbol. |
| 48 | | - Only `market` orders execute. `limit` is accepted by the schema |
| 49 | | (`orders.type`) but the matching logic is not implemented. |
| 50 | | - Passwords are SHA-256 without a salt. Adequate to demonstrate that the |
| 51 | | password itself is never stored; not adequate for real use. A proper |
| 52 | | password hash belongs in P9 (security). |
| 53 | | - Money is handled as `float64` in Go while the database columns are `numeric`. |
| 54 | | All arithmetic that must be exact — the weighted average — is done in SQL for |
| 55 | | that reason, but the Go side would need a decimal type for real use. |
| 56 | | - There is no connection pooling configuration and no explicit isolation level; |
| 57 | | both are P8 topics. |
| | 54 | Deliberately out of scope for a first prototype, and the natural content of the later phases: |
| | 55 | |
| | 56 | * Only `market` orders execute. `limit` is accepted by the schema (`orders.type`) but the |
| | 57 | matching logic is not implemented. |
| | 58 | * Passwords are SHA-256 without a salt. Adequate to demonstrate that the password itself is |
| | 59 | never stored; not adequate for real use. A proper password hash belongs in P9 (security). |
| | 60 | * Money is handled as `float64` in Go while the database columns are `numeric`. All arithmetic |
| | 61 | that must be exact – the weighted average – is done in SQL for that reason, but the Go side |
| | 62 | would need a decimal type for real use. |
| | 63 | * There is no connection pooling configuration and no explicit isolation level; both are P8 |
| | 64 | topics. |