feat: TTLock — scan TTHotel sources for API config (CE_ConfigServer)

- Agent: ttlock:find_api_config command scans TTHotel app JS files
  for CE_ConfigServer calls, oauth2 endpoints, API server URLs
- Backend: POST /ttlock/find-api-config route
- UI: Search button on each workstation row to trigger scan

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-02 11:10:40 +03:00
parent 92821a8436
commit ee7e515f61
3 changed files with 62 additions and 1 deletions

View File

@@ -619,6 +619,9 @@ export const api = {
testApi: (slug: string, workstationId: string) =>
req<{ ok: boolean; lockCount?: number }>('POST', `/api/hotels/${slug}/ttlock/test-api`, { workstation_id: workstationId }),
findApiConfig: (slug: string, workstationId: string) =>
req<{ ok: boolean; appDir?: string; results?: { path: string; matches: string[] }[] }>('POST', `/api/hotels/${slug}/ttlock/find-api-config`, { workstation_id: workstationId }),
dllInfo: (slug: string, workstationId: string) =>
req<{ ok: boolean; content: string; path: string }>('GET', `/api/hotels/${slug}/ttlock/dll-info?workstation_id=${workstationId}`),

View File

@@ -3,7 +3,7 @@ import * as XLSX from 'xlsx'
import {
KeyRound, Save, RefreshCw, Check, X, AlertCircle,
ChevronDown, ChevronRight, Trash2, Plus, Eye, EyeOff,
Lock, Unlock, Info, HardDriveDownload, Zap, Terminal, Upload, Globe,
Lock, Unlock, Info, HardDriveDownload, Zap, Terminal, Upload, Globe, Search,
} from 'lucide-react'
import { api, type TTLockConfig, type RoomLockMapping, type Workstation } from '../lib/api'
import { useAuth } from '../contexts/AuthContext'
@@ -633,6 +633,35 @@ export function TTLockPage() {
>
<Terminal size={13} />
</button>
{/* Find TTHotel API config */}
<button
type="button"
disabled={!ws.isOnline}
onClick={async () => {
setError(null)
try {
const result = await api.ttlock.findApiConfig(slug, ws.id)
if (!result.results?.length) {
showSuccess('Ничего не найдено в исходниках TTHotel')
return
}
const out = result.results.map(r =>
`📄 ${r.path}\n${r.matches.join('\n')}`
).join('\n\n')
// Выводим в консоль браузера и в alert для простоты
console.log('[TTHotel API config scan]\n', out)
alert(`Найдено в TTHotel (см. консоль браузера):\n\n${out.slice(0, 2000)}`)
} catch (e) {
const msg = e instanceof Error ? e.message : 'Ошибка сканирования'
setError(msg)
}
}}
className="btn-secondary p-1.5 shrink-0"
title={!ws.isOnline ? 'Агент офлайн' : 'Найти API-сервер TTHotel в исходниках'}
>
<Search size={13} />
</button>
</div>
)
})}