feat(reports): operational route — Area filter + areaOptions + hasData
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import { z } from 'zod';
|
|||||||
|
|
||||||
import { withAuth, withPermission } from '@/lib/api/helpers';
|
import { withAuth, withPermission } from '@/lib/api/helpers';
|
||||||
import { errorResponse } from '@/lib/errors';
|
import { errorResponse } from '@/lib/errors';
|
||||||
|
import { parseOperationalFilters } from '@/lib/services/reports/operational-filters';
|
||||||
import {
|
import {
|
||||||
getOperationalKpis,
|
getOperationalKpis,
|
||||||
getUtilisationHeatmap,
|
getUtilisationHeatmap,
|
||||||
@@ -16,6 +17,8 @@ import {
|
|||||||
getVacantBerths,
|
getVacantBerths,
|
||||||
getStuckSigning,
|
getStuckSigning,
|
||||||
getHighestValueVacant,
|
getHighestValueVacant,
|
||||||
|
getOperationalAreaOptions,
|
||||||
|
operationalHasData,
|
||||||
} from '@/lib/services/reports/operational.service';
|
} from '@/lib/services/reports/operational.service';
|
||||||
|
|
||||||
const querySchema = z.object({
|
const querySchema = z.object({
|
||||||
@@ -42,6 +45,7 @@ export const GET = withAuth(
|
|||||||
to: params.get('to') ?? undefined,
|
to: params.get('to') ?? undefined,
|
||||||
});
|
});
|
||||||
const range = resolveRange(from, to);
|
const range = resolveRange(from, to);
|
||||||
|
const filters = parseOperationalFilters(params);
|
||||||
|
|
||||||
const [
|
const [
|
||||||
kpis,
|
kpis,
|
||||||
@@ -56,19 +60,23 @@ export const GET = withAuth(
|
|||||||
vacantBerths,
|
vacantBerths,
|
||||||
stuckSigning,
|
stuckSigning,
|
||||||
highestValueVacant,
|
highestValueVacant,
|
||||||
|
areaOptions,
|
||||||
|
hasData,
|
||||||
] = await Promise.all([
|
] = await Promise.all([
|
||||||
getOperationalKpis(ctx.portId, range),
|
getOperationalKpis(ctx.portId, range, filters),
|
||||||
getUtilisationHeatmap(ctx.portId),
|
getUtilisationHeatmap(ctx.portId, 24, filters),
|
||||||
getStatusMixOverTime(ctx.portId),
|
getStatusMixOverTime(ctx.portId),
|
||||||
getTenancyChurn(ctx.portId),
|
getTenancyChurn(ctx.portId),
|
||||||
getTenureDistribution(ctx.portId),
|
getTenureDistribution(ctx.portId),
|
||||||
getSigningBoxPlot(ctx.portId),
|
getSigningBoxPlot(ctx.portId),
|
||||||
getOccupancyByArea(ctx.portId),
|
getOccupancyByArea(ctx.portId, filters),
|
||||||
getDocumentsInPipeline(ctx.portId),
|
getDocumentsInPipeline(ctx.portId),
|
||||||
getTenanciesEndingSoon(ctx.portId),
|
getTenanciesEndingSoon(ctx.portId),
|
||||||
getVacantBerths(ctx.portId),
|
getVacantBerths(ctx.portId, 60, filters),
|
||||||
getStuckSigning(ctx.portId),
|
getStuckSigning(ctx.portId),
|
||||||
getHighestValueVacant(ctx.portId),
|
getHighestValueVacant(ctx.portId, 10, filters),
|
||||||
|
getOperationalAreaOptions(ctx.portId),
|
||||||
|
operationalHasData(ctx.portId),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
@@ -85,6 +93,8 @@ export const GET = withAuth(
|
|||||||
vacantBerths,
|
vacantBerths,
|
||||||
stuckSigning,
|
stuckSigning,
|
||||||
highestValueVacant,
|
highestValueVacant,
|
||||||
|
areaOptions,
|
||||||
|
hasData,
|
||||||
range: {
|
range: {
|
||||||
from: range.from.toISOString(),
|
from: range.from.toISOString(),
|
||||||
to: range.to.toISOString(),
|
to: range.to.toISOString(),
|
||||||
|
|||||||
Reference in New Issue
Block a user