reporting-service
Bounded Context: Reporting (Supporting) · Owner: PMS-BackOffice · Phase: 1 · Storage: Cloud SQL Postgres (templates, runs, schedules) + GCS (artifacts) + BigQuery (read replica from analytics-service) · Bundle: services/reporting-service/
reporting-service is the document-rendering and delivery surface of Ghasi Melmastoon. It turns curated facts about a tenant's hotel operations into operational, financial, and regulatory documents — PDF, Excel, CSV — and delivers them to staff, owners, and (where the law requires) to government registers. It does not compute the underlying numbers. Every metric, total, count, and ledger figure originates from billing-service, reservation-service, inventory-service, housekeeping-service, staff-service, and is read either via versioned read-replicas in BigQuery or via curated projections owned by analytics-service.
Reports are facts at a point in time, frozen into a portable artifact, signed by the platform, and traceable end-to-end. Once a report is rendered and delivered, it is immutable. Re-running with the same inputs and the same template version produces a byte-identical artifact (modulo embedded timestamps), so an auditor can re-derive any historical report from the same template snapshot and source data.
Purpose
- Be the single rendering surface so every PDF / Excel / CSV the platform produces follows one layout system, one branding pipeline, one signing scheme, and one delivery audit log.
- Decouple what to compute (analytics-service projections, billing ledger, reservation aggregate) from how to render and deliver it (reporting templates, schedules, subscriptions).
- Provide a regulatory submission harness for jurisdictions that mandate daily/periodic transmission of guest-registration, tax, or occupancy data to a government register or tourism authority (Afghanistan, Tajikistan, Iran, GCC variants).
- Surface manager-grade composite reports that pull from multiple services in one document — the kind of "monthly P&L plus occupancy plus housekeeping productivity" an owner expects on the 1st of every month.
- Replicate subscribed reports and a window of recent runs to the Electron desktop so a GM on a flaky link still sees yesterday's arrivals report and last week's revenue summary.
Key responsibilities
- Template registry — versioned
ReportTemplateaggregates with column definitions, filter shapes, layout (header/footer/section blocks), branding hooks, locale variants (Pashto/Dari/Persian/Arabic/EN/FR), and RTL/LTR toggles. Templates are append-versioned; a template never mutates after publish. - On-demand generation (
POST /api/v1/reports/runs) — caller pickstemplateId@version, supplies filters (date range, property, room type, channel, …), the service creates aReportRun, dispatches it to the rendering worker, returns 202 with the run id; staff or BFF polls or subscribes to completion. - Scheduled generation —
ReportScheduleaggregates declare cron expressions and target subscriptions; Cloud Scheduler firesmelmastoon.reporting.schedule.fired.v1which the service handles by snapshotting the template, materializing inputs from BigQuery / read-replicas, and queueing aReportRun. - Rendering pipeline — Puppeteer (PDF) running in a sandboxed Cloud Run worker;
exceljs(XLSX) and a streaming CSV writer (fast-csv) for tabular outputs. All artifacts land in GCS under a tenant-partitioned, KMS-encrypted bucket with V4 signed URLs issued for delivery. - Subscription & delivery —
ReportSubscriptionaggregates declare per-recipient channels (email vianotification-service, in-app viabff-backoffice-servicepush, desktop via sync, WebDAV / SFTP for legacy partner integrations Phase 3+). - Regulatory submissions — special class of templates marked
regulatory=truewith per-jurisdiction submission adapters (HTTP form post, signed XML, CSV-over-SFTP, paper-print fallback). Failed submissions emitmelmastoon.reporting.regulatory.submission_due.v1tonotification-servicewith a P1 escalation path. - Audit log — every read of every artifact, every download, every email delivery is recorded so a tax auditor can demonstrate chain-of-custody for any rendered figure.
Aggregates owned
| Aggregate | Purpose | Identity prefix |
|---|---|---|
ReportTemplate | Versioned spec: columns, filters, layout, locale variants, branding, retention class | tpl_rep_ |
Report | Logical report instance (the thing the user asks for; carries name, default template, latest runs index) | rep_ |
ReportRun | A single execution of a template at a point in time, with its inputs, outputs (artifacts), status, signing chain | run_ |
ReportSchedule | Cron rule + target template + filters + subscription set | sch_ |
ReportSubscription | Recipient + channel + format + delivery audit | sub_ |
ReportFilter | Reusable saved filter (shareable across runs in a tenant) | flt_ |
ExportArtifact | Concrete file in GCS (PDF/XLSX/CSV) with checksum, signed URL state, retention class | art_ |
RegulatorySubmission | A ReportRun directed at a government register, plus submission adapter outcome and retry/audit chain | reg_ |
Key APIs (REST, /api/v1/reports)
| Method | Path | Purpose |
|---|---|---|
POST | /templates | Publish a new template version (template author / platform admin) |
GET | /templates | List templates (filter by category, regulatory, jurisdiction) |
GET | /templates/:id/versions | Version history of a template |
POST | /runs | Create a ReportRun from a template + filters |
GET | /runs/:id | Status + artifact links of a run |
GET | /runs/:id/artifacts/:artId/download | Issue a short-lived V4 signed URL |
POST | /runs/:id/cancel | Cancel a queued or in-progress run |
POST | /schedules | Create a schedule |
PATCH | /schedules/:id | Update schedule (paused, recipients, filter, template version pin) |
DELETE | /schedules/:id | Disable a schedule |
POST | /subscriptions | Create a per-user/per-channel subscription |
DELETE | /subscriptions/:id | Cancel subscription |
POST | /regulatory/submissions/:runId/retry | Manually retry a regulatory submission |
GET | /regulatory/submissions | List regulatory submissions and their statuses |
Consumed by bff-backoffice-service (desktop, web manager dashboards) and selected service callers (e.g., billing-service post-end-of-day) via internal service tokens.
Key events published
| Event | Trigger |
|---|---|
melmastoon.reporting.report.requested.v1 | A user / scheduler requested a run |
melmastoon.reporting.report.started.v1 | Worker picked up the run |
melmastoon.reporting.report.completed.v1 | Artifact written to GCS, signed URL minted |
melmastoon.reporting.report.failed.v1 | Render or data-fetch failed terminally (post-retries) |
melmastoon.reporting.report.delivered.v1 | Recipient delivery confirmed (per channel) |
melmastoon.reporting.template.published.v1 | A new template version was published |
melmastoon.reporting.template.archived.v1 | Template archived (no new runs allowed) |
melmastoon.reporting.schedule.created.v1 | Schedule created |
melmastoon.reporting.schedule.fired.v1 | Cloud Scheduler hit the schedule |
melmastoon.reporting.schedule.disabled.v1 | Schedule disabled (manual or after N consecutive failures) |
melmastoon.reporting.subscription.created.v1 | New subscription |
melmastoon.reporting.subscription.cancelled.v1 | Subscription cancelled |
melmastoon.reporting.regulatory.submission_due.v1 | Regulatory submission window opened (used to alert tenants) |
melmastoon.reporting.regulatory.submission_succeeded.v1 | Government register accepted the submission |
melmastoon.reporting.regulatory.submission_failed.v1 | Government register rejected (with reason code from adapter) |
Key events consumed
| Event | Effect |
|---|---|
melmastoon.tenant.settings.changed.v1 | Refresh per-tenant branding, locale defaults, regulatory jurisdiction settings |
melmastoon.theme_config.theme.updated.v1 | Re-cache tenant branding for renderer |
melmastoon.notification.delivery.recorded.v1 | Mark a ReportSubscription delivery as confirmed/failed |
melmastoon.analytics.projection.refreshed.v1 | Optional invalidate-and-rerun for streaming/near-realtime templates |
melmastoon.tenant.deleted.v1 | Cascade purge — soft-delete all template overrides, runs, artifacts within retention requirements |
Cloud Scheduler push (/internal/jobs/schedule-fire) | Translated into schedule.fired.v1 then run dispatch |
Upstream / downstream
Upstream (we read from): analytics-service (BigQuery curated tables — primary fact source), billing-service (folio + ledger read replica), reservation-service (read replica for arrivals/departures composites), inventory-service, housekeeping-service, staff-service, tenant-service (branding + jurisdiction), theme-config-service (logo, color tokens), iam-service (recipient authorization).
Downstream (we publish for): notification-service (email delivery), bff-backoffice-service (in-app + desktop sync), audit-service (every artifact and delivery is auditable), analytics-service (run telemetry), regulatory partner endpoints (per-jurisdiction adapters — outside the platform).
Non-functional requirements
| NFR | Target |
|---|---|
| On-demand p95 render latency, ≤ 50k-row tabular | < 12 s end-to-end (queue → artifact ready) |
| On-demand p95 render latency, regulatory PDF | < 25 s |
| Scheduled report on-time rate | > 99.5% monthly (fired within ±60 s of cron) |
| Regulatory submission success rate | > 99.9% monthly (post-retries) |
| Artifact retention (operational) | 2 years in GCS Standard, then 7 years in Coldline |
| Artifact retention (regulatory) | 10 years in GCS Coldline, with object-lock retention policy |
| API availability | 99.9% monthly |
| Sync footprint | Subscribed reports + most recent 30 runs per template per device |
| Replicas | Min 2 Cloud Run instances (API); separate worker pool (autoscaling 0→20) for rendering |
Where to go next
- Implementation-grade detail:
services/reporting-service/SERVICE_OVERVIEW.mdand the rest of the 17-doc bundle. - Source-of-truth fact tables consumed:
services/analytics-service/DATA_MODEL.md(fact_*anddim_*tables). - Branding & locale variants:
docs/03-microservices/theme-config-service.md. - Notification delivery contracts:
docs/03-microservices/notification-service.md. - Desktop subscription UX:
docs/frontend/desktop/06-desktop-app-specification.md. - Audit / Merkle anchoring:
docs/07-security-compliance-tenancy.md§9.