SPB Git forge

spb/toveli

Public
14commits 1branches 0releases
1.1 MBsize
maindefault branch
5 h agolast push
TypeScript 50.6% JavaScript 46.1% SQL 2.1% Shell 0.6% CSS 0.5%
2.2 KB · 22 lines typescript
Raw Blame History
1import { NextResponse } from "next/server";2import { eq, or } from "drizzle-orm";3import { db } from "@/db/client";4import { users, userProfiles, listings, properties, favorites, savedSearches, inquiries, messages, viewingRequests } from "@/db/schema";5import { requireUser } from "@/lib/auth/session";6import { decrypt } from "@/lib/auth/crypto";7import { audit } from "@/lib/auth/audit";8import { handle } from "@/lib/api";9export const dynamic = "force-dynamic";10/** Portabilité (Loi 25) : export JSON des données de la personne connectée. */11export async function GET() {12  try { const u = await requireUser(); const d = db();13    const [user] = await d.select().from(users).where(eq(users.id, u.id)); const [profile] = await d.select().from(userProfiles).where(eq(userProfiles.userId, u.id));14    const myListings = await d.select({ l: listings, p: properties }).from(listings).innerJoin(properties, eq(properties.id, listings.propertyId)).where(eq(listings.ownerUserId, u.id));15    const favs = await d.select().from(favorites).where(eq(favorites.userId, u.id)); const searches = await d.select().from(savedSearches).where(eq(savedSearches.userId, u.id));16    const inqs = await d.select().from(inquiries).where(or(eq(inquiries.senderUserId, u.id), eq(inquiries.recipientUserId, u.id))); const msgs = await d.select().from(messages).where(eq(messages.senderId, u.id)); const views = await d.select().from(viewingRequests).where(or(eq(viewingRequests.requesterId, u.id), eq(viewingRequests.ownerId, u.id)));17    let phone: string | null = null; try { phone = user.phoneEncrypted ? decrypt(user.phoneEncrypted) : null; } catch { phone = null; }18    await audit("me.export", { actorId: u.id });19    const body = { exportedAt: new Date().toISOString(), user: { id: user.id, email: user.email, displayName: user.displayName, phone, locale: user.locale, prefs: user.prefs, createdAt: user.createdAt }, profile, listings: myListings, favorites: favs, savedSearches: searches, inquiries: inqs, messagesSent: msgs, viewings: views };20    return new NextResponse(JSON.stringify(body, null, 2), { headers: { "content-type": "application/json; charset=utf-8", "content-disposition": "attachment; filename=toveli-mes-donnees.json" } }); } catch (e) { return handle(e); }21}22