Skip to content

feat: register queries and typed variables for hosted data apps - #33

Closed
robinvrd wants to merge 16 commits into
mainfrom
robin/data-app-query-variables
Closed

robinvrd wants to merge 16 commits into
mainfrom
robin/data-app-query-variables

Conversation

@robinvrd

@robinvrd robinvrd commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Hosted data apps execute registered queries by ID and variable values through the existing bridge. SQL templates stay on the host.

  • Add TypeScript types for query registration and variable definitions with name, type, nullable, default, and optional options, matching the frontend's supported types.
  • Add variable selectors with compact, shared single-date and date-range calendar pickers. Range controls retain presets, bounds, reset, and comparison; single dates use the same calendar navigation without range presets.
  • Add the data:query payload { operation, variables, limit } using the existing bridge.
  • Update the hosted starter and docs to produce three artifacts: app source, queries.json, and variables.json.

Variable and SQL parsing, registration validation, defaults, and query execution belong to the backend. This package supplies TypeScript types, selectors, and transport; the hosted preview uses mock backend results.

Local CLI apps keep their existing HTTP operations and server-owned SQL flow.

Hosted flow

  1. On creation and every source update, submit source, the complete query map, and the complete variable list together.
  2. App code calls query(queryId, values); the bridge forwards the ID and values to the frontend.
  3. The frontend calls runDataAppQuery with the trusted app slug, query ID, and values. The backend resolves the saved SQL, validates and binds values, authorizes access, and executes.
  4. Results return through the bridge for parsing and display. Hosted apps have no raw SQL fallback.

The frontend and create/update integration are coordinated with frontend #2766 and skills #87.

Validation

  • bun run check with Bun 1.4.2 passed, including 188 tests and local starter verification.
  • Full browser suite: 129 passed, 11 skipped across desktop and phone, including shared calendar navigation, presets, bounds, reset, and comparison.
  • Markdown, links, and formatting checks passed after the documentation cleanup.

@albert20260301 albert20260301 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The required browser suite is failing in browser-tests/bridge-source.spec.ts on both desktop and phone. After clicking Data query, the iframe still shows the prior virtual-state result ({"period":"last-7","version":1}), not the query result the test expects.

Please update the bridge fixture and coverage so this path either exercises the new registered data:query contract (including the operation ID and values) or explicitly preserves and verifies the legacy data:sql path. The current failure leaves the feature's route-selection and backward-compatibility behavior unverified.

@robinvrd robinvrd changed the title feat: add registered queries and typed variable controls feat!: unify registered queries for hosted and local iframe apps Oct 5, 2026
@robinvrd robinvrd changed the title feat!: unify registered queries for hosted and local iframe apps feat: register queries and typed variables for hosted data apps Oct 6, 2026
@robinvrd
robinvrd marked this pull request as ready for review October 6, 2026 14:38
Comment thread browser-tests/fixtures/bundle-host.tsx Outdated
return null;
}
const router = createMessageRouter(
const legacyRouter = createMessageRouter(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove all things legacy

Comment thread src/core/query-registration.ts Outdated
Comment thread src/react/ui/Combobox.tsx Outdated
missingOption?: ComboboxOption;
disabled?: boolean;
placeholder?: string;
searchable?: boolean;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't semantically correct. A combobox is always searchable. We should use another component when we don't need search.

Comment thread src/core/variables.ts Outdated
Comment on lines +396 to +398
valid() {
return true; // Query values are validated by the backend.
},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this then?

Comment on lines +26 to +27
from: range.start ? new Date(`${range.start}T00:00:00.000Z`) : null,
to: range.end ? new Date(`${range.end}T23:59:59.999Z`) : null,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps could extract date utils for agents to reuse across the app: startOfDay(), endOfDay().


/** Display URL or controlled values without making malformed values crash the UI. */
export function formatVariableDate(
value: AbsoluteOrRelativeDateTime | null | undefined

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need to carry these GraphQL dependent typings here? Ideally we narrow down possible types.

Comment thread src/react/ui/VariableValueSelector.tsx Outdated
onChange,
nullable = false,
options,
}: ValueProps<string | number> & { type: 'STRING' | 'INTEGER' | 'FLOAT' }) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have a single type dictionary and pick from there so that types flow down.

Comment thread src/react/ui/VariableValueSelector.tsx Outdated
Comment on lines +84 to +86
type === 'STRING'
? 'Enter a value'
: `Enter a valid ${type === 'INTEGER' ? 'integer' : 'number'}`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use a map instead of fragile conditionals that might break with additional data types. We can type check them.

Comment thread src/react/ui/VariableValueSelector.tsx Outdated
Comment on lines +99 to +101
function option(value: boolean | null) {
return choice(value, value === null ? 'Null' : value ? 'True' : 'False');
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to extract too

Comment thread src/react/ui/VariableValueSelector.tsx Outdated
option(value)
)}
onChange={next =>
onChange(JSON.parse(next) as VariableValue<'INTERVAL'> | null)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could provide a safe parsing function that casts?

@albert20260301

Copy link
Copy Markdown

@robinvrd the current head now conflicts with main, and only the semantic-title check has rerun after the latest styling change.

Please rebase and resolve the conflict before the next review. The required source/package and browser checks need to rerun on that resolved head, and François's active design-review threads still need to be addressed or resolved.

@leonkenneth

Copy link
Copy Markdown
Contributor

So following https://github.com/altertable-ai/backend/pull/4571 I think we can remove the variables part.

Then we will need to update the frontend and finally the skills I believe

@leonkenneth

Copy link
Copy Markdown
Contributor

We can also update the bun proxy logic

@leonkenneth leonkenneth closed this Oct 7, 2026
@leonkenneth

Copy link
Copy Markdown
Contributor

We can also update the bun proxy logic

@leonkenneth leonkenneth reopened this Oct 7, 2026
@albert20260301

Copy link
Copy Markdown

@leonkenneth @francoischalifour #33 is still conflicting and has active review feedback. Can you confirm whether the intended scope is now to remove hosted variables rather than finish this registration layer? Once confirmed, Robin should either re-scope/rebase this PR or replace it; I will not advance the existing implementation against an unsettled contract.

leonkenneth and others added 4 commits October 8, 2026 11:43
Registered queries now use DuckDB prepared-statement parameters ($name),
so apps only register queries and pass a name-to-value hash. Removes the
variable definitions, queryVariable(), and the variable selectors; the
date pickers keep their own browser coverage.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Resolve conflicts against main's styling, view, and Vitest refactors:

- Take main's DateRangePicker, Combobox, and react exports; drop the
  branch's DatePicker, CalendarContent, and open-range picker API, whose
  only consumers were the removed variable selectors.
- Port registered-query coverage into tests/public-api and route the
  hosted starter through registeredQueryRoute in the test host.
- Keep main's starter, re-applying only the registered query call.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…variables

# Conflicts:
#	dev/fixtures/bundle-host.tsx
#	examples/starter-data-app/index.tsx
Comment thread docs/hosted-apps.md
Comment on lines +25 to +26
Follow the [hosted build skill](https://github.com/altertable-ai/skills/blob/main/skills/build-data-app/SKILL.md)
for the create/update tool workflow.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This repo should be unaware of the skills.

Comment thread docs/hosted-apps.md
Comment on lines +19 to +21
- [queries.json](../examples/starter-data-app/queries.json): maps query IDs to SQL
statements with [DuckDB parameters](contract.md#execute-named-queries) such as
`$groupName`. Keep this map out of the browser bundle.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this a local data app concept?

Comment thread docs/hosted-apps.md
Comment on lines +36 to +38
2. Move SQL from local server operations into `queries.json`, replace interpolated
inputs with `$name` parameters, and replace statement calls with
`query(id, values)`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we provide a function for this, so that it's fast, determinist, and doesn't spend tokens.

@leonkenneth leonkenneth closed this Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants