Skip to content

Exports & audit log

CondoPulse’s record is only useful if it can leave the app - for AGM packets, tribunal evidence, vendor disputes, and spreadsheets. Three tools do that: the CSV export, the printable report page, and the audit log that backs the whole record’s integrity.

GET /api/export/incidents.csv (staff only) streams the incident list as CSV. It honours the same query filters as GET /api/incidents - status, severity, assetId, unitId - so you can pull exactly the slice you need:

Terminal window
# All resolved incidents on asset 2 (Elevator A2)
curl -H "Cookie: <staff session>" \
"https://your-condopulse.example/api/export/incidents.csv?assetId=2&status=resolved" \
-o elevator-a2-resolved.csv

Merged duplicates are excluded by default (add includeMerged=true to include them), matching what the incident list shows. Use the CSV when the destination is a spreadsheet; use /report when the destination is a human.

/report is a print-optimized incident-history report (A4/Letter @media print styles). “Download PDF” simply opens the browser’s print dialog - print to PDF and you have a clean document. It was built with AGMs and Tribunals Ontario evidence packets in mind: a dated, self-contained account of what happened and how long it took.

The default mode. Pick a date range and optionally filter by asset; the report renders:

  • the property header (name, address, generation date),
  • uptime summaries for the covered assets,
  • and per-incident timelines - every status change and update, in order, for each incident in range.

Add ?month=YYYY-MM (e.g. /report?month=2026-05) for the monthly board pack, titled “Board report - May 2026”. Without a month value it defaults to the last full month. It compiles:

  • Uptime per asset for the month, with downtime hours
  • SLA breaches - count and the list of breaching incidents
  • Throughput - new / resolved / verified counts
  • Costs - month total and per-asset repair costs (staff-only data, from the incident cost records)
  • Open-incident aging - what’s still open and how long it’s been
  • Upcoming maintenance

Print it, attach it to the minutes, done. One page of this per month is a better building record than most corporations have ever kept.

For multi-year asset arguments (“this elevator costs more than it’s worth”), /adminInsights ranks assets by health score - uptime, incident trend, downtime hours, and 365-day repair costs side by side. Asset detail pages carry the same rollup (“Down 89.2h this year · $14,200 in repairs”). The board report covers a month; Insights covers the asset’s life.

Every mutation in CondoPulse - every incident status change, merge, verification, asset edit, webhook change, role change, maintenance window, sweep escalation, inbound email - writes an entry to the audit log:

FieldMeaning
ActorWho did it. Empty actor = system (the sweep, seeding, inbound email processing)
Actione.g. incident.status_changed
EntityWhat it happened to (incident, asset, webhook, user…)
DetailJSON before/after or a summary
TimestampWhen

View it at /admin → Audit - filterable, paginated 50 entries per page.

The audit log is append-only. There is no edit and no delete - not for admins, not for anyone, by design. The UI offers no mechanism to alter history, which is precisely what makes the log citable: when a resident disputes how long the elevator was down, or a tribunal asks when management acknowledged a report, the answer comes from a record that no role in the system can rewrite.

Practical corollaries:

  • Mistakes stay visible - fix an error with a new action (e.g. correct a status), which writes its own entry. The wrong step and its correction both remain on the record. That’s a feature.
  • Anonymous reports are audited too - actions on them appear in the log, which staff can see; anonymity governs display to non-staff, not record-keeping.
  • Back up the database - append-only in the app doesn’t survive losing the data. The Postgres database is the building’s record; treat it like the minute book (Neon keeps point-in-time restore; photos live in .data/uploads/ or your R2 bucket and need their own backup).
NeedUse
Spreadsheet analysis, pivot tablesCSV export
AGM packet / monthly board pack/report?month=YYYY-MM
Evidence for a specific dispute/date range/report date-range mode, filtered to the asset
”Who changed this and when?”/admin → Audit
”Should we replace this asset?”/admin → Insights