48 lines
1.6 KiB
TypeScript
48 lines
1.6 KiB
TypeScript
import { defineAction } from "@agent-native/core/action";
|
|||
|
|
import { and, eq } from "@agent-native/core/db/schema";
|
||
|
|
import { z } from "zod";
|
||
|
|
|
||
|
|
import { getDb } from "../server/db/index.js";
|
||
|
|
import { stocks } from "../server/db/schema.js";
|
||
|
|
|
||
|
|
export default defineAction({
|
||
|
|
description:
|
||
|
|
"Update fields on an existing stock listing (patch — only pass the fields that change). Use this to edit price, change percent, sector, or toggle the watchlist.",
|
||
|
|
schema: z.object({
|
||
|
|
id: z.string().describe("Stock listing id"),
|
||
|
|
companyName: z.string().optional(),
|
||
|
|
exchange: z.string().optional(),
|
||
|
|
sector: z.string().optional(),
|
||
|
|
currency: z.string().optional(),
|
||
|
|
price: z.coerce.number().optional(),
|
||
|
|
changePercent: z.coerce.number().optional(),
|
||
|
|
marketCap: z.coerce.number().optional(),
|
||
|
|
watchlisted: z
|
||
|
|
.enum(["true", "false"])
|
||
|
|
.optional()
|
||
|
|
.describe("Set to \"true\" or \"false\" to toggle the watchlist"),
|
||
|
|
}),
|
||
|
|
http: { method: "PUT" },
|
||
|
|
run: async (args, ctx) => {
|
||
|
|
if (!ctx?.userEmail) throw new Error("Authentication required.");
|
||
|
|
const { id, watchlisted, ...rest } = args;
|
||
|
|
const db = getDb();
|
||
|
|
|
||
|
|
const patch: Record<string, unknown> = { ...rest };
|
||
|
|
if (watchlisted !== undefined) patch.watchlisted = watchlisted === "true";
|
||
|
|
if (Object.keys(patch).length === 0) {
|
||
|
|
throw new Error("No fields to update.");
|
||
|
|
}
|
||
|
|
patch.updatedAt = new Date().toISOString();
|
||
|
|
|
||
|
|
const updated = await db
|
||
|
|
.update(stocks)
|
||
|
|
.set(patch)
|
||
|
|
.where(and(eq(stocks.id, id), eq(stocks.ownerEmail, ctx.userEmail)))
|
||
|
|
.returning();
|
||
|
|
|
||
|
|
if (!updated[0]) throw new Error("Stock not found.");
|
||
|
|
return updated[0];
|
||
|
|
},
|
||
|
|
});
|