import { Router } from 'express'; import multer from 'multer'; import { asyncWrap } from '../errors.js'; import { requireOwner } from '../cap.js'; import * as whisper from '../../voice/whisper.js'; export const router = Router(); // In-memory upload; clips are small voice notes. 25 MB ceiling. const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 25 * 1024 * 1024 } }); // POST /api/voice/transcribe — owner-only. multipart field `audio`. Returns { text }. // (Phase 2b will optionally persist the clip + transcript when keepClips is on.) router.post('/transcribe', requireOwner, upload.single('audio'), asyncWrap(async (req, res) => { if (!req.file || !req.file.buffer?.length) { return res.status(400).json({ error: { code: 'no_audio', message: 'no audio supplied' } }); } try { const r = await whisper.transcribe( req.file.buffer, req.file.originalname || 'clip.webm', req.file.mimetype || 'audio/webm'); res.json({ text: r.text, duration: r.duration ?? null }); } catch { res.status(503).json({ error: { code: 'stt_unavailable', message: 'transcription service unavailable' } }); } }));