fix: AI recall-call flow, speech-to-text time parsing, and stale conversation state

- Reset conversation stage to a fresh start on every new voice call
  (recall and reminder alike), and on every hangup/timeout/goodbye,
  so an abandoned or completed call never leaves a patient stuck
  mid-flow for their next call or text.
- Add a staleness check to the SMS flow: after a long idle gap,
  check whether the patient's reply still reads as a continuation
  before resuming the stored stage, falling back to a friendly
  "it's been a while" re-greeting when unsure.
- Fix parseTime() to handle Twilio's speech-to-text output, which
  renders "pm"/"am" with periods and often drops the colon in a
  spoken time (e.g. "100 p.m." -> 1:00 PM) — this was silently
  failing and causing the AI to loop asking for a time it had
  already been given.
- Extend the voice Gather timeout so the AI doesn't hang up on a
  patient who just needs a few seconds to respond.
- Reword the recall-call opening line and rework the post-"yes"
  prompt to ask for day and time together.
- Fix rclone WebDAV server to serve only the backups folder instead
  of the entire backend app directory (was exposing .env and source).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
ff
2026-08-06 09:35:48 -04:00
co-authored by Claude Sonnet 5
parent 55ce52f276
commit 0cd095330a
7 changed files with 167 additions and 34 deletions
+8 -1
View File
@@ -46,9 +46,16 @@ export async function startWebDavServer(): Promise<void> {
const config = readRcloneConfig();
// Serve only the backups folder — never the app root, which contains
// .env (DB/Twilio/AI credentials) and the full source tree.
const backupsDir = path.join(APP_ROOT, "backups");
if (!fs.existsSync(backupsDir)) {
fs.mkdirSync(backupsDir, { recursive: true });
}
const args = [
"serve", "webdav",
APP_ROOT,
backupsDir,
"--addr", `:${config.serverPort}`,
"--user", RCLONE_USER,
"--pass", RCLONE_PASS,