Summary
Dashboard widget filters do not interpolate {current_user} / {current_user_id}. The literal string reaches the query, matches no owner, and the widget renders 0 — silently, with no error in the console or the server log.
The same token works correctly in ListView filters, so a user-scoped list view and a user-scoped dashboard widget over the same data disagree.
Reproduction
One dashboard, three metric widgets over the same dataset and the same seeded data (all records owned by the signed-in user):
| widget filter | rendered |
|---|
filter: { owner: '{current_user}', … } | 0 |
filter: { owner: '{current_user_id}', … } | 0 |
filter: { … } (no owner clause) | 10,100,081 ✓ |
Same session, same user, same opportunity_metrics / task_metrics datasets. The only variable is the owner clause.
Control: the identical token in a ListView resolves correctly —
// crm_lead listView `my_leads` — returns 21 rows for the signed-in user
filter: [{field: 'owner',operator: 'equals',value: '{current_user_id}'}]Where it comes from
{current_user_id} interpolation is implemented in @objectstack/platform-objects (the ListView / data path). Grepping @objectstack/service-analytics for current_user returns nothing — the dataset query path has no equivalent substitution step, so the placeholder is passed through to SQL as a literal.
Impact
Any "my …" dashboard is impossible to build. Every widget silently reports zero, which reads as "you have no work" rather than "this filter did not resolve" — the worst possible failure mode for a landing page.
This is not hypothetical: service_dashboard.my_open_cases_by_priority in the HotCRM template has been broken this way since it was written. It was never noticed because until recently no seeded record had an owner, so the widget was expected to be empty.
Environment
@objectstack/* 16.1.0- Repro app: HotCRM at
fc8716d - dev server, wasm SQLite
Expected
Dashboard widget filters resolve {current_user_id} (and {current_user}, whichever is canonical) the same way ListView filters do. Failing that, an unresolved placeholder should raise rather than silently produce an empty result set.
Summary
Dashboard widget filters do not interpolate
{current_user}/{current_user_id}. The literal string reaches the query, matches no owner, and the widget renders0— silently, with no error in the console or the server log.The same token works correctly in ListView filters, so a user-scoped list view and a user-scoped dashboard widget over the same data disagree.
Reproduction
One dashboard, three metric widgets over the same dataset and the same seeded data (all records owned by the signed-in user):
filter: { owner: '{current_user}', … }filter: { owner: '{current_user_id}', … }filter: { … }(no owner clause)Same session, same user, same
opportunity_metrics/task_metricsdatasets. The only variable is the owner clause.Control: the identical token in a ListView resolves correctly —
Where it comes from
{current_user_id}interpolation is implemented in@objectstack/platform-objects(the ListView / data path). Grepping@objectstack/service-analyticsforcurrent_userreturns nothing — the dataset query path has no equivalent substitution step, so the placeholder is passed through to SQL as a literal.Impact
Any "my …" dashboard is impossible to build. Every widget silently reports zero, which reads as "you have no work" rather than "this filter did not resolve" — the worst possible failure mode for a landing page.
This is not hypothetical:
service_dashboard.my_open_cases_by_priorityin the HotCRM template has been broken this way since it was written. It was never noticed because until recently no seeded record had an owner, so the widget was expected to be empty.Environment
@objectstack/*16.1.0fc8716dExpected
Dashboard widget filters resolve
{current_user_id}(and{current_user}, whichever is canonical) the same way ListView filters do. Failing that, an unresolved placeholder should raise rather than silently produce an empty result set.