new endpoints

This commit is contained in:
zipfriis
2026-03-25 16:54:46 +01:00
parent 4e5b830e75
commit 52d99c7012
8 changed files with 305 additions and 99 deletions

View File

@@ -16,6 +16,25 @@ func InitDB(db *sql.DB) {
name TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS 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
);
CREATE TABLE IF NOT EXISTS position (
id INTEGER PRIMARY KEY AUTOINCREMENT,
company_id INTEGER NOT NULL,
shares INTEGER NOT NULL,
weight REAL NOT NULL,
CostBases REAL NOT NULL,
);
CREATE TABLE IF NOT EXISTS companies (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,

View File

@@ -0,0 +1,45 @@
package database
import (
"Portifolio/internal/model"
"database/sql"
_ "github.com/mattn/go-sqlite3"
)
func GetTrades(db *sql.DB) ([]model.Trade, error) {
rows, err := db.Query("SELECT id, company_id, currency_id, shares, product, type, price, traded_at FROM trades")
if err != nil {
return nil, err
}
defer rows.Close()
var trades []model.Trade
for rows.Next() {
var t model.Trade
err := rows.Scan(&t.Ticker, &t.Currency, &t.Shares, &t.Product, &t.Type, &t.Price, &t.Date)
if err != nil {
return nil, err
}
trades = append(trades, t)
}
if err = rows.Err(); err != nil {
return nil, err
}
return trades, nil
}
func InsertTrade(db *sql.DB, trade model.Trade) error {
_, err := db.Exec(
"INSERT INTO trades (company_id, currency_id, shares, product, type, price, traded_at) VALUES (?, ?, ?, ?, ?, ?, ?)",
trade.Ticker.ID,
trade.Currency.ID,
trade.Shares,
trade.Product,
trade.Type,
trade.Price,
trade.Date,
)
return err
}

View File

@@ -0,0 +1,44 @@
package handlers
import (
"Portifolio/internal/database"
"Portifolio/internal/model"
"database/sql"
"encoding/json"
"net/http"
_ "github.com/mattn/go-sqlite3"
)
func AddTradeHandler(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req model.AddTradeRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "invalid json", http.StatusBadRequest)
return
}
err := req.Validate()
if err != nil {
http.Error(w, "invalid json", http.StatusBadRequest)
return
}
}
}
func GetTradeListHandler(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
tradeList, err := database.GetTrades(db)
if err != nil {
http.Error(w, "failed to fetch trades", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(tradeList); err != nil {
http.Error(w, "failed to encode trades", http.StatusInternalServerError)
return
}
}
}

View File

@@ -0,0 +1,81 @@
package model
import (
"errors"
"time"
)
type Position struct {
Company Company
weight float64
CostBasis float64
Shares int
}
type TradeProduct int
const (
StockTrade TradeProduct = iota // 0
OptionCallTrade // 1
OptionPutTrade // 2
CurrencyTrade // 3
BondTrade
)
type TradeType bool
const (
Buy TradeType = true
Sell TradeType = false
)
type Trade struct {
Ticker Company
Shares int
Product TradeProduct
Type TradeType
Price float64
Currency Currency
Date time.Time
}
type AddTradeRequest struct {
TickerId int
Shares int
Product int
Type bool
Price float64
Currency string
Date time.Time
}
func (r *AddTradeRequest) Validate() error {
if r.TickerId <= 0 {
return errors.New("ticker id must be a positive integer")
}
if r.Shares <= 0 {
return errors.New("shares must be a positive integer")
}
if r.Product < 0 || r.Product > 3 {
return errors.New("product must be between 0 and 3")
}
if r.Price <= 0 {
return errors.New("price must be a positive number")
}
if r.Currency == "" {
return errors.New("currency is required")
}
if r.Date.IsZero() {
return errors.New("date is required")
}
if r.Date.After(time.Now()) {
return errors.New("date cannot be in the future")
}
return nil
}
// for now trades and none stock position will not be supported.
type Portifolio struct {
Positions []Position
Trades []Trade
}