feat(reports-overhaul): sales + operational + custom reports, templates, schedules, exports
End-to-end reports build covering Phases 1, 2, 5, 6, 7 of Initiative 1
in docs/launch-readiness.md. Phases 3 (Marketing) + 4 (Financial)
remain deferred per the gap audit at the bottom of that doc.
Highlights:
- Sales performance report: 7 KPI tiles, pipeline funnel + stage
velocity + win-rate-over-time + source conversion + rep leaderboard
charts, deal-heat section, 5 detail tables, stage / lead-cat /
outcome filters.
- Operational report: 7 KPIs, 7 charts (heatmap, status mix, tenancy
churn, tenure histogram, signing box plot, occupancy by area, docs
in pipeline), 4 tables. Module-OFF banner when tenancies disabled.
- Custom (ad-hoc) builder v1: 4 entities (clients, interests, berths,
tenancies), column-whitelist composer, date filter, CSV download,
save-as-template. Registry-only extension path for the remaining 6
entities documented at src/lib/reports/custom/registry.ts.
- Templates: load / modify / save / save-as on Sales / Operational /
Custom. ?templateId= URL deep-link hydration via useRef guard.
Active-template badge clears when the user drives view-state via
wrapped setters; raw setters used on template apply so the badge
survives.
- Scheduled runs: BullMQ poll fires due schedules, mints report_runs,
renders, optionally emails. Recipients optional (zero-recipient
schedules archive without sending). PDF-only output for v1.
Schedule dialog re-mounts via key prop on schedule.id transitions
to avoid setState-in-effect reset patterns.
- Server-side PDF endpoint + shared payload renderer
(lib/pdf/reports/payload-report.tsx) so client + scheduler share
one rendering path.
- Shared currency formatter (lib/reports/format-currency.ts)
consolidates 5 duplicated formatMoney helpers; fixes hardcoded
'USD' in detail tables; pre-formats money rows so PDF export
(which strips column.format callbacks at the JSON boundary)
renders consistently with CSV / XLSX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 22:41:53 +02:00
|
|
|
import { NextRequest, NextResponse } from 'next/server';
|
|
|
|
|
import { z } from 'zod';
|
|
|
|
|
|
|
|
|
|
import { withAuth, withPermission } from '@/lib/api/helpers';
|
|
|
|
|
import { errorResponse } from '@/lib/errors';
|
2026-06-02 10:11:26 +02:00
|
|
|
import { parseOperationalFilters } from '@/lib/services/reports/operational-filters';
|
feat(reports-overhaul): sales + operational + custom reports, templates, schedules, exports
End-to-end reports build covering Phases 1, 2, 5, 6, 7 of Initiative 1
in docs/launch-readiness.md. Phases 3 (Marketing) + 4 (Financial)
remain deferred per the gap audit at the bottom of that doc.
Highlights:
- Sales performance report: 7 KPI tiles, pipeline funnel + stage
velocity + win-rate-over-time + source conversion + rep leaderboard
charts, deal-heat section, 5 detail tables, stage / lead-cat /
outcome filters.
- Operational report: 7 KPIs, 7 charts (heatmap, status mix, tenancy
churn, tenure histogram, signing box plot, occupancy by area, docs
in pipeline), 4 tables. Module-OFF banner when tenancies disabled.
- Custom (ad-hoc) builder v1: 4 entities (clients, interests, berths,
tenancies), column-whitelist composer, date filter, CSV download,
save-as-template. Registry-only extension path for the remaining 6
entities documented at src/lib/reports/custom/registry.ts.
- Templates: load / modify / save / save-as on Sales / Operational /
Custom. ?templateId= URL deep-link hydration via useRef guard.
Active-template badge clears when the user drives view-state via
wrapped setters; raw setters used on template apply so the badge
survives.
- Scheduled runs: BullMQ poll fires due schedules, mints report_runs,
renders, optionally emails. Recipients optional (zero-recipient
schedules archive without sending). PDF-only output for v1.
Schedule dialog re-mounts via key prop on schedule.id transitions
to avoid setState-in-effect reset patterns.
- Server-side PDF endpoint + shared payload renderer
(lib/pdf/reports/payload-report.tsx) so client + scheduler share
one rendering path.
- Shared currency formatter (lib/reports/format-currency.ts)
consolidates 5 duplicated formatMoney helpers; fixes hardcoded
'USD' in detail tables; pre-formats money rows so PDF export
(which strips column.format callbacks at the JSON boundary)
renders consistently with CSV / XLSX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 22:41:53 +02:00
|
|
|
import {
|
|
|
|
|
getOperationalKpis,
|
|
|
|
|
getUtilisationHeatmap,
|
|
|
|
|
getStatusMixOverTime,
|
|
|
|
|
getTenancyChurn,
|
|
|
|
|
getTenureDistribution,
|
|
|
|
|
getSigningBoxPlot,
|
|
|
|
|
getOccupancyByArea,
|
|
|
|
|
getDocumentsInPipeline,
|
|
|
|
|
getTenanciesEndingSoon,
|
|
|
|
|
getVacantBerths,
|
|
|
|
|
getStuckSigning,
|
|
|
|
|
getHighestValueVacant,
|
2026-06-02 10:11:26 +02:00
|
|
|
getOperationalAreaOptions,
|
|
|
|
|
operationalHasData,
|
feat(reports-overhaul): sales + operational + custom reports, templates, schedules, exports
End-to-end reports build covering Phases 1, 2, 5, 6, 7 of Initiative 1
in docs/launch-readiness.md. Phases 3 (Marketing) + 4 (Financial)
remain deferred per the gap audit at the bottom of that doc.
Highlights:
- Sales performance report: 7 KPI tiles, pipeline funnel + stage
velocity + win-rate-over-time + source conversion + rep leaderboard
charts, deal-heat section, 5 detail tables, stage / lead-cat /
outcome filters.
- Operational report: 7 KPIs, 7 charts (heatmap, status mix, tenancy
churn, tenure histogram, signing box plot, occupancy by area, docs
in pipeline), 4 tables. Module-OFF banner when tenancies disabled.
- Custom (ad-hoc) builder v1: 4 entities (clients, interests, berths,
tenancies), column-whitelist composer, date filter, CSV download,
save-as-template. Registry-only extension path for the remaining 6
entities documented at src/lib/reports/custom/registry.ts.
- Templates: load / modify / save / save-as on Sales / Operational /
Custom. ?templateId= URL deep-link hydration via useRef guard.
Active-template badge clears when the user drives view-state via
wrapped setters; raw setters used on template apply so the badge
survives.
- Scheduled runs: BullMQ poll fires due schedules, mints report_runs,
renders, optionally emails. Recipients optional (zero-recipient
schedules archive without sending). PDF-only output for v1.
Schedule dialog re-mounts via key prop on schedule.id transitions
to avoid setState-in-effect reset patterns.
- Server-side PDF endpoint + shared payload renderer
(lib/pdf/reports/payload-report.tsx) so client + scheduler share
one rendering path.
- Shared currency formatter (lib/reports/format-currency.ts)
consolidates 5 duplicated formatMoney helpers; fixes hardcoded
'USD' in detail tables; pre-formats money rows so PDF export
(which strips column.format callbacks at the JSON boundary)
renders consistently with CSV / XLSX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 22:41:53 +02:00
|
|
|
} from '@/lib/services/reports/operational.service';
|
|
|
|
|
|
|
|
|
|
const querySchema = z.object({
|
|
|
|
|
from: z.string().datetime().optional(),
|
|
|
|
|
to: z.string().datetime().optional(),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function resolveRange(from?: string, to?: string): { from: Date; to: Date } {
|
|
|
|
|
const now = new Date();
|
|
|
|
|
const defaultFrom = new Date(now);
|
|
|
|
|
defaultFrom.setDate(defaultFrom.getDate() - 30);
|
|
|
|
|
return {
|
|
|
|
|
from: from ? new Date(from) : defaultFrom,
|
|
|
|
|
to: to ? new Date(to) : now,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const GET = withAuth(
|
|
|
|
|
withPermission('reports', 'view_dashboard', async (req: NextRequest, ctx) => {
|
|
|
|
|
try {
|
|
|
|
|
const params = req.nextUrl.searchParams;
|
|
|
|
|
const { from, to } = querySchema.parse({
|
|
|
|
|
from: params.get('from') ?? undefined,
|
|
|
|
|
to: params.get('to') ?? undefined,
|
|
|
|
|
});
|
|
|
|
|
const range = resolveRange(from, to);
|
2026-06-02 10:11:26 +02:00
|
|
|
const filters = parseOperationalFilters(params);
|
feat(reports-overhaul): sales + operational + custom reports, templates, schedules, exports
End-to-end reports build covering Phases 1, 2, 5, 6, 7 of Initiative 1
in docs/launch-readiness.md. Phases 3 (Marketing) + 4 (Financial)
remain deferred per the gap audit at the bottom of that doc.
Highlights:
- Sales performance report: 7 KPI tiles, pipeline funnel + stage
velocity + win-rate-over-time + source conversion + rep leaderboard
charts, deal-heat section, 5 detail tables, stage / lead-cat /
outcome filters.
- Operational report: 7 KPIs, 7 charts (heatmap, status mix, tenancy
churn, tenure histogram, signing box plot, occupancy by area, docs
in pipeline), 4 tables. Module-OFF banner when tenancies disabled.
- Custom (ad-hoc) builder v1: 4 entities (clients, interests, berths,
tenancies), column-whitelist composer, date filter, CSV download,
save-as-template. Registry-only extension path for the remaining 6
entities documented at src/lib/reports/custom/registry.ts.
- Templates: load / modify / save / save-as on Sales / Operational /
Custom. ?templateId= URL deep-link hydration via useRef guard.
Active-template badge clears when the user drives view-state via
wrapped setters; raw setters used on template apply so the badge
survives.
- Scheduled runs: BullMQ poll fires due schedules, mints report_runs,
renders, optionally emails. Recipients optional (zero-recipient
schedules archive without sending). PDF-only output for v1.
Schedule dialog re-mounts via key prop on schedule.id transitions
to avoid setState-in-effect reset patterns.
- Server-side PDF endpoint + shared payload renderer
(lib/pdf/reports/payload-report.tsx) so client + scheduler share
one rendering path.
- Shared currency formatter (lib/reports/format-currency.ts)
consolidates 5 duplicated formatMoney helpers; fixes hardcoded
'USD' in detail tables; pre-formats money rows so PDF export
(which strips column.format callbacks at the JSON boundary)
renders consistently with CSV / XLSX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 22:41:53 +02:00
|
|
|
|
|
|
|
|
const [
|
|
|
|
|
kpis,
|
|
|
|
|
utilisationHeatmap,
|
|
|
|
|
statusMix,
|
|
|
|
|
tenancyChurn,
|
|
|
|
|
tenureDistribution,
|
|
|
|
|
signingBoxPlot,
|
|
|
|
|
occupancyByArea,
|
|
|
|
|
docsInPipeline,
|
|
|
|
|
endingSoon,
|
|
|
|
|
vacantBerths,
|
|
|
|
|
stuckSigning,
|
|
|
|
|
highestValueVacant,
|
2026-06-02 10:11:26 +02:00
|
|
|
areaOptions,
|
|
|
|
|
hasData,
|
feat(reports-overhaul): sales + operational + custom reports, templates, schedules, exports
End-to-end reports build covering Phases 1, 2, 5, 6, 7 of Initiative 1
in docs/launch-readiness.md. Phases 3 (Marketing) + 4 (Financial)
remain deferred per the gap audit at the bottom of that doc.
Highlights:
- Sales performance report: 7 KPI tiles, pipeline funnel + stage
velocity + win-rate-over-time + source conversion + rep leaderboard
charts, deal-heat section, 5 detail tables, stage / lead-cat /
outcome filters.
- Operational report: 7 KPIs, 7 charts (heatmap, status mix, tenancy
churn, tenure histogram, signing box plot, occupancy by area, docs
in pipeline), 4 tables. Module-OFF banner when tenancies disabled.
- Custom (ad-hoc) builder v1: 4 entities (clients, interests, berths,
tenancies), column-whitelist composer, date filter, CSV download,
save-as-template. Registry-only extension path for the remaining 6
entities documented at src/lib/reports/custom/registry.ts.
- Templates: load / modify / save / save-as on Sales / Operational /
Custom. ?templateId= URL deep-link hydration via useRef guard.
Active-template badge clears when the user drives view-state via
wrapped setters; raw setters used on template apply so the badge
survives.
- Scheduled runs: BullMQ poll fires due schedules, mints report_runs,
renders, optionally emails. Recipients optional (zero-recipient
schedules archive without sending). PDF-only output for v1.
Schedule dialog re-mounts via key prop on schedule.id transitions
to avoid setState-in-effect reset patterns.
- Server-side PDF endpoint + shared payload renderer
(lib/pdf/reports/payload-report.tsx) so client + scheduler share
one rendering path.
- Shared currency formatter (lib/reports/format-currency.ts)
consolidates 5 duplicated formatMoney helpers; fixes hardcoded
'USD' in detail tables; pre-formats money rows so PDF export
(which strips column.format callbacks at the JSON boundary)
renders consistently with CSV / XLSX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 22:41:53 +02:00
|
|
|
] = await Promise.all([
|
2026-06-02 10:11:26 +02:00
|
|
|
getOperationalKpis(ctx.portId, range, filters),
|
|
|
|
|
getUtilisationHeatmap(ctx.portId, 24, filters),
|
feat(reports-overhaul): sales + operational + custom reports, templates, schedules, exports
End-to-end reports build covering Phases 1, 2, 5, 6, 7 of Initiative 1
in docs/launch-readiness.md. Phases 3 (Marketing) + 4 (Financial)
remain deferred per the gap audit at the bottom of that doc.
Highlights:
- Sales performance report: 7 KPI tiles, pipeline funnel + stage
velocity + win-rate-over-time + source conversion + rep leaderboard
charts, deal-heat section, 5 detail tables, stage / lead-cat /
outcome filters.
- Operational report: 7 KPIs, 7 charts (heatmap, status mix, tenancy
churn, tenure histogram, signing box plot, occupancy by area, docs
in pipeline), 4 tables. Module-OFF banner when tenancies disabled.
- Custom (ad-hoc) builder v1: 4 entities (clients, interests, berths,
tenancies), column-whitelist composer, date filter, CSV download,
save-as-template. Registry-only extension path for the remaining 6
entities documented at src/lib/reports/custom/registry.ts.
- Templates: load / modify / save / save-as on Sales / Operational /
Custom. ?templateId= URL deep-link hydration via useRef guard.
Active-template badge clears when the user drives view-state via
wrapped setters; raw setters used on template apply so the badge
survives.
- Scheduled runs: BullMQ poll fires due schedules, mints report_runs,
renders, optionally emails. Recipients optional (zero-recipient
schedules archive without sending). PDF-only output for v1.
Schedule dialog re-mounts via key prop on schedule.id transitions
to avoid setState-in-effect reset patterns.
- Server-side PDF endpoint + shared payload renderer
(lib/pdf/reports/payload-report.tsx) so client + scheduler share
one rendering path.
- Shared currency formatter (lib/reports/format-currency.ts)
consolidates 5 duplicated formatMoney helpers; fixes hardcoded
'USD' in detail tables; pre-formats money rows so PDF export
(which strips column.format callbacks at the JSON boundary)
renders consistently with CSV / XLSX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 22:41:53 +02:00
|
|
|
getStatusMixOverTime(ctx.portId),
|
|
|
|
|
getTenancyChurn(ctx.portId),
|
|
|
|
|
getTenureDistribution(ctx.portId),
|
|
|
|
|
getSigningBoxPlot(ctx.portId),
|
2026-06-02 10:11:26 +02:00
|
|
|
getOccupancyByArea(ctx.portId, filters),
|
feat(reports-overhaul): sales + operational + custom reports, templates, schedules, exports
End-to-end reports build covering Phases 1, 2, 5, 6, 7 of Initiative 1
in docs/launch-readiness.md. Phases 3 (Marketing) + 4 (Financial)
remain deferred per the gap audit at the bottom of that doc.
Highlights:
- Sales performance report: 7 KPI tiles, pipeline funnel + stage
velocity + win-rate-over-time + source conversion + rep leaderboard
charts, deal-heat section, 5 detail tables, stage / lead-cat /
outcome filters.
- Operational report: 7 KPIs, 7 charts (heatmap, status mix, tenancy
churn, tenure histogram, signing box plot, occupancy by area, docs
in pipeline), 4 tables. Module-OFF banner when tenancies disabled.
- Custom (ad-hoc) builder v1: 4 entities (clients, interests, berths,
tenancies), column-whitelist composer, date filter, CSV download,
save-as-template. Registry-only extension path for the remaining 6
entities documented at src/lib/reports/custom/registry.ts.
- Templates: load / modify / save / save-as on Sales / Operational /
Custom. ?templateId= URL deep-link hydration via useRef guard.
Active-template badge clears when the user drives view-state via
wrapped setters; raw setters used on template apply so the badge
survives.
- Scheduled runs: BullMQ poll fires due schedules, mints report_runs,
renders, optionally emails. Recipients optional (zero-recipient
schedules archive without sending). PDF-only output for v1.
Schedule dialog re-mounts via key prop on schedule.id transitions
to avoid setState-in-effect reset patterns.
- Server-side PDF endpoint + shared payload renderer
(lib/pdf/reports/payload-report.tsx) so client + scheduler share
one rendering path.
- Shared currency formatter (lib/reports/format-currency.ts)
consolidates 5 duplicated formatMoney helpers; fixes hardcoded
'USD' in detail tables; pre-formats money rows so PDF export
(which strips column.format callbacks at the JSON boundary)
renders consistently with CSV / XLSX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 22:41:53 +02:00
|
|
|
getDocumentsInPipeline(ctx.portId),
|
|
|
|
|
getTenanciesEndingSoon(ctx.portId),
|
2026-06-02 10:11:26 +02:00
|
|
|
getVacantBerths(ctx.portId, 60, filters),
|
feat(reports-overhaul): sales + operational + custom reports, templates, schedules, exports
End-to-end reports build covering Phases 1, 2, 5, 6, 7 of Initiative 1
in docs/launch-readiness.md. Phases 3 (Marketing) + 4 (Financial)
remain deferred per the gap audit at the bottom of that doc.
Highlights:
- Sales performance report: 7 KPI tiles, pipeline funnel + stage
velocity + win-rate-over-time + source conversion + rep leaderboard
charts, deal-heat section, 5 detail tables, stage / lead-cat /
outcome filters.
- Operational report: 7 KPIs, 7 charts (heatmap, status mix, tenancy
churn, tenure histogram, signing box plot, occupancy by area, docs
in pipeline), 4 tables. Module-OFF banner when tenancies disabled.
- Custom (ad-hoc) builder v1: 4 entities (clients, interests, berths,
tenancies), column-whitelist composer, date filter, CSV download,
save-as-template. Registry-only extension path for the remaining 6
entities documented at src/lib/reports/custom/registry.ts.
- Templates: load / modify / save / save-as on Sales / Operational /
Custom. ?templateId= URL deep-link hydration via useRef guard.
Active-template badge clears when the user drives view-state via
wrapped setters; raw setters used on template apply so the badge
survives.
- Scheduled runs: BullMQ poll fires due schedules, mints report_runs,
renders, optionally emails. Recipients optional (zero-recipient
schedules archive without sending). PDF-only output for v1.
Schedule dialog re-mounts via key prop on schedule.id transitions
to avoid setState-in-effect reset patterns.
- Server-side PDF endpoint + shared payload renderer
(lib/pdf/reports/payload-report.tsx) so client + scheduler share
one rendering path.
- Shared currency formatter (lib/reports/format-currency.ts)
consolidates 5 duplicated formatMoney helpers; fixes hardcoded
'USD' in detail tables; pre-formats money rows so PDF export
(which strips column.format callbacks at the JSON boundary)
renders consistently with CSV / XLSX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 22:41:53 +02:00
|
|
|
getStuckSigning(ctx.portId),
|
2026-06-02 10:11:26 +02:00
|
|
|
getHighestValueVacant(ctx.portId, 10, filters),
|
|
|
|
|
getOperationalAreaOptions(ctx.portId),
|
|
|
|
|
operationalHasData(ctx.portId),
|
feat(reports-overhaul): sales + operational + custom reports, templates, schedules, exports
End-to-end reports build covering Phases 1, 2, 5, 6, 7 of Initiative 1
in docs/launch-readiness.md. Phases 3 (Marketing) + 4 (Financial)
remain deferred per the gap audit at the bottom of that doc.
Highlights:
- Sales performance report: 7 KPI tiles, pipeline funnel + stage
velocity + win-rate-over-time + source conversion + rep leaderboard
charts, deal-heat section, 5 detail tables, stage / lead-cat /
outcome filters.
- Operational report: 7 KPIs, 7 charts (heatmap, status mix, tenancy
churn, tenure histogram, signing box plot, occupancy by area, docs
in pipeline), 4 tables. Module-OFF banner when tenancies disabled.
- Custom (ad-hoc) builder v1: 4 entities (clients, interests, berths,
tenancies), column-whitelist composer, date filter, CSV download,
save-as-template. Registry-only extension path for the remaining 6
entities documented at src/lib/reports/custom/registry.ts.
- Templates: load / modify / save / save-as on Sales / Operational /
Custom. ?templateId= URL deep-link hydration via useRef guard.
Active-template badge clears when the user drives view-state via
wrapped setters; raw setters used on template apply so the badge
survives.
- Scheduled runs: BullMQ poll fires due schedules, mints report_runs,
renders, optionally emails. Recipients optional (zero-recipient
schedules archive without sending). PDF-only output for v1.
Schedule dialog re-mounts via key prop on schedule.id transitions
to avoid setState-in-effect reset patterns.
- Server-side PDF endpoint + shared payload renderer
(lib/pdf/reports/payload-report.tsx) so client + scheduler share
one rendering path.
- Shared currency formatter (lib/reports/format-currency.ts)
consolidates 5 duplicated formatMoney helpers; fixes hardcoded
'USD' in detail tables; pre-formats money rows so PDF export
(which strips column.format callbacks at the JSON boundary)
renders consistently with CSV / XLSX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 22:41:53 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
return NextResponse.json({
|
|
|
|
|
data: {
|
|
|
|
|
kpis,
|
|
|
|
|
utilisationHeatmap,
|
|
|
|
|
statusMix,
|
|
|
|
|
tenancyChurn,
|
|
|
|
|
tenureDistribution,
|
|
|
|
|
signingBoxPlot,
|
|
|
|
|
occupancyByArea,
|
|
|
|
|
docsInPipeline,
|
|
|
|
|
endingSoon,
|
|
|
|
|
vacantBerths,
|
|
|
|
|
stuckSigning,
|
|
|
|
|
highestValueVacant,
|
2026-06-02 10:11:26 +02:00
|
|
|
areaOptions,
|
|
|
|
|
hasData,
|
feat(reports-overhaul): sales + operational + custom reports, templates, schedules, exports
End-to-end reports build covering Phases 1, 2, 5, 6, 7 of Initiative 1
in docs/launch-readiness.md. Phases 3 (Marketing) + 4 (Financial)
remain deferred per the gap audit at the bottom of that doc.
Highlights:
- Sales performance report: 7 KPI tiles, pipeline funnel + stage
velocity + win-rate-over-time + source conversion + rep leaderboard
charts, deal-heat section, 5 detail tables, stage / lead-cat /
outcome filters.
- Operational report: 7 KPIs, 7 charts (heatmap, status mix, tenancy
churn, tenure histogram, signing box plot, occupancy by area, docs
in pipeline), 4 tables. Module-OFF banner when tenancies disabled.
- Custom (ad-hoc) builder v1: 4 entities (clients, interests, berths,
tenancies), column-whitelist composer, date filter, CSV download,
save-as-template. Registry-only extension path for the remaining 6
entities documented at src/lib/reports/custom/registry.ts.
- Templates: load / modify / save / save-as on Sales / Operational /
Custom. ?templateId= URL deep-link hydration via useRef guard.
Active-template badge clears when the user drives view-state via
wrapped setters; raw setters used on template apply so the badge
survives.
- Scheduled runs: BullMQ poll fires due schedules, mints report_runs,
renders, optionally emails. Recipients optional (zero-recipient
schedules archive without sending). PDF-only output for v1.
Schedule dialog re-mounts via key prop on schedule.id transitions
to avoid setState-in-effect reset patterns.
- Server-side PDF endpoint + shared payload renderer
(lib/pdf/reports/payload-report.tsx) so client + scheduler share
one rendering path.
- Shared currency formatter (lib/reports/format-currency.ts)
consolidates 5 duplicated formatMoney helpers; fixes hardcoded
'USD' in detail tables; pre-formats money rows so PDF export
(which strips column.format callbacks at the JSON boundary)
renders consistently with CSV / XLSX.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 22:41:53 +02:00
|
|
|
range: {
|
|
|
|
|
from: range.from.toISOString(),
|
|
|
|
|
to: range.to.toISOString(),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
return errorResponse(error);
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
);
|