Save ticker and last decision to DB; add order suggestion UI; upsert stocks with execution details; ensure analysis saves ticker

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-05-16 14:06:45 +02:00
parent 3a681fa309
commit 24c7ee2bf1
3 changed files with 66 additions and 7 deletions
+38
View File
@@ -116,6 +116,15 @@ export default function StockDetail() {
setDecision(null);
try {
// Ensure ticker is saved in DB before analysis
try {
const fd = new FormData();
fd.append("ticker", ticker);
await fetch("/api/stocks", { method: "POST", body: fd });
} catch (e) {
console.warn("Failed to ensure ticker saved:", e);
}
const res = await fetch("/api/analyze", {
method: "POST",
headers: { "Content-Type": "application/json" },
@@ -134,6 +143,18 @@ export default function StockDetail() {
setAnalystReports(reports);
setDebateRounds(debates);
setDecision(data);
// Save last decision/explanation to DB
try {
const fd2 = new FormData();
fd2.append("ticker", ticker);
fd2.append("lastDecision", data.action ?? "");
fd2.append("lastExplanation", data.reasoning ?? "");
if (data.executionPlan) fd2.append("lastExecutionPlan", JSON.stringify(data.executionPlan));
await fetch("/api/stocks", { method: "POST", body: fd2 });
} catch (e) {
console.warn("Failed to save decision to DB:", e);
}
// Cache the results
sessionStorage.setItem(cacheKey, JSON.stringify({
@@ -375,6 +396,23 @@ export default function StockDetail() {
<div>Note: <span className="font-medium">{decision.executionPlan.note}</span></div>
)}
</div>
{/* Order suggestion summary */}
<div className="mt-3 bg-gray-50 rounded-lg p-3 border border-gray-200">
<h5 className="text-sm font-medium text-gray-800">Order Suggestion</h5>
<div className="text-sm text-gray-700 mt-2">
<div>
<span className="font-medium">{decision.action.toUpperCase()}</span>
{decision.executionPlan.amount} shares
{decision.executionPlan.takeProfit != null && (
<span> Take profit: ${decision.executionPlan.takeProfit}</span>
)}
</div>
{decision.executionPlan.riskManagement?.maxLossPercent != null && (
<div className="text-xs text-gray-500">Risk: {decision.executionPlan.riskManagement.maxLossPercent}% max loss</div>
)}
</div>
</div>
</div>
)}
</div>
+20 -2
View File
@@ -23,8 +23,26 @@ export async function action({ request }: { request: Request }) {
return Response.json({ success: true });
}
const stock = await db.stock.create({
data: { ticker },
// Optional fields to save/update
const lastDecision = formData.get("lastDecision")?.toString();
const lastExplanation = formData.get("lastExplanation")?.toString();
const lastExecutionPlan = formData.get("lastExecutionPlan")?.toString();
// Upsert the stock record so ticker is ensured and optional fields are saved
const stock = await db.stock.upsert({
where: { ticker },
update: {
lastDecision: lastDecision ?? undefined,
lastExplanation: lastExplanation ?? undefined,
lastExecutionPlan: lastExecutionPlan ?? undefined,
},
create: {
ticker,
lastDecision: lastDecision ?? undefined,
lastExplanation: lastExplanation ?? undefined,
lastExecutionPlan: lastExecutionPlan ?? undefined,
},
});
return Response.json(stock);
}
+8 -5
View File
@@ -9,9 +9,12 @@ datasource db {
}
model Stock {
id String @id @default(cuid())
ticker String @unique
notes String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
ticker String @unique
notes String?
lastDecision String?
lastExplanation String?
lastExecutionPlan String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}