Listen again, I have a parking lot administrator - he manages several parking lots and I am only responsible for this user management, that is, displaying the details of all the existing administrators in the system, giving the option of updating user-administrator details, and the option to add a user. I think there is something to update in the area of seeing all the administrators - it may be worth adding filtering options - not only all the details of all the users, but certain data of certain administrators and perhaps also a certain number of administrators or by names, etc. In addition, I think there should be an option to update a user, not only by ID. But other things - according to logic.
This is the code that I already have:
import { pool } from '../config/db';
import { AdminUser } from '../model/adminUser';

// Uniqueness check of idNumber and email in the BaseUser table
async function checkUniqueBaseUser( 
idNumber: string, 
email: string, 
excludeBaseUserId?: number
): Promise<void> { 
let query = ` 
SELECT 1 FROM "BaseUser" 
WHERE ("idNumber" = $1 OR "email" = $2) 
`; 
const params: (string | number)[] = [idNumber, email]; 

if (excludeBaseUserId) { 
query += ' AND id <> $3'; 
params.push(excludeBaseUserId); 
} 

query += 'LIMIT 1'; 

const { rowCount } = await pool.query(query, params); 
if ((rowCount ?? 0) > 0) { 
throw new Error('User with same idNumber or email already exists'); 
}
}

// Helper function to retrieve full AdminUser by id
async function getAdminUserById(id: number): Promise<AdminUser> { 
const query = ` 
SELECT 
a.id, 
a."baseUserId", 
b."idNumber", 
b."email", 
b."firstName", 
b."lastName", 
a."passwordHash", 
a."role", 
a."permissions", 
a."lastLoginAt", 
a."createdAt", 
a."updatedAt" 
FROM "AdminUsers" a 
JOIN "BaseUser" b ON a."baseUserId" = b.id 
WHERE a.id = $1; 
`; 
const { rows } = await pool.query(query, [id]); 
if (rows.length === 0) throw new Error(`AdminUser with id ${id} not found`); 

// Convert permissions from string/jsonb to array if required
if (typeof rows[0].permissions === 'string') {
try {
rows[0].permissions = JSON.parse(rows[0].permissions);
} catch {
rows[0].permissions = [];
}
}
const { baseUserId, ...dataWithoutBaseUserId } = rows[0];

return AdminUser.create(dataWithoutBaseUserId);
}

// Add an admin user with full validation and create a valid AdminUser instance
export async function addAdminUser(data: any): Promise<AdminUser> {
const now = new Date();
const adminUser = AdminUser.create({
...data,
createdAt: now,
updatedAt: now,
lastLoginAt: now, // optional, you can leave it blank and let the code add
});

await checkUniqueBaseUser(adminUser.idNumber, adminUser.email);

// Add BaseUser 
const baseUserQuery = ` 
INSERT INTO "BaseUser" 
("idNumber", "email", "firstName", "lastName", "createdAt", "updatedAt") 
VALUES ($1, $2, $3, $4, $5, $6) 
RETURNING id 
`; 
const baseUserValues = [ 
adminUser.idNumber, 
adminUser.email, 
adminUser.firstName, 
adminUser.lastName, 
adminUser.createdAt, 
adminUser.updatedAt, 
]; 
const baseUserResult = await pool.query(baseUserQuery, baseUserValues); 
const baseUserId = baseUserResult.rows[0].id; 

// Add AdminUser 
const adminUserQuery = ` 
INSERT INTO "AdminUsers" ( 
"baseUserId", "passwordHash", "role", "permissions", "lastLoginAt", "createdAt", "updatedAt" 
) VALUES ($1, $2, $3, $4, $5, $6, $7) 
RETURNING id 
`; 
const adminUserValues = [ 
baseUserId, 
adminUser.passwordHash, 
adminUser.role, 
JSON.stringify(adminUser.permissions), 
adminUser.lastLoginAt, 
adminUser.createdAt, 
adminUser.updatedAt, 
]; 
const adminUserResult = await pool.query(adminUserQuery, adminUserValues); 
const newAdminUserId = adminUserResult.rows[0].id; 

// Retrieve a full AdminUser with all fields to create a proper object 
return await getAdminUserById(newAdminUserId);
}

// Update admin user
export async function updateAdminUser(id: number, data: any): Promise<AdminUser> {
const updatedAt = new Date();

// First, get the existing user (including all required fields)
const existingAdminUser = await getAdminUserById(id);

if (!existingAdminUser) {
throw new Error(`AdminUser with id ${id} not found`);
}

// Merge the updated fields (data) into the existing fields
const mergedData = {
...existingAdminUser,
...data,
updatedAt, // Update the update time field
};

const adminUser = AdminUser.create(mergedData);

// Continue writing to DB (as your example)
// First find baseUserId - if it is not in mergedData, ask from DB
const baseUserIdResult = await pool.query(`SELECT "baseUserId" FROM "AdminUsers" WHERE id = $1`, [id]);
if(baseUserIdResult.rowCount === 0) {
throw new Error(`AdminUser with id ${id} not found`);
}
const baseUserId = baseUserIdResult.rows[0].baseUserId;

// Checking the uniqueness of idNumber and email
await checkUniqueBaseUser(adminUser.idNumber, adminUser.email, baseUserId);

// Updating BaseUser table
const baseUserUpdateQuery = `
UPDATE "BaseUser"
SET "idNumber"=$1, "email"=$2, "firstName"=$3, "lastName"=$4, "updatedAt"=$5
WHERE id = $6
`;
  const baseUserValues = [
    adminUser.idNumber,
    adminUser.email,
    adminUser.firstName,
    adminUser.lastName,
    updatedAt,
    baseUserId,
  ];
  await pool.query(baseUserUpdateQuery, baseUserValues);

  // עדכון טבלת AdminUsers
  const adminUserUpdateQuery = `
    UPDATE "AdminUsers"
    SET "passwordHash"=$1, "role"=$2, "permissions"=$3, "lastLoginAt"=$4, "updatedAt"=$5
    WHERE id = $6
  `;
const adminUserValues = [ 
adminUser.passwordHash, 
adminUser.role, 
JSON.stringify(adminUser.permissions), 
adminUser.lastLoginAt ?? null, 
updatedAt, 
ID, 
]; 
const result = await pool.query(adminUserUpdateQuery, adminUserValues); 

if (result.rowCount === 0) { 
throw new Error(`AdminUser with id ${id} not found`); 
} 

return await getAdminUserById(id);
}


// Deleting an admin user (optimization with ON DELETE CASCADE in the base)
export async function deleteAdminUser(id: number): Promise<void> { 
const deleteResult = await pool.query(`DELETE FROM "AdminUsers" WHERE id = $1`, [id]); 
if (deleteResult.rowCount === 0) { 
throw new Error(`AdminUser with id ${id} not found`); 
}
// Deleting BaseUser is done automatically by FK with ON DELETE CASCADE in the database
}

// Getting all admin users
export async function getAllAdminUsers(): Promise<AdminUser[]> {
const query = `
SELECT
a.id,
a."baseUserId",
b."idNumber",
b."email",
b."firstName",
b."lastName",
a."passwordHash",
a."role",
a."permissions",
a."lastLoginAt",
a."createdAt",
a."updatedAt"
FROM "AdminUsers" a
JOIN "BaseUser" b ON a."baseUserId" = b.id;
`;
const { rows } = await pool.query(query);

return rows.map(row => { 
if (typeof row.permissions === 'string') { 
try { 
row.permissions = JSON.parse(row.permissions); 
} catch { 
row.permissions = []; 
} 
} 
const { baseUserId, ...dataWithoutBaseUserId } = row;

return AdminUser.create(dataWithoutBaseUserId); 
});
}.
Now I want you answer me- in table- which changes shuold I do.