Implement AC Nautik PDF Export, E2E Encrypted Photos, and Background GPS Route Tracking
This commit is contained in:
@@ -44,6 +44,8 @@ model Logbook {
|
||||
crews CrewPayload[]
|
||||
deviations DeviationPayload[]
|
||||
entries EntryPayload[]
|
||||
photos PhotoPayload[]
|
||||
gpsTracks GpsTrackPayload[]
|
||||
|
||||
@@index([userId])
|
||||
}
|
||||
@@ -94,3 +96,32 @@ model EntryPayload {
|
||||
@@unique([logbookId, payloadId])
|
||||
@@index([logbookId])
|
||||
}
|
||||
|
||||
model PhotoPayload {
|
||||
id String @id @default(uuid())
|
||||
logbookId String
|
||||
payloadId String
|
||||
entryId String
|
||||
encryptedData String
|
||||
iv String
|
||||
tag String
|
||||
updatedAt DateTime @updatedAt
|
||||
logbook Logbook @relation(fields: [logbookId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([logbookId, payloadId])
|
||||
@@index([logbookId])
|
||||
@@index([entryId])
|
||||
}
|
||||
|
||||
model GpsTrackPayload {
|
||||
id String @id @default(uuid())
|
||||
logbookId String
|
||||
entryId String @unique
|
||||
encryptedData String
|
||||
iv String
|
||||
tag String
|
||||
updatedAt DateTime @updatedAt
|
||||
logbook Logbook @relation(fields: [logbookId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([logbookId])
|
||||
}
|
||||
|
||||
@@ -152,6 +152,41 @@ router.post('/push', async (req: any, res) => {
|
||||
update: { encryptedData, iv, tag, updatedAt: itemUpdatedAt }
|
||||
})
|
||||
}
|
||||
} else if (type === 'photo') {
|
||||
if (action === 'delete') {
|
||||
await prisma.photoPayload.deleteMany({ where: { logbookId, payloadId } })
|
||||
} else {
|
||||
const existing = await prisma.photoPayload.findUnique({
|
||||
where: { logbookId_payloadId: { logbookId, payloadId } }
|
||||
})
|
||||
if (existing && new Date(existing.updatedAt) > itemUpdatedAt) {
|
||||
results.push({ payloadId, status: 'conflict', reason: 'Server version is newer' })
|
||||
continue
|
||||
}
|
||||
const entryId = parsed.entryId || ''
|
||||
await prisma.photoPayload.upsert({
|
||||
where: { logbookId_payloadId: { logbookId, payloadId } },
|
||||
create: { logbookId, payloadId, entryId, encryptedData, iv, tag, updatedAt: itemUpdatedAt },
|
||||
update: { encryptedData, iv, tag, updatedAt: itemUpdatedAt }
|
||||
})
|
||||
}
|
||||
} else if (type === 'gpsTrack') {
|
||||
if (action === 'delete') {
|
||||
await prisma.gpsTrackPayload.deleteMany({ where: { logbookId, entryId: payloadId } })
|
||||
} else {
|
||||
const existing = await prisma.gpsTrackPayload.findUnique({
|
||||
where: { entryId: payloadId }
|
||||
})
|
||||
if (existing && new Date(existing.updatedAt) > itemUpdatedAt) {
|
||||
results.push({ payloadId, status: 'conflict', reason: 'Server version is newer' })
|
||||
continue
|
||||
}
|
||||
await prisma.gpsTrackPayload.upsert({
|
||||
where: { entryId: payloadId },
|
||||
create: { logbookId, entryId: payloadId, encryptedData, iv, tag, updatedAt: itemUpdatedAt },
|
||||
update: { encryptedData, iv, tag, updatedAt: itemUpdatedAt }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
results.push({ payloadId, status: 'success' })
|
||||
@@ -193,12 +228,16 @@ router.get('/pull', async (req: any, res) => {
|
||||
const deviation = await prisma.deviationPayload.findUnique({ where: { logbookId } })
|
||||
const crews = await prisma.crewPayload.findMany({ where: { logbookId } })
|
||||
const entries = await prisma.entryPayload.findMany({ where: { logbookId } })
|
||||
const photos = await prisma.photoPayload.findMany({ where: { logbookId } })
|
||||
const gpsTracks = await prisma.gpsTrackPayload.findMany({ where: { logbookId } })
|
||||
|
||||
return res.json({
|
||||
yacht,
|
||||
deviation,
|
||||
crews,
|
||||
entries
|
||||
entries,
|
||||
photos,
|
||||
gpsTracks
|
||||
})
|
||||
} catch (error: any) {
|
||||
console.error('Error during sync pull:', error)
|
||||
|
||||
Reference in New Issue
Block a user