- Dockerfile + deploy.sh for Hetzner server - Email verification via Better Auth + Resend - Invite code flow (6-digit OTP, generate/join) - Settlement share percent fix (payer vs debtor) - OCR scanner fixes (date display, retry, viewfinder) - app.json icon/splash/adaptive-icon configured - iOS deployment target 15.5 (ML Kit requirement) - DB migration 0014: household_invitations table Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
76 lines
2.6 KiB
TypeScript
76 lines
2.6 KiB
TypeScript
import { zValidator } from "@hono/zod-validator";
|
|
import { Hono } from "hono";
|
|
import { authMiddleware, requireAuth, type AuthVariables } from "../middleware/auth.middleware";
|
|
import { tenantMiddleware, requireHousehold, type TenantVariables } from "../middleware/tenant.middleware";
|
|
import { CreateDebtSchema, CreateDebtPaymentSchema } from "@haushaltsApp/shared/schemas/debt.schema";
|
|
import {
|
|
getDebts,
|
|
getClaims,
|
|
createDebt,
|
|
deleteDebt,
|
|
getDebtPayments,
|
|
createDebtPayment,
|
|
} from "../services/debt.service";
|
|
|
|
type Variables = AuthVariables & TenantVariables;
|
|
|
|
export const debtRoutes = new Hono<{ Variables: Variables }>();
|
|
|
|
debtRoutes.use("/*", authMiddleware, requireAuth, tenantMiddleware, requireHousehold);
|
|
|
|
// GET /api/debts
|
|
debtRoutes.get("/", async (c) => {
|
|
const householdId = c.get("householdId") as string;
|
|
const user = c.get("user") as { id: string };
|
|
const data = await getDebts(householdId, user.id);
|
|
return c.json({ debts: data });
|
|
});
|
|
|
|
// POST /api/debts
|
|
debtRoutes.post("/", zValidator("json", CreateDebtSchema), async (c) => {
|
|
const householdId = c.get("householdId") as string;
|
|
const user = c.get("user") as { id: string };
|
|
const input = c.req.valid("json");
|
|
const debt = await createDebt(householdId, user.id, input);
|
|
return c.json({ debt }, 201);
|
|
});
|
|
|
|
// DELETE /api/debts/:id
|
|
debtRoutes.delete("/:id", async (c) => {
|
|
const householdId = c.get("householdId") as string;
|
|
const user = c.get("user") as { id: string };
|
|
const { id } = c.req.param();
|
|
const ok = await deleteDebt(id, householdId, user.id);
|
|
if (!ok) return c.json({ error: "Not found" }, 404);
|
|
return c.json({ success: true });
|
|
});
|
|
|
|
// GET /api/debts/claims — debts where I am the creditor
|
|
debtRoutes.get("/claims", async (c) => {
|
|
const householdId = c.get("householdId") as string;
|
|
const user = c.get("user") as { id: string };
|
|
const data = await getClaims(householdId, user.id);
|
|
return c.json({ debts: data });
|
|
});
|
|
|
|
// GET /api/debts/:id/payments
|
|
debtRoutes.get("/:id/payments", async (c) => {
|
|
const householdId = c.get("householdId") as string;
|
|
const { id } = c.req.param();
|
|
const payments = await getDebtPayments(id, householdId);
|
|
return c.json({ payments });
|
|
});
|
|
|
|
// POST /api/debts/payments
|
|
debtRoutes.post("/payments", zValidator("json", CreateDebtPaymentSchema), async (c) => {
|
|
const householdId = c.get("householdId") as string;
|
|
const user = c.get("user") as { id: string };
|
|
const input = c.req.valid("json");
|
|
try {
|
|
const result = await createDebtPayment(householdId, user.id, input);
|
|
return c.json(result, 201);
|
|
} catch {
|
|
return c.json({ error: "Debt not found" }, 404);
|
|
}
|
|
});
|