- Fix all TypeScript compilation errors (0 errors in src/) - Add try/catch error handling to ALL API routes (38 handlers) - Fix empty catch blocks (api-auth.ts now logs warnings) - Add aria-labels to all icon-only buttons (WCAG 2.1 AA) - Fix Prisma type mismatches (OR filter, Person.companyId, Estimate.projectId, Ticket.createdAt) - Fix webhook PATCH route (moved to [id]/route.ts) - Fix mobile-bottom-nav type safety - Fix KB route where-clause type - Fix test-mail banner null vs undefined - Fix task comment fetch: add cancellation + error toast - ESLint: 0 errors, 0 warnings - 175 files, 24.741 lines of code
47 lines
1.6 KiB
TypeScript
Executable File
47 lines
1.6 KiB
TypeScript
Executable File
import { db } from '@/lib/db'
|
|
import { verifyToken, requireScope } from '@/lib/api-auth'
|
|
|
|
export const dynamic = 'force-dynamic'
|
|
|
|
// GET /api/v1/licenses
|
|
// Public API: list issued licenses. Requires scope "licenses.license:read".
|
|
export async function GET(req: Request) {
|
|
try {
|
|
const auth = await verifyToken(req.headers.get('authorization'))
|
|
const check = requireScope(auth, 'licenses.license:read')
|
|
if (!check.allowed) return check.error!
|
|
|
|
const { searchParams } = new URL(req.url)
|
|
const limit = Math.min(Number(searchParams.get('limit') ?? 50), 200)
|
|
const status = searchParams.get('status')
|
|
|
|
const where = status ? { status } : {}
|
|
const licenses = await db.license.findMany({
|
|
where,
|
|
take: limit,
|
|
orderBy: { createdAt: 'desc' },
|
|
include: { company: true, activations: true },
|
|
})
|
|
|
|
return Response.json({
|
|
data: licenses.map((l) => ({
|
|
id: l.id,
|
|
key: l.key,
|
|
product: l.product,
|
|
plan: l.plan,
|
|
status: l.status,
|
|
maxActivations: l.maxActivations,
|
|
validUntil: l.validUntil,
|
|
createdAt: l.createdAt,
|
|
company: { id: l.company.id, name: l.company.name },
|
|
activations: l.activations.map((a) => ({ domain: a.domain, environment: a.environment, version: a.version, lastCheck: a.lastCheck })),
|
|
})),
|
|
pagination: { total: licenses.length, limit },
|
|
token: auth.token!.name,
|
|
})
|
|
} catch (err) {
|
|
const msg = err instanceof Error ? err.message : 'internal server error'
|
|
return Response.json({ error: msg }, { status: 500 })
|
|
}
|
|
}
|