ReportsHQ
Reports that run inside your own application, against your own database. A customer installs a package, declares which of their models and columns are queryable, and gets reports rendered from their own rows. Nothing is sent anywhere and nothing is hosted here.
This issue described a different product until 2026-09-04. ReportsHQ was a hosted event collector: apps POSTed events to
/ingestand reports were built from them.b3dbf0b("feat!: retire the hosted pipeline", 2026-08-16) deleted that pipeline —routes/ingest.ts,app/Events/,app/Reports/and thirteen models. The text below has been rewritten to match the tree. Older issues have not been rewritten, so read any of them against this description rather than the other way round; several name surfaces that no longer exist.
The product is two published packages, and neither of them is this app:
@reportshq/stacks(packages/stacks/) — the Stacks/TypeScript library. A semantic registry that allowlists measures and dimensions, a compiler that turns a block into one SQL query, a runner, grid layout, custom-element rendering, CSV export, HTTP route descriptions the host application mounts itself, and an offline licence. A test asserts the source contains nofetch(,XMLHttpRequest,WebSocketorBun.connect.reportshq/laravel(packages/laravel/, on Packagist) — the same product for Laravel, plus XLSX export. Its service provider keeps two independent halves apart: a reports half that is always registered and reads the application's own connection, and an optional event half that maps Laravel events onto the shared taxonomy and forwards them to a collector.
The event half is live, tested, and its future is undecided. The hosted collector at reportshq.org/ingest is not answering, and as of 78d5523 an endpoint must be configured explicitly or nothing registers. Whether that collector is retired for good or merely absent is the one open product decision here. Until it is made: do not delete the forwarder, the shared taxonomy in docs/fixtures/sdk-events.json, or their tests, and do not write documentation that assumes either answer.
reportshq.org is now a marketing site, an auth flow, an account page, and a read-only report viewer that dogfoods @reportshq/stacks against its own users table. Licensing is offline and gates nothing: an absent or malformed key changes only the notice printed under a report.
Sibling product to loghq — same architecture discipline, same design family, different accent and domain.
Ground rules (apply to every issue in this repo)
- Work from
/Users/chris/Code/Apps/reportshq. Commit as Chris (chrisbreuer93@gmail.com), conventional commit messages (feat:,fix:,chore:, ...), no co-author trailers, small focused commit chunks, push directly tomainonorigin. - No hand-written migrations, ever. All schema comes from
app/Models/*viabuddy generate:migrations+buddy migrate. If the generator cannot express something, fix the ORM/generator in~/Code/stacks(stacksjs/stacks) instead - see #5. - No workarounds, ever. When a framework or library gap blocks you, fix it at the root in the owning repo and release it.
- No third-party dependencies. Only our own packages from
~/Code/Libraries/*and~/Code/Tools/*(published under their npm names:stacks,ts-charts,ts-spreadsheets,ts-cache,bun-query-builder, ...). When one is missing a capability, improve it upstream, then runbun run release:patchin that repo to release, and consume the released version. - UI work follows
stacks-design-taste(plus the aesthetic preset skills andstacks-design-output). Run the Section 14 pre-flight before calling any UI done. Never emit an em-dash or separator en-dash in user-visible copy. - Before finishing any issue:
./buddy lint,./buddy typecheck,./buddy test- all green.
Architecture at a glance
| Concern | Where it lives |
|---|---|
| Semantic layer (what is queryable) | packages/stacks/src/semantic.ts, packages/laravel/src/Semantic/ |
| Query compilation | packages/stacks/src/compiler.ts, packages/laravel/src/Query/ |
| Report execution | packages/stacks/src/runner.ts, packages/laravel/src/Reports/ |
| Charts | resources/components/charts/ — stx components over ts-charts, published as @reportshq/elements with the stacks- element prefix |
| Grid layout | packages/stacks/src/layout.ts |
| Export | CSV in packages/stacks/src/export.ts; CSV and XLSX in packages/laravel/src/Reports/Export.php |
| HTTP surface | packages/stacks/src/http/ describes routes; routes/reports.ts mounts them here |
| Licence | packages/stacks/src/license.ts, packages/laravel/src/License.php — rhq_lic_ + 32 hex, checked offline |
| Event forwarder (optional) | packages/laravel/src/{Mapper,Sampler,Transport,Sender,SendEvents}.php |
| Shared event taxonomy | docs/fixtures/sdk-events.json, replayed by packages/laravel/tests/run.php |
| Plan copy | app/Billing/limits.ts — priced per installed application, a pricing-page data source rather than an enforcer |
Reports read the host application's own database connection. There is no ingest, no per-project key and no tenancy in this app; X-ReportsHQ-Key now belongs only to the optional event forwarder.
Roadmap
M1 through M5 shipped, then the pivot changed what several of them meant. Ticked below means the issue is closed, not that the feature survived: #6 built the ingest API that b3dbf0b later deleted, and #12 built a builder whose stx view went with it while its JSON API lives on in both packages.
Shipped
- #2 Scaffold the app and repo foundation
- #3 Brand identity and design language
- #5 Framework: append-only model-driven migrations
- #6 Event ingestion API — later retired by
b3dbf0b - #7 Stacks integration package — now
@reportshq/stacks, rewritten as an in-process library - #9 Report domain models
- #10 Query and aggregation engine
- #11 Chart component library on ts-charts
- #12 Drag-and-drop builder — stx view deleted; the JSON API survives in both packages
- #13 App shell: management, viewer, onboarding
- #14 Auto-created reports: template engine
- #15 Scheduled report delivery and exports
- #18 Plan limits, usage metering, retention
- #32 Postgres dialect differences
Open, and still shaped by the old product
Each of these needs rereading before it is picked up. The work is real; the acceptance criteria name deleted surfaces.
- #4 Accounts and membership — auth half is shipped; the
Projectmodel and ingest key it is built around are gone - #8 Laravel integration package — shipped and on Packagist; its criterion "both arrive through
/ingest" is unmeetable - #16 Public sharing and embeds — implemented, but inside the customer's application, not on
reportshq.org - #17 Billing — three tiers survive; the plan matrix meters events, retention and projects, none of which exist
- #19 Marketing site — largely built; the prescribed "send events → reports build themselves" narrative is the dead product
- #20 Documentation site — half its checklist points at
docs/ingest.mdanddocs/events.md, both deleted - #22 QA hardening — the frame survives; its authz matrix is keyed to ingest keys and share tokens
Open and unaffected by the pivot
- #21 CI/CD and production deploy — nothing in it is product-shaped
- #25 Dependency Dashboard — Renovate bot artifact
Obsolete
- #31 Per-project API tokens — its premise is deleted files; close unless the collector returns
Known debris
- Eight tables have no model behind them:
projects,project_invites,project_members,events,event_rollups,reports,report_blocks,report_shares. Inert since120532eremoved their last consumer. Dropping them is a data-retention decision, not a cleanup. - The 0.74 framework line cannot be installed from scratch (stacksjs/stacks#2425); 73 packages are pinned through
overridesuntil it is fixed.LibraryBuildOptionsdoes not declare the fields its own resolver reads (#2426); augmented inapp/library.d.ts.