Index: server/portfolio.go
===================================================================
--- server/portfolio.go	(revision b715712c7d5d3ee27c932a8a9d8e0a2bc6e85127)
+++ server/portfolio.go	(revision b715712c7d5d3ee27c932a8a9d8e0a2bc6e85127)
@@ -0,0 +1,67 @@
+package main
+
+import (
+	"fmt"
+
+	"bp_project/server/db"
+)
+
+// ShowPortfolio - UC0006
+// Uses the v_portfolio view to list holdings with current market value and P&L.
+func ShowPortfolio(s *Session) {
+	rows, err := db.DB.Query(
+		`SELECT symbol,
+		        quantity,
+		        COALESCE(avg_price, 0),
+		        COALESCE(current_price, 0),
+		        COALESCE(market_value, 0),
+		        COALESCE(unrealized_pnl, 0)
+		   FROM v_portfolio
+		  WHERE user_id = $1 AND quantity > 0
+		  ORDER BY symbol`,
+		s.UserID,
+	)
+	if err != nil {
+		fmt.Println("Error:", err)
+		return
+	}
+	defer rows.Close()
+
+	fmt.Println()
+	fmt.Printf("  %-8s  %12s  %14s  %14s  %14s  %14s\n",
+		"Symbol", "Quantity", "Avg buy", "Current", "Value", "Unrealised P/L")
+	fmt.Println("  ------------------------------------------------------------------------------------")
+
+	var totalValue, totalPnL float64
+	empty := true
+	for rows.Next() {
+		var sym string
+		var qty, avg, cur, val, pnl float64
+		if err := rows.Scan(&sym, &qty, &avg, &cur, &val, &pnl); err != nil {
+			fmt.Println("scan error:", err)
+			return
+		}
+		fmt.Printf("  %-8s  %12.4f  %14.6f  %14.6f  %14.4f  %+14.4f\n",
+			sym, qty, avg, cur, val, pnl)
+		totalValue += val
+		totalPnL += pnl
+		empty = false
+	}
+	if empty {
+		fmt.Println("  (no holdings yet)")
+		return
+	}
+	fmt.Println("  ------------------------------------------------------------------------------------")
+	fmt.Printf("  %-8s  %12s  %14s  %14s  %14.4f  %+14.4f\n",
+		"TOTAL", "", "", "", totalValue, totalPnL)
+
+	// cash summary
+	var avail, invested float64
+	_ = db.DB.QueryRow(
+		`SELECT available_balance, invested_balance FROM users WHERE id = $1`,
+		s.UserID,
+	).Scan(&avail, &invested)
+	fmt.Printf("\n  Cash available : %.4f USD\n", avail)
+	fmt.Printf("  Portfolio value: %.4f USD\n", totalValue)
+	fmt.Printf("  Net worth      : %.4f USD\n", avail+totalValue)
+}
