fixed docker
This commit is contained in:
@@ -90,7 +90,7 @@ export async function POST(request: NextRequest) {
|
||||
status: "failed",
|
||||
error: "OpenAI API key not configured",
|
||||
timeline: timeline.map((item) =>
|
||||
item.status === "running" ? { ...item, status: "failed" } : item
|
||||
item.status === "running" ? { ...item, status: "failed" as const } : item
|
||||
),
|
||||
},
|
||||
{ token }
|
||||
@@ -259,7 +259,7 @@ export async function POST(request: NextRequest) {
|
||||
status: "failed",
|
||||
error: error.message || "Manual analysis failed",
|
||||
timeline: timeline.map((item) =>
|
||||
item.status === "running" ? { ...item, status: "failed" } : item
|
||||
item.status === "running" ? { ...item, status: "failed" as const } : item
|
||||
),
|
||||
},
|
||||
{ token }
|
||||
|
||||
@@ -89,7 +89,7 @@ export async function POST(request: NextRequest) {
|
||||
status: "failed",
|
||||
error: "OpenAI API key not configured",
|
||||
timeline: timeline.map((item) =>
|
||||
item.status === "running" ? { ...item, status: "failed" } : item
|
||||
item.status === "running" ? { ...item, status: "failed" as const } : item
|
||||
),
|
||||
},
|
||||
{ token }
|
||||
@@ -270,7 +270,7 @@ export async function POST(request: NextRequest) {
|
||||
status: "failed",
|
||||
error: error.message || "Analysis failed",
|
||||
timeline: timeline.map((item) =>
|
||||
item.status === "running" ? { ...item, status: "failed" } : item
|
||||
item.status === "running" ? { ...item, status: "failed" as const } : item
|
||||
),
|
||||
},
|
||||
{ token }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Checkout } from "@polar-sh/nextjs";
|
||||
import { NextResponse } from "next/server";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
export const GET = async () => {
|
||||
export const GET = async (request: NextRequest) => {
|
||||
if (!process.env.POLAR_ACCESS_TOKEN || !process.env.POLAR_SUCCESS_URL) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
@@ -17,5 +17,5 @@ export const GET = async () => {
|
||||
successUrl: process.env.POLAR_SUCCESS_URL,
|
||||
});
|
||||
|
||||
return handler();
|
||||
return handler(request);
|
||||
};
|
||||
|
||||
@@ -39,6 +39,7 @@ const bodySchema = z.object({
|
||||
})
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
let ageFilters: SerperAgeFilter | undefined
|
||||
try {
|
||||
const requestId = request.headers.get("x-request-id") ?? undefined;
|
||||
if (!(await isAuthenticatedNextjs())) {
|
||||
@@ -51,7 +52,7 @@ export async function POST(request: NextRequest) {
|
||||
|
||||
const body = await request.json()
|
||||
const { analysis, minAgeDays, maxAgeDays } = bodySchema.parse(body)
|
||||
const ageFilters: SerperAgeFilter = {
|
||||
ageFilters = {
|
||||
minAgeDays,
|
||||
maxAgeDays,
|
||||
}
|
||||
@@ -287,15 +288,15 @@ async function analyzeOpportunities(
|
||||
const relevanceScore = Math.min(keywordScore + problemScore, 1)
|
||||
|
||||
// Determine intent
|
||||
let intent: Opportunity['intent'] = 'looking-for'
|
||||
let intent: Opportunity['intent'] = 'looking'
|
||||
if (content.includes('frustrated') || content.includes('hate') || content.includes('sucks')) {
|
||||
intent = 'frustrated'
|
||||
} else if (content.includes('alternative') || content.includes('switching')) {
|
||||
intent = 'alternative'
|
||||
intent = 'comparing'
|
||||
} else if (content.includes('vs') || content.includes('comparison') || content.includes('better')) {
|
||||
intent = 'comparison'
|
||||
intent = 'comparing'
|
||||
} else if (content.includes('how to') || content.includes('fix') || content.includes('solution')) {
|
||||
intent = 'problem-solving'
|
||||
intent = 'learning'
|
||||
}
|
||||
|
||||
// Find matching persona
|
||||
@@ -305,16 +306,21 @@ async function analyzeOpportunities(
|
||||
|
||||
if (relevanceScore >= 0.3) {
|
||||
opportunities.push({
|
||||
id: result.url,
|
||||
title: result.title,
|
||||
url: result.url,
|
||||
platform: result.source,
|
||||
source: result.source,
|
||||
snippet: result.snippet.slice(0, 300),
|
||||
relevanceScore,
|
||||
painPoints: matchedProblems.slice(0, 3),
|
||||
suggestedApproach: generateApproach(intent, analysis.productName),
|
||||
matchedKeywords: matchedKeywords.slice(0, 5),
|
||||
matchedProblems: matchedProblems.slice(0, 3),
|
||||
matchedPersona,
|
||||
intent
|
||||
intent,
|
||||
emotionalIntensity: intent === 'frustrated' ? 'high' : matchedProblems.length > 0 ? 'medium' : 'low',
|
||||
status: 'new',
|
||||
suggestedApproach: generateApproach(intent, analysis.productName),
|
||||
softPitch: false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { Inter } from 'next/font/google'
|
||||
import './globals.css'
|
||||
import ConvexClientProvider from './ConvexClientProvider'
|
||||
import { ConvexAuthNextjsServerProvider } from "@convex-dev/auth/nextjs/server";
|
||||
import { ThemeProvider } from "@/components/theme-provider";
|
||||
|
||||
const inter = Inter({ subsets: ['latin'] })
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Sanati - Find Product Opportunities',
|
||||
description: 'AI-powered product research and opportunity finding',
|
||||
@@ -20,7 +17,7 @@ export default function RootLayout({
|
||||
return (
|
||||
<ConvexAuthNextjsServerProvider>
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<body className={inter.className}>
|
||||
<body className="font-sans">
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="dark"
|
||||
|
||||
@@ -69,19 +69,19 @@ export default function OnboardingPage() {
|
||||
|
||||
try {
|
||||
await createAnalysis({
|
||||
projectId: resolved.projectId,
|
||||
dataSourceId: resolved.sourceId,
|
||||
projectId: resolved.projectId as any,
|
||||
dataSourceId: resolved.sourceId as any,
|
||||
analysis,
|
||||
})
|
||||
|
||||
await updateDataSourceStatus({
|
||||
dataSourceId: resolved.sourceId,
|
||||
dataSourceId: resolved.sourceId as any,
|
||||
analysisStatus: 'completed',
|
||||
lastAnalyzedAt: Date.now(),
|
||||
})
|
||||
} catch (err: any) {
|
||||
await updateDataSourceStatus({
|
||||
dataSourceId: resolved.sourceId,
|
||||
dataSourceId: resolved.sourceId as any,
|
||||
analysisStatus: 'failed',
|
||||
lastError: err?.message || 'Failed to save analysis',
|
||||
lastAnalyzedAt: Date.now(),
|
||||
@@ -106,7 +106,7 @@ export default function OnboardingPage() {
|
||||
})
|
||||
|
||||
await updateDataSourceStatus({
|
||||
dataSourceId: sourceId,
|
||||
dataSourceId: sourceId as any,
|
||||
analysisStatus: 'pending',
|
||||
lastError: undefined,
|
||||
lastAnalyzedAt: undefined,
|
||||
@@ -116,8 +116,8 @@ export default function OnboardingPage() {
|
||||
setPendingProjectId(projectId)
|
||||
|
||||
const jobId = await createAnalysisJob({
|
||||
projectId,
|
||||
dataSourceId: sourceId,
|
||||
projectId: projectId as any,
|
||||
dataSourceId: sourceId as any,
|
||||
})
|
||||
setPendingJobId(jobId)
|
||||
|
||||
@@ -175,7 +175,7 @@ export default function OnboardingPage() {
|
||||
setError(err.message || 'Failed to analyze website')
|
||||
if (pendingSourceId && !manualFallback) {
|
||||
await updateDataSourceStatus({
|
||||
dataSourceId: pendingSourceId,
|
||||
dataSourceId: pendingSourceId as any,
|
||||
analysisStatus: 'failed',
|
||||
lastError: err?.message || 'Failed to analyze',
|
||||
lastAnalyzedAt: Date.now(),
|
||||
@@ -255,8 +255,8 @@ export default function OnboardingPage() {
|
||||
|
||||
if (!resolvedJobId && resolvedProjectId && resolvedSourceId) {
|
||||
resolvedJobId = await createAnalysisJob({
|
||||
projectId: resolvedProjectId,
|
||||
dataSourceId: resolvedSourceId,
|
||||
projectId: resolvedProjectId as any,
|
||||
dataSourceId: resolvedSourceId as any,
|
||||
})
|
||||
setPendingJobId(resolvedJobId)
|
||||
}
|
||||
@@ -307,8 +307,8 @@ export default function OnboardingPage() {
|
||||
analysis: finalAnalysis,
|
||||
sourceUrl: manualSourceUrl,
|
||||
sourceName: finalAnalysis.productName,
|
||||
projectId: resolvedProjectId || undefined,
|
||||
dataSourceId: resolvedSourceId || undefined,
|
||||
projectId: (resolvedProjectId || undefined) as any,
|
||||
dataSourceId: (resolvedSourceId || undefined) as any,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -324,7 +324,7 @@ export default function OnboardingPage() {
|
||||
setError(err.message || 'Failed to analyze')
|
||||
if (pendingSourceId) {
|
||||
await updateDataSourceStatus({
|
||||
dataSourceId: pendingSourceId,
|
||||
dataSourceId: pendingSourceId as any,
|
||||
analysisStatus: 'failed',
|
||||
lastError: err?.message || 'Failed to analyze',
|
||||
lastAnalyzedAt: Date.now(),
|
||||
|
||||
Reference in New Issue
Block a user