refactor(backend): split stream routes into focused modules

This commit is contained in:
2026-04-16 12:30:00 +01:00
parent 9a8603e5cd
commit 68ecc82bd9
11 changed files with 920 additions and 857 deletions

View File

@@ -3,7 +3,7 @@ import { Router } from 'express';
import { z } from 'zod';
import { db } from '../db/client';
import { recordings, streamSessions } from '../db/schema';
import { recordings } from '../db/schema';
import { requireDeviceAuth } from '../middleware/device-auth';
import { writeAuditLog } from '../services/audit';
import { ensureMinioBucket, minioBucket, minioClient, minioPresignedExpirySeconds } from '../utils/minio';
@@ -120,27 +120,7 @@ router.post('/:recordingId/finalize', requireDeviceAuth, async (req, res) => {
objectKey,
});
} catch (error) {
if (objectKey.startsWith('sim/')) {
console.warn('[recording.finalize] creating simulator fallback object', {
recordingId: recording.id,
bucket,
objectKey,
error: error instanceof Error ? error.message : String(error),
});
const placeholder = Buffer.from(
JSON.stringify({
message: 'simulated recording placeholder',
recordingId: recording.id,
streamSessionId: recording.streamSessionId,
createdAt: now.toISOString(),
}),
'utf8',
);
await minioClient.putObject(bucket, objectKey, placeholder, placeholder.byteLength, {
'Content-Type': 'application/json',
});
} else if (isMissingStorageObjectError(error)) {
if (isMissingStorageObjectError(error)) {
console.warn('[recording.finalize] storage object missing', {
recordingId: recording.id,
streamSessionId: recording.streamSessionId,
@@ -150,15 +130,15 @@ router.post('/:recordingId/finalize', requireDeviceAuth, async (req, res) => {
});
res.status(409).json({ message: 'Recording object does not exist in storage yet' });
return;
} else {
console.error('[recording.finalize] storage verification failed', {
recordingId: recording.id,
bucket,
objectKey,
error: error instanceof Error ? error.message : String(error),
});
throw error;
}
console.error('[recording.finalize] storage verification failed', {
recordingId: recording.id,
bucket,
objectKey,
error: error instanceof Error ? error.message : String(error),
});
throw error;
}
const [updated] = await db
@@ -272,27 +252,4 @@ router.get('/:recordingId/download-url', requireDeviceAuth, async (req, res) =>
});
});
export const createRecordingForStream = async (streamSessionId: string): Promise<void> => {
const stream = await db.query.streamSessions.findFirst({ where: eq(streamSessions.id, streamSessionId) });
if (!stream) {
return;
}
const existing = await db.query.recordings.findFirst({ where: eq(recordings.streamSessionId, stream.id) });
if (existing) {
return;
}
await db.insert(recordings).values({
ownerUserId: stream.ownerUserId,
streamSessionId: stream.id,
cameraDeviceId: stream.cameraDeviceId,
requesterDeviceId: stream.requesterDeviceId,
status: 'awaiting_upload',
updatedAt: new Date(),
});
};
export default router;