feat: live position monitoring with charts + trading system production ready
Browse files- PositionChart component: area chart with BUY/SELL markers, entry price line,
stop-loss/take-profit reference lines, 10s price polling, 60s chart refresh
- Auto-trading page: open positions show live charts with P&L
- Closed trades: entry/exit markers on 30-day chart
- Prices API: added open price for OHLCV support
- Trading worker: fixed state persistence (broker positions load/save)
- Trading broker: fixed logging format bugs
- Restored data/, ai/, analysis/ modules from archive
- Synced HuggingFace space modules
- Cleaned up legacy Streamlit/macOS files
This view is limited to 50 files because it contains too many changes. See raw diff
- ._.env.local +0 -0
- ._.env.local.example +0 -0
- ._.env.vercel.template +0 -0
- ._.git +0 -0
- ._.next +0 -0
- ._.vercel +0 -0
- ._DEPLOYMENT_READY.md +0 -0
- ._ENV_SETUP.md +0 -0
- ._GITHUB_VERCEL_SETUP.md +0 -0
- ._HUGGINGFACE_NETLIFY_DEPLOYMENT.md +0 -0
- ._README.md +0 -0
- ._VERCEL_DEPLOYMENT.md +0 -0
- ._huggingface-space +0 -0
- ._netlify.toml +0 -0
- ._next-env.d.ts +0 -0
- ._next.config.js +0 -0
- ._node_modules +0 -0
- ._package-lock.json +0 -0
- ._package.json +0 -0
- ._postcss.config.js +0 -0
- ._src +0 -0
- ._tailwind.config.ts +0 -0
- ._tsconfig.json +0 -0
- ._upload_to_hf.py +0 -0
- ._vercel.json +0 -0
- .env.example +0 -15
- .env.local.example +0 -7
- .env.vercel.template +0 -87
- .github/workflows/ci.yml +46 -0
- .gitignore +20 -0
- .streamlit/config.toml +0 -25
- .vscode/settings.json +8 -1
- ACIMASIZ_EKSIKLIK_RAPORU_V2.md +613 -0
- DEPLOYMENT_READY.md +0 -120
- ENV_SETUP.md +0 -36
- GITHUB_DEPLOY_GUIDE.md +0 -117
- GITHUB_SETUP.md +0 -131
- GITHUB_VERCEL_SETUP.md +0 -138
- HIZLI_DEPLOY.md +0 -112
- HUGGINGFACE_NETLIFY_DEPLOYMENT.md +0 -85
- KOMPAKT_UYGULAMA_README.md +0 -118
- MIGRATION_COMPLETE.md +0 -298
- MIGRATION_PLAN.md +0 -1453
- NETLIFY_DEPLOYMENT.md +0 -280
- NETLIFY_README.md +0 -264
- PROJE_OZETI.md +0 -147
- QUICKSTART.md +0 -163
- README.md +6 -0
- STREAMLIT_DEPLOY_REHBERI.md +0 -184
- SUPABASE_SETUP.md +0 -268
._.env.local
DELETED
|
Binary file (4.1 kB)
|
|
|
._.env.local.example
DELETED
|
Binary file (4.1 kB)
|
|
|
._.env.vercel.template
DELETED
|
Binary file (4.1 kB)
|
|
|
._.git
DELETED
|
Binary file (4.1 kB)
|
|
|
._.next
DELETED
|
Binary file (4.1 kB)
|
|
|
._.vercel
DELETED
|
Binary file (4.1 kB)
|
|
|
._DEPLOYMENT_READY.md
DELETED
|
Binary file (4.1 kB)
|
|
|
._ENV_SETUP.md
DELETED
|
Binary file (4.1 kB)
|
|
|
._GITHUB_VERCEL_SETUP.md
DELETED
|
Binary file (4.1 kB)
|
|
|
._HUGGINGFACE_NETLIFY_DEPLOYMENT.md
DELETED
|
Binary file (4.1 kB)
|
|
|
._README.md
DELETED
|
Binary file (4.1 kB)
|
|
|
._VERCEL_DEPLOYMENT.md
DELETED
|
Binary file (4.1 kB)
|
|
|
._huggingface-space
DELETED
|
Binary file (4.1 kB)
|
|
|
._netlify.toml
DELETED
|
Binary file (4.1 kB)
|
|
|
._next-env.d.ts
DELETED
|
Binary file (4.1 kB)
|
|
|
._next.config.js
DELETED
|
Binary file (4.1 kB)
|
|
|
._node_modules
DELETED
|
Binary file (4.1 kB)
|
|
|
._package-lock.json
DELETED
|
Binary file (4.1 kB)
|
|
|
._package.json
DELETED
|
Binary file (4.1 kB)
|
|
|
._postcss.config.js
DELETED
|
Binary file (4.1 kB)
|
|
|
._src
DELETED
|
Binary file (4.1 kB)
|
|
|
._tailwind.config.ts
DELETED
|
Binary file (4.1 kB)
|
|
|
._tsconfig.json
DELETED
|
Binary file (4.1 kB)
|
|
|
._upload_to_hf.py
DELETED
|
Binary file (4.1 kB)
|
|
|
._vercel.json
DELETED
|
Binary file (4.1 kB)
|
|
|
.env.example
DELETED
|
@@ -1,15 +0,0 @@
|
|
| 1 |
-
# Netlify + Next.js + Python Backend için Environment Variables
|
| 2 |
-
|
| 3 |
-
# API Base URL (Production'da boş bırak, Netlify otomatik handle eder)
|
| 4 |
-
NEXT_PUBLIC_API_URL=
|
| 5 |
-
|
| 6 |
-
# Supabase (varsa - isteğe bağlı)
|
| 7 |
-
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
|
| 8 |
-
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
|
| 9 |
-
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
|
| 10 |
-
|
| 11 |
-
# Development için local API
|
| 12 |
-
# NEXT_PUBLIC_API_URL=http://localhost:8888
|
| 13 |
-
|
| 14 |
-
# Python Backend için (Netlify Functions otomatik alır)
|
| 15 |
-
PYTHON_VERSION=3.11
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.env.local.example
DELETED
|
@@ -1,7 +0,0 @@
|
|
| 1 |
-
# Supabase
|
| 2 |
-
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
|
| 3 |
-
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
|
| 4 |
-
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
|
| 5 |
-
|
| 6 |
-
# Optional
|
| 7 |
-
NODE_ENV=development
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.env.vercel.template
DELETED
|
@@ -1,87 +0,0 @@
|
|
| 1 |
-
# Environment Variables Template for Vercel
|
| 2 |
-
|
| 3 |
-
## 📝 Vercel Dashboard'a Girilecek Environment Variables
|
| 4 |
-
|
| 5 |
-
### Production & Preview & Development
|
| 6 |
-
|
| 7 |
-
**Variable Name:** `NEXT_PUBLIC_SUPABASE_URL`
|
| 8 |
-
**Value:** `https://mitlbxlqjibfcxswgmbq.supabase.co`
|
| 9 |
-
**Scope:** Production, Preview, Development
|
| 10 |
-
|
| 11 |
-
---
|
| 12 |
-
|
| 13 |
-
**Variable Name:** `NEXT_PUBLIC_SUPABASE_ANON_KEY`
|
| 14 |
-
**Value:** `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im1pdGxieGxxamliZmN4c3dnbWJxIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjczMjAzNjIsImV4cCI6MjA4Mjg5NjM2Mn0.La5BeCpz7s8R-LM0HKby5_925rCfVpB8qh9kC41n9Yc`
|
| 15 |
-
**Scope:** Production, Preview, Development
|
| 16 |
-
|
| 17 |
-
---
|
| 18 |
-
|
| 19 |
-
**Variable Name:** `SUPABASE_SERVICE_ROLE_KEY`
|
| 20 |
-
**Value:** `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im1pdGxieGxxamliZmN4c3dnbWJxIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc2NzMyMDM2MiwiZXhwIjoyMDgyODk2MzYyfQ.TrmQ3gtqD_Pb21zKyWZTdX9FtEDUM5St9-WGcWSEf8M`
|
| 21 |
-
**Scope:** Production, Preview, Development
|
| 22 |
-
|
| 23 |
-
## 🚀 Vercel Deployment Komutu
|
| 24 |
-
|
| 25 |
-
```bash
|
| 26 |
-
cd nextjs-app
|
| 27 |
-
|
| 28 |
-
# İlk deployment
|
| 29 |
-
vercel
|
| 30 |
-
|
| 31 |
-
# Production deployment
|
| 32 |
-
vercel --prod
|
| 33 |
-
```
|
| 34 |
-
|
| 35 |
-
## ✅ Deployment Checklist
|
| 36 |
-
|
| 37 |
-
- [ ] Vercel CLI yüklendi (`npm install -g vercel`)
|
| 38 |
-
- [ ] Vercel'e login yapıldı (`vercel login`)
|
| 39 |
-
- [ ] Environment variables Vercel dashboard'a eklendi
|
| 40 |
-
- [ ] İlk deployment başarılı (`vercel`)
|
| 41 |
-
- [ ] Production deployment başarılı (`vercel --prod`)
|
| 42 |
-
- [ ] Production URL test edildi
|
| 43 |
-
- [ ] API endpoints çalışıyor
|
| 44 |
-
- [ ] Database bağlantısı doğrulandı
|
| 45 |
-
|
| 46 |
-
## 📊 Production Build Stats
|
| 47 |
-
|
| 48 |
-
```
|
| 49 |
-
Route (app) Size First Load JS
|
| 50 |
-
┌ ○ / 2.7 kB 92.3 kB
|
| 51 |
-
├ ○ /_not-found 875 B 82.8 kB
|
| 52 |
-
├ ○ /api/movers 0 B 0 B
|
| 53 |
-
├ ○ /api/stocks 0 B 0 B
|
| 54 |
-
├ λ /api/stocks/[symbol] 0 B 0 B
|
| 55 |
-
├ λ /api/stocks/[symbol]/prices 0 B 0 B
|
| 56 |
-
├ ○ /api/test 0 B 0 B
|
| 57 |
-
└ λ /stocks/[symbol] 104 kB 193 kB
|
| 58 |
-
```
|
| 59 |
-
|
| 60 |
-
- **Homepage:** 92.3 kB First Load
|
| 61 |
-
- **Stock Detail:** 193 kB First Load
|
| 62 |
-
- **API Routes:** Server-side rendered (0 B client JS)
|
| 63 |
-
|
| 64 |
-
## 🌐 Post-Deployment URLs
|
| 65 |
-
|
| 66 |
-
- **Production:** `https://borsa-app.vercel.app` (veya custom domain)
|
| 67 |
-
- **Preview:** Her commit için otomatik preview URL
|
| 68 |
-
- **Local:** `http://localhost:3000`
|
| 69 |
-
|
| 70 |
-
## 🔧 Troubleshooting
|
| 71 |
-
|
| 72 |
-
**Build hatası alırsanız:**
|
| 73 |
-
```bash
|
| 74 |
-
# Cache temizle
|
| 75 |
-
rm -rf .next
|
| 76 |
-
npm run build
|
| 77 |
-
```
|
| 78 |
-
|
| 79 |
-
**Environment variables güncelledikten sonra:**
|
| 80 |
-
```bash
|
| 81 |
-
vercel --force
|
| 82 |
-
```
|
| 83 |
-
|
| 84 |
-
**Logs kontrol:**
|
| 85 |
-
```bash
|
| 86 |
-
vercel logs [deployment-url]
|
| 87 |
-
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.github/workflows/ci.yml
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: CI
|
| 2 |
+
|
| 3 |
+
on:
|
| 4 |
+
push:
|
| 5 |
+
branches: [main]
|
| 6 |
+
pull_request:
|
| 7 |
+
branches: [main]
|
| 8 |
+
|
| 9 |
+
defaults:
|
| 10 |
+
run:
|
| 11 |
+
working-directory: nextjs-app
|
| 12 |
+
|
| 13 |
+
jobs:
|
| 14 |
+
lint-typecheck-build:
|
| 15 |
+
runs-on: ubuntu-latest
|
| 16 |
+
|
| 17 |
+
strategy:
|
| 18 |
+
matrix:
|
| 19 |
+
node-version: [20]
|
| 20 |
+
|
| 21 |
+
steps:
|
| 22 |
+
- name: Checkout
|
| 23 |
+
uses: actions/checkout@v4
|
| 24 |
+
|
| 25 |
+
- name: Setup Node.js ${{ matrix.node-version }}
|
| 26 |
+
uses: actions/setup-node@v4
|
| 27 |
+
with:
|
| 28 |
+
node-version: ${{ matrix.node-version }}
|
| 29 |
+
cache: npm
|
| 30 |
+
cache-dependency-path: nextjs-app/package-lock.json
|
| 31 |
+
|
| 32 |
+
- name: Install dependencies
|
| 33 |
+
run: npm ci
|
| 34 |
+
|
| 35 |
+
- name: Lint
|
| 36 |
+
run: npm run lint
|
| 37 |
+
|
| 38 |
+
- name: Type check
|
| 39 |
+
run: npx tsc --noEmit
|
| 40 |
+
|
| 41 |
+
- name: Build
|
| 42 |
+
run: npm run build
|
| 43 |
+
env:
|
| 44 |
+
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets['NEXT_PUBLIC_SUPABASE_URL'] || 'https://placeholder.supabase.co' }}
|
| 45 |
+
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets['NEXT_PUBLIC_SUPABASE_ANON_KEY'] || 'placeholder-key' }}
|
| 46 |
+
NEXT_PUBLIC_API_URL: ${{ secrets['NEXT_PUBLIC_API_URL'] || 'https://placeholder.hf.space' }}
|
.gitignore
CHANGED
|
@@ -40,6 +40,8 @@ yarn-error.log*
|
|
| 40 |
# Local env files
|
| 41 |
.env*.local
|
| 42 |
.env
|
|
|
|
|
|
|
| 43 |
|
| 44 |
# Vercel
|
| 45 |
.vercel
|
|
@@ -59,3 +61,21 @@ node_modules/
|
|
| 59 |
|
| 60 |
# Local Netlify folder
|
| 61 |
.netlify
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
# Local env files
|
| 41 |
.env*.local
|
| 42 |
.env
|
| 43 |
+
.env.production
|
| 44 |
+
**/.env.production
|
| 45 |
|
| 46 |
# Vercel
|
| 47 |
.vercel
|
|
|
|
| 61 |
|
| 62 |
# Local Netlify folder
|
| 63 |
.netlify
|
| 64 |
+
|
| 65 |
+
# Trading state & secrets (NEVER commit)
|
| 66 |
+
paper_trading/
|
| 67 |
+
signals/
|
| 68 |
+
secrets.toml
|
| 69 |
+
.streamlit/secrets.toml
|
| 70 |
+
*.key
|
| 71 |
+
*.pem
|
| 72 |
+
|
| 73 |
+
# Archived Streamlit / legacy files (inactive)
|
| 74 |
+
_archive_streamlit/
|
| 75 |
+
|
| 76 |
+
# macOS resource forks
|
| 77 |
+
.DS_Store
|
| 78 |
+
._*
|
| 79 |
+
|
| 80 |
+
# Walk-forward backtest outputs
|
| 81 |
+
walk_forward_out/
|
.streamlit/config.toml
DELETED
|
@@ -1,25 +0,0 @@
|
|
| 1 |
-
[global]
|
| 2 |
-
# Uygulama ayarları
|
| 3 |
-
dataFrameSerialization = "legacy"
|
| 4 |
-
|
| 5 |
-
[server]
|
| 6 |
-
# Server ayarları
|
| 7 |
-
headless = true
|
| 8 |
-
runOnSave = true
|
| 9 |
-
port = 8501
|
| 10 |
-
enableCORS = false
|
| 11 |
-
enableXsrfProtection = false
|
| 12 |
-
|
| 13 |
-
[browser]
|
| 14 |
-
# Tarayıcı ayarları
|
| 15 |
-
gatherUsageStats = false
|
| 16 |
-
serverAddress = "0.0.0.0"
|
| 17 |
-
serverPort = 8501
|
| 18 |
-
|
| 19 |
-
[theme]
|
| 20 |
-
# Tema ayarları
|
| 21 |
-
primaryColor = "#FF6B6B"
|
| 22 |
-
backgroundColor = "#FFFFFF"
|
| 23 |
-
secondaryBackgroundColor = "#F0F2F6"
|
| 24 |
-
textColor = "#262730"
|
| 25 |
-
font = "sans serif"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.vscode/settings.json
CHANGED
|
@@ -4,8 +4,15 @@
|
|
| 4 |
"python.linting.flake8Enabled": false,
|
| 5 |
"files.exclude": {
|
| 6 |
"**/__pycache__": true,
|
| 7 |
-
"**/*.pyc": true
|
|
|
|
| 8 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
"css.lint.unknownAtRules": "ignore",
|
| 10 |
"css.validate": true
|
| 11 |
}
|
|
|
|
| 4 |
"python.linting.flake8Enabled": false,
|
| 5 |
"files.exclude": {
|
| 6 |
"**/__pycache__": true,
|
| 7 |
+
"**/*.pyc": true,
|
| 8 |
+
"_archive_streamlit": true
|
| 9 |
},
|
| 10 |
+
"search.exclude": {
|
| 11 |
+
"_archive_streamlit": true
|
| 12 |
+
},
|
| 13 |
+
"python.analysis.exclude": [
|
| 14 |
+
"_archive_streamlit/**"
|
| 15 |
+
],
|
| 16 |
"css.lint.unknownAtRules": "ignore",
|
| 17 |
"css.validate": true
|
| 18 |
}
|
ACIMASIZ_EKSIKLIK_RAPORU_V2.md
ADDED
|
@@ -0,0 +1,613 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ACMASIZ EKSİKLİK RAPORU — BORSA UYGULAMASI
|
| 2 |
+
|
| 3 |
+
**Tarih:** 2025-07-22
|
| 4 |
+
**Kapsam:** Tüm Next.js frontend, 23 API route, Supabase güvenlik, Python backend entegrasyonu
|
| 5 |
+
**Toplam Tespit:** 113 sorun (18 KRİTİK, 38 YÜKSEK, 39 ORTA, 18 DÜŞÜK)
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## YÖNETİCİ ÖZETİ
|
| 10 |
+
|
| 11 |
+
Bu uygulama **canlıya çıkarılamaz** durumda. Güvenlik açıkları, mimari tutarsızlıklar ve UX sorunları bir arada değerlendirildiğinde, uygulamanın kapsamlı bir revizyona ihtiyacı var.
|
| 12 |
+
|
| 13 |
+
**En kritik 5 sorun:**
|
| 14 |
+
1. **Hiçbir API route'unda (admin hariç) kimlik doğrulama yok** — herhangi biri trading, backtest, ML tahmin, tarama endpointlerini anonim olarak çağırabilir
|
| 15 |
+
2. **`/api/trading` POST'u sıfır auth ile kill switch'i açıp kapatabiliyor** — dosya sistemi manipülasyonu tamamen açık
|
| 16 |
+
3. **`/api/news/analyze` SSRF proxy olarak çalışıyor** — iç ağ IP'leri engellenmemiş, AWS metadata erişimi mümkün
|
| 17 |
+
4. **Hardcoded admin şifre (`admin123456`)** ve Supabase service role key `.env` dosyalarında
|
| 18 |
+
5. **Tema tutarsızlığı** — bazı sayfalar koyu, bazıları açık tema kullanıyor
|
| 19 |
+
|
| 20 |
+
### Ciddiyet Dağılımı
|
| 21 |
+
|
| 22 |
+
| Ciddiyet | Güvenlik | Frontend/UX | Backend API | Toplam |
|
| 23 |
+
|----------|----------|-------------|-------------|--------|
|
| 24 |
+
| **KRİTİK** | 6 | 7 | 5 | **18** |
|
| 25 |
+
| **YÜKSEK** | 6 | 22 | 10 | **38** |
|
| 26 |
+
| **ORTA** | 8 | 20 | 11 | **39** |
|
| 27 |
+
| **DÜŞÜK** | 8 | 5 | 5 | **18** |
|
| 28 |
+
| **Toplam** | **28** | **54** | **31** | **113** |
|
| 29 |
+
|
| 30 |
+
---
|
| 31 |
+
|
| 32 |
+
# BÖLÜM 1: GÜVENLİK SORUNLARI (28 bulgu)
|
| 33 |
+
|
| 34 |
+
## KRİTİK (6)
|
| 35 |
+
|
| 36 |
+
### S-C1. Hardcoded Supabase Service Role Key
|
| 37 |
+
**Dosya:** `.env.local`, `.env.production`
|
| 38 |
+
Service role key düz metin olarak dosyalarda duruyor. Bu key veritabanına **tam admin erişimi** sağlar — RLS'yi bypass eder, tüm tabloları okur/yazar/siler.
|
| 39 |
+
**Etki:** Repo'ya erişen herkes veritabanının tamamını ele geçirebilir.
|
| 40 |
+
|
| 41 |
+
### S-C2. Hardcoded Admin Şifre
|
| 42 |
+
**Dosya:** `nextjs-app/src/app/api/admin/create_admin.js`
|
| 43 |
+
Admin kullanıcı `admin@borsa.app` / `admin123456` olarak hardcode edilmiş. Bu dosya versiyon kontrolünde.
|
| 44 |
+
**Etki:** Herkes admin olarak giriş yapabilir.
|
| 45 |
+
|
| 46 |
+
### S-C3. `/api/trading` POST — Sıfır Authentication
|
| 47 |
+
**Dosya:** `nextjs-app/src/app/api/trading/route.ts`
|
| 48 |
+
`kill`, `unkill`, portföy okuma/yazma işlemleri hiçbir kimlik doğrulama olmadan çalışıyor. Anonim HTTP isteğiyle trading sistemi durdurulabilir.
|
| 49 |
+
**Etki:** Herhangi biri trading sistemini felç edebilir.
|
| 50 |
+
|
| 51 |
+
### S-C4. `/api/eligible` — Auth Yok
|
| 52 |
+
**Dosya:** `nextjs-app/src/app/api/eligible/route.ts`
|
| 53 |
+
Tarama sonuçları (hangi hisselerin alım sinyali verdiği) herkese açık.
|
| 54 |
+
**Etki:** Stratejik veriler anonim erişime açık.
|
| 55 |
+
|
| 56 |
+
### S-C5. Aşırı Permissive Database Grant'lar
|
| 57 |
+
**Dosya:** `supabase/migrations/20260102_initial_schema.sql`
|
| 58 |
+
```sql
|
| 59 |
+
GRANT ALL ON ALL TABLES IN SCHEMA public TO authenticated;
|
| 60 |
+
GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO authenticated;
|
| 61 |
+
```
|
| 62 |
+
Giriş yapmış **herhangi bir kullanıcı** tüm tabloları INSERT/UPDATE/DELETE yapabilir. RLS politikaları bu grant'ı yeterince kısıtlamıyor.
|
| 63 |
+
**Etki:** Normal kullanıcı başka kullanıcıların verilerini değiştirebilir.
|
| 64 |
+
|
| 65 |
+
### S-C6. Şifre Sıfırlama Recovery Link'i JSON'da Dönüyor
|
| 66 |
+
**Dosya:** `nextjs-app/src/app/api/admin/route.ts` (satır 221-232)
|
| 67 |
+
`reset_password` admin action'ı `generateLink()` çıktısını doğrudan JSON response'ta dönüyor. Bu link tam hesap erişimi sağlar ve proxy/CDN loglarında kalabilir.
|
| 68 |
+
|
| 69 |
+
## YÜKSEK (6)
|
| 70 |
+
|
| 71 |
+
### S-H1. `/api/debug-auth` — Oturum Bilgileri Sızdırıyor
|
| 72 |
+
**Dosya:** `nextjs-app/src/app/api/debug-auth/route.ts`
|
| 73 |
+
Production dışı ortamlarda (veya `DEBUG_AUTH=1` ile production'da) kullanıcı email, session token ve cookie isimlerini açığa çıkarıyor.
|
| 74 |
+
|
| 75 |
+
### S-H2. Path Traversal Riski
|
| 76 |
+
**Dosya:** `nextjs-app/src/app/api/trading/route.ts`
|
| 77 |
+
Dosya sistemi okuma/yazma işlemleri kullanıcı input'unu sanitize etmiyor. `../` ile üst dizinlere erişim potansiyeli var.
|
| 78 |
+
|
| 79 |
+
### S-H3. ProtectedRoute Sadece Client-Side
|
| 80 |
+
**Dosya:** `nextjs-app/src/components/ProtectedRoute.tsx`
|
| 81 |
+
Koruma sadece React render sırasında çalışıyor. Server-side HTML response'unda sayfa içeriği zaten mevcut — JavaScript devre dışıysa veya bot tarafından okunuyorsa koruma yok.
|
| 82 |
+
|
| 83 |
+
### S-H4. Middleware Her İstekte 2-3 DB Sorgusu Yapıyor
|
| 84 |
+
**Dosya:** `nextjs-app/src/middleware.ts`
|
| 85 |
+
Her route için `getUser()` + `user_profiles` sorgusu çalışıyor. Yüksek trafikte DB'yi gereksiz yere yoruyor.
|
| 86 |
+
|
| 87 |
+
### S-H5. Hiçbir Endpoint'te Rate Limiting Yok
|
| 88 |
+
23 endpoint tamamen açık. Özellikle tehlikeli:
|
| 89 |
+
- `/api/trading-signals` — her istekte N upstream fetch tetikliyor
|
| 90 |
+
- `/api/news/analyze` — SSRF proxy
|
| 91 |
+
- `/api/admin` — privilege escalation denemeleri
|
| 92 |
+
|
| 93 |
+
### S-H6. CSRF Koruması Yok
|
| 94 |
+
POST endpoint'leri (trading, backtest, sentiment, ml-predictions, scan-signals, trading-signals) CSRF token kontrolü yapmıyor.
|
| 95 |
+
|
| 96 |
+
## ORTA (8)
|
| 97 |
+
|
| 98 |
+
### S-M1. Admin Route'larında Input Validation Eksik
|
| 99 |
+
`userId` UUID formatı doğrulanmıyor. `ban_user`, `delete_user` gibi action'larda kötü niyetli string enjeksiyonu mümkün.
|
| 100 |
+
|
| 101 |
+
### S-M2. Zayıf Şifre Politikası
|
| 102 |
+
Minimum 6 karakter. Büyük harf, rakam, özel karakter zorunluluğu yok.
|
| 103 |
+
|
| 104 |
+
### S-M3. Environment Variable Non-null Assertion
|
| 105 |
+
```typescript
|
| 106 |
+
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
|
| 107 |
+
```
|
| 108 |
+
`!` ile null olmadığı varsayılıyor. Env değişkeni eksikse runtime crash.
|
| 109 |
+
|
| 110 |
+
### S-M4. Hata Mesajları Internal Bilgi Sızdırıyor
|
| 111 |
+
Upstream hataları olduğu gibi client'a iletiliyor. Stack trace, dosya yolu, iç servis URL'leri görünebilir.
|
| 112 |
+
|
| 113 |
+
### S-M5. Hardcoded Supabase Project ID
|
| 114 |
+
**Dosya:** `next.config.js`
|
| 115 |
+
`mitlbxlqjibfcxswgmbq.supabase.co` doğrudan config'de. Env variable olmalı.
|
| 116 |
+
|
| 117 |
+
### S-M6. CSP (Content Security Policy) Header'ı Yok
|
| 118 |
+
XSS saldırılarına karşı ek koruma katmanı eksik.
|
| 119 |
+
|
| 120 |
+
### S-M7. `user_profiles` Tablosuna INSERT Policy Eksik
|
| 121 |
+
Yeni kullanıcılar kendi profillerini oluşturamıyor (RLS INSERT policy tanımlı değil).
|
| 122 |
+
|
| 123 |
+
### S-M8. Duplicate RLS Policy'leri
|
| 124 |
+
Aynı tablo üzerinde birden fazla çelişen policy tanımı var.
|
| 125 |
+
|
| 126 |
+
## DÜŞÜK (8)
|
| 127 |
+
|
| 128 |
+
### S-L1. `.env.production` Git'te
|
| 129 |
+
Gizli bilgiler olmasa bile, production config'i versiyon kontrolünde olmamalı.
|
| 130 |
+
|
| 131 |
+
### S-L2. Kullanılmayan `pg` Dependency
|
| 132 |
+
`package.json`'da `pg` paketi var ama hiçbir yerde import edilmiyor.
|
| 133 |
+
|
| 134 |
+
### S-L3. Favoriler localStorage'da
|
| 135 |
+
Kullanıcı favori hisseleri tarayıcıda saklıyor. Cihaz değişince kaybolur.
|
| 136 |
+
|
| 137 |
+
### S-L4. Missing Suspense Boundary'ler
|
| 138 |
+
`useSearchParams()` kullanan sayfalar `<Suspense>` ile sarılmamış.
|
| 139 |
+
|
| 140 |
+
### S-L5. Singleton Supabase Client Pattern
|
| 141 |
+
Multiple module scope'da farklı Supabase client instance'ları oluşturuluyor.
|
| 142 |
+
|
| 143 |
+
### S-L6. Health Endpoint Bilgi Sızdırıyor
|
| 144 |
+
Backend URL, bağlantı durumu ve iç yapı detayları dönüyor.
|
| 145 |
+
|
| 146 |
+
### S-L7. Secure Cookie Flag'leri Eksik
|
| 147 |
+
Supabase cookie konfigürasyonunda `Secure`, `SameSite` flag'leri açıkça set edilmemiş.
|
| 148 |
+
|
| 149 |
+
### S-L8. Üçlü Admin Auth Pattern
|
| 150 |
+
Admin auth 3 farklı yerde 3 farklı şekilde kontrol ediliyor — tutarsız.
|
| 151 |
+
|
| 152 |
+
---
|
| 153 |
+
|
| 154 |
+
# BÖLÜM 2: FRONTEND & UX SORUNLARI (54 bulgu)
|
| 155 |
+
|
| 156 |
+
## KRİTİK (7)
|
| 157 |
+
|
| 158 |
+
### F-C1. Tema Bölünmesi — Koyu vs Açık
|
| 159 |
+
**Dosyalar:** `eligible/page.tsx`, `auto-trading/page.tsx` vs diğer tüm sayfalar
|
| 160 |
+
`eligible/` ve `auto-trading/` sayfaları koyu tema (`bg-gray-950`, `text-white`) kullanırken, geri kalan tüm uygulama açık tema (`bg-gray-50`, `text-gray-900`) kullanıyor. Kullanıcı sayfalar arası geçişte "farklı uygulama" hissi yaşıyor.
|
| 161 |
+
**Etki:** Profesyonel görünüm tamamen bozuluyor, UX güven duygusu azalıyor.
|
| 162 |
+
|
| 163 |
+
### F-C2. Ölü Dark Mode CSS
|
| 164 |
+
**Dosya:** `nextjs-app/src/app/globals.css`
|
| 165 |
+
`prefers-color-scheme: dark` media query'si altında CSS custom property'ler tanımlanmış ama **hiçbir component bunları tüketmiyor**. Tailwind sınıfları inline kullanılıyor. Dark mode altyapısı yarım kalmış.
|
| 166 |
+
|
| 167 |
+
### F-C3. PriceChart Ham Fetch — Error Handling Yok
|
| 168 |
+
**Dosya:** `nextjs-app/src/components/PriceChart.tsx`
|
| 169 |
+
`fetch()` çağrısında `response.ok` kontrolü yok. Hata durumunda kullanıcıya bilgi verilmiyor, grafik sessizce boş kalıyor.
|
| 170 |
+
|
| 171 |
+
### F-C4. `alert()` ile Hata Gösterimi
|
| 172 |
+
**Dosya:** `nextjs-app/src/app/ml-scan/page.tsx`
|
| 173 |
+
Hata durumunda `alert()` kullanılıyor. Bu tarayıcıyı bloklar, UI thread'ini durdurur ve modern UX standartlarına aykırı.
|
| 174 |
+
|
| 175 |
+
### F-C5. N+1 API Çağrısı — Portföy/Favoriler
|
| 176 |
+
**Dosyalar:** `portfolio/page.tsx`, `favorites/page.tsx`
|
| 177 |
+
Her hisse için ayrı API çağrısı yapılıyor. 20 hisseli portföyde 20 ayrı HTTP isteği. Batch endpoint kullanılmalı.
|
| 178 |
+
**Etki:** Sayfa yüklenmesi 5-10+ saniye sürebilir.
|
| 179 |
+
|
| 180 |
+
### F-C6. Error Boundary Yok
|
| 181 |
+
Proje genelinde hiçbir `error.tsx` dosyası yok. Herhangi bir component hata verdiğinde tüm sayfa beyaz ekrana dönüyor.
|
| 182 |
+
**Etki:** Kullanıcı ne olduğunu anlayamıyor, uygulamayı terk ediyor.
|
| 183 |
+
|
| 184 |
+
### F-C7. Finansal Veri localStorage'da
|
| 185 |
+
**Dosyalar:** `favorites.ts`, `analysis-history.ts`
|
| 186 |
+
Portföy pozisyonları, analiz geçmişi `localStorage`'da tutuluyor. Tarayıcı cache temizlendiğinde tüm veri kayboluyor.
|
| 187 |
+
**Etki:** Kullanıcı verilerinin kalıcılığı garanti değil.
|
| 188 |
+
|
| 189 |
+
## YÜKSEK (22)
|
| 190 |
+
|
| 191 |
+
### F-H1. Loading State Tutarsızlığı
|
| 192 |
+
Bazı sayfalar "Yükleniyor..." text, bazıları spinner, bazıları skeleton, bazıları hiçbir şey göstermiyor. Standart `LoadingSpinner` component'i var ama kullanılmıyor.
|
| 193 |
+
|
| 194 |
+
### F-H2. Responsive Design Eksiklikleri
|
| 195 |
+
Tablo-ağırlıklı sayfalar (`bist100/`, `scanner/`, `eligible/`) mobilde yatay scroll gerektiriyor. Mobil görünüm optimize edilmemiş.
|
| 196 |
+
|
| 197 |
+
### F-H3. Navigation Menüsü Mobilde Kırılıyor
|
| 198 |
+
**Dosya:** `nextjs-app/src/components/Navigation.tsx`
|
| 199 |
+
20+ menü linki mobilde taşıyor. Hamburger menü yok.
|
| 200 |
+
|
| 201 |
+
### F-H4. Grafik Boyutları Sabit Pixel
|
| 202 |
+
**Dosya:** `nextjs-app/src/components/AdvancedStockChart.tsx`
|
| 203 |
+
Recharts grafikleri sabit `height={400}` ile render ediliyor. Küçük ekranlarda orantısız yer kaplıyor.
|
| 204 |
+
|
| 205 |
+
### F-H5. Accessibility (a11y) Eksiklikleri
|
| 206 |
+
- Form input'larında `label` etiketleri eksik
|
| 207 |
+
- Renk kontrastı yetersiz (açık gri text'ler)
|
| 208 |
+
- `aria-label` kullanımı yok
|
| 209 |
+
- Keyboard navigation desteği eksik
|
| 210 |
+
- Screen reader uyumluluğu düşünülmemiş
|
| 211 |
+
|
| 212 |
+
### F-H6. Boş State Tasarımları Yok
|
| 213 |
+
Veri olmadığında tablolar boş kalıyor, kullanıcıya "Henüz veri yok" gibi bilgi verilmiyor.
|
| 214 |
+
|
| 215 |
+
### F-H7. SEO Meta Tag'leri Eksik
|
| 216 |
+
`metadata` export'ları çoğu sayfada bulunmuyor. `<title>`, `<meta description>`, Open Graph tag'leri eksik.
|
| 217 |
+
|
| 218 |
+
### F-H8. Form Validation Yetersiz
|
| 219 |
+
Login/register formlarında client-side validation minimal. Email format kontrolü, şifre gücü göstergesi, gerçek zamanlı feedback yok.
|
| 220 |
+
|
| 221 |
+
### F-H9. Stale Data Problemi
|
| 222 |
+
API çağrıları `useEffect` ile bir kere yapılıyor. Kullanıcı sayfada kalırken veri güncellenmiyor. SWR/React Query gibi cache-invalidation mekanizması yok.
|
| 223 |
+
|
| 224 |
+
### F-H10. Toast/Notification Sistemi Yok
|
| 225 |
+
Başarılı işlemler (favoriye ekleme, portföy güncelleme) sonrası kullanıcıya geri bildirim verilmiyor.
|
| 226 |
+
|
| 227 |
+
### F-H11. Infinite Scroll / Pagination Yok
|
| 228 |
+
BIST100 tablosu tüm veriyi bir seferde yüklüyor. Büyük veri setlerinde performans sorunu.
|
| 229 |
+
|
| 230 |
+
### F-H12. Component Prop Drilling
|
| 231 |
+
State yönetimi Context API ile yapılıyor ama birçok component'te props 3-4 seviye derinliğe aktarılıyor.
|
| 232 |
+
|
| 233 |
+
### F-H13. `key` Prop'ları Index Bazlı
|
| 234 |
+
Listelerde `key={index}` kullanılıyor. React reconciliation'ı bozar, gereksiz re-render'lara yol açar.
|
| 235 |
+
|
| 236 |
+
### F-H14. useEffect Dependency Array Sorunları
|
| 237 |
+
Birçok `useEffect`'te dependency array eksik veya yanlış. Sonsuz döngü riski var.
|
| 238 |
+
|
| 239 |
+
### F-H15. Console.log Production'da
|
| 240 |
+
Birçok component'te `console.log` ve `console.error` çağrıları bırakılmış. Production build'de bunlar kaldırılmalı.
|
| 241 |
+
|
| 242 |
+
### F-H16. Hardcoded Türkçe Stringler
|
| 243 |
+
Tüm UI metinleri doğrudan JSX içinde hardcode edilmiş. i18n altyapısı yok. İleride çok dilli destek eklemek çok zor olacak.
|
| 244 |
+
|
| 245 |
+
### F-H17. Image Optimization Yok
|
| 246 |
+
`<img>` tag'leri kullanılıyor, Next.js `<Image>` component'i kullanılmıyor. Lazy loading, responsive srcset, format optimization eksik.
|
| 247 |
+
|
| 248 |
+
### F-H18. Bundle Size Optimizasyonu Yok
|
| 249 |
+
`recharts` gibi büyük kütüphaneler tree-shaking yapılmadan import ediliyor. Tüm chart tipleri yükleniyor tek bir grafik için.
|
| 250 |
+
|
| 251 |
+
### F-H19. Duplicate Component Logic
|
| 252 |
+
`StockDetail`, `TechnicalIndicators`, `MLPredictions` arasında veri çekme ve formatlama kodu tekrar ediyor.
|
| 253 |
+
|
| 254 |
+
### F-H20. Modal/Dialog Erişilebilirliği
|
| 255 |
+
Modal'lar açıkken arka plan scroll'u engellenmemiyor. Focus trap yok. ESC tuşu ile kapatma tutarsız.
|
| 256 |
+
|
| 257 |
+
### F-H21. Type Safety Eksiklikleri
|
| 258 |
+
Birçok yerde `any` tipi kullanılıyor. API response tipleri `interface` olarak tanımlı ama runtime validation yok (zod/yup).
|
| 259 |
+
|
| 260 |
+
### F-H22. CSS Sınıf Çakışmaları
|
| 261 |
+
Tailwind utility sınıfları ile globals.css'teki custom CSS arasında öncelik çakışmaları var.
|
| 262 |
+
|
| 263 |
+
## ORTA (20)
|
| 264 |
+
|
| 265 |
+
### F-M1. `AuthContext` Token Refresh Yönetimi Belirsiz
|
| 266 |
+
Supabase `onAuthStateChange` dinliyor ama token yenileme hatası durumunda kullanıcıyı bilgilendirmiyor.
|
| 267 |
+
|
| 268 |
+
### F-M2. Link'ler `<a>` ile Yapılmış
|
| 269 |
+
Bazı yerlerde Next.js `<Link>` yerine `<a href>` kullanılmış. Client-side routing avantajı kaybediliyor.
|
| 270 |
+
|
| 271 |
+
### F-M3. Date Formatting Tutarsız
|
| 272 |
+
Tarih gösterimi yerlerde farklı: ISO string, locale string, custom format karışık kullanılıyor.
|
| 273 |
+
|
| 274 |
+
### F-M4. Number Formatting Standardı Yok
|
| 275 |
+
Fiyatlar bazen `toFixed(2)`, bazen `toLocaleString`, bazen ham sayı olarak gösteriliyor.
|
| 276 |
+
|
| 277 |
+
### F-M5. Retry Mekanizması Yok
|
| 278 |
+
API çağrıları başarısız olduğunda otomatik retry yok. Kullanıcı sayfayı yenilemek zorunda.
|
| 279 |
+
|
| 280 |
+
### F-M6. Placeholder Görseller Yok
|
| 281 |
+
Haber kartlarında görsel yoksa boş alan kalıyor. Fallback görsel veya ikon konmalı.
|
| 282 |
+
|
| 283 |
+
### F-M7. `useState` ile Karmaşık State
|
| 284 |
+
Birçok sayfada 8-10+ `useState` hook'u var. `useReducer` veya state machine kullanılmalı.
|
| 285 |
+
|
| 286 |
+
### F-M8. Tab Component'i Yarn Bağımlılığı
|
| 287 |
+
Tab geçişleri custom implementasyon. headless UI veya Radix gibi erişilebilir kütüphane kullanılmalı.
|
| 288 |
+
|
| 289 |
+
### F-M9. Grafik Tooltip'leri Yetersiz
|
| 290 |
+
Recharts tooltip'leri varsayılan stil kullanıyor. Fiyat, hacim, indikatör değerleri ayrıntılı gösterilmeli.
|
| 291 |
+
|
| 292 |
+
### F-M10. Print/Export Özelliği Yok
|
| 293 |
+
Kullanıcılar analiz sonuçlarını dışa aktaramaz veya yazdıramaz.
|
| 294 |
+
|
| 295 |
+
### F-M11. Undo/Redo Desteği Yok
|
| 296 |
+
Portföy düzenlemelerinde geri alma yok. Yanlışlıkla silme geri alınamaz.
|
| 297 |
+
|
| 298 |
+
### F-M12. Skeleton Loading Tutarsız
|
| 299 |
+
Bazı sayfalarda skeleton var, çoğunda yok.
|
| 300 |
+
|
| 301 |
+
### F-M13. API Error State'leri Ayrıştırılmamış
|
| 302 |
+
Network hatası, 404, 500, timeout hepsi aynı "Hata oluştu" mesajıyla gösteriliyor.
|
| 303 |
+
|
| 304 |
+
### F-M14. `useCallback`/`useMemo` Eksikliği
|
| 305 |
+
Performans açısından kritik yerlerde memoization yapılmamış.
|
| 306 |
+
|
| 307 |
+
### F-M15. Test Coverage %0
|
| 308 |
+
Hiçbir frontend test'i yok. Jest/Testing Library/Cypress/Playwright konfigürasyonu yok.
|
| 309 |
+
|
| 310 |
+
### F-M16. Storybook/Component Dokumentasyonu Yok
|
| 311 |
+
Component'lerin izole kullanımı ve dokumentasyonu yok.
|
| 312 |
+
|
| 313 |
+
### F-M17. SVG İkonlar Inline
|
| 314 |
+
İkon kullanımı inline SVG veya emoji ile yapılmış. İkon kütüphanesi (lucide, heroicons) kullanılmalı.
|
| 315 |
+
|
| 316 |
+
### F-M18. Layout Shift (CLS) Sorunları
|
| 317 |
+
Dinamik içerik yüklendiğinde sayfa layout'u kayıyor. Sabit yükseklik container'ları yok.
|
| 318 |
+
|
| 319 |
+
### F-M19. Focus Visible Stilleri Eksik
|
| 320 |
+
Keyboard kullanıcıları hangi elemente focus olduğunu göremez.
|
| 321 |
+
|
| 322 |
+
### F-M20. Conditional Rendering Karmaşıklığı
|
| 323 |
+
Birçok component'te 5+ ternary/&& zinciri var. Okunabilirlik çok düşük.
|
| 324 |
+
|
| 325 |
+
## DÜŞÜK (5)
|
| 326 |
+
|
| 327 |
+
### F-L1. README Güncel Değil
|
| 328 |
+
Kurulum adımları ve özellik listesi mevcut durumu yansıtmıyor.
|
| 329 |
+
|
| 330 |
+
### F-L2. Code Comment'ler Yetersiz
|
| 331 |
+
Karmaşık iş mantığı (indikatör hesaplamaları, formasyon tespiti) comment'siz.
|
| 332 |
+
|
| 333 |
+
### F-L3. Git Commit Mesajları
|
| 334 |
+
Tek satırlık, açıklayıcı olmayan commit mesajları.
|
| 335 |
+
|
| 336 |
+
### F-L4. Unused Import'lar
|
| 337 |
+
Birçok dosyada kullanılmayan import'lar var.
|
| 338 |
+
|
| 339 |
+
### F-L5. Console Warning'ler
|
| 340 |
+
Development modda React key, useEffect dependency uyarıları var.
|
| 341 |
+
|
| 342 |
+
---
|
| 343 |
+
|
| 344 |
+
# BÖLÜM 3: BACKEND API SORUNLARI (31 bulgu)
|
| 345 |
+
|
| 346 |
+
## Route Envanteri
|
| 347 |
+
|
| 348 |
+
| # | Route | Method | Auth | Timeout | Satır |
|
| 349 |
+
|---|-------|--------|------|---------|-------|
|
| 350 |
+
| 1 | `/api/stocks/[symbol]` | GET | ❌ | ❌ | 216 |
|
| 351 |
+
| 2 | `/api/stocks/[symbol]/prices` | GET | ❌ | ❌ | ~100 |
|
| 352 |
+
| 3 | `/api/stocks/[symbol]/analysis` | GET | ❌ | ❌ | **990** |
|
| 353 |
+
| 4 | `/api/trading-signals` | POST | ❌ | ❌ | 516 |
|
| 354 |
+
| 5 | `/api/market-overview` | GET | ❌ | 30s | 42 |
|
| 355 |
+
| 6 | `/api/movers` | GET | ❌ | 30s | 44 |
|
| 356 |
+
| 7 | `/api/news` | GET | ❌ | ❌ | 56 |
|
| 357 |
+
| 8 | `/api/news/analyze` | POST | ❌ | 20s | 227 |
|
| 358 |
+
| 9 | `/api/sentiment` | POST | ❌ | ❌ | 53 |
|
| 359 |
+
| 10 | `/api/ml-predictions` | POST | ❌ | ❌ | 41 |
|
| 360 |
+
| 11 | `/api/stock-data` | GET | ❌ | ❌ | 44 |
|
| 361 |
+
| 12 | `/api/technical-analysis` | GET | ❌ | ❌ | 55 |
|
| 362 |
+
| 13 | `/api/scan-signals` | POST | ❌ | ❌ | 103 |
|
| 363 |
+
| 14 | `/api/popular-stocks` | GET | ❌ | ❌ | 30 |
|
| 364 |
+
| 15 | `/api/universe` | GET | ❌ | ❌ | 129 |
|
| 365 |
+
| 16 | `/api/backtest` | POST | ❌ | ❌ | 44 |
|
| 366 |
+
| 17 | `/api/kap` | GET | ❌ | 12s | 99 |
|
| 367 |
+
| 18 | `/api/debug-auth` | GET | Kısmi | ❌ | 30 |
|
| 368 |
+
| 19 | `/api/admin` | GET/POST | ✅ | ❌ | 259 |
|
| 369 |
+
| 20 | `/api/trading` | GET/POST | ❌ | ❌ | 256 |
|
| 370 |
+
| 21 | `/api/eligible` | GET | ❌ | ❌ | 100 |
|
| 371 |
+
| 22 | `/api/stocks` | GET | ❌ | 30s | 55 |
|
| 372 |
+
| 23 | `/api/health` | GET | ❌ | 6s | 55 |
|
| 373 |
+
|
| 374 |
+
**23 route'tan sadece 1'i (admin) gerçek authentication kullanıyor.**
|
| 375 |
+
|
| 376 |
+
## KRİTİK (5)
|
| 377 |
+
|
| 378 |
+
### B-C1. `/api/trading` POST — Sıfır Auth ile Kill Switch
|
| 379 |
+
**Dosya:** `nextjs-app/src/app/api/trading/route.ts` (satır 200-256)
|
| 380 |
+
`kill` ve `unkill` action'ları dosya sisteminde dosya oluşturma/silme yapıyor. Hiçbir kimlik doğrulama yok. Anonim HTTP isteğiyle trading sistemi durdurulabilir.
|
| 381 |
+
|
| 382 |
+
### B-C2. `/api/news/analyze` Açık SSRF Proxy
|
| 383 |
+
**Dosya:** `nextjs-app/src/app/api/news/analyze/route.ts` (satır 119-152)
|
| 384 |
+
Rastgele URL kabul ediyor, sadece `http:`/`https:` protokolü kontrol ediliyor. İç ağ IP'leri (`127.0.0.1`, `10.x.x.x`, `169.254.169.254` AWS metadata, `192.168.x.x`, `::1`) **engellenmemiş**.
|
| 385 |
+
**Etki:** Saldırgan iç servisleri tarayabilir, cloud metadata'ya erişebilir.
|
| 386 |
+
|
| 387 |
+
### B-C3. Admin Password Recovery Link Response'ta
|
| 388 |
+
**Dosya:** `nextjs-app/src/app/api/admin/route.ts` (satır 221-232)
|
| 389 |
+
`reset_password` action'ı `generateLink()` çıktısını JSON response'ta geri dönüyor. Recovery link tam hesap erişimi sağlar.
|
| 390 |
+
|
| 391 |
+
### B-C4. 21/23 Route'ta Sıfır Authentication
|
| 392 |
+
Admin dışında tüm route'lar — veri değiştiren POST endpoint'leri dahil (`trading`, `backtest`, `ml-predictions`, `sentiment`, `scan-signals`, `trading-signals`) — tamamen anonim.
|
| 393 |
+
|
| 394 |
+
### B-C5. `/api/debug-auth` Session Bilgilerini Sızdırıyor
|
| 395 |
+
**Dosya:** `nextjs-app/src/app/api/debug-auth/route.ts` (satır 14-29)
|
| 396 |
+
Non-production ortamda (veya `DEBUG_AUTH=1` ile) Supabase session, kullanıcı email ve cookie isimlerini expose ediyor.
|
| 397 |
+
|
| 398 |
+
## YÜKSEK (10)
|
| 399 |
+
|
| 400 |
+
### B-H1. 12 Route'ta Upstream Timeout Yok
|
| 401 |
+
`stocks/[symbol]`, `prices`, `analysis`, `trading-signals`, `sentiment`, `ml-predictions`, `stock-data`, `technical-analysis`, `scan-signals`, `popular-stocks`, `backtest`, `universe` — hiçbirinde `AbortController` veya timeout yok. Upstream hangirse, Next.js process'i **sonsuza kadar bekliyor**.
|
| 402 |
+
|
| 403 |
+
### B-H2. 4 Route'ta `API_BASE` Null Check Yok
|
| 404 |
+
`market-overview`, `movers`, `popular-stocks`, `stocks` — `API_BASE` boş string olduğunda `fetch("/api/...")` çağrılıyor → Node.js hata verir veya kendi kendine sonsuz döngü yapar.
|
| 405 |
+
|
| 406 |
+
### B-H3. Hatalar HTTP 200 ile Maskeleniyor
|
| 407 |
+
6 route başarısız response'u 200 OK ile dönüyor:
|
| 408 |
+
- `market-overview` → `{ note: "failed" }` 200
|
| 409 |
+
- `movers` → `{ gainers: [], losers: [] }` 200
|
| 410 |
+
- `popular-stocks` → `{ stocks: [] }` 200
|
| 411 |
+
- `stocks` → `[]` 200
|
| 412 |
+
- `technical-analysis` → error payload 200
|
| 413 |
+
**Etki:** Monitoring/alerting "backend down" durumunu tespit edemez.
|
| 414 |
+
|
| 415 |
+
### B-H4. 6 Route Blind Proxy — Body Validation Yok
|
| 416 |
+
`ml-predictions`, `backtest`, `scan-signals` tümü `JSON.stringify(body ?? {})` ile **sıfır validation** yaparak upstream'e iletiyor. Saldırgan rastgele payload enjekte edebilir.
|
| 417 |
+
|
| 418 |
+
### B-H5. Admin Route'ta `userId` Format Validation Yok
|
| 419 |
+
`ban_user`, `unban_user`, `make_admin`, `remove_admin`, `delete_user` — `userId` UUID formatı doğrulanmıyor.
|
| 420 |
+
|
| 421 |
+
### B-H6. `/api/sentiment` Text Uzunluk Limiti Yok
|
| 422 |
+
Boş olmadığı kontrol ediliyor ama boyut sınırı yok. Multi-MB text gönderilebilir → upstream'de DoS.
|
| 423 |
+
|
| 424 |
+
### B-H7. Senkron Dosya Sistemi İşlemleri
|
| 425 |
+
**Dosya:** `nextjs-app/src/app/api/trading/route.ts` (satır 17-41)
|
| 426 |
+
`readFileSync`, `writeFileSync`, `existsSync`, `unlinkSync` — event loop'u blokluyor. Eşzamanlı istekleri durdurur.
|
| 427 |
+
|
| 428 |
+
### B-H8. Hiçbir Route'ta Rate Limiting Yok
|
| 429 |
+
23 endpoint tamamen açık. Brute force, DoS, istismar kolaylığı.
|
| 430 |
+
|
| 431 |
+
### B-H9. Tutarsız Response Format
|
| 432 |
+
4+ farklı hata şekli kullanılıyor:
|
| 433 |
+
```
|
| 434 |
+
{ ok: false, error: "..." }
|
| 435 |
+
{ success: false, error: "..." }
|
| 436 |
+
{ note: "..." }
|
| 437 |
+
{ error: "..." }
|
| 438 |
+
[]
|
| 439 |
+
```
|
| 440 |
+
Client hata tespitini güvenilir yapamaz. Standart error envelope yok.
|
| 441 |
+
|
| 442 |
+
### B-H10. Sıralı Upstream Çağrıları — Sequential Waterfall
|
| 443 |
+
**Dosya:** `nextjs-app/src/app/api/stocks/[symbol]/route.ts` (satır 48-195)
|
| 444 |
+
`stock-data` → `technical-analysis` → `scan-signals` → `ml-predictions` **sırayla** çağrılıyor. `Promise.all` ile paralelize edilmemiş. Tek istek 30+ saniye sürebilir.
|
| 445 |
+
|
| 446 |
+
## ORTA (11)
|
| 447 |
+
|
| 448 |
+
### B-M1. Masif Kod Tekrarı
|
| 449 |
+
- `toNumber()` — 5 dosyada duplicate
|
| 450 |
+
- `pick()` — 5 dosyada duplicate
|
| 451 |
+
- `getSymbolFromParams()` — 3 dosyada duplicate
|
| 452 |
+
- SMA/EMA/RSI/MACD/Bollinger/Stochastic/ATR hesaplamaları — `analysis/route.ts` ile `trading-signals/route.ts` arasında tamamen duplicate (ince farklarla)
|
| 453 |
+
- `API_BASE` null-check boilerplate — ~10 route'ta tekrar
|
| 454 |
+
|
| 455 |
+
### B-M2. `http.ts` `fetchJson()` Fonksiyonu Kullanılmıyor
|
| 456 |
+
Timeout, retry, content-type handling ve structured `ApiError` sağlıyor ama **hiçbir route kullanmıyor**. Her route kendi ad-hoc `fetch()` çağrısını yapıyor.
|
| 457 |
+
|
| 458 |
+
### B-M3. `runtime-config.ts` Helper'ları Kullanılmıyor
|
| 459 |
+
`requireApiBase()` ve `apiUrl()` hazır helper fonksiyonları var ama tüm route'lar manual URL concat yapıyor.
|
| 460 |
+
|
| 461 |
+
### B-M4. 990 Satırlık "God Route"
|
| 462 |
+
**Dosya:** `nextjs-app/src/app/api/stocks/[symbol]/analysis/route.ts`
|
| 463 |
+
Tüm teknik indikatör matematiği, 15+ mum formasyonu, chart formation detection, support/resistance, Fibonacci, trend analizi — tek dosyada. `src/lib/` modüllerine çıkarılmalı.
|
| 464 |
+
|
| 465 |
+
### B-M5. Serverless'ta Etkisiz In-Memory Cache
|
| 466 |
+
**Dosya:** `nextjs-app/src/app/api/universe/route.ts` (satır 15-17)
|
| 467 |
+
Module-level `csvCache` değişkeni. Vercel/serverless deployment'ta her instance kendi belleğine sahip. Cache hit oranı ~%0.
|
| 468 |
+
|
| 469 |
+
### B-M6. Hardcoded User-Agent String'leri
|
| 470 |
+
`kap/route.ts` ve `news/analyze` Chrome user-agent spoof ediyor. Bot detection eklenirse sessizce kırılır.
|
| 471 |
+
|
| 472 |
+
### B-M7. Duplicate `API_BASE` Derivation
|
| 473 |
+
`health/route.ts` kendi `getBackendBaseUrl()` fonksiyonunu tanımlıyor, `runtime-config.ts` ile tutarsız. İki truth kaynağı.
|
| 474 |
+
|
| 475 |
+
### B-M8. Veri Yoğun Route'larda Cache Yok
|
| 476 |
+
`stock-data`, `technical-analysis`, `trading-signals`, `scan-signals`, `backtest` — hepsi `cache: 'no-store'`. Aynı sembol/periyod için tekrarlanan istekler her seferinde tam upstream roundtrip yapıyor. Piyasa verisi dakika-içi değişmez.
|
| 477 |
+
|
| 478 |
+
### B-M9. `NEXT_PUBLIC_` ile Backend URL Client Bundle'a Gömülüyor
|
| 479 |
+
`runtime-config.ts` — `NEXT_PUBLIC_API_URL` prefix'i bu değeri client-side JavaScript'e embed ediyor. Backend URL iç ağda olmalıysa güvenlik riski.
|
| 480 |
+
|
| 481 |
+
### B-M10. `force-dynamic` Tutarsız Uygulanıyor
|
| 482 |
+
Sadece 3 route'ta set edilmiş. Diğer dinamik route'lar (market-overview, movers vb.) Next.js inference'ına bırakılmış.
|
| 483 |
+
|
| 484 |
+
### B-M11. Upstream Hata Detayları Verbatim Proxy'leniyor
|
| 485 |
+
`stock-data`, `ml-predictions` gibi route'lar upstream'den gelen `detail` alanını olduğu gibi client'a iletiyor. Stack trace, dosya yolu sızıntısı riski.
|
| 486 |
+
|
| 487 |
+
## DÜŞÜK (5)
|
| 488 |
+
|
| 489 |
+
### B-L1. Karışık Türkçe/İngilizce Hata Mesajları
|
| 490 |
+
`"API URL yapılandırılmamış"` vs `"symbol is required"` vs `"Unknown error"`. i18n stratejisi yok.
|
| 491 |
+
|
| 492 |
+
### B-L2. HTTP Method Rejection Eksik
|
| 493 |
+
Route'lar sadece handle ettikleri method'ları export ediyor. Tanımsız method'lar için yararlı hata body'si veya `Allow` header'ı yok.
|
| 494 |
+
|
| 495 |
+
### B-L3. MACD Implementasyonunda Dead Code
|
| 496 |
+
**Dosya:** `nextjs-app/src/app/api/trading-signals/route.ts` (satır 73-82)
|
| 497 |
+
Boş `if (i >= 26) { // recalculate properly }` bloğu, ardından tam yeniden türetme. Yarım kalmış refactoring.
|
| 498 |
+
|
| 499 |
+
### B-L4. `toNumber()` Null Handling Tutarsızlığı
|
| 500 |
+
NaN için `null` dönen fonksiyonun sonucunu bazı yerler `?? 0` ile, bazıları olduğu gibi kullanıyor.
|
| 501 |
+
|
| 502 |
+
### B-L5. Request Logging/Tracing Yok
|
| 503 |
+
23 route'tan hiçbiri gelen istekleri, response sürelerini veya hata bağlamlarını loglamamış. Sadece `trading/route.ts`'de tek bir `console.error` var.
|
| 504 |
+
|
| 505 |
+
---
|
| 506 |
+
|
| 507 |
+
# BÖLÜM 4: MİMARİ & ALTYAPI SORUNLARI
|
| 508 |
+
|
| 509 |
+
## 4.1 Proje Yapısı Karmaşası
|
| 510 |
+
- **İki paralel uygulama:** Root'ta Python Streamlit uygulaması + `nextjs-app/` altında Next.js uygulaması. Hangi birincil platform belirsiz.
|
| 511 |
+
- **Duplicate dosyalar:** `next.config.js`, `package.json`, `postcss.config.js`, `tailwind.config.ts`, `tsconfig.json`, `vercel.json` hem root'ta hem `nextjs-app/`'da var.
|
| 512 |
+
- **6+ deployment rehberi:** `NETLIFY_DEPLOYMENT.md`, `VERCEL_DEPLOYMENT.md`, `HUGGINGFACE_NETLIFY_DEPLOYMENT.md`, `GITHUB_DEPLOY_GUIDE.md`, `HIZLI_DEPLOY.md`, `STREAMLIT_DEPLOY_REHBERI.md` — hangisi güncel?
|
| 513 |
+
- **Kullanılmayan klasörler:** `netlify/`, `src/` (root), `profiles/`, `migration/` — aktif mi değil mi belirsiz.
|
| 514 |
+
|
| 515 |
+
## 4.2 Dependency Yönetimi
|
| 516 |
+
- Root'ta `requirements.txt` (Python) + `package.json` (Node) birlikte duruyor
|
| 517 |
+
- `requirements_deploy.txt`, `requirements-netlify.txt`, `requirements.txt` — 3 ayrı Python requirements dosyası
|
| 518 |
+
- `packages.txt` — ayrı bir sistem paketi listesi
|
| 519 |
+
- Test framework yok (Jest, Vitest, Pytest konfigürasyonu yok)
|
| 520 |
+
- Linting konfigürasyonu minimal (ESLint yok veya varsayılan)
|
| 521 |
+
|
| 522 |
+
## 4.3 Veritabanı Sorunları
|
| 523 |
+
- İki migration dosyası var ama migration tool (Prisma, Drizzle, knex) yok
|
| 524 |
+
- SQL migration'lar elle yazılmış, rollback stratejisi yok
|
| 525 |
+
- Veritabanı şeması documentation'ı yok
|
| 526 |
+
- Seed data mekanizması yok
|
| 527 |
+
|
| 528 |
+
## 4.4 CI/CD Pipeline Yok
|
| 529 |
+
- GitHub Actions workflow yok
|
| 530 |
+
- Otomatik test çalıştırma yok
|
| 531 |
+
- Lint/type-check otomasyonu yok
|
| 532 |
+
- Otomatik deployment pipeline yok
|
| 533 |
+
- Environment-based configuration management yok
|
| 534 |
+
|
| 535 |
+
## 4.5 Monitoring & Observability
|
| 536 |
+
- Error tracking (Sentry, LogRocket) yok
|
| 537 |
+
- Performance monitoring (Vercel Analytics, Web Vitals) yok
|
| 538 |
+
- API response time tracking yok
|
| 539 |
+
- Uptime monitoring yok
|
| 540 |
+
- Structured logging yok
|
| 541 |
+
|
| 542 |
+
---
|
| 543 |
+
|
| 544 |
+
# BÖLÜM 5: ÖNCELİKLENDİRİLMİŞ DÜZELTME YOLI HARİTASI
|
| 545 |
+
|
| 546 |
+
## Faz 1: Acil Güvenlik Düzeltmeleri (1-2 hafta)
|
| 547 |
+
|
| 548 |
+
| # | İş | Etki | Efor |
|
| 549 |
+
|---|------|------|------|
|
| 550 |
+
| 1 | Tüm API route'larına auth middleware ekle | KRİTİK | 2 gün |
|
| 551 |
+
| 2 | `/api/news/analyze`'a SSRF koruması (private IP blocklist) | KRİTİK | 2 saat |
|
| 552 |
+
| 3 | Hardcoded credential'ları kaldır, secret management kur | KRİTİK | 4 saat |
|
| 553 |
+
| 4 | Admin recovery link'i response'tan çıkar | KRİTİK | 30 dk |
|
| 554 |
+
| 5 | DB grant'ları kısıtla, RLS policy'leri düzelt | KRİTİK | 1 gün |
|
| 555 |
+
| 6 | Rate limiting ekle (tüm endpoint'ler) | YÜKSEK | 1 gün |
|
| 556 |
+
| 7 | CSRF koruması ekle | YÜKSEK | 4 saat |
|
| 557 |
+
| 8 | `/api/debug-auth` production'da tamamen kaldır | YÜKSEK | 30 dk |
|
| 558 |
+
|
| 559 |
+
## Faz 2: Stabilite & Güvenilirlik (2-3 hafta)
|
| 560 |
+
|
| 561 |
+
| # | İş | Etki | Efor |
|
| 562 |
+
|---|------|------|------|
|
| 563 |
+
| 9 | Tüm route'lara AbortController timeout ekle | YÜKSEK | 1 gün |
|
| 564 |
+
| 10 | `fetchJson()` ve `apiUrl()` helper'larını kullan | ORTA | 1 gün |
|
| 565 |
+
| 11 | Standart error response envelope oluştur | YÜKSEK | 1 gün |
|
| 566 |
+
| 12 | Error boundary (`error.tsx`) ekle | KRİTİK | 2 saat |
|
| 567 |
+
| 13 | Sequential API çağrılarını paralelize et | YÜKSEK | 4 saat |
|
| 568 |
+
| 14 | Input validation middleware (zod) ekle | YÜKSEK | 2 gün |
|
| 569 |
+
| 15 | API_BASE null check'leri düzelt | YÜKSEK | 2 saat |
|
| 570 |
+
| 16 | HTTP 200 hata maskelemeyi düzelt | YÜKSEK | 4 saat |
|
| 571 |
+
|
| 572 |
+
## Faz 3: UX & Performans (3-4 hafta)
|
| 573 |
+
|
| 574 |
+
| # | İş | Etki | Efor |
|
| 575 |
+
|---|------|------|------|
|
| 576 |
+
| 17 | Tema birleştir (tek tutarlı tema) | KRİTİK | 2 gün |
|
| 577 |
+
| 18 | Error/loading/empty state standartları | YÜKSEK | 2 gün |
|
| 578 |
+
| 19 | N+1 API çağrılarını batch'le | KRİTİK | 1 gün |
|
| 579 |
+
| 20 | React Query/SWR entegrasyonu | YÜKSEK | 3 gün |
|
| 580 |
+
| 21 | Responsive design düzelt | YÜKSEK | 3 gün |
|
| 581 |
+
| 22 | Accessibility audit ve düzeltme | YÜKSEK | 3 gün |
|
| 582 |
+
| 23 | Toast/notification sistemi ekle | YÜKSEK | 1 gün |
|
| 583 |
+
|
| 584 |
+
## Faz 4: Mimari İyileştirmeler (4-6 hafta)
|
| 585 |
+
|
| 586 |
+
| # | İş | Etki | Efor |
|
| 587 |
+
|---|------|------|------|
|
| 588 |
+
| 24 | God route'u modüllere ayır | ORTA | 2 gün |
|
| 589 |
+
| 25 | Duplicate kodu refactor et | ORTA | 2 gün |
|
| 590 |
+
| 26 | CI/CD pipeline kur (GitHub Actions) | YÜKSEK | 2 gün |
|
| 591 |
+
| 27 | Test altyapısı kur + kritik testler yaz | YÜKSEK | 1 hafta |
|
| 592 |
+
| 28 | Monitoring/observability ekle (Sentry, logging) | YÜKSEK | 2 gün |
|
| 593 |
+
| 29 | Proje yapısını temizle (kullanılmayan dosyaları sil) | ORTA | 1 gün |
|
| 594 |
+
| 30 | API caching stratejisi uygula | ORTA | 2 gün |
|
| 595 |
+
|
| 596 |
+
---
|
| 597 |
+
|
| 598 |
+
# SONUÇ
|
| 599 |
+
|
| 600 |
+
Bu uygulama **öğrenci projesi seviyesinde**. Borsa verisi gösteren temel fonksiyonlar çalışıyor ama:
|
| 601 |
+
|
| 602 |
+
- **Güvenlik:** Canlıya çıkarılacak seviyede değil. 21/23 endpoint auth'suz, SSRF açığı var, hardcoded credential'lar mevcut.
|
| 603 |
+
- **Kod Kalitesi:** Massive duplication, god files, kullanılmayan utility fonksiyonlar, tutarsız error handling.
|
| 604 |
+
- **UX:** Tema bölünmesi, responsive sorunları, accessibility eksiklikleri, error boundary yokluğu.
|
| 605 |
+
- **Altyapı:** CI/CD yok, test yok, monitoring yok, logging yok.
|
| 606 |
+
- **Mimari:** İki paralel uygulama (Python + Next.js), 6+ deployment rehberi, hangi platform birincil belirsiz.
|
| 607 |
+
|
| 608 |
+
**Tavsiye:** Faz 1'i (güvenlik) hemen yapın. Uygulama bu haliyle internet'e açılmamalı.
|
| 609 |
+
|
| 610 |
+
---
|
| 611 |
+
|
| 612 |
+
*Bu rapor 3 ayrı derin denetim (güvenlik, frontend/UX, backend API) sonuçlarının birleştirilmesiyle oluşturulmuştur.*
|
| 613 |
+
*Son güncelleme: 2025-07-22*
|
DEPLOYMENT_READY.md
DELETED
|
@@ -1,120 +0,0 @@
|
|
| 1 |
-
# 🚀 Vercel Deployment - Manuel Adımlar
|
| 2 |
-
|
| 3 |
-
## Deployment başarıyla hazır!
|
| 4 |
-
|
| 5 |
-
### ✅ Tamamlanan Adımlar:
|
| 6 |
-
1. ✅ vercel.json konfigürasyonu oluşturuldu
|
| 7 |
-
2. ✅ Production build başarılı (Build size: 92.3 kB homepage)
|
| 8 |
-
3. ✅ Environment variables template hazırlandı
|
| 9 |
-
4. ✅ Deployment dokümanları oluşturuldu
|
| 10 |
-
|
| 11 |
-
### 📋 Deployment için Yapılacaklar:
|
| 12 |
-
|
| 13 |
-
#### 1. Vercel CLI Kurulumu
|
| 14 |
-
```bash
|
| 15 |
-
npm install -g vercel
|
| 16 |
-
```
|
| 17 |
-
|
| 18 |
-
#### 2. Vercel'e Login
|
| 19 |
-
```bash
|
| 20 |
-
cd /Volumes/LaCie/borsa_uygulamasi/nextjs-app
|
| 21 |
-
vercel login
|
| 22 |
-
```
|
| 23 |
-
- Tarayıcıda açılacak sayfadan GitHub/GitLab/Bitbucket ile giriş yapın
|
| 24 |
-
|
| 25 |
-
#### 3. Environment Variables Ekle
|
| 26 |
-
|
| 27 |
-
**Vercel Dashboard'da:**
|
| 28 |
-
1. https://vercel.com adresine gidin
|
| 29 |
-
2. Project Settings → Environment Variables
|
| 30 |
-
3. Aşağıdaki 3 değişkeni ekleyin:
|
| 31 |
-
|
| 32 |
-
```
|
| 33 |
-
NEXT_PUBLIC_SUPABASE_URL=https://mitlbxlqjibfcxswgmbq.supabase.co
|
| 34 |
-
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
|
| 35 |
-
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
|
| 36 |
-
```
|
| 37 |
-
|
| 38 |
-
#### 4. İlk Deployment
|
| 39 |
-
```bash
|
| 40 |
-
vercel
|
| 41 |
-
```
|
| 42 |
-
- Projeye isim verin (örn: borsa-app)
|
| 43 |
-
- Settings'leri onaylayın
|
| 44 |
-
|
| 45 |
-
#### 5. Production Deployment
|
| 46 |
-
```bash
|
| 47 |
-
vercel --prod
|
| 48 |
-
```
|
| 49 |
-
|
| 50 |
-
#### 6. Test Et
|
| 51 |
-
Deployment tamamlandığında size verilen URL'i test edin:
|
| 52 |
-
```bash
|
| 53 |
-
curl https://your-app.vercel.app/api/stocks?limit=3
|
| 54 |
-
```
|
| 55 |
-
|
| 56 |
-
---
|
| 57 |
-
|
| 58 |
-
## 📊 Build İstatistikleri
|
| 59 |
-
|
| 60 |
-
**Başarılı Production Build:**
|
| 61 |
-
- Homepage: 2.7 kB (92.3 kB First Load)
|
| 62 |
-
- Stock Detail: 104 kB (193 kB First Load)
|
| 63 |
-
- API Routes: Server-side (0 B client JS)
|
| 64 |
-
- Total Routes: 7
|
| 65 |
-
- Static Pages: 4
|
| 66 |
-
- Dynamic Pages: 3
|
| 67 |
-
|
| 68 |
-
**Performans Optimizasyonları:**
|
| 69 |
-
- ✅ API caching (60s)
|
| 70 |
-
- ✅ Stale-while-revalidate (300s)
|
| 71 |
-
- ✅ Edge network (Frankfurt region)
|
| 72 |
-
- ✅ Automatic HTTPS
|
| 73 |
-
- ✅ DDoS protection
|
| 74 |
-
|
| 75 |
-
---
|
| 76 |
-
|
| 77 |
-
## 🔍 Alternatif: GitHub Integration
|
| 78 |
-
|
| 79 |
-
### Otomatik Deployment için:
|
| 80 |
-
|
| 81 |
-
1. GitHub'da yeni repo oluştur
|
| 82 |
-
2. Kodu push et:
|
| 83 |
-
```bash
|
| 84 |
-
cd /Volumes/LaCie/borsa_uygulamasi/nextjs-app
|
| 85 |
-
git init
|
| 86 |
-
git add .
|
| 87 |
-
git commit -m "Initial commit: BIST stock analysis app"
|
| 88 |
-
git remote add origin https://github.com/YOUR_USERNAME/borsa-app.git
|
| 89 |
-
git push -u origin main
|
| 90 |
-
```
|
| 91 |
-
|
| 92 |
-
3. Vercel dashboard'da:
|
| 93 |
-
- "Import Project" → GitHub seç
|
| 94 |
-
- Repository'yi seç
|
| 95 |
-
- Environment variables ekle
|
| 96 |
-
- Deploy
|
| 97 |
-
|
| 98 |
-
Artık her `main` branch'e push otomatik production deploy olacak!
|
| 99 |
-
|
| 100 |
-
---
|
| 101 |
-
|
| 102 |
-
## 📈 Sonraki Adımlar
|
| 103 |
-
|
| 104 |
-
Deployment tamamlandıktan sonra:
|
| 105 |
-
- [ ] Custom domain ekle (opsiyonel)
|
| 106 |
-
- [ ] Analytics kontrol et
|
| 107 |
-
- [ ] Performance monitoring
|
| 108 |
-
- [ ] Error tracking setup
|
| 109 |
-
- [ ] Supabase Edge Functions (cron jobs)
|
| 110 |
-
- [ ] HuggingFace ML model integration
|
| 111 |
-
|
| 112 |
-
---
|
| 113 |
-
|
| 114 |
-
## 💡 Notlar
|
| 115 |
-
|
| 116 |
-
- **Local geliştirme:** `npm run dev` (localhost:3000)
|
| 117 |
-
- **Production build test:** `npm run build && npm start`
|
| 118 |
-
- **Environment:** Vercel otomatik .env.local'i production'a taşımaz
|
| 119 |
-
- **Database:** Supabase zaten production'da, ek kurulum gerekmez
|
| 120 |
-
- **Region:** Frankfurt (fra1) - Türkiye'ye en yakın
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ENV_SETUP.md
DELETED
|
@@ -1,36 +0,0 @@
|
|
| 1 |
-
# BIST Stock Analysis Platform - Environment Variables
|
| 2 |
-
|
| 3 |
-
## Required Variables
|
| 4 |
-
|
| 5 |
-
### Supabase Configuration
|
| 6 |
-
```bash
|
| 7 |
-
NEXT_PUBLIC_SUPABASE_URL=https://mitlbxlqjibfcxswgmbq.supabase.co
|
| 8 |
-
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
|
| 9 |
-
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
|
| 10 |
-
```
|
| 11 |
-
|
| 12 |
-
## Optional Variables
|
| 13 |
-
|
| 14 |
-
### HuggingFace API (for Advanced Sentiment Analysis)
|
| 15 |
-
```bash
|
| 16 |
-
HUGGINGFACE_API_KEY=hf_your_key_here
|
| 17 |
-
```
|
| 18 |
-
|
| 19 |
-
**How to get HuggingFace API key:**
|
| 20 |
-
1. Sign up at https://huggingface.co
|
| 21 |
-
2. Go to Settings → Access Tokens
|
| 22 |
-
3. Create a new token with "Read" permissions
|
| 23 |
-
4. Add to Vercel: Settings → Environment Variables
|
| 24 |
-
|
| 25 |
-
**Note:** If not provided, the app will use rule-based sentiment analysis as fallback.
|
| 26 |
-
|
| 27 |
-
## Vercel Deployment
|
| 28 |
-
|
| 29 |
-
Add these environment variables in Vercel Dashboard:
|
| 30 |
-
- Settings → Environment Variables
|
| 31 |
-
- Add each variable for: Production, Preview, Development
|
| 32 |
-
|
| 33 |
-
### Current Setup Status
|
| 34 |
-
✅ Supabase configured
|
| 35 |
-
✅ ML Predictions working (no API key needed)
|
| 36 |
-
⏳ HuggingFace (optional - fallback enabled)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GITHUB_DEPLOY_GUIDE.md
DELETED
|
@@ -1,117 +0,0 @@
|
|
| 1 |
-
# 🎯 GitHub Repo Kurulumu ve Netlify Deployment
|
| 2 |
-
|
| 3 |
-
## Durum
|
| 4 |
-
|
| 5 |
-
- ✅ GitHub CLI kurulu
|
| 6 |
-
- ✅ `Oner65` hesabına login
|
| 7 |
-
- ❌ `veteroner/borsanew` repo'su yok
|
| 8 |
-
|
| 9 |
-
---
|
| 10 |
-
|
| 11 |
-
## Çözüm: Repo Oluştur ve Deploy Et
|
| 12 |
-
|
| 13 |
-
### Seçenek 1: Mevcut Hesapla (Oner65) - ÖNERİLEN
|
| 14 |
-
|
| 15 |
-
```bash
|
| 16 |
-
cd /Volumes/LaCie/borsa_uygulamasi
|
| 17 |
-
|
| 18 |
-
# 1. Yeni repo oluştur (Oner65 hesabında)
|
| 19 |
-
gh repo create borsanew --public --source=. --remote=origin --push
|
| 20 |
-
|
| 21 |
-
# 2. Netlify'a bağla
|
| 22 |
-
# https://app.netlify.com/ → New site from Git → GitHub → Oner65/borsanew
|
| 23 |
-
```
|
| 24 |
-
|
| 25 |
-
### Seçenek 2: veteroner Hesabına Geç
|
| 26 |
-
|
| 27 |
-
```bash
|
| 28 |
-
# 1. veteroner hesabına login ol
|
| 29 |
-
gh auth login
|
| 30 |
-
|
| 31 |
-
# 2. Repo oluştur
|
| 32 |
-
gh repo create veteroner/borsanew --public
|
| 33 |
-
|
| 34 |
-
# 3. Push et
|
| 35 |
-
git push -u origin main
|
| 36 |
-
```
|
| 37 |
-
|
| 38 |
-
### Seçenek 3: Manuel Repo Oluşturma
|
| 39 |
-
|
| 40 |
-
1. **Browser'da GitHub aç:** https://github.com/new
|
| 41 |
-
2. **Repo adı:** `borsanew`
|
| 42 |
-
3. **Public** seç
|
| 43 |
-
4. **"Create repository"**
|
| 44 |
-
5. **Terminal'de:**
|
| 45 |
-
```bash
|
| 46 |
-
cd /Volumes/LaCie/borsa_uygulamasi
|
| 47 |
-
git push -u origin main
|
| 48 |
-
```
|
| 49 |
-
|
| 50 |
-
---
|
| 51 |
-
|
| 52 |
-
## Hızlı Başlat (ÖNERİLEN)
|
| 53 |
-
|
| 54 |
-
```bash
|
| 55 |
-
# Tek komut ile repo oluştur ve push et
|
| 56 |
-
cd /Volumes/LaCie/borsa_uygulamasi
|
| 57 |
-
gh repo create borsanew --public --source=. --remote=origin --push
|
| 58 |
-
```
|
| 59 |
-
|
| 60 |
-
Bu komut:
|
| 61 |
-
- ✅ GitHub'da repo oluşturur
|
| 62 |
-
- ✅ Origin'i ayarlar
|
| 63 |
-
- ✅ Otomatik push eder
|
| 64 |
-
- ✅ Repo URL'i verir
|
| 65 |
-
|
| 66 |
-
---
|
| 67 |
-
|
| 68 |
-
## Netlify Deployment (Repo Oluştuktan Sonra)
|
| 69 |
-
|
| 70 |
-
1. **Netlify Dashboard:** https://app.netlify.com/
|
| 71 |
-
2. **"Add new site" → "Import an existing project"**
|
| 72 |
-
3. **GitHub'ı seç**
|
| 73 |
-
4. **Repo'yu seç** (`borsanew`)
|
| 74 |
-
5. **Build settings:**
|
| 75 |
-
```
|
| 76 |
-
Base directory: nextjs-app
|
| 77 |
-
Build command: npm run build
|
| 78 |
-
Publish directory: nextjs-app/.next
|
| 79 |
-
Functions directory: netlify/functions
|
| 80 |
-
```
|
| 81 |
-
6. **Environment Variables:**
|
| 82 |
-
```
|
| 83 |
-
PYTHON_VERSION=3.11
|
| 84 |
-
NEXT_PUBLIC_API_URL=(boş)
|
| 85 |
-
```
|
| 86 |
-
7. **"Deploy site"** 🚀
|
| 87 |
-
|
| 88 |
-
---
|
| 89 |
-
|
| 90 |
-
## Test
|
| 91 |
-
|
| 92 |
-
Deployment sonrası:
|
| 93 |
-
|
| 94 |
-
```bash
|
| 95 |
-
# Production URL al
|
| 96 |
-
netlify open
|
| 97 |
-
|
| 98 |
-
# API test et
|
| 99 |
-
curl https://your-site.netlify.app/api/market-overview
|
| 100 |
-
```
|
| 101 |
-
|
| 102 |
-
---
|
| 103 |
-
|
| 104 |
-
## Sorun Giderme
|
| 105 |
-
|
| 106 |
-
### "Repository not found"
|
| 107 |
-
→ Repo henüz oluşturulmamış. Yukarıdaki komutları çalıştır.
|
| 108 |
-
|
| 109 |
-
### "Permission denied"
|
| 110 |
-
→ `gh auth login` ile doğru hesaba giriş yap.
|
| 111 |
-
|
| 112 |
-
### SSH key sorunları
|
| 113 |
-
→ GitHub CLI kullan (SSH'ye gerek yok).
|
| 114 |
-
|
| 115 |
-
---
|
| 116 |
-
|
| 117 |
-
**Hemen başla:** `gh repo create borsanew --public --source=. --remote=origin --push` 🚀
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GITHUB_SETUP.md
DELETED
|
@@ -1,131 +0,0 @@
|
|
| 1 |
-
# 🔐 GitHub SSH Key Setup
|
| 2 |
-
|
| 3 |
-
## SSH Key'iniz
|
| 4 |
-
|
| 5 |
-
```
|
| 6 |
-
DlH63Ypt9s9XgSkAOfscPDfFTGrKVDpT30rqaJwg7b8
|
| 7 |
-
```
|
| 8 |
-
|
| 9 |
-
⚠️ **Bu bir SSH key değil, deploy key veya token gibi görünüyor.**
|
| 10 |
-
|
| 11 |
-
---
|
| 12 |
-
|
| 13 |
-
## GitHub Repo Bağlantısı
|
| 14 |
-
|
| 15 |
-
### Seçenek 1: HTTPS (Personal Access Token)
|
| 16 |
-
|
| 17 |
-
1. **GitHub Personal Access Token oluştur:**
|
| 18 |
-
- https://github.com/settings/tokens
|
| 19 |
-
- "Generate new token (classic)"
|
| 20 |
-
- Scope: `repo` (tüm repo izinleri)
|
| 21 |
-
- Token'ı kopyala
|
| 22 |
-
|
| 23 |
-
2. **Git credential'ları ayarla:**
|
| 24 |
-
```bash
|
| 25 |
-
cd /Volumes/LaCie/borsa_uygulamasi
|
| 26 |
-
|
| 27 |
-
# HTTPS URL kullan
|
| 28 |
-
git remote set-url origin https://github.com/veteroner/borsanew.git
|
| 29 |
-
|
| 30 |
-
# Push et (token soracak)
|
| 31 |
-
git push -u origin main
|
| 32 |
-
|
| 33 |
-
# Username: veteroner
|
| 34 |
-
# Password: <github-personal-access-token>
|
| 35 |
-
```
|
| 36 |
-
|
| 37 |
-
### Seçenek 2: SSH Key (Önerilen)
|
| 38 |
-
|
| 39 |
-
1. **SSH key oluştur:**
|
| 40 |
-
```bash
|
| 41 |
-
ssh-keygen -t ed25519 -C "your_email@example.com"
|
| 42 |
-
# Enter yaparak default konuma kaydet
|
| 43 |
-
|
| 44 |
-
# Public key'i göster
|
| 45 |
-
cat ~/.ssh/id_ed25519.pub
|
| 46 |
-
```
|
| 47 |
-
|
| 48 |
-
2. **GitHub'a ekle:**
|
| 49 |
-
- https://github.com/settings/ssh/new
|
| 50 |
-
- Public key'i yapıştır
|
| 51 |
-
- "Add SSH key"
|
| 52 |
-
|
| 53 |
-
3. **SSH URL kullan:**
|
| 54 |
-
```bash
|
| 55 |
-
git remote set-url origin git@github.com:veteroner/borsanew.git
|
| 56 |
-
git push -u origin main
|
| 57 |
-
```
|
| 58 |
-
|
| 59 |
-
### Seçenek 3: GitHub CLI (En Kolay)
|
| 60 |
-
|
| 61 |
-
```bash
|
| 62 |
-
# GitHub CLI kur
|
| 63 |
-
brew install gh
|
| 64 |
-
|
| 65 |
-
# GitHub'a giriş yap
|
| 66 |
-
gh auth login
|
| 67 |
-
|
| 68 |
-
# Push et
|
| 69 |
-
git push -u origin main
|
| 70 |
-
```
|
| 71 |
-
|
| 72 |
-
---
|
| 73 |
-
|
| 74 |
-
## Netlify Deployment
|
| 75 |
-
|
| 76 |
-
GitHub'a push sonrası:
|
| 77 |
-
|
| 78 |
-
1. **Netlify Dashboard aç:** https://app.netlify.com/
|
| 79 |
-
2. **"Add new site" → "Import an existing project"**
|
| 80 |
-
3. **GitHub'ı seç ve "veteroner/borsanew" repo'sunu seç**
|
| 81 |
-
4. **Build settings:**
|
| 82 |
-
- Base directory: `nextjs-app`
|
| 83 |
-
- Build command: `npm run build`
|
| 84 |
-
- Publish directory: `nextjs-app/.next`
|
| 85 |
-
- Functions directory: `netlify/functions`
|
| 86 |
-
|
| 87 |
-
5. **Environment variables ekle:**
|
| 88 |
-
- `PYTHON_VERSION`: `3.11`
|
| 89 |
-
- `NEXT_PUBLIC_API_URL`: (boş bırak)
|
| 90 |
-
|
| 91 |
-
6. **"Deploy site"** 🚀
|
| 92 |
-
|
| 93 |
-
---
|
| 94 |
-
|
| 95 |
-
## Verdiğiniz Key Hakkında
|
| 96 |
-
|
| 97 |
-
```
|
| 98 |
-
DlH63Ypt9s9XgSkAOfscPDfFTGrKVDpT30rqaJwg7b8
|
| 99 |
-
```
|
| 100 |
-
|
| 101 |
-
Bu bir:
|
| 102 |
-
- ❌ SSH private key değil (çok kısa)
|
| 103 |
-
- ❓ Netlify deploy token olabilir
|
| 104 |
-
- ❓ GitHub Personal Access Token olabilir
|
| 105 |
-
- ❓ API key olabilir
|
| 106 |
-
|
| 107 |
-
**Kullanım:** Eğer bu bir GitHub token ise, HTTPS push yaparken password olarak kullanabilirsiniz.
|
| 108 |
-
|
| 109 |
-
---
|
| 110 |
-
|
| 111 |
-
## Hızlı Çözüm
|
| 112 |
-
|
| 113 |
-
```bash
|
| 114 |
-
# GitHub CLI ile (en kolay)
|
| 115 |
-
brew install gh
|
| 116 |
-
gh auth login
|
| 117 |
-
# Browser'da GitHub'a giriş yap
|
| 118 |
-
git push -u origin main
|
| 119 |
-
```
|
| 120 |
-
|
| 121 |
-
**VEYA**
|
| 122 |
-
|
| 123 |
-
```bash
|
| 124 |
-
# Personal Access Token oluştur:
|
| 125 |
-
# https://github.com/settings/tokens
|
| 126 |
-
|
| 127 |
-
# Push et
|
| 128 |
-
git push -u origin main
|
| 129 |
-
# Username: veteroner
|
| 130 |
-
# Password: <your-github-token>
|
| 131 |
-
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GITHUB_VERCEL_SETUP.md
DELETED
|
@@ -1,138 +0,0 @@
|
|
| 1 |
-
# 🚀 GitHub ve Vercel Deployment Rehberi
|
| 2 |
-
|
| 3 |
-
## ⚠️ Önemli: Repository Henüz Oluşturulmamış
|
| 4 |
-
|
| 5 |
-
GitHub repository'si `https://github.com/veteroner/borsanew` henüz mevcut değil.
|
| 6 |
-
|
| 7 |
-
## 📋 Adım Adım GitHub + Vercel Deployment
|
| 8 |
-
|
| 9 |
-
### 1️⃣ GitHub Repository Oluştur
|
| 10 |
-
|
| 11 |
-
**Seçenek A: GitHub Web Interface**
|
| 12 |
-
1. https://github.com/new adresine git
|
| 13 |
-
2. Repository name: `borsanew`
|
| 14 |
-
3. Description: `BIST Stock Analysis App - Next.js 14 + Supabase + PostgreSQL`
|
| 15 |
-
4. Public/Private seç
|
| 16 |
-
5. ❌ **README, .gitignore, license EKLEME** (zaten var)
|
| 17 |
-
6. "Create repository" tıkla
|
| 18 |
-
|
| 19 |
-
**Seçenek B: GitHub CLI**
|
| 20 |
-
```bash
|
| 21 |
-
gh repo create veteroner/borsanew --public --source=. --remote=origin
|
| 22 |
-
```
|
| 23 |
-
|
| 24 |
-
### 2️⃣ Kodu GitHub'a Push Et
|
| 25 |
-
|
| 26 |
-
Repository oluşturduktan sonra:
|
| 27 |
-
|
| 28 |
-
```bash
|
| 29 |
-
cd /Volumes/LaCie/borsa_uygulamasi/nextjs-app
|
| 30 |
-
|
| 31 |
-
# Remote ekle (eğer Seçenek A kullandıysanız)
|
| 32 |
-
git remote add origin https://github.com/veteroner/borsanew.git
|
| 33 |
-
|
| 34 |
-
# Push et
|
| 35 |
-
git branch -M main
|
| 36 |
-
git push -u origin main
|
| 37 |
-
```
|
| 38 |
-
|
| 39 |
-
### 3️⃣ Vercel'e Bağla
|
| 40 |
-
|
| 41 |
-
#### **Vercel Dashboard'dan:**
|
| 42 |
-
|
| 43 |
-
1. https://vercel.com adresine git
|
| 44 |
-
2. "Add New..." → "Project"
|
| 45 |
-
3. "Import Git Repository"
|
| 46 |
-
4. GitHub'ı seç ve authorize et
|
| 47 |
-
5. `veteroner/borsanew` repository'sini seç
|
| 48 |
-
6. Framework Preset: **Next.js** (otomatik seçilecek)
|
| 49 |
-
7. Root Directory: `./` (default)
|
| 50 |
-
8. Environment Variables ekle:
|
| 51 |
-
|
| 52 |
-
```env
|
| 53 |
-
NEXT_PUBLIC_SUPABASE_URL=https://mitlbxlqjibfcxswgmbq.supabase.co
|
| 54 |
-
|
| 55 |
-
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
|
| 56 |
-
|
| 57 |
-
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
|
| 58 |
-
```
|
| 59 |
-
|
| 60 |
-
9. "Deploy" tıkla
|
| 61 |
-
|
| 62 |
-
### 4️⃣ Deployment Bekle
|
| 63 |
-
|
| 64 |
-
- İlk build ~2-3 dakika sürer
|
| 65 |
-
- Build logs'u canlı izleyebilirsiniz
|
| 66 |
-
- ✅ Success → Production URL alırsınız
|
| 67 |
-
|
| 68 |
-
### 5️⃣ Test Et
|
| 69 |
-
|
| 70 |
-
Deployment tamamlandığında:
|
| 71 |
-
|
| 72 |
-
```bash
|
| 73 |
-
# Production API'yi test et
|
| 74 |
-
curl https://borsanew.vercel.app/api/stocks?limit=3
|
| 75 |
-
|
| 76 |
-
# Tarayıcıda aç
|
| 77 |
-
open https://borsanew.vercel.app
|
| 78 |
-
```
|
| 79 |
-
|
| 80 |
-
---
|
| 81 |
-
|
| 82 |
-
## 🔄 Continuous Deployment
|
| 83 |
-
|
| 84 |
-
Artık her `git push` otomatik deployment tetikler:
|
| 85 |
-
|
| 86 |
-
```bash
|
| 87 |
-
# Kod değişikliği yap
|
| 88 |
-
git add .
|
| 89 |
-
git commit -m "Update: feature description"
|
| 90 |
-
git push
|
| 91 |
-
|
| 92 |
-
# Vercel otomatik deploy edecek!
|
| 93 |
-
```
|
| 94 |
-
|
| 95 |
-
---
|
| 96 |
-
|
| 97 |
-
## ✅ Mevcut Durum
|
| 98 |
-
|
| 99 |
-
- ✅ Git repository initialized
|
| 100 |
-
- ✅ Initial commit created (84 files)
|
| 101 |
-
- ✅ .gitignore configured
|
| 102 |
-
- ⏳ **GitHub repository oluşturulmalı**
|
| 103 |
-
- ⏳ **Code push edilmeli**
|
| 104 |
-
- ⏳ **Vercel integration yapılmalı**
|
| 105 |
-
|
| 106 |
-
---
|
| 107 |
-
|
| 108 |
-
## 🆘 Sorun Giderme
|
| 109 |
-
|
| 110 |
-
### "Repository not found" hatası
|
| 111 |
-
- GitHub'da repository'yi oluşturmayı unutmuş olabilirsiniz
|
| 112 |
-
- URL'i kontrol edin: `https://github.com/veteroner/borsanew`
|
| 113 |
-
- Private repo ise access token gerekebilir
|
| 114 |
-
|
| 115 |
-
### Push authentication hatası
|
| 116 |
-
```bash
|
| 117 |
-
# SSH kullan (önerilen)
|
| 118 |
-
git remote set-url origin git@github.com:veteroner/borsanew.git
|
| 119 |
-
git push -u origin main
|
| 120 |
-
|
| 121 |
-
# VEYA Personal Access Token kullan
|
| 122 |
-
git remote set-url origin https://YOUR_TOKEN@github.com/veteroner/borsanew.git
|
| 123 |
-
git push -u origin main
|
| 124 |
-
```
|
| 125 |
-
|
| 126 |
-
### Vercel build hatası
|
| 127 |
-
- Environment variables'ları kontrol et
|
| 128 |
-
- Build logs'u incele
|
| 129 |
-
- Local'de `npm run build` test et
|
| 130 |
-
|
| 131 |
-
---
|
| 132 |
-
|
| 133 |
-
## 📞 Yardım
|
| 134 |
-
|
| 135 |
-
Herhangi bir adımda takılırsanız:
|
| 136 |
-
1. GitHub repository'nin gerçekten oluşturulduğunu doğrulayın
|
| 137 |
-
2. Git credentials'larınızı kontrol edin
|
| 138 |
-
3. Vercel dashboard'da "Import" butonunu kullanın
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HIZLI_DEPLOY.md
DELETED
|
@@ -1,112 +0,0 @@
|
|
| 1 |
-
# ⚡ Hızlı Deploy Rehberi
|
| 2 |
-
|
| 3 |
-
Bu rehber, kompakt borsa uygulamanızı 5 dakikada Streamlit Community Cloud'a deploy etmenizi sağlayacak.
|
| 4 |
-
|
| 5 |
-
## 🚀 Hızlı Adımlar
|
| 6 |
-
|
| 7 |
-
### 1️⃣ GitHub Repository Oluştur (2 dakika)
|
| 8 |
-
|
| 9 |
-
```bash
|
| 10 |
-
# Terminal'de proje klasörünüzde çalıştırın:
|
| 11 |
-
|
| 12 |
-
# Git repository başlat
|
| 13 |
-
git init
|
| 14 |
-
|
| 15 |
-
# Tüm dosyaları ekle
|
| 16 |
-
git add .
|
| 17 |
-
|
| 18 |
-
# İlk commit
|
| 19 |
-
git commit -m "Kompakt Borsa Uygulaması - İlk Commit"
|
| 20 |
-
```
|
| 21 |
-
|
| 22 |
-
**GitHub'da:**
|
| 23 |
-
1. https://github.com adresine gidin
|
| 24 |
-
2. "New repository" tıklayın
|
| 25 |
-
3. Repository adı: `kompakt-borsa-app`
|
| 26 |
-
4. **Public** seçin (önemli!)
|
| 27 |
-
5. "Create repository" tıklayın
|
| 28 |
-
|
| 29 |
-
**Terminal'de devam:**
|
| 30 |
-
```bash
|
| 31 |
-
# GitHub repository'yi bağla (YOUR_USERNAME'i değiştirin)
|
| 32 |
-
git remote add origin https://github.com/YOUR_USERNAME/kompakt-borsa-app.git
|
| 33 |
-
|
| 34 |
-
# Ana branch'ı main yap
|
| 35 |
-
git branch -M main
|
| 36 |
-
|
| 37 |
-
# GitHub'a yükle
|
| 38 |
-
git push -u origin main
|
| 39 |
-
```
|
| 40 |
-
|
| 41 |
-
### 2️⃣ Streamlit Cloud'a Deploy (2 dakika)
|
| 42 |
-
|
| 43 |
-
1. https://share.streamlit.io adresine gidin
|
| 44 |
-
2. GitHub hesabınızla giriş yapın
|
| 45 |
-
3. "New app" butonuna tıklayın
|
| 46 |
-
4. **Repository:** `YOUR_USERNAME/kompakt-borsa-app`
|
| 47 |
-
5. **Branch:** `main`
|
| 48 |
-
6. **Main file path:** `compact_borsa_app.py`
|
| 49 |
-
7. **App URL:** İsteğe bağlı
|
| 50 |
-
8. "Deploy!" butonuna tıklayın
|
| 51 |
-
|
| 52 |
-
### 3️⃣ Tamamlandı! (1 dakika)
|
| 53 |
-
|
| 54 |
-
✅ Uygulamanız `https://YOUR_APP_NAME.streamlit.app` adresinde yayında!
|
| 55 |
-
|
| 56 |
-
---
|
| 57 |
-
|
| 58 |
-
## 🔧 Olası Sorunlar ve Çözümler
|
| 59 |
-
|
| 60 |
-
### ❌ Sorun 1: "ModuleNotFoundError"
|
| 61 |
-
**Çözüm:** requirements.txt dosyasının proje ana klasöründe olduğundan emin olun.
|
| 62 |
-
|
| 63 |
-
### ❌ Sorun 2: "FileNotFoundError: data/stock_analysis.db"
|
| 64 |
-
**Çözüm:** Normal! Cloud'da veritabanı otomatik oluşturulur.
|
| 65 |
-
|
| 66 |
-
### ❌ Sorun 3: "Memory limit exceeded"
|
| 67 |
-
**Çözüm:** Uygulamada cache kullanın:
|
| 68 |
-
```python
|
| 69 |
-
@st.cache_data(ttl=300)
|
| 70 |
-
def get_data():
|
| 71 |
-
return your_data
|
| 72 |
-
```
|
| 73 |
-
|
| 74 |
-
### ❌ Sorun 4: Repository "private"
|
| 75 |
-
**Çözüm:** GitHub'da repository'yi **public** yapın.
|
| 76 |
-
|
| 77 |
-
---
|
| 78 |
-
|
| 79 |
-
## 🎯 İpuçları
|
| 80 |
-
|
| 81 |
-
✅ **Deploy sonrası güncellemeler:**
|
| 82 |
-
```bash
|
| 83 |
-
git add .
|
| 84 |
-
git commit -m "Güncelleme"
|
| 85 |
-
git push
|
| 86 |
-
# Otomatik olarak yeniden deploy edilir!
|
| 87 |
-
```
|
| 88 |
-
|
| 89 |
-
✅ **API anahtarları için:**
|
| 90 |
-
1. Streamlit Cloud dashboard'da uygulamanızı seçin
|
| 91 |
-
2. Settings > Secrets
|
| 92 |
-
3. Formatı:
|
| 93 |
-
```toml
|
| 94 |
-
[api_keys]
|
| 95 |
-
GEMINI_API_KEY = "your_key_here"
|
| 96 |
-
```
|
| 97 |
-
|
| 98 |
-
✅ **Hızlı test:**
|
| 99 |
-
- Yerel test: `streamlit run compact_borsa_app.py`
|
| 100 |
-
- Deploy test: URL'yi ziyaret edin
|
| 101 |
-
|
| 102 |
-
---
|
| 103 |
-
|
| 104 |
-
## 📞 Yardım Gerekirse
|
| 105 |
-
|
| 106 |
-
1. **Streamlit Logs:** Cloud dashboard'da "Manage app" > "Logs"
|
| 107 |
-
2. **GitHub Issues:** Repository'nizde issue oluşturun
|
| 108 |
-
3. **Streamlit Community:** https://discuss.streamlit.io
|
| 109 |
-
|
| 110 |
-
---
|
| 111 |
-
|
| 112 |
-
**🎉 Başarılı deploy dileriz!**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HUGGINGFACE_NETLIFY_DEPLOYMENT.md
DELETED
|
@@ -1,85 +0,0 @@
|
|
| 1 |
-
# 🚀 Hugging Face (ML Backend) + Netlify (Frontend) Deployment Planı
|
| 2 |
-
|
| 3 |
-
## 📋 Deployment Stratejisi
|
| 4 |
-
|
| 5 |
-
**Mimari:**
|
| 6 |
-
- **Hugging Face Space:** Python FastAPI ile ML API (scikit-learn, xgboost, lightgbm)
|
| 7 |
-
- **Netlify:** Next.js frontend (basit UI, HF API'ye istek atar)
|
| 8 |
-
|
| 9 |
-
---
|
| 10 |
-
|
| 11 |
-
## ✅ ADIM 1: Hugging Face Space Kurulumu
|
| 12 |
-
|
| 13 |
-
### 1.1. HuggingFace hesabı ve Space oluştur
|
| 14 |
-
- [ ] https://huggingface.co/ hesabı aç
|
| 15 |
-
- [ ] New Space oluştur → "borsanew-ml-api"
|
| 16 |
-
- [ ] SDK seç: **Docker**
|
| 17 |
-
- [ ] Space type: **Public** (ücretsiz)
|
| 18 |
-
|
| 19 |
-
### 1.2. FastAPI Backend Dosyaları Hazırla
|
| 20 |
-
**Dosyalar:**
|
| 21 |
-
- `huggingface-space/app.py` - FastAPI ana dosya (hazır)
|
| 22 |
-
- `huggingface-space/requirements.txt` - Python dependencies (hazır)
|
| 23 |
-
- `huggingface-space/Dockerfile` - Docker entrypoint (hazır)
|
| 24 |
-
- `huggingface-space/README.md` - HF Space metadata + açıklama (hazır)
|
| 25 |
-
- `huggingface-space/ai/`, `huggingface-space/data/`, `huggingface-space/analysis/` (kopyalandı)
|
| 26 |
-
|
| 27 |
-
### 1.3. API Endpoints
|
| 28 |
-
```
|
| 29 |
-
GET /api/stock-data?symbol=THYAO&period=1y
|
| 30 |
-
POST /api/ml-predictions (body: {symbols, days_ahead, model})
|
| 31 |
-
GET /api/technical-analysis?symbol=THYAO
|
| 32 |
-
GET /api/market-overview
|
| 33 |
-
```
|
| 34 |
-
|
| 35 |
-
---
|
| 36 |
-
|
| 37 |
-
## ✅ ADIM 2: Netlify Frontend Güncelleme
|
| 38 |
-
|
| 39 |
-
### 2.1. Next.js API Client Güncelle
|
| 40 |
-
- ✅ `nextjs-app/src/lib/api-client.ts` - HF URL kullanıyor
|
| 41 |
-
- ✅ `.env.production` - HF API URL eklendi
|
| 42 |
-
|
| 43 |
-
### 2.2. Netlify Deploy
|
| 44 |
-
- [ ] GitHub'a push et (güncellenmiş API client)
|
| 45 |
-
- [ ] Netlify'da Environment Variables ekle:
|
| 46 |
-
- `NEXT_PUBLIC_API_URL=https://veteroner-borsa.hf.space`
|
| 47 |
-
- [ ] Netlify otomatik deploy
|
| 48 |
-
- [ ] Test et
|
| 49 |
-
|
| 50 |
-
---
|
| 51 |
-
|
| 52 |
-
## ✅ ADIM 3: Test ve Monitoring
|
| 53 |
-
|
| 54 |
-
### 3.1. API Test
|
| 55 |
-
- [ ] HF Space'de API endpoint test et
|
| 56 |
-
- [ ] Netlify frontend'den HF API çağır
|
| 57 |
-
- [ ] CORS ayarlarını kontrol et
|
| 58 |
-
|
| 59 |
-
### 3.2. Performance
|
| 60 |
-
- [ ] HF Space cold start kontrolü (~30s ilk istek)
|
| 61 |
-
- [ ] Caching stratejisi (HF persistent storage)
|
| 62 |
-
|
| 63 |
-
---
|
| 64 |
-
|
| 65 |
-
## 📦 Şu Anda Yapılacaklar
|
| 66 |
-
|
| 67 |
-
### ⏳ YAPILIYOR: Hugging Face Space'e yükleme
|
| 68 |
-
|
| 69 |
-
**Sonraki adım:** Hugging Face Space repo'suna `huggingface-space/` içeriğini root olarak push
|
| 70 |
-
|
| 71 |
-
Önerilen yol (en pratik):
|
| 72 |
-
1) HF'de Space oluştur (SDK: Docker)
|
| 73 |
-
2) HF Space repo URL'sini al (git)
|
| 74 |
-
3) Bu repo içinden sadece `huggingface-space/` klasörünü Space'e gönder
|
| 75 |
-
|
| 76 |
-
Not: İstersen tek bir ayrı git repo olarak da `huggingface-space/` klasörünü yönetebiliriz.
|
| 77 |
-
|
| 78 |
-
---
|
| 79 |
-
|
| 80 |
-
## 🎯 Beklenen Sonuç
|
| 81 |
-
|
| 82 |
-
✅ Hugging Face Space: `https://USERNAME-borsanew-ml-api.hf.space/api/...`
|
| 83 |
-
✅ Netlify Frontend: Next.js UI
|
| 84 |
-
✅ Tam ML özellikleri çalışır
|
| 85 |
-
✅ Ücretsiz deployment
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KOMPAKT_UYGULAMA_README.md
DELETED
|
@@ -1,118 +0,0 @@
|
|
| 1 |
-
# 📊 Kompakt Borsa Analiz Uygulaması
|
| 2 |
-
|
| 3 |
-
Bu uygulama, ana borsa uygulamanızdan seçilen 3 temel sekmeyi içeren kompakt bir versiyondur.
|
| 4 |
-
|
| 5 |
-
## 🎯 İçerik
|
| 6 |
-
|
| 7 |
-
### 1. 📊 BIST 100 Genel Bakış
|
| 8 |
-
- BIST 100 endeksinin teknik analizi
|
| 9 |
-
- Günlük, haftalık, aylık performans verileri
|
| 10 |
-
- Sektör performans analizi
|
| 11 |
-
- En çok yükselenler ve düşenler
|
| 12 |
-
- Teknik gösterge sinyalleri
|
| 13 |
-
- Piyasa genel durumu ve öneriler
|
| 14 |
-
|
| 15 |
-
### 2. 🔍 Hisse Analizi
|
| 16 |
-
- Hisse senedi teknik analizi
|
| 17 |
-
- Hareketli ortalamalar (SMA/EMA)
|
| 18 |
-
- Osilatörler (RSI, MACD, Stochastic)
|
| 19 |
-
- Destek ve direnç seviyeleri
|
| 20 |
-
- Fibonacci seviyeleri
|
| 21 |
-
- Grafik desenleri
|
| 22 |
-
- Yapay zeka değerlendirmesi
|
| 23 |
-
- Risk analizi ve yatırım önerileri
|
| 24 |
-
|
| 25 |
-
### 3. 🧠 ML Yükseliş Tahmini
|
| 26 |
-
- Makine öğrenmesi tabanlı yükseliş tahminleri
|
| 27 |
-
- RandomForest, XGBoost, LightGBM modelleri
|
| 28 |
-
- Gelişmiş teknik göstergeler
|
| 29 |
-
- Sentiment analizi (opsiyonel)
|
| 30 |
-
- Makroekonomik veriler (opsiyonel)
|
| 31 |
-
- Model performans analizi
|
| 32 |
-
- Backtesting sonuçları
|
| 33 |
-
|
| 34 |
-
## 🚀 Nasıl Başlatılır
|
| 35 |
-
|
| 36 |
-
### Yöntem 1: Batch Dosyası (Önerilen)
|
| 37 |
-
1. `kompakt_borsa_baslat.bat` dosyasına çift tıklayın
|
| 38 |
-
2. Uygulama otomatik olarak tarayıcınızda açılacaktır
|
| 39 |
-
3. Adres: `http://localhost:8502`
|
| 40 |
-
|
| 41 |
-
### Yöntem 2: Manuel
|
| 42 |
-
```bash
|
| 43 |
-
# Terminal/Command Prompt'ta
|
| 44 |
-
streamlit run compact_borsa_app.py --server.port=8502
|
| 45 |
-
```
|
| 46 |
-
|
| 47 |
-
## ✨ Özellikler
|
| 48 |
-
|
| 49 |
-
### Kullanıcı Dostu Arayüz
|
| 50 |
-
- Modern ve sade tasarım
|
| 51 |
-
- Responsive yapı
|
| 52 |
-
- Kolay navigasyon
|
| 53 |
-
- Sidebar ile hızlı erişim
|
| 54 |
-
|
| 55 |
-
### Akıllı Özellikler
|
| 56 |
-
- Favori hisse yönetimi
|
| 57 |
-
- Son analizleri kaydetme
|
| 58 |
-
- Otomatik veri güncelleme
|
| 59 |
-
- Hata yönetimi
|
| 60 |
-
|
| 61 |
-
### Performans
|
| 62 |
-
- Veri cache'leme
|
| 63 |
-
- Hızlı yükleme
|
| 64 |
-
- Optimize edilmiş göstergeler
|
| 65 |
-
|
| 66 |
-
## 📋 Gereksinimler
|
| 67 |
-
|
| 68 |
-
Bu uygulama ana borsa uygulamanızın tüm bağımlılıklarını kullanır:
|
| 69 |
-
- Python 3.8+
|
| 70 |
-
- Streamlit
|
| 71 |
-
- Pandas, NumPy
|
| 72 |
-
- Plotly
|
| 73 |
-
- yfinance
|
| 74 |
-
- scikit-learn
|
| 75 |
-
- XGBoost, LightGBM
|
| 76 |
-
- Diğer gerekli kütüphaneler
|
| 77 |
-
|
| 78 |
-
## 🔧 Yapılandırma
|
| 79 |
-
|
| 80 |
-
Uygulama ana projenizdeki yapılandırma dosyalarını kullanır:
|
| 81 |
-
- `config.py` - Genel ayarlar
|
| 82 |
-
- `data/` klasörü - Veri kaynakları
|
| 83 |
-
- `ui/` klasörü - Arayüz bileşenleri
|
| 84 |
-
- `analysis/` klasörü - Analiz fonksiyonları
|
| 85 |
-
|
| 86 |
-
## 📊 Veri Kaynakları
|
| 87 |
-
|
| 88 |
-
- **Hisse Verileri**: Yahoo Finance (yfinance)
|
| 89 |
-
- **Teknik Göstergeler**: Kendi hesaplama algoritmaları
|
| 90 |
-
- **Haberler**: Yapılandırılmış haber kaynakları
|
| 91 |
-
- **ML Modelleri**: Yerel veritabanında saklanan eğitilmiş modeller
|
| 92 |
-
|
| 93 |
-
## ⚠️ Önemli Notlar
|
| 94 |
-
|
| 95 |
-
1. **Yatırım Tavsiyesi Değildir**: Bu uygulama sadece analiz amaçlıdır
|
| 96 |
-
2. **Veri Güncelliği**: Veriler gerçek zamanlı değildir
|
| 97 |
-
3. **Risk**: Yatırım kararlarını kendi riskinizle alın
|
| 98 |
-
4. **Ana Uygulama**: Bu uygulama ana borsa uygulamanızı etkilemez
|
| 99 |
-
|
| 100 |
-
## 🔄 Güncelleme
|
| 101 |
-
|
| 102 |
-
Ana borsa uygulamanızda yapılan değişiklikler otomatik olarak bu uygulamaya da yansır çünkü aynı modülleri kullanır.
|
| 103 |
-
|
| 104 |
-
## 📞 Destek
|
| 105 |
-
|
| 106 |
-
Bu uygulama ana borsa uygulamanızın bir alt kümesi olduğu için, herhangi bir sorun durumunda ana uygulamanızın dokümantasyonunu kontrol edin.
|
| 107 |
-
|
| 108 |
-
## 🎉 Kullanım İpuçları
|
| 109 |
-
|
| 110 |
-
1. **Favori Hisseler**: Sık analiz ettiğiniz hisseleri favorilere ekleyin
|
| 111 |
-
2. **Sekme Geçişi**: Üç sekme arasında kolayca geçiş yapabilirsiniz
|
| 112 |
-
3. **ML Tahminleri**: Gelişmiş ayarlarda parametreleri değiştirerek farklı sonuçlar alabilirsiniz
|
| 113 |
-
4. **BIST 100**: Piyasa genel durumunu takip etmek için kullanın
|
| 114 |
-
5. **Hisse Analizi**: Detaylı teknik analiz için ideal
|
| 115 |
-
|
| 116 |
-
---
|
| 117 |
-
|
| 118 |
-
**Başarılı analizler dileriz! 📈**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MIGRATION_COMPLETE.md
DELETED
|
@@ -1,298 +0,0 @@
|
|
| 1 |
-
# 📊 Borsa Uygulaması - Netlify Migration Tamamlandı!
|
| 2 |
-
|
| 3 |
-
## 🎯 Problem
|
| 4 |
-
- ❌ Streamlit Cloud çalışmıyor
|
| 5 |
-
- ❌ Vercel Python desteklemiyor
|
| 6 |
-
- ❌ Next.js'e baştan yazmak istemedin
|
| 7 |
-
- ❌ Mevcut Python kodların kullanılmıyor
|
| 8 |
-
|
| 9 |
-
## ✅ Çözüm: Netlify + Python Functions
|
| 10 |
-
|
| 11 |
-
### Yapılan Değişiklikler
|
| 12 |
-
|
| 13 |
-
#### 1. Netlify Konfigürasyonu
|
| 14 |
-
```
|
| 15 |
-
✅ netlify.toml - Build & function config
|
| 16 |
-
✅ runtime.txt - Python 3.11
|
| 17 |
-
✅ requirements-netlify.txt - Python dependencies
|
| 18 |
-
✅ .env.example - Environment variables
|
| 19 |
-
```
|
| 20 |
-
|
| 21 |
-
#### 2. Python Serverless Functions (4 adet)
|
| 22 |
-
```
|
| 23 |
-
netlify/functions/
|
| 24 |
-
✅ stock-data.py - Hisse verisi API
|
| 25 |
-
✅ ml-predictions.py - ML tahmin API
|
| 26 |
-
✅ technical-analysis.py - Teknik analiz API
|
| 27 |
-
✅ market-overview.py - Piyasa özeti API
|
| 28 |
-
```
|
| 29 |
-
|
| 30 |
-
#### 3. API-Ready Python Modülleri (Streamlit'siz)
|
| 31 |
-
```
|
| 32 |
-
✅ data/stock_data_api.py - Veri çekme (yfinance)
|
| 33 |
-
✅ ai/predictions_api.py - ML tahminler (sklearn, xgboost)
|
| 34 |
-
✅ analysis/indicators_api.py - Teknik göstergeler (RSI, MACD, BB)
|
| 35 |
-
```
|
| 36 |
-
|
| 37 |
-
#### 4. Next.js Frontend Integration
|
| 38 |
-
```
|
| 39 |
-
✅ nextjs-app/src/lib/api-client.ts - TypeScript API client
|
| 40 |
-
```
|
| 41 |
-
|
| 42 |
-
#### 5. Deployment Tools
|
| 43 |
-
```
|
| 44 |
-
✅ netlify-check.sh - Hazırlık kontrolü (chmod +x)
|
| 45 |
-
✅ netlify-deploy.sh - Hızlı deployment (chmod +x)
|
| 46 |
-
✅ NETLIFY_DEPLOYMENT.md - Detaylı rehber
|
| 47 |
-
✅ NETLIFY_README.md - Genel bakış
|
| 48 |
-
✅ QUICKSTART.md - Hızlı başlangıç
|
| 49 |
-
```
|
| 50 |
-
|
| 51 |
-
---
|
| 52 |
-
|
| 53 |
-
## 🚀 ŞİMDİ NE YAPILACAK?
|
| 54 |
-
|
| 55 |
-
### Seçenek 1: Local Test (Önerilen)
|
| 56 |
-
|
| 57 |
-
```bash
|
| 58 |
-
cd /Volumes/LaCie/borsa_uygulamasi
|
| 59 |
-
|
| 60 |
-
# 1. Kontrol et
|
| 61 |
-
./netlify-check.sh
|
| 62 |
-
|
| 63 |
-
# 2. Deploy script çalıştır
|
| 64 |
-
./netlify-deploy.sh
|
| 65 |
-
# → Seçenek 1'i seç (Local test)
|
| 66 |
-
|
| 67 |
-
# 3. Browser'da aç
|
| 68 |
-
http://localhost:8888
|
| 69 |
-
```
|
| 70 |
-
|
| 71 |
-
### Seçenek 2: Production Deploy
|
| 72 |
-
|
| 73 |
-
```bash
|
| 74 |
-
# Netlify'a giriş
|
| 75 |
-
netlify login
|
| 76 |
-
|
| 77 |
-
# Deploy!
|
| 78 |
-
netlify deploy --prod
|
| 79 |
-
|
| 80 |
-
# URL'i al ve test et
|
| 81 |
-
```
|
| 82 |
-
|
| 83 |
-
### Seçenek 3: GitHub Otomatik Deploy
|
| 84 |
-
|
| 85 |
-
```bash
|
| 86 |
-
# 1. GitHub repo oluştur
|
| 87 |
-
# https://github.com/new
|
| 88 |
-
|
| 89 |
-
# 2. Push et
|
| 90 |
-
git add .
|
| 91 |
-
git commit -m "Netlify deployment ready"
|
| 92 |
-
git push origin main
|
| 93 |
-
|
| 94 |
-
# 3. Netlify Dashboard
|
| 95 |
-
# https://app.netlify.com/
|
| 96 |
-
# "New site from Git" → Repository seç → Deploy!
|
| 97 |
-
```
|
| 98 |
-
|
| 99 |
-
---
|
| 100 |
-
|
| 101 |
-
## 📦 Yüklü Olan Her Şey
|
| 102 |
-
|
| 103 |
-
### Netlify Config Dosyaları
|
| 104 |
-
- [netlify.toml](netlify.toml) - Build, functions, redirects
|
| 105 |
-
- [runtime.txt](runtime.txt) - Python 3.11
|
| 106 |
-
- [requirements-netlify.txt](requirements-netlify.txt) - yfinance, pandas, sklearn, xgboost, lightgbm
|
| 107 |
-
|
| 108 |
-
### Python Backend (4 Serverless Function)
|
| 109 |
-
- [stock-data.py](netlify/functions/stock-data.py) - GET `/api/stock-data?symbol=THYAO`
|
| 110 |
-
- [ml-predictions.py](netlify/functions/ml-predictions.py) - POST `/api/ml-predictions`
|
| 111 |
-
- [technical-analysis.py](netlify/functions/technical-analysis.py) - GET `/api/technical-analysis?symbol=THYAO`
|
| 112 |
-
- [market-overview.py](netlify/functions/market-overview.py) - GET `/api/market-overview`
|
| 113 |
-
|
| 114 |
-
### API Modülleri (Mevcut Kodlardan Türetildi)
|
| 115 |
-
- [stock_data_api.py](data/stock_data_api.py) - `get_stock_data_for_api()`, `get_market_summary_for_api()`
|
| 116 |
-
- [predictions_api.py](ai/predictions_api.py) - `predict_stock_for_api()`, `predict_multiple_stocks_for_api()`
|
| 117 |
-
- [indicators_api.py](analysis/indicators_api.py) - `calculate_all_indicators_for_api()` (RSI, MACD, Bollinger)
|
| 118 |
-
|
| 119 |
-
### Frontend Integration
|
| 120 |
-
- [api-client.ts](nextjs-app/src/lib/api-client.ts) - TypeScript API client
|
| 121 |
-
|
| 122 |
-
### Deployment Tools
|
| 123 |
-
- [netlify-check.sh](netlify-check.sh) - Deployment hazırlık kontrolü
|
| 124 |
-
- [netlify-deploy.sh](netlify-deploy.sh) - Interactive deployment script
|
| 125 |
-
|
| 126 |
-
### Dokümantasyon
|
| 127 |
-
- [QUICKSTART.md](QUICKSTART.md) - 3 adımda başlangıç
|
| 128 |
-
- [NETLIFY_README.md](NETLIFY_README.md) - Genel bakış
|
| 129 |
-
- [NETLIFY_DEPLOYMENT.md](NETLIFY_DEPLOYMENT.md) - Detaylı rehber
|
| 130 |
-
- [.env.example](.env.example) - Environment variables template
|
| 131 |
-
|
| 132 |
-
---
|
| 133 |
-
|
| 134 |
-
## 🎯 Mevcut Python Kodların Durumu
|
| 135 |
-
|
| 136 |
-
### ✅ KORUNDU ve Kullanılıyor
|
| 137 |
-
|
| 138 |
-
**Orijinal Modüller (Streamlit ile):**
|
| 139 |
-
- `data/stock_data.py` - Hala mevcut, Streamlit app için
|
| 140 |
-
- `ai/predictions.py` - Hala mevcut, Streamlit app için
|
| 141 |
-
- `analysis/indicators.py` - Hala mevcut, Streamlit app için
|
| 142 |
-
|
| 143 |
-
**Yeni API Versiyonları (Streamlit'siz):**
|
| 144 |
-
- `data/stock_data_api.py` - Netlify Functions için
|
| 145 |
-
- `ai/predictions_api.py` - Netlify Functions için
|
| 146 |
-
- `analysis/indicators_api.py` - Netlify Functions için
|
| 147 |
-
|
| 148 |
-
**Sonuç:** İstersen hala Streamlit app'i local çalıştırabilirsin! (`streamlit run compact_borsa_app.py`)
|
| 149 |
-
|
| 150 |
-
---
|
| 151 |
-
|
| 152 |
-
## 💰 Netlify Free Tier
|
| 153 |
-
|
| 154 |
-
✅ **300 build dakika/ay** - Her deploy ~2-3 dakika
|
| 155 |
-
✅ **100GB bandwidth/ay** - Binlerce kullanıcı
|
| 156 |
-
✅ **125,000 function çağrısı/ay** - Günde ~4000 request
|
| 157 |
-
✅ **Otomatik SSL** - HTTPS ücretsiz
|
| 158 |
-
✅ **Global CDN** - Hızlı erişim
|
| 159 |
-
|
| 160 |
-
⚠️ **Limitler:**
|
| 161 |
-
- Function timeout: 10 saniye (free tier)
|
| 162 |
-
- Concurrent builds: 1
|
| 163 |
-
|
| 164 |
-
---
|
| 165 |
-
|
| 166 |
-
## 🧪 Test Endpoints (Deploy Sonrası)
|
| 167 |
-
|
| 168 |
-
```bash
|
| 169 |
-
# Production URL ile:
|
| 170 |
-
BASE_URL="https://your-site.netlify.app"
|
| 171 |
-
|
| 172 |
-
# 1. Market overview
|
| 173 |
-
curl $BASE_URL/api/market-overview
|
| 174 |
-
|
| 175 |
-
# 2. Hisse verisi
|
| 176 |
-
curl "$BASE_URL/api/stock-data?symbol=THYAO&period=1y"
|
| 177 |
-
|
| 178 |
-
# 3. Teknik analiz
|
| 179 |
-
curl "$BASE_URL/api/technical-analysis?symbol=THYAO"
|
| 180 |
-
|
| 181 |
-
# 4. ML tahmin
|
| 182 |
-
curl -X POST $BASE_URL/api/ml-predictions \
|
| 183 |
-
-H "Content-Type: application/json" \
|
| 184 |
-
-d '{"symbols": ["THYAO", "AKBNK"], "days_ahead": 5, "model": "ensemble"}'
|
| 185 |
-
```
|
| 186 |
-
|
| 187 |
-
---
|
| 188 |
-
|
| 189 |
-
## 🔥 Hızlı Komutlar
|
| 190 |
-
|
| 191 |
-
```bash
|
| 192 |
-
# Hazırlık kontrolü
|
| 193 |
-
./netlify-check.sh
|
| 194 |
-
|
| 195 |
-
# Deployment başlat
|
| 196 |
-
./netlify-deploy.sh
|
| 197 |
-
|
| 198 |
-
# Manuel komutlar
|
| 199 |
-
netlify login
|
| 200 |
-
netlify dev # Local test
|
| 201 |
-
netlify deploy --prod # Production
|
| 202 |
-
netlify status # Durum
|
| 203 |
-
netlify open # Dashboard aç
|
| 204 |
-
netlify logs:function stock-data # Function logs
|
| 205 |
-
```
|
| 206 |
-
|
| 207 |
-
---
|
| 208 |
-
|
| 209 |
-
## 📊 Sonraki Adımlar
|
| 210 |
-
|
| 211 |
-
### Hemen Yapılacaklar
|
| 212 |
-
|
| 213 |
-
1. **Deploy Et**
|
| 214 |
-
```bash
|
| 215 |
-
./netlify-deploy.sh
|
| 216 |
-
```
|
| 217 |
-
|
| 218 |
-
2. **Test Et**
|
| 219 |
-
- Local: `http://localhost:8888`
|
| 220 |
-
- Production: Test endpoint'leri çalıştır
|
| 221 |
-
|
| 222 |
-
3. **Environment Variables Ayarla** (Supabase kullanıyorsan)
|
| 223 |
-
- Netlify Dashboard → Environment Variables
|
| 224 |
-
- `NEXT_PUBLIC_SUPABASE_URL`
|
| 225 |
-
- `NEXT_PUBLIC_SUPABASE_ANON_KEY`
|
| 226 |
-
|
| 227 |
-
### İlerisi İçin
|
| 228 |
-
|
| 229 |
-
4. **Custom Domain Ekle**
|
| 230 |
-
- Netlify Dashboard → Domain settings
|
| 231 |
-
- Örnek: `borsa.senindomain.com`
|
| 232 |
-
|
| 233 |
-
5. **Analytics Aktif Et**
|
| 234 |
-
- Netlify Analytics (ücretli)
|
| 235 |
-
- veya Google Analytics entegrasyonu
|
| 236 |
-
|
| 237 |
-
6. **CI/CD Pipeline**
|
| 238 |
-
- GitHub Actions ile otomatik test
|
| 239 |
-
- Staging environment kurulumu
|
| 240 |
-
|
| 241 |
-
7. **Monitoring**
|
| 242 |
-
- Sentry entegrasyonu (error tracking)
|
| 243 |
-
- Uptime monitoring (UptimeRobot)
|
| 244 |
-
|
| 245 |
-
---
|
| 246 |
-
|
| 247 |
-
## ⚠️ Bilinen Sorunlar ve Çözümler
|
| 248 |
-
|
| 249 |
-
### 1. Import Hatası
|
| 250 |
-
**Sorun:** Python functions modülleri bulamıyor
|
| 251 |
-
**Çözüm:** Her function başında `sys.path.insert()` var, kontrol et
|
| 252 |
-
|
| 253 |
-
### 2. Build Hatası
|
| 254 |
-
**Sorun:** Next.js build failed
|
| 255 |
-
**Çözüm:**
|
| 256 |
-
```bash
|
| 257 |
-
cd nextjs-app
|
| 258 |
-
npm run build # Local test
|
| 259 |
-
```
|
| 260 |
-
|
| 261 |
-
### 3. Function Timeout
|
| 262 |
-
**Sorun:** 10 saniye üstü işlemler
|
| 263 |
-
**Çözüm:**
|
| 264 |
-
- Veri setini küçült (6 ay → 3 ay)
|
| 265 |
-
- Cache kullan
|
| 266 |
-
- Model karmaşıklığını azalt
|
| 267 |
-
|
| 268 |
-
---
|
| 269 |
-
|
| 270 |
-
## 🎉 Tebrikler!
|
| 271 |
-
|
| 272 |
-
Artık **production-ready** bir borsa uygulaması var:
|
| 273 |
-
|
| 274 |
-
✅ Mevcut Python kodların korundu
|
| 275 |
-
✅ Modern Next.js frontend
|
| 276 |
-
✅ Serverless Python backend
|
| 277 |
-
✅ Ücretsiz Netlify hosting
|
| 278 |
-
✅ Otomatik scaling
|
| 279 |
-
✅ Global CDN
|
| 280 |
-
✅ SSL/HTTPS
|
| 281 |
-
|
| 282 |
-
**İlk deployment için:** `./netlify-deploy.sh` 🚀
|
| 283 |
-
|
| 284 |
-
---
|
| 285 |
-
|
| 286 |
-
## 📞 Yardım
|
| 287 |
-
|
| 288 |
-
- **Deployment sorunları:** `./netlify-check.sh` çalıştır
|
| 289 |
-
- **Function hatası:** `netlify logs:function <function-name>`
|
| 290 |
-
- **Build hatası:** `cd nextjs-app && npm run build`
|
| 291 |
-
- **Netlify Docs:** https://docs.netlify.com/
|
| 292 |
-
- **Community:** https://answers.netlify.com/
|
| 293 |
-
|
| 294 |
-
---
|
| 295 |
-
|
| 296 |
-
**Son güncelleme:** 27 Ocak 2026
|
| 297 |
-
**Durum:** ✅ Deployment hazır
|
| 298 |
-
**Sonraki adım:** `./netlify-deploy.sh` çalıştır
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MIGRATION_PLAN.md
DELETED
|
@@ -1,1453 +0,0 @@
|
|
| 1 |
-
# 🚀 BORSA UYGULAMASI - STREAMLIT'TEN MODERN STACK'E DÖNÜŞÜM PLANI
|
| 2 |
-
|
| 3 |
-
## 📅 Tarih: 2 Ocak 2026
|
| 4 |
-
## 🎯 Hedef: Streamlit → Supabase + HuggingFace + Vercel
|
| 5 |
-
|
| 6 |
-
---
|
| 7 |
-
|
| 8 |
-
## 📊 MEVCUT DURUM ANALİZİ
|
| 9 |
-
|
| 10 |
-
### Teknik Envanter
|
| 11 |
-
- **Platform:** Streamlit
|
| 12 |
-
- **Kod Tabanı:** 4,777 Python dosyası
|
| 13 |
-
- **Proje Boyutu:** 20GB
|
| 14 |
-
- **Veritabanı:** SQLite 17GB
|
| 15 |
-
- **Modüller:** 13+ sekme/özellik
|
| 16 |
-
- **Ana Bağımlılıklar:** 21+ Python paketi
|
| 17 |
-
|
| 18 |
-
### Performans Sorunları
|
| 19 |
-
- ❌ Yavaş sayfa yüklenmeleri (5+ saniye)
|
| 20 |
-
- ❌ Her interaksionda sayfa yenileme
|
| 21 |
-
- ❌ Memory limitleri (Streamlit Cloud 1GB)
|
| 22 |
-
- ❌ Zayıf caching mekanizması
|
| 23 |
-
- ❌ 17GB veritabanı disk I/O darboğazı
|
| 24 |
-
- ❌ ML model eğitimleri client-side
|
| 25 |
-
- ❌ Concurrent kullanıcı sınırı (10-20)
|
| 26 |
-
|
| 27 |
-
---
|
| 28 |
-
|
| 29 |
-
## 🎯 YENİ MİMARİ
|
| 30 |
-
|
| 31 |
-
```
|
| 32 |
-
┌─────────────────────────────────────────────────────────┐
|
| 33 |
-
│ KULLANICI │
|
| 34 |
-
└────────────────────┬────────────────────────────────────┘
|
| 35 |
-
│
|
| 36 |
-
┌────────────▼───────────────┐
|
| 37 |
-
│ VERCEL CDN (Global) │
|
| 38 |
-
│ - Edge Caching │
|
| 39 |
-
│ - DDoS Protection │
|
| 40 |
-
└────────────┬───────────────┘
|
| 41 |
-
│
|
| 42 |
-
┌────────────────────▼─────────────────────────┐
|
| 43 |
-
│ NEXT.JS 14 APP (Vercel) │
|
| 44 |
-
│ ┌─────────────────────────────────────┐ │
|
| 45 |
-
│ │ Pages/Routes │ │
|
| 46 |
-
│ ├─────────────────────────────────────┤ │
|
| 47 |
-
│ │ / (dashboard) │ │
|
| 48 |
-
│ │ /stocks/[symbol] │ │
|
| 49 |
-
│ │ /ml-predictions │ │
|
| 50 |
-
│ │ /portfolio │ │
|
| 51 |
-
│ │ /news │ │
|
| 52 |
-
│ │ /api/* (API Routes) │ │
|
| 53 |
-
│ └─────────────────────────────────────┘ │
|
| 54 |
-
└───────┬─────────────┬──────────────┬─────────┘
|
| 55 |
-
│ │ │
|
| 56 |
-
┌───────▼──────┐ ┌───▼─────────┐ ┌─▼──────────┐
|
| 57 |
-
│ SUPABASE │ │ HUGGINGFACE │ │ EXTERNAL │
|
| 58 |
-
│ │ │ │ │ APIs │
|
| 59 |
-
│ PostgreSQL │ │ ML Models │ │ │
|
| 60 |
-
│ - Stocks │ │ - Sentiment │ │ - Yahoo │
|
| 61 |
-
│ - Prices │ │ - Price Pred│ │ Finance │
|
| 62 |
-
│ - Portfolios │ │ - NLP │ │ - News API │
|
| 63 |
-
│ │ │ │ │ │
|
| 64 |
-
│ Edge Funcs │ │ Inference │ │ │
|
| 65 |
-
│ - Cron Jobs │ │ API │ │ │
|
| 66 |
-
│ - Webhooks │ │ │ │ │
|
| 67 |
-
│ │ │ │ │ │
|
| 68 |
-
│ Storage │ │ │ │ │
|
| 69 |
-
│ - Charts │ │ │ │ │
|
| 70 |
-
│ - Reports │ │ │ │ │
|
| 71 |
-
│ │ │ │ │ │
|
| 72 |
-
│ Auth │ │ │ │ │
|
| 73 |
-
│ - Users │ │ │ │ │
|
| 74 |
-
│ - Sessions │ │ │ │ │
|
| 75 |
-
└──────────────┘ └─────────────┘ └────────────┘
|
| 76 |
-
```
|
| 77 |
-
|
| 78 |
-
---
|
| 79 |
-
|
| 80 |
-
## 📋 DETAYLI DÖNÜŞÜM ADIMLARİ
|
| 81 |
-
|
| 82 |
-
### PHASE 0: HAZIRLIK (Gün 1)
|
| 83 |
-
**Süre:** 1 gün
|
| 84 |
-
**Öncelik:** KRITIK
|
| 85 |
-
|
| 86 |
-
#### ✅ 0.1 Hesap Oluşturma
|
| 87 |
-
- [ ] Supabase hesabı oluştur (supabase.com)
|
| 88 |
-
- [ ] HuggingFace hesabı oluştur (huggingface.co)
|
| 89 |
-
- [ ] Vercel hesabı oluştur (vercel.com)
|
| 90 |
-
- [ ] GitHub repository oluştur (yeni proje için)
|
| 91 |
-
|
| 92 |
-
#### ✅ 0.2 Mevcut Kod Analizi
|
| 93 |
-
- [ ] Kritik fonksiyonları listele
|
| 94 |
-
- [ ] API endpoint'leri dokümante et
|
| 95 |
-
- [ ] Veritabanı şemasını çıkar
|
| 96 |
-
- [ ] ML model parametrelerini kaydet
|
| 97 |
-
|
| 98 |
-
#### ✅ 0.3 Development Environment
|
| 99 |
-
```bash
|
| 100 |
-
# Gerekli araçlar
|
| 101 |
-
brew install node # Node.js 18+
|
| 102 |
-
brew install postgresql # PostgreSQL client
|
| 103 |
-
npm install -g vercel # Vercel CLI
|
| 104 |
-
npm install -g supabase # Supabase CLI
|
| 105 |
-
```
|
| 106 |
-
|
| 107 |
-
---
|
| 108 |
-
|
| 109 |
-
### PHASE 1: SUPABASE KURULUMU (Gün 2-3)
|
| 110 |
-
**Süre:** 2 gün
|
| 111 |
-
**Öncelik:** YÜKSEK
|
| 112 |
-
|
| 113 |
-
#### ✅ 1.1 Supabase Projesi Oluştur
|
| 114 |
-
```bash
|
| 115 |
-
# Supabase CLI ile yeni proje
|
| 116 |
-
supabase init
|
| 117 |
-
supabase login
|
| 118 |
-
supabase projects create borsa-app
|
| 119 |
-
```
|
| 120 |
-
|
| 121 |
-
#### ✅ 1.2 Database Schema Tasarımı
|
| 122 |
-
|
| 123 |
-
**Tablolar:**
|
| 124 |
-
|
| 125 |
-
**1. stocks** (Hisse Senetleri)
|
| 126 |
-
```sql
|
| 127 |
-
CREATE TABLE stocks (
|
| 128 |
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
| 129 |
-
symbol TEXT UNIQUE NOT NULL,
|
| 130 |
-
name TEXT NOT NULL,
|
| 131 |
-
sector TEXT,
|
| 132 |
-
market_cap BIGINT,
|
| 133 |
-
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
| 134 |
-
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
| 135 |
-
);
|
| 136 |
-
|
| 137 |
-
CREATE INDEX idx_stocks_symbol ON stocks(symbol);
|
| 138 |
-
CREATE INDEX idx_stocks_sector ON stocks(sector);
|
| 139 |
-
```
|
| 140 |
-
|
| 141 |
-
**2. stock_prices** (Fiyat Geçmişi - Partitioned)
|
| 142 |
-
```sql
|
| 143 |
-
CREATE TABLE stock_prices (
|
| 144 |
-
id BIGSERIAL,
|
| 145 |
-
stock_id UUID REFERENCES stocks(id) ON DELETE CASCADE,
|
| 146 |
-
date DATE NOT NULL,
|
| 147 |
-
open DECIMAL(12,2),
|
| 148 |
-
high DECIMAL(12,2),
|
| 149 |
-
low DECIMAL(12,2),
|
| 150 |
-
close DECIMAL(12,2),
|
| 151 |
-
volume BIGINT,
|
| 152 |
-
adj_close DECIMAL(12,2),
|
| 153 |
-
PRIMARY KEY (stock_id, date, id)
|
| 154 |
-
) PARTITION BY RANGE (date);
|
| 155 |
-
|
| 156 |
-
-- Partitions (performans için)
|
| 157 |
-
CREATE TABLE stock_prices_2024 PARTITION OF stock_prices
|
| 158 |
-
FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');
|
| 159 |
-
|
| 160 |
-
CREATE TABLE stock_prices_2025 PARTITION OF stock_prices
|
| 161 |
-
FOR VALUES FROM ('2025-01-01') TO ('2026-01-01');
|
| 162 |
-
|
| 163 |
-
CREATE TABLE stock_prices_2026 PARTITION OF stock_prices
|
| 164 |
-
FOR VALUES FROM ('2026-01-01') TO ('2027-01-01');
|
| 165 |
-
|
| 166 |
-
CREATE INDEX idx_stock_prices_date ON stock_prices(date DESC);
|
| 167 |
-
CREATE INDEX idx_stock_prices_stock_date ON stock_prices(stock_id, date DESC);
|
| 168 |
-
```
|
| 169 |
-
|
| 170 |
-
**3. technical_indicators** (Teknik Göstergeler)
|
| 171 |
-
```sql
|
| 172 |
-
CREATE TABLE technical_indicators (
|
| 173 |
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
| 174 |
-
stock_id UUID REFERENCES stocks(id) ON DELETE CASCADE,
|
| 175 |
-
date DATE NOT NULL,
|
| 176 |
-
rsi_14 DECIMAL(6,2),
|
| 177 |
-
macd DECIMAL(10,4),
|
| 178 |
-
macd_signal DECIMAL(10,4),
|
| 179 |
-
macd_histogram DECIMAL(10,4),
|
| 180 |
-
sma_20 DECIMAL(12,2),
|
| 181 |
-
sma_50 DECIMAL(12,2),
|
| 182 |
-
sma_200 DECIMAL(12,2),
|
| 183 |
-
ema_12 DECIMAL(12,2),
|
| 184 |
-
ema_26 DECIMAL(12,2),
|
| 185 |
-
bollinger_upper DECIMAL(12,2),
|
| 186 |
-
bollinger_middle DECIMAL(12,2),
|
| 187 |
-
bollinger_lower DECIMAL(12,2),
|
| 188 |
-
stochastic_k DECIMAL(6,2),
|
| 189 |
-
stochastic_d DECIMAL(6,2),
|
| 190 |
-
atr_14 DECIMAL(10,4),
|
| 191 |
-
williams_r DECIMAL(6,2),
|
| 192 |
-
cci_20 DECIMAL(10,4),
|
| 193 |
-
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
| 194 |
-
UNIQUE(stock_id, date)
|
| 195 |
-
);
|
| 196 |
-
|
| 197 |
-
CREATE INDEX idx_tech_indicators_stock ON technical_indicators(stock_id, date DESC);
|
| 198 |
-
```
|
| 199 |
-
|
| 200 |
-
**4. ml_predictions** (ML Tahminleri)
|
| 201 |
-
```sql
|
| 202 |
-
CREATE TABLE ml_predictions (
|
| 203 |
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
| 204 |
-
stock_id UUID REFERENCES stocks(id) ON DELETE CASCADE,
|
| 205 |
-
model_type TEXT NOT NULL, -- 'RandomForest', 'XGBoost', 'LightGBM', 'Ensemble'
|
| 206 |
-
prediction_date DATE NOT NULL,
|
| 207 |
-
predicted_price DECIMAL(12,2),
|
| 208 |
-
predicted_change_pct DECIMAL(6,2),
|
| 209 |
-
confidence_score DECIMAL(5,4),
|
| 210 |
-
lower_bound DECIMAL(12,2),
|
| 211 |
-
upper_bound DECIMAL(12,2),
|
| 212 |
-
features JSONB,
|
| 213 |
-
model_version TEXT,
|
| 214 |
-
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
| 215 |
-
);
|
| 216 |
-
|
| 217 |
-
CREATE INDEX idx_predictions_stock ON ml_predictions(stock_id, prediction_date DESC);
|
| 218 |
-
CREATE INDEX idx_predictions_model ON ml_predictions(model_type, created_at DESC);
|
| 219 |
-
```
|
| 220 |
-
|
| 221 |
-
**5. news_articles** (Haberler)
|
| 222 |
-
```sql
|
| 223 |
-
CREATE TABLE news_articles (
|
| 224 |
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
| 225 |
-
stock_id UUID REFERENCES stocks(id) ON DELETE SET NULL,
|
| 226 |
-
title TEXT NOT NULL,
|
| 227 |
-
content TEXT,
|
| 228 |
-
url TEXT UNIQUE,
|
| 229 |
-
source TEXT,
|
| 230 |
-
published_at TIMESTAMP WITH TIME ZONE,
|
| 231 |
-
sentiment_score DECIMAL(4,3), -- -1 to 1
|
| 232 |
-
sentiment_label TEXT, -- 'positive', 'negative', 'neutral'
|
| 233 |
-
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
| 234 |
-
);
|
| 235 |
-
|
| 236 |
-
CREATE INDEX idx_news_stock ON news_articles(stock_id, published_at DESC);
|
| 237 |
-
CREATE INDEX idx_news_published ON news_articles(published_at DESC);
|
| 238 |
-
CREATE INDEX idx_news_sentiment ON news_articles(sentiment_score);
|
| 239 |
-
```
|
| 240 |
-
|
| 241 |
-
**6. users** (Kullanıcılar - Supabase Auth ile entegre)
|
| 242 |
-
```sql
|
| 243 |
-
-- Supabase Auth kullanıcılarına ek profil bilgileri
|
| 244 |
-
CREATE TABLE user_profiles (
|
| 245 |
-
id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
|
| 246 |
-
display_name TEXT,
|
| 247 |
-
avatar_url TEXT,
|
| 248 |
-
settings JSONB DEFAULT '{}',
|
| 249 |
-
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
| 250 |
-
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
| 251 |
-
);
|
| 252 |
-
```
|
| 253 |
-
|
| 254 |
-
**7. portfolios** (Portföyler)
|
| 255 |
-
```sql
|
| 256 |
-
CREATE TABLE portfolios (
|
| 257 |
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
| 258 |
-
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
|
| 259 |
-
stock_id UUID REFERENCES stocks(id) ON DELETE CASCADE,
|
| 260 |
-
quantity INTEGER NOT NULL CHECK (quantity > 0),
|
| 261 |
-
avg_purchase_price DECIMAL(12,2),
|
| 262 |
-
purchase_date DATE,
|
| 263 |
-
notes TEXT,
|
| 264 |
-
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
| 265 |
-
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
| 266 |
-
);
|
| 267 |
-
|
| 268 |
-
CREATE INDEX idx_portfolios_user ON portfolios(user_id);
|
| 269 |
-
CREATE INDEX idx_portfolios_stock ON portfolios(stock_id);
|
| 270 |
-
```
|
| 271 |
-
|
| 272 |
-
**8. watchlists** (Favori Hisseler)
|
| 273 |
-
```sql
|
| 274 |
-
CREATE TABLE watchlists (
|
| 275 |
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
| 276 |
-
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
|
| 277 |
-
stock_id UUID REFERENCES stocks(id) ON DELETE CASCADE,
|
| 278 |
-
notes TEXT,
|
| 279 |
-
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
| 280 |
-
UNIQUE(user_id, stock_id)
|
| 281 |
-
);
|
| 282 |
-
|
| 283 |
-
CREATE INDEX idx_watchlists_user ON watchlists(user_id);
|
| 284 |
-
```
|
| 285 |
-
|
| 286 |
-
**9. analysis_history** (Analiz Geçmişi)
|
| 287 |
-
```sql
|
| 288 |
-
CREATE TABLE analysis_history (
|
| 289 |
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
| 290 |
-
user_id UUID REFERENCES auth.users(id) ON DELETE CASCADE,
|
| 291 |
-
stock_id UUID REFERENCES stocks(id) ON DELETE CASCADE,
|
| 292 |
-
analysis_type TEXT, -- 'technical', 'fundamental', 'ml_prediction'
|
| 293 |
-
analysis_data JSONB,
|
| 294 |
-
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
| 295 |
-
);
|
| 296 |
-
|
| 297 |
-
CREATE INDEX idx_analysis_user ON analysis_history(user_id, created_at DESC);
|
| 298 |
-
CREATE INDEX idx_analysis_stock ON analysis_history(stock_id, created_at DESC);
|
| 299 |
-
```
|
| 300 |
-
|
| 301 |
-
#### ✅ 1.3 Row Level Security (RLS) Policies
|
| 302 |
-
```sql
|
| 303 |
-
-- Portfolios - Kullanıcılar sadece kendi portföylerini görsün
|
| 304 |
-
ALTER TABLE portfolios ENABLE ROW LEVEL SECURITY;
|
| 305 |
-
|
| 306 |
-
CREATE POLICY "Users can view own portfolios"
|
| 307 |
-
ON portfolios FOR SELECT
|
| 308 |
-
USING (auth.uid() = user_id);
|
| 309 |
-
|
| 310 |
-
CREATE POLICY "Users can insert own portfolios"
|
| 311 |
-
ON portfolios FOR INSERT
|
| 312 |
-
WITH CHECK (auth.uid() = user_id);
|
| 313 |
-
|
| 314 |
-
CREATE POLICY "Users can update own portfolios"
|
| 315 |
-
ON portfolios FOR UPDATE
|
| 316 |
-
USING (auth.uid() = user_id);
|
| 317 |
-
|
| 318 |
-
CREATE POLICY "Users can delete own portfolios"
|
| 319 |
-
ON portfolios FOR DELETE
|
| 320 |
-
USING (auth.uid() = user_id);
|
| 321 |
-
|
| 322 |
-
-- Watchlists
|
| 323 |
-
ALTER TABLE watchlists ENABLE ROW LEVEL SECURITY;
|
| 324 |
-
|
| 325 |
-
CREATE POLICY "Users can view own watchlists"
|
| 326 |
-
ON watchlists FOR SELECT
|
| 327 |
-
USING (auth.uid() = user_id);
|
| 328 |
-
|
| 329 |
-
CREATE POLICY "Users can manage own watchlists"
|
| 330 |
-
ON watchlists FOR ALL
|
| 331 |
-
USING (auth.uid() = user_id);
|
| 332 |
-
|
| 333 |
-
-- Public read for stocks, prices, indicators
|
| 334 |
-
ALTER TABLE stocks ENABLE ROW LEVEL SECURITY;
|
| 335 |
-
CREATE POLICY "Stocks are viewable by everyone"
|
| 336 |
-
ON stocks FOR SELECT
|
| 337 |
-
USING (true);
|
| 338 |
-
|
| 339 |
-
ALTER TABLE stock_prices ENABLE ROW LEVEL SECURITY;
|
| 340 |
-
CREATE POLICY "Stock prices are viewable by everyone"
|
| 341 |
-
ON stock_prices FOR SELECT
|
| 342 |
-
USING (true);
|
| 343 |
-
```
|
| 344 |
-
|
| 345 |
-
#### ✅ 1.4 Database Functions & Triggers
|
| 346 |
-
```sql
|
| 347 |
-
-- Otomatik updated_at güncelleme
|
| 348 |
-
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
| 349 |
-
RETURNS TRIGGER AS $$
|
| 350 |
-
BEGIN
|
| 351 |
-
NEW.updated_at = NOW();
|
| 352 |
-
RETURN NEW;
|
| 353 |
-
END;
|
| 354 |
-
$$ LANGUAGE plpgsql;
|
| 355 |
-
|
| 356 |
-
CREATE TRIGGER update_stocks_updated_at
|
| 357 |
-
BEFORE UPDATE ON stocks
|
| 358 |
-
FOR EACH ROW
|
| 359 |
-
EXECUTE FUNCTION update_updated_at_column();
|
| 360 |
-
|
| 361 |
-
-- Latest price view (performans için)
|
| 362 |
-
CREATE OR REPLACE VIEW latest_stock_prices AS
|
| 363 |
-
SELECT DISTINCT ON (stock_id)
|
| 364 |
-
stock_id,
|
| 365 |
-
date,
|
| 366 |
-
close as last_price,
|
| 367 |
-
volume,
|
| 368 |
-
(close - LAG(close) OVER (PARTITION BY stock_id ORDER BY date)) / LAG(close) OVER (PARTITION BY stock_id ORDER BY date) * 100 as change_pct
|
| 369 |
-
FROM stock_prices
|
| 370 |
-
ORDER BY stock_id, date DESC;
|
| 371 |
-
|
| 372 |
-
-- Top gainers/losers view
|
| 373 |
-
CREATE OR REPLACE VIEW daily_movers AS
|
| 374 |
-
WITH latest_prices AS (
|
| 375 |
-
SELECT * FROM latest_stock_prices
|
| 376 |
-
)
|
| 377 |
-
SELECT
|
| 378 |
-
s.symbol,
|
| 379 |
-
s.name,
|
| 380 |
-
s.sector,
|
| 381 |
-
lp.last_price,
|
| 382 |
-
lp.change_pct,
|
| 383 |
-
lp.volume
|
| 384 |
-
FROM stocks s
|
| 385 |
-
JOIN latest_prices lp ON s.id = lp.stock_id
|
| 386 |
-
ORDER BY lp.change_pct DESC;
|
| 387 |
-
```
|
| 388 |
-
|
| 389 |
-
---
|
| 390 |
-
|
| 391 |
-
### PHASE 2: DATA MIGRATION (Gün 4-5)
|
| 392 |
-
**Süre:** 2 gün
|
| 393 |
-
**Öncelik:** KRITIK
|
| 394 |
-
|
| 395 |
-
#### ✅ 2.1 Migration Script Hazırlama
|
| 396 |
-
|
| 397 |
-
**Dosya:** `migration/sqlite_to_postgres.py`
|
| 398 |
-
|
| 399 |
-
```python
|
| 400 |
-
"""
|
| 401 |
-
SQLite → PostgreSQL Migration Script
|
| 402 |
-
Mevcut 17GB SQLite veritabanını Supabase PostgreSQL'e taşır
|
| 403 |
-
"""
|
| 404 |
-
|
| 405 |
-
import sqlite3
|
| 406 |
-
import pandas as pd
|
| 407 |
-
from supabase import create_client, Client
|
| 408 |
-
import os
|
| 409 |
-
from dotenv import load_dotenv
|
| 410 |
-
from tqdm import tqdm
|
| 411 |
-
import logging
|
| 412 |
-
from datetime import datetime
|
| 413 |
-
import time
|
| 414 |
-
|
| 415 |
-
# Setup
|
| 416 |
-
load_dotenv()
|
| 417 |
-
logging.basicConfig(level=logging.INFO)
|
| 418 |
-
logger = logging.getLogger(__name__)
|
| 419 |
-
|
| 420 |
-
# Supabase connection
|
| 421 |
-
SUPABASE_URL = os.getenv('SUPABASE_URL')
|
| 422 |
-
SUPABASE_KEY = os.getenv('SUPABASE_SERVICE_KEY') # Service role key for admin access
|
| 423 |
-
supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
|
| 424 |
-
|
| 425 |
-
# SQLite connection
|
| 426 |
-
SQLITE_DB = '/Volumes/LaCie/borsa_uygulamasi/data/stock_analysis.db'
|
| 427 |
-
sqlite_conn = sqlite3.connect(SQLITE_DB)
|
| 428 |
-
|
| 429 |
-
# Batch settings
|
| 430 |
-
BATCH_SIZE = 500 # Küçük batch'ler ile memory sorununu önle
|
| 431 |
-
|
| 432 |
-
def get_sqlite_tables():
|
| 433 |
-
"""SQLite veritabanındaki tüm tabloları listele"""
|
| 434 |
-
cursor = sqlite_conn.cursor()
|
| 435 |
-
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
|
| 436 |
-
tables = [row[0] for row in cursor.fetchall()]
|
| 437 |
-
logger.info(f"Found {len(tables)} tables in SQLite")
|
| 438 |
-
return tables
|
| 439 |
-
|
| 440 |
-
def migrate_stocks():
|
| 441 |
-
"""Stocks tablosunu migrate et"""
|
| 442 |
-
logger.info("Migrating stocks table...")
|
| 443 |
-
|
| 444 |
-
# SQLite'dan oku
|
| 445 |
-
query = """
|
| 446 |
-
SELECT DISTINCT
|
| 447 |
-
symbol,
|
| 448 |
-
name,
|
| 449 |
-
sector
|
| 450 |
-
FROM stocks
|
| 451 |
-
WHERE symbol IS NOT NULL
|
| 452 |
-
"""
|
| 453 |
-
df = pd.read_sql(query, sqlite_conn)
|
| 454 |
-
|
| 455 |
-
logger.info(f"Found {len(df)} unique stocks")
|
| 456 |
-
|
| 457 |
-
# Batch insert to Supabase
|
| 458 |
-
total_inserted = 0
|
| 459 |
-
for i in tqdm(range(0, len(df), BATCH_SIZE)):
|
| 460 |
-
batch = df[i:i+BATCH_SIZE]
|
| 461 |
-
records = batch.to_dict('records')
|
| 462 |
-
|
| 463 |
-
try:
|
| 464 |
-
result = supabase.table('stocks').upsert(
|
| 465 |
-
records,
|
| 466 |
-
on_conflict='symbol'
|
| 467 |
-
).execute()
|
| 468 |
-
total_inserted += len(records)
|
| 469 |
-
time.sleep(0.1) # Rate limiting
|
| 470 |
-
except Exception as e:
|
| 471 |
-
logger.error(f"Error inserting batch {i}: {e}")
|
| 472 |
-
continue
|
| 473 |
-
|
| 474 |
-
logger.info(f"Migrated {total_inserted} stocks")
|
| 475 |
-
return total_inserted
|
| 476 |
-
|
| 477 |
-
def migrate_stock_prices():
|
| 478 |
-
"""Stock prices tablosunu migrate et (en büyük tablo)"""
|
| 479 |
-
logger.info("Migrating stock prices...")
|
| 480 |
-
|
| 481 |
-
# Önce kaç kayıt var öğren
|
| 482 |
-
count_query = "SELECT COUNT(*) FROM stock_prices"
|
| 483 |
-
total_rows = pd.read_sql(count_query, sqlite_conn).iloc[0, 0]
|
| 484 |
-
logger.info(f"Total price records: {total_rows}")
|
| 485 |
-
|
| 486 |
-
# Hisse bazında migrate et (memory efficient)
|
| 487 |
-
stocks_query = "SELECT DISTINCT symbol FROM stocks"
|
| 488 |
-
stocks_df = pd.read_sql(stocks_query, sqlite_conn)
|
| 489 |
-
|
| 490 |
-
total_inserted = 0
|
| 491 |
-
for idx, row in tqdm(stocks_df.iterrows(), total=len(stocks_df)):
|
| 492 |
-
symbol = row['symbol']
|
| 493 |
-
|
| 494 |
-
# Get stock_id from Supabase
|
| 495 |
-
stock_result = supabase.table('stocks').select('id').eq('symbol', symbol).execute()
|
| 496 |
-
if not stock_result.data:
|
| 497 |
-
logger.warning(f"Stock {symbol} not found in Supabase")
|
| 498 |
-
continue
|
| 499 |
-
|
| 500 |
-
stock_id = stock_result.data[0]['id']
|
| 501 |
-
|
| 502 |
-
# SQLite'dan bu hisse için tüm fiyatları al
|
| 503 |
-
prices_query = f"""
|
| 504 |
-
SELECT
|
| 505 |
-
date,
|
| 506 |
-
open,
|
| 507 |
-
high,
|
| 508 |
-
low,
|
| 509 |
-
close,
|
| 510 |
-
volume,
|
| 511 |
-
adj_close
|
| 512 |
-
FROM stock_prices
|
| 513 |
-
WHERE symbol = '{symbol}'
|
| 514 |
-
ORDER BY date
|
| 515 |
-
"""
|
| 516 |
-
|
| 517 |
-
try:
|
| 518 |
-
prices_df = pd.read_sql(prices_query, sqlite_conn)
|
| 519 |
-
|
| 520 |
-
if len(prices_df) == 0:
|
| 521 |
-
continue
|
| 522 |
-
|
| 523 |
-
# Add stock_id
|
| 524 |
-
prices_df['stock_id'] = stock_id
|
| 525 |
-
|
| 526 |
-
# Batch insert
|
| 527 |
-
for i in range(0, len(prices_df), BATCH_SIZE):
|
| 528 |
-
batch = prices_df[i:i+BATCH_SIZE]
|
| 529 |
-
records = batch.to_dict('records')
|
| 530 |
-
|
| 531 |
-
supabase.table('stock_prices').upsert(
|
| 532 |
-
records,
|
| 533 |
-
on_conflict='stock_id,date'
|
| 534 |
-
).execute()
|
| 535 |
-
|
| 536 |
-
total_inserted += len(records)
|
| 537 |
-
|
| 538 |
-
time.sleep(0.1) # Rate limiting
|
| 539 |
-
|
| 540 |
-
except Exception as e:
|
| 541 |
-
logger.error(f"Error migrating prices for {symbol}: {e}")
|
| 542 |
-
continue
|
| 543 |
-
|
| 544 |
-
logger.info(f"Migrated {total_inserted} price records")
|
| 545 |
-
return total_inserted
|
| 546 |
-
|
| 547 |
-
def migrate_ml_predictions():
|
| 548 |
-
"""ML predictions tablosunu migrate et"""
|
| 549 |
-
logger.info("Migrating ML predictions...")
|
| 550 |
-
|
| 551 |
-
# Eğer predictions tablosu varsa
|
| 552 |
-
query = """
|
| 553 |
-
SELECT
|
| 554 |
-
stock_symbol,
|
| 555 |
-
model_type,
|
| 556 |
-
prediction_date,
|
| 557 |
-
predicted_price,
|
| 558 |
-
confidence
|
| 559 |
-
FROM ml_predictions
|
| 560 |
-
WHERE prediction_date >= date('now', '-30 days')
|
| 561 |
-
"""
|
| 562 |
-
|
| 563 |
-
try:
|
| 564 |
-
df = pd.read_sql(query, sqlite_conn)
|
| 565 |
-
logger.info(f"Found {len(df)} recent predictions")
|
| 566 |
-
|
| 567 |
-
# Get stock IDs
|
| 568 |
-
for idx, row in tqdm(df.iterrows(), total=len(df)):
|
| 569 |
-
stock_result = supabase.table('stocks').select('id').eq('symbol', row['stock_symbol']).execute()
|
| 570 |
-
if not stock_result.data:
|
| 571 |
-
continue
|
| 572 |
-
|
| 573 |
-
stock_id = stock_result.data[0]['id']
|
| 574 |
-
|
| 575 |
-
record = {
|
| 576 |
-
'stock_id': stock_id,
|
| 577 |
-
'model_type': row['model_type'],
|
| 578 |
-
'prediction_date': row['prediction_date'],
|
| 579 |
-
'predicted_price': float(row['predicted_price']) if row['predicted_price'] else None,
|
| 580 |
-
'confidence_score': float(row['confidence']) if row['confidence'] else None
|
| 581 |
-
}
|
| 582 |
-
|
| 583 |
-
supabase.table('ml_predictions').insert(record).execute()
|
| 584 |
-
|
| 585 |
-
except Exception as e:
|
| 586 |
-
logger.error(f"Error migrating predictions: {e}")
|
| 587 |
-
|
| 588 |
-
logger.info("ML predictions migration complete")
|
| 589 |
-
|
| 590 |
-
def verify_migration():
|
| 591 |
-
"""Migration doğrulaması"""
|
| 592 |
-
logger.info("Verifying migration...")
|
| 593 |
-
|
| 594 |
-
# Supabase'deki kayıt sayıları
|
| 595 |
-
stocks_count = supabase.table('stocks').select('id', count='exact').execute()
|
| 596 |
-
prices_count = supabase.table('stock_prices').select('id', count='exact').execute()
|
| 597 |
-
|
| 598 |
-
logger.info(f"Supabase stocks: {stocks_count.count}")
|
| 599 |
-
logger.info(f"Supabase prices: {prices_count.count}")
|
| 600 |
-
|
| 601 |
-
# SQLite'daki kayıt sayıları
|
| 602 |
-
sqlite_stocks = pd.read_sql("SELECT COUNT(DISTINCT symbol) FROM stocks", sqlite_conn).iloc[0, 0]
|
| 603 |
-
sqlite_prices = pd.read_sql("SELECT COUNT(*) FROM stock_prices", sqlite_conn).iloc[0, 0]
|
| 604 |
-
|
| 605 |
-
logger.info(f"SQLite stocks: {sqlite_stocks}")
|
| 606 |
-
logger.info(f"SQLite prices: {sqlite_prices}")
|
| 607 |
-
|
| 608 |
-
# Comparison
|
| 609 |
-
if stocks_count.count >= sqlite_stocks * 0.95: # 95% threshold
|
| 610 |
-
logger.info("✅ Stocks migration successful")
|
| 611 |
-
else:
|
| 612 |
-
logger.warning("⚠️ Stocks migration incomplete")
|
| 613 |
-
|
| 614 |
-
if prices_count.count >= sqlite_prices * 0.90: # 90% threshold
|
| 615 |
-
logger.info("✅ Prices migration successful")
|
| 616 |
-
else:
|
| 617 |
-
logger.warning("⚠️ Prices migration incomplete")
|
| 618 |
-
|
| 619 |
-
def main():
|
| 620 |
-
"""Ana migration workflow"""
|
| 621 |
-
start_time = time.time()
|
| 622 |
-
|
| 623 |
-
logger.info("Starting migration process...")
|
| 624 |
-
logger.info(f"SQLite DB: {SQLITE_DB}")
|
| 625 |
-
logger.info(f"Supabase URL: {SUPABASE_URL}")
|
| 626 |
-
|
| 627 |
-
# Step 1: Migrate stocks
|
| 628 |
-
migrate_stocks()
|
| 629 |
-
|
| 630 |
-
# Step 2: Migrate prices (en uzun sürecek)
|
| 631 |
-
migrate_stock_prices()
|
| 632 |
-
|
| 633 |
-
# Step 3: Migrate ML predictions
|
| 634 |
-
migrate_ml_predictions()
|
| 635 |
-
|
| 636 |
-
# Step 4: Verify
|
| 637 |
-
verify_migration()
|
| 638 |
-
|
| 639 |
-
elapsed = time.time() - start_time
|
| 640 |
-
logger.info(f"Migration completed in {elapsed/60:.2f} minutes")
|
| 641 |
-
|
| 642 |
-
sqlite_conn.close()
|
| 643 |
-
|
| 644 |
-
if __name__ == '__main__':
|
| 645 |
-
main()
|
| 646 |
-
```
|
| 647 |
-
|
| 648 |
-
#### ✅ 2.2 Migration Execution
|
| 649 |
-
|
| 650 |
-
```bash
|
| 651 |
-
# .env dosyası oluştur
|
| 652 |
-
cat > migration/.env << EOF
|
| 653 |
-
SUPABASE_URL=https://your-project.supabase.co
|
| 654 |
-
SUPABASE_SERVICE_KEY=your-service-role-key
|
| 655 |
-
EOF
|
| 656 |
-
|
| 657 |
-
# Migration'ı çalıştır
|
| 658 |
-
cd migration
|
| 659 |
-
python sqlite_to_postgres.py
|
| 660 |
-
|
| 661 |
-
# Progress monitoring
|
| 662 |
-
tail -f migration.log
|
| 663 |
-
```
|
| 664 |
-
|
| 665 |
-
---
|
| 666 |
-
|
| 667 |
-
### PHASE 3: NEXT.JS SETUP (Gün 6-8)
|
| 668 |
-
**Süre:** 3 gün
|
| 669 |
-
**Öncelik:** YÜKSEK
|
| 670 |
-
|
| 671 |
-
#### ✅ 3.1 Next.js Projesi Oluştur
|
| 672 |
-
|
| 673 |
-
```bash
|
| 674 |
-
# Next.js 14 ile yeni proje
|
| 675 |
-
npx create-next-app@latest borsa-app --typescript --tailwind --app --no-src
|
| 676 |
-
cd borsa-app
|
| 677 |
-
|
| 678 |
-
# Gerekli paketleri yükle
|
| 679 |
-
npm install @supabase/supabase-js @supabase/auth-helpers-nextjs
|
| 680 |
-
npm install @tanstack/react-query
|
| 681 |
-
npm install recharts lucide-react
|
| 682 |
-
npm install date-fns
|
| 683 |
-
npm install zustand
|
| 684 |
-
npm install @radix-ui/react-dropdown-menu
|
| 685 |
-
npm install @radix-ui/react-dialog
|
| 686 |
-
npm install @radix-ui/react-select
|
| 687 |
-
npm install class-variance-authority clsx tailwind-merge
|
| 688 |
-
|
| 689 |
-
# Dev dependencies
|
| 690 |
-
npm install -D @types/node
|
| 691 |
-
```
|
| 692 |
-
|
| 693 |
-
#### ✅ 3.2 Proje Yapısı
|
| 694 |
-
|
| 695 |
-
```
|
| 696 |
-
borsa-app/
|
| 697 |
-
├── app/
|
| 698 |
-
│ ├── layout.tsx # Root layout
|
| 699 |
-
│ ├── page.tsx # Ana sayfa (dashboard)
|
| 700 |
-
│ ├── globals.css
|
| 701 |
-
│ │
|
| 702 |
-
│ ├── (dashboard)/ # Dashboard route group
|
| 703 |
-
│ │ ├── layout.tsx
|
| 704 |
-
│ │ ├── stocks/
|
| 705 |
-
│ │ │ ├── page.tsx # Hisse listesi
|
| 706 |
-
│ │ │ └── [symbol]/
|
| 707 |
-
│ │ │ ├── page.tsx # Hisse detay
|
| 708 |
-
│ │ │ └── loading.tsx
|
| 709 |
-
│ │ ├── ml-predictions/
|
| 710 |
-
│ │ │ └── page.tsx
|
| 711 |
-
│ │ ├── portfolio/
|
| 712 |
-
│ │ │ └── page.tsx
|
| 713 |
-
│ │ └── news/
|
| 714 |
-
│ │ └── page.tsx
|
| 715 |
-
│ │
|
| 716 |
-
│ ├── api/ # API routes
|
| 717 |
-
│ │ ├── stocks/
|
| 718 |
-
│ │ │ ├── route.ts # GET /api/stocks
|
| 719 |
-
│ │ │ └── [symbol]/
|
| 720 |
-
│ │ │ ├── route.ts # GET /api/stocks/:symbol
|
| 721 |
-
│ │ │ └── prices/
|
| 722 |
-
│ │ │ └── route.ts # GET /api/stocks/:symbol/prices
|
| 723 |
-
│ │ ├── predictions/
|
| 724 |
-
│ │ │ └── route.ts
|
| 725 |
-
│ │ ├── news/
|
| 726 |
-
│ │ │ └── route.ts
|
| 727 |
-
│ │ └── portfolio/
|
| 728 |
-
│ │ └── route.ts
|
| 729 |
-
│ │
|
| 730 |
-
│ └── auth/ # Auth pages
|
| 731 |
-
│ ├── login/
|
| 732 |
-
│ │ └── page.tsx
|
| 733 |
-
│ └── callback/
|
| 734 |
-
│ └── route.ts
|
| 735 |
-
│
|
| 736 |
-
├── components/
|
| 737 |
-
│ ├── ui/ # Shadcn UI components
|
| 738 |
-
│ │ ├── button.tsx
|
| 739 |
-
│ │ ├── card.tsx
|
| 740 |
-
│ │ ├── table.tsx
|
| 741 |
-
│ │ ├── select.tsx
|
| 742 |
-
│ │ └── dialog.tsx
|
| 743 |
-
│ │
|
| 744 |
-
│ ├── charts/ # Chart components
|
| 745 |
-
│ │ ├── stock-chart.tsx
|
| 746 |
-
│ │ ├── candlestick-chart.tsx
|
| 747 |
-
│ │ ├── volume-chart.tsx
|
| 748 |
-
│ │ └── indicator-chart.tsx
|
| 749 |
-
│ │
|
| 750 |
-
│ ├── stocks/ # Stock components
|
| 751 |
-
│ │ ├── stock-card.tsx
|
| 752 |
-
│ │ ├── stock-table.tsx
|
| 753 |
-
│ │ ├── stock-search.tsx
|
| 754 |
-
│ │ └── technical-indicators.tsx
|
| 755 |
-
│ │
|
| 756 |
-
│ ├── layout/ # Layout components
|
| 757 |
-
│ │ ├── navbar.tsx
|
| 758 |
-
│ │ ├── sidebar.tsx
|
| 759 |
-
│ │ └── footer.tsx
|
| 760 |
-
│ │
|
| 761 |
-
│ └── providers/
|
| 762 |
-
│ ├── query-provider.tsx
|
| 763 |
-
│ └── supabase-provider.tsx
|
| 764 |
-
│
|
| 765 |
-
├── lib/
|
| 766 |
-
│ ├── supabase/
|
| 767 |
-
│ │ ├── client.ts # Client-side Supabase
|
| 768 |
-
│ │ ├── server.ts # Server-side Supabase
|
| 769 |
-
│ │ └── middleware.ts
|
| 770 |
-
│ │
|
| 771 |
-
│ ├── api/
|
| 772 |
-
│ │ ├── stocks.ts # Stock API functions
|
| 773 |
-
│ │ ├── predictions.ts
|
| 774 |
-
│ │ └── portfolio.ts
|
| 775 |
-
│ │
|
| 776 |
-
│ ├── hooks/
|
| 777 |
-
│ │ ├── use-stock-data.ts
|
| 778 |
-
│ │ ├── use-predictions.ts
|
| 779 |
-
│ │ └── use-portfolio.ts
|
| 780 |
-
│ │
|
| 781 |
-
│ ├── store/
|
| 782 |
-
│ │ └── app-store.ts # Zustand store
|
| 783 |
-
│ │
|
| 784 |
-
│ └── utils/
|
| 785 |
-
│ ├── cn.ts # classNames utility
|
| 786 |
-
│ ├── format.ts # Formatters
|
| 787 |
-
│ └── calculations.ts # Technical calculations
|
| 788 |
-
│
|
| 789 |
-
├── types/
|
| 790 |
-
│ ├── stock.ts
|
| 791 |
-
│ ├── prediction.ts
|
| 792 |
-
│ └── portfolio.ts
|
| 793 |
-
│
|
| 794 |
-
├── .env.local
|
| 795 |
-
├── .env.example
|
| 796 |
-
├── next.config.js
|
| 797 |
-
├── tailwind.config.ts
|
| 798 |
-
├── tsconfig.json
|
| 799 |
-
└── package.json
|
| 800 |
-
```
|
| 801 |
-
|
| 802 |
-
---
|
| 803 |
-
|
| 804 |
-
### PHASE 4: CORE COMPONENTS (Gün 9-12)
|
| 805 |
-
**Süre:** 4 gün
|
| 806 |
-
**Öncelik:** YÜKSEK
|
| 807 |
-
|
| 808 |
-
#### ✅ 4.1 Supabase Client Setup
|
| 809 |
-
|
| 810 |
-
**Dosya:** `lib/supabase/client.ts`
|
| 811 |
-
```typescript
|
| 812 |
-
import { createBrowserClient } from '@supabase/ssr'
|
| 813 |
-
|
| 814 |
-
export function createClient() {
|
| 815 |
-
return createBrowserClient(
|
| 816 |
-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
| 817 |
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
|
| 818 |
-
)
|
| 819 |
-
}
|
| 820 |
-
```
|
| 821 |
-
|
| 822 |
-
**Dosya:** `lib/supabase/server.ts`
|
| 823 |
-
```typescript
|
| 824 |
-
import { createServerClient, type CookieOptions } from '@supabase/ssr'
|
| 825 |
-
import { cookies } from 'next/headers'
|
| 826 |
-
|
| 827 |
-
export async function createClient() {
|
| 828 |
-
const cookieStore = await cookies()
|
| 829 |
-
|
| 830 |
-
return createServerClient(
|
| 831 |
-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
| 832 |
-
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
| 833 |
-
{
|
| 834 |
-
cookies: {
|
| 835 |
-
get(name: string) {
|
| 836 |
-
return cookieStore.get(name)?.value
|
| 837 |
-
},
|
| 838 |
-
},
|
| 839 |
-
}
|
| 840 |
-
)
|
| 841 |
-
}
|
| 842 |
-
```
|
| 843 |
-
|
| 844 |
-
#### ✅ 4.2 Type Definitions
|
| 845 |
-
|
| 846 |
-
**Dosya:** `types/stock.ts`
|
| 847 |
-
```typescript
|
| 848 |
-
export interface Stock {
|
| 849 |
-
id: string
|
| 850 |
-
symbol: string
|
| 851 |
-
name: string
|
| 852 |
-
sector: string | null
|
| 853 |
-
market_cap: number | null
|
| 854 |
-
created_at: string
|
| 855 |
-
updated_at: string
|
| 856 |
-
}
|
| 857 |
-
|
| 858 |
-
export interface StockPrice {
|
| 859 |
-
id: number
|
| 860 |
-
stock_id: string
|
| 861 |
-
date: string
|
| 862 |
-
open: number
|
| 863 |
-
high: number
|
| 864 |
-
low: number
|
| 865 |
-
close: number
|
| 866 |
-
volume: number
|
| 867 |
-
adj_close: number
|
| 868 |
-
}
|
| 869 |
-
|
| 870 |
-
export interface TechnicalIndicators {
|
| 871 |
-
id: string
|
| 872 |
-
stock_id: string
|
| 873 |
-
date: string
|
| 874 |
-
rsi_14: number
|
| 875 |
-
macd: number
|
| 876 |
-
macd_signal: number
|
| 877 |
-
macd_histogram: number
|
| 878 |
-
sma_20: number
|
| 879 |
-
sma_50: number
|
| 880 |
-
sma_200: number
|
| 881 |
-
ema_12: number
|
| 882 |
-
ema_26: number
|
| 883 |
-
bollinger_upper: number
|
| 884 |
-
bollinger_middle: number
|
| 885 |
-
bollinger_lower: number
|
| 886 |
-
stochastic_k: number
|
| 887 |
-
stochastic_d: number
|
| 888 |
-
atr_14: number
|
| 889 |
-
williams_r: number
|
| 890 |
-
cci_20: number
|
| 891 |
-
created_at: string
|
| 892 |
-
}
|
| 893 |
-
|
| 894 |
-
export interface MLPrediction {
|
| 895 |
-
id: string
|
| 896 |
-
stock_id: string
|
| 897 |
-
model_type: 'RandomForest' | 'XGBoost' | 'LightGBM' | 'Ensemble'
|
| 898 |
-
prediction_date: string
|
| 899 |
-
predicted_price: number
|
| 900 |
-
predicted_change_pct: number
|
| 901 |
-
confidence_score: number
|
| 902 |
-
lower_bound: number
|
| 903 |
-
upper_bound: number
|
| 904 |
-
features: Record<string, any>
|
| 905 |
-
model_version: string
|
| 906 |
-
created_at: string
|
| 907 |
-
}
|
| 908 |
-
```
|
| 909 |
-
|
| 910 |
-
#### ✅ 4.3 API Functions
|
| 911 |
-
|
| 912 |
-
**Dosya:** `lib/api/stocks.ts`
|
| 913 |
-
```typescript
|
| 914 |
-
import { createClient } from '@/lib/supabase/client'
|
| 915 |
-
import { Stock, StockPrice, TechnicalIndicators } from '@/types/stock'
|
| 916 |
-
|
| 917 |
-
export async function getStocks(sector?: string): Promise<Stock[]> {
|
| 918 |
-
const supabase = createClient()
|
| 919 |
-
|
| 920 |
-
let query = supabase
|
| 921 |
-
.from('stocks')
|
| 922 |
-
.select('*')
|
| 923 |
-
.order('symbol')
|
| 924 |
-
|
| 925 |
-
if (sector) {
|
| 926 |
-
query = query.eq('sector', sector)
|
| 927 |
-
}
|
| 928 |
-
|
| 929 |
-
const { data, error } = await query
|
| 930 |
-
|
| 931 |
-
if (error) throw error
|
| 932 |
-
return data || []
|
| 933 |
-
}
|
| 934 |
-
|
| 935 |
-
export async function getStock(symbol: string): Promise<Stock | null> {
|
| 936 |
-
const supabase = createClient()
|
| 937 |
-
|
| 938 |
-
const { data, error } = await supabase
|
| 939 |
-
.from('stocks')
|
| 940 |
-
.select('*')
|
| 941 |
-
.eq('symbol', symbol)
|
| 942 |
-
.single()
|
| 943 |
-
|
| 944 |
-
if (error) throw error
|
| 945 |
-
return data
|
| 946 |
-
}
|
| 947 |
-
|
| 948 |
-
export async function getStockPrices(
|
| 949 |
-
stockId: string,
|
| 950 |
-
fromDate?: string,
|
| 951 |
-
toDate?: string
|
| 952 |
-
): Promise<StockPrice[]> {
|
| 953 |
-
const supabase = createClient()
|
| 954 |
-
|
| 955 |
-
let query = supabase
|
| 956 |
-
.from('stock_prices')
|
| 957 |
-
.select('*')
|
| 958 |
-
.eq('stock_id', stockId)
|
| 959 |
-
.order('date', { ascending: false })
|
| 960 |
-
|
| 961 |
-
if (fromDate) query = query.gte('date', fromDate)
|
| 962 |
-
if (toDate) query = query.lte('date', toDate)
|
| 963 |
-
|
| 964 |
-
const { data, error } = await query
|
| 965 |
-
|
| 966 |
-
if (error) throw error
|
| 967 |
-
return data || []
|
| 968 |
-
}
|
| 969 |
-
|
| 970 |
-
export async function getTechnicalIndicators(
|
| 971 |
-
stockId: string,
|
| 972 |
-
date?: string
|
| 973 |
-
): Promise<TechnicalIndicators | null> {
|
| 974 |
-
const supabase = createClient()
|
| 975 |
-
|
| 976 |
-
let query = supabase
|
| 977 |
-
.from('technical_indicators')
|
| 978 |
-
.select('*')
|
| 979 |
-
.eq('stock_id', stockId)
|
| 980 |
-
.order('date', { ascending: false })
|
| 981 |
-
.limit(1)
|
| 982 |
-
|
| 983 |
-
if (date) {
|
| 984 |
-
query = query.eq('date', date)
|
| 985 |
-
}
|
| 986 |
-
|
| 987 |
-
const { data, error } = await query
|
| 988 |
-
|
| 989 |
-
if (error) throw error
|
| 990 |
-
return data?.[0] || null
|
| 991 |
-
}
|
| 992 |
-
```
|
| 993 |
-
|
| 994 |
-
#### ✅ 4.4 React Hooks
|
| 995 |
-
|
| 996 |
-
**Dosya:** `lib/hooks/use-stock-data.ts`
|
| 997 |
-
```typescript
|
| 998 |
-
import { useQuery } from '@tanstack/react-query'
|
| 999 |
-
import { getStock, getStockPrices, getTechnicalIndicators } from '@/lib/api/stocks'
|
| 1000 |
-
|
| 1001 |
-
export function useStock(symbol: string) {
|
| 1002 |
-
return useQuery({
|
| 1003 |
-
queryKey: ['stock', symbol],
|
| 1004 |
-
queryFn: () => getStock(symbol),
|
| 1005 |
-
staleTime: 60000, // 1 minute
|
| 1006 |
-
})
|
| 1007 |
-
}
|
| 1008 |
-
|
| 1009 |
-
export function useStockPrices(stockId: string, period: string = '1M') {
|
| 1010 |
-
const fromDate = getFromDate(period)
|
| 1011 |
-
|
| 1012 |
-
return useQuery({
|
| 1013 |
-
queryKey: ['stockPrices', stockId, period],
|
| 1014 |
-
queryFn: () => getStockPrices(stockId, fromDate),
|
| 1015 |
-
staleTime: 60000,
|
| 1016 |
-
})
|
| 1017 |
-
}
|
| 1018 |
-
|
| 1019 |
-
export function useTechnicalIndicators(stockId: string) {
|
| 1020 |
-
return useQuery({
|
| 1021 |
-
queryKey: ['technicalIndicators', stockId],
|
| 1022 |
-
queryFn: () => getTechnicalIndicators(stockId),
|
| 1023 |
-
staleTime: 300000, // 5 minutes
|
| 1024 |
-
})
|
| 1025 |
-
}
|
| 1026 |
-
|
| 1027 |
-
function getFromDate(period: string): string {
|
| 1028 |
-
const now = new Date()
|
| 1029 |
-
const date = new Date()
|
| 1030 |
-
|
| 1031 |
-
switch (period) {
|
| 1032 |
-
case '1D': date.setDate(now.getDate() - 1); break
|
| 1033 |
-
case '1W': date.setDate(now.getDate() - 7); break
|
| 1034 |
-
case '1M': date.setMonth(now.getMonth() - 1); break
|
| 1035 |
-
case '3M': date.setMonth(now.getMonth() - 3); break
|
| 1036 |
-
case '6M': date.setMonth(now.getMonth() - 6); break
|
| 1037 |
-
case '1Y': date.setFullYear(now.getFullYear() - 1); break
|
| 1038 |
-
case '5Y': date.setFullYear(now.getFullYear() - 5); break
|
| 1039 |
-
default: date.setMonth(now.getMonth() - 1)
|
| 1040 |
-
}
|
| 1041 |
-
|
| 1042 |
-
return date.toISOString().split('T')[0]
|
| 1043 |
-
}
|
| 1044 |
-
```
|
| 1045 |
-
|
| 1046 |
-
#### ✅ 4.5 Stock Chart Component
|
| 1047 |
-
|
| 1048 |
-
**Dosya:** `components/charts/stock-chart.tsx`
|
| 1049 |
-
```typescript
|
| 1050 |
-
'use client'
|
| 1051 |
-
|
| 1052 |
-
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'
|
| 1053 |
-
import { useStockPrices } from '@/lib/hooks/use-stock-data'
|
| 1054 |
-
import { format } from 'date-fns'
|
| 1055 |
-
|
| 1056 |
-
interface StockChartProps {
|
| 1057 |
-
stockId: string
|
| 1058 |
-
period?: string
|
| 1059 |
-
}
|
| 1060 |
-
|
| 1061 |
-
export function StockChart({ stockId, period = '1M' }: StockChartProps) {
|
| 1062 |
-
const { data: prices, isLoading } = useStockPrices(stockId, period)
|
| 1063 |
-
|
| 1064 |
-
if (isLoading) {
|
| 1065 |
-
return (
|
| 1066 |
-
<div className="h-[400px] flex items-center justify-center">
|
| 1067 |
-
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600" />
|
| 1068 |
-
</div>
|
| 1069 |
-
)
|
| 1070 |
-
}
|
| 1071 |
-
|
| 1072 |
-
if (!prices || prices.length === 0) {
|
| 1073 |
-
return (
|
| 1074 |
-
<div className="h-[400px] flex items-center justify-center text-gray-500">
|
| 1075 |
-
Veri bulunamadı
|
| 1076 |
-
</div>
|
| 1077 |
-
)
|
| 1078 |
-
}
|
| 1079 |
-
|
| 1080 |
-
const chartData = prices
|
| 1081 |
-
.slice()
|
| 1082 |
-
.reverse()
|
| 1083 |
-
.map(price => ({
|
| 1084 |
-
date: format(new Date(price.date), 'dd MMM'),
|
| 1085 |
-
price: price.close,
|
| 1086 |
-
volume: price.volume
|
| 1087 |
-
}))
|
| 1088 |
-
|
| 1089 |
-
return (
|
| 1090 |
-
<ResponsiveContainer width="100%" height={400}>
|
| 1091 |
-
<LineChart data={chartData}>
|
| 1092 |
-
<CartesianGrid strokeDasharray="3 3" />
|
| 1093 |
-
<XAxis dataKey="date" />
|
| 1094 |
-
<YAxis yAxisId="left" />
|
| 1095 |
-
<YAxis yAxisId="right" orientation="right" />
|
| 1096 |
-
<Tooltip />
|
| 1097 |
-
<Legend />
|
| 1098 |
-
<Line
|
| 1099 |
-
yAxisId="left"
|
| 1100 |
-
type="monotone"
|
| 1101 |
-
dataKey="price"
|
| 1102 |
-
stroke="#3b82f6"
|
| 1103 |
-
strokeWidth={2}
|
| 1104 |
-
dot={false}
|
| 1105 |
-
name="Fiyat (TL)"
|
| 1106 |
-
/>
|
| 1107 |
-
</LineChart>
|
| 1108 |
-
</ResponsiveContainer>
|
| 1109 |
-
)
|
| 1110 |
-
}
|
| 1111 |
-
```
|
| 1112 |
-
|
| 1113 |
-
---
|
| 1114 |
-
|
| 1115 |
-
### PHASE 5: HUGGING FACE INTEGRATION (Gün 13-15)
|
| 1116 |
-
**Süre:** 3 gün
|
| 1117 |
-
**Öncelik:** ORTA
|
| 1118 |
-
|
| 1119 |
-
#### ✅ 5.1 ML Model Migration Plan
|
| 1120 |
-
|
| 1121 |
-
**Mevcut Modeller:**
|
| 1122 |
-
- RandomForest
|
| 1123 |
-
- XGBoost
|
| 1124 |
-
- LightGBM
|
| 1125 |
-
- Ensemble
|
| 1126 |
-
|
| 1127 |
-
**HuggingFace Stratejisi:**
|
| 1128 |
-
|
| 1129 |
-
**Seçenek 1: Custom Model Deploy (Önerilen)**
|
| 1130 |
-
```python
|
| 1131 |
-
# Local'de modelinizi kaydedin
|
| 1132 |
-
import joblib
|
| 1133 |
-
from transformers import pipeline
|
| 1134 |
-
|
| 1135 |
-
# Mevcut model
|
| 1136 |
-
model = train_your_model() # XGBoost, RandomForest, etc.
|
| 1137 |
-
|
| 1138 |
-
# HuggingFace formatına çevir
|
| 1139 |
-
joblib.dump(model, 'stock_predictor.joblib')
|
| 1140 |
-
|
| 1141 |
-
# HuggingFace'e push
|
| 1142 |
-
from huggingface_hub import HfApi
|
| 1143 |
-
api = HfApi()
|
| 1144 |
-
api.upload_file(
|
| 1145 |
-
path_or_fileobj="stock_predictor.joblib",
|
| 1146 |
-
path_in_repo="model.joblib",
|
| 1147 |
-
repo_id="your-username/stock-price-predictor",
|
| 1148 |
-
repo_type="model",
|
| 1149 |
-
)
|
| 1150 |
-
```
|
| 1151 |
-
|
| 1152 |
-
**Seçenek 2: Time Series Models (Alternatif)**
|
| 1153 |
-
```python
|
| 1154 |
-
# Transformer tabanlı time series model
|
| 1155 |
-
from transformers import AutoModelForSequenceClassification, Trainer
|
| 1156 |
-
|
| 1157 |
-
# Hugging Face'ten hazır model
|
| 1158 |
-
model_name = "huggingface/timeseries-transformer"
|
| 1159 |
-
```
|
| 1160 |
-
|
| 1161 |
-
#### ✅ 5.2 Inference API Integration
|
| 1162 |
-
|
| 1163 |
-
**Dosya:** `lib/api/predictions.ts`
|
| 1164 |
-
```typescript
|
| 1165 |
-
const HF_API_URL = 'https://api-inference.huggingface.co/models'
|
| 1166 |
-
const HF_TOKEN = process.env.HF_TOKEN
|
| 1167 |
-
|
| 1168 |
-
export async function getPrediction(stockData: number[]): Promise<PredictionResult> {
|
| 1169 |
-
const response = await fetch(
|
| 1170 |
-
`${HF_API_URL}/your-username/stock-price-predictor`,
|
| 1171 |
-
{
|
| 1172 |
-
method: 'POST',
|
| 1173 |
-
headers: {
|
| 1174 |
-
'Authorization': `Bearer ${HF_TOKEN}`,
|
| 1175 |
-
'Content-Type': 'application/json',
|
| 1176 |
-
},
|
| 1177 |
-
body: JSON.stringify({
|
| 1178 |
-
inputs: stockData,
|
| 1179 |
-
}),
|
| 1180 |
-
}
|
| 1181 |
-
)
|
| 1182 |
-
|
| 1183 |
-
if (!response.ok) {
|
| 1184 |
-
throw new Error('Prediction failed')
|
| 1185 |
-
}
|
| 1186 |
-
|
| 1187 |
-
return response.json()
|
| 1188 |
-
}
|
| 1189 |
-
```
|
| 1190 |
-
|
| 1191 |
-
---
|
| 1192 |
-
|
| 1193 |
-
### PHASE 6: DEPLOYMENT (Gün 16-17)
|
| 1194 |
-
**Süre:** 2 gün
|
| 1195 |
-
**Öncelik:** YÜKSEK
|
| 1196 |
-
|
| 1197 |
-
#### ✅ 6.1 Environment Variables
|
| 1198 |
-
|
| 1199 |
-
**Dosya:** `.env.local`
|
| 1200 |
-
```bash
|
| 1201 |
-
# Supabase
|
| 1202 |
-
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
|
| 1203 |
-
NEXT_PUBLIC_SUPABASE_ANON_KEY=xxx
|
| 1204 |
-
SUPABASE_SERVICE_ROLE_KEY=xxx
|
| 1205 |
-
|
| 1206 |
-
# HuggingFace
|
| 1207 |
-
HF_TOKEN=hf_xxx
|
| 1208 |
-
HF_MODEL_ID=your-username/stock-predictor
|
| 1209 |
-
|
| 1210 |
-
# Optional
|
| 1211 |
-
YAHOO_FINANCE_API_KEY=xxx
|
| 1212 |
-
NEWS_API_KEY=xxx
|
| 1213 |
-
```
|
| 1214 |
-
|
| 1215 |
-
#### ✅ 6.2 Vercel Deployment
|
| 1216 |
-
|
| 1217 |
-
```bash
|
| 1218 |
-
# Vercel CLI ile deploy
|
| 1219 |
-
npm install -g vercel
|
| 1220 |
-
vercel login
|
| 1221 |
-
|
| 1222 |
-
# İlk deploy
|
| 1223 |
-
vercel
|
| 1224 |
-
|
| 1225 |
-
# Production deploy
|
| 1226 |
-
vercel --prod
|
| 1227 |
-
|
| 1228 |
-
# Environment variables'ı Vercel'e ekle
|
| 1229 |
-
vercel env add NEXT_PUBLIC_SUPABASE_URL
|
| 1230 |
-
vercel env add NEXT_PUBLIC_SUPABASE_ANON_KEY
|
| 1231 |
-
vercel env add HF_TOKEN
|
| 1232 |
-
```
|
| 1233 |
-
|
| 1234 |
-
#### ✅ 6.3 Vercel Config
|
| 1235 |
-
|
| 1236 |
-
**Dosya:** `vercel.json`
|
| 1237 |
-
```json
|
| 1238 |
-
{
|
| 1239 |
-
"framework": "nextjs",
|
| 1240 |
-
"buildCommand": "npm run build",
|
| 1241 |
-
"devCommand": "npm run dev",
|
| 1242 |
-
"installCommand": "npm install",
|
| 1243 |
-
"env": {
|
| 1244 |
-
"NEXT_PUBLIC_SUPABASE_URL": "@supabase-url",
|
| 1245 |
-
"NEXT_PUBLIC_SUPABASE_ANON_KEY": "@supabase-anon-key"
|
| 1246 |
-
},
|
| 1247 |
-
"functions": {
|
| 1248 |
-
"app/api/**/*.ts": {
|
| 1249 |
-
"maxDuration": 30
|
| 1250 |
-
}
|
| 1251 |
-
},
|
| 1252 |
-
"crons": [
|
| 1253 |
-
{
|
| 1254 |
-
"path": "/api/cron/update-prices",
|
| 1255 |
-
"schedule": "0 */6 * * *"
|
| 1256 |
-
}
|
| 1257 |
-
]
|
| 1258 |
-
}
|
| 1259 |
-
```
|
| 1260 |
-
|
| 1261 |
-
---
|
| 1262 |
-
|
| 1263 |
-
### PHASE 7: TESTING & OPTIMIZATION (Gün 18-20)
|
| 1264 |
-
**Süre:** 3 gün
|
| 1265 |
-
**Öncelik:** ORTA
|
| 1266 |
-
|
| 1267 |
-
#### ✅ 7.1 Performance Testing
|
| 1268 |
-
- [ ] Lighthouse audit (target: 90+ score)
|
| 1269 |
-
- [ ] Load testing (k6 veya Artillery)
|
| 1270 |
-
- [ ] Database query optimization
|
| 1271 |
-
- [ ] Image optimization
|
| 1272 |
-
- [ ] Code splitting check
|
| 1273 |
-
|
| 1274 |
-
#### ✅ 7.2 Features Testing
|
| 1275 |
-
- [ ] Stock listing
|
| 1276 |
-
- [ ] Price charts
|
| 1277 |
-
- [ ] Technical indicators
|
| 1278 |
-
- [ ] ML predictions
|
| 1279 |
-
- [ ] Portfolio management
|
| 1280 |
-
- [ ] User authentication
|
| 1281 |
-
|
| 1282 |
-
---
|
| 1283 |
-
|
| 1284 |
-
## 📊 TIMELINE ÖZET
|
| 1285 |
-
|
| 1286 |
-
| Phase | Görev | Süre | Başlangıç | Bitiş |
|
| 1287 |
-
|-------|-------|------|-----------|-------|
|
| 1288 |
-
| 0 | Hazırlık | 1 gün | Gün 1 | Gün 1 |
|
| 1289 |
-
| 1 | Supabase Setup | 2 gün | Gün 2 | Gün 3 |
|
| 1290 |
-
| 2 | Data Migration | 2 gün | Gün 4 | Gün 5 |
|
| 1291 |
-
| 3 | Next.js Setup | 3 gün | Gün 6 | Gün 8 |
|
| 1292 |
-
| 4 | Core Components | 4 gün | Gün 9 | Gün 12 |
|
| 1293 |
-
| 5 | HuggingFace Integration | 3 gün | Gün 13 | Gün 15 |
|
| 1294 |
-
| 6 | Deployment | 2 gün | Gün 16 | Gün 17 |
|
| 1295 |
-
| 7 | Testing | 3 gün | Gün 18 | Gün 20 |
|
| 1296 |
-
|
| 1297 |
-
**Toplam Süre: 20 iş günü (4 hafta)**
|
| 1298 |
-
|
| 1299 |
-
---
|
| 1300 |
-
|
| 1301 |
-
## 💰 MALIYET ANALİZİ
|
| 1302 |
-
|
| 1303 |
-
### Geliştirme Maliyetleri
|
| 1304 |
-
- **Geliştirme Süresi:** 20 gün
|
| 1305 |
-
- **Maliyetler:** $0 (kendi geliştirmeniz)
|
| 1306 |
-
|
| 1307 |
-
### Hosting Maliyetleri (Aylık)
|
| 1308 |
-
|
| 1309 |
-
**Free Tier (Başlangıç):**
|
| 1310 |
-
- Vercel: $0 (100GB bandwidth, 100GB-hours)
|
| 1311 |
-
- Supabase: $0 (500MB DB, 2GB storage, 50GB bandwidth)
|
| 1312 |
-
- HuggingFace: $0 (Inference API - rate limited)
|
| 1313 |
-
- **Toplam: $0/ay**
|
| 1314 |
-
|
| 1315 |
-
**Pro Tier (Büyüdükçe):**
|
| 1316 |
-
- Vercel Pro: $20/ay
|
| 1317 |
-
- Supabase Pro: $25/ay (8GB DB, 100GB storage)
|
| 1318 |
-
- HuggingFace Pro: $9/ay (unlimited inference)
|
| 1319 |
-
- **Toplam: $54/ay**
|
| 1320 |
-
|
| 1321 |
-
**Karşılaştırma:**
|
| 1322 |
-
- Streamlit Cloud Pro: $200+/ay
|
| 1323 |
-
- **Tasarruf: $146/ay = $1,752/yıl**
|
| 1324 |
-
|
| 1325 |
-
---
|
| 1326 |
-
|
| 1327 |
-
## 🎯 BAŞARI KRİTERLERİ
|
| 1328 |
-
|
| 1329 |
-
### Performans Hedefleri
|
| 1330 |
-
- ✅ İlk sayfa yüklenme: < 1s
|
| 1331 |
-
- ✅ Sayfa geçişleri: < 200ms
|
| 1332 |
-
- ✅ API yanıt süresi: < 500ms
|
| 1333 |
-
- ✅ Grafik render: < 300ms
|
| 1334 |
-
- ✅ ML tahmin: < 5s
|
| 1335 |
-
|
| 1336 |
-
### Kullanıcı Deneyimi
|
| 1337 |
-
- ✅ Mobile responsive (100%)
|
| 1338 |
-
- ✅ Accessibility (WCAG 2.1 AA)
|
| 1339 |
-
- ✅ Offline support (PWA)
|
| 1340 |
-
- ✅ Real-time updates
|
| 1341 |
-
|
| 1342 |
-
### Teknik Metrikler
|
| 1343 |
-
- ✅ Lighthouse Score: 90+
|
| 1344 |
-
- ✅ Database size: < 1GB
|
| 1345 |
-
- ✅ Concurrent users: 1000+
|
| 1346 |
-
- ✅ Uptime: 99.9%
|
| 1347 |
-
|
| 1348 |
-
---
|
| 1349 |
-
|
| 1350 |
-
## 🚨 RİSK YÖNETİMİ
|
| 1351 |
-
|
| 1352 |
-
### Yüksek Risk
|
| 1353 |
-
1. **Data Migration Hatası**
|
| 1354 |
-
- Mitigation: Incremental migration + validation
|
| 1355 |
-
- Backup: SQLite'ı sakla, rollback planı
|
| 1356 |
-
|
| 1357 |
-
2. **ML Model Performansı**
|
| 1358 |
-
- Mitigation: A/B testing, multiple models
|
| 1359 |
-
- Fallback: Basit statistical modeller
|
| 1360 |
-
|
| 1361 |
-
### Orta Risk
|
| 1362 |
-
3. **API Rate Limiting**
|
| 1363 |
-
- Mitigation: Caching, batch operations
|
| 1364 |
-
- Alternative: Self-hosted API
|
| 1365 |
-
|
| 1366 |
-
4. **Database Scaling**
|
| 1367 |
-
- Mitigation: Partitioning, indexing
|
| 1368 |
-
- Upgrade: Supabase Pro
|
| 1369 |
-
|
| 1370 |
-
---
|
| 1371 |
-
|
| 1372 |
-
## 📚 KAYNAKLAR VE REFERANSLAR
|
| 1373 |
-
|
| 1374 |
-
### Dökümanlar
|
| 1375 |
-
- [Next.js 14 Docs](https://nextjs.org/docs)
|
| 1376 |
-
- [Supabase Docs](https://supabase.com/docs)
|
| 1377 |
-
- [HuggingFace Docs](https://huggingface.co/docs)
|
| 1378 |
-
- [Vercel Docs](https://vercel.com/docs)
|
| 1379 |
-
|
| 1380 |
-
### Örnekler
|
| 1381 |
-
- [Next.js + Supabase Template](https://github.com/vercel/next.js/tree/canary/examples/with-supabase)
|
| 1382 |
-
- [Stock Dashboard Example](https://github.com/shadcn-ui/ui)
|
| 1383 |
-
|
| 1384 |
-
---
|
| 1385 |
-
|
| 1386 |
-
## ✅ KONTROL LİSTESİ
|
| 1387 |
-
|
| 1388 |
-
### Hazırlık
|
| 1389 |
-
- [ ] Supabase hesabı oluşturuldu
|
| 1390 |
-
- [ ] HuggingFace hesabı oluşturuldu
|
| 1391 |
-
- [ ] Vercel hesabı oluşturuldu
|
| 1392 |
-
- [ ] GitHub repo oluşturuldu
|
| 1393 |
-
- [ ] Development environment hazır
|
| 1394 |
-
|
| 1395 |
-
### Database
|
| 1396 |
-
- [ ] Supabase projesi oluşturuldu
|
| 1397 |
-
- [ ] Schema deploy edildi
|
| 1398 |
-
- [ ] RLS policies aktif
|
| 1399 |
-
- [ ] Indexes oluşturuldu
|
| 1400 |
-
- [ ] Migration script hazır
|
| 1401 |
-
- [ ] Data migrate edildi
|
| 1402 |
-
- [ ] Verification tamamlandı
|
| 1403 |
-
|
| 1404 |
-
### Frontend
|
| 1405 |
-
- [ ] Next.js projesi oluşturuldu
|
| 1406 |
-
- [ ] Supabase entegrasyonu
|
| 1407 |
-
- [ ] React Query setup
|
| 1408 |
-
- [ ] UI components hazır
|
| 1409 |
-
- [ ] Stock pages
|
| 1410 |
-
- [ ] ML prediction pages
|
| 1411 |
-
- [ ] Portfolio pages
|
| 1412 |
-
|
| 1413 |
-
### Backend
|
| 1414 |
-
- [ ] API routes oluşturuldu
|
| 1415 |
-
- [ ] Supabase functions
|
| 1416 |
-
- [ ] HuggingFace integration
|
| 1417 |
-
- [ ] Cron jobs
|
| 1418 |
-
- [ ] Error handling
|
| 1419 |
-
|
| 1420 |
-
### Deployment
|
| 1421 |
-
- [ ] Environment variables
|
| 1422 |
-
- [ ] Vercel deployment
|
| 1423 |
-
- [ ] Domain bağlandı
|
| 1424 |
-
- [ ] SSL aktif
|
| 1425 |
-
- [ ] Analytics kuruldu
|
| 1426 |
-
|
| 1427 |
-
### Testing
|
| 1428 |
-
- [ ] Unit tests
|
| 1429 |
-
- [ ] Integration tests
|
| 1430 |
-
- [ ] E2E tests
|
| 1431 |
-
- [ ] Performance tests
|
| 1432 |
-
- [ ] Security audit
|
| 1433 |
-
|
| 1434 |
-
---
|
| 1435 |
-
|
| 1436 |
-
## 🎉 SONUÇ
|
| 1437 |
-
|
| 1438 |
-
Bu plan ile:
|
| 1439 |
-
- ⚡ **10-20x** performans artışı
|
| 1440 |
-
- 💰 **$1,752/yıl** tasarruf
|
| 1441 |
-
- 📱 Modern, responsive UI
|
| 1442 |
-
- 🚀 Sınırsız scalability
|
| 1443 |
-
- 🔐 Enterprise-level security
|
| 1444 |
-
|
| 1445 |
-
**İlk adım:** PHASE 0'dan başlayın ve her phase'i tamamladıktan sonra işaretleyin.
|
| 1446 |
-
|
| 1447 |
-
**Sonraki Adım:** Supabase hesabı oluşturun ve database schema'sını deploy edin.
|
| 1448 |
-
|
| 1449 |
-
---
|
| 1450 |
-
|
| 1451 |
-
*Plan Version: 1.0*
|
| 1452 |
-
*Oluşturma Tarihi: 2 Ocak 2026*
|
| 1453 |
-
*Güncellenme: -*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NETLIFY_DEPLOYMENT.md
DELETED
|
@@ -1,280 +0,0 @@
|
|
| 1 |
-
# 🚀 Netlify Deployment Rehberi
|
| 2 |
-
## Python Backend + Next.js Frontend
|
| 3 |
-
|
| 4 |
-
Mevcut Python kodlarınızı **koruyarak** modern bir mimari ile Netlify'a deploy ediyoruz!
|
| 5 |
-
|
| 6 |
-
---
|
| 7 |
-
|
| 8 |
-
## 📋 Mimari
|
| 9 |
-
|
| 10 |
-
```
|
| 11 |
-
┌─────────────────────────────────────┐
|
| 12 |
-
│ Next.js Frontend (Netlify CDN) │
|
| 13 |
-
│ - Modern React UI │
|
| 14 |
-
│ - Tailwind CSS │
|
| 15 |
-
│ - TypeScript │
|
| 16 |
-
└──────────────┬──────────────────────┘
|
| 17 |
-
│ API Calls
|
| 18 |
-
▼
|
| 19 |
-
┌─────────────────────────────────────┐
|
| 20 |
-
│ Netlify Serverless Functions │
|
| 21 |
-
│ (Python 3.11) │
|
| 22 |
-
│ │
|
| 23 |
-
│ ✓ /api/stock-data │
|
| 24 |
-
│ ✓ /api/ml-predictions │
|
| 25 |
-
│ ✓ /api/technical-analysis │
|
| 26 |
-
│ ✓ /api/market-overview │
|
| 27 |
-
│ │
|
| 28 |
-
│ Kullandığı Modüller: │
|
| 29 |
-
│ - data/stock_data_api.py │
|
| 30 |
-
│ - ai/predictions_api.py │
|
| 31 |
-
│ - analysis/indicators_api.py │
|
| 32 |
-
└─────────────────────────────────────┘
|
| 33 |
-
```
|
| 34 |
-
|
| 35 |
-
---
|
| 36 |
-
|
| 37 |
-
## ⚡ Hızlı Başlangıç (5 Dakika)
|
| 38 |
-
|
| 39 |
-
### 1. Netlify CLI Kurulumu
|
| 40 |
-
|
| 41 |
-
```bash
|
| 42 |
-
npm install -g netlify-cli
|
| 43 |
-
```
|
| 44 |
-
|
| 45 |
-
### 2. Netlify'a Giriş
|
| 46 |
-
|
| 47 |
-
```bash
|
| 48 |
-
netlify login
|
| 49 |
-
```
|
| 50 |
-
|
| 51 |
-
### 3. Proje Hazırlığı
|
| 52 |
-
|
| 53 |
-
```bash
|
| 54 |
-
cd /Volumes/LaCie/borsa_uygulamasi
|
| 55 |
-
|
| 56 |
-
# Next.js dependencies kur
|
| 57 |
-
cd nextjs-app
|
| 58 |
-
npm install
|
| 59 |
-
cd ..
|
| 60 |
-
|
| 61 |
-
# Python dependencies kontrol et
|
| 62 |
-
pip install -r requirements-netlify.txt
|
| 63 |
-
```
|
| 64 |
-
|
| 65 |
-
### 4. Environment Variables
|
| 66 |
-
|
| 67 |
-
`.env` dosyası oluştur:
|
| 68 |
-
|
| 69 |
-
```bash
|
| 70 |
-
cp .env.example .env
|
| 71 |
-
```
|
| 72 |
-
|
| 73 |
-
Düzenle:
|
| 74 |
-
```env
|
| 75 |
-
NEXT_PUBLIC_API_URL=
|
| 76 |
-
```
|
| 77 |
-
|
| 78 |
-
### 5. Local Test (Opsiyonel)
|
| 79 |
-
|
| 80 |
-
```bash
|
| 81 |
-
# Netlify Dev ile test et
|
| 82 |
-
netlify dev
|
| 83 |
-
```
|
| 84 |
-
|
| 85 |
-
Browser: `http://localhost:8888`
|
| 86 |
-
|
| 87 |
-
### 6. Deploy! 🚀
|
| 88 |
-
|
| 89 |
-
```bash
|
| 90 |
-
# Production deploy
|
| 91 |
-
netlify deploy --prod
|
| 92 |
-
```
|
| 93 |
-
|
| 94 |
-
**VEYA GitHub ile otomatik deploy:**
|
| 95 |
-
|
| 96 |
-
```bash
|
| 97 |
-
# GitHub repo oluştur
|
| 98 |
-
git init
|
| 99 |
-
git add .
|
| 100 |
-
git commit -m "Initial commit: Netlify Python + Next.js"
|
| 101 |
-
git remote add origin <github-repo-url>
|
| 102 |
-
git push -u origin main
|
| 103 |
-
|
| 104 |
-
# Netlify Dashboard'dan "New site from Git" ile bağla
|
| 105 |
-
```
|
| 106 |
-
|
| 107 |
-
---
|
| 108 |
-
|
| 109 |
-
## 🔧 Netlify Dashboard Ayarları
|
| 110 |
-
|
| 111 |
-
### Build Settings
|
| 112 |
-
|
| 113 |
-
```
|
| 114 |
-
Base directory: nextjs-app
|
| 115 |
-
Build command: npm run build
|
| 116 |
-
Publish directory: nextjs-app/.next
|
| 117 |
-
Functions directory: netlify/functions
|
| 118 |
-
```
|
| 119 |
-
|
| 120 |
-
### Environment Variables
|
| 121 |
-
|
| 122 |
-
Netlify Dashboard → Site Settings → Environment Variables:
|
| 123 |
-
|
| 124 |
-
```
|
| 125 |
-
PYTHON_VERSION=3.11
|
| 126 |
-
NEXT_PUBLIC_API_URL=(boş bırak)
|
| 127 |
-
```
|
| 128 |
-
|
| 129 |
-
Supabase kullanıyorsan:
|
| 130 |
-
```
|
| 131 |
-
NEXT_PUBLIC_SUPABASE_URL=your_url
|
| 132 |
-
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_key
|
| 133 |
-
```
|
| 134 |
-
|
| 135 |
-
---
|
| 136 |
-
|
| 137 |
-
## 📁 Dosya Yapısı
|
| 138 |
-
|
| 139 |
-
```
|
| 140 |
-
borsa_uygulamasi/
|
| 141 |
-
├── netlify.toml ← Netlify config
|
| 142 |
-
├── runtime.txt ← Python version
|
| 143 |
-
├── requirements-netlify.txt ← Python deps
|
| 144 |
-
├── .env.example ← Env template
|
| 145 |
-
│
|
| 146 |
-
├── netlify/functions/ ← Serverless Functions
|
| 147 |
-
│ ├── stock-data.py
|
| 148 |
-
│ ├── ml-predictions.py
|
| 149 |
-
│ ├── technical-analysis.py
|
| 150 |
-
│ └── market-overview.py
|
| 151 |
-
│
|
| 152 |
-
├── data/ ← MEVCUT Python modüllerin
|
| 153 |
-
│ ├── stock_data.py (korundu)
|
| 154 |
-
│ └── stock_data_api.py (API versiyonu)
|
| 155 |
-
│
|
| 156 |
-
├── ai/
|
| 157 |
-
│ ├── predictions.py (korundu)
|
| 158 |
-
│ └── predictions_api.py (API versiyonu)
|
| 159 |
-
│
|
| 160 |
-
├── analysis/
|
| 161 |
-
│ ├── indicators.py (korundu)
|
| 162 |
-
│ └── indicators_api.py (API versiyonu)
|
| 163 |
-
│
|
| 164 |
-
└── nextjs-app/ ← Next.js Frontend
|
| 165 |
-
├── src/
|
| 166 |
-
│ ├── app/ (Pages)
|
| 167 |
-
│ ├── components/ (UI Components)
|
| 168 |
-
│ └── lib/
|
| 169 |
-
│ └── api-client.ts ← API Client
|
| 170 |
-
└── package.json
|
| 171 |
-
```
|
| 172 |
-
|
| 173 |
-
---
|
| 174 |
-
|
| 175 |
-
## 🧪 Test Endpoints
|
| 176 |
-
|
| 177 |
-
Deploy sonrası test et:
|
| 178 |
-
|
| 179 |
-
```bash
|
| 180 |
-
# Market overview
|
| 181 |
-
curl https://your-site.netlify.app/api/market-overview
|
| 182 |
-
|
| 183 |
-
# Stock data
|
| 184 |
-
curl "https://your-site.netlify.app/api/stock-data?symbol=THYAO"
|
| 185 |
-
|
| 186 |
-
# Technical analysis
|
| 187 |
-
curl "https://your-site.netlify.app/api/technical-analysis?symbol=THYAO"
|
| 188 |
-
|
| 189 |
-
# ML predictions
|
| 190 |
-
curl -X POST https://your-site.netlify.app/api/ml-predictions \
|
| 191 |
-
-H "Content-Type: application/json" \
|
| 192 |
-
-d '{"symbols": ["THYAO", "AKBNK"], "days_ahead": 5}'
|
| 193 |
-
```
|
| 194 |
-
|
| 195 |
-
---
|
| 196 |
-
|
| 197 |
-
## 🎯 Avantajlar
|
| 198 |
-
|
| 199 |
-
### ✅ Mevcut Kodlar Korundu
|
| 200 |
-
- `data/`, `ai/`, `analysis/` modüllerin **hepsi** kullanılıyor
|
| 201 |
-
- Sadece API wrapper'lar eklendi (Streamlit bağımlılıksız)
|
| 202 |
-
|
| 203 |
-
### ✅ Modern Stack
|
| 204 |
-
- Next.js 14 (React Server Components)
|
| 205 |
-
- TypeScript
|
| 206 |
-
- Tailwind CSS
|
| 207 |
-
- Python 3.11 Serverless Functions
|
| 208 |
-
|
| 209 |
-
### ✅ Ücretsiz & Scalable
|
| 210 |
-
- Netlify Free Tier: 300 build dakika/ay
|
| 211 |
-
- 100GB bandwidth
|
| 212 |
-
- Otomatik SSL
|
| 213 |
-
- Global CDN
|
| 214 |
-
|
| 215 |
-
### ✅ Kolay Yönetim
|
| 216 |
-
- Git push → otomatik deploy
|
| 217 |
-
- Preview deployments (PR'lar için)
|
| 218 |
-
- Rollback 1 tık
|
| 219 |
-
|
| 220 |
-
---
|
| 221 |
-
|
| 222 |
-
## 🔍 Troubleshooting
|
| 223 |
-
|
| 224 |
-
### Python Import Hatası
|
| 225 |
-
|
| 226 |
-
Function'lar `sys.path` ile modülleri buluyor:
|
| 227 |
-
|
| 228 |
-
```python
|
| 229 |
-
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))
|
| 230 |
-
```
|
| 231 |
-
|
| 232 |
-
### Build Hatası
|
| 233 |
-
|
| 234 |
-
```bash
|
| 235 |
-
# Local test et
|
| 236 |
-
cd nextjs-app
|
| 237 |
-
npm run build
|
| 238 |
-
```
|
| 239 |
-
|
| 240 |
-
### Function Timeout
|
| 241 |
-
|
| 242 |
-
Netlify free tier: 10 saniye timeout
|
| 243 |
-
- Ağır ML modellerini cache'le
|
| 244 |
-
- Veri setini küçült (6 ay yerine 3 ay)
|
| 245 |
-
|
| 246 |
-
---
|
| 247 |
-
|
| 248 |
-
## 📊 Next Steps
|
| 249 |
-
|
| 250 |
-
1. ✅ **Deploy tamamlandı mı?** → Production URL'i test et
|
| 251 |
-
2. ✅ **Custom domain?** → Netlify Dashboard → Domain settings
|
| 252 |
-
3. ✅ **Analytics?** → Netlify Analytics aktif et
|
| 253 |
-
4. ✅ **Monitoring?** → Function logs kontrol et
|
| 254 |
-
|
| 255 |
-
---
|
| 256 |
-
|
| 257 |
-
## 🆘 Yardım
|
| 258 |
-
|
| 259 |
-
**Deploy sorunları:**
|
| 260 |
-
```bash
|
| 261 |
-
netlify status
|
| 262 |
-
netlify logs:function stock-data
|
| 263 |
-
```
|
| 264 |
-
|
| 265 |
-
**Local development:**
|
| 266 |
-
```bash
|
| 267 |
-
netlify dev --live
|
| 268 |
-
```
|
| 269 |
-
|
| 270 |
-
**Netlify Support:**
|
| 271 |
-
- [Docs](https://docs.netlify.com/)
|
| 272 |
-
- [Community](https://answers.netlify.com/)
|
| 273 |
-
|
| 274 |
-
---
|
| 275 |
-
|
| 276 |
-
## 🎉 Tebrikler!
|
| 277 |
-
|
| 278 |
-
Python kodlarını **koruyarak** modern bir web uygulaması deploy ettiniz!
|
| 279 |
-
|
| 280 |
-
**Production URL:** `https://your-site.netlify.app`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NETLIFY_README.md
DELETED
|
@@ -1,264 +0,0 @@
|
|
| 1 |
-
# 🚀 Borsa Uygulaması - Netlify Edition
|
| 2 |
-
|
| 3 |
-
## Python Backend + Next.js Frontend
|
| 4 |
-
|
| 5 |
-
Streamlit yerine **modern web stack** ile yeniden yapılandırıldı!
|
| 6 |
-
|
| 7 |
-
---
|
| 8 |
-
|
| 9 |
-
## ✨ Ne Değişti?
|
| 10 |
-
|
| 11 |
-
### ÖNCEKI (Streamlit)
|
| 12 |
-
```
|
| 13 |
-
❌ Streamlit Cloud'da çalışmıyor
|
| 14 |
-
❌ Vercel'de Python çalıştırılamıyor
|
| 15 |
-
❌ Next.js'e baştan yazmak gerekti
|
| 16 |
-
❌ Mevcut Python kodları kullanılmadı
|
| 17 |
-
```
|
| 18 |
-
|
| 19 |
-
### ŞİMDİ (Netlify)
|
| 20 |
-
```
|
| 21 |
-
✅ Mevcut Python kodların KORUNDU
|
| 22 |
-
✅ Netlify Python Functions ile serverless
|
| 23 |
-
✅ Next.js modern frontend
|
| 24 |
-
✅ Ücretsiz deployment
|
| 25 |
-
✅ Otomatik scaling
|
| 26 |
-
```
|
| 27 |
-
|
| 28 |
-
---
|
| 29 |
-
|
| 30 |
-
## 🏗️ Mimari
|
| 31 |
-
|
| 32 |
-
```
|
| 33 |
-
┌──────────────────────────┐
|
| 34 |
-
│ Next.js Frontend │ ← Kullanıcı arayüzü
|
| 35 |
-
│ (Tailwind + React) │
|
| 36 |
-
└──────────┬───────────────┘
|
| 37 |
-
│
|
| 38 |
-
▼ API Calls
|
| 39 |
-
┌──────────────────────────┐
|
| 40 |
-
│ Python Serverless Funcs │ ← MEVCUTKodların!
|
| 41 |
-
│ • stock-data.py │ data/stock_data.py
|
| 42 |
-
│ • ml-predictions.py │ ai/predictions.py
|
| 43 |
-
│ • technical-analysis.py │ analysis/indicators.py
|
| 44 |
-
│ • market-overview.py │
|
| 45 |
-
└──────────────────────────┘
|
| 46 |
-
```
|
| 47 |
-
|
| 48 |
-
---
|
| 49 |
-
|
| 50 |
-
## 📋 Oluşturulan Dosyalar
|
| 51 |
-
|
| 52 |
-
### Netlify Config
|
| 53 |
-
- ✅ `netlify.toml` - Netlify yapılandırması
|
| 54 |
-
- ✅ `runtime.txt` - Python 3.11
|
| 55 |
-
- ✅ `requirements-netlify.txt` - Python dependencies
|
| 56 |
-
|
| 57 |
-
### Serverless Functions
|
| 58 |
-
- ✅ `netlify/functions/stock-data.py` - Hisse verisi API
|
| 59 |
-
- ✅ `netlify/functions/ml-predictions.py` - ML tahmin API
|
| 60 |
-
- ✅ `netlify/functions/technical-analysis.py` - Teknik analiz API
|
| 61 |
-
- ✅ `netlify/functions/market-overview.py` - Piyasa özeti API
|
| 62 |
-
|
| 63 |
-
### API Modülleri (Streamlit'siz)
|
| 64 |
-
- ✅ `data/stock_data_api.py` - Veri çekme (cache'siz)
|
| 65 |
-
- ✅ `ai/predictions_api.py` - ML tahminler (API-ready)
|
| 66 |
-
- ✅ `analysis/indicators_api.py` - Teknik göstergeler (API-ready)
|
| 67 |
-
|
| 68 |
-
### Frontend
|
| 69 |
-
- ✅ `nextjs-app/src/lib/api-client.ts` - TypeScript API client
|
| 70 |
-
- ✅ `.env.example` - Environment variables template
|
| 71 |
-
|
| 72 |
-
### Deployment Tools
|
| 73 |
-
- ✅ `netlify-check.sh` - Deployment hazırlık kontrolü
|
| 74 |
-
- ✅ `netlify-deploy.sh` - Hızlı deployment script
|
| 75 |
-
- ✅ `NETLIFY_DEPLOYMENT.md` - Detaylı deployment rehberi
|
| 76 |
-
|
| 77 |
-
---
|
| 78 |
-
|
| 79 |
-
## 🚀 Hızlı Başlangıç (2 Dakika!)
|
| 80 |
-
|
| 81 |
-
### 1. Hazırlık Kontrolü
|
| 82 |
-
|
| 83 |
-
```bash
|
| 84 |
-
cd /Volumes/LaCie/borsa_uygulamasi
|
| 85 |
-
./netlify-check.sh
|
| 86 |
-
```
|
| 87 |
-
|
| 88 |
-
### 2. Deploy!
|
| 89 |
-
|
| 90 |
-
```bash
|
| 91 |
-
./netlify-deploy.sh
|
| 92 |
-
```
|
| 93 |
-
|
| 94 |
-
**VEYA manuel:**
|
| 95 |
-
|
| 96 |
-
```bash
|
| 97 |
-
# Netlify'a giriş
|
| 98 |
-
netlify login
|
| 99 |
-
|
| 100 |
-
# Local test
|
| 101 |
-
netlify dev
|
| 102 |
-
|
| 103 |
-
# Production deploy
|
| 104 |
-
netlify deploy --prod
|
| 105 |
-
```
|
| 106 |
-
|
| 107 |
-
---
|
| 108 |
-
|
| 109 |
-
## 📊 Özellikler
|
| 110 |
-
|
| 111 |
-
### API Endpoints
|
| 112 |
-
|
| 113 |
-
1. **Hisse Verisi**
|
| 114 |
-
```
|
| 115 |
-
GET /api/stock-data?symbol=THYAO&period=1y
|
| 116 |
-
```
|
| 117 |
-
|
| 118 |
-
2. **ML Tahminleri**
|
| 119 |
-
```
|
| 120 |
-
POST /api/ml-predictions
|
| 121 |
-
Body: { "symbols": ["THYAO"], "days_ahead": 5 }
|
| 122 |
-
```
|
| 123 |
-
|
| 124 |
-
3. **Teknik Analiz**
|
| 125 |
-
```
|
| 126 |
-
GET /api/technical-analysis?symbol=THYAO
|
| 127 |
-
```
|
| 128 |
-
|
| 129 |
-
4. **Piyasa Özeti**
|
| 130 |
-
```
|
| 131 |
-
GET /api/market-overview
|
| 132 |
-
```
|
| 133 |
-
|
| 134 |
-
### Frontend Sayfalar
|
| 135 |
-
|
| 136 |
-
- ✅ `/` - Ana sayfa (market overview)
|
| 137 |
-
- ✅ `/stocks/[symbol]` - Hisse detay
|
| 138 |
-
- ✅ `/ml-scan` - ML tahmin tarayıcı
|
| 139 |
-
- ✅ `/bist100` - BIST 100 analiz
|
| 140 |
-
- ✅ `/sentiment` - Sentiment analiz
|
| 141 |
-
|
| 142 |
-
---
|
| 143 |
-
|
| 144 |
-
## 💰 Maliyet
|
| 145 |
-
|
| 146 |
-
### Netlify Free Tier
|
| 147 |
-
- ✅ **300 build dakika/ay**
|
| 148 |
-
- ✅ **100GB bandwidth**
|
| 149 |
-
- ✅ **125,000 function çağrısı**
|
| 150 |
-
- ✅ **Otomatik SSL**
|
| 151 |
-
- ✅ **Global CDN**
|
| 152 |
-
|
| 153 |
-
**Tamamen ücretsiz başlangıç!**
|
| 154 |
-
|
| 155 |
-
---
|
| 156 |
-
|
| 157 |
-
## 🎯 Avantajlar vs Dezavantajlar
|
| 158 |
-
|
| 159 |
-
### ✅ Avantajlar
|
| 160 |
-
|
| 161 |
-
1. **Mevcut Kodlar Korundu**
|
| 162 |
-
- `data/`, `ai/`, `analysis/` modüllerin hepsi kullanılıyor
|
| 163 |
-
- Sadece Streamlit bağımlılıkları kaldırıldı
|
| 164 |
-
|
| 165 |
-
2. **Modern Stack**
|
| 166 |
-
- Next.js 14 + TypeScript
|
| 167 |
-
- Python 3.11 Serverless
|
| 168 |
-
- Tailwind CSS
|
| 169 |
-
|
| 170 |
-
3. **Production-Ready**
|
| 171 |
-
- Otomatik scaling
|
| 172 |
-
- Global CDN
|
| 173 |
-
- SSL certificate
|
| 174 |
-
- HTTPS
|
| 175 |
-
|
| 176 |
-
4. **Developer Experience**
|
| 177 |
-
- Git push → otomatik deploy
|
| 178 |
-
- Preview deployments
|
| 179 |
-
- Instant rollbacks
|
| 180 |
-
|
| 181 |
-
### ⚠️ Limitler
|
| 182 |
-
|
| 183 |
-
1. **Function Timeout**
|
| 184 |
-
- Free tier: 10 saniye
|
| 185 |
-
- Çözüm: Veri setlerini küçült, cache kullan
|
| 186 |
-
|
| 187 |
-
2. **Build Dakikaları**
|
| 188 |
-
- 300 dk/ay (genellikle yeter)
|
| 189 |
-
- Çözüm: Gereksiz build'leri minimize et
|
| 190 |
-
|
| 191 |
-
3. **Bandwidth**
|
| 192 |
-
- 100GB/ay
|
| 193 |
-
- Çözüm: CDN sayesinde genelde sorun olmaz
|
| 194 |
-
|
| 195 |
-
---
|
| 196 |
-
|
| 197 |
-
## 📚 Dökümanlar
|
| 198 |
-
|
| 199 |
-
1. **[NETLIFY_DEPLOYMENT.md](NETLIFY_DEPLOYMENT.md)** - Detaylı deployment rehberi
|
| 200 |
-
2. **[.env.example](.env.example)** - Environment variables
|
| 201 |
-
3. **[netlify.toml](netlify.toml)** - Netlify config
|
| 202 |
-
|
| 203 |
-
---
|
| 204 |
-
|
| 205 |
-
## 🔧 Troubleshooting
|
| 206 |
-
|
| 207 |
-
### Build Hatası
|
| 208 |
-
```bash
|
| 209 |
-
cd nextjs-app
|
| 210 |
-
npm run build # Local test
|
| 211 |
-
```
|
| 212 |
-
|
| 213 |
-
### Function Hatası
|
| 214 |
-
```bash
|
| 215 |
-
netlify logs:function stock-data
|
| 216 |
-
```
|
| 217 |
-
|
| 218 |
-
### Import Hatası
|
| 219 |
-
Python functions, `sys.path` ile modülleri buluyor:
|
| 220 |
-
```python
|
| 221 |
-
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))
|
| 222 |
-
```
|
| 223 |
-
|
| 224 |
-
---
|
| 225 |
-
|
| 226 |
-
## 📞 Sonraki Adımlar
|
| 227 |
-
|
| 228 |
-
1. ✅ **Deploy tamamlandı mı?**
|
| 229 |
-
- Production URL'i test et
|
| 230 |
-
- API endpoint'leri dene
|
| 231 |
-
|
| 232 |
-
2. 🔗 **Custom Domain?**
|
| 233 |
-
- Netlify Dashboard → Domain settings
|
| 234 |
-
- DNS kayıtlarını güncelle
|
| 235 |
-
|
| 236 |
-
3. 📊 **Analytics?**
|
| 237 |
-
- Netlify Analytics → Enable
|
| 238 |
-
- Google Analytics ekle (opsiyonel)
|
| 239 |
-
|
| 240 |
-
4. 🔔 **Monitoring?**
|
| 241 |
-
- Netlify Function logs kontrol et
|
| 242 |
-
- Error tracking ekle (Sentry vs)
|
| 243 |
-
|
| 244 |
-
---
|
| 245 |
-
|
| 246 |
-
## 🎉 Sonuç
|
| 247 |
-
|
| 248 |
-
Streamlit yerine **modern web teknolojileri** ile:
|
| 249 |
-
- ✅ Mevcut Python kodların korundu
|
| 250 |
-
- ✅ Professional görünüm
|
| 251 |
-
- ✅ Ücretsiz deployment
|
| 252 |
-
- ✅ Otomatik scaling
|
| 253 |
-
|
| 254 |
-
**Production URL:** `https://your-site.netlify.app`
|
| 255 |
-
|
| 256 |
-
---
|
| 257 |
-
|
| 258 |
-
## 🆘 Yardım
|
| 259 |
-
|
| 260 |
-
- **Deployment sorunları:** `./netlify-check.sh`
|
| 261 |
-
- **Netlify Docs:** https://docs.netlify.com/
|
| 262 |
-
- **Community:** https://answers.netlify.com/
|
| 263 |
-
|
| 264 |
-
İyi kodlamalar! 🚀
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PROJE_OZETI.md
DELETED
|
@@ -1,147 +0,0 @@
|
|
| 1 |
-
# 📊 Kompakt Borsa Uygulaması - Proje Özeti
|
| 2 |
-
|
| 3 |
-
## 🎯 Proje Amacı
|
| 4 |
-
|
| 5 |
-
Ana borsa uygulamanızdan 3 temel sekmeyi (BIST 100, Hisse Analizi, ML Yükseliş Tahmini) içeren **kompakt ve deploy edilebilir** bir web uygulaması.
|
| 6 |
-
|
| 7 |
-
## 📁 Oluşturulan Dosyalar
|
| 8 |
-
|
| 9 |
-
### 🚀 Ana Uygulama
|
| 10 |
-
- `compact_borsa_app.py` - Kompakt borsa uygulaması
|
| 11 |
-
- `kompakt_borsa_baslat.bat` - Yerel başlatma scripti
|
| 12 |
-
|
| 13 |
-
### 🌐 Deploy Dosyaları
|
| 14 |
-
- `requirements.txt` - Python kütüphaneleri
|
| 15 |
-
- `.streamlit/config.toml` - Streamlit yapılandırması
|
| 16 |
-
- `packages.txt` - Sistem paketleri
|
| 17 |
-
- `.gitignore` - Git ignore kuralları
|
| 18 |
-
- `secrets.toml.example` - API anahtarları örneği
|
| 19 |
-
|
| 20 |
-
### 📚 Dokümantasyon
|
| 21 |
-
- `KOMPAKT_UYGULAMA_README.md` - Detaylı kullanım kılavuzu
|
| 22 |
-
- `STREAMLIT_DEPLOY_REHBERI.md` - Tam deploy rehberi
|
| 23 |
-
- `HIZLI_DEPLOY.md` - 5 dakikalık hızlı deploy
|
| 24 |
-
- `PROJE_OZETI.md` - Bu dosya
|
| 25 |
-
|
| 26 |
-
### 🔧 Yardımcı Araçlar
|
| 27 |
-
- `deploy_hazirlik.bat` - Deploy hazırlık kontrolü
|
| 28 |
-
- `requirements_deploy.txt` - Yedek requirements dosyası
|
| 29 |
-
|
| 30 |
-
## ✨ Özellikler
|
| 31 |
-
|
| 32 |
-
### 🏠 Ana Özellikler
|
| 33 |
-
- ✅ **3 Sekme**: BIST 100, Hisse Analizi, ML Tahminleri
|
| 34 |
-
- ✅ **Modern Arayüz**: Sade ve kullanıcı dostu
|
| 35 |
-
- ✅ **Responsive**: Tüm ekran boyutlarında çalışır
|
| 36 |
-
- ✅ **Hata Yönetimi**: Cloud ortamı için optimize edilmiş
|
| 37 |
-
|
| 38 |
-
### 📊 BIST 100 Sekmesi
|
| 39 |
-
- ✅ Endeks teknik analizi ve grafikler
|
| 40 |
-
- ✅ Sektör performans analizi
|
| 41 |
-
- ✅ En çok yükselenler/düşenler
|
| 42 |
-
- ✅ Teknik gösterge sinyalleri
|
| 43 |
-
|
| 44 |
-
### 🔍 Hisse Analizi Sekmesi
|
| 45 |
-
- ✅ Detaylı teknik analiz
|
| 46 |
-
- ✅ Hareketli ortalamalar ve osilatörler
|
| 47 |
-
- ✅ Destek/direnç seviyeleri
|
| 48 |
-
- ✅ Yapay zeka değerlendirmesi
|
| 49 |
-
|
| 50 |
-
### 🧠 ML Yükseliş Tahmini Sekmesi
|
| 51 |
-
- ✅ Makine öğrenmesi tabanlı tahminler
|
| 52 |
-
- ✅ Çoklu model desteği
|
| 53 |
-
- ✅ Gelişmiş parametreler
|
| 54 |
-
- ✅ Model performans analizi
|
| 55 |
-
|
| 56 |
-
## 🚀 Kullanım
|
| 57 |
-
|
| 58 |
-
### Yerel Kullanım
|
| 59 |
-
```bash
|
| 60 |
-
# Kolay yöntem
|
| 61 |
-
kompakt_borsa_baslat.bat
|
| 62 |
-
|
| 63 |
-
# Manuel yöntem
|
| 64 |
-
streamlit run compact_borsa_app.py --server.port=8502
|
| 65 |
-
```
|
| 66 |
-
|
| 67 |
-
### Deploy
|
| 68 |
-
```bash
|
| 69 |
-
# 1. Deploy hazırlığını kontrol et
|
| 70 |
-
deploy_hazirlik.bat
|
| 71 |
-
|
| 72 |
-
# 2. Hızlı deploy rehberini takip et
|
| 73 |
-
# HIZLI_DEPLOY.md dosyasını okuyun
|
| 74 |
-
```
|
| 75 |
-
|
| 76 |
-
## 🔧 Teknik Detaylar
|
| 77 |
-
|
| 78 |
-
### Teknolojiler
|
| 79 |
-
- **Frontend**: Streamlit
|
| 80 |
-
- **Backend**: Python
|
| 81 |
-
- **Veri**: yfinance, pandas
|
| 82 |
-
- **ML**: scikit-learn, XGBoost, LightGBM
|
| 83 |
-
- **Grafikler**: Plotly
|
| 84 |
-
- **Deploy**: Streamlit Community Cloud
|
| 85 |
-
|
| 86 |
-
### Gereksinimler
|
| 87 |
-
- Python 3.8+
|
| 88 |
-
- Tüm dependencies `requirements.txt`'te tanımlı
|
| 89 |
-
- İnternet bağlantısı (veri çekimi için)
|
| 90 |
-
|
| 91 |
-
### Performans
|
| 92 |
-
- ✅ Veri cache'leme ile hızlı yükleme
|
| 93 |
-
- ✅ Optimize edilmiş memory kullanımı
|
| 94 |
-
- ✅ Cloud ortamı için uyarlanmış
|
| 95 |
-
|
| 96 |
-
## 🌟 Avantajlar
|
| 97 |
-
|
| 98 |
-
### 💡 Ana Uygulamaya Göre
|
| 99 |
-
- ⚡ **Daha Hızlı**: Sadece 3 sekme
|
| 100 |
-
- 🎯 **Odaklanmış**: Temel fonksiyonlar
|
| 101 |
-
- 🌐 **Deploy Edilebilir**: Cloud'a uygun
|
| 102 |
-
- 📱 **Mobil Uyumlu**: Responsive tasarım
|
| 103 |
-
|
| 104 |
-
### 🔒 Güvenlik
|
| 105 |
-
- ✅ API anahtarları gizli
|
| 106 |
-
- ✅ Hassas veriler .gitignore'da
|
| 107 |
-
- ✅ Cloud ortamı güvenliği
|
| 108 |
-
|
| 109 |
-
## 📈 Kullanım Senaryoları
|
| 110 |
-
|
| 111 |
-
1. **Hızlı Analiz**: Günlük hisse takibi
|
| 112 |
-
2. **Demo**: Müşterilere gösterim
|
| 113 |
-
3. **Mobile**: Telefonda kullanım
|
| 114 |
-
4. **Paylaşım**: Kolay URL paylaşımı
|
| 115 |
-
|
| 116 |
-
## 🔄 Güncelleme
|
| 117 |
-
|
| 118 |
-
Uygulama ana projenizle bağlantılı olduğu için:
|
| 119 |
-
- Ana projede yapılan iyileştirmeler otomatik yansır
|
| 120 |
-
- Aynı veritabanını paylaşır
|
| 121 |
-
- Aynı analiz algoritmalarını kullanır
|
| 122 |
-
|
| 123 |
-
## 📞 Destek
|
| 124 |
-
|
| 125 |
-
### Deploy Sorunları
|
| 126 |
-
1. `STREAMLIT_DEPLOY_REHBERI.md` - Detaylı çözümler
|
| 127 |
-
2. `HIZLI_DEPLOY.md` - Hızlı troubleshooting
|
| 128 |
-
3. Streamlit Community: https://discuss.streamlit.io
|
| 129 |
-
|
| 130 |
-
### Teknik Destek
|
| 131 |
-
- GitHub Issues
|
| 132 |
-
- Streamlit Logs
|
| 133 |
-
- Kod yorumları ve dokümantasyon
|
| 134 |
-
|
| 135 |
-
## 🎉 Sonuç
|
| 136 |
-
|
| 137 |
-
Bu proje ile:
|
| 138 |
-
- ✅ Ana uygulamanızın önemli özelliklerini koruyarak
|
| 139 |
-
- ✅ Daha kompakt ve hızlı bir versiyon oluşturduk
|
| 140 |
-
- ✅ Streamlit Cloud'a deploy edilebilir hale getirdik
|
| 141 |
-
- ✅ Kapsamlı dokümantasyon sağladık
|
| 142 |
-
|
| 143 |
-
**Artık kompakt borsa uygulamanız dünya ile paylaşıma hazır! 🚀**
|
| 144 |
-
|
| 145 |
-
---
|
| 146 |
-
|
| 147 |
-
**Geliştirici Notu**: Bu uygulama, ana borsa projenizin bir alt kümesidir ve bağımsız olarak çalışabilir.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QUICKSTART.md
DELETED
|
@@ -1,163 +0,0 @@
|
|
| 1 |
-
# 🎯 Netlify Migration - Hızlı Başlangıç
|
| 2 |
-
|
| 3 |
-
## Ne Yaptık?
|
| 4 |
-
|
| 5 |
-
Streamlit + Vercel **çalışmadı** → **Netlify + Python Functions** kullanarak çözdük!
|
| 6 |
-
|
| 7 |
-
### ✅ Kazançlar
|
| 8 |
-
- Mevcut Python kodların (`data/`, `ai/`, `analysis/`) **korundu**
|
| 9 |
-
- Modern Next.js frontend
|
| 10 |
-
- Ücretsiz, scalable deployment
|
| 11 |
-
- Tek komutla deployment
|
| 12 |
-
|
| 13 |
-
---
|
| 14 |
-
|
| 15 |
-
## 🚀 Hemen Başla (3 Adım)
|
| 16 |
-
|
| 17 |
-
### 1️⃣ Kontrol Et
|
| 18 |
-
|
| 19 |
-
```bash
|
| 20 |
-
cd /Volumes/LaCie/borsa_uygulamasi
|
| 21 |
-
./netlify-check.sh
|
| 22 |
-
```
|
| 23 |
-
|
| 24 |
-
✅ **Başarılı!** Tüm gereksinimler hazır.
|
| 25 |
-
|
| 26 |
-
### 2️⃣ Deploy Et
|
| 27 |
-
|
| 28 |
-
**A) Local Test (Önerilen)**
|
| 29 |
-
```bash
|
| 30 |
-
./netlify-deploy.sh
|
| 31 |
-
# Seçenek 1'i seç: Local test
|
| 32 |
-
# Browser: http://localhost:8888
|
| 33 |
-
```
|
| 34 |
-
|
| 35 |
-
**B) Production Deploy**
|
| 36 |
-
```bash
|
| 37 |
-
netlify login
|
| 38 |
-
netlify deploy --prod
|
| 39 |
-
```
|
| 40 |
-
|
| 41 |
-
**C) GitHub Otomatik Deploy**
|
| 42 |
-
1. GitHub'da repo oluştur
|
| 43 |
-
2. Push et: `git push origin main`
|
| 44 |
-
3. [Netlify Dashboard](https://app.netlify.com/) → "New site from Git"
|
| 45 |
-
|
| 46 |
-
### 3️⃣ Test Et
|
| 47 |
-
|
| 48 |
-
```bash
|
| 49 |
-
# Production URL'in ile:
|
| 50 |
-
curl https://your-site.netlify.app/api/market-overview
|
| 51 |
-
|
| 52 |
-
# Local test ile:
|
| 53 |
-
curl http://localhost:8888/api/stock-data?symbol=THYAO
|
| 54 |
-
```
|
| 55 |
-
|
| 56 |
-
---
|
| 57 |
-
|
| 58 |
-
## 📁 Önemli Dosyalar
|
| 59 |
-
|
| 60 |
-
```
|
| 61 |
-
├── netlify.toml ← Netlify config
|
| 62 |
-
├── runtime.txt ← Python 3.11
|
| 63 |
-
├── requirements-netlify.txt ← Python deps
|
| 64 |
-
│
|
| 65 |
-
├── netlify/functions/ ← 4 Serverless API
|
| 66 |
-
│ ├── stock-data.py
|
| 67 |
-
│ ├── ml-predictions.py
|
| 68 |
-
│ ├── technical-analysis.py
|
| 69 |
-
│ └── market-overview.py
|
| 70 |
-
│
|
| 71 |
-
├── data/stock_data_api.py ← API modülleri
|
| 72 |
-
├── ai/predictions_api.py
|
| 73 |
-
├── analysis/indicators_api.py
|
| 74 |
-
│
|
| 75 |
-
├── nextjs-app/ ← Frontend
|
| 76 |
-
│ └── src/lib/api-client.ts
|
| 77 |
-
│
|
| 78 |
-
└── NETLIFY_DEPLOYMENT.md ← Detaylı rehber
|
| 79 |
-
```
|
| 80 |
-
|
| 81 |
-
---
|
| 82 |
-
|
| 83 |
-
## 🔥 Hızlı Komutlar
|
| 84 |
-
|
| 85 |
-
```bash
|
| 86 |
-
# Hazırlık kontrolü
|
| 87 |
-
./netlify-check.sh
|
| 88 |
-
|
| 89 |
-
# Hızlı deployment
|
| 90 |
-
./netlify-deploy.sh
|
| 91 |
-
|
| 92 |
-
# Manuel deployment
|
| 93 |
-
netlify login
|
| 94 |
-
netlify dev # Local test
|
| 95 |
-
netlify deploy --prod # Production
|
| 96 |
-
|
| 97 |
-
# Function logs
|
| 98 |
-
netlify logs:function stock-data
|
| 99 |
-
|
| 100 |
-
# Status
|
| 101 |
-
netlify status
|
| 102 |
-
```
|
| 103 |
-
|
| 104 |
-
---
|
| 105 |
-
|
| 106 |
-
## 📊 API Endpoints
|
| 107 |
-
|
| 108 |
-
Deployment sonrası bu endpoint'ler hazır:
|
| 109 |
-
|
| 110 |
-
1. **Hisse Verisi:** `/api/stock-data?symbol=THYAO`
|
| 111 |
-
2. **ML Tahmin:** POST `/api/ml-predictions`
|
| 112 |
-
3. **Teknik Analiz:** `/api/technical-analysis?symbol=THYAO`
|
| 113 |
-
4. **Piyasa Özet:** `/api/market-overview`
|
| 114 |
-
|
| 115 |
-
---
|
| 116 |
-
|
| 117 |
-
## 💡 Önemli Notlar
|
| 118 |
-
|
| 119 |
-
### Environment Variables
|
| 120 |
-
|
| 121 |
-
`.env` dosyası oluştur:
|
| 122 |
-
```bash
|
| 123 |
-
cp .env.example .env
|
| 124 |
-
```
|
| 125 |
-
|
| 126 |
-
Production'da Netlify Dashboard → Environment Variables:
|
| 127 |
-
- `PYTHON_VERSION=3.11`
|
| 128 |
-
- `NEXT_PUBLIC_API_URL=` (boş bırak)
|
| 129 |
-
|
| 130 |
-
### Free Tier Limitler
|
| 131 |
-
|
| 132 |
-
- ✅ 300 build dakika/ay
|
| 133 |
-
- ✅ 100GB bandwidth
|
| 134 |
-
- ✅ 125K function çağrısı
|
| 135 |
-
- ⚠️ 10 sn function timeout
|
| 136 |
-
|
| 137 |
-
### Mevcut Python Kodların
|
| 138 |
-
|
| 139 |
-
**KORUNDU ve kullanılıyor:**
|
| 140 |
-
- `data/stock_data.py` → `stock_data_api.py` (Streamlit'siz)
|
| 141 |
-
- `ai/predictions.py` → `predictions_api.py` (API-ready)
|
| 142 |
-
- `analysis/indicators.py` → `indicators_api.py` (API-ready)
|
| 143 |
-
|
| 144 |
-
---
|
| 145 |
-
|
| 146 |
-
## 🎉 Başarı!
|
| 147 |
-
|
| 148 |
-
Artık:
|
| 149 |
-
- ✅ Mevcut Python kodların çalışıyor
|
| 150 |
-
- ✅ Modern web arayüzü var
|
| 151 |
-
- ✅ Ücretsiz deployment hazır
|
| 152 |
-
- ✅ Otomatik scaling aktif
|
| 153 |
-
|
| 154 |
-
---
|
| 155 |
-
|
| 156 |
-
## 📚 Daha Fazla Bilgi
|
| 157 |
-
|
| 158 |
-
- **[NETLIFY_README.md](NETLIFY_README.md)** - Genel bakış
|
| 159 |
-
- **[NETLIFY_DEPLOYMENT.md](NETLIFY_DEPLOYMENT.md)** - Detaylı rehber
|
| 160 |
-
|
| 161 |
-
---
|
| 162 |
-
|
| 163 |
-
**Hızlı başlangıç:** `./netlify-deploy.sh` 🚀
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
README.md
CHANGED
|
@@ -18,6 +18,12 @@ Modern, performanslı borsa analiz platformu - Next.js 14, Supabase ve TypeScrip
|
|
| 18 |
- ✅ **Type-Safe**: TypeScript ile tip güvenliği
|
| 19 |
- ✅ **Fast Performance**: Next.js 14 App Router, Server Components
|
| 20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
## 📦 Kurulum
|
| 22 |
|
| 23 |
### 1. Bağımlılıkları Yükle
|
|
|
|
| 18 |
- ✅ **Type-Safe**: TypeScript ile tip güvenliği
|
| 19 |
- ✅ **Fast Performance**: Next.js 14 App Router, Server Components
|
| 20 |
|
| 21 |
+
## ✅ Model Doğrulama (Önerilen)
|
| 22 |
+
|
| 23 |
+
ML sinyallerini gerçek para ile kullanmadan önce, yerel walk-forward backtest ile ölçüm alın:
|
| 24 |
+
|
| 25 |
+
- [WALK_FORWARD_BACKTEST.md](WALK_FORWARD_BACKTEST.md)
|
| 26 |
+
|
| 27 |
## 📦 Kurulum
|
| 28 |
|
| 29 |
### 1. Bağımlılıkları Yükle
|
STREAMLIT_DEPLOY_REHBERI.md
DELETED
|
@@ -1,184 +0,0 @@
|
|
| 1 |
-
# 🚀 Streamlit Community Cloud Deploy Rehberi
|
| 2 |
-
|
| 3 |
-
Bu rehber, kompakt borsa uygulamanızı Streamlit Community Cloud'a deploy etmenizi sağlayacak.
|
| 4 |
-
|
| 5 |
-
## 📋 Gerekli Dosyalar (✅ Hazırlandı)
|
| 6 |
-
|
| 7 |
-
- ✅ `compact_borsa_app.py` - Ana uygulama
|
| 8 |
-
- ✅ `requirements_deploy.txt` - Python kütüphaneleri
|
| 9 |
-
- ✅ `.streamlit/config.toml` - Streamlit yapılandırması
|
| 10 |
-
- ✅ `packages.txt` - Sistem paketleri
|
| 11 |
-
- ✅ `.gitignore` - Git ignore dosyası
|
| 12 |
-
- ✅ `secrets.toml.example` - API anahtarları örneği
|
| 13 |
-
|
| 14 |
-
## 🔧 Adım 1: GitHub Repository Oluşturma
|
| 15 |
-
|
| 16 |
-
### 1.1 GitHub'da Yeni Repository Oluşturun
|
| 17 |
-
1. GitHub hesabınıza giriş yapın
|
| 18 |
-
2. "New repository" butonuna tıklayın
|
| 19 |
-
3. Repository adını girin: `kompakt-borsa-app`
|
| 20 |
-
4. Public olarak ayarlayın (Streamlit Community Cloud için gerekli)
|
| 21 |
-
5. "Create repository" butonuna tıklayın
|
| 22 |
-
|
| 23 |
-
### 1.2 Lokal Git Repository Başlatın
|
| 24 |
-
Terminal/Command Prompt'ta projenizin klasöründe:
|
| 25 |
-
|
| 26 |
-
```bash
|
| 27 |
-
# Git repository başlat
|
| 28 |
-
git init
|
| 29 |
-
|
| 30 |
-
# Dosyaları ekle
|
| 31 |
-
git add .
|
| 32 |
-
|
| 33 |
-
# İlk commit
|
| 34 |
-
git commit -m "İlk commit: Kompakt Borsa Uygulaması"
|
| 35 |
-
|
| 36 |
-
# GitHub repository'yi bağla (YOUR_USERNAME yerine kendi kullanıcı adınızı yazın)
|
| 37 |
-
git remote add origin https://github.com/YOUR_USERNAME/kompakt-borsa-app.git
|
| 38 |
-
|
| 39 |
-
# Ana branch'ı main olarak ayarla
|
| 40 |
-
git branch -M main
|
| 41 |
-
|
| 42 |
-
# GitHub'a yükle
|
| 43 |
-
git push -u origin main
|
| 44 |
-
```
|
| 45 |
-
|
| 46 |
-
## 🔧 Adım 2: Requirements Dosyasını Yeniden Adlandırın
|
| 47 |
-
|
| 48 |
-
Deploy için `requirements_deploy.txt` dosyasını `requirements.txt` olarak değiştirin:
|
| 49 |
-
|
| 50 |
-
```bash
|
| 51 |
-
# Windows'ta
|
| 52 |
-
ren requirements_deploy.txt requirements.txt
|
| 53 |
-
|
| 54 |
-
# Linux/Mac'te
|
| 55 |
-
mv requirements_deploy.txt requirements.txt
|
| 56 |
-
```
|
| 57 |
-
|
| 58 |
-
## 🔧 Adım 3: Streamlit Community Cloud'a Deploy
|
| 59 |
-
|
| 60 |
-
### 3.1 Streamlit Community Cloud'a Giriş
|
| 61 |
-
1. [share.streamlit.io](https://share.streamlit.io) adresine gidin
|
| 62 |
-
2. GitHub hesabınızla giriş yapın
|
| 63 |
-
3. "New app" butonuna tıklayın
|
| 64 |
-
|
| 65 |
-
### 3.2 App Yapılandırması
|
| 66 |
-
1. **Repository**: `YOUR_USERNAME/kompakt-borsa-app`
|
| 67 |
-
2. **Branch**: `main`
|
| 68 |
-
3. **Main file path**: `compact_borsa_app.py`
|
| 69 |
-
4. **App URL** (opsiyonel): Özel URL belirleyebilirsiniz
|
| 70 |
-
|
| 71 |
-
### 3.3 Deploy Butonuna Tıklayın
|
| 72 |
-
- "Deploy!" butonuna tıklayın
|
| 73 |
-
- Streamlit uygulamanızı otomatik olarak kuracak
|
| 74 |
-
|
| 75 |
-
## 🔑 Adım 4: API Anahtarlarını Ayarlama (Opsiyonel)
|
| 76 |
-
|
| 77 |
-
Eğer uygulamanızda API anahtarları kullanıyorsanız:
|
| 78 |
-
|
| 79 |
-
1. Streamlit Cloud dashboard'da uygulamanızı seçin
|
| 80 |
-
2. "Settings" > "Secrets" kısmına gidin
|
| 81 |
-
3. Aşağıdaki formatı kullanın:
|
| 82 |
-
|
| 83 |
-
```toml
|
| 84 |
-
[api_keys]
|
| 85 |
-
GEMINI_API_KEY = "your_actual_gemini_api_key"
|
| 86 |
-
OPENAI_API_KEY = "your_actual_openai_api_key"
|
| 87 |
-
```
|
| 88 |
-
|
| 89 |
-
## 🔧 Adım 5: Config Dosyasını Güncelle (Gerekirse)
|
| 90 |
-
|
| 91 |
-
Eğer uygulamanızda yerel dosya yolları varsa, bunları Streamlit Cloud için uyarlayın:
|
| 92 |
-
|
| 93 |
-
```python
|
| 94 |
-
# config.py dosyasında
|
| 95 |
-
import os
|
| 96 |
-
import streamlit as st
|
| 97 |
-
|
| 98 |
-
# Yerel veya cloud ortamını algıla
|
| 99 |
-
if hasattr(st, 'secrets'):
|
| 100 |
-
# Streamlit Cloud'da çalışıyor
|
| 101 |
-
API_KEYS = {
|
| 102 |
-
"GEMINI_API_KEY": st.secrets["api_keys"]["GEMINI_API_KEY"],
|
| 103 |
-
"OPENAI_API_KEY": st.secrets["api_keys"]["OPENAI_API_KEY"]
|
| 104 |
-
}
|
| 105 |
-
else:
|
| 106 |
-
# Yerel ortamda çalışıyor
|
| 107 |
-
API_KEYS = {
|
| 108 |
-
"GEMINI_API_KEY": "your_local_key",
|
| 109 |
-
"OPENAI_API_KEY": "your_local_key"
|
| 110 |
-
}
|
| 111 |
-
```
|
| 112 |
-
|
| 113 |
-
## 🔧 Olası Sorunlar ve Çözümler
|
| 114 |
-
|
| 115 |
-
### Sorun 1: Import Hatası
|
| 116 |
-
```
|
| 117 |
-
ModuleNotFoundError: No module named 'xyz'
|
| 118 |
-
```
|
| 119 |
-
**Çözüm**: `requirements.txt` dosyasına eksik kütüphaneyi ekleyin
|
| 120 |
-
|
| 121 |
-
### Sorun 2: Dosya Yolu Hatası
|
| 122 |
-
```
|
| 123 |
-
FileNotFoundError: [Errno 2] No such file or directory
|
| 124 |
-
```
|
| 125 |
-
**Çözüm**: Dosya yollarını Streamlit Cloud için düzenleyin
|
| 126 |
-
|
| 127 |
-
### Sorun 3: Database Hatası
|
| 128 |
-
```
|
| 129 |
-
sqlite3.OperationalError: unable to open database file
|
| 130 |
-
```
|
| 131 |
-
**Çözüm**: Database dosyasını `.gitignore`'dan çıkarın veya otomatik oluşturma kodu ekleyin
|
| 132 |
-
|
| 133 |
-
### Sorun 4: Memory Hatası
|
| 134 |
-
```
|
| 135 |
-
ResourceError: This app has gone over the resource limits
|
| 136 |
-
```
|
| 137 |
-
**Çözüm**: Veri cache'leme kullanın ve gereksiz hesaplamaları azaltın
|
| 138 |
-
|
| 139 |
-
## 🎯 Performans Optimizasyonu
|
| 140 |
-
|
| 141 |
-
### Cache Kullanımı
|
| 142 |
-
```python
|
| 143 |
-
@st.cache_data(ttl=300) # 5 dakika cache
|
| 144 |
-
def get_stock_data_cached(symbol):
|
| 145 |
-
return get_stock_data(symbol)
|
| 146 |
-
```
|
| 147 |
-
|
| 148 |
-
### Memory Management
|
| 149 |
-
```python
|
| 150 |
-
# Büyük DataFrame'leri cache'le
|
| 151 |
-
@st.cache_data
|
| 152 |
-
def load_large_data():
|
| 153 |
-
return pd.read_csv("large_file.csv")
|
| 154 |
-
```
|
| 155 |
-
|
| 156 |
-
## 🔄 Güncelleme
|
| 157 |
-
|
| 158 |
-
Uygulamanızda değişiklik yaptığınızda:
|
| 159 |
-
|
| 160 |
-
```bash
|
| 161 |
-
git add .
|
| 162 |
-
git commit -m "Güncelleme mesajı"
|
| 163 |
-
git push origin main
|
| 164 |
-
```
|
| 165 |
-
|
| 166 |
-
Streamlit otomatik olarak uygulamanızı güncelleyecek.
|
| 167 |
-
|
| 168 |
-
## 📱 Sonuç
|
| 169 |
-
|
| 170 |
-
Deploy başarılı olduğunda:
|
| 171 |
-
- Uygulamanız `https://YOUR_APP_NAME.streamlit.app` adresinde yayında olacak
|
| 172 |
-
- Otomatik SSL sertifikası ile güvenli bağlantı
|
| 173 |
-
- GitHub'daki her değişiklik otomatik deploy edilecek
|
| 174 |
-
|
| 175 |
-
## 🆘 Yardım
|
| 176 |
-
|
| 177 |
-
Deploy sırasında sorun yaşarsanız:
|
| 178 |
-
1. Streamlit Community Cloud logs'larını kontrol edin
|
| 179 |
-
2. GitHub repository'nizin public olduğundan emin olun
|
| 180 |
-
3. `requirements.txt` dosyasındaki versiyonları kontrol edin
|
| 181 |
-
|
| 182 |
-
---
|
| 183 |
-
|
| 184 |
-
**Başarılı deploy dileriz! 🚀**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SUPABASE_SETUP.md
DELETED
|
@@ -1,268 +0,0 @@
|
|
| 1 |
-
# 🚀 SUPABASE KURULUM REHBERİ
|
| 2 |
-
|
| 3 |
-
## Adım 1: API Keys'leri Al
|
| 4 |
-
|
| 5 |
-
Supabase projeniz: `mitlbxlqjibfcxswgmbq`
|
| 6 |
-
Dashboard URL: https://supabase.com/dashboard/project/mitlbxlqjibfcxswgmbq
|
| 7 |
-
|
| 8 |
-
### API Keys'leri kopyalayın:
|
| 9 |
-
|
| 10 |
-
1. **Supabase Dashboard'a gidin:**
|
| 11 |
-
https://supabase.com/dashboard/project/mitlbxlqjibfcxswgmbq/settings/api
|
| 12 |
-
|
| 13 |
-
2. **Şu bilgileri kopyalayın:**
|
| 14 |
-
- ✅ **Project URL** (örn: https://mitlbxlqjibfcxswgmbq.supabase.co)
|
| 15 |
-
- ✅ **anon/public key** (başlangıç: eyJhbG...)
|
| 16 |
-
- ✅ **service_role key** (başlangıç: eyJhbG... - **GİZLİ**, migration için gerekli)
|
| 17 |
-
|
| 18 |
-
---
|
| 19 |
-
|
| 20 |
-
## Adım 2: Database Schema'yı Deploy Et
|
| 21 |
-
|
| 22 |
-
1. **SQL Editor'a gidin:**
|
| 23 |
-
https://supabase.com/dashboard/project/mitlbxlqjibfcxswgmbq/sql/new
|
| 24 |
-
|
| 25 |
-
2. **Aşağıdaki dosyayı açın ve tüm içeriği kopyalayın:**
|
| 26 |
-
```
|
| 27 |
-
supabase/migrations/20260102_initial_schema.sql
|
| 28 |
-
```
|
| 29 |
-
|
| 30 |
-
3. **SQL Editor'a yapıştırın ve "RUN" butonuna basın**
|
| 31 |
-
- ⏱️ ~30 saniye sürecek
|
| 32 |
-
- ✅ "Success" mesajı göreceksiniz
|
| 33 |
-
|
| 34 |
-
4. **Tabloları kontrol edin:**
|
| 35 |
-
https://supabase.com/dashboard/project/mitlbxlqjibfcxswgmbq/editor
|
| 36 |
-
|
| 37 |
-
Görmemiz gerekenler:
|
| 38 |
-
- ✅ stocks
|
| 39 |
-
- ✅ stock_prices (+ partitions)
|
| 40 |
-
- ✅ technical_indicators
|
| 41 |
-
- ✅ ml_predictions
|
| 42 |
-
- ✅ news_articles
|
| 43 |
-
- ✅ user_profiles
|
| 44 |
-
- ✅ portfolios
|
| 45 |
-
- ✅ watchlists
|
| 46 |
-
- ✅ analysis_history
|
| 47 |
-
- ✅ sector_performance
|
| 48 |
-
|
| 49 |
-
---
|
| 50 |
-
|
| 51 |
-
## Adım 3: .env Dosyası Oluştur
|
| 52 |
-
|
| 53 |
-
Terminal'de çalıştırın:
|
| 54 |
-
|
| 55 |
-
```bash
|
| 56 |
-
cd /Volumes/LaCie/borsa_uygulamasi/migration
|
| 57 |
-
|
| 58 |
-
# .env dosyası oluştur
|
| 59 |
-
cat > .env << 'EOF'
|
| 60 |
-
# Supabase Configuration
|
| 61 |
-
SUPABASE_URL=https://mitlbxlqjibfcxswgmbq.supabase.co
|
| 62 |
-
SUPABASE_SERVICE_KEY=YOUR_SERVICE_ROLE_KEY_HERE
|
| 63 |
-
SUPABASE_ANON_KEY=YOUR_ANON_KEY_HERE
|
| 64 |
-
EOF
|
| 65 |
-
|
| 66 |
-
# Şimdi .env dosyasını düzenleyin ve gerçek key'leri yapıştırın
|
| 67 |
-
nano .env
|
| 68 |
-
```
|
| 69 |
-
|
| 70 |
-
**veya manuel olarak:**
|
| 71 |
-
1. `migration/.env.example` dosyasını kopyalayın
|
| 72 |
-
2. `migration/.env` olarak kaydedin
|
| 73 |
-
3. Key'leri gerçek değerlerle değiştirin
|
| 74 |
-
|
| 75 |
-
---
|
| 76 |
-
|
| 77 |
-
## Adım 4: Migration Paketlerini Yükle
|
| 78 |
-
|
| 79 |
-
```bash
|
| 80 |
-
cd /Volumes/LaCie/borsa_uygulamasi/migration
|
| 81 |
-
|
| 82 |
-
# Virtual environment oluştur (opsiyonel ama önerilen)
|
| 83 |
-
python3 -m venv venv
|
| 84 |
-
source venv/bin/activate
|
| 85 |
-
|
| 86 |
-
# Gerekli paketleri yükle
|
| 87 |
-
pip install -r requirements.txt
|
| 88 |
-
```
|
| 89 |
-
|
| 90 |
-
---
|
| 91 |
-
|
| 92 |
-
## Adım 5: Test Migration (Dry Run)
|
| 93 |
-
|
| 94 |
-
```bash
|
| 95 |
-
# Tüm migration'ı simüle et (gerçek veri eklemez)
|
| 96 |
-
python sqlite_to_postgres.py --dry-run
|
| 97 |
-
|
| 98 |
-
# Sadece stocks tablosunu test et
|
| 99 |
-
python sqlite_to_postgres.py --dry-run --table stocks
|
| 100 |
-
```
|
| 101 |
-
|
| 102 |
-
**Beklenen çıktı:**
|
| 103 |
-
```
|
| 104 |
-
🚀 BORSA UYGULAMASI - DATABASE MIGRATION
|
| 105 |
-
📅 Tarih: 2026-01-02 ...
|
| 106 |
-
============================================================
|
| 107 |
-
📂 SQLite veritabanı: /Volumes/LaCie/borsa_uygulamasi/data/stock_analysis.db
|
| 108 |
-
📊 Veritabanı boyutu: 17.00 GB
|
| 109 |
-
✅ Supabase'e bağlandı: https://mitlbxlqjibfcxswgmbq.supabase.co
|
| 110 |
-
...
|
| 111 |
-
🔍 DRY RUN - Gerçek insert yapılmayacak
|
| 112 |
-
...
|
| 113 |
-
```
|
| 114 |
-
|
| 115 |
-
---
|
| 116 |
-
|
| 117 |
-
## Adım 6: Gerçek Migration Başlat
|
| 118 |
-
|
| 119 |
-
⚠️ **ÖNEMLİ:** Bu işlem 3-5 saat sürebilir!
|
| 120 |
-
|
| 121 |
-
### Stratejik Yaklaşım (Önerilen):
|
| 122 |
-
|
| 123 |
-
**A) Önce stocks'u migrate et (hızlı - ~30 saniye):**
|
| 124 |
-
```bash
|
| 125 |
-
python sqlite_to_postgres.py --table stocks
|
| 126 |
-
```
|
| 127 |
-
|
| 128 |
-
**B) Verification yap:**
|
| 129 |
-
```bash
|
| 130 |
-
python sqlite_to_postgres.py --verify-only
|
| 131 |
-
```
|
| 132 |
-
|
| 133 |
-
**C) Tek bir hisse ile test et (örnek: THYAO):**
|
| 134 |
-
```bash
|
| 135 |
-
python sqlite_to_postgres.py --table stock_prices --symbol THYAO
|
| 136 |
-
```
|
| 137 |
-
|
| 138 |
-
**D) Sonuç başarılıysa, tüm fiyatları migrate et:**
|
| 139 |
-
```bash
|
| 140 |
-
# Bu uzun sürecek! Screen veya tmux kullanmanızı öneririm
|
| 141 |
-
python sqlite_to_postgres.py --table stock_prices
|
| 142 |
-
```
|
| 143 |
-
|
| 144 |
-
**E) ML predictions'ı migrate et:**
|
| 145 |
-
```bash
|
| 146 |
-
python sqlite_to_postgres.py --table ml_predictions
|
| 147 |
-
```
|
| 148 |
-
|
| 149 |
-
### Tek Seferde Tümü:
|
| 150 |
-
```bash
|
| 151 |
-
# Tüm tabloları migrate et
|
| 152 |
-
python sqlite_to_postgres.py
|
| 153 |
-
```
|
| 154 |
-
|
| 155 |
-
---
|
| 156 |
-
|
| 157 |
-
## Progress İzleme
|
| 158 |
-
|
| 159 |
-
### Terminal 1: Migration çalıştır
|
| 160 |
-
```bash
|
| 161 |
-
python sqlite_to_postgres.py --table stock_prices
|
| 162 |
-
```
|
| 163 |
-
|
| 164 |
-
### Terminal 2: Log izle
|
| 165 |
-
```bash
|
| 166 |
-
cd /Volumes/LaCie/borsa_uygulamasi/migration
|
| 167 |
-
tail -f migration.log
|
| 168 |
-
```
|
| 169 |
-
|
| 170 |
-
### Terminal 3: Supabase'de kayıtları kontrol et
|
| 171 |
-
```bash
|
| 172 |
-
# Veya web'den: https://supabase.com/dashboard/project/mitlbxlqjibfcxswgmbq/editor
|
| 173 |
-
# stocks tablosunu açıp kayıt sayısını görün
|
| 174 |
-
```
|
| 175 |
-
|
| 176 |
-
---
|
| 177 |
-
|
| 178 |
-
## Adım 7: Doğrulama
|
| 179 |
-
|
| 180 |
-
Migration tamamlandıktan sonra:
|
| 181 |
-
|
| 182 |
-
```bash
|
| 183 |
-
python sqlite_to_postgres.py --verify-only
|
| 184 |
-
```
|
| 185 |
-
|
| 186 |
-
**Beklenen çıktı:**
|
| 187 |
-
```
|
| 188 |
-
============================================================
|
| 189 |
-
🔍 MİGRATION DOĞRULAMA
|
| 190 |
-
============================================================
|
| 191 |
-
📊 Stocks: SQLite=150, Supabase=150 (100.0%)
|
| 192 |
-
💹 Stock Prices: SQLite=1250000, Supabase=1248500 (99.9%)
|
| 193 |
-
============================================================
|
| 194 |
-
✅ TÜM DOĞRULAMALAR BAŞARILI!
|
| 195 |
-
============================================================
|
| 196 |
-
```
|
| 197 |
-
|
| 198 |
-
---
|
| 199 |
-
|
| 200 |
-
## Troubleshooting
|
| 201 |
-
|
| 202 |
-
### Problem: "ModuleNotFoundError: No module named 'supabase'"
|
| 203 |
-
**Çözüm:**
|
| 204 |
-
```bash
|
| 205 |
-
pip install -r requirements.txt
|
| 206 |
-
```
|
| 207 |
-
|
| 208 |
-
### Problem: "SUPABASE_URL not found"
|
| 209 |
-
**Çözüm:**
|
| 210 |
-
```bash
|
| 211 |
-
# .env dosyasının doğru yerde olduğundan emin olun
|
| 212 |
-
ls -la migration/.env
|
| 213 |
-
|
| 214 |
-
# İçeriğini kontrol edin (key'ler doğru mu?)
|
| 215 |
-
cat migration/.env
|
| 216 |
-
```
|
| 217 |
-
|
| 218 |
-
### Problem: Migration çok yavaş
|
| 219 |
-
**Çözüm:**
|
| 220 |
-
```bash
|
| 221 |
-
# Script içinde BATCH_SIZE'ı artırın (varsayılan 500)
|
| 222 |
-
# nano migration/sqlite_to_postgres.py
|
| 223 |
-
# BATCH_SIZE = 1000 # Bunu 1000'e çıkarın
|
| 224 |
-
```
|
| 225 |
-
|
| 226 |
-
### Problem: Rate limit hatası
|
| 227 |
-
**Çözüm:**
|
| 228 |
-
Script otomatik retry yapıyor, bekleyin. Eğer devam ederse BATCH_SIZE'ı düşürün.
|
| 229 |
-
|
| 230 |
-
---
|
| 231 |
-
|
| 232 |
-
## Sonraki Adım: Next.js Template
|
| 233 |
-
|
| 234 |
-
Migration tamamlandıktan sonra Next.js uygulamasını oluşturacağız! 🎉
|
| 235 |
-
|
| 236 |
-
---
|
| 237 |
-
|
| 238 |
-
## Hızlı Komutlar Özeti
|
| 239 |
-
|
| 240 |
-
```bash
|
| 241 |
-
# 1. Klasöre git
|
| 242 |
-
cd /Volumes/LaCie/borsa_uygulamasi/migration
|
| 243 |
-
|
| 244 |
-
# 2. .env oluştur (keys'leri ekle)
|
| 245 |
-
cp .env.example .env && nano .env
|
| 246 |
-
|
| 247 |
-
# 3. Paketleri yükle
|
| 248 |
-
pip install -r requirements.txt
|
| 249 |
-
|
| 250 |
-
# 4. Test
|
| 251 |
-
python sqlite_to_postgres.py --dry-run
|
| 252 |
-
|
| 253 |
-
# 5. Stocks migrate et
|
| 254 |
-
python sqlite_to_postgres.py --table stocks
|
| 255 |
-
|
| 256 |
-
# 6. Verify
|
| 257 |
-
python sqlite_to_postgres.py --verify-only
|
| 258 |
-
|
| 259 |
-
# 7. Fiyatları migrate et (UZUN!)
|
| 260 |
-
python sqlite_to_postgres.py --table stock_prices
|
| 261 |
-
|
| 262 |
-
# 8. Final verify
|
| 263 |
-
python sqlite_to_postgres.py --verify-only
|
| 264 |
-
```
|
| 265 |
-
|
| 266 |
-
---
|
| 267 |
-
|
| 268 |
-
**Hazır mısınız? İlk adım: API keys'leri almak! 🔑**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|