|
@@ -41,7 +41,7 @@ export class CapturesService {
|
|
|
const validKey = await this.deviceRepo.verifyApiKey(device.apiKeyHash, apiKey)
|
|
const validKey = await this.deviceRepo.verifyApiKey(device.apiKeyHash, apiKey)
|
|
|
if (!validKey) throw new UnauthorizedException('Invalid API key')
|
|
if (!validKey) throw new UnauthorizedException('Invalid API key')
|
|
|
if (!device.projectId || !device.orgId) throw new BadRequestException('Device not assigned to a project')
|
|
if (!device.projectId || !device.orgId) throw new BadRequestException('Device not assigned to a project')
|
|
|
- return device
|
|
|
|
|
|
|
+ return device as Required<Pick<typeof device, 'id' | 'projectId' | 'orgId' | 'serialNo' | 'name'>>
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async handleUpload(params: {
|
|
async handleUpload(params: {
|
|
@@ -66,30 +66,30 @@ export class CapturesService {
|
|
|
const dateStr = new Date(params.capturedAt).toISOString().slice(0, 10)
|
|
const dateStr = new Date(params.capturedAt).toISOString().slice(0, 10)
|
|
|
const ext = path.extname(params.file.originalname) || '.jpg'
|
|
const ext = path.extname(params.file.originalname) || '.jpg'
|
|
|
const id = crypto.randomUUID().slice(0, 12)
|
|
const id = crypto.randomUUID().slice(0, 12)
|
|
|
- const storagePath = path.join(this.uploadDir, device.projectId, dateStr)
|
|
|
|
|
|
|
+ const storagePath = path.join(this.uploadDir, device.projectId!, dateStr)
|
|
|
fs.mkdirSync(storagePath, { recursive: true })
|
|
fs.mkdirSync(storagePath, { recursive: true })
|
|
|
|
|
|
|
|
- const fileKey = `${device.projectId}/${dateStr}/${id}${ext}`
|
|
|
|
|
|
|
+ const fileKey = `${device.projectId!}/${dateStr}/${id}${ext}`
|
|
|
const destPath = path.join(this.uploadDir, fileKey)
|
|
const destPath = path.join(this.uploadDir, fileKey)
|
|
|
fs.renameSync(params.file.path, destPath)
|
|
fs.renameSync(params.file.path, destPath)
|
|
|
|
|
|
|
|
const capture = await this.repo.createCapture({
|
|
const capture = await this.repo.createCapture({
|
|
|
- projectId: device.projectId,
|
|
|
|
|
|
|
+ projectId: device.projectId!,
|
|
|
deviceId: params.deviceId,
|
|
deviceId: params.deviceId,
|
|
|
capturedAt: new Date(params.capturedAt),
|
|
capturedAt: new Date(params.capturedAt),
|
|
|
fileKey,
|
|
fileKey,
|
|
|
checksum,
|
|
checksum,
|
|
|
- resolution: params.resolution ?? null,
|
|
|
|
|
|
|
+ resolution: params.resolution ?? undefined,
|
|
|
fileSizeBytes: params.file.size,
|
|
fileSizeBytes: params.file.size,
|
|
|
- exposureMs: params.exposureMs ?? null,
|
|
|
|
|
- iso: params.iso ?? null,
|
|
|
|
|
- aperture: params.aperture ?? null,
|
|
|
|
|
- gpsLat: params.gpsLat ?? null,
|
|
|
|
|
- gpsLng: params.gpsLng ?? null,
|
|
|
|
|
|
|
+ exposureMs: params.exposureMs ?? undefined,
|
|
|
|
|
+ iso: params.iso ?? undefined,
|
|
|
|
|
+ aperture: params.aperture ?? undefined,
|
|
|
|
|
+ gpsLat: params.gpsLat ?? undefined,
|
|
|
|
|
+ gpsLng: params.gpsLng ?? undefined,
|
|
|
metadata: { originalFilename: params.file.originalname, uploadedAt: new Date().toISOString() },
|
|
metadata: { originalFilename: params.file.originalname, uploadedAt: new Date().toISOString() },
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- this.realtime.emitCaptureUploaded(params.deviceId, device.projectId, capture.id)
|
|
|
|
|
|
|
+ this.realtime.emitCaptureUploaded(params.deviceId, device.projectId!, capture.id)
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
|
captureId: capture.id,
|
|
captureId: capture.id,
|
|
@@ -117,21 +117,21 @@ export class CapturesService {
|
|
|
const device = await this.validateDeviceApiKey(params.deviceId, params.apiKey)
|
|
const device = await this.validateDeviceApiKey(params.deviceId, params.apiKey)
|
|
|
|
|
|
|
|
const capture = await this.repo.createCapture({
|
|
const capture = await this.repo.createCapture({
|
|
|
- projectId: device.projectId,
|
|
|
|
|
|
|
+ projectId: device.projectId!,
|
|
|
deviceId: params.deviceId,
|
|
deviceId: params.deviceId,
|
|
|
capturedAt: new Date(params.capturedAt),
|
|
capturedAt: new Date(params.capturedAt),
|
|
|
fileKey: params.fileKey,
|
|
fileKey: params.fileKey,
|
|
|
- checksum: params.checksum ?? null,
|
|
|
|
|
- resolution: params.resolution ?? null,
|
|
|
|
|
- fileSizeBytes: params.fileSizeBytes ?? null,
|
|
|
|
|
- exposureMs: params.exposureMs ?? null,
|
|
|
|
|
- iso: params.iso ?? null,
|
|
|
|
|
- aperture: params.aperture ?? null,
|
|
|
|
|
- gpsLat: params.gpsLat ?? null,
|
|
|
|
|
- gpsLng: params.gpsLng ?? null,
|
|
|
|
|
|
|
+ checksum: params.checksum ?? undefined,
|
|
|
|
|
+ resolution: params.resolution ?? undefined,
|
|
|
|
|
+ fileSizeBytes: params.fileSizeBytes ?? undefined,
|
|
|
|
|
+ exposureMs: params.exposureMs ?? undefined,
|
|
|
|
|
+ iso: params.iso ?? undefined,
|
|
|
|
|
+ aperture: params.aperture ?? undefined,
|
|
|
|
|
+ gpsLat: params.gpsLat ?? undefined,
|
|
|
|
|
+ gpsLng: params.gpsLng ?? undefined,
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- this.realtime.emitCaptureUploaded(params.deviceId, device.projectId, capture.id)
|
|
|
|
|
|
|
+ this.realtime.emitCaptureUploaded(params.deviceId, device.projectId!, capture.id)
|
|
|
|
|
|
|
|
return { captureId: capture.id, fileKey: params.fileKey }
|
|
return { captureId: capture.id, fileKey: params.fileKey }
|
|
|
}
|
|
}
|