- Added RECORDING_TIMEOUT_MS and recordingTimeouts Map to track sessions
- Timer starts after browser is added to pool; emits recording-timeout
socket event then destroys the remote browser after 1s delay (gives
frontend time to handle the event before socket teardown)
- clearRecordingTimeout() exported and called in destroyRemoteBrowser
and the /stop/:browserId route to cancel timer on normal save/discard
- RecordingPage listens for recording-timeout: broadcasts via
BroadcastChannel then calls window.close(); falls back to
navigate('/robots') if close is blocked by the browser
- PageWrapper (always mounted in original tab) listens on
BroadcastChannel, navigates back to the page the recording was
started from (stored in sessionStorage), and shows warning notification
- RobotCreate stores current pathname in sessionStorage before opening
the recording tab so PageWrapper can navigate back on timeout
- Added timeout_discarded translation key to all 6 locale files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move LLM duplicate-name check before the expensive LLM call to avoid
burning API time/cost on a name that will be rejected anyway
- Hoist trimmedName declaration in PUT endpoint to eliminate the
redundant second name.trim() call outside the validation block
- Guard recording_meta.name type in Generator pre-check so legacy rows
with missing/non-string names don't throw; normalize both sides to
match the DB index semantics (lower + trim)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Reject whitespace-only names in all create endpoints (scrape, crawl,
search, llm) using explicit string trim + fallback instead of ||.trim()
- Validate name type and emptiness in PUT endpoint with 400 responses
- Catch SequelizeUniqueConstraintError in all create/update/Generator
paths and return 409/emit nameExists to close TOCTOU race window
- Add blank-name guard in Generator.saveNewWorkflow before DB write
- Propagate isDuplicate flag from updateRecording for i18n-aware error
display in RobotEditPage
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>