import { query, transaction } from "./postgres"; import type { Plan } from "../types/plan"; /** * Store plan in database */ export async function storePlan(plan: Plan): Promise { await query( `INSERT INTO plans ( plan_id, creator, plan_hash, steps, max_recursion, max_ltv, signature, message_hash, signer_address, signed_at, status ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) ON CONFLICT (plan_id) DO UPDATE SET steps = EXCLUDED.steps, status = EXCLUDED.status, updated_at = CURRENT_TIMESTAMP`, [ plan.plan_id, plan.creator, plan.plan_hash, JSON.stringify(plan.steps), plan.maxRecursion || 3, plan.maxLTV || 0.6, plan.signature || null, null, // message_hash null, // signer_address null, // signed_at plan.status || "pending", ] ); } /** * Get plan by ID */ export async function getPlanById(planId: string): Promise { const result = await query( "SELECT * FROM plans WHERE plan_id = $1", [planId] ); if (result.length === 0) { return null; } const row = result[0]; return { plan_id: row.plan_id, creator: row.creator, steps: typeof row.steps === "string" ? JSON.parse(row.steps) : row.steps, maxRecursion: row.max_recursion, maxLTV: row.max_ltv, signature: row.signature, plan_hash: row.plan_hash, created_at: row.created_at ? (row.created_at instanceof Date ? row.created_at.toISOString() : String(row.created_at)) : undefined, status: row.status, }; } /** * Update plan signature */ export async function updatePlanSignature( planId: string, signature: { signature: string; messageHash: string; signerAddress: string; signedAt: string; } ): Promise { await query( `UPDATE plans SET signature = $1, message_hash = $2, signer_address = $3, signed_at = $4, updated_at = CURRENT_TIMESTAMP WHERE plan_id = $5`, [ signature.signature, signature.messageHash, signature.signerAddress, signature.signedAt, planId, ] ); } /** * Update plan status */ export async function updatePlanStatus( planId: string, status: string ): Promise { await query( "UPDATE plans SET status = $1, updated_at = CURRENT_TIMESTAMP WHERE plan_id = $2", [status, planId] ); } /** * List all plans (with optional filtering) */ export async function listPlans(options?: { creator?: string; status?: string; limit?: number; offset?: number; }): Promise { let queryText = "SELECT * FROM plans WHERE 1=1"; const params: any[] = []; let paramIndex = 1; if (options?.creator) { queryText += ` AND creator = $${paramIndex}`; params.push(options.creator); paramIndex++; } if (options?.status) { queryText += ` AND status = $${paramIndex}`; params.push(options.status); paramIndex++; } queryText += " ORDER BY created_at DESC"; if (options?.limit) { queryText += ` LIMIT $${paramIndex}`; params.push(options.limit); paramIndex++; } if (options?.offset) { queryText += ` OFFSET $${paramIndex}`; params.push(options.offset); paramIndex++; } const result = await query(queryText, params); return result.map((row) => ({ plan_id: row.plan_id, creator: row.creator, steps: typeof row.steps === "string" ? JSON.parse(row.steps) : row.steps, maxRecursion: row.max_recursion, maxLTV: row.max_ltv, signature: row.signature, plan_hash: row.plan_hash, created_at: row.created_at ? (row.created_at instanceof Date ? row.created_at.toISOString() : String(row.created_at)) : undefined, status: row.status, })); }