source: docs/P2-RelationalDesign/RelationalDesignAIUsage.md

main
Last change on this file was 1549dae, checked in by Stefan <trsunovstefan@…>, 55 minutes ago

Correct P1/P2 consistency (Holdings, WatchlistItems), redo P5 normalization

  • Property mode set to 100644
File size: 7.9 KB
Line 
1# Relational Design AI Usage
2
3## Name of AI service/solution that was used
4
5**Claude Code** (Anthropic)
6
7- **URL:** https://claude.com/claude-code
8- **Type of service/subscription:** Claude subscription, model Claude Opus 4.7 (1M context).
9
10## Final result
11
12### Diagram
13
14`relational_diagram_v4.png` was exported by the student in DBeaver from the live `project` schema, with the tables in the same positions as the entity sets of `ERModel_v05.png`; see [RelationalDesign](RelationalDesign.md#how-to-regenerate-it) for instructions.
15
16### Results in details / description
17
18The AI:
19
20- Consolidated two inconsistent draft schemas (`server/db/db.sql` and `server/db/schema.sql`) into a single `schema_creation.sql`.
21- Corrected foreign-key errors in the original (the `crypto_id` column in `holdings`, `orders`, and `transactions` had been pointed at both `users(id)` and `crypto(id)`; the AI split it into separate `user_id` and `crypto_id` columns per `ep-diagram.md`).
22- Added two convenience views, `v_latest_prices` and `v_portfolio`, to keep the Go CLI simple.
23- Produced a sample-data script `data_load.sql` that TRUNCATEs and re-inserts deterministic rows, so the "must work on empty DB and on a DB that already has data" requirement from P2 is met.
24- Documented normalisation up to 3NF and the intentional denormalisation of `holdings.avg_price`.
25
26## Summary of AI involvement
27
28| | Session 1 — 2026-04-21 | Session 2 — 2026-08-06/07 |
29|---|---|---|
30| **What I brought** | My own draft SQL (`db.sql`, `schema.sql`) and the model in `ep-diagram.md` | The schema as it stood after session 1 |
31| **What the AI did** | Reviewed my SQL, found the foreign-key errors, consolidated two inconsistent drafts into one script | Reviewed the schema again; one constraint change, plus documentation of the transformation |
32| **What I decided** | Which corrections to adopt, to keep both balance columns, to drop the secret-question fields | To make `avg_price` `NOT NULL` rather than handle nulls in application code |
33
34The relational model in this phase is a transformation of *my* ER model, and the
35foreign-key errors the AI found in session 1 were errors in *my* draft SQL — that
36review is the single most useful thing the AI did on this phase.
37
38## Entire AI usage log
39
40See [ERModelAIUsage](../P1-ConceptualModel/ERModelAIUsage.md) — the full transcript of the 2026-04-21 conversation covers both P1 and P2 work. The specific prompts that drove the relational-design output were the same "make it work and make it fill in or to follow all of the needed instructions" instruction and the student's subsequent "do everything that you need to do".
41
42> **Student action required:** append any future consultations where you asked the AI to refine the schema, tune constraints, or write additional queries.
43
44
45### Session 2 — 2026-08-06 / 2026-08-07
46
47Prompts are logged in full in [ERModelAIUsage](../P1-ConceptualModel/ERModelAIUsage.md#session-2--2026-08-06--2026-08-07);
48the one that drove this phase was *"Also fix some database things or golang
49things if you think we can do it better"*. Changes to the P2 artefacts:
50
51- `holdings.avg_price` changed from nullable to `NOT NULL DEFAULT 0 CHECK
52 (avg_price >= 0)`. Reason: it feeds the P/L arithmetic in `v_portfolio`, and
53 SQL arithmetic involving `NULL` produces `NULL`, so a nullable average would
54 have silently blanked the unrealised-P/L column of a real position. A related
55 crash path in the Go code (scanning a `NULL` average into a non-nullable
56 `float64`, which was reported to the user as "Insufficient holding") was fixed
57 at the same time.
58- [RelationalDesign](RelationalDesign.md) gained an explicit account of the
59 partial transformation: which ER construct each foreign key comes from, that
60 M:N relationships with attributes become tables whose foreign-key pair is a
61 `UNIQUE` constraint, and that total participation becomes `NOT NULL` — which is
62 why `transactions.related_order` is the one nullable foreign key.
63- The candidate keys of `holdings` and `watchlist_items` are now documented as
64 the relationship keys `{user_id, crypto_id}` and `{watchlist_id, crypto_id}`.
65
66Both scripts were re-run end to end against PostgreSQL 16 after these changes.
67
68> **Still outstanding:** `relational_schema.jpg` must be exported from DBeaver
69> against the faculty database. No AI involvement is possible there — it needs a
70> live connection to your assigned database.
71
72### Session 3 — 2026-09-16
73
74Driven by the same design review logged in full in
75[ERModelAIUsage](../P1-ConceptualModel/ERModelAIUsage.md#session-3--2026-09-16):
76a sell order had nothing to check `holdings.quantity` against except itself,
77so nothing stopped two sell orders from being granted the same units.
78
79Changes to the P2 artefacts:
80
81- `holdings` gained `reserved_quantity numeric(20,4) NOT NULL DEFAULT 0
82 CHECK (reserved_quantity >= 0 AND reserved_quantity <= quantity)` in
83 `schema_creation.sql`.
84- `v_portfolio` gained `reserved_quantity` and the derived
85 `available_quantity = quantity - reserved_quantity`.
86- [RelationalDesign](RelationalDesign.md) gained a "Reservation and the order
87 lifecycle" section explaining why the check is enforced at the database
88 level rather than trusted to application code, and why it does not conflict
89 with the existing `SELECT … FOR UPDATE` locking on the sell path.
90- `data_load.sql` needed no change — `reserved_quantity` defaults to 0, which
91 is correct for every seeded holding.
92
93Re-run end to end against the live database on `localhost:5433`
94(`-init` then `-load-data`), and against a manually seeded 2 BTC holding to
95reproduce the exact scenario that motivated the change — see
96[UseCase0005Implementation](../P4-Prototype/UseCase0005Implementation.md) for
97the transcript.
98
99**What I decided:** to add the `CHECK` constraint rather than rely on
100`trade.go` alone to keep the reservation consistent — the same reasoning
101already applied to `avg_price NOT NULL` in session 2.
102
103### Session 4 — 2026-09-29 (Claude Opus 5.5): correction after review
104
105**Prompt (student, excerpt):** I pasted the reviewer's comments on P2:
106
107> the `contains` relationship from the model is implemented differently in the database
108> the `holds` relationship from the model is implemented differently in the database
109> there may be other inconsistencies that are difficult to spot; the Phase 2 diagram should
110> have been created using DBeaver with a layout visually similar to the ERD
111
112> I suggest correcting only the Phase 1 model so that it matches Phase 2 [...] For Phase 2,
113> simply update the image according to the requirements.
114
115**Response (AI, summarised):**
116
117- Explained the mismatch. In the model, `Holds` and `Contains` were M:N relationships, whose
118 table key would be the pair `{user_id, crypto_id}` / `{watchlist_id, crypto_id}`. But
119 `holdings` and `watchlist_items` have their own `id` primary key, which is how an entity
120 set is implemented. Following the reviewer's advice, P1 was corrected (v05, entity sets
121 `Holdings` and `WatchlistItems`), and the database was not changed.
122- Found the other inconsistencies between this page and the live schema. The page was
123 missing `users.reserved_balance`, `orders.filled_quantity`, the status
124 `partially_filled`, `market_trades.buy_order_id` / `sell_order_id` and the whole
125 `order_events` table. The "10 tables", "5 indexes" and "the one nullable foreign key"
126 counts were also out of date (really 11 tables, 8 indexes in `schema_creation.sql`, and 3
127 nullable foreign keys).
128- Rewrote [RelationalDesign](RelationalDesign.md). Each relation is labelled with its entity
129 set and each foreign key with its relationship, and the transformation is a table of all
130 15 relationships → 15 foreign keys, with `NOT NULL` following participation.
131- Wrote export instructions with a table grid that mirrors `ERModel_v05.png`.
132
133**What I decided:** to correct P1 instead of the database, as the reviewer suggested. I
134exported `relational_diagram_v4.png` from DBeaver myself, with the tables arranged like the
135ER diagram.
Note: See TracBrowser for help on using the repository browser.