push to develop

This commit is contained in:
Jun-te Kim 2025-11-03 19:08:05 +00:00
parent 3583b5ab53
commit d2d7c9576a
2 changed files with 184 additions and 56 deletions

View file

@ -1,40 +1,33 @@
// app/api/book-survey/route.ts
import { NextResponse } from "next/server";
import { db } from "@/app/db/db";
import { propertyStatusTracker } from "@/app/db/schema/crm/property_status_tracker";
import { eq, and } from "drizzle-orm";
import { user } from "@/app/db/schema/users";
export async function POST(req: Request) {
console.log("📩 Incoming POST /api/property-status request");
try {
const { dealName, pipelineId, dealStageId, propertyId, portfolioId } =
await req.json();
const {
pipelineId,
dealStageId,
propertyId,
portfolioId,
userInfo,
propertyMeta,
} = await req.json();
// 1⃣ Create HubSpot deal
const hsRes = await fetch("https://api.hubapi.com/crm/v3/objects/deals", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.HUBSPOT_API_KEY}`,
},
body: JSON.stringify({
properties: {
dealname: dealName,
pipeline: pipelineId,
dealstage: dealStageId,
},
}),
console.log("🧠 Parsed body:", {
pipelineId,
dealStageId,
propertyId,
portfolioId,
userInfo,
propertyMeta,
});
if (!hsRes.ok) {
const err = await hsRes.text();
throw new Error(`HubSpot error: ${err}`);
}
const hsData = await hsRes.json();
const hubspotDealId = hsData.id;
// 2⃣ Check if record exists for property + portfolio
// 1⃣ Check if record exists first
console.log("🔍 Checking if record already exists in DB...");
const existing = await db
.select()
.from(propertyStatusTracker)
@ -45,32 +38,170 @@ export async function POST(req: Request) {
)
);
console.log("🗃️ Existing record check result:", existing);
if (existing.length > 0) {
// 3⃣ Update existing record
await db
.update(propertyStatusTracker)
.set({
hubspotDealId,
updatedAt: new Date(),
})
.where(
and(
eq(propertyStatusTracker.propertyId, propertyId),
eq(propertyStatusTracker.portfolioId, portfolioId)
)
);
} else {
// 4⃣ Create new record
await db.insert(propertyStatusTracker).values({
hubspotDealId: hubspotDealId,
propertyId: propertyId,
portfolioId: portfolioId,
console.log("⚠️ Record already exists, skipping deal creation");
return NextResponse.json({
message: "Record already exists, no new deal created",
dealId: existing[0].hubspotDealId,
});
}
// 2⃣ Create HubSpot deal
console.log("🧱 Creating HubSpot deal...");
const dealRes = await fetch("https://api.hubapi.com/crm/v3/objects/deals", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.HUBSPOT_API_KEY}`,
},
body: JSON.stringify({
properties: {
dealname: propertyMeta?.address || "New Property Deal",
pipeline: pipelineId,
dealstage: dealStageId,
},
}),
});
console.log("📡 HubSpot deal response status:", dealRes.status);
if (!dealRes.ok) {
const err = await dealRes.text();
console.error("❌ HubSpot Deal creation failed:", err);
throw new Error(`HubSpot Deal Error: ${err}`);
}
const dealData = await dealRes.json();
const hubspotDealId = dealData.id;
console.log("✅ Created HubSpot deal:", hubspotDealId);
// 3⃣ Retrieve user info from your DB
console.log("👤 Fetching user info from DB...");
const userProfile = await db
.select()
.from(user)
.where(eq(user.id, userInfo.dbId))
.limit(1);
const userInfoFromDb = userProfile[0];
console.log("📇 User info from DB:", userInfoFromDb);
if (!userInfoFromDb?.email) {
console.error("❌ User email missing in DB for user:", userInfo.dbId);
throw new Error("User email not found; cannot create HubSpot contact.");
}
// 4⃣ Create or find contact in HubSpot
console.log("📞 Creating HubSpot contact...");
const contactRes = await fetch("https://api.hubapi.com/crm/v3/objects/contacts", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.HUBSPOT_API_KEY}`,
},
body: JSON.stringify({
properties: {
email: userInfoFromDb.email,
},
}),
});
let hubspotContactId: string | null = null;
console.log("📡 HubSpot contact response status:", contactRes.status);
if (contactRes.ok) {
const contactData = await contactRes.json();
hubspotContactId = contactData.id;
console.log("✅ Created new HubSpot contact:", hubspotContactId);
} else {
console.warn("⚠️ HubSpot contact creation failed — checking if contact exists...");
// Check if contact already exists
const findContactRes = await fetch(
`https://api.hubapi.com/crm/v3/objects/contacts/search`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.HUBSPOT_API_KEY}`,
},
body: JSON.stringify({
filterGroups: [
{
filters: [
{
propertyName: "email",
operator: "EQ",
value: userInfoFromDb.email,
},
],
},
],
}),
}
);
console.log("📡 HubSpot contact search response:", findContactRes.status);
if (findContactRes.ok) {
const found = await findContactRes.json();
console.log("🔎 Found contact results:", found.results);
if (found.results?.length > 0) {
hubspotContactId = found.results[0].id;
console.log("✅ Found existing HubSpot contact:", hubspotContactId);
} else {
console.error("❌ HubSpot contact creation and lookup both failed");
throw new Error("HubSpot contact creation and lookup both failed.");
}
} else {
const findErr = await findContactRes.text();
console.error("❌ HubSpot contact search failed:", findErr);
throw new Error("HubSpot contact lookup request failed.");
}
}
// 5⃣ Associate contact with deal
if (hubspotContactId) {
console.log("🔗 Associating HubSpot deal and contact...");
const assocUrl = `https://api.hubapi.com/crm/v3/objects/deals/${hubspotDealId}/associations/contacts/${hubspotContactId}/deal_to_contact`;
const assocRes = await fetch(assocUrl, {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.HUBSPOT_API_KEY}`,
"Content-Type": "application/json",
},
});
console.log("📡 HubSpot association response:", assocRes.status);
if (!assocRes.ok) {
const assocErr = await assocRes.text();
console.warn("⚠️ HubSpot association failed:", assocErr);
} else {
console.log("✅ Successfully associated contact with deal");
}
}
// 6⃣ Create DB record
console.log("🗄️ Inserting new tracker record into DB...");
await db.insert(propertyStatusTracker).values({
hubspotDealId,
propertyId,
portfolioId,
createdAt: new Date(),
updatedAt: new Date(),
});
console.log("✅ All done — returning success response");
return NextResponse.json({
message: existing.length > 0 ? "Updated existing tracker" : "Created new tracker",
message: "Created new tracker, HubSpot deal, and linked contact",
dealId: hubspotDealId,
contactId: hubspotContactId,
});
} catch (error: any) {
console.error("❌ Error creating or updating HubSpot deal:", error);

View file

@ -14,8 +14,8 @@ import { useState, useEffect } from "react";
import { useMutation } from "@tanstack/react-query";
import { PropertyMeta } from "@/app/db/schema/property";
import { cache } from "react";
import { getServerSession } from "next-auth";
import { AuthOptions } from "@/app/api/auth/[...nextauth]/authOptions";
import { useSession } from "next-auth/react";
interface BookSurveyModalProps {
open: boolean;
@ -26,10 +26,6 @@ interface BookSurveyModalProps {
onSuccess?: () => void; // ✅ fix: properly declare optional callback
}
const getSession = cache(async () => {
const session = await getServerSession(AuthOptions);
return session;
});
export default function BookSurveyModal({
open,
@ -39,9 +35,9 @@ export default function BookSurveyModal({
propertyMeta,
onSuccess, // ✅ fix: remove “?:” here, we already declared it optional in interface
}: BookSurveyModalProps) {
const { data: session, status } = useSession();
const user = getSession();
console.log(user, "user details");
const user = session?.user;
// 🧠 Simple mutation to call your HubSpot API
@ -51,11 +47,12 @@ export default function BookSurveyModal({
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
dealName: propertyMeta.address,
pipelineId: "2400089278",
dealStageId: "3660660975",
propertyId: propertyId.toString(),
portfolioId: portfolioId,
userInfo: user,
propertyMeta: propertyMeta,
}),
});