Skip to content

Navigation Menu

Sign in
Sign up

fix(legal): add default user agreement + privacy policy to brand-config - #206

Open
TThranduil1 wants to merge 2 commits into
OpenByteInc:main from
TThranduil1:fix/legal-defaults
Open

fix(legal): add default user agreement + privacy policy to brand-config #206
TThranduil1 wants to merge 2 commits into
OpenByteInc:main from
TThranduil1:fix/legal-defaults

Conversation

@TThranduil1

@TThranduil1 TThranduil1 commented Aug 13, 2026

Copy link
Copy Markdown

Summary

/api/settings/brand-config was returning all-empty legal fields (user_agreement_url, privacy_policy_url, user_agreement_text, privacy_policy_text all ""). This is a compliance gap for a platform handling real funds.

Changes

  • branding.py: add legal defaults to BRAND_DEFAULTS so the public brand-config API returns non-empty legal metadata out of the box. Operators can still override via BRAND_LEGAL_* env vars.
    • user_agreement_url/legal/user-agreement
    • privacy_policy_url/legal/privacy-policy
    • Both *_text fields get a summary string (full pages should be created at the URLs)
  • env.example: fill in BRAND_LEGAL_* defaults so operators see the expected values

Verified

Live curl https://quant.kai.com/api/settings/brand-config | jq .data.legal returned all empty before this fix.

Related

Thranduil added 2 commits August 13, 2026 16:18
...onfig
The /api/settings/brand-config endpoint was returning empty legal fields
(user_agreement_url, privacy_policy_url, user_agreement_text,
privacy_policy_text all blank). This is a compliance gap for a trading
platform handling real funds.
- branding.py: add legal defaults to BRAND_DEFAULTS (summary text + URLs
 pointing to /legal/user-agreement and /legal/privacy-policy), so the
 public brand-config API returns non-empty legal metadata out of the box
- env.example: fill in the BRAND_LEGAL_* defaults so operators see the
 expected values
...wire guard into order gateway
### Platform-level risk guard (app/services/risk_guard.py)
- New RiskGuard module: 5 hard rules — drawdown halt (default 20%),
 single-symbol position ratio cap (30%), martingale layer/leverage
 lock (6 layers / 4x), order notional + ratio cap (100k / 10%),
 sliding-window rate limit (20 orders/60s)
- All thresholds configurable via RISK_GUARD_* env vars
- Thread-safe singleton (RiskGuard.shared())
- Fail-open design: if account snapshot is unavailable, guard skips
 rather than blocking trading
### Frontend error monitoring endpoint (app/routes/error_reports.py)
- POST /api/v2/errors — receives batched frontend error events
 (window.onerror, unhandledrejection, resource errors, trade/strategy
 crashes). No auth (errors can happen pre-login). Rate-limited by
 payload size cap (50 events/batch, 4k chars/field)
- GET /api/v2/errors/stats — lightweight ops counter
- Registered in openapi/register.py + tags.py as ErrorReports tag
### Risk guard integration (app/services/strategy_v2/live_execution.py)
- StrategyV2OrderGateway.submit() now calls _check_risk_guard() after
 _validate() and before persisting the pending order
- Fetches best-effort account snapshot to evaluate drawdown/position
 ratio; infers martingale state from action prefix
- Blocked orders raise ValueError('strategyV2.riskGuardBlocked: ...')
 so the caller can surface the reason to the AI strategy review
Related frontend PR: OpenByteInc/QuantDinger-Vue#8 (error_monitor.js
reports to this /api/v2/errors endpoint)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

1 participant

AltStyle によって変換されたページ (->オリジナル) /