diff --git a/Data-Models.md b/Data-Models.md new file mode 100644 index 0000000..bd3d107 --- /dev/null +++ b/Data-Models.md @@ -0,0 +1,144 @@ +

Data Models

+

Portfolio

+

Position

+

Represents the current holding for a single symbol, derived by aggregating trades.

+
type Position struct {
+    CompanyID    int
+    Symbol       string
+    CurrencyCode string
+    CurrencyID   int
+    Weight       float64
+    CostBasis    float64
+    Shares       int
+}
+
+

Trade

+

A single executed trade.

+
type Trade struct {
+    Symbol       string
+    CurrencyCode string
+    Shares       int
+    Product      TradeProduct
+    Type         TradeType
+    Price        float64
+    Date         time.Time
+}
+
+

TradeProduct (int enum)

+ +Value | Constant +-- | -- +0 | StockTrade +1 | OptionCallTrade +2 | OptionPutTrade +3 | CurrencyTrade +4 | BondTrade + + +

Portfolio

+

Top-level aggregate — currently only stock positions are supported.

+
type Portfolio struct {
+    Positions []Position
+    Trades    []Trade
+}
+
+
+

Company

+
type Company struct {
+    ID                int
+    Name              string
+    SharesOutstanding int
+    Price             float64
+    CurrencyID        int
+}
+
+
+

Currency

+
type Currency struct {
+    ID   int
+    Code string
+    Name string
+}
+
+
+

Period

+

Periods are created automatically when revenue entries are added.

+
type Period struct {
+    ID        int
+    Type      string    // "Q", "H", or "Y"
+    Year      int
+    Index     int
+    StartDate time.Time
+    EndDate   time.Time
+}
+
+

Helper constructors: QuarterPeriod, HalfYearPeriod, FullYearPeriod.

+
+

Revenue

+
type RevenueEntry struct {
+    ID         int
+    ReportID   int
+    CurrencyID int
+    Category   string
+    Label      string
+    Value      float64
+}
+
+
+

Database Schema

+
CREATE TABLE currencies (
+    id   INTEGER PRIMARY KEY AUTOINCREMENT,
+    code TEXT    NOT NULL UNIQUE,
+    name TEXT    NOT NULL
+);
+
+CREATE TABLE companies (
+    id                 INTEGER PRIMARY KEY AUTOINCREMENT,
+    name               TEXT    NOT NULL UNIQUE,
+    shares_outstanding INTEGER NOT NULL,
+    price              REAL    NOT NULL,
+    currency_id        INTEGER NOT NULL,
+    FOREIGN KEY (currency_id) REFERENCES currencies(id)
+);
+
+CREATE TABLE periods (
+    id         INTEGER PRIMARY KEY AUTOINCREMENT,
+    type       TEXT    NOT NULL CHECK(type IN ('Q', 'H', 'Y')),
+    year       INTEGER NOT NULL,
+    idx        INTEGER NOT NULL,
+    start_date TEXT    NOT NULL,
+    end_date   TEXT    NOT NULL,
+    UNIQUE(type, year, idx)
+);
+
+CREATE TABLE revenue_reports (
+    id         INTEGER PRIMARY KEY AUTOINCREMENT,
+    company_id INTEGER NOT NULL,
+    period_id  INTEGER NOT NULL,
+    FOREIGN KEY (company_id) REFERENCES companies(id),
+    FOREIGN KEY (period_id)  REFERENCES periods(id),
+    UNIQUE(company_id, period_id)
+);
+
+CREATE TABLE revenue_entries (
+    id          INTEGER PRIMARY KEY AUTOINCREMENT,
+    report_id   INTEGER NOT NULL,
+    currency_id INTEGER NOT NULL,
+    category    TEXT    NOT NULL,
+    label       TEXT    NOT NULL,
+    value       REAL    NOT NULL,
+    FOREIGN KEY (report_id)   REFERENCES revenue_reports(id),
+    FOREIGN KEY (currency_id) REFERENCES currencies(id)
+);
+
+CREATE TABLE trades (
+    id          INTEGER  PRIMARY KEY AUTOINCREMENT,
+    company_id  INTEGER  NOT NULL,
+    currency_id INTEGER  NOT NULL,
+    shares      INTEGER  NOT NULL,
+    product     INTEGER  NOT NULL CHECK(product IN (0, 1, 2, 3)),
+    type        INTEGER  NOT NULL CHECK(type IN (0, 1)),
+    price       REAL     NOT NULL,
+    traded_at   DATETIME NOT NULL
+);
+
\ No newline at end of file