feat(ledger): add bookkeeping workbench and transaction views

- Add transactions_dirty table and zero-tolerance cleansing action

- Implement bookkeeping workbench (/bookkeeping) with searchable Combobox channel selector and card suffix / account identifier

- Implement transaction ledger (/transactions) with date groupings, multi-currency metrics, and filters

- Update AGENTS.md guidelines for Base UI Select and Combobox bindings
This commit is contained in:
2026-09-06 23:23:29 +08:00
parent 1ccee1414c
commit c33857ffac
42 changed files with 3329 additions and 598 deletions
+22 -29
View File
@@ -1,5 +1,5 @@
import { redirect } from "next/navigation";
import Link from "next/link";
import { redirect } from "next/navigation"
import Link from "next/link"
import {
ArrowRightIcon,
CreditCardIcon,
@@ -9,35 +9,27 @@ import {
SlidersHorizontalIcon,
TrendingUpIcon,
WalletIcon,
} from "lucide-react";
} from "lucide-react"
import { auth } from "@/lib/auth";
import { AppSidebar } from "@/components/app-sidebar";
import { AppHeader } from "@/components/app-header";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import {
SidebarInset,
SidebarProvider,
} from "@/components/ui/sidebar";
import { auth } from "@/lib/auth"
import { AppSidebar } from "@/components/app-sidebar"
import { AppHeader } from "@/components/app-header"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar"
export default async function HomePage() {
const session = await auth();
const session = await auth()
// 若用户未登录,由于 proxy 会拦截并重定向,作为服务端页面增加双重保障
if (!session?.user) {
redirect("/login");
redirect("/login")
}
const user = session.user;
const userName = user.name || "Fluxent 用户";
const userEmail = user.email || "";
const userAvatar = user.image || null;
const user = session.user
const userName = user.name || "Fluxent 用户"
const userEmail = user.email || ""
const userAvatar = user.image || null
return (
<SidebarProvider>
@@ -59,8 +51,9 @@ export default async function HomePage() {
<h1 className="font-heading text-2xl font-bold tracking-tight text-foreground md:text-3xl">
欢迎回来,{userName}
</h1>
<p className="text-sm text-muted-foreground leading-relaxed">
这是您的 Fluxent 多币种资产与记账中心。通过左侧导航栏,您可以轻松追踪你的资金流动、管理银行与支付卡账户、维护清晰的收支流水。
<p className="text-sm leading-relaxed text-muted-foreground">
这是您的 Fluxent
多币种资产与记账中心。通过左侧导航栏,您可以轻松追踪你的资金流动、管理银行与支付卡账户、维护清晰的收支流水。
</p>
<div className="mt-2 flex flex-wrap items-center gap-3">
@@ -150,7 +143,7 @@ export default async function HomePage() {
<h3 className="font-heading text-sm font-semibold text-foreground">
1. 添加账户与支付渠道
</h3>
<p className="text-xs text-muted-foreground leading-relaxed">
<p className="text-xs leading-relaxed text-muted-foreground">
录入您的现金账户、活期存款,或绑定支持港币、美元、日元结算的跨境信用卡与电子钱包。
</p>
</div>
@@ -171,7 +164,7 @@ export default async function HomePage() {
<h3 className="font-heading text-sm font-semibold text-foreground">
2. 建立首笔复式流水
</h3>
<p className="text-xs text-muted-foreground leading-relaxed">
<p className="text-xs leading-relaxed text-muted-foreground">
支持自动计算交易币种到入账币种的清算汇率与手续费,让每一分折损清清楚楚。
</p>
</div>
@@ -192,7 +185,7 @@ export default async function HomePage() {
<h3 className="font-heading text-sm font-semibold text-foreground">
3. 账户首选项与设置
</h3>
<p className="text-xs text-muted-foreground leading-relaxed">
<p className="text-xs leading-relaxed text-muted-foreground">
配置个人偏好货币、导出记账数据或连接外部服务。
</p>
</div>
@@ -209,5 +202,5 @@ export default async function HomePage() {
</div>
</SidebarInset>
</SidebarProvider>
);
)
}