Include voice recording payload in analysis
Build and deploy Worker / build (push) Successful in 53s
Build and deploy Worker / build (push) Successful in 53s
This commit is contained in:
+33
-10
@@ -17,16 +17,25 @@ enum VoiceExperienceStatus {
|
||||
}
|
||||
|
||||
model Place {
|
||||
id String @id @default(cuid())
|
||||
googlePlaceId String @unique
|
||||
name String
|
||||
latitude Float
|
||||
longitude Float
|
||||
googlePrimaryType String?
|
||||
googleTypes String[] @default([])
|
||||
experiences VoiceExperience[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
id String @id @default(cuid())
|
||||
googlePlaceId String @unique
|
||||
name String
|
||||
latitude Float
|
||||
longitude Float
|
||||
googlePrimaryType String?
|
||||
googleTypes String[] @default([])
|
||||
googleBusinessStatus String?
|
||||
googleRating Float?
|
||||
googleUserRatingCount Int?
|
||||
googleRegularOpeningHours Json?
|
||||
googleCurrentOpeningHours Json?
|
||||
googlePhotos Json?
|
||||
googlePayload Json?
|
||||
googlePayloadFetchedAt DateTime?
|
||||
experiences VoiceExperience[]
|
||||
favoriteUsers UserFavoritePlace[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model User {
|
||||
@@ -39,10 +48,22 @@ model User {
|
||||
languageCode String?
|
||||
isAdmin Boolean @default(false)
|
||||
voiceExperiences VoiceExperience[]
|
||||
favoritePlaces UserFavoritePlace[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model UserFavoritePlace {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
placeId String
|
||||
place Place @relation(fields: [placeId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([userId, placeId])
|
||||
}
|
||||
|
||||
model VoiceExperience {
|
||||
id String @id @default(cuid())
|
||||
placeId String
|
||||
@@ -57,6 +78,8 @@ model VoiceExperience {
|
||||
status VoiceExperienceStatus @default(UPLOADED)
|
||||
transcript String?
|
||||
analysis Json?
|
||||
recordingPayload Json?
|
||||
promptHintsShown String[] @default([])
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -128,6 +128,14 @@ exports.Prisma.PlaceScalarFieldEnum = {
|
||||
longitude: 'longitude',
|
||||
googlePrimaryType: 'googlePrimaryType',
|
||||
googleTypes: 'googleTypes',
|
||||
googleBusinessStatus: 'googleBusinessStatus',
|
||||
googleRating: 'googleRating',
|
||||
googleUserRatingCount: 'googleUserRatingCount',
|
||||
googleRegularOpeningHours: 'googleRegularOpeningHours',
|
||||
googleCurrentOpeningHours: 'googleCurrentOpeningHours',
|
||||
googlePhotos: 'googlePhotos',
|
||||
googlePayload: 'googlePayload',
|
||||
googlePayloadFetchedAt: 'googlePayloadFetchedAt',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
@@ -145,6 +153,13 @@ exports.Prisma.UserScalarFieldEnum = {
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.UserFavoritePlaceScalarFieldEnum = {
|
||||
id: 'id',
|
||||
userId: 'userId',
|
||||
placeId: 'placeId',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
exports.Prisma.VoiceExperienceScalarFieldEnum = {
|
||||
id: 'id',
|
||||
placeId: 'placeId',
|
||||
@@ -157,6 +172,8 @@ exports.Prisma.VoiceExperienceScalarFieldEnum = {
|
||||
status: 'status',
|
||||
transcript: 'transcript',
|
||||
analysis: 'analysis',
|
||||
recordingPayload: 'recordingPayload',
|
||||
promptHintsShown: 'promptHintsShown',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
@@ -176,16 +193,16 @@ exports.Prisma.QueryMode = {
|
||||
insensitive: 'insensitive'
|
||||
};
|
||||
|
||||
exports.Prisma.NullsOrder = {
|
||||
first: 'first',
|
||||
last: 'last'
|
||||
};
|
||||
|
||||
exports.Prisma.JsonNullValueFilter = {
|
||||
DbNull: Prisma.DbNull,
|
||||
JsonNull: Prisma.JsonNull,
|
||||
AnyNull: Prisma.AnyNull
|
||||
};
|
||||
|
||||
exports.Prisma.NullsOrder = {
|
||||
first: 'first',
|
||||
last: 'last'
|
||||
};
|
||||
exports.VoiceExperienceStatus = exports.$Enums.VoiceExperienceStatus = {
|
||||
UPLOADED: 'UPLOADED',
|
||||
TRANSCRIBING: 'TRANSCRIBING',
|
||||
@@ -198,6 +215,7 @@ exports.VoiceExperienceStatus = exports.$Enums.VoiceExperienceStatus = {
|
||||
exports.Prisma.ModelName = {
|
||||
Place: 'Place',
|
||||
User: 'User',
|
||||
UserFavoritePlace: 'UserFavoritePlace',
|
||||
VoiceExperience: 'VoiceExperience'
|
||||
};
|
||||
|
||||
|
||||
Vendored
+2433
-118
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "prisma-client-404088dc715856cb4ed2e7f2d4b8eb35c87427ce32c0e67bc04d6ff67961fc2b",
|
||||
"name": "prisma-client-baa0475e783dd87e65df5f828f4a43807c3762e0c66b9d15b841a12e00ad0bd4",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"browser": "default.js",
|
||||
|
||||
@@ -17,30 +17,51 @@ enum VoiceExperienceStatus {
|
||||
}
|
||||
|
||||
model Place {
|
||||
id String @id @default(cuid())
|
||||
googlePlaceId String @unique
|
||||
name String
|
||||
latitude Float
|
||||
longitude Float
|
||||
googlePrimaryType String?
|
||||
googleTypes String[] @default([])
|
||||
experiences VoiceExperience[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
id String @id @default(cuid())
|
||||
googlePlaceId String @unique
|
||||
name String
|
||||
latitude Float
|
||||
longitude Float
|
||||
googlePrimaryType String?
|
||||
googleTypes String[] @default([])
|
||||
googleBusinessStatus String?
|
||||
googleRating Float?
|
||||
googleUserRatingCount Int?
|
||||
googleRegularOpeningHours Json?
|
||||
googleCurrentOpeningHours Json?
|
||||
googlePhotos Json?
|
||||
googlePayload Json?
|
||||
googlePayloadFetchedAt DateTime?
|
||||
experiences VoiceExperience[]
|
||||
favoriteUsers UserFavoritePlace[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
telegramId String @unique
|
||||
id String @id @default(cuid())
|
||||
telegramId String @unique
|
||||
username String?
|
||||
firstName String?
|
||||
lastName String?
|
||||
photoUrl String?
|
||||
languageCode String?
|
||||
isAdmin Boolean @default(false)
|
||||
isAdmin Boolean @default(false)
|
||||
voiceExperiences VoiceExperience[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
favoritePlaces UserFavoritePlace[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model UserFavoritePlace {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
placeId String
|
||||
place Place @relation(fields: [placeId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([userId, placeId])
|
||||
}
|
||||
|
||||
model VoiceExperience {
|
||||
@@ -57,6 +78,8 @@ model VoiceExperience {
|
||||
status VoiceExperienceStatus @default(UPLOADED)
|
||||
transcript String?
|
||||
analysis Json?
|
||||
recordingPayload Json?
|
||||
promptHintsShown String[] @default([])
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
@@ -26,6 +26,11 @@ type PlaceAnalysis = {
|
||||
summary: string;
|
||||
};
|
||||
|
||||
type RecordingContext = {
|
||||
promptHintsShown: string[];
|
||||
recordingPayload: unknown;
|
||||
};
|
||||
|
||||
export async function analyzeVoiceExperience(experienceId: string) {
|
||||
const experience = await prisma.voiceExperience.findUnique({
|
||||
where: { id: experienceId },
|
||||
@@ -48,6 +53,8 @@ export async function analyzeVoiceExperience(experienceId: string) {
|
||||
const analysis = await buildPlaceAnalysis({
|
||||
placeName: experience.place.name,
|
||||
transcript: experience.transcript,
|
||||
promptHintsShown: experience.promptHintsShown,
|
||||
recordingPayload: experience.recordingPayload,
|
||||
});
|
||||
|
||||
await prisma.voiceExperience.update({
|
||||
@@ -64,6 +71,8 @@ export async function analyzeVoiceExperience(experienceId: string) {
|
||||
async function buildPlaceAnalysis(input: {
|
||||
placeName: string;
|
||||
transcript: string;
|
||||
promptHintsShown: string[];
|
||||
recordingPayload: unknown;
|
||||
}): Promise<PlaceAnalysis> {
|
||||
if (!config.openRouterApiKey) {
|
||||
throw new Error('OPENROUTER_API_KEY is required for voice analysis.');
|
||||
@@ -146,6 +155,7 @@ async function buildPlaceAnalysis(input: {
|
||||
},
|
||||
placeName: input.placeName,
|
||||
ontology,
|
||||
recordingContext: recordingContext(input),
|
||||
transcript: input.transcript,
|
||||
}),
|
||||
},
|
||||
@@ -174,6 +184,13 @@ async function buildPlaceAnalysis(input: {
|
||||
return analysis;
|
||||
}
|
||||
|
||||
function recordingContext(input: RecordingContext) {
|
||||
return {
|
||||
promptHintsShown: input.promptHintsShown,
|
||||
recordingPayload: input.recordingPayload,
|
||||
};
|
||||
}
|
||||
|
||||
function assertValidAnalysis(analysis: PlaceAnalysis) {
|
||||
const allowedTags = new Set(
|
||||
placeOntology.flatMap((axis) =>
|
||||
|
||||
Reference in New Issue
Block a user