- Complete transformation from boilerplate to full-featured financial app - Add comprehensive dashboard with KPI cards and interactive charts - Implement transaction management with predefined expense/income categories - Create account management system with multiple account types - Add authentication flow with session management - Implement analytics overview with demo financial data - Add budget tracking and goal progress visualization - Include custom category creation functionality - Update branding and footer with MoneyMind by RoMoS - Add shadcn/ui components and Recharts for data visualization 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
163 lines
6.1 KiB
TypeScript
163 lines
6.1 KiB
TypeScript
import { z } from "zod";
|
|
|
|
// Financial Account Schemas
|
|
export const financialAccountSchema = z.object({
|
|
id: z.string().optional(),
|
|
name: z.string().min(1, "Name is required"),
|
|
type: z.enum(["checking", "savings", "credit", "investment", "cash"]),
|
|
balance: z.number().min(0, "Balance must be non-negative"),
|
|
currency: z.string().default("EUR"),
|
|
isActive: z.boolean().default(true),
|
|
accountNumber: z.string().optional(),
|
|
bankName: z.string().optional(),
|
|
});
|
|
|
|
export const updateFinancialAccountSchema = financialAccountSchema.partial().extend({
|
|
id: z.string(),
|
|
});
|
|
|
|
// Category Schemas
|
|
export const categorySchema = z.object({
|
|
id: z.string().optional(),
|
|
name: z.string().min(1, "Name is required"),
|
|
type: z.enum(["income", "expense"]),
|
|
color: z.string().default("#3B82F6"),
|
|
icon: z.string().optional(),
|
|
parentId: z.string().optional(),
|
|
});
|
|
|
|
export const updateCategorySchema = categorySchema.partial().extend({
|
|
id: z.string(),
|
|
});
|
|
|
|
// Transaction Schemas
|
|
export const transactionSchema = z.object({
|
|
id: z.string().optional(),
|
|
description: z.string().min(1, "Description is required"),
|
|
amount: z.number().min(0.01, "Amount must be greater than 0"),
|
|
type: z.enum(["income", "expense"]),
|
|
date: z.string().min(1, "Date is required"),
|
|
categoryId: z.string().optional(),
|
|
accountId: z.string().min(1, "Account is required"),
|
|
isRecurring: z.boolean().default(false),
|
|
recurringInterval: z.enum(["daily", "weekly", "monthly", "yearly"]).optional(),
|
|
tags: z.array(z.string()).default([]),
|
|
notes: z.string().optional(),
|
|
merchant: z.string().optional(),
|
|
location: z.string().optional(),
|
|
});
|
|
|
|
export const updateTransactionSchema = transactionSchema.partial().extend({
|
|
id: z.string(),
|
|
});
|
|
|
|
export const transactionImportSchema = z.object({
|
|
transactions: z.array(transactionSchema),
|
|
source: z.string().optional(),
|
|
});
|
|
|
|
// Budget Schemas
|
|
export const budgetSchema = z.object({
|
|
id: z.string().optional(),
|
|
name: z.string().min(1, "Name is required"),
|
|
amount: z.number().min(0.01, "Budget amount must be greater than 0"),
|
|
period: z.enum(["weekly", "monthly", "yearly"]),
|
|
categoryId: z.string().optional(),
|
|
isActive: z.boolean().default(true),
|
|
alertThreshold: z.number().min(0).max(100).default(80),
|
|
rolloverUnused: z.boolean().default(false),
|
|
startDate: z.string().min(1, "Start date is required"),
|
|
endDate: z.string().optional(),
|
|
});
|
|
|
|
export const updateBudgetSchema = budgetSchema.partial().extend({
|
|
id: z.string(),
|
|
});
|
|
|
|
// Goal Schemas
|
|
export const goalSchema = z.object({
|
|
id: z.string().optional(),
|
|
name: z.string().min(1, "Name is required"),
|
|
description: z.string().optional(),
|
|
targetAmount: z.number().min(0.01, "Target amount must be greater than 0"),
|
|
currentAmount: z.number().min(0).default(0),
|
|
targetDate: z.string().optional(),
|
|
type: z.enum(["savings", "debt_payoff", "investment", "emergency_fund"]),
|
|
priority: z.enum(["low", "medium", "high"]).default("medium"),
|
|
status: z.enum(["active", "completed", "paused", "cancelled"]).default("active"),
|
|
accountId: z.string().optional(),
|
|
isRecurring: z.boolean().default(false),
|
|
recurringAmount: z.number().min(0).optional(),
|
|
recurringInterval: z.enum(["daily", "weekly", "monthly", "yearly"]).optional(),
|
|
});
|
|
|
|
export const updateGoalSchema = goalSchema.partial().extend({
|
|
id: z.string(),
|
|
});
|
|
|
|
// Analytics & Insights Schemas
|
|
export const financialInsightSchema = z.object({
|
|
type: z.enum(["spending_alert", "saving_opportunity", "budget_warning", "trend_analysis"]),
|
|
title: z.string().min(1, "Title is required"),
|
|
message: z.string().min(1, "Message is required"),
|
|
severity: z.enum(["low", "medium", "high", "critical"]).default("low"),
|
|
data: z.record(z.string(), z.unknown()).optional(),
|
|
});
|
|
|
|
// Report Schemas
|
|
export const reportSchema = z.object({
|
|
name: z.string().min(1, "Name is required"),
|
|
type: z.enum(["monthly_summary", "expense_analysis", "income_report", "net_worth"]),
|
|
period: z.enum(["monthly", "quarterly", "yearly", "custom"]),
|
|
startDate: z.string().min(1, "Start date is required"),
|
|
endDate: z.string().min(1, "End date is required"),
|
|
data: z.record(z.string(), z.unknown()),
|
|
});
|
|
|
|
// Query Schemas
|
|
export const dateRangeSchema = z.object({
|
|
startDate: z.string().optional(),
|
|
endDate: z.string().optional(),
|
|
});
|
|
|
|
export const paginationSchema = z.object({
|
|
page: z.coerce.number().min(1).default(1),
|
|
limit: z.coerce.number().min(1).max(100).default(20),
|
|
});
|
|
|
|
export const transactionFilterSchema = z.object({
|
|
type: z.enum(["income", "expense"]).optional(),
|
|
categoryId: z.string().optional(),
|
|
accountId: z.string().optional(),
|
|
startDate: z.string().optional(),
|
|
endDate: z.string().optional(),
|
|
search: z.string().optional(),
|
|
tags: z.array(z.string()).optional(),
|
|
...paginationSchema.shape,
|
|
});
|
|
|
|
export const analyticsQuerySchema = z.object({
|
|
period: z.enum(["week", "month", "quarter", "year"]).default("month"),
|
|
startDate: z.string().optional(),
|
|
endDate: z.string().optional(),
|
|
type: z.enum(["overview", "trends", "categories", "comparison"]).default("overview"),
|
|
});
|
|
|
|
// Type exports
|
|
export type FinancialAccountInput = z.infer<typeof financialAccountSchema>;
|
|
export type UpdateFinancialAccountInput = z.infer<typeof updateFinancialAccountSchema>;
|
|
export type CategoryInput = z.infer<typeof categorySchema>;
|
|
export type UpdateCategoryInput = z.infer<typeof updateCategorySchema>;
|
|
export type TransactionInput = z.infer<typeof transactionSchema>;
|
|
export type UpdateTransactionInput = z.infer<typeof updateTransactionSchema>;
|
|
export type TransactionImportInput = z.infer<typeof transactionImportSchema>;
|
|
export type BudgetInput = z.infer<typeof budgetSchema>;
|
|
export type UpdateBudgetInput = z.infer<typeof updateBudgetSchema>;
|
|
export type GoalInput = z.infer<typeof goalSchema>;
|
|
export type UpdateGoalInput = z.infer<typeof updateGoalSchema>;
|
|
export type FinancialInsightInput = z.infer<typeof financialInsightSchema>;
|
|
export type ReportInput = z.infer<typeof reportSchema>;
|
|
export type DateRangeInput = z.infer<typeof dateRangeSchema>;
|
|
export type PaginationInput = z.infer<typeof paginationSchema>;
|
|
export type TransactionFilterInput = z.infer<typeof transactionFilterSchema>;
|
|
export type AnalyticsQueryInput = z.infer<typeof analyticsQuerySchema>; |