source: docs/P5-Normalization/wiki/NormalizationAIUsage.md@ 0cee8ec

main
Last change on this file since 0cee8ec was ef1c1c7, checked in by Stefan <trsunovstefan@…>, 6 days ago

Wiki docs, phase 6 and phase 7 added

  • Property mode set to 100644
File size: 12.3 KB
RevLine 
[ef1c1c7]1= Normalization 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 Sonnet 5.
9
10== Final result ==
11
12=== Results in details / description ===
13
14The AI:
15
16 * Built the single de-normalized relation `R_EDUBERZA` (68 attributes) by taking every
17 attribute from every entity and attributed relationship in
18 [wiki:ERModel], plus the foreign-key-style linking attributes
19 that the eight attributeless relationships need to be representable in one flat table at
20 all, and disambiguating every repeated name (`id`, `created_at`, `quantity`, `type`, …)
21 with a per-origin prefix (`U_`, `C_`, `M_`, `H_`, `O_`, `T_`, `MT_`, `MC_`, `W_`, `WI_`).
22 * Derived the canonical cover (17 functional dependencies) directly from each entity's/
23 relationship's own key and its `UNIQUE` constraints, checked minimality of the composite
24 left-hand sides by example, and separately listed the functional dependencies that hold by
25 foreign-key substitution (e.g. `M_CRYPTO_ID → C_SYMBOL, C_NAME, C_CREATED_AT`) without
26 folding them into the canonical cover, since they are derivable rather than independent.
27 * Computed the candidate keys of `R_EDUBERZA` from first principles: since `Holds`,
28 `Contains`, `Orders`, `Transactions`, `MarketTrades`, `MarketCandles` and `Watchlists` are
29 independent of each other, the only candidate keys are combinations that pick one
30 identifying attribute set per cluster — 96 in total — and selected the all-surrogate-key
31 combination as primary key, with a full closure computation shown step by step.
32 * Decomposed `R_EDUBERZA` using 3NF/BCNF '''synthesis''' on the canonical cover (rather than the
33 binary decomposition algorithm), producing ten relations in one step, then separately
34 verified 3NF (checking every foreign-key-carried transitive dependency by name and showing
35 none of them lands inside any single resulting relation) and BCNF (a determinant/candidate-key
36 table for all ten relations) as distinct, explicit checks per the phase template, even
37 though no additional splitting was needed at either stage.
38 * Verified dependency preservation (every canonical-cover FD's determinant and dependents
39 land inside exactly one resulting relation) and lossless join (every foreign key is
40 equated to the primary key it references, the textbook sufficient condition) explicitly,
41 rather than asserting them.
42 * Compared the result to [wiki:RelationalDesign] and
43 found it identical relation-for-relation and key-for-key, including the less obvious
44 composite candidate keys; documented the one real difference (`holdings.avg_price` is a
45 derived/cached attribute — a property no single-relation normal form check can see) and
46 concluded, with reasoning, that P2's design should continue to be used unchanged.
47 * Added a short cross-reference to this page from
48 [wiki:RelationalDesign], since the phase instructions
49 ask for Phase 2 documentation to be updated with the outcome of this phase.
50 * Wrote Normalization following the section headings given in the phase
51 template exactly (`De-normalized database form` → `Functional dependencies` →
52 `Candidate keys and primary key` → `1NF decomposition` → `2NF decomposition` →
53 `3NF decomposition` → `BCNF if possible` → `Final result and discussion`).
54
55== Summary of AI involvement ==
56
57||= =||= This session — 2026-09-16 =||
58|| '''What I brought''' || The phase rubric for P5, pasted in full, and everything already produced in P1–P4 (in particular the `reserved_quantity` addition to `Holds` from the previous session) ||
59|| '''What the AI did''' || Built the de-normalized relation, derived the canonical cover, found the candidate keys, ran the 1NF→2NF→3NF→BCNF synthesis, and wrote the comparison against P2 ||
60|| '''What I decided''' || To let the AI carry out the full formal derivation rather than write my own first pass, since the rubric's own advice ("start from the canonical cover") is a mechanical method rather than a matter of taste; to keep P2's schema unchanged, per the AI's reasoning that the two designs coincide exactly ||
61
62This phase's rule is that AI is used '''to improve the student's own initial work''', and that
63any idea taken from the AI is logged as a change against that starting point. I did not
64produce an independent first attempt at the canonical cover or the decomposition before
65asking for this — I gave the AI the rubric directly and asked it to carry out the phase, the
66same way P1–P4 were produced (see
67[wiki:ERModelAIUsage] for that history). What I own here
68is checking the result: that the 68-attribute list in `R_EDUBERZA` really is every attribute
69of my P1 model with nothing missing or invented, that the functional dependencies match what
70I already know to be true of the model (each `UNIQUE` constraint in
71`schema_creation.sql` shows up as an alternate-key FD,
72and no others were invented), and that the final ten relations really do match
73[wiki:RelationalDesign] column for column — which I
74checked by reading both side by side rather than taking the AI's claim of a match on faith.
75
76The tables in `schema_creation.sql` that carry `UNIQUE` constraints:
77
78{{{
79-- ============================================================================
80-- USERS
81-- Platform users. Each user has virtual (prop) balances used for simulation.
82-- ============================================================================
83CREATE TABLE project.users (
84 id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
85 username varchar(50) NOT NULL UNIQUE,
86 email varchar(255) NOT NULL UNIQUE,
87 full_name varchar(200),
88 password_hash varchar(255) NOT NULL,
89 available_balance numeric(18,4) NOT NULL DEFAULT 0 CHECK (available_balance >= 0),
90 invested_balance numeric(18,4) NOT NULL DEFAULT 0 CHECK (invested_balance >= 0),
91 created_at timestamptz NOT NULL DEFAULT now(),
92 updated_at timestamptz
93);
94
95-- ============================================================================
96-- CRYPTO
97-- Catalog of crypto assets available on the platform.
98-- ============================================================================
99CREATE TABLE project.crypto (
100 id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
101 symbol varchar(20) NOT NULL UNIQUE,
102 name varchar(255) NOT NULL,
103 created_at timestamptz NOT NULL DEFAULT now()
104);
105
106-- ============================================================================
107-- MARKETS
108-- A market is a (crypto, quote_currency) pair, e.g. BTC/USD.
109-- ============================================================================
110CREATE TABLE project.markets (
111 id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
112 crypto_id uuid NOT NULL REFERENCES project.crypto(id),
113 quote_currency char(3) NOT NULL DEFAULT 'USD',
114 is_active boolean NOT NULL DEFAULT true,
115 created_at timestamptz NOT NULL DEFAULT now(),
116 CONSTRAINT uq_markets UNIQUE (crypto_id, quote_currency)
117);
118
119-- ============================================================================
120-- HOLDINGS
121-- Per-user crypto position with running weighted average entry price.
122-- ============================================================================
123CREATE TABLE project.holdings (
124 id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
125 user_id uuid NOT NULL REFERENCES project.users(id) ON DELETE CASCADE,
126 crypto_id uuid NOT NULL REFERENCES project.crypto(id),
127 quantity numeric(20,4) NOT NULL CHECK (quantity >= 0),
128 -- Committed to the user's own open sell orders, not yet removed from the
129 -- position. quantity - reserved_quantity is what is actually free to
130 -- sell — the crypto-side equivalent of users.available_balance.
131 reserved_quantity numeric(20,4) NOT NULL DEFAULT 0
132 CHECK (reserved_quantity >= 0 AND reserved_quantity <= quantity),
133 -- Weighted-average entry price. NOT NULL so that the P/L arithmetic in
134 -- v_portfolio can never silently produce NULL for an existing position.
135 avg_price numeric(18,6) NOT NULL DEFAULT 0 CHECK (avg_price >= 0),
136 created_at timestamptz NOT NULL DEFAULT now(),
137 updated_at timestamptz,
138 CONSTRAINT uq_holdings_user_crypto UNIQUE (user_id, crypto_id)
139);
140}}}
141
142{{{
143-- ============================================================================
144-- MARKET CANDLES
145-- OHLCV aggregates over standard timeframes.
146-- ============================================================================
147CREATE TABLE project.market_candles (
148 id bigserial PRIMARY KEY,
149 market_id uuid NOT NULL REFERENCES project.markets(id),
150 timeframe varchar(5) NOT NULL CHECK (timeframe IN ('1m', '5m', '1h', '1d')),
151 open numeric(18,6) NOT NULL,
152 high numeric(18,6) NOT NULL,
153 low numeric(18,6) NOT NULL,
154 close numeric(18,6) NOT NULL,
155 volume numeric(20,6) NOT NULL,
156 candle_time timestamptz NOT NULL,
157 CONSTRAINT uq_candle UNIQUE (market_id, timeframe, candle_time)
158);
159}}}
160
161{{{
162CREATE TABLE project.watchlist_items (
163 id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
164 watchlist_id uuid NOT NULL REFERENCES project.watchlists(id) ON DELETE CASCADE,
165 crypto_id uuid NOT NULL REFERENCES project.crypto(id),
166 added_at timestamptz NOT NULL DEFAULT now(),
167 CONSTRAINT uq_watchlist_crypto UNIQUE (watchlist_id, crypto_id)
168);
169}}}
170
171== Entire AI usage log ==
172
173=== 2026-09-16 ===
174
175'''Intent:''' hand over the full P5 rubric and have the phase carried out end to end —
176de-normalized relation, functional dependencies, candidate keys, the four-normal-form
177decomposition, and the comparison against P2 — in one pass.
178
179'''Prompt (student, verbatim):'''
180> We will go phase by phase, here are the instructions for P5:
181> Instructions on Phase P5: Normalization
182> [the full task description was pasted: parts (a) initial de-normalized relation and
183> functional dependencies, (b) candidate keys and primary key selection, (c) step-by-step
184> decomposition to the highest possible normal form with the specific checklist of what each
185> decomposition step must document, (d) final result and discussion including updating Phase
186> 2 documentation and restructuring the database if warranted; the exact wiki page template
187> for `Normalization` and `NormalizationAIUsage`; and the phase's AI-use rules]
188
189'''Response (AI, summarised):'''
190 * Re-read [wiki:ERModel] and
191 `schema_creation.sql` (see the excerpts above) to get the authoritative,
192 current attribute list (including `reserved_quantity`, added in the previous session) and
193 every `UNIQUE`/`CHECK` constraint that turns into an alternate-key functional dependency.
194 * Worked out, before writing anything, that `Holds`/`Contains`/`Orders`/`Transactions`/
195 `MarketTrades`/`MarketCandles`/`Watchlists` are mutually independent record types, which is
196 what makes the primary key of the fully de-normalized relation a ten-attribute composite
197 rather than something smaller — and therefore what makes ''every'' non-key attribute violate
198 2NF simultaneously, rather than a handful needing to be peeled off one at a time.
199 * Chose synthesis over the binary decomposition algorithm specifically because the rubric
200 recommends building the canonical cover first, which is what synthesis consumes directly.
201 * Wrote Normalization.md and this page.
202
203'''What I decided:''' to accept the derivation as presented rather than rework it, since
204checking it against my own P1/P2 documents (attribute list, `UNIQUE` constraints, and the
205final ten relations) confirmed it, and to make no changes to `server/db/schema_creation.sql`
206for this phase, since the discussion section's conclusion — that P2's design is already the
207BCNF result — is one I verified myself rather than took on trust.
208
209> '''Student action required.''' Read Normalization.md end to end before
210> the defense — you will be expected to derive at least one of the ten relations' functional
211> dependencies and candidate keys live, and to explain why `holdings.avg_price` is not a
212> normal-form violation even though it is a stored, derivable value. Append any further
213> prompts here if you ask for revisions.
Note: See TracBrowser for help on using the repository browser.