new readme
This commit is contained in:
174
README.md
174
README.md
@@ -1 +1,173 @@
|
|||||||
Replace Excel
|
# Portfolio Engine
|
||||||
|
|
||||||
|
A lightweight portfolio tracking backend written in Go. Replaces spreadsheets with a proper database, REST API, and an interactive shell — all in a single binary.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- SQLite database with foreign key enforcement
|
||||||
|
- REST API on port `8080`
|
||||||
|
- Interactive shell for managing data without an HTTP client
|
||||||
|
- Tracks companies with share count, price, and currency
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├── main.go # Entry point, HTTP routes, shell loop
|
||||||
|
├── app.db # SQLite database (auto-created on first run)
|
||||||
|
├── build.sh # Build script
|
||||||
|
├── go.mod / go.sum
|
||||||
|
└── internal/
|
||||||
|
├── database/
|
||||||
|
│ └── main.go # Schema init (InitDB)
|
||||||
|
├── handlers/
|
||||||
|
│ └── main.go # HTTP handlers (HealthHandler, AddCompanyHandler)
|
||||||
|
├── model/
|
||||||
|
│ └── company.go # Structs + SQL queries (Company, Currency, CompanyInput)
|
||||||
|
├── service/
|
||||||
|
│ ├── company.go # Company business logic
|
||||||
|
│ ├── currency.go # Currency business logic
|
||||||
|
│ └── main.go # Service setup
|
||||||
|
└── shell/
|
||||||
|
├── company.go # Shell commands for companies
|
||||||
|
└── currency.go # Shell commands for currencies
|
||||||
|
```
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Go 1.21+
|
||||||
|
- GCC (required for SQLite CGO bindings)
|
||||||
|
- Ubuntu/Debian: `sudo apt install gcc`
|
||||||
|
- macOS: comes with Xcode Command Line Tools
|
||||||
|
|
||||||
|
### Install & Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone git@git.samantha42.xyz:samantha/Portifolio-Engine.git
|
||||||
|
cd Portifolio-Engine
|
||||||
|
go mod download
|
||||||
|
go run main.go
|
||||||
|
```
|
||||||
|
|
||||||
|
Or use the build script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
chmod +x build.sh
|
||||||
|
./build.sh
|
||||||
|
./Portifolio
|
||||||
|
```
|
||||||
|
|
||||||
|
On startup you'll see:
|
||||||
|
|
||||||
|
```
|
||||||
|
Connected to SQLite database
|
||||||
|
Server running on :8080
|
||||||
|
|
||||||
|
Shell ready. Commands: add-company, help, exit
|
||||||
|
>
|
||||||
|
```
|
||||||
|
|
||||||
|
The HTTP server and the shell run concurrently — the API is live while you type shell commands.
|
||||||
|
|
||||||
|
## REST API
|
||||||
|
|
||||||
|
### `GET /health`
|
||||||
|
|
||||||
|
Returns the status of the server and database connection.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8080/health
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "ok",
|
||||||
|
"database": "ok"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns `503` if the database is unreachable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `POST /add/company`
|
||||||
|
|
||||||
|
Add a new company. The `currency_id` must reference an existing currency in the database.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:8080/add/company \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"name": "Novo Nordisk",
|
||||||
|
"shares_outstanding": 4442064180,
|
||||||
|
"price": 251.00,
|
||||||
|
"currency_id": 1
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "status": "created" }
|
||||||
|
```
|
||||||
|
|
||||||
|
## Shell Commands
|
||||||
|
|
||||||
|
The shell starts automatically after the server and accepts commands interactively.
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|------------------|--------------------------------------|
|
||||||
|
| `add-currency` | Add a new currency interactively |
|
||||||
|
| `list-currency` | List all currencies with their IDs |
|
||||||
|
| `add-company` | Add a new company interactively |
|
||||||
|
| `help` | Show available commands |
|
||||||
|
| `exit` | Quit the application |
|
||||||
|
|
||||||
|
### Example session
|
||||||
|
|
||||||
|
```
|
||||||
|
> add-currency
|
||||||
|
Code (e.g. DKK): DKK
|
||||||
|
Name (e.g. Danish Krone): Danish Krone
|
||||||
|
✓ Currency 'Danish Krone' (DKK) added with ID 1
|
||||||
|
|
||||||
|
> list-currency
|
||||||
|
ID CODE NAME
|
||||||
|
------------------------------
|
||||||
|
1 DKK Danish Krone
|
||||||
|
|
||||||
|
> add-company
|
||||||
|
Name: Maersk
|
||||||
|
Shares outstanding: 15224309
|
||||||
|
Price: 15270.00
|
||||||
|
Currency ID: 1
|
||||||
|
✓ Company 'Maersk' added.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database Schema
|
||||||
|
|
||||||
|
```sql
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
- `GET /companies` — list all companies
|
||||||
|
- `GET /currencies` — list all currencies
|
||||||
|
- Price update endpoint
|
||||||
|
- Market cap calculation (price × shares)
|
||||||
|
- Multi-currency conversion
|
||||||
|
- Frontend dashboard
|
||||||
6
main.go
6
main.go
@@ -33,7 +33,11 @@ func main() {
|
|||||||
fmt.Println("Connected to SQLite database")
|
fmt.Println("Connected to SQLite database")
|
||||||
|
|
||||||
http.HandleFunc("/health", handlers.HealthHandler(db))
|
http.HandleFunc("/health", handlers.HealthHandler(db))
|
||||||
http.HandleFunc("/add/company", handlers.AddCompanyHandler(db))
|
http.HandleFunc("POST /add/company", handlers.AddCompanyHandler(db))
|
||||||
|
/*
|
||||||
|
http.HandleFunc("GET /companies", handlers.AddCompanyHandler(db))
|
||||||
|
http.HandleFunc("GET /currencies", handlers.AddCompanyHandler(db))
|
||||||
|
*/
|
||||||
|
|
||||||
fmt.Println("Server running on :8080")
|
fmt.Println("Server running on :8080")
|
||||||
go func() {
|
go func() {
|
||||||
|
|||||||
Reference in New Issue
Block a user