Ignore:
Timestamp:
09/24/26 17:43:19 (5 days ago)
Author:
Stefan <trsunovstefan@…>
Branches:
main
Children:
0cee8ec
Parents:
a531b45
Message:

Wiki docs, phase 6 and phase 7 added

File:
1 edited

Legend:

Unmodified
Added
Removed
  • docs/P4-Prototype/PrototypeImplementationAIUsage.md

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