Files
expense-control/web/src/app/shared/models.ts
Mateusz Gruszczyński a8e497fec3 zmiany cd
2026-04-06 15:38:16 +02:00

260 lines
6.7 KiB
TypeScript

export interface User {
id: string;
fullName: string;
email: string;
role: 'ADMIN' | 'USER';
isActive: boolean;
defaultCurrency: string;
reportPreferences?: ReportPreferences;
createdAt: string;
}
export interface Category {
id: string;
name: string;
color: string;
isSystem: boolean;
ownerId: string | null;
}
export interface Merchant {
id: string;
name: string;
kind: 'MERCHANT' | 'SERVICE_PROVIDER' | 'OTHER';
notes: string | null;
isActive: boolean;
createdAt: string;
updatedAt: string;
}
export interface Proof {
id: string;
type: 'RECEIPT' | 'INVOICE' | 'NOTE' | 'BANK_STATEMENT' | 'OTHER';
label: string | null;
note: string | null;
originalName: string | null;
mimeType: string | null;
fileSize: number | null;
fileUrl: string | null;
createdAt: string;
}
export type ExpenseStatus = 'DRAFT' | 'PENDING' | 'APPROVED' | 'REJECTED';
export type DuplicateStatus = 'OPEN' | 'CONFIRMED' | 'DISMISSED';
export interface Expense {
id: string;
title: string;
description: string | null;
amount: number;
expenseDate: string;
merchant: string | null;
paymentMethod: 'CARD' | 'CASH' | 'TRANSFER' | 'BLIK' | 'OTHER' | null;
currency: string;
status: ExpenseStatus;
tags: string[];
customFields: Record<string, string>;
possibleDuplicate: boolean;
duplicateStatus: DuplicateStatus | null;
duplicateReviewedAt: string | null;
recurringSourceId: string | null;
category: Category;
proofs: Proof[];
createdAt: string;
updatedAt: string;
}
export interface DuplicateGroup {
source: Expense;
matches: Expense[];
}
export interface StatsResponse {
total: number;
count: number;
average: number;
topCategory: { categoryId: string; categoryName: string; total: number; count: number } | null;
byCategory: Array<{ categoryId: string; categoryName: string; total: number; count: number }>;
timeline: Array<{ label: string; total: number }>;
byTag?: Array<{ tag: string; total: number }>;
byStatus?: Array<{ status: string; count: number }>;
}
export interface CashflowResponse {
currentMonth: string;
actualCurrent: number;
totalBudget: number;
budgetUsagePercent: number;
duplicateCount: number;
pendingApproval: number;
forecastCurrentMonth: number;
trend: Array<{ label: string; actual: number; budget: number }>;
alerts: Array<{ id: string; name: string; usagePercent: number; spent: number; amount: number }>;
upcomingRecurring: Array<{ id: string; title: string; amount: number; nextRunDate: string; frequency: string }>;
statusSummary: Array<{ status: string; count: number }>;
}
export interface Budget {
id: string;
month: string;
name: string | null;
amount: number;
spent: number;
usagePercent: number;
alertLevel: number | null;
alertThresholds: number[];
isActive: boolean;
category: Category | null;
createdAt: string;
updatedAt: string;
}
export interface BudgetListResponse {
month: string;
items: Budget[];
summary: {
totalBudget: number;
totalSpent: number;
alerts: Array<{ budgetId: string; message: string; usagePercent: number; level: number }>;
};
}
export interface RecurringExpense {
id: string;
title: string;
description: string | null;
amount: number;
merchant: string | null;
paymentMethod: 'CARD' | 'CASH' | 'TRANSFER' | 'BLIK' | 'OTHER' | null;
currency: string;
frequency: 'WEEKLY' | 'MONTHLY' | 'YEARLY';
intervalValue: number;
startDate: string;
nextRunDate: string;
lastRunDate: string | null;
endDate: string | null;
maxOccurrences: number | null;
generatedCount: number;
defaultStatus: 'DRAFT' | 'PENDING';
tags: string[];
customFields: Record<string, string>;
isActive: boolean;
category: Category;
createdAt: string;
updatedAt: string;
}
export interface AppSettings {
id: string;
appName: string;
defaultCurrency: string;
registrationEnabled: boolean;
allowedProofTypes: string[];
uiPreferences: Record<string, string | number | boolean>;
smtpEnabled: boolean;
smtpHost: string | null;
smtpPort: number;
smtpSecure: boolean;
smtpUser: string | null;
smtpPassword: string | null;
smtpFromName: string | null;
smtpFromEmail: string | null;
createdAt: string;
updatedAt: string;
}
export interface ReportPreferences {
enabled: boolean;
frequency: 'monthly' | 'yearly' | 'threshold';
thresholdAmount: number;
sendToEmail: string | null;
categoryIds: string[];
}
export interface ShoppingListIntegrationSettings {
enabled: boolean;
baseUrl: string;
hasToken: boolean;
authMode: 'bearer' | 'x-api-token' | 'both';
ownerId: string | null;
defaultListId: string | null;
}
export interface ShoppingListSummary {
total?: number;
amount?: number;
count?: number;
records?: number;
meta?: { total_amount?: number; total_count?: number; returned_count?: number; [key: string]: unknown };
lists?: Array<{ id?: string | number; title?: string; name?: string; total_amount?: number; total?: number; expense_count?: number; count?: number }>;
totals?: Array<{ list_id?: string | number; listId?: string | number; name?: string; total?: number; amount?: number; count?: number }>;
aggregates?: Array<{ list_id?: string | number; listId?: string | number; name?: string; total?: number; amount?: number; count?: number }>;
[key: string]: unknown;
}
export interface ShoppingListRef {
id: string | number;
name?: string;
title?: string;
created_at?: string;
categories?: string[];
owner_id?: string | number;
ownerId?: string | number;
owner?: { id?: string | number; username?: string; name?: string; fullName?: string; email?: string };
is_active?: boolean;
is_archived?: boolean;
[key: string]: unknown;
}
export interface ShoppingListExpenseItem {
id?: string | number;
expense_id?: string | number;
title?: string;
name?: string;
amount?: number;
total?: number;
created_at?: string;
added_at?: string;
expense_date?: string;
receipt_filename?: string;
list?: ShoppingListRef;
owner?: { id?: string | number; username?: string; name?: string; fullName?: string; email?: string };
[key: string]: unknown;
}
export interface AdminSystemInfo {
appName: string;
suiteVersion: string;
apiVersion: string;
webVersion: string;
nodeVersion: string;
environment: string;
database: string;
uploadDir: string;
registrationEnabled: boolean;
smtpConfigured: boolean;
counters: {
users: number;
expenses: number;
categories: number;
merchants: number;
budgets: number;
recurring: number;
shoppingIntegrations: number;
};
sources: {
appRepository: string;
shoppingListRepository: string;
apiBasePath: string;
};
checkedAt: string;
}
export interface ShoppingListTemplate {
id: string;
name?: string;
title?: string;
[key: string]: unknown;
}