From c6eb26037b85b89b0aebaf49f8b53e2b4368a9d3 Mon Sep 17 00:00:00 2001 From: Peter Wood Date: Fri, 14 Nov 2025 12:43:09 -0500 Subject: [PATCH] feat: Add CI/CD setup guide with Gitea Actions for trading analysis application feat: Implement multi-user support with separate brokerage accounts and user authentication feat: Configure SSO authentication setup using Google OAuth 2.0 for secure access refactor: Update index page to reflect new Trading Analysis Dashboard features and descriptions docs: Enhance quickstart guide for deploying Trading Analysis Dashboard with detailed steps chore: Add runner configuration for Gitea Actions with logging and container settings --- api-reference/auth.mdx | 141 +++++++++ api-reference/month-data.mdx | 124 ++++++++ api-reference/months.mdx | 116 ++++++++ api-reference/portfolio-holdings.mdx | 136 +++++++++ api-reference/portfolio-refresh.mdx | 104 +++++++ api-reference/timeframe.mdx | 105 +++++++ api-reference/trade-details.mdx | 59 ++++ docker-compose.yml | 84 ++++++ docs.json | 97 +++--- features/csv-upload.mdx | 109 +++++++ features/hybrid-matching.mdx | 111 +++++++ features/portfolio-management.mdx | 153 ++++++++++ features/portfolio-quickstart.mdx | 181 ++++++++++++ features/timeframe-analysis.mdx | 92 ++++++ features/trading-analysis.mdx | 69 +++++ features/trading-calendar.mdx | 90 ++++++ guides/deployment/caddy.mdx | 393 ++++++++++++++++++++++++ guides/deployment/docker.mdx | 426 +++++++++++++++++++++++++++ guides/setup/cicd.mdx | 283 ++++++++++++++++++ guides/setup/multi-user.mdx | 262 ++++++++++++++++ guides/setup/sso.mdx | 234 +++++++++++++++ index.mdx | 166 ++++++----- quickstart.mdx | 213 +++++++++++--- runner-config.yaml | 15 + 24 files changed, 3594 insertions(+), 169 deletions(-) create mode 100644 api-reference/auth.mdx create mode 100644 api-reference/month-data.mdx create mode 100644 api-reference/months.mdx create mode 100644 api-reference/portfolio-holdings.mdx create mode 100644 api-reference/portfolio-refresh.mdx create mode 100644 api-reference/timeframe.mdx create mode 100644 api-reference/trade-details.mdx create mode 100644 docker-compose.yml create mode 100644 features/csv-upload.mdx create mode 100644 features/hybrid-matching.mdx create mode 100644 features/portfolio-management.mdx create mode 100644 features/portfolio-quickstart.mdx create mode 100644 features/timeframe-analysis.mdx create mode 100644 features/trading-analysis.mdx create mode 100644 features/trading-calendar.mdx create mode 100644 guides/deployment/caddy.mdx create mode 100644 guides/deployment/docker.mdx create mode 100644 guides/setup/cicd.mdx create mode 100644 guides/setup/multi-user.mdx create mode 100644 guides/setup/sso.mdx create mode 100644 runner-config.yaml diff --git a/api-reference/auth.mdx b/api-reference/auth.mdx new file mode 100644 index 0000000..04e47e0 --- /dev/null +++ b/api-reference/auth.mdx @@ -0,0 +1,141 @@ +--- +title: 'Authentication' +description: 'OAuth 2.0 authentication endpoints and flow' +--- + +## Overview + +The Trading Analysis Dashboard uses Google OAuth 2.0 for secure authentication. All API endpoints require an authenticated session. + +## Authentication Flow + + + + Unauthenticated users are redirected to the login page + + + + User initiates OAuth flow by clicking the Google sign-in button + + + + User is redirected to Google to authorize the application + + + + Google redirects back to the application with authorization code + + + + Application exchanges code for tokens and creates a secure session + + + + User is redirected to the dashboard with an authenticated session + + + +## Endpoints + +### Login Page + +``` +GET /auth/login +``` + +Displays the login page for unauthenticated users. + +### Initiate OAuth + +``` +GET /login +``` + +Redirects user to Google OAuth authorization page. + +### OAuth Callback + +``` +GET /auth/callback +``` + +Handles the OAuth callback from Google and creates user session. + +**Query Parameters:** +- `code` (string): Authorization code from OAuth provider +- `state` (string): State parameter for security + +### Logout + +``` +GET /logout +``` + +Clears user session and logs out the user. + +### User Profile + +``` +GET /auth/profile +``` + +Displays user profile information (requires authentication). + +## Session Management + +- Sessions are stored server-side using Flask sessions +- Session cookies are HTTP-only and secure (in production) +- Sessions expire after a period of inactivity +- Users must re-authenticate after session expiration + +## User Authorization + +Access is controlled by the `AUTHORIZED_USERS` environment variable: + +```env +AUTHORIZED_USERS=user1@example.com,user2@example.com,user3@example.com +``` + +Only users with email addresses in this list can access the application after authenticating with Google. + +## Error Responses + +### 401 Unauthorized + +```json +{ + "success": false, + "error": "Authentication required", + "redirect_to_login": true +} +``` + +### 403 Forbidden + +```json +{ + "success": false, + "error": "Access denied. User not authorized." +} +``` + +## Security Best Practices + + + + Always use HTTPS in production for OAuth callbacks + + + Session cookies are HTTP-only and secure + + + Only authorized email addresses can access the application + + + OAuth tokens are never exposed to the client + + + +## Configuration + +See the [SSO Setup Guide](/guides/setup/sso) for detailed configuration instructions. diff --git a/api-reference/month-data.mdx b/api-reference/month-data.mdx new file mode 100644 index 0000000..752c003 --- /dev/null +++ b/api-reference/month-data.mdx @@ -0,0 +1,124 @@ +--- +title: 'Get Month Data' +api: 'GET /api/month/{month}' +description: 'Retrieves detailed trading data for a specific month' +--- + +## Endpoint + +``` +GET /api/month/{month} +``` + +## Path Parameters + + + Month in YYYY-MM format (e.g., "2024-08") + + +## Authentication + +Requires OAuth 2.0 authentication via session cookies. + +## Response + +Returns detailed trading data including summary, trades, and dividends. + + + Request success status + + + + Monthly summary statistics + + + + Month in YYYY-MM format + + + Total number of completed trades + + + Number of profitable trades + + + Win rate percentage + + + Total profit/loss from trades + + + Total dividend income + + + Combined trading P&L and dividends + + + + + + List of completed trades + + + + List of dividend payments + + +## Example + + +```bash cURL +curl -X GET https://your-domain.com/api/month/2024-08 \ + -H "Cookie: session=your_session_cookie" +``` + +```javascript JavaScript +const month = '2024-08'; +const response = await fetch(`/api/month/${month}`); +const data = await response.json(); + +if (data.success) { + console.log(`P/L: $${data.summary.trading_profit_loss}`); + console.log(`Trades: ${data.trades.length}`); +} +``` + + +## Response Example + +```json +{ + "success": true, + "summary": { + "month": "2024-08", + "total_trades": 15, + "winning_trades": 9, + "win_rate": 60.0, + "trading_profit_loss": 850.75, + "total_dividends": 125.50, + "total_return_with_dividends": 976.25 + }, + "trades": [ + { + "symbol": "AAPL", + "buy_date": "2024-08-01", + "sell_date": "2024-08-15", + "buy_price": 195.50, + "sell_price": 198.75, + "volume": 100, + "total_profit_loss": 325.00, + "return_percentage": 1.66, + "trade_result": "Win" + } + ], + "dividends": [ + { + "transaction_date": "2024-08-15", + "symbol": "MSFT", + "action": "Cash Dividend", + "amount": 75.50 + } + ], + "data_source": "postgresql" +} +``` diff --git a/api-reference/months.mdx b/api-reference/months.mdx new file mode 100644 index 0000000..5c586b4 --- /dev/null +++ b/api-reference/months.mdx @@ -0,0 +1,116 @@ +--- +title: 'Get Available Months' +api: 'GET /api/months' +description: 'Retrieves a list of all months that have trading data available' +--- + +## Endpoint + +``` +GET /api/months +``` + +## Authentication + +Requires OAuth 2.0 authentication via session cookies. + +## Parameters + +None + +## Response + + + Indicates if the request was successful + + + + List of month objects + + + + Month in YYYY-MM format + + + + Total return including dividends for that month + + + + + + Database source (always "postgresql") + + +## Example + + +```bash cURL +curl -X GET https://your-domain.com/api/months \ + -H "Cookie: session=your_session_cookie" +``` + +```javascript JavaScript +const response = await fetch('/api/months'); +const data = await response.json(); + +if (data.success) { + console.log('Available months:', data.months); +} +``` + +```python Python +import requests + +response = requests.get('http://localhost:5000/api/months') +data = response.json() + +if data['success']: + for month in data['months']: + print(f"{month['month']}: ${month['total_return_with_dividends']}") +``` + + +## Response Example + +```json +{ + "success": true, + "months": [ + { + "month": "2024-08", + "total_return_with_dividends": 1250.75 + }, + { + "month": "2024-07", + "total_return_with_dividends": -320.50 + }, + { + "month": "2024-06", + "total_return_with_dividends": 890.25 + } + ], + "data_source": "postgresql" +} +``` + +## Error Responses + + +```json Database Connection Failed +{ + "success": false, + "error": "Database connection failed" +} +``` + + + +```json Unauthorized +{ + "success": false, + "error": "Authentication required", + "redirect_to_login": true +} +``` + diff --git a/api-reference/portfolio-holdings.mdx b/api-reference/portfolio-holdings.mdx new file mode 100644 index 0000000..c130f30 --- /dev/null +++ b/api-reference/portfolio-holdings.mdx @@ -0,0 +1,136 @@ +--- +title: 'Portfolio Holdings' +api: 'GET /api/portfolio/holdings' +description: 'Get, add, update, or delete portfolio holdings' +--- + +## Get All Holdings + +``` +GET /api/portfolio/holdings +``` + +Returns all holdings for the current user with current prices and calculated metrics. + +### Response Example + +```json +{ + "success": true, + "holdings": [ + { + "id": 1, + "symbol": "AAPL", + "holding_type": "stock", + "shares": 100, + "average_cost": 150.50, + "current_price": 175.25, + "total_cost": 15050.00, + "current_value": 17525.00, + "gain_loss": 2475.00, + "return_percentage": 16.44, + "last_updated": "2024-11-14T10:30:00Z" + } + ] +} +``` + +## Add a Holding + +``` +POST /api/portfolio/holdings +``` + +### Request Body + + + Stock ticker symbol (e.g., "AAPL") + + + + Type: "stock", "etf", or "mutual_fund" + + + + Number of shares owned + + + + Average cost per share + + + + Optional notes about the holding + + +### Example + + +```bash cURL +curl -X POST https://your-domain.com/api/portfolio/holdings \ + -H "Content-Type: application/json" \ + -d '{ + "symbol": "AAPL", + "holding_type": "stock", + "shares": 100, + "average_cost": 150.50, + "notes": "Tech holding" + }' +``` + +```javascript JavaScript +const response = await fetch('/api/portfolio/holdings', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + symbol: 'AAPL', + holding_type: 'stock', + shares: 100, + average_cost: 150.50, + notes: 'Tech holding' + }) +}); + +const data = await response.json(); +``` + + +## Update a Holding + +``` +PUT /api/portfolio/holdings/{id} +``` + +### Path Parameters + + + Holding ID to update + + +### Request Body + + + Updated number of shares + + + + Updated average cost per share + + + + Updated notes + + +## Delete a Holding + +``` +DELETE /api/portfolio/holdings/{id} +``` + +### Path Parameters + + + Holding ID to delete + diff --git a/api-reference/portfolio-refresh.mdx b/api-reference/portfolio-refresh.mdx new file mode 100644 index 0000000..a6405bc --- /dev/null +++ b/api-reference/portfolio-refresh.mdx @@ -0,0 +1,104 @@ +--- +title: 'Refresh Portfolio Prices' +api: 'POST /api/portfolio/refresh-prices' +description: 'Fetch current market prices for all portfolio holdings' +--- + +## Endpoint + +``` +POST /api/portfolio/refresh-prices +``` + +## Description + +Fetches the latest market prices from Finnhub API for all holdings in the user's portfolio. + +## Authentication + +Requires OAuth 2.0 authentication via session cookies. + +## Rate Limiting + +The free Finnhub API tier allows 60 requests per minute. The application intelligently manages API requests to stay within these limits. + +## Response + + + Indicates if the refresh was successful + + + + Number of holdings successfully updated + + + + List of any errors encountered during refresh + + +## Example + + +```bash cURL +curl -X POST https://your-domain.com/api/portfolio/refresh-prices \ + -H "Cookie: session=your_session_cookie" +``` + +```javascript JavaScript +const response = await fetch('/api/portfolio/refresh-prices', { + method: 'POST' +}); + +const data = await response.json(); + +if (data.success) { + console.log(`Updated ${data.updated_count} holdings`); +} +``` + +```python Python +import requests + +response = requests.post('http://localhost:5000/api/portfolio/refresh-prices') +data = response.json() + +if data['success']: + print(f"Updated {data['updated_count']} holdings") +``` + + +## Response Example + +```json Success +{ + "success": true, + "updated_count": 5, + "message": "Successfully updated prices for 5 holdings" +} +``` + +```json Partial Success +{ + "success": true, + "updated_count": 4, + "errors": [ + { + "symbol": "INVALID", + "error": "Symbol not found" + } + ] +} +``` + +```json Error +{ + "success": false, + "error": "Finnhub API key not configured" +} +``` + +## Notes + +- Prices are automatically refreshed when viewing the portfolio page if last update was >15 minutes ago +- Use this endpoint to manually force a refresh at any time +- Mutual fund prices may be delayed 15-30 minutes diff --git a/api-reference/timeframe.mdx b/api-reference/timeframe.mdx new file mode 100644 index 0000000..f9c80a7 --- /dev/null +++ b/api-reference/timeframe.mdx @@ -0,0 +1,105 @@ +--- +title: 'Get Timeframe Data' +api: 'GET /api/timeframe-data' +description: 'Retrieves trading analysis data for a custom timeframe or all-time data' +--- + +## Endpoint + +``` +GET /api/timeframe-data +``` + +## Query Parameters + + + Start date in YYYY-MM-DD format (optional if using all=true) + + + + End date in YYYY-MM-DD format (optional if using all=true) + + + + Set to "true" for all-time data (ignores start/end dates) + + + + Comma-separated list of stock symbols to filter by (optional) + + +## Response + +Returns summary, weekly breakdown, monthly breakdown, and open positions. + +## Example + + +```bash Date Range +curl -X GET "https://your-domain.com/api/timeframe-data?start=2024-01-01&end=2024-08-31" +``` + +```bash All Time +curl -X GET "https://your-domain.com/api/timeframe-data?all=true" +``` + +```bash With Symbols +curl -X GET "https://your-domain.com/api/timeframe-data?start=2024-06-01&end=2024-08-31&symbols=AAPL,TSLA,MSFT" +``` + +```javascript JavaScript +// Get YTD data +const start = '2024-01-01'; +const end = new Date().toISOString().split('T')[0]; +const response = await fetch(`/api/timeframe-data?start=${start}&end=${end}`); +const data = await response.json(); + +console.log('Total P/L:', data.summary.trading_profit_loss); +``` + + +## Response Example + +```json +{ + "success": true, + "data": { + "summary": { + "trading_profit_loss": 2450.75, + "total_dividends": 380.50, + "total_trades": 45, + "winning_trades": 28, + "win_rate_percentage": 62.22 + }, + "weekly_summary": [ + { + "week_start": "2024-08-26", + "period": "2024-08-26", + "trading_profit_loss": 150.25, + "total_dividends": 25.00, + "total_trades": 3, + "winning_trades": 2, + "win_rate_percentage": 66.67 + } + ], + "monthly_summary": [ + { + "month_start": "2024-08-01", + "period": "2024-08", + "trading_profit_loss": 850.75, + "total_dividends": 125.50, + "total_trades": 15, + "winning_trades": 9, + "win_rate_percentage": 60.0 + } + ], + "open_positions": [ + { + "symbol": "NVDA", + "shares": 150 + } + ] + }, + "data_source": "postgresql" +} +``` diff --git a/api-reference/trade-details.mdx b/api-reference/trade-details.mdx new file mode 100644 index 0000000..17f5d52 --- /dev/null +++ b/api-reference/trade-details.mdx @@ -0,0 +1,59 @@ +--- +title: 'Get Trade Details' +api: 'GET /api/trade-details/{month}' +description: 'Retrieves detailed trade information for a specific month' +--- + +## Endpoint + +``` +GET /api/trade-details/{month} +``` + +## Path Parameters + + + Month in YYYY-MM format (e.g., "2024-08") + + +## Response + +Returns detailed trade information with buy/sell prices, volumes, and profit/loss calculations. + +## Example + + +```bash cURL +curl -X GET https://your-domain.com/api/trade-details/2024-08 +``` + +```javascript JavaScript +const response = await fetch('/api/trade-details/2024-08'); +const data = await response.json(); + +console.log('Trades:', data.trades); +``` + + +## Response Example + +```json +{ + "success": true, + "trades": [ + { + "symbol": "AAPL", + "buy_date": "2024-08-01", + "sell_date": "2024-08-15", + "buy_price": 195.50, + "sell_price": 198.75, + "volume": 100, + "profit_per_share": 3.25, + "total_profit_loss": 325.00, + "return_percentage": 1.66, + "trade_result": "Win" + } + ], + "data_source": "postgresql" +} +``` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..fbde7ab --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,84 @@ +services: + server: + image: docker.gitea.com/gitea:latest + container_name: gitea + environment: + - USER_UID=${USER_UID} + - USER_GID=${USER_GID} + - GITEA__database__DB_TYPE=postgres + - GITEA__database__HOST=db:5432 + - GITEA__database__NAME=${POSTGRES_USER} + - GITEA__database__USER=${POSTGRES_USER} + - GITEA__database__PASSWD=${POSTGRES_PASSWORD} + restart: always + networks: + - gitea + volumes: + - gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + ports: + - ${GITEA_HTTP_PORT:-3500}:3000 + - ${GITEA_SSH_PORT:-2229}:22 + depends_on: + - db + labels: + - diun.enable=true + healthcheck: + test: + - CMD + - curl + - -f + - http://localhost + interval: 10s + retries: 3 + start_period: 30s + timeout: 10s + + db: + image: docker.io/library/postgres:14 + restart: always + environment: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} + networks: + - gitea + volumes: + - postgres:/var/lib/postgresql/data + + runner: + image: gitea/act_runner:latest + container_name: gitea-runner + restart: always + networks: + - gitea + volumes: + - runner:/data + - /var/run/docker.sock:/var/run/docker.sock + - ./runner-config.yaml:/data/config.yaml:ro + environment: + - GITEA_INSTANCE_URL=http://server:3000 + - GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_REGISTRATION_TOKEN} + - GITEA_RUNNER_NAME=docker-runner + - CONFIG_FILE=/data/config.yaml + command: > + sh -c " + if [ ! -f /data/.runner ]; then + act_runner register --no-interactive --instance http://server:3000 --token $${GITEA_RUNNER_REGISTRATION_TOKEN} --name docker-runner; + fi; + act_runner --config /data/config.yaml daemon + " + depends_on: + - server + labels: + - diun.enable=true + +networks: + gitea: + external: false + +volumes: + gitea: + postgres: + runner: diff --git a/docs.json b/docs.json index 46b44cc..05efcda 100644 --- a/docs.json +++ b/docs.json @@ -1,68 +1,83 @@ { "$schema": "https://mintlify.com/docs.json", "theme": "mint", - "name": "Mint Starter Kit", + "name": "Trading Analysis Dashboard", "colors": { - "primary": "#16A34A", - "light": "#07C983", - "dark": "#15803D" + "primary": "#0066CC", + "light": "#3399FF", + "dark": "#003D7A" }, "favicon": "/favicon.svg", "navigation": { "tabs": [ { - "tab": "Guides", + "tab": "Documentation", "groups": [ { - "group": "Getting started", + "group": "Getting Started", "pages": [ "index", - "quickstart", - "development" + "quickstart" ] }, { - "group": "Customization", + "group": "Setup & Configuration", "pages": [ - "essentials/settings", - "essentials/navigation" + "guides/setup/cicd", + "guides/setup/sso", + "guides/setup/multi-user" ] }, { - "group": "Writing content", + "group": "Deployment", "pages": [ - "essentials/markdown", - "essentials/code", - "essentials/images", - "essentials/reusable-snippets" + "guides/deployment/docker", + "guides/deployment/caddy" ] }, { - "group": "AI tools", + "group": "Features", "pages": [ - "ai-tools/cursor", - "ai-tools/claude-code", - "ai-tools/windsurf" + "features/portfolio-management", + "features/portfolio-quickstart", + "features/trading-analysis", + "features/csv-upload", + "features/hybrid-matching", + "features/timeframe-analysis", + "features/trading-calendar" ] } ] }, { - "tab": "API reference", + "tab": "API Reference", "groups": [ { - "group": "API documentation", + "group": "Overview", "pages": [ "api-reference/introduction" ] }, { - "group": "Endpoint examples", + "group": "Trading Data", "pages": [ - "api-reference/endpoint/get", - "api-reference/endpoint/create", - "api-reference/endpoint/delete", - "api-reference/endpoint/webhook" + "api-reference/months", + "api-reference/month-data", + "api-reference/trade-details", + "api-reference/timeframe" + ] + }, + { + "group": "Portfolio", + "pages": [ + "api-reference/portfolio-holdings", + "api-reference/portfolio-refresh" + ] + }, + { + "group": "Authentication", + "pages": [ + "api-reference/auth" ] } ] @@ -71,14 +86,9 @@ "global": { "anchors": [ { - "anchor": "Documentation", - "href": "https://mintlify.com/docs", - "icon": "book-open-cover" - }, - { - "anchor": "Blog", - "href": "https://mintlify.com/blog", - "icon": "newspaper" + "anchor": "GitHub", + "href": "https://github.com/acedanger", + "icon": "github" } ] } @@ -87,19 +97,6 @@ "light": "/logo/light.svg", "dark": "/logo/dark.svg" }, - "navbar": { - "links": [ - { - "label": "Support", - "href": "mailto:hi@mintlify.com" - } - ], - "primary": { - "type": "button", - "label": "Dashboard", - "href": "https://dashboard.mintlify.com" - } - }, "contextual": { "options": [ "copy", @@ -114,9 +111,7 @@ }, "footer": { "socials": { - "x": "https://x.com/mintlify", - "github": "https://github.com/mintlify", - "linkedin": "https://linkedin.com/company/mintlify" + "github": "https://github.com/acedanger" } } } diff --git a/features/csv-upload.mdx b/features/csv-upload.mdx new file mode 100644 index 0000000..cd03fe7 --- /dev/null +++ b/features/csv-upload.mdx @@ -0,0 +1,109 @@ +--- +title: 'CSV Upload' +description: 'Import trading data via CSV files with drag-and-drop support' +--- + +## Overview + +The CSV Upload feature allows you to import trading transaction data through an intuitive web interface with drag-and-drop support and real-time processing feedback. + +## Features + + + + Drag CSV files directly onto the upload area + + + Real-time progress bar during processing + + + View recent uploads and statistics + + + Automatic CSV format and size validation + + + +## CSV Format Requirements + +Your CSV file must include these columns: + +| Column | Format | Description | +|--------|--------|-------------| +| **Date** | MM/DD/YYYY | Transaction date | +| **Action** | Text | Buy, Sell, Cash Dividend, etc. | +| **Symbol** | Text | Stock ticker | +| **Description** | Text | Transaction description | +| **Quantity** | Number | Number of shares (can be empty for dividends) | +| **Price** | Number | Price per share (can be empty for dividends) | +| **Fees & Comm** | Number | Trading fees | +| **Amount** | Number | Total transaction amount | + +## Example CSV + +```csv +Date,Action,Symbol,Description,Quantity,Price,Fees & Comm,Amount +01/15/2024,Buy,AAPL,Apple Inc,100,150.50,6.95,-15056.95 +01/30/2024,Sell,AAPL,Apple Inc,100,155.75,6.95,15568.05 +02/15/2024,Cash Dividend,MSFT,Microsoft Corp,,,0.00,75.50 +``` + +## Upload Process + + + + Go to `/upload` in your application + + + + Either drag and drop your CSV file or click to browse + + + + The system validates file type (CSV only) and size (50MB max) + + + + Watch real-time progress updates as the file is processed + + + + View the upload in your history and navigate to the dashboard + + + +## Processing Flow + +1. File uploaded to Flask backend +2. Server validation (file type, size) +3. Trading analysis script processes CSV +4. Database synchronization +5. History updated and temp files cleaned up + +## Security + + + + Login required for all uploads + + + File type and size validation + + + Secure filename handling + + + Automatic temp file removal + + + +## Next Steps + + + + Analyze your uploaded data + + + Track your current holdings + + diff --git a/features/hybrid-matching.mdx b/features/hybrid-matching.mdx new file mode 100644 index 0000000..fff9387 --- /dev/null +++ b/features/hybrid-matching.mdx @@ -0,0 +1,111 @@ +--- +title: 'Hybrid Matching Algorithm' +description: 'Broker-level accuracy for profit/loss and wash sale tracking' +--- + +## Overview + +The hybrid matching algorithm combines two data sources to provide the most accurate profit/loss and wash sale tracking: + +1. **Broker's Realized Gains/Losses CSV** - Pre-calculated lot matches with definitive P&L +2. **Transaction History CSV** - Complete record of all buy/sell transactions + +## Key Benefits + + + + Uses broker's proprietary matching logic + + + Accurate wash sale flags from broker + + + Estimates P/L when broker data unavailable + + + Handles all transaction types + + + +## How It Works + + + + System loads pre-calculated lot matches from broker's realized gains/losses CSV + + + + For each sell transaction, checks if corresponding broker lot exists + + + + If lot found, uses broker's P/L, wash sale flag, and cost basis + + + + If no broker lot, applies FIFO (First In, First Out) matching logic + + + +## Data Sources + +### Broker Realized Gains/Losses + +Contains: +- Opened date (purchase date) +- Closed date (sale date) +- Quantity sold from specific lot +- Cost basis and proceeds +- Gain/loss amount (pre-calculated) +- Wash sale flag +- Disallowed loss amount +- Term (Short/Long) + +### Transaction History + +Contains: +- All buy/sell transactions +- Transaction dates +- Symbol, quantity, price +- Commissions and fees + +## Matching Criteria + +The system matches broker lots to transactions using: + +- **Symbol**: Must match exactly +- **Date**: Must match the transaction date +- **Quantity**: With tolerance for fractional shares + +## Data Source Indicators + + + + ✓ **Broker-verified badge** + + All trades matched to broker lots with definitive P/L + + + + ⚠️ **FIFO estimate badge** + + Trades matched using FIFO logic (no broker lot available) + + + + ✓ **Broker-verified** + ⚠️ **FIFO estimate** + + Month contains both broker-verified and FIFO-estimated trades + + + +## Next Steps + + + + Learn how to upload both CSV files + + + View your matched trades + + diff --git a/features/portfolio-management.mdx b/features/portfolio-management.mdx new file mode 100644 index 0000000..fdf3017 --- /dev/null +++ b/features/portfolio-management.mdx @@ -0,0 +1,153 @@ +--- +title: 'Portfolio Management' +description: 'Track your stock, ETF, and mutual fund holdings with real-time price updates' +--- + +## Overview + +The Portfolio Management feature allows you to track your current stock, ETF, and mutual fund holdings with real-time price updates from Finnhub.io. View comprehensive metrics, allocation charts, and performance analysis all in one place. + +## Key Features + + + + Automatic price updates from Finnhub API + + + Track stocks, ETFs, and mutual funds + + + Interactive allocation and performance charts + + + Bulk import holdings from CSV files + + + +## Quick Start + + + + Register at [Finnhub.io](https://finnhub.io/register) and copy your API key + + + + Add your API key to `.env`: + ```bash + FINNHUB_API_KEY=your_api_key_here + ``` + + + + Use the web interface to add holdings manually or upload a CSV file + + + + Click "Refresh Prices" to fetch current market prices + + + +## Adding Holdings + +### Manual Entry + + + + Navigate to the Portfolio page and click the "Add Holding" button + + + + - **Symbol**: Stock ticker (e.g., AAPL, MSFT) + - **Type**: Select stock, ETF, or mutual_fund + - **Shares**: Number of shares owned + - **Average Cost**: Your average cost per share + - **Notes**: Optional notes about the holding + + + + Click "Save" to add the holding to your portfolio + + + +### CSV Upload + +Upload a CSV file with the following format: + +```csv +symbol,type,shares,average_cost,notes +AAPL,stock,100,150.50,Tech holding +VOO,etf,50,400.00,S&P 500 ETF +VTSAX,mutual_fund,500,120.25,Index fund +``` + + + See the [CSV Upload guide](/features/csv-upload) for detailed formatting instructions. + + +## Portfolio Metrics + +The dashboard displays four key summary cards: + +| Metric | Description | +|--------|-------------| +| **Total Value** | Current market value of all holdings | +| **Total Cost** | Total amount invested (shares × average cost) | +| **Total Gain/Loss** | Dollar amount gained or lost | +| **Total Return** | Percentage return on investment | + +## Charts + +### Allocation Chart + +Interactive doughnut chart showing: +- Percentage of portfolio in each holding +- Dollar amounts on hover +- Click legend to show/hide holdings + +### Performance Chart + +Bar chart displaying: +- Gain/loss for each holding +- Green bars for profitable holdings +- Red bars for losing holdings + +## Managing Holdings + +### Edit a Holding + +1. Click the edit (✏️) button next to any holding +2. Update the fields you want to change +3. Click "Save" + + + You cannot change the symbol of an existing holding. To change a symbol, delete the holding and add a new one. + + +### Delete a Holding + +1. Click the delete (🗑️) button next to any holding +2. Confirm the deletion + +## Price Updates + +Click the **"Refresh Prices"** button to fetch the latest market prices for all holdings. Prices are also automatically refreshed when viewing the page if the last update was more than 15 minutes ago. + +### Rate Limiting + +The free Finnhub API tier allows: +- **60 requests per minute** +- **Real-time US stock quotes** +- **Delayed mutual fund prices** (typically 15-30 minutes) + +The application intelligently manages API requests to stay within these limits. + +## Next Steps + + + + Analyze your historical trading performance + + + Integrate with the Portfolio API + + diff --git a/features/portfolio-quickstart.mdx b/features/portfolio-quickstart.mdx new file mode 100644 index 0000000..cb1af30 --- /dev/null +++ b/features/portfolio-quickstart.mdx @@ -0,0 +1,181 @@ +--- +title: 'Portfolio Quick Start' +description: 'Get started with portfolio tracking in minutes' +--- + +## Quick Setup Guide + +Get your portfolio up and running in just a few minutes. + +## Step 1: Get Your Finnhub API Key + + + + Go to [Finnhub.io](https://finnhub.io/register) and sign up for a free account + + + + After logging in, copy your API key from the dashboard + + + +## Step 2: Configure the API Key + +Add your Finnhub API key to the `.env.docker` file (or `.env` if running locally): + +```bash .env.docker +FINNHUB_API_KEY=your_api_key_here +``` + + + The `.env.docker` file already has a placeholder for the API key. + + +## Step 3: Deploy/Restart the Application + +If you're already running the application, restart it to load the new environment variable: + +```bash +docker compose down +docker compose up -d +``` + +For first-time deployment: + + + + ```bash + ./deploy.sh + ``` + + + ```batch + deploy.bat + ``` + + + +## Step 4: Apply Database Schema + +The portfolio holdings table needs to be created in your database: + +```bash +# Access the database container +docker compose exec postgres psql -U trading_user -d mining_wood + +# Run the schema file +\i /docker-entrypoint-initdb.d/portfolio_schema.sql + +# Or run it directly from the host +docker compose exec -T postgres psql -U trading_user -d mining_wood < database_init/portfolio_schema.sql +``` + +## Step 5: Access the Portfolio Page + + + + Navigate to `http://localhost:8080` + + + + You should be redirected to the Portfolio Management page (now the default landing page) + + + + If you see an error, check the application logs: + ```bash + docker compose logs -f trading_app + ``` + + + +## Step 6: Add Your First Holding + +### Option A: Manual Entry + + + + Click the **"Add Holding"** button + + + + - **Symbol**: Enter a stock ticker (e.g., AAPL) + - **Type**: Select "stock", "etf", or "mutual_fund" + - **Shares**: Enter the number of shares you own + - **Average Cost**: Enter your average cost per share + - **Notes**: (Optional) Add any notes + + + + Click **"Save"** + + + +### Option B: CSV Upload + + + + Create a CSV file with your holdings: + + ```csv + symbol,type,shares,average_cost,notes + AAPL,stock,100,150.50,Apple Inc + MSFT,stock,50,300.00,Microsoft + VOO,etf,25,400.00,S&P 500 ETF + ``` + + + + - Click the **"Upload CSV"** button + - Select your CSV file + - Click **"Upload"** + + + +## Step 7: Refresh Prices + +Click the **"Refresh Prices"** button to fetch current market prices from Finnhub for all your holdings. + +## Troubleshooting + + + + **Solution**: Verify your API key is set correctly in `.env.docker` and you've restarted the containers. + + ```bash + # Check if environment variable is loaded + docker compose exec trading_app env | grep FINNHUB + ``` + + + + **Solution**: Run the portfolio schema script: + + ```bash + docker compose exec -T postgres psql -U trading_user -d mining_wood < database_init/portfolio_schema.sql + ``` + + + + **Solution**: Make sure your CSV file has the correct format with columns: `symbol`, `type`, `shares`, `average_cost`, `notes` + + + + **Solution**: Check the logs for errors: + + ```bash + docker compose logs -f trading_app + ``` + + + +## Next Steps + + + + Learn more about portfolio features + + + Analyze your trading performance + + diff --git a/features/timeframe-analysis.mdx b/features/timeframe-analysis.mdx new file mode 100644 index 0000000..6b57292 --- /dev/null +++ b/features/timeframe-analysis.mdx @@ -0,0 +1,92 @@ +--- +title: 'Timeframe Analysis' +description: 'Analyze trading performance across custom time periods' +--- + +## Overview + +The Timeframe Analysis feature allows you to analyze trading performance across different time periods with comprehensive P/L summaries including both trading profits/losses and dividend income. + +## Time Period Selection + + + + Analyzes all available trading data + + + Current calendar month performance + + + Performance from January 1st to today + + + Rolling 365-day performance + + + Select your own date range + + + +## Key Metrics + +- **Period**: Exact date range for selected timeframe +- **Total P/L**: Combined trading profit/loss and dividends +- **Trading P/L**: Profit/loss from completed trades only +- **Dividends**: Total dividend income received +- **Closed Trades**: Number of completed buy/sell transactions +- **Win Rate**: Percentage of profitable trades + +## Summary Breakdowns + +### Weekly Summary + +Groups data by calendar week showing: +- Trading P/L per week +- Dividends per week +- Total P/L per week +- Number of trades per week + +### Monthly Summary + +Groups data by calendar month showing: +- Trading P/L per month +- Dividends per month +- Total P/L per month +- Number of trades per month + +## Open Positions + +Displays current open positions (stocks bought but not yet sold): +- Symbol and number of shares +- Notes that open positions are excluded from P/L calculations + +## Usage + + + + Go to the Summary page and click "By Timeframe" + + + + Choose from dropdown - date fields auto-populate + + + + Manually adjust start/end dates for fine-tuning + + + + Click "Apply Dates" for custom date ranges + + + +## Next Steps + + + + View monthly trading performance + + + Use the Timeframe API + + diff --git a/features/trading-analysis.mdx b/features/trading-analysis.mdx new file mode 100644 index 0000000..52d8042 --- /dev/null +++ b/features/trading-analysis.mdx @@ -0,0 +1,69 @@ +--- +title: 'Trading Analysis' +description: 'Analyze monthly trading performance and track profit/loss' +--- + +## Overview + +The Trading Analysis feature provides comprehensive monthly trading performance analysis with detailed profit/loss tracking, trade-by-trade breakdowns, and dividend income reporting. + +## Features + + + + Navigate between months with trading data + + + Color-coded profit/loss amounts + + + Detailed breakdown of individual trades + + + Track dividend income separately + + + +## Monthly Dashboard + +The dashboard displays: + +- **Total Trades**: Number of completed buy/sell transactions +- **Winning Trades**: Number of profitable trades +- **Win Rate**: Percentage of winning trades +- **Trading P/L**: Profit/loss from trades +- **Dividend Income**: Total dividends received +- **Total Return**: Combined trading P/L and dividends + +## Trade Details + +Click on any profit/loss amount to see detailed trade information: + +- **Symbol**: Stock ticker +- **Buy Date**: Purchase date +- **Sell Date**: Sale date +- **Buy Price**: Purchase price per share +- **Sell Price**: Sale price per share +- **Volume**: Number of shares traded +- **Profit/Loss**: Total profit or loss +- **Return %**: Percentage return + +## Hybrid Matching Algorithm + +The system uses a hybrid matching algorithm that combines: + +1. **Broker Realized Gains/Losses** - Pre-calculated lot matches with definitive P/L +2. **Transaction History** - Complete record of all buy/sell transactions + +This achieves **broker-level accuracy** for closed positions. + +## Next Steps + + + + Import your trading history + + + Integrate with the Trading API + + diff --git a/features/trading-calendar.mdx b/features/trading-calendar.mdx new file mode 100644 index 0000000..536c437 --- /dev/null +++ b/features/trading-calendar.mdx @@ -0,0 +1,90 @@ +--- +title: 'Trading Calendar' +description: 'Real-time market trading days and holiday information' +--- + +## Overview + +The Trading Calendar API provides real-time metrics about NYSE (New York Stock Exchange) trading days and upcoming market holidays. + +## Features + + + + Trading days left in month and year + + + Upcoming market closure information + + + Is the market open today/tomorrow? + + + View upcoming market holidays + + + +## API Endpoint + +### GET /api/trading-calendar/metrics + +Returns trading calendar metrics including remaining trading days and next market holiday. + +**Authentication**: Required (OAuth 2.0) + +**Response**: + +```json +{ + "success": true, + "remaining_trading_days_month": 14, + "remaining_trading_days_year": 36, + "next_market_holiday": { + "name": "Thanksgiving Day", + "date": "2025-11-27" + }, + "days_until_next_market_holiday": 19, + "upcoming_holidays": [ + { + "name": "Thanksgiving Day", + "date": "2025-11-27", + "days_until": 19 + }, + { + "name": "Christmas Day", + "date": "2025-12-25", + "days_until": 47 + } + ], + "is_market_open_today": false, + "is_market_open_tomorrow": false, + "timezone": "America/New_York" +} +``` + +## Response Fields + +| Field | Type | Description | +|-------|------|-------------| +| `remaining_trading_days_month` | integer | Trading days left in current month | +| `remaining_trading_days_year` | integer | Trading days left in current year | +| `next_market_holiday` | object | Next market closure info | +| `days_until_next_market_holiday` | integer | Days until next closure | +| `upcoming_holidays` | array | List of upcoming holidays (up to 10) | +| `is_market_open_today` | boolean | Market open today? | +| `is_market_open_tomorrow` | boolean | Market open tomorrow? | + +## Data Source + +Uses `pandas_market_calendars` library for accurate NYSE calendar data. + +## Next Steps + + + + View full API documentation + + + Analyze trading performance + + diff --git a/guides/deployment/caddy.mdx b/guides/deployment/caddy.mdx new file mode 100644 index 0000000..39fd92b --- /dev/null +++ b/guides/deployment/caddy.mdx @@ -0,0 +1,393 @@ +--- +title: 'Caddy Configuration' +description: 'Configure Caddy reverse proxy for different deployment scenarios' +--- + +## Overview + +Caddy is a powerful web server that automatically handles HTTPS with Let's Encrypt. This guide explains how to configure Caddy for different deployment scenarios. + +## Local Development + +The default `Caddyfile` is configured for local development: + +```caddy Caddyfile +localhost { + reverse_proxy trading_app:5000 + encode gzip + header { + X-Content-Type-Options nosniff + X-Frame-Options DENY + X-XSS-Protection "1; mode=block" + Referrer-Policy "strict-origin-when-cross-origin" + -Server + } +} +``` + + + Access your app at: `http://localhost` + + +## Production Deployment + +### Step 1: Domain Setup + + + + Point your domain's DNS A record to your server's IP + + + + ```bash + cp Caddyfile.production Caddyfile + ``` + + + + Replace `your-domain.com` with your actual domain + + + +### Step 2: Environment Configuration + +Update your `.env` file: + +```env .env +DOMAIN=your-domain.com +FLASK_ENV=production +``` + +### Step 3: Deploy + +```bash +docker-compose up -d +``` + + + Caddy will automatically: + - Obtain SSL certificates from Let's Encrypt + - Handle HTTP to HTTPS redirects + - Renew certificates automatically + + +## Configuration Options + +### Basic Reverse Proxy + +```caddy +your-domain.com { + reverse_proxy trading_app:5000 +} +``` + +### With Compression and Security Headers + +```caddy +your-domain.com { + reverse_proxy trading_app:5000 + encode gzip + + header { + X-Content-Type-Options nosniff + X-Frame-Options DENY + Strict-Transport-Security "max-age=31536000" + } +} +``` + +### Static File Caching + +```caddy +your-domain.com { + reverse_proxy trading_app:5000 + + @static path /static/* + handle @static { + header Cache-Control "public, max-age=3600" + reverse_proxy trading_app:5000 + } +} +``` + +### Rate Limiting + +```caddy +your-domain.com { + rate_limit { + zone general 10r/s + } + reverse_proxy trading_app:5000 +} +``` + +### Basic Authentication + +```caddy +admin.your-domain.com { + basicauth { + admin $2a$14$hashed_password_here + } + reverse_proxy trading_app:5000 +} +``` + +## SSL/TLS Configuration + +### Automatic HTTPS (Default) + +Caddy automatically obtains certificates from Let's Encrypt: + +```caddy +your-domain.com { + reverse_proxy trading_app:5000 +} +``` + + + No additional configuration needed! Caddy handles everything automatically. + + +### Custom Certificates + +```caddy +your-domain.com { + tls /path/to/cert.pem /path/to/key.pem + reverse_proxy trading_app:5000 +} +``` + +### Internal/Self-Signed Certificates + +```caddy +your-domain.com { + tls internal + reverse_proxy trading_app:5000 +} +``` + +## Monitoring and Logging + +### Access Logs + +```caddy +your-domain.com { + reverse_proxy trading_app:5000 + + log { + output file /var/log/caddy/access.log + format json + } +} +``` + +### Error Handling + +```caddy +your-domain.com { + reverse_proxy trading_app:5000 + + handle_errors { + @404 expression {http.error.status_code} == 404 + handle @404 { + rewrite * /404.html + reverse_proxy trading_app:5000 + } + } +} +``` + +## Advanced Features + +### Multiple Domains + +```caddy +site1.com, site2.com { + reverse_proxy trading_app:5000 +} +``` + +### Subdomain Routing + +```caddy +api.your-domain.com { + reverse_proxy trading_app:5000/api +} + +app.your-domain.com { + reverse_proxy trading_app:5000 +} +``` + +### Load Balancing + +```caddy +your-domain.com { + reverse_proxy trading_app1:5000 trading_app2:5000 { + lb_policy round_robin + health_path /health + } +} +``` + +## Troubleshooting + +### Check Caddy Status + +```bash +docker-compose logs caddy +``` + +### Certificate Issues + +```bash +# Check certificate status +docker-compose exec caddy caddy list-certificates + +# Force certificate renewal +docker-compose exec caddy caddy reload --config /etc/caddy/Caddyfile +``` + +### Configuration Validation + +```bash +# Validate Caddyfile syntax +docker-compose exec caddy caddy validate --config /etc/caddy/Caddyfile +``` + +### Common Issues + + + + ```bash + # Check what's using the ports + netstat -tlnp | grep :80 + netstat -tlnp | grep :443 + ``` + + Stop the conflicting service or change Caddy's ports in docker-compose.yml + + + + ```bash + # Check DNS resolution + nslookup your-domain.com + ``` + + Verify your domain's A record points to the correct IP address + + + + Use staging environment for testing: + + ```caddy + your-domain.com { + tls { + ca https://acme-staging-v02.api.letsencrypt.org/directory + } + reverse_proxy trading_app:5000 + } + ``` + + + + - Ensure port 80 is accessible from the internet + - Verify DNS is propagated: `dig your-domain.com` + - Check firewall rules allow incoming connections + - Review Caddy logs for specific errors + + + +## Performance Tuning + +### Enable HTTP/2 and HTTP/3 + +```caddy +your-domain.com { + protocols h1 h2 h3 + reverse_proxy trading_app:5000 +} +``` + +### Connection Limits + +```caddy +your-domain.com { + reverse_proxy trading_app:5000 { + transport http { + max_conns_per_host 100 + } + } +} +``` + +### Timeout Configuration + +```caddy +your-domain.com { + reverse_proxy trading_app:5000 { + transport http { + read_timeout 30s + write_timeout 30s + } + } +} +``` + +## Security Best Practices + + + + Use TLS 1.2+ with strong cipher suites (Caddy's default) + + + Add security headers like CSP, HSTS, X-Frame-Options + + + Implement rate limiting to prevent abuse + + + Use basic auth or OAuth for sensitive routes + + + +### Recommended Security Configuration + +```caddy +your-domain.com { + reverse_proxy trading_app:5000 + + encode gzip + + header { + # Security headers + Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" + X-Content-Type-Options "nosniff" + X-Frame-Options "DENY" + X-XSS-Protection "1; mode=block" + Referrer-Policy "strict-origin-when-cross-origin" + Permissions-Policy "geolocation=(), microphone=(), camera=()" + + # Hide server info + -Server + -X-Powered-By + } +} +``` + +## Additional Resources + + + + Official Caddy documentation + + + Learn Caddyfile syntax + + + How Caddy handles HTTPS automatically + + + Back to Docker deployment guide + + diff --git a/guides/deployment/docker.mdx b/guides/deployment/docker.mdx new file mode 100644 index 0000000..a2eb27c --- /dev/null +++ b/guides/deployment/docker.mdx @@ -0,0 +1,426 @@ +--- +title: 'Docker Deployment' +description: 'Deploy the Trading Analysis Dashboard using Docker containers' +--- + +## Quick Start + + + + Install [Docker Desktop](https://www.docker.com/products/docker-desktop/) (includes Docker Compose) + + + + + + ```batch + deploy.bat + ``` + + + ```bash + chmod +x deploy.sh + ./deploy.sh + ``` + + + + + + ```bash + # Copy environment file + cp .env.docker .env + + # Build and start services + docker compose up -d + + # Check status + docker compose ps + ``` + + + +## Services Overview + +The deployment includes these services: + +| Service | Port | Description | +|---------|------|-------------| +| **trading_app** | 8080 | Main Flask application | +| **postgres** | 5432 | PostgreSQL database | +| **caddy** | 80, 443 | Reverse proxy with automatic HTTPS | + +## Access URLs + + + + https://performance.miningwood.com + + + http://localhost:8080 + + + http://localhost + + + localhost:5432 + + + +## Docker Compose Configuration + +The complete `docker-compose.yml` file for the application: + +```yaml docker-compose.yml +services: + server: + image: docker.gitea.com/gitea:latest + container_name: gitea + environment: + - USER_UID=${USER_UID} + - USER_GID=${USER_GID} + - GITEA__database__DB_TYPE=postgres + - GITEA__database__HOST=db:5432 + - GITEA__database__NAME=${POSTGRES_USER} + - GITEA__database__USER=${POSTGRES_USER} + - GITEA__database__PASSWD=${POSTGRES_PASSWORD} + restart: always + networks: + - gitea + volumes: + - gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + ports: + - ${GITEA_HTTP_PORT:-3500}:3000 + - ${GITEA_SSH_PORT:-2229}:22 + depends_on: + - db + labels: + - diun.enable=true + healthcheck: + test: + - CMD + - curl + - -f + - http://localhost + interval: 10s + retries: 3 + start_period: 30s + timeout: 10s + + db: + image: docker.io/library/postgres:14 + restart: always + environment: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} + networks: + - gitea + volumes: + - postgres:/var/lib/postgresql/data + + runner: + image: gitea/act_runner:latest + container_name: gitea-runner + restart: always + networks: + - gitea + volumes: + - runner:/data + - /var/run/docker.sock:/var/run/docker.sock + - ./runner-config.yaml:/data/config.yaml:ro + environment: + - GITEA_INSTANCE_URL=http://server:3000 + - GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_REGISTRATION_TOKEN} + - GITEA_RUNNER_NAME=docker-runner + - CONFIG_FILE=/data/config.yaml + command: > + sh -c " + if [ ! -f /data/.runner ]; then + act_runner register --no-interactive --instance http://server:3000 --token $${GITEA_RUNNER_REGISTRATION_TOKEN} --name docker-runner; + fi; + act_runner --config /data/config.yaml daemon + " + depends_on: + - server + labels: + - diun.enable=true + +networks: + gitea: + external: false + +volumes: + gitea: + postgres: + runner: +``` + +## Configuration + +### Environment Variables + +Edit the `.env` file to customize your deployment: + +```env .env +# Database Configuration +DB_HOST=postgres +DB_PORT=5432 +DB_NAME=mining_wood +DB_USER=trading_user +DB_PASSWORD=your_secure_password + +# Flask Configuration +FLASK_SECRET_KEY=your-super-secret-key-change-this +FLASK_ENV=production + +# Gitea Configuration +USER_UID=1000 +USER_GID=1000 +POSTGRES_USER=gitea +POSTGRES_PASSWORD=gitea_password +POSTGRES_DB=gitea +GITEA_HTTP_PORT=3500 +GITEA_SSH_PORT=2229 +GITEA_RUNNER_REGISTRATION_TOKEN=your_token_here +``` + + + Always change default passwords before deploying to production! + + +### SSL/HTTPS Setup with Caddy + +Caddy provides automatic HTTPS with Let's Encrypt: + + + + No setup needed - uses HTTP by default + + + + ```bash + # Edit Caddyfile and replace localhost with your domain + cp Caddyfile.production Caddyfile + # Edit the domain in Caddyfile: your-domain.com + ``` + + Caddy will automatically get and renew SSL certificates! + + + +## Database Setup + +The PostgreSQL database is automatically initialized with: +- **Database**: `mining_wood` +- **Schema**: `trading_analysis` +- **User**: `trading_user` + +### Import Your Trading Data + +After deployment, import your trading data: + + + + ```bash + docker compose exec postgres psql -U trading_user -d mining_wood + ``` + + + + ```bash + # Copy your CSV files to the container + docker cp your-data.csv trading_app:/app/data/ + + # Run your import script + docker compose exec trading_app python your_import_script.py + ``` + + + +## Management Commands + +### View Logs + +```bash +# All services +docker compose logs -f + +# Specific service +docker compose logs -f trading_app +docker compose logs -f postgres +docker compose logs -f caddy +``` + +### Restart Services + +```bash +# Restart all services +docker compose restart + +# Restart specific service +docker compose restart trading_app +``` + +### Stop/Start + +```bash +# Stop all services +docker compose down + +# Start services +docker compose up -d + +# Stop and remove volumes (⚠️ removes database data) +docker compose down -v +``` + +### Update Application + +```bash +# Pull latest images and restart +docker compose pull +docker compose up -d +``` + +### Database Backup + +```bash +# Backup database +docker compose exec postgres pg_dump -U trading_user mining_wood > backup.sql + +# Restore database +docker compose exec -T postgres psql -U trading_user mining_wood < backup.sql +``` + +## Security Considerations + +### For Production Deployment + + + + Update `POSTGRES_PASSWORD` and `FLASK_SECRET_KEY` in docker compose.yml/.env + + + Configure SSL certificates and enable HTTPS redirect + + + Only expose necessary ports (80, 443). Restrict database access (5432) + + + Keep Docker images updated and monitor security advisories + + + +## Production Deployment + +### Domain Setup + + + + - Point your domain to your server's IP address + - For performance.miningwood.com: Create an A record pointing to your server IP + + + + ```bash + # Caddy handles SSL automatically with Let's Encrypt + # The domain is already configured for performance.miningwood.com + # Just deploy and Caddy will handle the rest + docker compose up -d + ``` + + + + - Domain is already set to `performance.miningwood.com` in `.env.docker` + - Set `FLASK_ENV=production` + - Use strong passwords + + + +### Monitoring + +Consider adding monitoring services: + +```yaml docker-compose.yml +# Add to docker compose.yml +prometheus: + image: prom/prometheus + ports: + - "9090:9090" + +grafana: + image: grafana/grafana + ports: + - "3000:3000" +``` + +## Troubleshooting + + + + ```bash + # Check logs + docker compose logs trading_app + + # Common issues: + # - Database connection failure + # - Missing environment variables + # - Port conflicts + ``` + + + + ```bash + # Check database status + docker compose exec postgres pg_isready -U trading_user + + # Reset database + docker compose down -v + docker compose up -d + ``` + + + + ```bash + # Check resource usage + docker stats + + # Scale services + docker compose up -d --scale trading_app=2 + ``` + + + + - Ensure DNS is pointing to correct server + - Wait a few minutes for certificate provisioning + - Check Caddy logs: `docker compose logs caddy` + + + +## Development Mode + +To run in development mode: + +```bash +# Use development override +docker compose -f docker compose.yml -f docker compose.dev.yml up -d +``` + +This enables: +- Live code reloading +- Debug mode +- Development tools + +## Next Steps + + + + Learn more about Caddy reverse proxy setup + + + Automate deployments with CI/CD + + diff --git a/guides/setup/cicd.mdx b/guides/setup/cicd.mdx new file mode 100644 index 0000000..6f6e782 --- /dev/null +++ b/guides/setup/cicd.mdx @@ -0,0 +1,283 @@ +--- +title: 'CI/CD Setup with Gitea' +description: 'Set up continuous integration and deployment using Gitea Actions' +--- + +## Overview + +This guide will help you set up continuous integration and continuous deployment (CI/CD) for your trading analysis application using Gitea Actions. + +## Prerequisites + +Before starting, ensure you have: + + + + Running and accessible Gitea instance + + + Docker, Docker Compose, SSH access, and Git installed + + + Domain pointing to your production server + + + SSH key pair for deployment access + + + +## Step 1: Repository Setup + +Push your code to Gitea and enable Actions: + +```bash +git remote add origin https://your-gitea-instance.com/your-username/stocks-trading-analysis.git +git push -u origin main +``` + + + + Go to Repository Settings → Actions and enable Actions for this repository + + + +## Step 2: Configure Repository Secrets + +Navigate to your repository → Settings → Secrets and add the following secrets: + +### Required Secrets + +| Secret Name | Description | Example | +|-------------|-------------|---------| +| `SSH_PRIVATE_KEY` | SSH private key for production server access | `-----BEGIN OPENSSH PRIVATE KEY-----\n...` | +| `PRODUCTION_HOST` | Production server IP or hostname | `203.0.113.1` or `server.example.com` | +| `PRODUCTION_USER` | SSH username for production server | `ubuntu`, `root`, or your username | +| `DOMAIN` | Your production domain | `performance.miningwood.com` | + +### Application Secrets + +| Secret Name | Description | Example | +|-------------|-------------|---------| +| `FLASK_SECRET_KEY` | Flask session secret key | `your-very-secure-secret-key-here` | +| `POSTGRES_PASSWORD` | Production database password | `secure-database-password` | +| `GOOGLE_CLIENT_ID` | OAuth Google Client ID | `123456789.apps.googleusercontent.com` | +| `GOOGLE_CLIENT_SECRET` | OAuth Google Client Secret | `GOCSPX-your-client-secret` | +| `AUTHORIZED_USERS` | Comma-separated authorized emails | `admin@example.com,user@example.com` | + +### Optional Notification Secrets + +| Secret Name | Description | +|-------------|-------------| +| `SLACK_WEBHOOK_URL` | Slack webhook for notifications | +| `DISCORD_WEBHOOK_URL` | Discord webhook for notifications | + +## Step 3: Production Server Setup + +### Create Application Directory + +```bash +# SSH into your production server +ssh your-user@your-production-server + +# Create application directory +sudo mkdir -p /opt/stocks-trading-analysis +sudo chown $USER:$USER /opt/stocks-trading-analysis +cd /opt/stocks-trading-analysis + +# Clone the repository +git clone https://your-gitea-instance.com/your-username/stocks-trading-analysis.git . +``` + +### Configure Environment Variables + +```bash +# Copy the production environment template +cp .gitea/deployment/production.env .env + +# Edit the environment file with your actual values +nano .env +``` + +Update the following values in `.env`: +- `POSTGRES_PASSWORD`: Set a secure database password +- `FLASK_SECRET_KEY`: Generate a secure secret key +- `GOOGLE_CLIENT_ID` & `GOOGLE_CLIENT_SECRET`: Your OAuth credentials +- `AUTHORIZED_USERS`: List of authorized email addresses +- `DOMAIN`: Your production domain name + +### Initial Deployment + +```bash +# Make deployment script executable +chmod +x .gitea/deployment/deploy.sh + +# Run initial deployment +./deploy.sh +``` + +## Step 4: SSH Key Setup + +### Generate SSH Key Pair (if needed) + +```bash +# On your local machine or CI/CD runner +ssh-keygen -t ed25519 -C "gitea-actions-deployment" -f ~/.ssh/gitea_deploy_key +``` + +### Add Public Key to Production Server + +```bash +# Copy public key to production server +ssh-copy-id -i ~/.ssh/gitea_deploy_key.pub your-user@your-production-server + +# Or manually add to authorized_keys +cat ~/.ssh/gitea_deploy_key.pub | ssh your-user@your-production-server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys" +``` + +### Add Private Key to Gitea Secrets + +```bash +# Copy private key content +cat ~/.ssh/gitea_deploy_key + +# Add this content to the SSH_PRIVATE_KEY secret in Gitea +``` + +## Step 5: Test the CI/CD Pipeline + +### Trigger First Pipeline + + + + Make a small change to your code + + + ```bash + git add . + git commit -m "Test CI/CD pipeline" + git push origin main + ``` + + + Check the Actions tab in your Gitea repository to see the pipeline running + + + +### Verify Deployment + + + + Visit `https://your-domain.com` to verify the application is running + + + SSH to server and run `docker compose logs -f` + + + Run `docker compose ps` to check service status + + + +## Workflow Overview + +### Automatic Triggers + +- **Push to main/master**: Triggers full CI/CD pipeline with production deployment +- **Push to develop**: Triggers CI/CD pipeline with staging deployment (if configured) +- **Pull requests**: Triggers testing and build validation only +- **Schedule**: Security scans run weekly, cleanup runs weekly + +### Manual Triggers + +Navigate to Actions tab in your repository, click "Run workflow" on any workflow, select branch and run. + +## Monitoring and Maintenance + +### Check Application Health + +```bash +# SSH to production server +ssh your-user@your-production-server + +# Check service status +docker compose ps + +# View logs +docker compose logs -f trading_app + +# Check resource usage +docker stats +``` + +### Database Backups + +Backups are automatically created during deployments and stored in `/opt/backups/stocks-app/`. + +```bash +# Manual backup +docker compose exec postgres pg_dump -U trading_user mining_wood | gzip > backup_$(date +%Y%m%d_%H%M%S).sql.gz + +# Restore from backup +gunzip -c backup_file.sql.gz | docker compose exec -T postgres psql -U trading_user mining_wood +``` + +### SSL Certificate + +Caddy automatically handles SSL certificates. Check certificate status: + +```bash +# Check certificate +echo | openssl s_client -servername your-domain.com -connect your-domain.com:443 2>/dev/null | openssl x509 -noout -dates +``` + +## Troubleshooting + + + + - Verify SSH key is correctly formatted in secrets + - Check server SSH configuration + - Ensure server is accessible from internet + + + + - Check Dockerfile syntax + - Verify all dependencies in requirements.txt + - Check for file permission issues + + + + - Check environment variables in .env + - Verify database is running: `docker compose logs postgres` + - Check application logs: `docker compose logs trading_app` + + + + - Ensure DNS is pointing to correct server + - Wait a few minutes for certificate provisioning + - Check Caddy logs: `docker compose logs caddy` + + + +## Security Best Practices + + + Remember to regularly rotate secrets and monitor deployment logs for suspicious activity. + + +1. **Regularly rotate secrets** (SSH keys, database passwords) +2. **Monitor deployment logs** for suspicious activity +3. **Keep dependencies updated** (run security scans) +4. **Use strong passwords** for all services +5. **Backup regularly** and test restore procedures +6. **Monitor server resources** and set up alerts + +## Customization + +You can customize the CI/CD pipeline by modifying files in `.gitea/workflows/`: + +- `main.yml`: Main CI/CD pipeline +- `security.yml`: Security scanning +- `cleanup.yml`: Resource cleanup and maintenance + + + Remember to test changes in a staging environment before deploying to production! + diff --git a/guides/setup/multi-user.mdx b/guides/setup/multi-user.mdx new file mode 100644 index 0000000..9bbb567 --- /dev/null +++ b/guides/setup/multi-user.mdx @@ -0,0 +1,262 @@ +--- +title: 'Multi-User Support' +description: 'Configure multi-user support with separate brokerage accounts' +--- + +## Overview + +The application supports multiple users, each with their own brokerage account numbers and transaction data. Users authenticate via Google OAuth and can set up their brokerage account number in their profile. + +## Database Schema Changes + +### New Tables + +#### `trading_analysis.users` +Stores user information from OAuth: + +| Column | Type | Description | +|--------|------|-------------| +| `id` | Primary Key | User identifier | +| `email` | Unique | User email address | +| `name` | String | User's full name | +| `google_sub` | String | Google OAuth subject ID | +| `picture_url` | String | Profile picture URL | +| `brokerage_account_number` | String | User's primary account | +| `is_active` | Boolean | Account active status | +| `created_at` | Timestamp | Creation date | +| `updated_at` | Timestamp | Last update date | + +#### `trading_analysis.brokerage_accounts` +Cross-reference table for account numbers: + +| Column | Type | Description | +|--------|------|-------------| +| `id` | Primary Key | Account identifier | +| `account_number` | Unique | Brokerage account number | +| `account_display_name` | String | Optional friendly name | +| `user_id` | Foreign Key | Links to users table | +| `is_primary` | Boolean | Primary account flag | +| `created_at` | Timestamp | Creation date | +| `updated_at` | Timestamp | Last update date | + +### Updated Tables + +All existing tables have been updated with a `brokerage_account_id` foreign key: +- `raw_transactions` +- `matched_trades` +- `dividend_transactions` +- `monthly_trading_summary` +- `monthly_dividend_summary` +- `monthly_combined_summary` +- `processing_log` + +## Migration Process + +To migrate an existing database to support multiple users: + +### Step 1: Run the Migration Script + +```bash +python migrate_to_multiuser.py +``` + +### Step 2: Set Environment Variables (optional) + +```bash +export DEFAULT_MIGRATION_EMAIL="your-admin@example.com" +export DEFAULT_MIGRATION_NAME="Admin User" +export DEFAULT_BROKERAGE_ACCOUNT="YOUR_ACCOUNT_NUMBER" +``` + + + The migration script will create default values if these environment variables are not set. + + +### What the Migration Does + + + + Creates `users` and `brokerage_accounts` tables + + + Adds `brokerage_account_id` columns to existing tables + + + Creates a default user and account for existing data + + + Updates all existing transactions to reference the default account + + + Recreates database views to work with the new schema + + + +## Application Changes + +### User Profile Management + + + + Users can now set their brokerage account number in their profile + + + CSV uploads require a valid brokerage account number + + + Users can have multiple brokerage accounts (future feature) + + + Users only see their own transaction data + + + +### Upload Process + +1. **User Validation**: Checks that user has a brokerage account before allowing uploads +2. **Account Association**: All uploaded transactions are associated with the user's account +3. **Processing**: Modified `trading_analysis.py` to accept `--account-id` parameter + +### Authentication Flow + + + + User logs in via Google OAuth + + + User record is created/updated in the database + + + User sets their brokerage account number in profile + + + Brokerage account record is created and linked to user + + + CSV uploads are associated with the user's account + + + +## Database Queries + +### User-Specific Data + +All queries now need to filter by `brokerage_account_id`: + +```sql +-- Get user's transactions +SELECT * FROM trading_analysis.raw_transactions rt +JOIN trading_analysis.brokerage_accounts ba ON rt.brokerage_account_id = ba.id +WHERE ba.user_id = ?; + +-- Get user's trading performance +SELECT * FROM trading_analysis.v_trading_performance +WHERE user_email = 'user@example.com'; +``` + +### Updated Views + +Views now include user context: + +- `v_current_positions` - Shows account and user information +- `v_trading_performance` - Includes user email and account number + +## Configuration + +### Environment Variables + +```bash +# Migration Configuration +DEFAULT_MIGRATION_EMAIL=your-admin@example.com +DEFAULT_MIGRATION_NAME=Admin User +DEFAULT_BROKERAGE_ACCOUNT=YOUR_ACCOUNT_NUMBER + +# OAuth Configuration (existing) +GOOGLE_CLIENT_ID=your-client-id +GOOGLE_CLIENT_SECRET=your-client-secret +AUTHORIZED_USERS=user1@example.com,user2@example.com +``` + +## Security Considerations + + + User data isolation is critical for multi-user environments. Always verify queries filter by the correct account ID. + + +1. **User Isolation**: Users can only see their own transaction data +2. **Account Validation**: Brokerage account numbers are validated before processing +3. **OAuth Integration**: User authentication is handled by Google OAuth +4. **Data Protection**: User data is isolated by account ID in all database operations + +## Future Enhancements + + + + Support for users with multiple brokerage accounts + + + Allow users to share specific accounts with other users + + + Administrative interface for managing users and accounts + + + User-specific data export functionality + + + +## Troubleshooting + + + + - Ensure database connection is working + - Verify you have proper permissions + - Check for existing foreign key constraints + - Review migration logs for specific errors + + + + - Check that OAuth is configured correctly + - Verify user email is in AUTHORIZED_USERS + - Check application logs for authentication errors + + + + - Verify user has set brokerage account number in profile + - Check CSV format matches expected schema + - Review processing logs in `trading_analysis.log` + + + + - Ensure queries are filtering by correct account ID + - Verify user-account association is correct + - Check database views are updated + + + +### Database Verification + +```sql +-- Check user-account associations +SELECT u.email, u.brokerage_account_number, ba.account_number, ba.is_primary +FROM trading_analysis.users u +LEFT JOIN trading_analysis.brokerage_accounts ba ON u.id = ba.user_id; + +-- Check transaction associations +SELECT COUNT(*) as transaction_count, ba.account_number, u.email +FROM trading_analysis.raw_transactions rt +JOIN trading_analysis.brokerage_accounts ba ON rt.brokerage_account_id = ba.id +JOIN trading_analysis.users u ON ba.user_id = u.id +GROUP BY ba.account_number, u.email; +``` + +## Next Steps + + + + Set up portfolio tracking for your account + + + Learn how to upload transaction data + + diff --git a/guides/setup/sso.mdx b/guides/setup/sso.mdx new file mode 100644 index 0000000..0b34b00 --- /dev/null +++ b/guides/setup/sso.mdx @@ -0,0 +1,234 @@ +--- +title: 'SSO Authentication Setup' +description: 'Configure Google OAuth 2.0 authentication for your Trading Analysis Dashboard' +--- + +## Overview + +This guide will help you configure Google OAuth 2.0 authentication for secure access to your Trading Analysis Dashboard. + +## Step 1: Create Google OAuth Application + + + + Visit [Google Cloud Console](https://console.cloud.google.com/) and sign in with your Google account + + + + - Click "Select a project" → "New Project" + - Name: "Trading Dashboard" + - Click "Create" + + + + - Go to "APIs & Services" → "Library" + - Search for "Google+ API" and enable it + - Also enable "Google Identity" if available + + + + - Go to "APIs & Services" → "Credentials" + - Click "Create Credentials" → "OAuth 2.0 Client IDs" + - Choose "Web application" + - Name: "Trading Dashboard Auth" + + + + Add the following URLs: + + **Authorized JavaScript origins:** + - `https://performance.miningwood.com` + - `http://localhost:8080` (for testing) + + **Authorized redirect URIs:** + - `https://performance.miningwood.com/auth/callback` + - `http://localhost:8080/auth/callback` (for testing) + + + + Copy the "Client ID" and "Client Secret" for the next step + + + +## Step 2: Configure Environment Variables + +Update your `.env.docker` file with the OAuth credentials: + +```bash .env.docker +# OAuth Configuration +GOOGLE_CLIENT_ID=your-actual-client-id.apps.googleusercontent.com +GOOGLE_CLIENT_SECRET=your-actual-client-secret + +# Authorized Users (your email addresses) +AUTHORIZED_USERS=your-email@gmail.com,admin@company.com +``` + + + Never commit your `.env` files to version control. Keep them secure and out of your repository. + + +## Step 3: Update and Deploy + +### Rebuild the application + +```bash +docker compose build trading_app +docker compose restart trading_app +``` + +### Test the authentication + + + + Navigate to `https://performance.miningwood.com` + + + + You should be redirected to the login page. Click "Sign in with Google" + + + + Authorize the application when prompted by Google + + + + You should be redirected back and logged in successfully + + + +## Security Features + + + + Industry standard authentication protocol + + + Only specific email addresses can access + + + Secure server-side sessions with expiration + + + All authentication over encrypted connections + + + +## User Management + +### Add Users + +Add email addresses to `AUTHORIZED_USERS` in `.env.docker`, separated by commas: + +```bash +AUTHORIZED_USERS=user1@example.com,user2@example.com,user3@example.com +``` + +Then restart the application: + +```bash +docker compose restart trading_app +``` + +### Remove Users + +Remove email addresses from `AUTHORIZED_USERS` and restart the application. + + + Leave `AUTHORIZED_USERS` empty to allow all users (not recommended for production) + + +## Troubleshooting + + + + - Check that Client ID and Secret are correct in `.env.docker` + - Verify redirect URLs match exactly in Google Cloud Console + - Ensure Google+ API is enabled + - Check application logs: `docker compose logs trading_app` + + + + - Verify your email is in `AUTHORIZED_USERS` + - Ensure email case matches exactly + - Check for extra spaces in the email list + + + + - Clear browser cookies for your domain + - Verify Flask secret key is set in `.env.docker` + - Check session configuration in application logs + + + + Ensure the redirect URIs in Google Cloud Console match your deployment: + - Use `https://` for production + - Include the exact domain and path + - No trailing slashes + + + +## Alternative OAuth Providers + +You can also configure other OAuth providers: + + + + ```bash .env.docker + GITHUB_CLIENT_ID=your-github-client-id + GITHUB_CLIENT_SECRET=your-github-client-secret + ``` + + 1. Create OAuth App at https://github.com/settings/developers + 2. Set Authorization callback URL to `https://your-domain.com/auth/callback` + + + + ```bash .env.docker + MICROSOFT_CLIENT_ID=your-microsoft-client-id + MICROSOFT_CLIENT_SECRET=your-microsoft-client-secret + ``` + + 1. Register app at https://portal.azure.com + 2. Add redirect URI in Authentication settings + + + + + Contact your administrator if you need help configuring alternative providers. + + +## Testing OAuth Configuration + +To test your OAuth setup locally: + +```bash +# Start the application locally +docker compose up -d + +# Check logs for any OAuth errors +docker compose logs -f trading_app + +# Visit localhost +open http://localhost:8080 +``` + +## Security Checklist + +- [ ] OAuth credentials are stored in `.env` files, not in code +- [ ] `.env` files are in `.gitignore` +- [ ] `AUTHORIZED_USERS` list is properly configured +- [ ] HTTPS is enabled in production +- [ ] Strong `FLASK_SECRET_KEY` is set +- [ ] Redirect URIs are exact matches in Google Cloud Console +- [ ] Google+ API is enabled + +## Next Steps + + + + Configure multi-user support with brokerage accounts + + + Deploy your application to production + + diff --git a/index.mdx b/index.mdx index 15c23fb..d63e3a9 100644 --- a/index.mdx +++ b/index.mdx @@ -1,97 +1,115 @@ --- -title: "Introduction" -description: "Welcome to the new home for your documentation" +title: "Trading Analysis Dashboard" +description: "A comprehensive platform for analyzing trading performance and managing your investment portfolio" --- -## Setting up +## Welcome to Trading Analysis Dashboard -Get your documentation site up and running in minutes. +A modern, interactive web application for tracking and analyzing your stock trading performance with real-time portfolio management and comprehensive reporting. - - Follow our three step quickstart guide. - - -## Make it yours - -Design a docs site that looks great and empowers your users. - - + - Edit your docs locally and preview them in real time. + Get up and running in minutes with our quick start guide - Customize the design and colors of your site to match your brand. - - - Organize your docs to help users find what they need and succeed with your product. + Track your holdings with real-time price updates from Finnhub + Analyze monthly trading performance and track P&L + + - Auto-generate API documentation from OpenAPI specifications. + Integrate with our comprehensive RESTful API - + -## Create beautiful pages +## Key Features -Everything you need to create world-class documentation. + + + Track your stock, ETF, and mutual fund holdings with real-time price updates from Finnhub. View allocation charts, performance metrics, and gain/loss analysis. + + + + Analyze monthly trading performance with detailed P&L breakdowns, win/loss ratios, and trade-by-trade analysis. View comprehensive reports with dividend tracking. + + + + Google OAuth 2.0 integration with user-specific data isolation. Support for multiple users with separate brokerage accounts. + + + + Easy CSV import with drag-and-drop support. Real-time processing feedback and upload history tracking. + + + + Complete Docker Compose setup with PostgreSQL database, Caddy reverse proxy, and automatic HTTPS with Let's Encrypt. + + + + Full Gitea Actions workflow for automated testing, building, and deployment with security scanning and rollback capabilities. + + - - - Use MDX to style your docs pages. - - - Add sample code to demonstrate how to use your product. - - - Display images and other media. - - - Write once and reuse across your docs. - - +## Technology Stack -## Need inspiration? + + + Python web framework + + + Relational database + + + Containerization + + + Reverse proxy & HTTPS + + + Real-time market data + + + Secure authentication + + + +## Getting Started + + + + Install Docker and Docker Compose, and obtain a Finnhub API key + + + Clone the repository and set up your environment variables + + + Run the deployment script to start all services + + + Import your trading data via CSV upload + + - Browse our showcase of exceptional documentation sites. + Check out our comprehensive quickstart guide to get your dashboard running in minutes diff --git a/quickstart.mdx b/quickstart.mdx index c711458..9b372bc 100644 --- a/quickstart.mdx +++ b/quickstart.mdx @@ -1,80 +1,205 @@ --- title: "Quickstart" -description: "Start building awesome documentation in minutes" +description: "Get your Trading Analysis Dashboard up and running in minutes" --- -## Get started in three steps +## Get Started in Four Steps -Get your documentation site running locally and make your first customization. +Deploy your trading analysis dashboard and start tracking your portfolio performance. -### Step 1: Set up your local environment +### Step 1: Prerequisites - - During the onboarding process, you created a GitHub repository with your docs content if you didn't already have one. You can find a link to this repository in your [dashboard](https://dashboard.mintlify.com). - - To clone the repository locally so that you can make and preview changes to your docs, follow the [Cloning a repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) guide in the GitHub docs. + + Install [Docker Desktop](https://www.docker.com/products/docker-desktop/) which includes Docker Compose. This is required for running the application containers. - - 1. Install the Mintlify CLI: `npm i -g mint` - 2. Navigate to your docs directory and run: `mint dev` - 3. Open `http://localhost:3000` to see your docs live! + + 1. Register for a free account at [Finnhub.io](https://finnhub.io/register) + 2. Navigate to your dashboard + 3. Copy your API key - you'll need this for real-time price updates - Your preview updates automatically as you edit files. + The free tier includes 60 API calls per minute and real-time US stock quotes + + + For secure authentication, create OAuth credentials: + 1. Visit [Google Cloud Console](https://console.cloud.google.com/) + 2. Create a new project + 3. Enable Google+ API + 4. Create OAuth 2.0 credentials + 5. Copy Client ID and Client Secret + + See the [SSO Setup Guide](/guides/setup/sso) for detailed instructions. -### Step 2: Deploy your changes +### Step 2: Configure Environment - - - Install the Mintlify GitHub app from your [dashboard](https://dashboard.mintlify.com/settings/organization/github-app). + + + ```bash + git clone https://your-repo-url/trading-analysis-dashboard.git + cd trading-analysis-dashboard + ``` + + + + ```bash + cp .env.docker .env + ``` + + + + Update the following values: - Our GitHub app automatically deploys your changes to your docs site, so you don't need to manage deployments yourself. - - - For a first change, let's update the name and colors of your docs site. + ```env .env + # Finnhub Configuration + FINNHUB_API_KEY=your_finnhub_api_key_here + + # Database Configuration + POSTGRES_PASSWORD=choose_secure_password + + # Flask Configuration + FLASK_SECRET_KEY=generate_random_secret_key + + # OAuth Configuration (Optional) + GOOGLE_CLIENT_ID=your_google_client_id + GOOGLE_CLIENT_SECRET=your_google_client_secret + AUTHORIZED_USERS=your-email@example.com + ``` + + Never commit the `.env` file to version control! + + - 1. Open `docs.json` in your editor. - 2. Change the `"name"` field to your project name. - 3. Update the `"colors"` to match your brand. - 4. Save and see your changes instantly at `http://localhost:3000`. +### Step 3: Deploy - Try changing the primary color to see an immediate difference! - - + + + ```batch + deploy.bat + ``` + + + ```bash + chmod +x deploy.sh + ./deploy.sh + ``` + + + ```bash + docker compose up -d + docker compose ps + ``` + + -### Step 3: Go live + + Wait for all containers to start. This may take a minute for first-time setup. + - - 1. Commit and push your changes. - 2. Your docs will update and be live in moments! - +### Step 4: Access and Configure -## Next steps + + + Navigate to `http://localhost:8080` in your browser + + + + Click "Sign in with Google" and authorize the application + + + + Add your brokerage account number in the profile page + + + + Go to the Upload page and import your CSV transaction history + + -Now that you have your docs running, explore these key features: +## Next Steps + +Now that your dashboard is running, explore these features: - - Learn MDX syntax and start writing your documentation. + + Add your holdings and track real-time performance - - Make your docs match your brand perfectly. + + Import your trading history from your broker - - Include syntax-highlighted code blocks. + + Analyze monthly trading performance and P&L - - Auto-generate API docs from OpenAPI specs. + + Integrate with the REST API +## Common Tasks + +### View Logs + +```bash +# All services +docker compose logs -f + +# Specific service +docker compose logs -f trading_app +``` + +### Restart Services + +```bash +docker compose restart +``` + +### Update Application + +```bash +docker compose pull +docker compose up -d +``` + +### Backup Database + +```bash +docker compose exec postgres pg_dump -U trading_user mining_wood > backup.sql +``` + +## Troubleshooting + + + + Check the logs for errors: + ```bash + docker compose logs trading_app + ``` + + Common issues: + - Missing environment variables + - Database connection failure + - Port 8080 already in use + + + + - Verify OAuth credentials are correct in `.env` + - Check that your email is in `AUTHORIZED_USERS` + - Clear browser cookies and try again + + + + - Verify `FINNHUB_API_KEY` is set correctly + - Check API quota hasn't been exceeded + - Review application logs for API errors + + + - **Need help?** See our [full documentation](https://mintlify.com/docs) or join our [community](https://mintlify.com/community). + **Need help?** Check our [deployment guide](/guides/deployment/docker) or [setup guides](/guides/setup/cicd) for more detailed instructions. diff --git a/runner-config.yaml b/runner-config.yaml new file mode 100644 index 0000000..f949168 --- /dev/null +++ b/runner-config.yaml @@ -0,0 +1,15 @@ +log: + level: info + +runner: + capacity: 1 + timeout: 3h + +container: + # Use the gitea network so job containers can resolve the 'server' hostname + network: gitea_gitea + privileged: false + options: "" + workdir_parent: "" + valid_volumes: [] + docker_host: ""