feat(kakeibo): dört harcama grubu, banka maliyeti ve geri alınabilir migration
- shared/kakeibo: grup devralma, banka maliyeti, kayıt bazında grup, grup özeti (saf, testli) - kategori ve işlem/kalem modellerine kakeiboGroup ve bankCost; form şemaları - migration 016 varsayılanları doldurur; npm run migrate -- --down <ad> ile geri alma - Kakeibo rapor servisi: tutarlar bütçeyle aynı kaynaktan, grup değiştirmeler taşınır Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { z } from "zod";
|
||||
import { tr } from "../../i18n/tr";
|
||||
import { ICON_KEYS, SWATCHES } from "../appearance";
|
||||
import { KAKEIBO_GROUPS } from "../kakeibo";
|
||||
|
||||
export const CATEGORY_KINDS = ["expense", "income"] as const;
|
||||
export type CategoryKind = (typeof CATEGORY_KINDS)[number];
|
||||
@@ -14,6 +15,13 @@ export const categoryFormSchema = z.object({
|
||||
.transform((s) => (s === "" ? null : s)),
|
||||
icon: z.enum(ICON_KEYS),
|
||||
color: z.enum(SWATCHES),
|
||||
/** Kakeibo grubu ("" = üst kategoriden devral); yalnızca gider. */
|
||||
kakeiboGroup: z
|
||||
.union([z.enum(KAKEIBO_GROUPS), z.literal("")])
|
||||
.default("")
|
||||
.transform((x) => (x === "" ? null : x)),
|
||||
/** Banka maliyeti (KMH faizi, ücret): Kakeibo harcamasına girmez. */
|
||||
bankCost: z.boolean().default(false),
|
||||
});
|
||||
|
||||
export type CategoryFormInput = z.input<typeof categoryFormSchema>;
|
||||
|
||||
@@ -3,6 +3,7 @@ import { tr } from "../../i18n/tr";
|
||||
import { parseMoney } from "../money";
|
||||
import { MAX_ATTACHMENTS_PER_RECORD } from "../attachments";
|
||||
import { MAX_INSTALLMENTS } from "../card-periods";
|
||||
import { KAKEIBO_GROUPS } from "../kakeibo";
|
||||
import { MAX_SPLITS, normalizeTags, TRANSACTION_TYPES } from "../transactions";
|
||||
|
||||
const v = tr.validation;
|
||||
@@ -28,10 +29,17 @@ const positiveMoney = z
|
||||
return minor;
|
||||
});
|
||||
|
||||
/** Kakeibo grubu bu kayıt için değiştirildiyse; "" / yok = kategoriden (Faz 16). */
|
||||
const kakeiboOverride = z
|
||||
.union([z.enum(KAKEIBO_GROUPS), z.literal(""), z.null()])
|
||||
.transform((x) => (x ? x : null))
|
||||
.optional();
|
||||
|
||||
const splitSchema = z.object({
|
||||
categoryId: objectId.refine(Boolean, t.selectCategory),
|
||||
amount: positiveMoney,
|
||||
note: z.string().trim().max(120).default(""),
|
||||
kakeiboGroup: kakeiboOverride,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -48,6 +56,7 @@ export const transactionFormSchema = z
|
||||
toAccountId: optionalId,
|
||||
categoryId: optionalId,
|
||||
splits: z.array(splitSchema).max(MAX_SPLITS).default([]),
|
||||
kakeiboGroup: kakeiboOverride,
|
||||
payee: z.string().trim().max(80).default(""),
|
||||
description: z.string().trim().max(500).default(""),
|
||||
tags: z
|
||||
|
||||
Reference in New Issue
Block a user