redone routes

This commit is contained in:
2025-12-07 22:06:37 +01:00
parent dc0b49355d
commit b90e056e7c
10 changed files with 895 additions and 1555 deletions

View File

@@ -11,18 +11,8 @@ import {
} from "drizzle-orm"
import {
projects,
customers,
plants,
contracts,
projecttypes,
createddocuments,
files,
events,
tasks, contacts, vendors
} from "../../../db/schema"
import * as sea from "node:sea";
import {resourceConfig} from "../../resource.config";
// -------------------------------------------------------------
// SQL Volltextsuche auf mehreren Feldern
@@ -50,7 +40,7 @@ export default async function resourceRoutes(server: FastifyInstance) {
// -------------------------------------------------------------
// LIST
// -------------------------------------------------------------
/*server.get("/resource/:resource", async (req, reply) => {
server.get("/resource/:resource", async (req, reply) => {
try {
const tenantId = req.user?.tenant_id
if (!tenantId)
@@ -62,34 +52,85 @@ export default async function resourceRoutes(server: FastifyInstance) {
asc?: string
}
const {resource} = req.params as {resource: string}
const table = resourceConfig[resource].table
// WHERE-Basis
let whereCond: any = eq(projects.tenant, tenantId)
let whereCond: any = eq(table.tenant, tenantId)
// 🔍 SQL Search
const searchCond = buildProjectSearch(search)
if (searchCond) whereCond = and(whereCond, searchCond)
if(search) {
const searchCond = buildSearchCondition(
table,
resourceConfig[resource].searchColumns,
search.trim()
)
if (searchCond) {
whereCond = and(whereCond, searchCond)
}
}
// Base Query
let q = server.db.select().from(projects).where(whereCond)
let q = server.db.select().from(table).where(whereCond)
// Sortierung
if (sort) {
const col = (projects as any)[sort]
const col = (table as any)[sort]
if (col) {
//@ts-ignore
q = ascQuery === "true"
? q.orderBy(asc(col))
: q.orderBy(desc(col))
}
}
const data = await q
const queryData = await q
// RELATION LOADING (MANY-TO-ONE)
let ids = {}
let lists = {}
let maps = {}
let data = []
if(resourceConfig[resource].mtoLoad) {
resourceConfig[resource].mtoLoad.forEach(relation => {
ids[relation] = [...new Set(queryData.map(r => r[relation]).filter(Boolean))];
})
for await (const relation of resourceConfig[resource].mtoLoad ) {
lists[relation] = ids[relation].length ? await server.db.select().from(resourceConfig[relation + "s"].table).where(inArray(resourceConfig[relation + "s"].table.id, ids[relation])) : []
}
resourceConfig[resource].mtoLoad.forEach(relation => {
maps[relation] = Object.fromEntries(lists[relation].map(i => [i.id, i]));
})
data = queryData.map(row => {
let toReturn = {
...row
}
resourceConfig[resource].mtoLoad.forEach(relation => {
toReturn[relation] = row[relation] ? maps[relation][row[relation]] : null
})
return toReturn
});
} else {
data = queryData
}
return data
} catch (err) {
console.error("ERROR /resource/projects", err)
console.error("ERROR /resource/:resource", err)
return reply.code(500).send({ error: "Internal Server Error" })
}
})*/
})
// -------------------------------------------------------------
@@ -118,41 +159,10 @@ export default async function resourceRoutes(server: FastifyInstance) {
};
const config = {
projects: {
searchColumns: ["name"],
mtoLoad: ["customer","plant","contract","projecttype"],
table: projects
},
customers: {
searchColumns: ["name", "customerNumber", "firstname", "lastname", "notes"],
table: customers,
},
contacts: {
searchColumns: ["firstName", "lastName", "email", "phone", "notes"],
table: contacts,
mtoLoad: ["customer","vendor"]
},
contracts: {
table: contracts,
searchColumns: ["name", "notes", "contractNumber", "paymentType", "sepaRef", "bankingName"]
},
plants: {
table: plants
},
projecttypes: {
table: projecttypes
},
vendors: {
table: vendors,
searchColumns: ["name","vendorNumber","notes","defaultPaymentType"],
},
files: {
table: files
}
}
let table = config[resource].table
let table = resourceConfig[resource].table
let whereCond: any = eq(table.tenant, tenantId);
@@ -160,7 +170,7 @@ export default async function resourceRoutes(server: FastifyInstance) {
if(search) {
const searchCond = buildSearchCondition(
table,
config[resource].searchColumns,
resourceConfig[resource].searchColumns,
search.trim()
)
@@ -225,7 +235,7 @@ export default async function resourceRoutes(server: FastifyInstance) {
if (sort?.length > 0) {
const s = sort[0];
const col = (projects as any)[s.field];
const col = (table as any)[s.field];
if (col) {
orderField = col;
direction = s.direction === "asc" ? "asc" : "desc";
@@ -268,17 +278,17 @@ export default async function resourceRoutes(server: FastifyInstance) {
let maps = {}
let data = []
if(config[resource].mtoLoad) {
config[resource].mtoLoad.forEach(relation => {
if(resourceConfig[resource].mtoLoad) {
resourceConfig[resource].mtoLoad.forEach(relation => {
ids[relation] = [...new Set(rows.map(r => r[relation]).filter(Boolean))];
})
for await (const relation of config[resource].mtoLoad ) {
lists[relation] = ids[relation].length ? await server.db.select().from(config[relation + "s"].table).where(inArray(config[relation + "s"].table.id, ids[relation])) : []
for await (const relation of resourceConfig[resource].mtoLoad ) {
lists[relation] = ids[relation].length ? await server.db.select().from(resourceConfig[relation + "s"].table).where(inArray(resourceConfig[relation + "s"].table.id, ids[relation])) : []
}
config[resource].mtoLoad.forEach(relation => {
resourceConfig[resource].mtoLoad.forEach(relation => {
maps[relation] = Object.fromEntries(lists[relation].map(i => [i.id, i]));
})
@@ -287,12 +297,14 @@ export default async function resourceRoutes(server: FastifyInstance) {
...row
}
config[resource].mtoLoad.forEach(relation => {
resourceConfig[resource].mtoLoad.forEach(relation => {
toReturn[relation] = row[relation] ? maps[relation][row[relation]] : null
})
return toReturn
});
} else {
data = rows
}
// -----------------------------------------------
@@ -318,96 +330,55 @@ export default async function resourceRoutes(server: FastifyInstance) {
// -------------------------------------------------------------
// DETAIL (mit JOINS)
// -------------------------------------------------------------
/*server.get("/resource/projects/:id", async (req, reply) => {
server.get("/resource/:resource/:id", async (req, reply) => {
try {
const { id } = req.params as { id: string }
const tenantId = req.user?.tenant_id
if (!tenantId) return reply.code(400).send({ error: "No tenant selected" })
const pid = Number(id)
const {resource} = req.params as { resource: string }
const table = resourceConfig[resource].table
const projRows = await server.db
.select()
.from(projects)
.where(and(eq(projects.id, pid), eq(projects.tenant, tenantId)))
.from(table)
.where(and(eq(table.id, id), eq(table.tenant, tenantId)))
.limit(1)
if (!projRows.length)
return reply.code(404).send({ error: "Project not found" })
const project = projRows[0]
return reply.code(404).send({ error: "Resource not found" })
// ------------------------------------
// LOAD RELATIONS
// ------------------------------------
const [
customerRecord,
plantRecord,
contractRecord,
projectTypeRecord,
projectTasks,
projectFiles,
projectDocuments,
projectEvents,
] = await Promise.all([
project.customer
? server.db.select().from(customers).where(eq(customers.id, project.customer))
: [],
project.plant
? server.db.select().from(plants).where(eq(plants.id, project.plant))
: [],
project.contract
? server.db.select().from(contracts).where(eq(contracts.id, project.contract))
: [],
project.projecttype
? server.db.select().from(projecttypes).where(eq(projecttypes.id, project.projecttype))
: [],
// Tasks
server.db
.select()
.from(tasks)
.where(eq(tasks.project, pid)),
// Files
server.db
.select()
.from(files)
.where(eq(files.project, pid)),
// Documents
server.db
.select()
.from(createddocuments)
.where(eq(createddocuments.project, pid)),
// Events
server.db
.select()
.from(events)
.where(eq(events.project, pid)),
])
return {
...project,
customer: customerRecord[0] ?? null,
plant: plantRecord[0] ?? null,
contract: contractRecord[0] ?? null,
projecttype: projectTypeRecord[0] ?? null,
tasks: projectTasks,
files: projectFiles,
createddocuments: projectDocuments,
events: projectEvents,
let ids = {}
let lists = {}
let maps = {}
let data = {
...projRows[0]
}
if(resourceConfig[resource].mtoLoad) {
for await (const relation of resourceConfig[resource].mtoLoad ) {
if(data[relation]) {
data[relation] = await server.db.select().from(resourceConfig[relation + "s"].table).where(eq(resourceConfig[relation + "s"].table.id, data[relation]))
}
}
for await (const relation of resourceConfig[resource].mtmLoad ) {
console.log(relation)
data[relation] = await server.db.select().from(resourceConfig[relation].table).where(eq(resourceConfig[relation].table[resource.substring(0,resource.length - 1)],id))
}
}
return data
} catch (err) {
console.error("ERROR /resource/projects/:id", err)
return reply.code(500).send({ error: "Internal Server Error" })
}
})*/
})
}