Dataface Tasks

Spec

Goals (v1)

  1. Authors can link between boards without hand-building environment-specific absolute URLs—works for dft serve and Cloud after resolution.
  2. Query parameters on those links align with existing dashboard variables (see Cloud dashboard_render query parsing).
  3. Authoring uses standard Markdown link URLs only—no custom markdown dialect. Optional .md / .yaml / .yml suffixes on paths may be stripped as author sugar (tool behavior, not CommonMark).

Non-goals (v1)

  • canonical_for / entity-registry YAMLdeferred to M5 and only if needed; see ADR-002 and task. Prefer path conventions (e.g. …/list, …/detail) instead.
  • Per-dashboard slug / url_path frontmatter overrides — not v1; file location is source of truth (move the file to change URL).
  • Full Lightdash-style opaque filter blobs in the URL (may revisit; see research synthesis).
  • Chart click wiring end-to-end—coordinate with ai_notes/features/CLICK_INTERACTIONS.md; v1 makes href targets unambiguous so clicks can reuse the same resolver later.
  • Wikilinks [[board]] in v1 unless trivial on top of the same resolver.

Dependencies


Author-facing URL model (v1)

Dashboard URL root (author view): paths are root-relative from the logical dashboard namespace—authors do not type a storage prefix like faces/.

Examples:

[Open tickets](/zendesk/tickets/list?status=open)
[Ticket detail](/zendesk/tickets/detail?id={{ ticket_id }})

Implementation mapping: the resolver maps author path → canonical project slug used by Cloud and dft serve today (typically under faces/ on disk, e.g. faces/zendesk/tickets/list). Exact normalization rules must match dashboard discovery / existing slug behavior—see open questions.

Relative paths: ../ and ./ resolve against the current board’s slug directory (after the same author-root ↔ storage-slug mapping), then rewrite for Cloud vs serve—see ADR-001.

Convention for “views” (no metadata): teams can standardize recognizable paths such as:

  • …/list — filtered / overview table
  • …/detail — single-entity board (variables in query, e.g. ?id=)

This is documentation + habit, not enforced schema in v1.


Why render-time rewriting?

Concern Compile time Render time
Knows Cloud org/project No Yes (dashboard_render)
Same YAML in CLI and Cloud Yes Yes

Browsers resolve relative href against the HTML page URL (Suite: /{org}/{project}/d/{slug}/), not the repo slug tree—so we rewrite board links when rendering. Same pattern as static site generators that “fix” .md links: tool behavior, not CommonMark.


Resolution targets (after rewrite)

Runtime Shape (conceptual)
dft serve /{storage_slug_path}?{query} per dataface/core/serve/server.py
Cloud /{org}/{project}/d/{dashboard_slug}/?{query} + merge branch (allowlist TBD) from current request when absent on link

Pass link_context through render(..., **options) into the content pipeline (dataface/core/render/faces.py, etc.); centralize in e.g. dataface/core/render/board_links.py with tests.


Phase plan (v1)

Phase Scope
1a Root-relative /… + board-relative ../ / ./ in face.content; suffix strip; serve + Cloud
1b Context merge (branch, allowlist)
2 Optional escape hatch only if ambiguity appears (e.g. explicit scheme)—not default

M5 (separate task): optional canonical_for / entity index only if product proves need beyond conventions—task.


Testing & docs

  • TDD: Resolver tests (mapping author root → storage slug, ../, suffix strip, query merge, Cloud vs serve).
  • Docs (required for v1 ship): New or updated docs/docs/ page stating author rules (this section), branch behavior, and examples; link from variables docs. Update drill-down example when action: link shares resolver.
  • Quickstart: _templates/link-matrix.template.md with /connector/... style examples.

Open questions

  1. Allowlist for merged query params (branch only vs more).
  2. Board links in nested includes / chart footnotes—same pipeline if shared.
  3. Author path → storage slug when both faces/ and dashboards/ trees exist (precedence, explicit disambiguation).