| 14 | | During the 2026-04-21 session the AI: |
| 15 | | |
| 16 | | * Replaced the broken HTTP + frontend scaffolding (which the student had already decided to drop) with a single-binary CLI prototype in Go, split across `main.go`, `cli.go`, `auth.go`, `account.go`, `market.go`, `trade.go`, `portfolio.go`, `watchlist.go`. |
| 17 | | * Consolidated the broken `db.go` — which used to drop every table on every startup — into a single `Connect()` plus explicit `-init` and `-load-data` flags. |
| 18 | | * Moved `go.mod` from `server/` to the project root so the same module graph covers both `server/` and `bots/`. |
| 19 | | * Fixed `go.mod`: removed the unused MySQL driver, promoted `github.com/lib/pq` to a direct dependency. |
| 20 | | * Implemented the trade flows as real database transactions with row-level `FOR UPDATE` locks, cost-basis bookkeeping, and a ledger row per operation. |
| 21 | | * Wrote a 140-line market-simulation bot that inserts trades and upserts 1-minute candles every tick. |
| 22 | | * Exercised the full prototype end-to-end against a running PostgreSQL on port 5433 and verified a sample buy and portfolio view produced the expected numbers. |
| | 25 | '''My own starting code (before any AI was used).''' Before session 1 I had written: |
| | 26 | |
| | 27 | * a Go backend with HTTP handlers (Chi router); |
| | 28 | * a draft database schema (`server/db/db.sql`, `server/db/schema.sql`) and a diagram description |
| | 29 | (`docs/dbdiagram.md`), based on my data model in `ep-diagram.md`; |
| | 30 | * a `main.go` / `db.go` that connected to PostgreSQL and dropped and recreated every table on |
| | 31 | each start; |
| | 32 | * a half-finished frontend, which I deleted myself at the start of session 1 because the |
| | 33 | prototype does not need it. |
| | 34 | |
| | 35 | This code is older than the git repository. The first commit (2026-08-07) was made after |
| | 36 | sessions 1 and 2, so the history in git starts from the AI-improved version. My original files |
| | 37 | are not in the repository. What they contained, and which errors the AI found in them, is |
| | 38 | recorded in the session 1 log below and in [wiki:ERModelAIUsage]. |
| | 39 | |
| | 40 | '''Session 1 (2026-04-21).''' Starting from that code, the AI: |
| | 41 | |
| | 42 | * replaced my HTTP backend and the frontend scaffolding with a single-binary CLI prototype in Go, |
| | 43 | split across `main.go`, `cli.go`, `auth.go`, `account.go`, `market.go`, `trade.go`, |
| | 44 | `portfolio.go` and `watchlist.go`. This followed my decision to make a CLI and not a web app; |
| | 45 | * corrected my schema. `crypto_id` had been declared as a foreign key to two tables at once in |
| | 46 | `holdings`, `orders` and `transactions`, and `market_candles` referenced a `markets` table that |
| | 47 | did not exist. The corrected schema became `schema_creation.sql`, with the sample data in |
| | 48 | `data_load.sql`; |
| | 49 | * replaced my `db.go`, which dropped every table on every start, with one `Connect()` plus |
| | 50 | explicit `-init` and `-load-data` flags; |
| | 51 | * moved `go.mod` to the project root, removed an unused MySQL driver, and made |
| | 52 | `github.com/lib/pq` a direct dependency; |
| | 53 | * wrote the trade flows as database transactions with `FOR UPDATE` row locks, cost-basis |
| | 54 | bookkeeping and one ledger row per operation; |
| | 55 | * wrote the market-simulation bot (`bots/main.go`), after I decided to keep a market simulator |
| | 56 | in the project. |
| | 57 | |
| | 58 | '''Session 2 (2026-08-06/07).''' I asked for a code review. The AI found and fixed three bugs |
| | 59 | (`.env`/SQL path resolution, an endless loop at end of input, and a wrong error check on the |
| | 60 | sell path). It also replaced the read-modify-write holding update with one |
| | 61 | `INSERT … ON CONFLICT DO UPDATE`, removed the committed `TerraER3.11.jar` and a !TradingView |
| | 62 | screenshot we had no licence for, and wrote the first version of the P4 pages. |
| | 63 | |
| | 64 | '''Session 3 (2026-09-16).''' From an edge case I described, the AI added |
| | 65 | `holdings.reserved_quantity`, made the sell path reserve and then settle, and gave |
| | 66 | `orders.status` a real `open` → `executed` lifecycle. |
| | 67 | |
| | 68 | '''Session 4 (2026-09-24).''' I asked whether P4 fulfils the course rules. The AI found that the |
| | 69 | prototype still asked the user to type a market symbol and crypto symbols, which breaks the rule |
| | 70 | that the user must never have to remember identifiers or codes. It changed every choice to a |
| | 71 | numbered list (`market.go`, `trade.go`, `watchlist.go`), retook every screenshot, one per |
| | 72 | scenario step, and rewrote the P4 pages. |
| 41 | | ||= =||= Session 1 — 2026-04-21 =||= Session 2 — 2026-08-06/07 =||= Session 3 — 2026-09-16 =|| |
| 42 | | || '''What I brought''' || My existing Go backend (Chi HTTP handlers) and a half-finished frontend || The CLI prototype as it stood after session 1 || A design review: the sell path had no way to reserve crypto committed to an order || |
| 43 | | || '''What the AI did''' || Rewrote the backend as a CLI covering UC0001–UC0007, wrote the market bot || Reviewed the code, found and fixed three bugs, improved the holding upsert || Added `holdings.reserved_quantity`, changed the sell path to reserve-then-settle, gave `Orders.status` a real lifecycle, tested it live including under real concurrency || |
| 44 | | || '''What I decided''' || To delete the frontend, to build a CLI rather than a web app, to keep the market simulator || To ask for a code review pass rather than documentation alone || To keep reserve+settle in one transaction rather than split it across two, since there is no cancel-order use case to recover a stuck reservation || |
| 45 | | |
| 46 | | The prototype was built in session 1 and worked. What session 2 added was a |
| 47 | | review pass I asked for specifically because I have to defend this code in |
| 48 | | person: it turned up a path-resolution bug that made my own documented build |
| 49 | | instructions fail, an infinite loop at end of input, and an error check in the |
| 50 | | wrong order that misreported database failures as "Insufficient holding". |
| | 109 | ||= =||= Session 1 — 2026-04-21 =||= Session 2 — 2026-08-06/07 =||= Session 3 — 2026-09-16 =||= Session 4 — 2026-09-24 =|| |
| | 110 | || '''What I brought''' || My Go backend (Chi HTTP handlers), draft schema, a half-finished frontend || The CLI prototype as it stood after session 1 || A design review: the sell path had no way to reserve crypto committed to an order || The official P4 instructions and the question whether the prototype and pages meet them || |
| | 111 | || '''What the AI did''' || Rewrote the backend as a CLI covering UC0001–UC0007, corrected the schema, wrote the market bot || Reviewed the code, found and fixed three bugs, improved the holding upsert || Added `holdings.reserved_quantity`, reserve-then-settle sell path, `orders.status` lifecycle, tested it including real concurrency || Audited P4, made every choice a numbered list, retook all screenshots, rewrote the P4 pages || |
| | 112 | || '''What I decided''' || To delete the frontend, to build a CLI and not a web app, to keep the market simulator || To ask for a code review and not only documentation || To keep reserve and settle in one transaction, because there is no cancel-order use case to free a stuck reservation || To fix the problems found and to have the screenshots taken from real runs || |
| 54 | | See ERModelAIUsage for the full prompt/response transcript of the 2026-04-21 session — that single conversation produced all of the P1–P4 artefacts. The defining student prompt for P4 was: |
| 55 | | |
| | 116 | '''About this log.''' Sessions 3 and 4 are still in my local Claude Code history, so their |
| | 117 | prompts are quoted '''verbatim''' below, typos included. The local history of sessions 1 and 2 |
| | 118 | (April and August 2026) is no longer available. For them, the prompts are the excerpts I wrote |
| | 119 | down at the time, the same ones as on [wiki:ERModelAIUsage], |
| | 120 | where they were logged because the same conversation produced P1–P4. The AI's responses are |
| | 121 | summarised, because several ran to many pages of code and file edits. |
| | 122 | |
| | 123 | ---- |
| | 124 | |
| | 125 | === Session 1 — 2026-04-21 (Claude Opus 4.7, 1M context) === |
| | 126 | |
| | 127 | '''Prompt (student, excerpt):''' |
| | 128 | > This is my project for my exam Database, go to the docs folder and README.md there you will find all of the documentation, afterwards take a look at the whole project. Delete everything you want add everything you want just make it work and make it fill in or to follow all of the needed instructions. Ask me anything, also tell me what do I need to do |
| | 129 | |
| | 130 | '''Response (AI, summarised):''' |
| | 131 | * Read `docs/opis.md`, `docs/ep-diagram.md`, `docs/dbdiagram.md`, `server/db/db.sql`, |
| | 132 | `server/db/schema.sql` and all Go sources. |
| | 133 | * Found errors in my schema: `holdings.crypto_id` declared as a foreign key to both |
| | 134 | `users(id)` and `crypto(id)` (and the same mistake in `orders` and `transactions`), and |
| | 135 | `market_candles` referencing a non-existent `markets` table. Also found that `main.go` dropped |
| | 136 | and recreated all tables on every start, wiping the data. |
| | 137 | * Asked me to decide on team composition, prototype shape (CLI or HTTP), which columns to keep, |
| | 138 | which use cases to implement, and the documentation language. |
| | 139 | |
| | 140 | '''Prompt (student, excerpt):''' |
| | 141 | > Read it now, just filled it in, also deleted the frontend we don' need that |
| | 142 | |
| | 143 | '''Response (AI, summarised):''' |
| | 144 | * Re-read `docs/README.md`, which now contained the course rubric, and explained the AI rules |
| | 145 | per phase and the deliverables of each phase. |
| | 146 | |
| | 147 | '''Prompt (student, excerpt):''' |
| 58 | | which translated into the rewrite of the backend and the writing of this documentation. |
| 59 | | |
| 60 | | > '''Student action required:''' append any further prompts here where you asked the AI to debug, extend, or refactor the prototype. |
| 61 | | |
| 62 | | === Session 2 — 2026-08-06 / 2026-08-07 === |
| 63 | | |
| 64 | | Prompts are logged in full in ERModelAIUsage (section "Session 2 — 2026-08-06 / 2026-08-07"). |
| 65 | | The student asked the AI to complete the phase documentation and to ''"fix some |
| 66 | | database things or golang things if you think we can do it better"''. What the AI |
| 67 | | changed in the prototype, and why: |
| | 150 | '''Response (AI, summarised):''' |
| | 151 | * Rewrote the backend as the CLI prototype (UC0001–UC0007), with the corrected |
| | 152 | `schema_creation.sql`, `data_load.sql`, the new `db.go` with `-init` / `-load-data`, the |
| | 153 | transactional trade flows and the market bot. The details are under ''Results in details'' |
| | 154 | above. |
| | 155 | * Ran the prototype end to end against PostgreSQL on port 5433 and checked that a sample buy |
| | 156 | and the portfolio view gave the expected numbers. |
| | 157 | |
| | 158 | ---- |
| | 159 | |
| | 160 | === Session 2 — 2026-08-06 / 2026-08-07 (Claude Opus 5, 1M context) === |
| | 161 | |
| | 162 | '''Prompt (student, excerpt):''' |
| | 163 | > […] do all of the other Phases till m0. |
| | 164 | > opis.md It's p0 so I will take care of that. Delete anything that we don't need, |
| | 165 | > make all of the phases and terra diagram if you can, and delete anything |
| | 166 | > that we don't need and make a documentation about how to start it. |
| | 167 | |
| | 168 | '''Prompt (student, excerpt, follow-up):''' |
| | 169 | > Also fix some database things or golang things if you think we can do it better, |
| | 170 | |
| | 171 | '''Response (AI, summarised): what changed in the prototype, and why''' |
| 71 | | 1. `server/db/db.go` resolved `../.env` and `db/schema_creation.sql` as paths |
| 72 | | relative to the working directory, so they only worked when the program was |
| 73 | | started from inside `server/`. Following the documented instructions — build |
| 74 | | from the repository root and run `./eduberza -init` — failed with |
| 75 | | `password authentication failed for user "postgres"`, because the `.env` file |
| 76 | | was never found and the defaults were used. The two SQL scripts are now |
| 77 | | compiled into the binary with `go:embed`, and `.env` is located by searching |
| 78 | | the working directory and every parent. Real environment variables now take |
| 79 | | precedence over the file, which is what allows the prototype to be pointed at |
| 80 | | the faculty database without editing anything. |
| 81 | | 2. `prompt()` in `server/cli.go` ignored the error from `ReadString`. At end of |
| 82 | | input — Ctrl-D, or a scripted run — it returned an empty string forever and |
| 83 | | the menu loop spun printing "Unknown option." without end. It now exits |
| 84 | | cleanly. |
| 85 | | 3. On the sell path, `trade.go` checked `err == sql.ErrNoRows || held < qty` |
| 86 | | before checking for other errors, so any scan failure was reported to the user |
| 87 | | as "Insufficient holding" regardless of the real cause. The error check now |
| 88 | | comes first. |
| | 175 | 1. `server/db/db.go` resolved `../.env` and `db/schema_creation.sql` relative to the working |
| | 176 | directory, so they only worked when the program was started from inside `server/`. |
| | 177 | Following the documented instructions (build from the repository root and run |
| | 178 | `./eduberza -init`) failed with `password authentication failed for user "postgres"`, |
| | 179 | because `.env` was never found and the defaults were used. The two SQL scripts are now |
| | 180 | compiled into the binary with `go:embed`, and `.env` is searched for in the working directory |
| | 181 | and every parent. Real environment variables now take precedence over the file. |
| | 182 | 2. `prompt()` in `server/cli.go` ignored the error from `ReadString`. At end of input (Ctrl-D, |
| | 183 | or a scripted run) it returned an empty string forever, and the menu loop kept printing |
| | 184 | "Unknown option." without end. It now exits cleanly. |
| | 185 | 3. On the sell path, `trade.go` checked `err == sql.ErrNoRows || held < qty` before checking |
| | 186 | for other errors, so any scan failure was reported as "Insufficient holding". The error |
| | 187 | check now comes first. |
| 92 | | 4. The holding upsert was a read-modify-write in Go (`SELECT ... FOR UPDATE`, |
| 93 | | compute the new weighted average in `float64`, then `INSERT` or `UPDATE`). It |
| 94 | | is now a single `INSERT … ON CONFLICT (user_id, crypto_id) DO UPDATE`, so the |
| 95 | | average is recomputed by PostgreSQL in `numeric` arithmetic and the statement |
| 96 | | relies on the unique constraint that the relational design already declared. |
| 97 | | 5. `TerraER3.11.jar` was removed from the repository and `.gitignore` now |
| 98 | | excludes `*.jar`, because P4 requires third-party executables to be |
| 99 | | downloaded rather than committed. `.env` is excluded too and `.env.example` |
| 100 | | was added in its place. |
| 101 | | 6. `image.png`, a !TradingView screenshot, was deleted — the project has no |
| 102 | | licence to publish it and P4 requires explicit usage rights. |
| 103 | | |
| 104 | | '''Verification''' |
| 105 | | |
| 106 | | All seven use cases were executed against a live PostgreSQL 16 database. The |
| 107 | | screenshots on the `UseCaseXXXXImplementation` pages are captures of those runs. |
| 108 | | The four failure paths were tested, and the rollback behaviour was checked |
| 109 | | directly in SQL: after a rejected purchase, the affected user has zero rows in |
| 110 | | `orders`, `transactions` and `holdings`. |
| 111 | | |
| 112 | | > '''Student action required:''' read the changed files (`server/db/db.go`, |
| 113 | | > `server/cli.go`, `server/trade.go`, `server/db/schema_creation.sql`) before the |
| 114 | | > presentation. You will be asked how the buy transaction works, and the answer |
| 115 | | > has to be yours. |
| 116 | | |
| 117 | | === Session 3 — 2026-09-16 === |
| 118 | | |
| 119 | | Prompted by a design review I did myself, logged in full in |
| 120 | | ERModelAIUsage (section "Session 3 — 2026-09-16"). |
| 121 | | The report: a user who owns 2 BTC and places a sell order for 0.5 BTC has that |
| 122 | | crypto immediately removed from `quantity`, but nothing in the model recorded |
| 123 | | that a ''pending'' order had already committed part of a position before it |
| 124 | | settled — `holdings` had `quantity` and `avg_price` only, no equivalent of the |
| 125 | | `available_balance`/`invested_balance` split already used for cash. |
| 126 | | |
| 127 | | '''Bug fixed''' |
| 128 | | |
| 129 | | `server/trade.go`'s sell path checked `held < qty` directly against |
| 130 | | `holdings.quantity`. This happened to be safe against concurrent double-sells |
| 131 | | only because the whole operation — order, holding check, holding update, |
| 132 | | balance update, ledger, trade — runs inside one transaction with a |
| 133 | | `SELECT ... FOR UPDATE` lock. It was not safe against the actual scenario |
| 134 | | described: nothing distinguished "owned" from "owned, but already promised to |
| 135 | | this order," which matters the moment an order can legitimately sit `open` |
| 136 | | across more than one transaction — exactly what a limit-order matcher would |
| 137 | | need, and what `orders.status` already implied was coming. |
| 138 | | |
| 139 | | '''What changed''' |
| | 191 | 4. The holding upsert was a read-modify-write in Go. It is now a single |
| | 192 | `INSERT … ON CONFLICT (user_id, crypto_id) DO UPDATE`, so PostgreSQL recomputes the average |
| | 193 | in `numeric` arithmetic, relying on the unique constraint of the relational design. |
| | 194 | 5. `TerraER3.11.jar` was removed from the repository and `.gitignore` now excludes `*.jar`, |
| | 195 | because P4 requires third-party executables to be downloaded, not committed. `.env` is |
| | 196 | excluded too, and `.env.example` was added in its place. |
| | 197 | 6. `image.png`, a !TradingView screenshot, was deleted, because the project has no licence to |
| | 198 | publish it. |
| | 199 | |
| | 200 | '''Verification.''' All seven use cases were run against PostgreSQL 16, and the four failure |
| | 201 | paths were tested. After a rejected purchase, the affected user had zero rows in `orders`, |
| | 202 | `transactions` and `holdings`. |
| | 203 | |
| | 204 | ---- |
| | 205 | |
| | 206 | === Session 3 — 2026-09-16 (Claude Sonnet 5) === |
| | 207 | |
| | 208 | '''Prompt (student, verbatim):''' |
| | 209 | > Soo we have a problem here In this scenario we have an edge case where our functionallity doesn't work: |
| | 210 | > Suppose the user owns: |
| | 211 | > |
| | 212 | > 2 BTC |
| | 213 | > |
| | 214 | > and wants to sell: |
| | 215 | > |
| | 216 | > 0.5 BTC at market price |
| | 217 | > |
| | 218 | > A sensible procedure is: |
| | 219 | > |
| | 220 | > 1. User creates an Order |
| | 221 | > |
| | 222 | > Orders gets something like: |
| | 223 | > |
| | 224 | > id user market side type quantity status |
| | 225 | > O1 Alice BTC/USD sell market 0.5 open |
| | 226 | > |
| | 227 | > At this point, no trade has necessarily happened yet. |
| | 228 | > |
| | 229 | > 2. Reserve the crypto |
| | 230 | > |
| | 231 | > This is where your current model has a gap. |
| | 232 | > |
| | 233 | > You currently have: |
| | 234 | > |
| | 235 | > Holds |
| | 236 | > quantity |
| | 237 | > avg_price |
| | 238 | > |
| | 239 | > but you don't have a concept of reserved/committed crypto. |
| | 240 | > |
| | 241 | > For cash, you already explicitly distinguish: |
| | 242 | > |
| | 243 | > available_balance |
| | 244 | > invested_balance |
| | 245 | > |
| | 246 | > For crypto, you probably want the equivalent: |
| | 247 | > |
| | 248 | > quantity |
| | 249 | > reserved_quantity |
| | 250 | > avg_price |
| | 251 | > |
| | 252 | > So Alice might go from: |
| | 253 | > |
| | 254 | > quantity = 2.0 BTC |
| | 255 | > reserved_quantity = 0 |
| | 256 | > |
| | 257 | > to: |
| | 258 | > |
| | 259 | > quantity = 2.0 BTC |
| | 260 | > reserved_quantity = 0.5 BTC |
| | 261 | > |
| | 262 | > with: |
| | 263 | > |
| | 264 | > available BTC = quantity - reserved_quantity = 1.5 BTC |
| | 265 | > |
| | 266 | > The important point is that you generally don't actually remove the 0.5 BTC from her position yet. You reserve it so she cannot submit another sell order for the same BTC. |
| | 267 | > |
| | 268 | > Can you please start from Phase 1 and modify everything to make it work like it should, modify the AIUsage.md in every Phase, and can you make the ConceptualMOdel a little bit more put together not that much spread out. |
| | 269 | |
| | 270 | The other prompts of that day were about the P1 diagram (logged on |
| | 271 | [wiki:ERModelAIUsage]) and about P5 and P6. None of them |
| | 272 | changed the P4 prototype. |
| | 273 | |
| | 274 | '''Response (AI, summarised)''' |
| | 275 | |
| | 276 | The gap: `trade.go`'s sell path checked `held < qty` directly against `holdings.quantity`. |
| | 277 | Nothing distinguished "owned" from "owned, but already promised to an order". This was safe only |
| | 278 | because the whole sell runs in one transaction with a `SELECT … FOR UPDATE` lock. It would stop |
| | 279 | being safe the moment an order could stay `open` across transactions. |
| | 280 | |
| | 281 | What changed: |
| 142 | | added to `schema_creation.sql`. |
| 143 | | 2. `v_portfolio` gained `reserved_quantity` and derived `available_quantity`. |
| 144 | | 3. `trade.go`'s sell path now: locks the holding, computes |
| 145 | | `available := quantity - reserved_quantity`, rejects if `available < qty` |
| 146 | | (previously: rejects if `quantity < qty`), reserves |
| 147 | | (`reserved_quantity += qty`), then settles (`quantity -= qty; reserved_quantity -= qty`) |
| 148 | | — two statements instead of one, kept inside the |
| 149 | | same transaction rather than split into two commits, which would risk an |
| 150 | | order stuck `open` with reserved crypto and no cancel command to free it. |
| 151 | | 4. Both `PlaceOrder` branches now insert the order as `status='open'` and |
| 152 | | `UPDATE ... SET status='executed', executed_at=now()` at the end, instead |
| 153 | | of inserting `'executed'` directly — `Orders.status` is now a real |
| 154 | | lifecycle rather than a label written once. |
| 155 | | 5. `portfolio.go` gained `Reserved`/`Available` columns, reading |
| 156 | | `v_portfolio.reserved_quantity`/`available_quantity`, so the new field is |
| 157 | | something a Trader can actually see. |
| 158 | | 6. The error message on the sell path changed from |
| 159 | | `"Insufficient holding: trying to sell X, hold Y"` to |
| 160 | | `"Insufficient holding: trying to sell X, available Y (of Z held, W reserved)"`, |
| 161 | | since "how much you hold" is no longer the only number that |
| 162 | | matters. |
| 163 | | |
| 164 | | '''Test evidence''' |
| 165 | | |
| 166 | | Verified against PostgreSQL 16 (`bp_database`, `localhost:5433`): |
| | 284 | was added to `schema_creation.sql`. |
| | 285 | 2. `v_portfolio` gained `reserved_quantity` and the derived `available_quantity`. |
| | 286 | 3. The sell path in `trade.go` now locks the holding, computes |
| | 287 | `available := quantity - reserved_quantity`, rejects the order if `available < qty`, |
| | 288 | reserves (`reserved_quantity += qty`), then settles (`quantity -= qty; reserved_quantity -= qty`). |
| | 289 | All of this stays inside the same transaction. |
| | 290 | 4. Both branches of `PlaceOrder` insert the order as `status='open'` and set |
| | 291 | `status='executed', executed_at=now()` at the end. |
| | 292 | 5. `portfolio.go` shows new `Reserved` and `Available` columns. |
| | 293 | 6. The sell error message became |
| | 294 | `"Insufficient holding: trying to sell X, available Y (of Z held, W reserved)"`. |
| | 295 | |
| | 296 | '''Test evidence''' (PostgreSQL 16, `bp_database`, `localhost:5433`): |
| 191 | | Full transcripts are on |
| 192 | | UseCase0005Implementation. The rejected-order |
| 193 | | rollback guarantee from session 2 was re-checked too: after both the |
| 194 | | insufficient-funds and insufficient-holding failure paths, the affected user |
| 195 | | still has zero new rows in `orders`. |
| 196 | | |
| 197 | | '''What I decided:''' to keep reserve and settle inside a single transaction — |
| 198 | | splitting them into two, so an order genuinely sits `open` and reserved |
| 199 | | between two commits, is what a real limit-order matcher will eventually need, |
| 200 | | but building that now would add a way for an order to get stuck without also |
| 201 | | building a way to cancel it, which is out of scope for this review. |
| 202 | | `go build ./...` was run after every change; all seven use cases were re-exercised |
| 203 | | manually. |
| | 321 | (At that time the sell path still asked for a symbol, so a user with no holding could reach the |
| | 322 | check. Since session 4, such a user is never offered anything to sell.) |
| | 323 | |
| | 324 | '''What I decided:''' to keep reserve and settle inside a single transaction. Splitting them into |
| | 325 | two commits, so that an order really sits `open` and reserved in between, is what a real |
| | 326 | limit-order matcher will need. Building it now would add a way for an order to get stuck without |
| | 327 | a way to cancel it. |
| | 328 | |
| | 329 | ---- |
| | 330 | |
| | 331 | === Session 4 — 2026-09-24 (Claude Opus 5.5, 1M context) === |
| | 332 | |
| | 333 | '''Prompt (student, verbatim):''' |
| | 334 | > Does the P4 documentation, fullfill this: |
| | 335 | > |
| | 336 | > ''[pasted: the complete official text "Instructions on Phase P4: First Application Prototype"'' |
| | 337 | > ''from the course site — the prototype requirements, the rule that the user must never have to'' |
| | 338 | > ''remember identifiers or codes, the !PrototypeImplementation / UseCaseXXXXImplementation /'' |
| | 339 | > ''!BuildInstructions templates, the source-code rules and the AI Use rules with the'' |
| | 340 | > ''PrototypeImplementationAIUsage template]'' |
| | 341 | > |
| | 342 | > is this correct? |
| | 343 | > Or do we need to change anything? |
| | 344 | |
| | 345 | '''Response (AI, summarised):''' an audit of the prototype and of the P4 pages against each |
| | 346 | requirement. The main findings: |
| | 347 | * The prototype asked the user to type a market symbol (`Market symbol (e.g. BTC):`) and, in the |
| | 348 | watchlist, a crypto symbol. That breaks the rule that every choice must be picked from a list. |
| | 349 | * The use-case implementation pages had one screenshot per use case, not one per step, and did |
| | 350 | not show the SQL at every step. |
| | 351 | * `PrototypeImplementation.md` was written in Trac markup inside a Markdown file. It did not |
| | 352 | follow the template, and it said identifiers were never typed, which was not accurate. |
| | 353 | * `BuildInstructions` had wrong details: the `-init` message, the order of the history, an |
| | 354 | outdated ER diagram path, an unpinned PostgreSQL version described as 16, and a concurrency |
| | 355 | test with no steps to prepare it. |
| | 356 | * This page listed only one model, still had "Student action required" notes, and had no |
| | 357 | line-by-line log. |
| | 358 | |
| | 359 | '''Prompt (student, verbatim):''' |
| | 360 | > YEs you can start fixing it, and can you make the screenshots yourself? |
| | 361 | |
| | 362 | '''Response (AI, summarised):''' |
| | 363 | * '''Code''' (`market.go`, `trade.go`, `watchlist.go`): |
| | 364 | * `ListMarkets` now returns the numbered list it prints. `ChooseMarket` asks for `Market #:` |
| | 365 | and takes the market by its position in that list. |
| | 366 | * New `ChooseHolding` for the sell path. It lists only the user's holdings that still have a |
| | 367 | free quantity, with `Held` and `Free to sell`, and asks for `Holding #:`. |
| | 368 | * Watchlist ''Add'' lists, numbered, the cryptos not yet on the watchlist. ''Remove'' lists the ones |
| | 369 | on it. |
| | 370 | * A shared `pickNumber` refuses anything outside `1…n` with |
| | 371 | `Invalid choice, enter a number from 1 to N.` |
| | 372 | * The SQL that looked a crypto up by symbol (`WHERE upper(c.symbol) = upper($1)`) is gone. The |
| | 373 | chosen row's id is used directly. |
| | 374 | * '''Screenshots:''' all of them were retaken from real CLI sessions, driven in a pseudo-terminal |
| | 375 | against freshly initialised sample data. There is one screenshot per scenario step, including |
| | 376 | the alternate flows (invalid e-mail, duplicate user, wrong password, invalid amount, |
| | 377 | insufficient funds, insufficient holding, invalid list choice). This gave 30 screenshots, |
| | 378 | which replace the old 8. |
| | 379 | * '''Documentation:''' |
| | 380 | * Rewrote the seven UseCase000XImplementation pages, with the SQL of each step quoted literally |
| | 381 | from the code. |
| | 382 | * Rewrote [wiki:PrototypeImplementation] (real Markdown, template |
| | 383 | order, accurate description of the choices), [wiki:BuildInstructions] (the |
| | 384 | corrections above, a mini-guide of every menu item, and a smoke test re-run on 2026-09-24) |
| | 385 | and this page. |
| | 386 | * Made small matching edits to the P3 use cases UC0004, UC0005 and UC0007, so that the "system |
| | 387 | lists …, user picks …" steps match the prototype. |
| | 388 | * Wrote the wiki versions of the P4 pages for the faculty site. |
| | 389 | |
| | 390 | '''What I decided:''' to accept the numbered-list change, because it is what the P4 rule asks for. |
| | 391 | I also decided to have the screenshots made from real runs instead of editing the old ones. |