Switch auth to plain-text password env var (remove bcrypt)

- Replace ADMIN_PASSWORD_HASH with ADMIN_PASSWORD in auth route and docker-compose
- Remove bcryptjs / @types/bcryptjs dependencies
- Delete scripts/hashPassword.ts (no longer needed)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-21 22:05:42 -05:00
parent 7ef0509f2b
commit bcb8a95fae
16 changed files with 407 additions and 156 deletions

View File

@@ -135,6 +135,42 @@ export async function deleteModule(id: string) {
return prisma.module.delete({ where: { id } });
}
/**
* Move a module to a new rack and/or U-position.
* Ports and VLAN assignments move with the module (they're linked by moduleId).
*/
export async function moveModule(
id: string,
targetRackId: string,
targetUPosition: number
) {
const existing = await prisma.module.findUnique({ where: { id } });
if (!existing) throw new AppError('Module not found', 404, 'NOT_FOUND');
const targetRack = await prisma.rack.findUnique({ where: { id: targetRackId } });
if (!targetRack) throw new AppError('Target rack not found', 404, 'NOT_FOUND');
if (targetUPosition < 1 || targetUPosition + existing.uSize - 1 > targetRack.totalU) {
throw new AppError(
`Module does not fit within target rack (U1U${targetRack.totalU})`,
400,
'OUT_OF_BOUNDS'
);
}
// Collision check in target rack, excluding self (handles same-rack moves)
const excludeInTarget = targetRackId === existing.rackId ? id : undefined;
if (await hasCollision(targetRackId, targetUPosition, existing.uSize, excludeInTarget)) {
throw new AppError('U-slot collision in target rack', 409, 'COLLISION');
}
return prisma.module.update({
where: { id },
data: { rackId: targetRackId, uPosition: targetUPosition },
include: moduleInclude,
});
}
export async function getModulePorts(id: string) {
const existing = await prisma.module.findUnique({ where: { id } });
if (!existing) throw new AppError('Module not found', 404, 'NOT_FOUND');