feat: per-domain backend routing

Each allowed_domains entry can now carry its own backend {host, port}.
That lets one proxy on port 25565 serve multiple MC servers, picking
the upstream from the domain the client typed.

- proxy/main.py: ProxyState.backend_for(domain) → tuple|None,
  honors per-domain backend first, falls back to top-level backend.
  handle_client uses backend_for(); blocked / disabled domains
  return None (and still get a Login Disconnect on join attempts).
- api/routes/{config,domains}.py: DomainBackend model + optional
  backend field on create/patch. PATCH supports clear_backend=true
  to drop a per-domain override and revert to default.
- frontend/Domains.jsx: full rewrite — new-domain form has host/port
  inputs, table shows each row's effective backend, inline edit +
  reset button per row.
- frontend/Settings.jsx: backend section relabeled "기본 백엔드 (fallback)"
- README updated with multi-server example config.
This commit is contained in:
2026-05-23 17:25:14 +09:00
parent 9540a3a576
commit 58b112e449
7 changed files with 228 additions and 53 deletions

View File

@@ -189,6 +189,22 @@ textarea:focus {
align-items: center;
}
.form-row input { flex: 1; }
.form-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 12px;
margin-bottom: 12px;
}
.form-grid label {
display: flex;
flex-direction: column;
gap: 4px;
color: var(--muted);
font-size: 12px;
}
.form-grid input { width: 100%; }
.inline-edit { display: flex; gap: 6px; }
.inline-edit input { padding: 4px 8px; font-size: 13px; }
.table {
width: 100%;