checkpoint: goals feature, wallet balance, and goals/wallet detail UI

- Add goals feature (models, migrations, API, web pages)
- Add reserved/centralized wallet balance service
- Add wallet detail page and overview components
- Add new UI components (progress, multi-select, FAB)
- Remove stray empty -H/-d files from working tree
This commit is contained in:
Dwindi Ramadhana
2026-06-17 20:40:00 +07:00
parent 35e93b826a
commit 6a6e74562c
401 changed files with 9517 additions and 397 deletions

267
apps/api/dist/goals/goals.service.d.ts vendored Executable file
View File

@@ -0,0 +1,267 @@
import { PrismaService } from '../prisma/prisma.service';
import { WalletBalanceService } from '../wallets/wallet-balance.service';
import { CreateGoalDto } from './dto/create-goal.dto';
import { UpdateGoalDto } from './dto/update-goal.dto';
import { CreateAllocationDto } from './dto/create-allocation.dto';
import { Decimal } from '@prisma/client/runtime/library';
export declare class GoalsService {
private prisma;
private walletBalanceService;
constructor(prisma: PrismaService, walletBalanceService: WalletBalanceService);
create(userId: string, createGoalDto: CreateGoalDto): Promise<{
allocations: ({
wallet: {
id: string;
createdAt: Date;
updatedAt: Date;
name: string;
userId: string;
kind: string;
currency: string | null;
unit: string | null;
deletedAt: Date | null;
initialAmount: Decimal | null;
pricePerUnit: Decimal | null;
reservedBalance: Decimal;
};
} & {
id: string;
createdAt: Date;
currency: string;
amount: Decimal;
walletId: string;
notes: string | null;
goalId: string;
exchangeRate: Decimal | null;
amountInGoalCurrency: Decimal;
createdBy: string;
})[];
milestones: {
id: string;
targetAmount: Decimal;
percentage: number;
goalId: string;
achievedAt: Date | null;
notifiedAt: Date | null;
}[];
} & {
category: string | null;
id: string;
createdAt: Date;
updatedAt: Date;
status: string;
name: string;
userId: string;
currency: string;
description: string | null;
targetAmount: Decimal;
targetDate: Date | null;
imageUrl: string | null;
teamId: string | null;
currentAmount: Decimal;
completedAt: Date | null;
}>;
findAll(userId: string, status?: string): Promise<({
allocations: ({
wallet: {
id: string;
createdAt: Date;
updatedAt: Date;
name: string;
userId: string;
kind: string;
currency: string | null;
unit: string | null;
deletedAt: Date | null;
initialAmount: Decimal | null;
pricePerUnit: Decimal | null;
reservedBalance: Decimal;
};
} & {
id: string;
createdAt: Date;
currency: string;
amount: Decimal;
walletId: string;
notes: string | null;
goalId: string;
exchangeRate: Decimal | null;
amountInGoalCurrency: Decimal;
createdBy: string;
})[];
milestones: {
id: string;
targetAmount: Decimal;
percentage: number;
goalId: string;
achievedAt: Date | null;
notifiedAt: Date | null;
}[];
} & {
category: string | null;
id: string;
createdAt: Date;
updatedAt: Date;
status: string;
name: string;
userId: string;
currency: string;
description: string | null;
targetAmount: Decimal;
targetDate: Date | null;
imageUrl: string | null;
teamId: string | null;
currentAmount: Decimal;
completedAt: Date | null;
})[]>;
findOne(userId: string, id: string): Promise<{
allocations: ({
wallet: {
id: string;
createdAt: Date;
updatedAt: Date;
name: string;
userId: string;
kind: string;
currency: string | null;
unit: string | null;
deletedAt: Date | null;
initialAmount: Decimal | null;
pricePerUnit: Decimal | null;
reservedBalance: Decimal;
};
} & {
id: string;
createdAt: Date;
currency: string;
amount: Decimal;
walletId: string;
notes: string | null;
goalId: string;
exchangeRate: Decimal | null;
amountInGoalCurrency: Decimal;
createdBy: string;
})[];
milestones: {
id: string;
targetAmount: Decimal;
percentage: number;
goalId: string;
achievedAt: Date | null;
notifiedAt: Date | null;
}[];
} & {
category: string | null;
id: string;
createdAt: Date;
updatedAt: Date;
status: string;
name: string;
userId: string;
currency: string;
description: string | null;
targetAmount: Decimal;
targetDate: Date | null;
imageUrl: string | null;
teamId: string | null;
currentAmount: Decimal;
completedAt: Date | null;
}>;
update(userId: string, id: string, updateGoalDto: UpdateGoalDto): Promise<{
allocations: ({
wallet: {
id: string;
createdAt: Date;
updatedAt: Date;
name: string;
userId: string;
kind: string;
currency: string | null;
unit: string | null;
deletedAt: Date | null;
initialAmount: Decimal | null;
pricePerUnit: Decimal | null;
reservedBalance: Decimal;
};
} & {
id: string;
createdAt: Date;
currency: string;
amount: Decimal;
walletId: string;
notes: string | null;
goalId: string;
exchangeRate: Decimal | null;
amountInGoalCurrency: Decimal;
createdBy: string;
})[];
milestones: {
id: string;
targetAmount: Decimal;
percentage: number;
goalId: string;
achievedAt: Date | null;
notifiedAt: Date | null;
}[];
} & {
category: string | null;
id: string;
createdAt: Date;
updatedAt: Date;
status: string;
name: string;
userId: string;
currency: string;
description: string | null;
targetAmount: Decimal;
targetDate: Date | null;
imageUrl: string | null;
teamId: string | null;
currentAmount: Decimal;
completedAt: Date | null;
}>;
remove(userId: string, id: string): Promise<{
message: string;
}>;
addAllocation(userId: string, goalId: string, createAllocationDto: CreateAllocationDto): Promise<{
wallet: {
id: string;
createdAt: Date;
updatedAt: Date;
name: string;
userId: string;
kind: string;
currency: string | null;
unit: string | null;
deletedAt: Date | null;
initialAmount: Decimal | null;
pricePerUnit: Decimal | null;
reservedBalance: Decimal;
};
} & {
id: string;
createdAt: Date;
currency: string;
amount: Decimal;
walletId: string;
notes: string | null;
goalId: string;
exchangeRate: Decimal | null;
amountInGoalCurrency: Decimal;
createdBy: string;
}>;
removeAllocation(userId: string, goalId: string, allocationId: string): Promise<{
message: string;
}>;
getStats(userId: string): Promise<{
totalGoals: number;
activeGoals: number;
completedGoals: number;
totalTargetAmount: number;
totalCurrentAmount: number;
overallProgress: number;
}>;
private createMilestones;
private updateMilestones;
private getExchangeRate;
}