Index: docs/P1-ConceptualModel/ERModel.md
===================================================================
--- docs/P1-ConceptualModel/ERModel.md	(revision 9577c7944ff24ddc9145ff6637494f07d87c3dd4)
+++ docs/P1-ConceptualModel/ERModel.md	(revision ef1c1c725137d93fa85292f43440214aaddcdf05)
@@ -1,7 +1,7 @@
-# Entity-Relationship Model v.03
+# Entity-Relationship Model v.04
 
 ## Diagram
 
-![ERModel_v03](ERModel_v03.png)
+![ERModel_v04](ERModel_v04.png)
 
 Notation: Chen. Rectangles are entity sets, diamonds are relationships, ellipses
@@ -51,4 +51,5 @@
 | `available_balance` | numeric(18,4) | required, default 0, ≥ 0 |
 | `invested_balance` | numeric(18,4) | required, default 0, ≥ 0 |
+| `reserved_balance` | numeric(18,4) | required, default 0, ≥ 0 — cash set aside for the user's open buy orders (added in v04, after P7) |
 | `created_at` | timestamptz | required, defaults to now |
 | `updated_at` | timestamptz | optional (null until first change) |
@@ -96,14 +97,15 @@
 makes the ledger auditable.
 
-Placing an order is what triggers a **reservation** of whatever it commits —
-the crypto being sold (`Holds.reserved_quantity`, below) on a sell, cash
-already handled the same way on a buy via `available_balance` /
-`invested_balance`. `status` therefore has real meaning as a lifecycle, not
-just a label: `open` means reserved but not yet settled, `executed` means
-settled, `cancelled` would release the reservation without settling (not yet
-exercised by any use case, since only market orders — which settle
-immediately — are implemented). See
+Placing an order is what triggers a **reservation** of whatever it commits:
+the crypto being sold (`Holds.reserved_quantity`, below) on a sell, and the
+cash (`Users.reserved_balance`) on a buy. Since v04 (after P7) an order can
+wait in the order book and be filled in parts, so `status` is a real
+lifecycle driven by `filled_quantity`: `open` (nothing filled yet),
+`partially_filled`, `executed` (completely filled), or `cancelled`, which
+releases what is still reserved. See
 [UseCase0005](../P3-UseCaseModel/UseCase0005.md) for the reserve-then-settle
-sequence.
+sequence and
+[AdvancedDatabaseDevelopment](../P7-AdvancedDatabaseDevelopment/AdvancedDatabaseDevelopment.md)
+for the rules that keep it consistent.
 
 **Keys:** candidate `{id}` only — there is no natural key, since the same user
@@ -115,8 +117,9 @@
 | `id` | UUID | PK, required |
 | `side` | text | required, `buy` or `sell` |
-| `type` | text | required, `market` or `limit` — the prototype executes only `market`; `limit` exists so the model does not have to change when limit orders are implemented |
-| `status` | text | required, `open`, `executed` or `cancelled` |
+| `type` | text | required, `market` or `limit` (both executed since P7) |
+| `status` | text | required, `open`, `partially_filled`, `executed` or `cancelled` |
 | `quantity` | numeric(20,4) | required, > 0 |
-| `price` | numeric(18,6) | optional — null until the order settles, then the fill price |
+| `filled_quantity` | numeric(20,4) | required, default 0, between 0 and `quantity` — how much has been traded; remaining = `quantity − filled_quantity` (added in v04, after P7) |
+| `price` | numeric(18,6) | the limit price; for a market order, the market price when it was placed |
 | `placed_at` | timestamptz | required, defaults to now |
 | `executed_at` | timestamptz | optional, set when the order settles |
@@ -160,4 +163,25 @@
 | `source` | text(50) | required, default `simulation` — distinguishes a simulated trade from a user's own fill (`user`) |
 
+Since v04 (after P7) a trade also records which orders it filled, through the
+relationships `FillsBuy` and `FillsSell` below.
+
+#### OrderEvents
+*Added in v04, after P7.* The audit trail of an order: one event for its
+placement, one for every (partial) fill, and one for a cancellation. The
+`Orders` row only holds the current state; this entity keeps the history of
+how the order got there. Events are recorded automatically by the database.
+
+**Keys:** candidate `{id}` only; primary key **`id`** (auto-incrementing
+integer, events are only read in order).
+
+| Attribute | Type | Constraints |
+|---|---|---|
+| `id` | integer | PK, required, auto-generated |
+| `event_type` | text | required, `placed`, `partially_filled`, `filled` or `cancelled` |
+| `quantity` | numeric(20,4) | required — the ordered quantity for `placed`, the filled amount for a fill, the unfilled rest for `cancelled` |
+| `price` | numeric(18,6) | optional — the order price, or the trade price for a fill |
+| `status_after` | text | required, the order's status after the event |
+| `created_at` | timestamptz | required, defaults to now |
+
 #### MarketCandles
 OHLCV aggregates per market and timeframe — the data a price chart is drawn
@@ -222,4 +246,18 @@
 #### Fills — Markets (1) : MarketTrades (N), total on MarketTrades
 Every executed trade happened on exactly one market. No attributes.
+
+#### FillsBuy — Orders (1) : MarketTrades (N), partial on both sides
+*Added in v04, after P7.* The buy order a trade filled. An order can be
+filled by many trades (partial fills); a trade fills at most one buy order,
+and none when the simulated market was the buyer. No attributes.
+
+#### FillsSell — Orders (1) : MarketTrades (N), partial on both sides
+*Added in v04, after P7.* The sell order a trade filled, symmetric to
+`FillsBuy`. A trade between two users' orders participates in both. No
+attributes.
+
+#### Logs — Orders (1) : OrderEvents (N), total on OrderEvents
+*Added in v04, after P7.* Every event belongs to exactly one order. No
+attributes.
 
 #### Aggregates — Markets (1) : MarketCandles (N), total on MarketCandles
@@ -290,11 +328,21 @@
   [UseCase0005](../P3-UseCaseModel/UseCase0005.md) for how the new attribute
   is enforced.
+- **v04 — after P7.** Phase 7 (order, balance and trade consistency) needed
+  data the model did not have, so the model was extended to stay in line with
+  the database:
+  - `Users.reserved_balance`: cash reserved by open buy orders;
+  - `Orders.filled_quantity` and the status value `partially_filled`: orders
+    can now be filled in parts;
+  - the relationships `FillsBuy` and `FillsSell` between `Orders` and
+    `MarketTrades`: which orders a trade filled;
+  - the entity set `OrderEvents` with the relationship `Logs`: the
+    automatically recorded history of every order.
+
+  Nothing existing was removed or changed. See
+  [AdvancedDatabaseDevelopment](../P7-AdvancedDatabaseDevelopment/AdvancedDatabaseDevelopment.md).
+  The diagram files are `ERModel_v04.xml` / `ERModel_v04.png`; earlier versions
+  are kept.
 
 Reasoning for the AI-assisted part of this phase, and the full interaction log,
 are on [ERModelAIUsage](ERModelAIUsage.md).
 
-> **Student action required.** Open `ERModel_v03.xml` in TerraER, read the
-> whole diagram — not just the new `reserved_quantity` ellipse — and change
-> anything you disagree with, including the compaction. The phase rules
-> require the model to be yours; this is a generated revision to review and
-> take over, not an answer to submit unread.
Index: docs/P1-ConceptualModel/ERModelAIUsage.md
===================================================================
--- docs/P1-ConceptualModel/ERModelAIUsage.md	(revision 9577c7944ff24ddc9145ff6637494f07d87c3dd4)
+++ docs/P1-ConceptualModel/ERModelAIUsage.md	(revision ef1c1c725137d93fa85292f43440214aaddcdf05)
@@ -283,6 +283,32 @@
 white `(255,255,255)`, matching `ERModel_v02.png`.
 
-> **Student action required.** Open `ERModel_v03.xml` in TerraER and read it
-> end to end before submission — see the note at the end of
-> [ERModel](ERModel.md). Everything else in this session's diff is already
-> applied to the docs and to `server/`.
+
+### Session 4 — 2026-09-24 (Claude Opus 5.5): v04 after P7
+
+**Prompts (student, verbatim):**
+> But this order_events is added after Phase 7 right? can we add that too?
+
+> can you make the ERmodel again with TerraER file to update it? and tell that after P7 we added this
+
+> Make it with a white background like earier versions
+
+**Response (AI, summarised):**
+
+- Explained that the P7 changes must also appear in P1 and P2, since both must describe the
+  current data structure.
+- Built `ERModel_v04.xml` in TerraER's own file format by taking `ERModel_v03.xml` unchanged
+  and appending the new elements with the same XML structure TerraER uses:
+  - the attribute `reserved_balance` on `Users`;
+  - the attribute `filled_quantity` on `Orders`;
+  - the relationships `FillsBuy` and `FillsSell` (Orders 1 : N MarketTrades, partial);
+  - the entity set `OrderEvents` (key `id`, `event_type`, `quantity`, `price`,
+    `status_after`, `created_at`) with `Logs` (Orders 1 : N OrderEvents, total on
+    OrderEvents).
+- Rendered `ERModel_v04.png` with TerraER 3.14's own drawing classes (loading the `.xml`
+  exactly as TerraER does and using its image export), on a white background and trimmed like
+  the earlier versions.
+- Updated [ERModel](ERModel.md) (title v.04, new attribute rows, the `OrderEvents` section, the
+  three relationships, and a v04 history entry stating these were added after P7).
+
+**What I decided:** to add the P7 structure to the ER model. The new elements are placed
+automatically, so the layout can be tidied by hand in TerraER.
Index: docs/P1-ConceptualModel/ERModel_v04.xml
===================================================================
--- docs/P1-ConceptualModel/ERModel_v04.xml	(revision ef1c1c725137d93fa85292f43440214aaddcdf05)
+++ docs/P1-ConceptualModel/ERModel_v04.xml	(revision ef1c1c725137d93fa85292f43440214aaddcdf05)
@@ -0,0 +1,1 @@
+<drawing><figures><ent id="0"><children><r id="1" x="1074.6" y="871.7" w="210" h="72"/><t id="2" x="1157.9098373413085" y="899.5279428482056"><a><text><string>Cryptos</string></text></a></t></children></ent><ent id="3"><children><r id="4" x="1917" y="871.7" w="210" h="72"/><t id="5" x="1999.0858306884766" y="899.5279428482056"><a><text><string>Markets</string></text></a></t></children></ent><ent id="6"><children><r id="7" x="2478.6" y="1058.9" w="210" h="72"/><t id="8" x="2544.431718444824" y="1086.7279428482057"><a><text><string>MarketTrades</string></text></a></t></children></ent><ent id="9"><children><r id="a" x="2478.6" y="1526.9" w="210" h="72"/><t id="b" x="2541.1976943969726" y="1554.7279428482057"><a><text><string>MarketCandles</string></text></a></t></children></ent><ent id="c"><children><r id="d" x="1917" y="1807.7" w="210" h="72"/><t id="e" x="2002.4098510742188" y="1835.5279428482056"><a><text><string>Orders</string></text></a></t></children></ent><ent id="f"><children><r id="10" x="1402.2" y="1994.9" w="210" h="72"/><t id="11" x="1471.2657501220704" y="2022.7279428482057"><a><text><string>Transactions</string></text></a></t></children></ent><ent id="12"><children><r id="13" x="887.4" y="1620.5" w="210.0000000000001" h="72"/><t id="14" x="976.4038757324219" y="1648.3279428482056"><a><text><string>Users</string></text></a></t></children></ent><ent id="15"><children><r id="16" x="653.4" y="1152.5" w="210" h="72"/><t id="17" x="729.689794921875" y="1180.3279428482056"><a><text><string>Watchlists</string></text></a></t></children></ent><rel id="18"><children><diamond id="19" x="1500.8" y="859.7" w="200" h="96"/><t id="1a" x="1571.1417892456054" y="899.5279428482056"><a><text><string>QuotedOn</string></text></a></t></children></rel><rel id="1b"><children><diamond id="1c" x="2226.2" y="929.9" w="200" h="96.00000000000011"/><t id="1d" x="2315.567919921875" y="969.7279428482055"><a><text><string>Fills</string></text></a></t></children></rel><rel id="1e"><children><diamond id="1f" x="2249.6" y="1257.5" w="200" h="96"/><t id="20" x="2317.04376373291" y="1297.3279428482056"><a><text><string>Aggregates</string></text></a></t></children></rel><rel id="21"><children><diamond id="22" x="1922" y="1327.7" w="200" h="96"/><t id="23" x="1995.107810974121" y="1367.5279428482056"><a><text><string>PlacedOn</string></text></a></t></children></rel><rel id="24"><children><diamond id="25" x="1664.6" y="1889.3000000000002" w="200" h="96"/><t id="26" x="1745.7838607788085" y="1929.1279428482057"><a><text><string>Settles</string></text></a></t></children></rel><rel id="27"><children><diamond id="28" x="1149.8" y="1795.7" w="200" h="96"/><t id="29" x="1227.1318328857421" y="1835.5279428482056"><a><text><string>Records</string></text></a></t></children></rel><rel id="2a"><children><diamond id="2b" x="1407.2" y="1702.1" w="200" h="96"/><t id="2c" x="1489.51787109375" y="1741.9279428482055"><a><text><string>Places</string></text></a></t></children></rel><rel id="2d"><children><diamond id="2e" x="986" y="1234.1" w="200" h="96"/><t id="2f" x="1069.811882019043" y="1273.9279428482055"><a><text><string>Holds</string></text></a></t></children></rel><rel id="30"><children><diamond id="31" x="775.4" y="1374.5" w="200" h="96"/><t id="32" x="859.415884399414" y="1414.3279428482056"><a><text><string>Owns</string></text></a></t></children></rel><rel id="33"><children><diamond id="34" x="845.6" y="976.7" w="199.9999999999999" h="96"/><t id="35" x="920.8078247070313" y="1016.5279428482056"><a><text><string>Contains</string></text></a></t></children></rel><llabelUm id="36"><points><p colinear="true" x="1285.1" y="907.7" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1500.367268932415" y="907.7" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="37"><Owner><r ref="1"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="38"><Owner><diamond ref="19"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="39"><points><p colinear="true" x="1701.2327310675846" y="907.7" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1916.5" y="907.7" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="3a"><Owner><diamond ref="19"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="3b"><Owner><r ref="4"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="3c"><points><p colinear="true" x="2127.5" y="932.046153846154" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2258.061419777714" y="962.1757122563956" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="3d"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="3e"><Owner><diamond ref="1c"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="3f"><points><p colinear="true" x="2378.142569236337" y="1001.5102587437897" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2503.2999999999997" y="1058.4" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="40"><Owner><diamond ref="1c"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="41"><Owner><r ref="7"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="42"><points><p colinear="true" x="2052.0588235294117" y="944.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2320.854586641136" y="1270.5948552070938" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="43"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="44"><Owner><diamond ref="1f"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="45"><points><p colinear="true" x="2380.415596146642" y="1339.3971557613067" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2550.418181818182" y="1526.4" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="46"><Owner><diamond ref="1f"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="47"><Owner><r ref="a"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelMuitos id="48"><points><p colinear="true" x="1001.525" y="1620" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1075.1012874391326" y="1325.6948502434695" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="49"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="4a"><Owner><diamond ref="2e"/></Owner></diamondConnector></endConnector></llabelMuitos><llabelMuitos id="4b"><points><p colinear="true" x="1096.8987125608674" y="1238.5051497565303" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1170.475" y="944.2" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="4c"><Owner><diamond ref="2e"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="4d"><Owner><r ref="1"/></Owner></rConnector></endConnector></llabelMuitos><llabelUm id="4e"><points><p colinear="true" x="974.15" y="1620" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="895.0635816788919" y="1461.8271633577838" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="4f"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="50"><Owner><diamond ref="31"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="51"><points><p colinear="true" x="855.7364183211081" y="1383.1728366422162" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="776.65" y="1225" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="52"><Owner><diamond ref="31"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="53"><Owner><r ref="16"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelMuitos id="54"><points><p colinear="true" x="800.1142857142856" y="1152" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="909.6933786333907" y="1056.1182936957832" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="55"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="56"><Owner><diamond ref="34"/></Owner></diamondConnector></endConnector></llabelMuitos><llabelMuitos id="57"><points><p colinear="true" x="995.1502233131612" y="999.9248883434194" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1106.6" y="944.2" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="58"><Owner><diamond ref="34"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="59"><Owner><r ref="1"/></Owner></rConnector></endConnector></llabelMuitos><llabelUm id="5a"><points><p colinear="true" x="1097.9" y="1675.6818181818182" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1434.0736476037464" y="1736.8042995643175" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="5b"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="5c"><Owner><diamond ref="2b"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="5d"><points><p colinear="true" x="1580.3263523962532" y="1763.3957004356823" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1916.5" y="1824.5181818181818" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="5e"><Owner><diamond ref="2b"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="5f"><Owner><r ref="d"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="60"><points><p colinear="true" x="2022" y="944.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2022" y="1326.7984769425318" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="61"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="62"><Owner><diamond ref="22"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="63"><points><p colinear="true" x="2022" y="1424.6015230574683" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2022" y="1807.2" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="64"><Owner><diamond ref="22"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="65"><Owner><r ref="d"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="66"><points><p colinear="true" x="1042.5875" y="1693" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1209.524682824987" y="1814.4088602363543" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="67"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="68"><Owner><diamond ref="28"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="69"><points><p colinear="true" x="1290.0753171750125" y="1872.9911397636458" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1457.0125" y="1994.4" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="6a"><Owner><diamond ref="28"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="6b"><Owner><r ref="10"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="6c"><points><p colinear="true" x="1921.6250000000002" y="1880.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1822.0943672237672" y="1916.3929573731757" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="6d"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="6e"><Owner><diamond ref="25"/></Owner></diamondConnector></endConnector></llabelUm><llabelMuitos id="6f"><points><p colinear="true" x="1707.1056327762324" y="1958.2070426268247" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1607.575" y="1994.4" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="70"><Owner><diamond ref="25"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="71"><Owner><r ref="10"/></Owner></rConnector></endConnector></llabelMuitos><atr id="72" nullable="false" attributeType="VARCHAR2(128)"><children><e id="73" x="726.8879772722291" y="947.7138777184988" w="168" h="50"/><t id="74" x="781.3437725603151" y="964.5418205667044"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="75"><points><p colinear="true" x="1074.1" y="926.3024964647431" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="884.3466049810012" y="960.3493031779781" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="76"><Owner><r ref="1"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="77"><Owner><e ref="73"/></Owner></ellipseConnector></endConnector></llabel><atr id="78" nullable="false" attributeType="VARCHAR2(128)"><children><e id="79" x="747.6522869294774" y="744.469218446131" w="168" h="50"/><t id="7a" x="815.584179324497" y="761.2971612943365"><a><text><string>name</string></text></a></t></children></atr><llabel id="7b"><points><p colinear="true" x="1087.723998256316" y="871.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="883.2653378775243" y="790.2751342913638" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="7c"><Owner><r ref="1"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="7d"><Owner><e ref="79"/></Owner></ellipseConnector></endConnector></llabel><atr id="7e" nullable="false" attributeType="VARCHAR2(128)"><children><e id="7f" x="872.0238232664767" y="584.0548844636454" w="168" h="50"/><t id="80" x="935.611675744504" y="600.882827311851"><a><text><string>symbol</string></text></a></t></children></atr><llabel id="81"><points><p colinear="true" x="1152.2748236410375" y="871.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="975.144726893544" y="634.428026120974" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="82"><Owner><r ref="1"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="83"><Owner><e ref="7f"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="84" nullable="false" attributeType="NUMBER"><children><e id="85" x="1062.9688899152766" y="508.0548972033168" w="168" h="50.00000000000006"/><t id="86" x="1141.3408534162531" y="524.8828400515224"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="87"><points><p colinear="true" x="1176.4208966053434" y="871.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1149.6891405457882" y="559.0460932902021" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="88"><Owner><r ref="1"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="89"><Owner><e ref="85"/></Owner></ellipseConnector></endConnector></llabel><atr id="8a" nullable="false" attributeType="VARCHAR2(128)"><children><e id="8b" x="1631.3094746182014" y="667.9529822301685" w="168" h="50"/><t id="8c" x="1685.7652699062874" y="684.780925078374"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="8d"><points><p colinear="true" x="1969.8725977539127" y="871.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1749.2534612709806" y="716.8707137922294" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="8e"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="8f"><Owner><e ref="8b"/></Owner></ellipseConnector></endConnector></llabel><atr id="90" nullable="false" attributeType="VARCHAR2(128)"><children><e id="91" x="1809.9476583388696" y="530.8790827777559" w="168" h="50"/><t id="92" x="1870.469493666018" y="547.7070256259615"><a><text><string>is_active</string></text></a></t></children></atr><llabel id="93"><points><p colinear="true" x="2008.7150864492837" y="871.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1903.6734154443525" y="581.7266421024433" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="94"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="95"><Owner><e ref="91"/></Owner></ellipseConnector></endConnector></llabel><atr id="96" nullable="false" attributeType="VARCHAR2(128)"><children><e id="97" x="2034.9018504863839" y="521.0573706373729" w="168" h="50"/><t id="98" x="2075.0835445171456" y="537.8853134855784"><a><text><string>quote_currency</string></text></a></t></children></atr><llabel id="99"><points><p colinear="true" x="2031.7801455237359" y="871.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2112.5913746299984" y="571.9744125571244" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="9a"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="9b"><Owner><e ref="97"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="9c" nullable="false" attributeType="NUMBER"><children><e id="9d" x="2224.8070395037453" y="642.0403189333597" w="168" h="50"/><t id="9e" x="2303.179003004722" y="658.8682617815653"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="9f"><points><p colinear="true" x="2065.4990061296885" y="871.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2280.7104729582716" y="691.5356873746031" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="a0"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="a1"><Owner><e ref="9d"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="a2" nullable="false" attributeType="NUMBER"><children><e id="a3" x="2684.1996567283372" y="674.0247586223913" w="168" h="50"/><t id="a4" x="2762.571620229314" y="690.8527014705969"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="a5"><points><p colinear="true" x="2600.620229522657" y="1058.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2756.9248233656053" y="724.7759702566166" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="a6"><Owner><r ref="7"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="a7"><Owner><e ref="a3"/></Owner></ellipseConnector></endConnector></llabel><atr id="a8" nullable="false" attributeType="VARCHAR2(128)"><children><e id="a9" x="2803.02677621649" y="755.6923752120773" w="168" h="50"/><t id="aa" x="2853.060543916685" y="772.5203180602829"><a><text><string>executed_at</string></text></a></t></children></atr><llabel id="ab"><points><p colinear="true" x="2618.847640280458" y="1058.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2863.885153628648" y="805.6739920689837" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="ac"><Owner><r ref="7"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="ad"><Owner><e ref="a9"/></Owner></ellipseConnector></endConnector></llabel><atr id="ae" nullable="false" attributeType="VARCHAR2(128)"><children><e id="af" x="2888.791649765479" y="871.5969497137661" w="168" h="50"/><t id="b0" x="2958.8115472264167" y="888.4248925619717"><a><text><string>price</string></text></a></t></children></atr><llabel id="b1"><points><p colinear="true" x="2655.235283450938" y="1058.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2930.2308648073213" y="919.0375155251545" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="b2"><Owner><r ref="7"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="b3"><Owner><e ref="af"/></Owner></ellipseConnector></endConnector></llabel><atr id="b4" nullable="false" attributeType="VARCHAR2(128)"><children><e id="b5" x="2932.149092426318" y="1009.1091895006435" w="168" h="49.999999999999886"/><t id="b6" x="2992.736937274951" y="1025.937132348849"><a><text><string>quantity</string></text></a></t></children></atr><llabel id="b7"><points><p colinear="true" x="2689.1" y="1080.0729419388979" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2940.0486683659437" y="1045.3746770366456" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="b8"><Owner><r ref="7"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="b9"><Owner><e ref="b5"/></Owner></ellipseConnector></endConnector></llabel><atr id="ba" nullable="false" attributeType="VARCHAR2(128)"><children><e id="bb" x="2928.3747537299396" y="1153.2453691804749" w="168" h="50"/><t id="bc" x="3000.878667609334" y="1170.0733120286804"><a><text><string>side</string></text></a></t></children></atr><llabel id="bd"><points><p colinear="true" x="2689.1" y="1115.4071226140295" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2941.8361049738987" y="1164.93685467455" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="be"><Owner><r ref="7"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="bf"><Owner><e ref="bb"/></Owner></ellipseConnector></endConnector></llabel><atr id="c0" nullable="false" attributeType="VARCHAR2(128)"><children><e id="c1" x="2877.879896373043" y="1288.3000000000002" w="168" h="50"/><t id="c2" x="2942.92575666357" y="1305.1279428482057"><a><text><string>source</string></text></a></t></children></atr><llabel id="c3"><points><p colinear="true" x="2646.819854476264" y="1131.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2923.2371144835133" y="1291.2009043392497" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="c4"><Owner><r ref="7"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="c5"><Owner><e ref="c1"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="c6" nullable="false" attributeType="NUMBER"><children><e id="c7" x="2952.0288472886955" y="1326.928963739043" w="168" h="50"/><t id="c8" x="3030.400810789672" y="1343.7569065872485"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="c9"><points><p colinear="true" x="2661.8745025985986" y="1526.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2990.619110480273" y="1373.8370255966909" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="ca"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="cb"><Owner><e ref="c7"/></Owner></ellipseConnector></endConnector></llabel><atr id="cc" nullable="false" attributeType="VARCHAR2(128)"><children><e id="cd" x="2992.258472645275" y="1457.350205892103" w="168" h="50"/><t id="ce" x="3046.6482584118767" y="1474.1781487403086"><a><text><string>timeframe</string></text></a></t></children></atr><llabel id="cf"><points><p colinear="true" x="2689.1" y="1545.650721340985" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3002.4622954386923" y="1494.9976510478937" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="d0"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="d1"><Owner><e ref="cd"/></Owner></ellipseConnector></endConnector></llabel><atr id="d2" nullable="false" attributeType="VARCHAR2(128)"><children><e id="d3" x="2995.6611351787064" y="1593.7926664707713" w="168" h="50"/><t id="d4" x="3065.249033433101" y="1610.620609318977"><a><text><string>open</string></text></a></t></children></atr><llabel id="d5"><points><p colinear="true" x="2689.1" y="1574.7869951594619" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3000.99890549264" y="1610.3732253229944" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="d6"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="d7"><Owner><e ref="d3"/></Owner></ellipseConnector></endConnector></llabel><atr id="d8" nullable="false" attributeType="VARCHAR2(128)"><children><e id="d9" x="2961.982480739866" y="1726.057066050806" w="168" h="50"/><t id="da" x="3033.3283974879128" y="1742.8850088990116"><a><text><string>high</string></text></a></t></children></atr><llabel id="db"><points><p colinear="true" x="2673.2961294158786" y="1599.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2996.1485074731736" y="1731.0746880909269" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="dc"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="dd"><Owner><e ref="d9"/></Owner></ellipseConnector></endConnector></llabel><atr id="de" nullable="false" attributeType="VARCHAR2(128)"><children><e id="df" x="2893.7400394714773" y="1844.25644156019" w="168" h="50"/><t id="e0" x="2967.845965985149" y="1861.0843844083956"><a><text><string>low</string></text></a></t></children></atr><llabel id="e1"><points><p colinear="true" x="2630.5587365861948" y="1599.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2947.6573226090923" y="1845.9851639103306" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="e2"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="e3"><Owner><e ref="df"/></Owner></ellipseConnector></endConnector></llabel><atr id="e4" nullable="false" attributeType="VARCHAR2(128)"><children><e id="e5" x="2796.035036638292" y="1934.1924511643451" w="168" h="50"/><t id="e6" x="2865.7189279346785" y="1951.0203940125507"><a><text><string>close</string></text></a></t></children></atr><llabel id="e7"><points><p colinear="true" x="2610.9027629103402" y="1599.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2861.9286659462064" y="1934.8183191033766" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="e8"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="e9"><Owner><e ref="e5"/></Owner></ellipseConnector></endConnector></llabel><atr id="ea" nullable="false" attributeType="VARCHAR2(128)"><children><e id="eb" x="2710.6394760805692" y="2010.1924102495736" w="168" h="50"/><t id="ec" x="2773.7113297182646" y="2027.0203530977792"><a><text><string>volume</string></text></a></t></children></atr><llabel id="ed"><points><p colinear="true" x="2599.9096859271363" y="1599.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2783.8472404503373" y="2010.421132657545" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="ee"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="ef"><Owner><e ref="eb"/></Owner></ellipseConnector></endConnector></llabel><atr id="f0" nullable="false" attributeType="VARCHAR2(128)"><children><e id="f1" x="2508.639739054654" y="2035.2003932873995" w="168" h="50"/><t id="f2" x="2558.6915044965485" y="2052.028336135605"><a><text><string>candle_time</string></text></a></t></children></atr><llabel id="f3"><points><p colinear="true" x="2584.263483238599" y="1599.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2592.6762166427297" y="2035.2007769429708" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="f4"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="f5"><Owner><e ref="f1"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="f6" nullable="false" attributeType="NUMBER"><children><e id="f7" x="2435.3003932873994" y="1775.191853220369" w="168" h="50.00000000000023"/><t id="f8" x="2513.672356788376" y="1792.0197960685748"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="f9"><points><p colinear="true" x="2127.5" y="1834.469945998015" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2438.642251542709" y="1807.7922705758594" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="fa"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="fb"><Owner><e ref="f7"/></Owner></ellipseConnector></endConnector></llabel><atr id="fc" nullable="false" attributeType="VARCHAR2(128)"><children><e id="fd" x="2430.658472645275" y="1899.249794107897" w="168" h="50"/><t id="fe" x="2503.1623865246697" y="1916.0777369561026"><a><text><string>side</string></text></a></t></children></atr><llabel id="ff"><points><p colinear="true" x="2127.5" y="1860.9492786590151" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2440.8622954386924" y="1912.6023489521065" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="100"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="101"><Owner><e ref="fd"/></Owner></ellipseConnector></endConnector></llabel><atr id="102" nullable="false" attributeType="VARCHAR2(128)"><children><e id="103" x="2395.5478781302922" y="2018.3260985404147" w="168" h="50.00000000000023"/><t id="104" x="2467.2477911551946" y="2035.1540413886203"><a><text><string>type</string></text></a></t></children></atr><llabel id="105"><points><p colinear="true" x="2105.658888661668" y="1880.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2431.9793163146783" y="2022.8539994086007" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="106"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="107"><Owner><e ref="103"/></Owner></ellipseConnector></endConnector></llabel><atr id="108" nullable="false" attributeType="VARCHAR2(128)"><children><e id="109" x="2332.1400394714774" y="2125.0564415601903" w="168" h="50"/><t id="10a" x="2398.9859180725516" y="2141.884384408396"><a><text><string>status</string></text></a></t></children></atr><llabel id="10b"><points><p colinear="true" x="2068.958736586195" y="1880.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2386.0573226090924" y="2126.7851639103305" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="10c"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="10d"><Owner><e ref="109"/></Owner></ellipseConnector></endConnector></llabel><atr id="10e" nullable="false" attributeType="VARCHAR2(128)"><children><e id="10f" x="2244.35644156019" y="2206.5439828185263" w="168" h="50"/><t id="110" x="2304.944286408823" y="2223.371925666732"><a><text><string>quantity</string></text></a></t></children></atr><llabel id="111"><points><p colinear="true" x="2050.83120690873" y="1880.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2309.2630564043266" y="2207.2389664883754" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="112"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="113"><Owner><e ref="10f"/></Owner></ellipseConnector></endConnector></llabel><atr id="114" nullable="false" attributeType="VARCHAR2(128)"><children><e id="115" x="2218.435791376831" y="2282.5439347832435" w="168" h="50"/><t id="116" x="2288.4556888377683" y="2299.371877631449"><a><text><string>price</string></text></a></t></children></atr><llabel id="117"><points><p colinear="true" x="2044.0675654410306" y="1880.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2287.7690944556634" y="2282.9580484809276" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="118"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="119"><Owner><e ref="115"/></Owner></ellipseConnector></endConnector></llabel><atr id="11a" nullable="false" attributeType="VARCHAR2(128)"><children><e id="11b" x="2016.8892486229179" y="2311.3584726452755" w="168" h="50"/><t id="11c" x="2074.1350677147148" y="2328.186415493481"><a><text><string>placed_at</string></text></a></t></children></atr><llabel id="11d"><points><p colinear="true" x="2027.844733694065" y="1880.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2097.3107007103577" y="2311.388193484461" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="11e"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="11f"><Owner><e ref="11b"/></Owner></ellipseConnector></endConnector></llabel><atr id="120" nullable="false" attributeType="VARCHAR2(128)"><children><e id="121" x="1815.3427058689322" y="2316.0003932873997" w="168" h="50"/><t id="122" x="1865.3764735691275" y="2332.8283361356052"><a><text><string>executed_at</string></text></a></t></children></atr><llabel id="123"><points><p colinear="true" x="2012.9974106270279" y="1880.2" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1906.1148360588406" y="2316.070737168798" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="124"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="125"><Owner><e ref="121"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="126" nullable="false" attributeType="NUMBER"><children><e id="127" x="998.083058356455" y="2160.6299128405326" w="168" h="50"/><t id="128" x="1076.4550218574316" y="2177.457855688738"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="129"><points><p colinear="true" x="1406.9170741899063" y="2067.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1136.516739013257" y="2166.499658457038" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="12a"><Owner><r ref="10"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="12b"><Owner><e ref="127"/></Owner></ellipseConnector></endConnector></llabel><atr id="12c" nullable="false" attributeType="VARCHAR2(128)"><children><e id="12d" x="1120.4853136832526" y="2342.098719045973" w="168" h="50"/><t id="12e" x="1192.185226708155" y="2358.926661894179"><a><text><string>type</string></text></a></t></children></atr><llabel id="12f"><points><p colinear="true" x="1474.3352523831288" y="2067.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1227.1422415288407" y="2342.9909576904956" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="130"><Owner><r ref="10"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="131"><Owner><e ref="12d"/></Owner></ellipseConnector></endConnector></llabel><atr id="132" nullable="false" attributeType="VARCHAR2(128)"><children><e id="133" x="1313.7545344307102" y="2444.861786567261" w="168" h="50"/><t id="134" x="1375.566385932175" y="2461.6897294154664"><a><text><string>amount</string></text></a></t></children></atr><llabel id="135"><points><p colinear="true" x="1498.099527896224" y="2067.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1404.5944779630238" y="2444.9336619281635" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="136"><Owner><r ref="10"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="137"><Owner><e ref="133"/></Owner></ellipseConnector></endConnector></llabel><atr id="138" nullable="false" attributeType="VARCHAR2(128)"><children><e id="139" x="1532.6454655692896" y="2444.861786567261" w="168" h="50"/><t id="13a" x="1592.0692936942896" y="2461.6897294154664"><a><text><string>currency</string></text></a></t></children></atr><llabel id="13b"><points><p colinear="true" x="1516.3004721037762" y="2067.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1610.805522036976" y="2444.9336619281635" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="13c"><Owner><r ref="10"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="13d"><Owner><e ref="139"/></Owner></ellipseConnector></endConnector></llabel><atr id="13e" nullable="false" attributeType="VARCHAR2(128)"><children><e id="13f" x="1725.9146863167473" y="2342.098719045973" w="168" h="50"/><t id="140" x="1780.3704816048332" y="2358.926661894179"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="141"><points><p colinear="true" x="1540.0647476168713" y="2067.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1788.2577584711591" y="2342.9909576904956" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="142"><Owner><r ref="10"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="143"><Owner><e ref="13f"/></Owner></ellipseConnector></endConnector></llabel><atr id="144" nullable="false" attributeType="VARCHAR2(128)"><children><e id="145" x="1848.316941643545" y="2160.6299128405326" w="168" h="50"/><t id="146" x="1900.7207120903224" y="2177.457855688738"><a><text><string>description</string></text></a></t></children></atr><llabel id="147"><points><p colinear="true" x="1607.4829258100938" y="2067.4" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1878.8832609867432" y="2166.499658457038" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="148"><Owner><r ref="10"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="149"><Owner><e ref="145"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="14a" nullable="false" attributeType="NUMBER"><children><e id="14b" x="252.258589427763" y="1492.032837799447" w="168" h="50"/><t id="14c" x="330.6305529287396" y="1508.8607806476525"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="14d"><points><p colinear="true" x="886.9" y="1634.0752827438127" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="405.842078709622" y="1532.2169867493667" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="14e"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="14f"><Owner><e ref="14b"/></Owner></ellipseConnector></endConnector></llabel><atr id="150" nullable="false" attributeType="VARCHAR2(128)"><children><e id="151" x="237.91286726673286" y="1651.985234661149" w="168" h="50"/><t id="152" x="293.4006678648774" y="1668.8131775093545"><a><text><string>username</string></text></a></t></children></atr><llabel id="153"><points><p colinear="true" x="886.9" y="1659.723316528001" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="406.4830957511068" y="1674.9166568698076" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="154"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="155"><Owner><e ref="151"/></Owner></ellipseConnector></endConnector></llabel><atr id="156" nullable="false" attributeType="VARCHAR2(128)"><children><e id="157" x="261.9966919876556" y="1810.7635026732946" w="168" h="50"/><t id="158" x="330.5405838943939" y="1827.5914455215002"><a><text><string>email</string></text></a></t></children></atr><llabel id="159"><points><p colinear="true" x="886.9" y="1685.7577393983129" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="408.71455432892077" y="1819.0089623671254" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="15a"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="15b"><Owner><e ref="157"/></Owner></ellipseConnector></endConnector></llabel><atr id="15c" nullable="false" attributeType="VARCHAR2(128)"><children><e id="15d" x="323.1296784555676" y="1959.2671287961575" w="168" h="50"/><t id="15e" x="379.52948924658324" y="1976.095071644363"><a><text><string>full_name</string></text></a></t></children></atr><llabel id="15f"><points><p colinear="true" x="927.2245603064812" y="1693" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="447.71399180642965" y="1962.318834711968" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="160"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="161"><Owner><e ref="15d"/></Owner></ellipseConnector></endConnector></llabel><atr id="162" nullable="false" attributeType="VARCHAR2(128)"><children><e id="163" x="417.8079369538603" y="2088.984499929924" w="167.99999999999994" h="50"/><t id="164" x="458.1696312897978" y="2105.8124427781295"><a><text><string>password_hash</string></text></a></t></children></atr><llabel id="165"><points><p colinear="true" x="953.2585420840991" y="1693" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="528.3249235586993" y="2090.22326742507" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="166"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="167"><Owner><e ref="163"/></Owner></ellipseConnector></endConnector></llabel><atr id="168" nullable="false" attributeType="VARCHAR2(128)"><children><e id="169" x="540.6049016380412" y="2190.1523416658747" w="168" h="50"/><t id="16a" x="575.1345723533732" y="2206.9802845140803"><a><text><string>available_balance</string></text></a></t></children></atr><llabel id="16b"><points><p colinear="true" x="968.3698114749144" y="1693" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="641.5712755917845" y="2190.6411916832512" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="16c"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="16d"><Owner><e ref="169"/></Owner></ellipseConnector></endConnector></llabel><atr id="16e" nullable="false" attributeType="VARCHAR2(128)"><children><e id="16f" x="640.7223063987228" y="2266.1523239014355" w="168" h="50"/><t id="170" x="676.3139735740158" y="2282.980266749641"><a><text><string>invested_balance</string></text></a></t></children></atr><llabel id="171"><points><p colinear="true" x="977.0053729758911" y="1693" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="735.8913835562713" y="2266.356399833859" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="172"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="173"><Owner><e ref="16f"/></Owner></ellipseConnector></endConnector></llabel><atr id="174" nullable="false" attributeType="VARCHAR2(128)"><children><e id="175" x="842.4778410735205" y="2298.9248820427115" w="168" h="50"/><t id="176" x="896.9336363616064" y="2315.752824890917"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="177"><points><p colinear="true" x="988.7948620053658" y="1693" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="929.4953810392356" y="2298.93620202953" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="178"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="179"><Owner><e ref="175"/></Owner></ellipseConnector></endConnector></llabel><atr id="17a" nullable="false" attributeType="VARCHAR2(128)"><children><e id="17b" x="1044.2333757483743" y="2295.7718205118454" w="168" h="50"/><t id="17c" x="1096.343162735679" y="2312.599763360051"><a><text><string>updated_at</string></text></a></t></children></atr><llabel id="17d"><points><p colinear="true" x="999.8636889022259" y="1693" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1123.5289174237262" y="2295.8202333224326" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="17e"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="17f"><Owner><e ref="17b"/></Owner></ellipseConnector></endConnector></llabel><atr id="180" nullable="false" attributeType="VARCHAR2(128)"><children><e id="181" x="450.70518982309187" y="1482.9692972727066" w="167.99999999999994" h="50"/><t id="182" x="505.1609851111778" y="1499.7972401209122"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="183"><points><p colinear="true" x="732.8424248553455" y="1225" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="552.674734208172" y="1483.5202022804615" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="184"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="185"><Owner><e ref="181"/></Owner></ellipseConnector></endConnector></llabel><atr id="186" nullable="false" attributeType="VARCHAR2(128)"><children><e id="187" x="290.3249763252388" y="1095.7772107098972" w="168" h="50"/><t id="188" x="358.25686872025835" y="1112.6051535581028"><a><text><string>name</string></text></a></t></children></atr><llabel id="189"><points><p colinear="true" x="652.9" y="1169.8975035352569" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="447.78360403401086" y="1134.141785250418" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="18a"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="18b"><Owner><e ref="187"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="18c" nullable="false" attributeType="NUMBER"><children><e id="18d" x="573.4605724100169" y="786.7889277472634" w="168" h="50"/><t id="18e" x="651.8325359109934" y="803.616870595469"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="18f"><points><p colinear="true" x="748.619854476264" y="1152" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="664.7710482664023" y="837.705969667015" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="190"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="191"><Owner><e ref="18d"/></Owner></ellipseConnector></endConnector></llabel><atr id="192" nullable="false" attributeType="VARCHAR2(128)"><children><e id="193" x="1339.7499074759312" y="1062.1" w="168" h="50"/><t id="194" x="1400.337752324564" y="1078.9279428482055"><a><text><string>quantity</string></text></a></t></children></atr><llabel id="195"><points><p colinear="true" x="1131.9489148679422" y="1255.5713816320224" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1385.107125586402" y="1110.1990956607503" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="196"><Owner><diamond ref="2e"/></Owner></diamondConnector></startConnector><endConnector><ellipseConnector id="197"><Owner><e ref="193"/></Owner></ellipseConnector></endConnector></llabel><atrderivado id="198"><children><e id="199" x="1386.0750236747613" y="1189.377210709897" w="168" h="50"><a><strokeDashes><doubleArray><double>5</double></doubleArray></strokeDashes><fillColor><color rgba="#ffffebeb"/></fillColor></a></e><t id="19a" x="1443.3268394706597" y="1206.2051535581027"><a><text><string>avg_price</string></text></a></t></children></atrderivado><llabel id="19b"><points><p colinear="true" x="1159.7317959892898" y="1269.0990950309958" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1397.616395965989" y="1227.741785250418" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="19c"><Owner><diamond ref="2e"/></Owner></diamondConnector></startConnector><endConnector><ellipseConnector id="19d"><Owner><e ref="199"/></Owner></ellipseConnector></endConnector></llabel><atr id="19e" nullable="false" attributeType="VARCHAR2(128)"><children><e id="19f" x="1386.0750236747613" y="1324.8227892901027" w="168" h="50"/><t id="1a0" x="1440.5308189628472" y="1341.6507321383083"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="1a1"><points><p colinear="true" x="1159.7317959892898" y="1295.100904969004" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1397.616395965989" y="1337.4582147495819" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="1a2"><Owner><diamond ref="2e"/></Owner></diamondConnector></startConnector><endConnector><ellipseConnector id="1a3"><Owner><e ref="19f"/></Owner></ellipseConnector></endConnector></llabel><atr id="1a4" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1a5" x="1339.7499074759312" y="1452.1" w="168" h="50"/><t id="1a6" x="1391.8596944632359" y="1468.9279428482055"><a><text><string>updated_at</string></text></a></t></children></atr><llabel id="1a7"><points><p colinear="true" x="1131.9489148679422" y="1308.6286183679774" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1385.107125586402" y="1455.0009043392495" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="1a8"><Owner><diamond ref="2e"/></Owner></diamondConnector></startConnector><endConnector><ellipseConnector id="1a9"><Owner><e ref="1a5"/></Owner></ellipseConnector></endConnector></llabel><atr id="1aa" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1ab" x="618.1457551736057" y="780.492813356838" w="168" h="50"/><t id="1ac" x="676.1295808571995" y="797.3207562050436"><a><text><string>added_at</string></text></a></t></children></atr><llabel id="1ad"><points><p colinear="true" x="910.35088986456" y="992.9615586761499" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="729.4983404514223" y="830.1709897408368" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="1ae"><Owner><diamond ref="34"/></Owner></diamondConnector></startConnector><endConnector><ellipseConnector id="1af"><Owner><e ref="1ab"/></Owner></ellipseConnector></endConnector></llabel><atr id="1b0" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1b1" x="1386.0750236747613" y="1589.1" w="168" h="50"/><t id="1b2" x="1419.2786674735894" y="1605.9279428482055"><a><text><string>reserved_quantity</string></text></a></t></children></atr><llabel id="1b3"><points><p colinear="true" x="1122.1878949476747" y="1313.3813392750108" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1442.7237232517468" y="1590.5249334883308" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="1b4"><Owner><diamond ref="2e"/></Owner></diamondConnector></startConnector><endConnector><ellipseConnector id="1b5"><Owner><e ref="1b1"/></Owner></ellipseConnector></endConnector></llabel><atr id="1b6" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1b7" x="300" y="1330" w="168" h="50"/><t id="1b8" x="326.4" y="1346.8"><a><text><string>reserved_balance</string></text></a></t></children></atr><llabel id="1b9"><points><p colinear="true" x="992.4" y="1656.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="384.0" y="1355.0" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1ba"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1bb"><Owner><e ref="1b7"/></Owner></ellipseConnector></endConnector></llabel><atr id="1bc" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1bd" x="2380" y="1690" w="168" h="50"/><t id="1be" x="2410.0" y="1706.8"><a><text><string>filled_quantity</string></text></a></t></children></atr><llabel id="1bf"><points><p colinear="true" x="2022.0" y="1843.7" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2464.0" y="1715.0" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1c0"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1c1"><Owner><e ref="1bd"/></Owner></ellipseConnector></endConnector></llabel><rel id="1c2"><children><diamond id="1c3" x="2130" y="1420" w="200" h="96"/><t id="1c4" x="2197.2" y="1459.8"><a><text><string>FillsBuy</string></text></a></t></children></rel><llabelUm id="1c5"><points><p colinear="true" x="2022.0" y="1843.7" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2230.0" y="1468.0" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1c6"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="1c7"><Owner><diamond ref="1c3"/></Owner></diamondConnector></endConnector></llabelUm><llabelMuitos id="1c8"><points><p colinear="true" x="2230.0" y="1468.0" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2583.6" y="1094.9" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="1c9"><Owner><diamond ref="1c3"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="1ca"><Owner><r ref="7"/></Owner></rConnector></endConnector></llabelMuitos><rel id="1cb"><children><diamond id="1cc" x="2130" y="1570" w="200" h="96"/><t id="1cd" x="2193.1" y="1609.8"><a><text><string>FillsSell</string></text></a></t></children></rel><llabelUm id="1ce"><points><p colinear="true" x="2022.0" y="1843.7" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2230.0" y="1618.0" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1cf"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="1d0"><Owner><diamond ref="1cc"/></Owner></diamondConnector></endConnector></llabelUm><llabelMuitos id="1d1"><points><p colinear="true" x="2230.0" y="1618.0" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2583.6" y="1094.9" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="1d2"><Owner><diamond ref="1cc"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="1d3"><Owner><r ref="7"/></Owner></rConnector></endConnector></llabelMuitos><rel id="1d4"><children><diamond id="1d5" x="1922" y="2560" w="200" h="96"/><t id="1d6" x="2005.6" y="2599.8"><a><text><string>Logs</string></text></a></t></children></rel><ent id="1d7"><children><r id="1d8" x="1917" y="2780" w="210" h="72"/><t id="1d9" x="1976.9" y="2807.8"><a><text><string>OrderEvents</string></text></a></t></children></ent><llabelUm id="1da"><points><p colinear="true" x="2022.0" y="1843.7" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2022.0" y="2608.0" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1db"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="1dc"><Owner><diamond ref="1d5"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="1dd"><points><p colinear="true" x="2022.0" y="2608.0" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2022.0" y="2816.0" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="1de"><Owner><diamond ref="1d5"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="1df"><Owner><r ref="1d8"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><atrchave id="1e0" nullable="false" attributeType="NUMBER"><children><e id="1e1" x="1640" y="2700" w="168" h="50"/><t id="1e2" x="1716.8" y="2716.8"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="1e3"><points><p colinear="true" x="2022.0" y="2816.0" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1724.0" y="2725.0" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1e4"><Owner><r ref="1d8"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1e5"><Owner><e ref="1e1"/></Owner></ellipseConnector></endConnector></llabel><atr id="1e6" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1e7" x="1620" y="2860" w="168" h="50"/><t id="1e8" x="1668.0" y="2876.8"><a><text><string>event_type</string></text></a></t></children></atr><llabel id="1e9"><points><p colinear="true" x="2022.0" y="2816.0" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1704.0" y="2885.0" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1ea"><Owner><r ref="1d8"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1eb"><Owner><e ref="1e7"/></Owner></ellipseConnector></endConnector></llabel><atr id="1ec" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1ed" x="1760" y="2960" w="168" h="50"/><t id="1ee" x="1815.2" y="2976.8"><a><text><string>quantity</string></text></a></t></children></atr><llabel id="1ef"><points><p colinear="true" x="2022.0" y="2816.0" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1844.0" y="2985.0" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1f0"><Owner><r ref="1d8"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1f1"><Owner><e ref="1ed"/></Owner></ellipseConnector></endConnector></llabel><atr id="1f2" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1f3" x="1940" y="3000" w="168" h="50"/><t id="1f4" x="2006.0" y="3016.8"><a><text><string>price</string></text></a></t></children></atr><llabel id="1f5"><points><p colinear="true" x="2022.0" y="2816.0" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2024.0" y="3025.0" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1f6"><Owner><r ref="1d8"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1f7"><Owner><e ref="1f3"/></Owner></ellipseConnector></endConnector></llabel><atr id="1f8" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1f9" x="2120" y="2960" w="168" h="50"/><t id="1fa" x="2160.8" y="2976.8"><a><text><string>status_after</string></text></a></t></children></atr><llabel id="1fb"><points><p colinear="true" x="2022.0" y="2816.0" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2204.0" y="2985.0" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1fc"><Owner><r ref="1d8"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1fd"><Owner><e ref="1f9"/></Owner></ellipseConnector></endConnector></llabel><atr id="1fe" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1ff" x="2270" y="2860" w="168" h="50"/><t id="200" x="2318.0" y="2876.8"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="201"><points><p colinear="true" x="2022.0" y="2816.0" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2354.0" y="2885.0" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="202"><Owner><r ref="1d8"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="203"><Owner><e ref="1ff"/></Owner></ellipseConnector></endConnector></llabel></figures></drawing>
Index: docs/P1-ConceptualModel/wiki/ERModel.md
===================================================================
--- docs/P1-ConceptualModel/wiki/ERModel.md	(revision ef1c1c725137d93fa85292f43440214aaddcdf05)
+++ docs/P1-ConceptualModel/wiki/ERModel.md	(revision ef1c1c725137d93fa85292f43440214aaddcdf05)
@@ -0,0 +1,307 @@
+= Entity-Relationship Model v.04 =
+
+== Diagram ==
+
+[[Image(ERModel_v04.png, 800px)]]
+
+Notation: Chen. Rectangles are entity sets, diamonds are relationships, ellipses
+are attributes, underlined ellipses are primary keys, the dashed ellipse is a
+derived attribute. A double line between an entity set and a relationship marks
+'''total participation''' (every instance of that entity set must participate); a
+single line marks partial participation.
+
+Two deliberate modeling decisions worth stating up front:
+
+ * '''No foreign keys appear in the diagram.''' Connections between entity sets are expressed as relationships, per the notation. Foreign-key columns appear only in the relational model in [wiki:RelationalDesign].
+ * '''`Holds` and `Contains` are relationships, not entity sets.''' Both are M:N and both carry their own attributes, which is exactly what a Chen relationship is for. They become tables (`holdings`, `watchlist_items`) only in P2.
+
+== Data requirements ==
+
+Each entity set is given as a short rationale for why it exists as its own set,
+its keys, and its attributes as a table. Each relationship is given as its
+cardinality and participation, a short rationale, and — where it carries data —
+an attribute table.
+
+=== Entity sets ===
+
+==== Users ====
+Registered participants of the platform. Every action in the simulation is
+attributed to a user, and the two balance attributes are what makes the
+simulation work: cash that is free to trade is tracked separately from cash
+that is currently committed to open positions, so the platform can refuse a
+purchase without having to recompute the whole portfolio first.
+
+'''Keys:''' candidates `{id}`, `{username}`, `{email}`; primary key '''`id`'''. A
+surrogate UUID was chosen because it is opaque and stable — `username` and
+`email` are both things a user may legitimately want to change later, and
+every relationship in the diagram points at `Users`, so a mutable key would
+propagate changes across the whole database.
+
+||= Attribute =||= Type =||= Constraints =||
+|| `id` || UUID || PK, required ||
+|| `username` || text(50) || required, unique ||
+|| `email` || text(255) || required, unique, contains `@` ||
+|| `full_name` || text(200) || optional ||
+|| `password_hash` || text(255) || required — never the password itself; the prototype stores a SHA-256 hex digest ||
+|| `available_balance` || numeric(18,4) || required, default 0, ≥ 0 ||
+|| `invested_balance` || numeric(18,4) || required, default 0, ≥ 0 ||
+|| `reserved_balance` || numeric(18,4) || required, default 0, ≥ 0 — cash set aside for the user's open buy orders (added in v04, after P7) ||
+|| `created_at` || timestamptz || required, defaults to now ||
+|| `updated_at` || timestamptz || optional (null until first change) ||
+
+==== Cryptos ====
+The catalog of crypto assets the platform knows about. Kept separate from
+`Markets` because an asset exists independently of the pairs it is traded in —
+the same asset can be quoted against several currencies, and a user's holding is
+in the ''asset'', not in a particular pair.
+
+'''Keys:''' candidates `{id}`, `{symbol}`; primary key '''`id`''', for the same
+reason as in `Users`. `symbol` is kept as a unique natural key because that is
+what users type and see.
+
+||= Attribute =||= Type =||= Constraints =||
+|| `id` || UUID || PK, required ||
+|| `symbol` || text(20) || required, unique (e.g. `BTC`) ||
+|| `name` || text(255) || required (e.g. `Bitcoin`) ||
+|| `created_at` || timestamptz || required, defaults to now ||
+
+==== Markets ====
+A tradeable pair: one crypto asset quoted in one currency, e.g. BTC/USD. This is
+where prices live, and it is the thing an order is placed ''on''. Modeled as its
+own entity set rather than an attribute of `Cryptos` because a market has its own
+lifecycle — it can be deactivated without deleting the asset — and because
+trades, candles and orders all reference the pair, not the asset.
+
+'''Keys:''' candidates `{id}`, `{crypto_id, quote_currency}` — that pair is
+unique by definition, since a given asset can only be quoted once per
+currency; primary key '''`id`''', so that the many entity sets referencing a
+market carry one narrow column instead of a composite key.
+
+||= Attribute =||= Type =||= Constraints =||
+|| `id` || UUID || PK, required ||
+|| `quote_currency` || text(3) || required, default `USD` ||
+|| `is_active` || boolean || required, default true — inactive markets are hidden from the trading menus but keep their history ||
+|| `created_at` || timestamptz || required, defaults to now ||
+
+==== Orders ====
+A user's instruction to buy or sell on a market. Needed as a separate entity set
+because an order is a record of ''intent'' that outlives its execution: it keeps
+the requested quantity and price even after it has been filled, which is what
+makes the ledger auditable.
+
+Placing an order is what triggers a '''reservation''' of whatever it commits:
+the crypto being sold (`Holds.reserved_quantity`, below) on a sell, and the
+cash (`Users.reserved_balance`) on a buy. Since v04 (after P7) an order can
+wait in the order book and be filled in parts, so `status` is a real
+lifecycle driven by `filled_quantity`: `open` (nothing filled yet),
+`partially_filled`, `executed` (completely filled), or `cancelled`, which
+releases what is still reserved. See
+[wiki:UseCase0005] for the reserve-then-settle
+sequence and
+[wiki:AdvancedDatabaseDevelopment]
+for the rules that keep it consistent.
+
+'''Keys:''' candidate `{id}` only — there is no natural key, since the same user
+can place two identical orders on the same market in the same second, and both
+are legitimately distinct; primary key '''`id`'''.
+
+||= Attribute =||= Type =||= Constraints =||
+|| `id` || UUID || PK, required ||
+|| `side` || text || required, `buy` or `sell` ||
+|| `type` || text || required, `market` or `limit` (both executed since P7) ||
+|| `status` || text || required, `open`, `partially_filled`, `executed` or `cancelled` ||
+|| `quantity` || numeric(20,4) || required, > 0 ||
+|| `filled_quantity` || numeric(20,4) || required, default 0, between 0 and `quantity` — how much has been traded; remaining = `quantity − filled_quantity` (added in v04, after P7) ||
+|| `price` || numeric(18,6) || the limit price; for a market order, the market price when it was placed ||
+|| `placed_at` || timestamptz || required, defaults to now ||
+|| `executed_at` || timestamptz || optional, set when the order settles ||
+
+==== Transactions ====
+The financial ledger: every movement of virtual cash, in one place. This exists
+so that a balance is never just a number someone edited — it is the sum of an
+auditable list of entries, which is also what the "explain every step" goal of
+the project needs.
+
+'''Keys:''' candidate `{id}` only; primary key '''`id`'''.
+
+||= Attribute =||= Type =||= Constraints =||
+|| `id` || UUID || PK, required ||
+|| `type` || text || required, `deposit`, `buy`, `sell` or `fee` ||
+|| `amount` || numeric(18,4) || required, signed — negative for money leaving the cash balance, positive for money arriving ||
+|| `currency` || text(3) || required, default `USD` ||
+|| `created_at` || timestamptz || required, defaults to now ||
+|| `description` || text || optional, free-form ||
+
+==== !MarketTrades ====
+Individual executed trades on a market, from the user's own fills and from the
+market simulator. This is the single source of truth for the current price: the
+price of a market is the price of its most recent trade, never a column someone
+writes directly.
+
+'''Keys:''' candidate `{id}` — `{market_id, executed_at}` looks unique in
+principle, but two trades can share a timestamp, so it is not a safe key;
+primary key '''`id`''' (a plain auto-incrementing integer here rather than a
+UUID, because this is the highest-volume entity set and it is only ever read
+in timestamp order, never referenced by anything else).
+
+||= Attribute =||= Type =||= Constraints =||
+|| `id` || integer || PK, required, auto-generated ||
+|| `executed_at` || timestamptz || required ||
+|| `price` || numeric(18,6) || required, > 0 ||
+|| `quantity` || numeric(20,6) || required, > 0 ||
+|| `side` || text || optional, `buy` or `sell` ||
+|| `source` || text(50) || required, default `simulation` — distinguishes a simulated trade from a user's own fill (`user`) ||
+
+Since v04 (after P7) a trade also records which orders it filled, through the
+relationships `FillsBuy` and `FillsSell` below.
+
+==== !OrderEvents ====
+''Added in v04, after P7.'' The audit trail of an order: one event for its
+placement, one for every (partial) fill, and one for a cancellation. The
+`Orders` row only holds the current state; this entity keeps the history of
+how the order got there. Events are recorded automatically by the database.
+
+'''Keys:''' candidate `{id}` only; primary key '''`id`''' (auto-incrementing
+integer, events are only read in order).
+
+||= Attribute =||= Type =||= Constraints =||
+|| `id` || integer || PK, required, auto-generated ||
+|| `event_type` || text || required, `placed`, `partially_filled`, `filled` or `cancelled` ||
+|| `quantity` || numeric(20,4) || required — the ordered quantity for `placed`, the filled amount for a fill, the unfilled rest for `cancelled` ||
+|| `price` || numeric(18,6) || optional — the order price, or the trade price for a fill ||
+|| `status_after` || text || required, the order's status after the event ||
+|| `created_at` || timestamptz || required, defaults to now ||
+
+==== !MarketCandles ====
+OHLCV aggregates per market and timeframe — the data a price chart is drawn
+from. Stored rather than computed on the fly because the point of the project is
+a chart-driven interface, and re-aggregating the whole trade history for every
+screen refresh does not scale.
+
+'''Keys:''' candidates `{id}`, `{market_id, timeframe, candle_time}` — a market
+has exactly one candle per timeframe per time bucket; primary key '''`id`''', the
+composite is enforced as a uniqueness rule because it is the real-world
+constraint and it is what prevents duplicate candles.
+
+||= Attribute =||= Type =||= Constraints =||
+|| `id` || integer || PK, required, auto-generated ||
+|| `timeframe` || text || required, `1m`, `5m`, `1h` or `1d` ||
+|| `open`, `high`, `low`, `close` || numeric(18,6) || all required ||
+|| `volume` || numeric(20,6) || required ||
+|| `candle_time` || timestamptz || required — the start of the bucket ||
+
+==== Watchlists ====
+A named list of assets a user wants to monitor. A separate entity set rather than
+a flag on the relationship between users and assets, because a user may want
+several lists ("long term", "watching today") and each needs its own name.
+
+'''Keys:''' candidate `{id}` — `{user_id, name}` would also work if list names
+were required to be unique per user, which the model does not impose, so it is
+not listed as a candidate key; primary key '''`id`'''.
+
+||= Attribute =||= Type =||= Constraints =||
+|| `id` || UUID || PK, required ||
+|| `name` || text(100) || required ||
+|| `created_at` || timestamptz || required, defaults to now ||
+
+=== Relationships ===
+
+==== !QuotedOn — Cryptos (1) : Markets (N), total on Markets ====
+Ties a market to the asset it trades. One asset can be quoted in many markets;
+every market must have exactly one asset, hence total participation on the
+`Markets` side. No attributes.
+
+==== !PlacedOn — Markets (1) : Orders (N), total on Orders ====
+Records which market an order was placed on. Every order must name a market;
+a market may have no orders yet. No attributes.
+
+==== Places — Users (1) : Orders (N), total on Orders ====
+Records who placed an order. Every order belongs to exactly one user; a new
+user has no orders. No attributes.
+
+==== Records — Users (1) : Transactions (N), total on Transactions ====
+Attributes each ledger entry to a user. Every entry belongs to exactly one
+user. No attributes.
+
+==== Settles — Orders (1) : Transactions (N), partial on both sides ====
+Links a ledger entry to the order that caused it. Partial on the
+`Transactions` side because deposits have no originating order, and partial on
+the `Orders` side because an order that never executes never produces a
+ledger entry — which is why the corresponding column is nullable in P2. No
+attributes.
+
+==== Fills — Markets (1) : !MarketTrades (N), total on !MarketTrades ====
+Every executed trade happened on exactly one market. No attributes.
+
+==== !FillsBuy — Orders (1) : !MarketTrades (N), partial on both sides ====
+''Added in v04, after P7.'' The buy order a trade filled. An order can be
+filled by many trades (partial fills); a trade fills at most one buy order,
+and none when the simulated market was the buyer. No attributes.
+
+==== !FillsSell — Orders (1) : !MarketTrades (N), partial on both sides ====
+''Added in v04, after P7.'' The sell order a trade filled, symmetric to
+`FillsBuy`. A trade between two users' orders participates in both. No
+attributes.
+
+==== Logs — Orders (1) : !OrderEvents (N), total on !OrderEvents ====
+''Added in v04, after P7.'' Every event belongs to exactly one order. No
+attributes.
+
+==== Aggregates — Markets (1) : !MarketCandles (N), total on !MarketCandles ====
+Every candle summarises trades of exactly one market. No attributes.
+
+==== Owns — Users (1) : Watchlists (N), total on Watchlists ====
+Every watchlist belongs to exactly one user. No attributes.
+
+==== Holds — Users (M) : Cryptos (N), partial on both sides, '''with attributes''' ====
+A user's position in an asset. M:N because one user holds many assets and one
+asset is held by many users, and partial on both sides because a user may hold
+nothing and an asset may be held by nobody. Modeled as a relationship rather
+than an entity set because a position has no identity of its own — it is
+entirely described by ''which user'', ''which asset'', and how much.
+
+`reserved_quantity` mirrors `available_balance`/`invested_balance` on `Users`:
+two independently updated stored numbers, with the amount actually free to use
+computed on demand rather than stored (`quantity − reserved_quantity` here,
+`available_balance` alone on the cash side). Without it, nothing stopped a
+user from placing a second sell order against crypto already promised to a
+first one — `quantity` alone cannot tell "owned" apart from "owned, but
+already committed elsewhere." See history, v03.
+
+||= Attribute =||= Type =||= Constraints =||
+|| `quantity` || numeric(20,4) || required, ≥ 0 — total amount owned ||
+|| `reserved_quantity` || numeric(20,4) || required, default 0, `0 ≤ reserved_quantity ≤ quantity` — committed to the user's own open sell orders, not yet removed from the position ||
+|| `avg_price` || numeric(18,6) || required, ≥ 0, '''derived''' (dashed ellipse) — the weighted average of the prices at which the position was accumulated; derivable from the buy history, stored anyway so unrealised P/L can be shown without replaying the whole ledger ||
+|| `created_at` || timestamptz || required, defaults to now ||
+|| `updated_at` || timestamptz || optional ||
+
+==== Contains — Watchlists (M) : Cryptos (N), partial on both sides, '''with attribute''' ====
+Which assets are on which watchlist. M:N: a list holds many assets, an asset
+appears on many lists. Partial on both sides — an empty list is valid and an
+asset need not be on any list.
+
+||= Attribute =||= Type =||= Constraints =||
+|| `added_at` || timestamptz || required, defaults to now — recorded so a list can be shown in the order the user built it ||
+
+== Entity-Relationship Model History ==
+
+ * '''v01''' — First complete version. Built from the entity notes in `ep-diagram.md` (the initial hand-written model), with three changes made to that initial model while drawing it:
+   1. `Markets` was promoted from an implied attribute of the asset to its own entity set, so that prices, orders, trades and candles can all reference a pair rather than an asset.
+   2. `holdings` and `watchlist_items` were re-expressed as the M:N relationships `Holds` and `Contains` with their own attributes, instead of entity sets with foreign keys — the initial notes listed them as tables, which is a relational concept that does not belong in a Chen ERD.
+   3. `avg_price` was marked as a derived attribute rather than a plain one, to make the denormalisation explicit rather than hidden.
+ * '''v02''' — Student review pass over the AI-generated v01 in the TerraER GUI.
+ * '''v03''' — Added `reserved_quantity` to `Holds`, and reworded `Orders.status` to state its reserve → settle → (cancel) lifecycle explicitly, instead of leaving `open`/`cancelled` as unused enum values. Triggered by a design review that pointed out the model had no way to stop a user from placing a second sell order against crypto already promised to a first, unsettled one — `quantity` alone cannot distinguish "owned" from "owned, but already committed." Also redrawn more compactly: every entity and relationship (with its own attributes moved along with it) was pulled proportionally toward the diagram's centroid, shrinking the canvas by roughly 45% with the same topology and no new overlaps. See [wiki:ERModelAIUsage] for the reasoning and how the diagram file itself was produced, and [wiki:RelationalDesign] and [wiki:UseCase0005] for how the new attribute is enforced.
+ * '''v04 — after P7.''' Phase 7 (order, balance and trade consistency) needed data the model did not have, so the model was extended to stay in line with the database:
+   * `Users.reserved_balance`: cash reserved by open buy orders;
+   * `Orders.filled_quantity` and the status value `partially_filled`: orders can now be filled in parts;
+   * the relationships `FillsBuy` and `FillsSell` between `Orders` and `MarketTrades`: which orders a trade filled;
+   * the entity set `OrderEvents` with the relationship `Logs`: the automatically recorded history of every order.
+
+  Nothing existing was removed or changed. See
+  [wiki:AdvancedDatabaseDevelopment].
+  The diagram files are `ERModel_v04.xml` / `ERModel_v04.png`; earlier versions
+  are kept.
+
+Reasoning for the AI-assisted part of this phase, and the full interaction log,
+are on [wiki:ERModelAIUsage].
+
Index: docs/P1-ConceptualModel/wiki/ERModelAIUsage.md
===================================================================
--- docs/P1-ConceptualModel/wiki/ERModelAIUsage.md	(revision ef1c1c725137d93fa85292f43440214aaddcdf05)
+++ docs/P1-ConceptualModel/wiki/ERModelAIUsage.md	(revision ef1c1c725137d93fa85292f43440214aaddcdf05)
@@ -0,0 +1,306 @@
+= Entity-Relationship Model AI Usage =
+
+== Name of AI service/solution that was used ==
+
+'''Claude Code''' (Anthropic)
+
+ * '''URL:''' `https://claude.com/claude-code`
+ * '''Type of service/subscription:''' Claude subscription. Session 1 used model
+   Claude Opus 4.7 (1M context); session 2 used Claude Opus 5 (1M context).
+
+== Final result ==
+
+=== Diagram ===
+
+`ERModel_v01.xml` / `ERModel_v01.png`.
+
+'''Declaration of how the diagram was produced.''' The initial model is the
+student's own: the entity and attribute list in `ep-diagram.md`,
+written in Macedonian before any AI was involved. In session 2 the AI turned that
+list into the TerraER diagram file, and while doing so proposed three changes to
+the initial model, all three listed in the model history on
+[wiki:ERModel]:
+promoting `Markets` to its own entity set, re-expressing `holdings` and
+`watchlist_items` as M:N relationships with attributes rather than entity sets
+with foreign keys, and marking `avg_price` as derived.
+
+The diagram was not drawn by hand in the TerraER GUI. It was generated
+programmatically by constructing TerraER's own figure objects
+(`EntidadeFigure`, `RelacionamentoFigure`, `AtributoFigure`,
+`AtributoChaveFigure`, `AtributoDerivadoFigure` and the labelled line-connection
+figures) and serialising them with TerraER's own
+`DOMStorableInputOutputFormat` — the same writer the application uses when you
+choose ''Save''. The file is therefore a normal TerraER document: it was verified
+by reading it back through TerraER's own reader and comparing the figure count
+(144), and it opens and can be edited in TerraER 3.11 like any hand-drawn
+diagram. `ERModel_v02.xml` is the student's own review pass over v01, done by
+hand in the GUI.
+
+`ERModel_v03.xml` / `ERModel_v03.png` (session 3, 2026-09-16) were produced the
+same way, this time as a genuine load–modify–save round trip through TerraER's
+own classes rather than a from-scratch build: `ERModel_v02.xml` was read with
+the application's real `DrawFigureFactory` and `DOMStorableInputOutputFormat`
+into a live `QuadTreeDrawing`, one `AtributoFigure` was cloned from the
+existing `quantity` attribute of `Holds` (to inherit its exact styling) and
+relabelled `reserved_quantity`, a matching `LabeledLineConnectionFigure` was
+added between it and the `Holds` diamond (`ChopDiamondConnector` /
+`ChopEllipseConnector`, the same connector pair every other attribute of
+`Holds` uses), and every entity and relationship — together with its own
+attributes, moved by the same offset — was translated proportionally toward
+the diagram's centroid to close up excess canvas space, after which every
+connection figure had `updateConnection()` called so its drawn path follows
+the moved figures. The result was written with the real writer and rendered to
+PNG with TerraER's own `ImageOutputFormat`, and re-verified by reading
+`ERModel_v03.xml` back and confirming the figure count (146 = 144 + the new
+attribute + its line) and that all five attributes of `Holds` resolve with the
+expected connector classes. No figure was hand-edited in XML.
+
+=== Model description ===
+
+See [wiki:ERModel].
+
+== Summary of AI involvement ==
+
+Work on this project happened in three working sessions.
+
+||= =||= Session 1 =||= Session 2 =||= Session 3 =||
+|| '''When''' || 2026-04-21 || 2026-08-06 / 2026-08-07 || 2026-09-16 ||
+|| '''Model''' || Claude Opus 4.7 (1M context) || Claude Opus 5 (1M context) || Claude Sonnet 5 ||
+|| '''Phases advanced''' || P1, P2, P3 and the first working prototype || The ER diagram file, P4 documentation, bug fixes || `Holds.reserved_quantity` added across P1–P4 ||
+|| '''My starting material''' || `ep-diagram.md`, `opis.md`, my existing Go backend and draft SQL || Everything from session 1, plus the phase rubric || Everything from sessions 1–2, plus a design review of the sell-order flow ||
+
+In '''session 1''' I brought my own data model (`ep-diagram.md`, written in
+Macedonian before any AI was involved) and my own draft schema and Go backend. I
+used the AI to review them, and it found real errors in my SQL that I had missed
+— most seriously that I had declared `crypto_id` as a foreign key to two
+different tables at once, in three separate tables. I decided the corrections to
+adopt, chose to go solo, chose a CLI prototype over an HTTP one, and chose
+English for the documentation. The output of that session was the corrected
+schema, the sample-data script, the use-case model and the working prototype.
+
+In '''session 2''' I came back to produce the deliverable I was still missing — the
+TerraER diagram file itself — and to finish the P4 documentation. I also asked
+for a review pass over the database and Go code, which turned up three further
+bugs (see [wiki:PrototypeImplementationAIUsage]).
+
+In '''session 3''' I described a concrete edge case I'd spotted in the sell flow
+— nothing stopped a user from placing a second sell order against crypto
+already promised to a first, unsettled one — and asked the AI to fix it
+starting from P1 and carry the fix through every phase. This added
+`reserved_quantity` to `Holds` and changed the sell path in `trade.go` to use
+it; see the model history on
+[wiki:ERModel] (v03) and the log
+below.
+
+Below is the log, one entry per exchange. My prompts are quoted as '''excerpts''':
+the wording is my own, unaltered, but I have left out scheduling remarks and
+other working chatter that says nothing about the model or the code. Typos are
+kept as they were. The ''Intent'' line above each prompt is my own note on what I
+was trying to achieve. AI responses are summarised rather than quoted in full,
+because several ran to many pages of code and file edits. The complete
+unabridged transcript is in my Claude Code session history and can be produced
+on request.
+
+== Entire AI usage log ==
+
+----
+
+=== Session 1 — 2026-04-21 ===
+
+'''Intent:''' hand the AI the whole project and the course rubric, and have it
+audit my existing model and code against the phase requirements before I commit
+to anything.
+
+'''Prompt (student, excerpt):'''
+> 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
+
+'''Response (AI, summarised):'''
+ * Read `docs/opis.md`, `docs/ep-diagram.md`, `docs/dbdiagram.md`, `server/db/db.sql`, `server/db/schema.sql`, all Go sources.
+ * Flagged bugs in the initial schema:
+   * `holdings.crypto_id` declared as a foreign key to both `users(id)` and `crypto(id)`; should be a separate `user_id` column.
+   * Same mistake in `orders` and `transactions`.
+   * `market_candles` referenced a non-existent `markets` table.
+   * `main.go` dropped and recreated all tables on every startup, wiping data.
+ * Proposed a single authoritative schema, to be placed in `server/db/schema_creation.sql`, based on `docs/ep-diagram.md` and `docs/dbdiagram.md` with the above issues fixed.
+ * Asked the student for decisions: team composition, prototype shape (CLI vs HTTP), whether to keep `available_balance`, `invested_balance`, `secret_question`, `secret_answer`, which use cases to implement, language of documentation.
+
+'''Intent:''' I had just pasted the course rubric into `README.md` and removed the
+half-finished frontend, so that the AI would plan against the actual phase
+requirements and against a backend-only prototype.
+
+'''Prompt (student, excerpt):'''
+> Read it now, just filled it in, also deleted the frontend we don' need that
+
+'''Response (AI, summarised):'''
+ * Re-read `docs/README.md`, which now contained the course phase rubric (P0–P9).
+ * Explained the constraints each phase places on AI usage (P0 forbids AI; P1–P4 allow AI only to improve the student's own initial model and require an AIUsage log).
+ * Listed the deliverables per phase and asked the remaining questions.
+
+----
+
+=== Session 2 — 2026-08-06 / 2026-08-07 ===
+
+'''Intent:''' re-read the rubric from scratch after the gap, reduce it to a
+checklist of what each phase actually has to produce, confirm TerraER runs on
+this machine.
+
+'''Prompt (student, excerpt):'''
+> We will start from the begining in some ways, please read first docs/insturctions.md
+> The goal is to finish with milestone 0 so I can publish it […]
+> Read the Instuctions.md like I said and delete everything that you think we don't need
+> and for each phrase tell me what do I need to submit and how to do it. and can you also
+> do the thing with TerraER3.11.jar?
+
+'''Response (AI, summarised):'''
+ * Read the phase rubric and condensed `Instructions.md` to a per-phase checklist
+   of deliverables, keeping every requirement and every load-bearing filename.
+ * Confirmed TerraER 3.11 runs on the installed OpenJDK 21 and launched it.
+ * Listed, per phase, what has to be submitted and how; flagged that P0's
+   deliverables are wiki pages, that the EPRMS proposal is a prerequisite.
+ * Flagged `image.png` (a !TradingView screenshot) as material the project has no
+   licence to publish.
+
+'''Intent:''' produce the artefacts still missing for P1–P4 — above all the TerraER
+diagram — while keeping P0 for myself, since AI use is forbidden there.
+
+'''Prompt (student, excerpt):'''
+> […] do all of the other Phases till m0.
+> opis.md It's p0 so I will take care of that. Delete anything that we don't need,
+> make all of the phases and terra diagram if you can, and delete anything
+> that we don't need and make a documentation about how to start it.
+
+'''Intent:''' ask for a review pass over the schema and the Go code rather than
+only documentation, on the grounds that a prototype I have to defend in person
+should not have known defects in it.
+
+'''Prompt (student, excerpt, follow-up):'''
+> Also fix some database things or golang things if you think we can do it better,
+
+'''Response (AI, summarised) — the part relevant to P1:'''
+ * Read `ep-diagram.md` (the student's own initial model) and the existing
+   `schema_creation.sql`.
+ * Reverse-engineered TerraER's file format from the distributed jar to learn the
+   element names it stores figures under (`ent`, `rel`, `atr`, `atrchave`,
+   `atrderivado`, `llabelUm`, `llabelMuitos`, `llabelDoubleUm`,
+   `llabelDoubleMuitos`, …).
+ * Generated `ERModel_v01.xml` and `ERModel_v01.png` as described above, in Chen
+   notation: 8 entity sets, 10 relationships, 57 attributes, cardinality labels
+   on every relationship line and double lines for total participation.
+ * Proposed the three changes to the initial model recorded in the model history.
+ * Rewrote [wiki:ERModel] with the per-entity documentation, candidate-key
+   justifications and attribute types the phase template requires.
+
+----
+
+> '''Student action required.''' Two things, in this order:
+>
+> 1. Open `ERModel_v01.xml` in TerraER, read the whole diagram, and change what
+>    you disagree with. Save the result as `ERModel_v02.xml` with a matching PNG
+>    and add a history line. The phase rules require that the model be yours;
+>    the generated v01 is a starting point to review and take over, not an
+>    answer to submit unread.
+> 2. Verify that this log matches your recollection and append the full text of
+>    any further prompts. The complete transcript is in your Claude Code session
+>    history.
+
+----
+
+=== Session 3 — 2026-09-16 ===
+
+'''Intent:''' describe a concrete gap I'd found in the sell-order design — the
+model had no way to represent crypto committed to an order that had not yet
+settled — and have the AI trace the fix through every phase rather than patch
+`trade.go` alone.
+
+'''Prompt (student, excerpt):'''
+> Suppose the user owns 2 BTC and wants to sell 0.5 BTC at market price. […] You
+> currently have Holds: quantity, avg_price but you don't have a concept of
+> reserved/committed crypto. For cash, you already explicitly distinguish
+> available_balance, invested_balance. For crypto, you probably want the
+> equivalent: quantity, reserved_quantity, avg_price. […] 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.
+
+'''Response (AI, summarised):'''
+ * Read every phase document and the live `server/trade.go`, `portfolio.go` and
+   `schema_creation.sql` to confirm the actual gap: the sell path checked
+   `holdings.quantity` directly, with nothing recording that part of a position
+   was already promised to another order.
+ * Added `reserved_quantity` to `Holds` (P1), `holdings` (P2), the sell scenario
+   SQL (P3), and `trade.go`/`portfolio.go`/`schema_creation.sql` (P4) — one
+   attribute threaded consistently through all four phases rather than a
+   patch confined to the Go code.
+ * Changed the sell path to lock the holding row, compute
+   `available = quantity − reserved_quantity`, reserve (`reserved_quantity += qty`)
+   and then settle (`quantity -= qty; reserved_quantity -= qty`) inside
+   the same transaction — keeping the existing all-or-nothing guarantee rather
+   than splitting into two commits, which would leave an unresolvable `open`
+   order if the process died in between and there is no cancel use case to
+   recover it.
+ * Made both buy and sell orders genuinely pass through `status='open'` before
+   `status='executed'`, instead of being inserted as `'executed'` directly, so
+   the lifecycle the ER model already claimed for `Orders` is real.
+ * Added a `CHECK (reserved_quantity >= 0 AND reserved_quantity <= quantity)`
+   constraint and exposed `reserved_quantity`/`available_quantity` on
+   `v_portfolio` and in the CLI's portfolio table, so the new field is
+   observable rather than a column nobody can see.
+ * Restructured this phase's [wiki:ERModel] into short rationale + a
+   compact attribute table per entity/relationship, per the "more put together,
+   not that much spread out" request — no content was removed, only
+   reformatted.
+ * Verified the fix against the live database (`bp_database` on `localhost:5433`):
+   ran two concurrent `sell 1.0 BTC` attempts against a holding with only 1.5
+   BTC available — exactly one succeeded, the other correctly reported
+   insufficient holding — and ran the reserve/settle sequence by hand in `psql`
+   to show `reserved_quantity` at 0.5 mid-transaction. Both are recorded in
+   [wiki:UseCase0005Implementation].
+
+'''What I decided:''' to keep reserve and settle inside one transaction rather
+than two (see the AI's reasoning above — I agreed with it, since a stuck
+`open` order with no cancel command would be a worse bug than the one being
+fixed).
+
+'''Follow-up, same day:''' I asked for `ERModel_v03.xml`/`.png` after all,
+having noticed the PNG still showed v02 with no `reserved_quantity` on it, and
+asked at the same time for the diagram to be a little more compact — it had a
+lot of empty canvas in the middle. The AI drove TerraER's own classes directly
+(load → clone the `quantity` attribute → relabel it → add its connecting line
+→ pull every cluster toward the centroid → save → render), described in full
+under Diagram above, rather than hand-editing the XML or asking me
+to do it in the GUI. I reviewed the rendered PNG before accepting it.
+
+'''Second follow-up, same day:''' the first `ERModel_v03.png` rendered with a
+black background instead of white, unlike v01/v02. Cause: TerraER's
+`ImageOutputFormat` defaults to an ARGB image and paints its background with
+zero alpha (transparent), not opaque white; whatever displayed the PNG then
+flattened that transparency onto black instead of white. Fixed by exporting
+through the same `ImageOutputFormat.toImage(...)` call for figure geometry,
+but compositing its result onto an explicitly white-filled opaque `RGB` image
+before saving, rather than trusting the library's own (transparent) output.
+Verified the fix by reading back the corner pixel of the written PNG as pure
+white `(255,255,255)`, matching `ERModel_v02.png`.
+
+
+=== Session 4 — 2026-09-24 (Claude Opus 5.5): v04 after P7 ===
+
+'''Prompts (student, verbatim):'''
+> But this order_events is added after Phase 7 right? can we add that too?
+
+> can you make the ERmodel again with TerraER file to update it? and tell that after P7 we added this
+
+> Make it with a white background like earier versions
+
+'''Response (AI, summarised):'''
+
+ * Explained that the P7 changes must also appear in P1 and P2, since both must describe the current data structure.
+ * Built `ERModel_v04.xml` in TerraER's own file format by taking `ERModel_v03.xml` unchanged and appending the new elements with the same XML structure TerraER uses:
+   * the attribute `reserved_balance` on `Users`;
+   * the attribute `filled_quantity` on `Orders`;
+   * the relationships `FillsBuy` and `FillsSell` (Orders 1 : N !MarketTrades, partial);
+   * the entity set `OrderEvents` (key `id`, `event_type`, `quantity`, `price`, `status_after`, `created_at`) with `Logs` (Orders 1 : N !OrderEvents, total on !OrderEvents).
+ * Rendered `ERModel_v04.png` with TerraER 3.14's own drawing classes (loading the `.xml` exactly as TerraER does and using its image export), on a white background and trimmed like the earlier versions.
+ * Updated [wiki:ERModel] (title v.04, new attribute rows, the `OrderEvents` section, the three relationships, and a v04 history entry stating these were added after P7).
+
+'''What I decided:''' to add the P7 structure to the ER model. The new elements are placed
+automatically, so the layout can be tidied by hand in TerraER.
