Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
94ac752
update readme
Nov 12, 2025
ecd20b1
feat: add whether to enable self registration toggle (#760)
xqliu Nov 12, 2025
dd280f9
feat(dashboard): 在交易者详情页显示系统提示词模板名称 (#775)
xqliu Nov 12, 2025
be90c5d
fix(trader): get peakPnlPct using posKey (#955)
hzb1115 Nov 13, 2025
28394da
Fix(readme): modify docoments (#956)
hzb1115 Nov 13, 2025
344c251
fix(stats): fixed the PNL calculation (#963)
tangmengqiu Nov 13, 2025
6a8536d
update readme
Nov 13, 2025
f1a1d6d
fix(api): market/combined_streams: Get Proxy form Environment (#879)
MarsDoge Nov 13, 2025
01b2b61
Revert "fix(api): market/combined_streams: Get Proxy form Environment…
xqliu Nov 13, 2025
f7a509e
update readme
Nov 13, 2025
de35e48
fix(web): await mutateTraders() to eliminate 3-4s delay after operati…
the-dev-z Nov 13, 2025
c27ccfc
Improve(interface): replace some struct with interface for testing (#…
hzb1115 Nov 14, 2025
a7820f9
fix(web): fix 401 unauthorized redirect not working properly (#997)
tangmengqiu Nov 14, 2025
a5bb5c4
fix(api): use UUID to ensure traderID uniqueness (#893) (#1008)
the-dev-z Nov 14, 2025
f60130d
Git 工作流规范 (#974)
livelybug Nov 14, 2025
facf2ec
fix gh job failed when pr contains issues (#1019)
tangmengqiu Nov 15, 2025
ffa4ea2
refactor(web): restructure AITradersPage into modular architecture (#…
0xEmberZz Nov 15, 2025
73843fd
fix(decision): add missing actions to AI prompt (#983)
xqliu Nov 16, 2025
5573852
fix(decision): clarify field names for update_stop_loss and update_ta…
xqliu Nov 16, 2025
1bb78ff
fix(docker): revert healthcheck to wget for Alpine compatibility (#986)
the-dev-z Nov 16, 2025
518a936
refactor(mcp) (#1042)
hzb1115 Nov 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions .github/workflows/pr-docker-compose-healthcheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
name: PR Docker Compose Healthcheck

# 驗證 docker-compose.yml 的 healthcheck 配置在 Alpine 容器中正常工作
on:
pull_request:
branches:
- main
- dev
paths:
- 'docker-compose.yml'
- 'docker/Dockerfile.backend'
- 'docker/Dockerfile.frontend'
- '.github/workflows/pr-docker-compose-healthcheck.yml'

jobs:
healthcheck-test:
name: Test Docker Compose Healthcheck
runs-on: ubuntu-22.04
timeout-minutes: 10
permissions:
contents: read

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Create minimal .env for testing
run: |
cat > .env <<EOF
# Minimal config for healthcheck testing
NOFX_BACKEND_PORT=8080
NOFX_FRONTEND_PORT=3000
NOFX_TIMEZONE=UTC
DATA_ENCRYPTION_KEY=test-key-32-chars-minimum-length
JWT_SECRET=test-jwt-secret-minimum-32-chars
EOF

- name: Create minimal config.json
run: |
cat > config.json <<EOF
{
"ai_models": [],
"exchanges": [],
"traders": []
}
EOF

- name: Start services with docker compose
run: |
docker compose up -d
echo "✅ Services started, waiting for healthcheck..."

- name: Wait for healthcheck start_period
run: |
echo "⏳ Waiting 70 seconds for healthcheck start_period to complete..."
sleep 70

- name: Verify backend healthcheck
run: |
echo "🔍 Checking backend container health..."

BACKEND_HEALTH=$(docker inspect nofx-trading --format='{{.State.Health.Status}}')
echo "Backend health status: $BACKEND_HEALTH"

if [ "$BACKEND_HEALTH" != "healthy" ]; then
echo "❌ Backend container is not healthy!"
echo "Health status: $BACKEND_HEALTH"
echo ""
echo "Health logs:"
docker inspect nofx-trading --format='{{json .State.Health}}' | jq
echo ""
echo "Container logs:"
docker logs nofx-trading
exit 1
fi

echo "✅ Backend container is healthy"

- name: Verify frontend healthcheck
run: |
echo "🔍 Checking frontend container health..."

FRONTEND_HEALTH=$(docker inspect nofx-frontend --format='{{.State.Health.Status}}')
echo "Frontend health status: $FRONTEND_HEALTH"

if [ "$FRONTEND_HEALTH" != "healthy" ]; then
echo "❌ Frontend container is not healthy!"
echo "Health status: $FRONTEND_HEALTH"
echo ""
echo "Health logs:"
docker inspect nofx-frontend --format='{{json .State.Health}}' | jq
echo ""
echo "Container logs:"
docker logs nofx-frontend
exit 1
fi

echo "✅ Frontend container is healthy"

- name: Verify healthcheck commands are Alpine-compatible
run: |
echo "🔍 Verifying healthcheck commands use Alpine-compatible tools..."

# Check that docker-compose.yml uses wget (not curl)
if grep -q 'test:.*curl' docker-compose.yml; then
echo "❌ ERROR: docker-compose.yml uses 'curl' which doesn't exist in Alpine!"
echo ""
echo "Alpine Linux (used by our containers) includes 'wget' but not 'curl'."
echo "Please use 'wget --no-verbose --tries=1 --spider' instead."
exit 1
fi

if ! grep -q 'test:.*wget' docker-compose.yml; then
echo "⚠️ WARNING: No wget healthcheck found in docker-compose.yml"
else
echo "✅ Healthcheck uses Alpine-compatible 'wget' command"
fi

- name: Test healthcheck commands inside containers
run: |
echo "🧪 Testing healthcheck commands directly..."

# Test backend healthcheck command
echo "Testing backend healthcheck..."
docker exec nofx-trading wget --no-verbose --tries=1 --spider http://localhost:8080/api/health
echo "✅ Backend healthcheck command works"

# Test frontend healthcheck command
echo "Testing frontend healthcheck..."
docker exec nofx-frontend wget --no-verbose --tries=1 --spider http://127.0.0.1/health
echo "✅ Frontend healthcheck command works"

- name: Show container status
if: always()
run: |
echo "📊 Final container status:"
docker ps --format "table {{.Names}}\t{{.Status}}"

- name: Show logs on failure
if: failure()
run: |
echo "📋 Backend logs:"
docker logs nofx-trading
echo ""
echo "📋 Frontend logs:"
docker logs nofx-frontend

- name: Cleanup
if: always()
run: |
docker compose down -v
rm -f .env config.json
1 change: 1 addition & 0 deletions .github/workflows/pr-template-suggester.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:

permissions:
pull-requests: write
issues: write
contents: read

jobs:
Expand Down
20 changes: 1 addition & 19 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,10 @@ Thumbs.db
# 环境变量
.env
config.json
<<<<<<< HEAD
config.db
.tool-versions
=======
config.db*
nofx.db
configbak.json

# 生产配置
nginx/
certs/
beta_codes.txt

# 密钥文件
keys/
*.key
*.pem
>>>>>>> beta

# 决策日志
decision_logs/
coin_pool_cache/
Expand All @@ -59,9 +44,6 @@ web/node_modules/
node_modules/
web/dist/
web/.vite/
<<<<<<< HEAD
web/yarn.lock
=======

# ESLint 临时报告文件(调试时生成,不纳入版本控制)
eslint-*.json
Expand Down Expand Up @@ -140,4 +122,4 @@ dmypy.json

# Pyre type checker
.pyre/
>>>>>>> beta
PR_DESCRIPTION.md
1 change: 0 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,6 @@ Reviewers will check:

- [Project Roadmap](docs/roadmap/README.md)
- [Architecture Documentation](docs/architecture/README.md)
- [API Documentation](docs/api/README.md)
- [Deployment Guide](docs/getting-started/docker-deploy.en.md)

---
Expand Down
52 changes: 2 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

**Languages:** [English](README.md) | [中文](docs/i18n/zh-CN/README.md) | [Українська](docs/i18n/uk/README.md) | [Русский](docs/i18n/ru/README.md) | [日本語](docs/i18n/ja/README.md)

**Official Twitter:** [@nofx_ai](https://x.com/nofx_ai)

**📚 Documentation:** [Docs Home](docs/README.md) | [Getting Started](docs/getting-started/README.md) | [Prompt Writing Guide](docs/prompt-guide.md) ([中文](docs/prompt-guide.zh-CN.md)) | [Changelog](CHANGELOG.md) | [Contributing](CONTRIBUTING.md) | [Security](SECURITY.md)

---
Expand All @@ -31,7 +29,6 @@
- [🧠 AI Self-Learning](#-ai-self-learning-example)
- [📊 Web Interface Features](#-web-interface-features)
- [🎛️ API Endpoints](#️-api-endpoints)
- [🔐 Admin Mode (Single-User)](#-admin-mode-single-user)
- [⚠️ Important Risk Warnings](#️-important-risk-warnings)
- [🛠️ Common Issues](#️-common-issues)
- [📈 Performance Tips](#-performance-optimization-tips)
Expand All @@ -56,15 +53,12 @@
### 👥 Core Team

- **Tinkle** - [@Web3Tinkle](https://x.com/Web3Tinkle)
- **Zack** - [@0x_ZackH](https://x.com/0x_ZackH)

### 💼 Seed Funding Round Open

We are currently raising our **seed round**.

**For investment inquiries**, please DM **Tinkle** or **Zack** via Twitter.
We are currently raising our **seed round**.

**For partnerships and collaborations**, please DM our official Twitter [@nofx_ai](https://x.com/nofx_ai).
**For investment inquiries**, please DM **Tinkle** via Twitter.

---

Expand Down Expand Up @@ -245,48 +239,6 @@ NOFX is built with a modern, modular architecture:

---

## 🔐 Admin Mode (Single-User)

For self-hosted or single-tenant setups, NOFX supports a strict admin-only mode that disables public features and requires an admin password for all access.

### How it works
- All API endpoints require a valid JWT when `admin_mode=true`, except:
- `GET /api/health`
- `GET /api/config`
- `POST /api/admin-login`
- Logout invalidates the current token via an in-memory blacklist (sufficient for single instance; use Redis for multi-instance – see Notes).

### Quick setup
1) Set flags in `config.json`:
```jsonc
{
// ... other config
"admin_mode": true,
"jwt_secret": "YOUR_JWT_SCR"
}
```

2) Provide required environment variables:
- `NOFX_ADMIN_PASSWORD` — plaintext admin password (only used at startup to derive a bcrypt hash)

Docker Compose example (already wired):
```yaml
services:
nofx:
environment:
- NOFX_ADMIN_PASSWORD=${NOFX_ADMIN_PASSWORD}
```

1) Login flow (admin mode):
- Open the web UI → you’ll be redirected to the login page
- Enter admin password → the server returns a JWT
- The UI stores the token and authenticates subsequent API calls

### Notes
- Token lifetime: 24h. On logout, tokens are blacklisted in-memory until expiry. For multi-instance deployments, use a shared store (e.g., Redis) to sync the blacklist.

---

## 💰 Register Binance Account (Save on Fees!)

Before using this system, you need a Binance Futures account. **Use our referral link to save on trading fees:**
Expand Down
Loading
Loading