fixed docker

This commit is contained in:
2026-02-04 15:37:59 +00:00
parent 6d271ef65b
commit 025ce8f763
16 changed files with 135 additions and 93 deletions

View File

@@ -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 }

View File

@@ -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 }

View File

@@ -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);
};

View File

@@ -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
})
}
}

View File

@@ -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"

View File

@@ -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(),