mirror of
https://github.com/kjanat/livedash-node.git
synced 2026-01-16 11:12:11 +01:00
feat: comprehensive Biome linting fixes and code quality improvements
Major code quality overhaul addressing 58% of all linting issues: • Type Safety Improvements: - Replace all any types with proper TypeScript interfaces - Fix Map component shadowing (renamed to CountryMap) - Add comprehensive custom error classes system - Enhance API route type safety • Accessibility Enhancements: - Add explicit button types to all interactive elements - Implement useId() hooks for form element accessibility - Add SVG title attributes for screen readers - Fix static element interactions with keyboard handlers • React Best Practices: - Resolve exhaustive dependencies warnings with useCallback - Extract nested component definitions to top level - Fix array index keys with proper unique identifiers - Improve component organization and prop typing • Code Organization: - Automatic import organization and type import optimization - Fix unused function parameters and variables - Enhanced error handling with structured error responses - Improve component reusability and maintainability Results: 248 → 104 total issues (58% reduction) - Fixed all critical type safety and security issues - Enhanced accessibility compliance significantly - Improved code maintainability and performance
This commit is contained in:
@ -1,8 +1,8 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { CompanyStatus } from "@prisma/client";
|
||||
import { type NextRequest, NextResponse } from "next/server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { platformAuthOptions } from "../../../../../lib/platform-auth";
|
||||
import { prisma } from "../../../../../lib/prisma";
|
||||
import { CompanyStatus } from "@prisma/client";
|
||||
|
||||
interface PlatformSession {
|
||||
user: {
|
||||
@ -16,14 +16,19 @@ interface PlatformSession {
|
||||
|
||||
// GET /api/platform/companies/[id] - Get company details
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
_request: NextRequest,
|
||||
{ params }: { params: Promise<{ id: string }> }
|
||||
) {
|
||||
try {
|
||||
const session = await getServerSession(platformAuthOptions) as PlatformSession | null;
|
||||
const session = (await getServerSession(
|
||||
platformAuthOptions
|
||||
)) as PlatformSession | null;
|
||||
|
||||
if (!session?.user?.isPlatformUser) {
|
||||
return NextResponse.json({ error: "Platform access required" }, { status: 401 });
|
||||
return NextResponse.json(
|
||||
{ error: "Platform access required" },
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
const { id } = await params;
|
||||
@ -59,7 +64,10 @@ export async function GET(
|
||||
return NextResponse.json(company);
|
||||
} catch (error) {
|
||||
console.error("Platform company details error:", error);
|
||||
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
|
||||
return NextResponse.json(
|
||||
{ error: "Internal server error" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,15 +79,30 @@ export async function PATCH(
|
||||
try {
|
||||
const session = await getServerSession(platformAuthOptions);
|
||||
|
||||
if (!session?.user?.isPlatformUser || session.user.platformRole === "SUPPORT") {
|
||||
return NextResponse.json({ error: "Admin access required" }, { status: 403 });
|
||||
if (
|
||||
!session?.user?.isPlatformUser ||
|
||||
session.user.platformRole === "SUPPORT"
|
||||
) {
|
||||
return NextResponse.json(
|
||||
{ error: "Admin access required" },
|
||||
{ status: 403 }
|
||||
);
|
||||
}
|
||||
|
||||
const { id } = await params;
|
||||
const body = await request.json();
|
||||
const { name, email, maxUsers, csvUrl, csvUsername, csvPassword, status } = body;
|
||||
const { name, email, maxUsers, csvUrl, csvUsername, csvPassword, status } =
|
||||
body;
|
||||
|
||||
const updateData: any = {};
|
||||
const updateData: {
|
||||
name?: string;
|
||||
email?: string;
|
||||
maxUsers?: number;
|
||||
csvUrl?: string;
|
||||
csvUsername?: string;
|
||||
csvPassword?: string;
|
||||
status?: CompanyStatus;
|
||||
} = {};
|
||||
if (name !== undefined) updateData.name = name;
|
||||
if (email !== undefined) updateData.email = email;
|
||||
if (maxUsers !== undefined) updateData.maxUsers = maxUsers;
|
||||
@ -96,20 +119,29 @@ export async function PATCH(
|
||||
return NextResponse.json({ company });
|
||||
} catch (error) {
|
||||
console.error("Platform company update error:", error);
|
||||
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
|
||||
return NextResponse.json(
|
||||
{ error: "Internal server error" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /api/platform/companies/[id] - Delete company (archives instead)
|
||||
export async function DELETE(
|
||||
request: NextRequest,
|
||||
_request: NextRequest,
|
||||
{ params }: { params: Promise<{ id: string }> }
|
||||
) {
|
||||
try {
|
||||
const session = await getServerSession(platformAuthOptions);
|
||||
|
||||
if (!session?.user?.isPlatformUser || session.user.platformRole !== "SUPER_ADMIN") {
|
||||
return NextResponse.json({ error: "Super admin access required" }, { status: 403 });
|
||||
if (
|
||||
!session?.user?.isPlatformUser ||
|
||||
session.user.platformRole !== "SUPER_ADMIN"
|
||||
) {
|
||||
return NextResponse.json(
|
||||
{ error: "Super admin access required" },
|
||||
{ status: 403 }
|
||||
);
|
||||
}
|
||||
|
||||
const { id } = await params;
|
||||
@ -123,6 +155,9 @@ export async function DELETE(
|
||||
return NextResponse.json({ company });
|
||||
} catch (error) {
|
||||
console.error("Platform company archive error:", error);
|
||||
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
|
||||
return NextResponse.json(
|
||||
{ error: "Internal server error" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { hash } from "bcryptjs";
|
||||
import { type NextRequest, NextResponse } from "next/server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { platformAuthOptions } from "../../../../../../lib/platform-auth";
|
||||
import { prisma } from "../../../../../../lib/prisma";
|
||||
import { hash } from "bcryptjs";
|
||||
|
||||
// POST /api/platform/companies/[id]/users - Invite user to company
|
||||
export async function POST(
|
||||
@ -12,8 +12,14 @@ export async function POST(
|
||||
try {
|
||||
const session = await getServerSession(platformAuthOptions);
|
||||
|
||||
if (!session?.user?.isPlatformUser || session.user.platformRole === "SUPPORT") {
|
||||
return NextResponse.json({ error: "Admin access required" }, { status: 403 });
|
||||
if (
|
||||
!session?.user?.isPlatformUser ||
|
||||
session.user.platformRole === "SUPPORT"
|
||||
) {
|
||||
return NextResponse.json(
|
||||
{ error: "Admin access required" },
|
||||
{ status: 403 }
|
||||
);
|
||||
}
|
||||
|
||||
const { id: companyId } = await params;
|
||||
@ -21,7 +27,10 @@ export async function POST(
|
||||
const { name, email, role = "USER" } = body;
|
||||
|
||||
if (!name || !email) {
|
||||
return NextResponse.json({ error: "Name and email are required" }, { status: 400 });
|
||||
return NextResponse.json(
|
||||
{ error: "Name and email are required" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Check if company exists
|
||||
@ -88,24 +97,31 @@ export async function POST(
|
||||
return NextResponse.json({
|
||||
user,
|
||||
tempPassword, // Remove this in production and send via email
|
||||
message: "User invited successfully. In production, credentials would be sent via email.",
|
||||
message:
|
||||
"User invited successfully. In production, credentials would be sent via email.",
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Platform user invitation error:", error);
|
||||
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
|
||||
return NextResponse.json(
|
||||
{ error: "Internal server error" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/platform/companies/[id]/users - Get company users
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
_request: NextRequest,
|
||||
{ params }: { params: Promise<{ id: string }> }
|
||||
) {
|
||||
try {
|
||||
const session = await getServerSession(platformAuthOptions);
|
||||
|
||||
if (!session?.user?.isPlatformUser) {
|
||||
return NextResponse.json({ error: "Platform access required" }, { status: 401 });
|
||||
return NextResponse.json(
|
||||
{ error: "Platform access required" },
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
const { id: companyId } = await params;
|
||||
@ -127,6 +143,9 @@ export async function GET(
|
||||
return NextResponse.json({ users });
|
||||
} catch (error) {
|
||||
console.error("Platform users list error:", error);
|
||||
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
|
||||
return NextResponse.json(
|
||||
{ error: "Internal server error" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import type { CompanyStatus } from "@prisma/client";
|
||||
import { type NextRequest, NextResponse } from "next/server";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { platformAuthOptions } from "../../../../lib/platform-auth";
|
||||
import { prisma } from "../../../../lib/prisma";
|
||||
import { CompanyStatus } from "@prisma/client";
|
||||
|
||||
// GET /api/platform/companies - List all companies
|
||||
export async function GET(request: NextRequest) {
|
||||
@ -10,7 +10,10 @@ export async function GET(request: NextRequest) {
|
||||
const session = await getServerSession(platformAuthOptions);
|
||||
|
||||
if (!session?.user?.isPlatformUser) {
|
||||
return NextResponse.json({ error: "Platform access required" }, { status: 401 });
|
||||
return NextResponse.json(
|
||||
{ error: "Platform access required" },
|
||||
{ status: 401 }
|
||||
);
|
||||
}
|
||||
|
||||
const { searchParams } = new URL(request.url);
|
||||
@ -20,7 +23,13 @@ export async function GET(request: NextRequest) {
|
||||
const limit = parseInt(searchParams.get("limit") || "20");
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
const where: any = {};
|
||||
const where: {
|
||||
status?: CompanyStatus;
|
||||
name?: {
|
||||
contains: string;
|
||||
mode: "insensitive";
|
||||
};
|
||||
} = {};
|
||||
if (status) where.status = status;
|
||||
if (search) {
|
||||
where.name = {
|
||||
@ -65,7 +74,10 @@ export async function GET(request: NextRequest) {
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Platform companies list error:", error);
|
||||
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
|
||||
return NextResponse.json(
|
||||
{ error: "Internal server error" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,33 +86,46 @@ export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const session = await getServerSession(platformAuthOptions);
|
||||
|
||||
if (!session?.user?.isPlatformUser || session.user.platformRole === "SUPPORT") {
|
||||
return NextResponse.json({ error: "Admin access required" }, { status: 403 });
|
||||
if (
|
||||
!session?.user?.isPlatformUser ||
|
||||
session.user.platformRole === "SUPPORT"
|
||||
) {
|
||||
return NextResponse.json(
|
||||
{ error: "Admin access required" },
|
||||
{ status: 403 }
|
||||
);
|
||||
}
|
||||
|
||||
const body = await request.json();
|
||||
const {
|
||||
name,
|
||||
csvUrl,
|
||||
csvUsername,
|
||||
csvPassword,
|
||||
const {
|
||||
name,
|
||||
csvUrl,
|
||||
csvUsername,
|
||||
csvPassword,
|
||||
adminEmail,
|
||||
adminName,
|
||||
adminPassword,
|
||||
maxUsers = 10,
|
||||
status = "TRIAL"
|
||||
status = "TRIAL",
|
||||
} = body;
|
||||
|
||||
if (!name || !csvUrl) {
|
||||
return NextResponse.json({ error: "Name and CSV URL required" }, { status: 400 });
|
||||
return NextResponse.json(
|
||||
{ error: "Name and CSV URL required" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
if (!adminEmail || !adminName) {
|
||||
return NextResponse.json({ error: "Admin email and name required" }, { status: 400 });
|
||||
return NextResponse.json(
|
||||
{ error: "Admin email and name required" },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Generate password if not provided
|
||||
const finalAdminPassword = adminPassword || `Temp${Math.random().toString(36).slice(2, 8)}!`;
|
||||
const finalAdminPassword =
|
||||
adminPassword || `Temp${Math.random().toString(36).slice(2, 8)}!`;
|
||||
|
||||
// Hash the admin password
|
||||
const bcrypt = await import("bcryptjs");
|
||||
@ -133,20 +158,30 @@ export async function POST(request: NextRequest) {
|
||||
},
|
||||
});
|
||||
|
||||
return { company, adminUser, generatedPassword: adminPassword ? null : finalAdminPassword };
|
||||
return {
|
||||
company,
|
||||
adminUser,
|
||||
generatedPassword: adminPassword ? null : finalAdminPassword,
|
||||
};
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
company: result.company,
|
||||
adminUser: {
|
||||
email: result.adminUser.email,
|
||||
name: result.adminUser.name,
|
||||
role: result.adminUser.role,
|
||||
return NextResponse.json(
|
||||
{
|
||||
company: result.company,
|
||||
adminUser: {
|
||||
email: result.adminUser.email,
|
||||
name: result.adminUser.name,
|
||||
role: result.adminUser.role,
|
||||
},
|
||||
generatedPassword: result.generatedPassword,
|
||||
},
|
||||
generatedPassword: result.generatedPassword,
|
||||
}, { status: 201 });
|
||||
{ status: 201 }
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Platform company creation error:", error);
|
||||
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
|
||||
return NextResponse.json(
|
||||
{ error: "Internal server error" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user