source: docs/P4-Prototype/PrototypeImplementation.md@ 8b447ef

main
Last change on this file since 8b447ef was 9577c79, checked in by Stefan <trsunovstefan@…>, 13 days ago

add reserved_quantity and modify the phases, add v_03.png and v_03.xml for P1

  • Property mode set to 100644
File size: 8.0 KB
Line 
1= Prototype Implementation =
2
3The prototype is a Go command-line application in
4[https://github.com/StefanTrsunov/bp/tree/main/server server/] that works against the `project`
5schema 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.
8An auxiliary program in [https://github.com/StefanTrsunov/bp/tree/main/bots bots/] simulates a
9live market so prices move while the prototype is running.
10
11Build, configure, run and test instructions:
12[https://github.com/StefanTrsunov/bp/blob/main/docs/P4-Prototype/BuildInstructions.md BuildInstructions].
13
14All pages listed below, together with the screenshots of each run, are kept in the project's
15GitHub repository, [https://github.com/StefanTrsunov/bp StefanTrsunov/bp], under
16`docs/P4-Prototype/`.
17
18== Implemented use-cases ==
19
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]||
28
29Each page mirrors its P3 use-case page and adds the actual SQL emitted by the Go code plus a
30screenshot of the corresponding run against the live database. The screenshots are committed
31alongside the pages, in
32[https://github.com/StefanTrsunov/bp/tree/main/docs/P4-Prototype/screenshots docs/P4-Prototype/screenshots/].
33
34== What the prototype demonstrates about the database design ==
35
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. `CHECK (reserved_quantity >= 0 AND reserved_quantity <= quantity)` is the same idea
49 applied to the sell path: an inconsistent reservation is impossible at the database level, not
50 just something `trade.go` is careful about.
51 * '''Selling reserves before it removes.''' A sell order locks the holding row, reserves the
52 quantity being sold, then settles by removing it — see
53 [UseCase0005Implementation](UseCase0005Implementation.md). Two sell orders placed at the same
54 instant for more than the available quantity are serialised correctly by `SELECT ... FOR
55 UPDATE`, not just by luck of everything happening in one CLI process; this is demonstrated
56 there with two concurrent processes.
57 * '''No identifiers are ever typed.''' Markets are listed with their prices before any choice is
58 made, and everything else is selected by symbol.
59
60== Known limitations ==
61
62Deliberately out of scope for a first prototype, and the natural content of the later phases:
63
64 * Only `market` orders execute. `limit` is accepted by the schema (`orders.type`) but the
65 matching logic is not implemented.
66 * Passwords are SHA-256 without a salt. Adequate to demonstrate that the password itself is
67 never stored; not adequate for real use. A proper password hash belongs in P9 (security).
68 * Money is handled as `float64` in Go while the database columns are `numeric`. All arithmetic
69 that must be exact – the weighted average – is done in SQL for that reason, but the Go side
70 would need a decimal type for real use.
71 * There is no connection pooling configuration and no explicit isolation level; both are P8
72 topics.
73 * Reservation only ever lives inside one transaction, because only market orders (which settle
74 immediately) exist. A real limit-order matcher would leave `holdings.reserved_quantity` set
75 and `orders.status = 'open'` between two separate commits, and would need a way to cancel an
76 order to release the reservation — neither is implemented, since nothing in the prototype
77 produces an order that stays open.
78
79== AI usage ==
80
81AI was used in this phase and is logged in full, per the course rule for P1 onward.
82
83 * '''Phase log:'''
84 [https://github.com/StefanTrsunov/bp/blob/main/docs/P4-Prototype/PrototypeImplementationAIUsage.md PrototypeImplementationAIUsage.md]
85 – service used, the bugs found and fixed, the test evidence, and what I decided myself.
86 * '''Full conversation transcript:'''
87 [https://github.com/StefanTrsunov/bp/blob/main/docs/P1-ConceptualModel/ERModelAIUsage.md ERModelAIUsage.md]
88 – the same conversation produced the P1–P4 artefacts, so the complete prompt/response log is
89 kept in one place. Direct links:
90 [https://github.com/StefanTrsunov/bp/blob/main/docs/P1-ConceptualModel/ERModelAIUsage.md#session-1--2026-04-21 Session 1 – 2026-04-21],
91 [https://github.com/StefanTrsunov/bp/blob/main/docs/P1-ConceptualModel/ERModelAIUsage.md#session-2--2026-08-06--2026-08-07 Session 2 – 2026-08-06/07],
92 [https://github.com/StefanTrsunov/bp/blob/main/docs/P1-ConceptualModel/ERModelAIUsage.md#session-3--2026-09-16 Session 3 – 2026-09-16].
93
94'''Service:''' Claude Code (Anthropic), https://claude.com/claude-code – Claude subscription,
95model Claude Opus 4.7 (1M context) in sessions 1–2, Claude Sonnet 5 in session 3.
96
97'''In short:''' session 1 rewrote the existing Chi/HTTP backend as the CLI prototype covering
98UC0001–UC0007 and added the market bot. Session 2 was a review pass I asked for, which found and
99fixed three bugs – a path-resolution bug that made the documented build instructions fail, an
100infinite loop at end of input, and an error check in the wrong order that misreported database
101failures as "Insufficient holding" – and replaced the read-modify-write holding update with a
102single `INSERT … ON CONFLICT DO UPDATE`. Session 3 added `holdings.reserved_quantity` and changed
103`trade.go`'s sell path to reserve crypto before removing it, closing a gap where two sell orders
104could be granted the same units; see
105[PrototypeImplementationAIUsage](PrototypeImplementationAIUsage.md#session-3--2026-09-16).
Note: See TracBrowser for help on using the repository browser.