{bill.name}
+ {bill.computedStatus} + {bill.autopay && autopay} ++ {money(bill.amount, bill.currency)} due {new Date(bill.dueDate).toLocaleDateString()} · {bill.recurrence} +
+ {bill.payee &&Payee: {bill.payee.name}
} +diff --git a/app/api/accounts/route.ts b/app/api/accounts/route.ts
index 5b1b440..dbf6003 100644
--- a/app/api/accounts/route.ts
+++ b/app/api/accounts/route.ts
@@ -2,5 +2,5 @@ import { NextRequest } from "next/server";
import { proxyRequest } from "@/lib/backend";
export async function GET(req: NextRequest) {
- return proxyRequest(req, "accounts");
+ return proxyRequest(req, "view/accounts");
}
diff --git a/app/api/bill-pay/bills/[id]/pay/route.ts b/app/api/bill-pay/bills/[id]/pay/route.ts
new file mode 100644
index 0000000..4e3dbcc
--- /dev/null
+++ b/app/api/bill-pay/bills/[id]/pay/route.ts
@@ -0,0 +1,6 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function POST(req: NextRequest, { params }: { params: { id: string } }) {
+ return proxyRequest(req, `bill-pay/bills/${params.id}/pay`);
+}
diff --git a/app/api/bill-pay/bills/[id]/route.ts b/app/api/bill-pay/bills/[id]/route.ts
new file mode 100644
index 0000000..045b0ff
--- /dev/null
+++ b/app/api/bill-pay/bills/[id]/route.ts
@@ -0,0 +1,6 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function PATCH(req: NextRequest, { params }: { params: { id: string } }) {
+ return proxyRequest(req, `bill-pay/bills/${params.id}`);
+}
diff --git a/app/api/bill-pay/bills/route.ts b/app/api/bill-pay/bills/route.ts
new file mode 100644
index 0000000..b387c9e
--- /dev/null
+++ b/app/api/bill-pay/bills/route.ts
@@ -0,0 +1,10 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function GET(req: NextRequest) {
+ return proxyRequest(req, "bill-pay/bills");
+}
+
+export async function POST(req: NextRequest) {
+ return proxyRequest(req, "bill-pay/bills");
+}
diff --git a/app/api/bill-pay/payees/route.ts b/app/api/bill-pay/payees/route.ts
new file mode 100644
index 0000000..5d7da65
--- /dev/null
+++ b/app/api/bill-pay/payees/route.ts
@@ -0,0 +1,10 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function GET(req: NextRequest) {
+ return proxyRequest(req, "bill-pay/payees");
+}
+
+export async function POST(req: NextRequest) {
+ return proxyRequest(req, "bill-pay/payees");
+}
diff --git a/app/api/bill-pay/summary/route.ts b/app/api/bill-pay/summary/route.ts
new file mode 100644
index 0000000..dfeb8f3
--- /dev/null
+++ b/app/api/bill-pay/summary/route.ts
@@ -0,0 +1,6 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function GET(req: NextRequest) {
+ return proxyRequest(req, "bill-pay/summary");
+}
diff --git a/app/api/credit-score/entries/route.ts b/app/api/credit-score/entries/route.ts
new file mode 100644
index 0000000..4dd73d1
--- /dev/null
+++ b/app/api/credit-score/entries/route.ts
@@ -0,0 +1,10 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function GET(req: NextRequest) {
+ return proxyRequest(req, "credit-score/entries");
+}
+
+export async function POST(req: NextRequest) {
+ return proxyRequest(req, "credit-score/entries");
+}
diff --git a/app/api/credit-score/summary/route.ts b/app/api/credit-score/summary/route.ts
new file mode 100644
index 0000000..baab993
--- /dev/null
+++ b/app/api/credit-score/summary/route.ts
@@ -0,0 +1,6 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function GET(req: NextRequest) {
+ return proxyRequest(req, "credit-score/summary");
+}
diff --git a/app/api/notifications/[id]/read/route.ts b/app/api/notifications/[id]/read/route.ts
new file mode 100644
index 0000000..62c0c6b
--- /dev/null
+++ b/app/api/notifications/[id]/read/route.ts
@@ -0,0 +1,6 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function PATCH(req: NextRequest, { params }: { params: { id: string } }) {
+ return proxyRequest(req, `notifications/${params.id}/read`);
+}
diff --git a/app/api/notifications/preferences/route.ts b/app/api/notifications/preferences/route.ts
new file mode 100644
index 0000000..62b33b7
--- /dev/null
+++ b/app/api/notifications/preferences/route.ts
@@ -0,0 +1,10 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function GET(req: NextRequest) {
+ return proxyRequest(req, "notifications/preferences");
+}
+
+export async function PATCH(req: NextRequest) {
+ return proxyRequest(req, "notifications/preferences");
+}
diff --git a/app/api/notifications/push-subscriptions/route.ts b/app/api/notifications/push-subscriptions/route.ts
new file mode 100644
index 0000000..09484d2
--- /dev/null
+++ b/app/api/notifications/push-subscriptions/route.ts
@@ -0,0 +1,6 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function POST(req: NextRequest) {
+ return proxyRequest(req, "notifications/push-subscriptions");
+}
diff --git a/app/api/notifications/read-all/route.ts b/app/api/notifications/read-all/route.ts
new file mode 100644
index 0000000..059b4d7
--- /dev/null
+++ b/app/api/notifications/read-all/route.ts
@@ -0,0 +1,6 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function POST(req: NextRequest) {
+ return proxyRequest(req, "notifications/read-all");
+}
diff --git a/app/api/notifications/route.ts b/app/api/notifications/route.ts
new file mode 100644
index 0000000..e6d6620
--- /dev/null
+++ b/app/api/notifications/route.ts
@@ -0,0 +1,6 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function GET(req: NextRequest) {
+ return proxyRequest(req, "notifications");
+}
diff --git a/app/api/notifications/test/route.ts b/app/api/notifications/test/route.ts
new file mode 100644
index 0000000..d9c2ef7
--- /dev/null
+++ b/app/api/notifications/test/route.ts
@@ -0,0 +1,6 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function POST(req: NextRequest) {
+ return proxyRequest(req, "notifications/test");
+}
diff --git a/app/api/notifications/vapid-public-key/route.ts b/app/api/notifications/vapid-public-key/route.ts
new file mode 100644
index 0000000..95149d1
--- /dev/null
+++ b/app/api/notifications/vapid-public-key/route.ts
@@ -0,0 +1,6 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function GET(req: NextRequest) {
+ return proxyRequest(req, "notifications/vapid-public-key");
+}
diff --git a/app/api/transactions/route.ts b/app/api/transactions/route.ts
index 79477f2..5dd69b4 100644
--- a/app/api/transactions/route.ts
+++ b/app/api/transactions/route.ts
@@ -2,7 +2,7 @@ import { NextRequest } from "next/server";
import { proxyRequest } from "@/lib/backend";
export async function GET(req: NextRequest) {
- return proxyRequest(req, "transactions");
+ return proxyRequest(req, "view/transactions");
}
export async function POST(req: NextRequest) {
diff --git a/app/api/view/accounts/route.ts b/app/api/view/accounts/route.ts
new file mode 100644
index 0000000..dbf6003
--- /dev/null
+++ b/app/api/view/accounts/route.ts
@@ -0,0 +1,6 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function GET(req: NextRequest) {
+ return proxyRequest(req, "view/accounts");
+}
diff --git a/app/api/view/transactions/route.ts b/app/api/view/transactions/route.ts
new file mode 100644
index 0000000..14d9cef
--- /dev/null
+++ b/app/api/view/transactions/route.ts
@@ -0,0 +1,6 @@
+import { NextRequest } from "next/server";
+import { proxyRequest } from "@/lib/backend";
+
+export async function GET(req: NextRequest) {
+ return proxyRequest(req, "view/transactions");
+}
diff --git a/app/app/connect/page.tsx b/app/app/connect/page.tsx
index db3a42c..4dd43f6 100644
--- a/app/app/connect/page.tsx
+++ b/app/app/connect/page.tsx
@@ -5,7 +5,7 @@ import { useCallback, useEffect, useState } from "react";
import { usePlaidLink } from "react-plaid-link";
type Account = {
- id: string;
+ viewRef: string;
institutionName: string;
accountType: string;
mask?: string | null;
@@ -43,7 +43,7 @@ declare global {
export default function ConnectPage() {
const [status, setStatus] = useState("");
const [linkToken, setLinkToken] = useState
Active bills
+{summary?.activeCount ?? 0}
+Due next 30 days
+{summary?.upcomingCount ?? 0}
+Overdue
+{summary?.overdueCount ?? 0}
+Total due next 30 days
+{money(summary?.totalDueNext30 ?? 0)}
+Payees
+No payees yet.
} + {payees.map((payee) => ( +{payee.name}
+{payee.category || "Uncategorized"}{payee.accountNumberLast4 ? ` · ${payee.accountNumberLast4}` : ""}
+New Bill
+{status}
} +Bill Schedule
+ +No bills for this view.
} + {filteredBills.map((bill) => ( +{bill.name}
+ {bill.computedStatus} + {bill.autopay && autopay} ++ {money(bill.amount, bill.currency)} due {new Date(bill.dueDate).toLocaleDateString()} · {bill.recurrence} +
+ {bill.payee &&Payee: {bill.payee.name}
} +Latest score
+{summary?.latest?.score ?? "--"}
+{scoreBand(summary?.latest?.score)}
+Last change
++ {summary?.change === null || summary?.change === undefined ? "--" : `${summary.change > 0 ? "+" : ""}${summary.change}`} +
+Compared with previous same-bureau entry
+Average score
+{summary?.averageScore ?? "--"}
+Across saved entries
+Entries
+{summary?.entryCount ?? 0}
+Manual or imported history
+Add Score Entry
+{status}
} +Bureau Snapshot
+ +{entry.bureau}
+{entry.score}
+{new Date(entry.scoreDate).toLocaleDateString()}
+No bureau scores yet.
} +Score History
+No score entries for this view.
} + {filteredEntries.map((entry) => { + const factors = entry.factors ?? {}; + const positive = Array.isArray(factors.positive) ? factors.positive : []; + const negative = Array.isArray(factors.negative) ? factors.negative : []; + return ( +{entry.score}
+ {entry.bureau} + {entry.model} +{new Date(entry.scoreDate).toLocaleDateString()} · {entry.source}
+ {(positive.length > 0 || negative.length > 0) && ( ++ {positive.length > 0 ? `Positive: ${positive.join(", ")}` : ""} + {positive.length > 0 && negative.length > 0 ? " · " : ""} + {negative.length > 0 ? `Negative: ${negative.join(", ")}` : ""} +
+ )} +{scoreBand(entry.score)}
+SMTP Email
+Send important LedgerOne alerts through the configured SMTP transport.
+ +Browser Push
++ {vapid.enabled ? "Register this browser for web push alerts." : "Backend VAPID keys are not configured."} +
+ +Delivery Threshold
+Email and push delivery only run at or above this severity.
+ +Notification Center
+{unreadCount} unread alert{unreadCount === 1 ? "" : "s"}
+{status}
} + +Loading notifications...
} + {!loading && notifications.length === 0 &&No notifications yet.
} + {!loading && notifications.map((item) => ( +{item.title}
+ {item.severity} +{item.body}
++ {new Date(item.createdAt).toLocaleString()} · {item.channels.join(", ") || "in_app"} +
+Preview: {csvPreview.fileName}
+Columns: {csvPreview.fileName}
+{csvPreview.rowCount} detected row{csvPreview.rowCount === 1 ? "" : "s"}
| {header} | - ))} +Column | +Mapped as |
|---|---|---|
| {row[header] ?? ""} | - ))} -||
| {header} | +{mapped ?? "Not mapped"} | +