Added Backend
This commit is contained in:
120
backend/src/routes/profiles.ts
Normal file
120
backend/src/routes/profiles.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import { FastifyInstance } from "fastify";
|
||||
import { eq, and } from "drizzle-orm";
|
||||
|
||||
import {
|
||||
authProfiles,
|
||||
} from "../../db/schema";
|
||||
|
||||
export default async function authProfilesRoutes(server: FastifyInstance) {
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// GET SINGLE PROFILE
|
||||
// -------------------------------------------------------------
|
||||
server.get("/profiles/:id", async (req, reply) => {
|
||||
try {
|
||||
const { id } = req.params as { id: string };
|
||||
const tenantId = (req.user as any)?.tenant_id;
|
||||
|
||||
if (!tenantId) {
|
||||
return reply.code(400).send({ error: "No tenant selected" });
|
||||
}
|
||||
|
||||
const rows = await server.db
|
||||
.select()
|
||||
.from(authProfiles)
|
||||
.where(
|
||||
and(
|
||||
eq(authProfiles.id, id),
|
||||
eq(authProfiles.tenant_id, tenantId)
|
||||
)
|
||||
)
|
||||
.limit(1);
|
||||
|
||||
if (!rows.length) {
|
||||
return reply.code(404).send({ error: "User not found or not in tenant" });
|
||||
}
|
||||
|
||||
return rows[0];
|
||||
|
||||
} catch (error) {
|
||||
console.error("GET /profiles/:id ERROR:", error);
|
||||
return reply.code(500).send({ error: "Internal Server Error" });
|
||||
}
|
||||
});
|
||||
|
||||
function sanitizeProfileUpdate(body: any) {
|
||||
const cleaned: any = { ...body }
|
||||
|
||||
// ❌ Systemfelder entfernen
|
||||
const forbidden = [
|
||||
"id", "user_id", "tenant_id", "created_at", "updated_at",
|
||||
"updatedAt", "updatedBy", "old_profile_id", "full_name"
|
||||
]
|
||||
forbidden.forEach(f => delete cleaned[f])
|
||||
|
||||
// ❌ Falls NULL Strings vorkommen → in null umwandeln
|
||||
for (const key of Object.keys(cleaned)) {
|
||||
if (cleaned[key] === "") cleaned[key] = null
|
||||
}
|
||||
|
||||
// ✅ Date-Felder sauber konvertieren, falls vorhanden
|
||||
const dateFields = ["birthday", "entry_date"]
|
||||
|
||||
for (const field of dateFields) {
|
||||
if (cleaned[field]) {
|
||||
const d = new Date(cleaned[field])
|
||||
if (!isNaN(d.getTime())) cleaned[field] = d
|
||||
else delete cleaned[field] // invalid → entfernen
|
||||
}
|
||||
}
|
||||
|
||||
return cleaned
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// UPDATE PROFILE
|
||||
// -------------------------------------------------------------
|
||||
server.put("/profiles/:id", async (req, reply) => {
|
||||
try {
|
||||
const tenantId = req.user?.tenant_id
|
||||
const userId = req.user?.user_id
|
||||
|
||||
if (!tenantId) {
|
||||
return reply.code(400).send({ error: "No tenant selected" })
|
||||
}
|
||||
|
||||
const { id } = req.params as { id: string }
|
||||
let body = req.body as any
|
||||
|
||||
// Clean + Normalize
|
||||
body = sanitizeProfileUpdate(body)
|
||||
|
||||
const updateData = {
|
||||
...body,
|
||||
updatedAt: new Date(),
|
||||
updatedBy: userId
|
||||
}
|
||||
|
||||
const updated = await server.db
|
||||
.update(authProfiles)
|
||||
.set(updateData)
|
||||
.where(
|
||||
and(
|
||||
eq(authProfiles.id, id),
|
||||
eq(authProfiles.tenant_id, tenantId)
|
||||
)
|
||||
)
|
||||
.returning()
|
||||
|
||||
if (!updated.length) {
|
||||
return reply.code(404).send({ error: "User not found or not in tenant" })
|
||||
}
|
||||
|
||||
return updated[0]
|
||||
|
||||
} catch (err) {
|
||||
console.error("PUT /profiles/:id ERROR:", err)
|
||||
return reply.code(500).send({ error: "Internal Server Error" })
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user