roboto.domain.views#

Wire types for Views: named, shareable searches over a single resource type.

A View saves the filters, sort, page size, and column layout a user arrived at, so they can return to it later or hand it to a teammate rather than rebuilding it.

Submodules#

Package Contents#

class roboto.domain.views.CreateViewRequest(/, **data)#

Bases: pydantic.BaseModel

Request payload to create a View.

Parameters:

data (Any)

definition: roboto.domain.views.record.ViewDefinition#

The query and presentation state to save.

name: str = None#

Display name. Need not be unique.

target: roboto.query.QueryTarget#

The resource type this View searches. Cannot be changed afterwards.

roboto.domain.views.MAX_VIEW_NAME_LENGTH: Final[int] = 120#

Longest permitted View name, matching the limit layouts uses.

class roboto.domain.views.UpdateViewRequest(/, **data)#

Bases: pydantic.BaseModel

Request payload to update a View.

Omitted fields are left unchanged. target is absent by design: a View’s conditions are written against one resource type, so retargeting it would leave them referring to fields the new target does not have. Create a new View instead.

Parameters:

data (Any)

definition: roboto.domain.views.record.ViewDefinition | roboto.sentinels.NotSetType#

Replacement query and presentation state, or NotSet to leave it alone.

Replaces the definition wholesale rather than merging, so a caller changing one filter must send the whole definition back.

model_config#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

name: str | roboto.sentinels.NotSetType = None#

New display name, or NotSet to leave it alone.

roboto.domain.views.VIEW_SCHEMA_VERSION_V1: Final[int] = 1#

Value stored in the schema_version column for a VIEW_SCHEME_V1 definition.

roboto.domain.views.VIEW_SCHEME_V1: Final = 'view_v1'#

Identifier for the first version of the View definition schema.

class roboto.domain.views.ViewDefinition(/, **data)#

Bases: pydantic.BaseModel

The saved contents of a View: what its author searched for, and how they were shown it.

Persisted as JSON in the views.definition column. That column has no database constraint, so this model is the only thing enforcing the shape.

A View records intent, not a query. It holds what the author expressed — filter controls or RoboQL text — and the client rebuilds an executable query from that on load. It does not hold a ready-made QuerySpecification, because one cannot be stored faithfully: Comparator has no way to say “the last 7 days”, so translating a relative date filter resolves it to fixed instants. A stored query would show the week the View was saved forever after, presented as though it were live.

Intent is nonetheless recorded in a typed form — SavedFilters — so that anything able to call the API can create a View, not only a client that already knows the filter UI’s internal shape. Executing one still needs a translation step, and today the web UI is what performs it; a RoboQL View needs none, since its text runs anywhere.

Making structured Views executable server-side means first teaching Comparator what FilterOnlyComparator currently covers (ENG-2957). A later view_v2 could then carry a query directly, and filters would fold into it.

target is deliberately absent. It is a column on the views table, and duplicating it here would create two sources of truth that can disagree.

Parameters:

data (Any)

display: ViewDisplay = None#

columns, sort, and page size.

Type:

Presentation state to restore when the View is loaded

filters: roboto.query.SavedFilters | None = None#

The filter controls the author built.

Serves the same purpose as roboql for Views built from filter controls rather than typed queries: it records what the author expressed, so a client can rebuild the query on load rather than replaying a translation that has since gone stale.

This and roboql are alternatives, not a pair: at most one is ever set. Both are None for a View that filters nothing, which is a legitimate thing to save — it captures a column layout and a sort over the unfiltered list. So None here does not imply the View is a RoboQL one.

Typed rather than an opaque blob, so that a View is something any caller can construct. An untyped shape would leave an SDK user, the CLI, or an agent with nothing to build against and no way to learn they got it wrong — the row would store, and only fail later when a client tried to render it. That would make Views a web-UI feature rather than a platform one.

The cost is a definition that must agree with the filter UI’s own. That agreement was always required; it was simply unchecked before, and is now enforced where the data enters.

roboql: str | None = None#

The RoboQL text the author wrote, when the View came from RoboQL rather than filter controls.

RoboQL has no relative-date syntax, so this text does not go stale — it means the same thing whenever it is run, and a backend can execute it directly.

None for a View built from structured filters, and also for one that filters nothing at all — see filters.

scheme: Literal['view_v1'] = 'view_v1'#

Version tag for this definition’s shape.

A future view_v2 becomes a separate model, letting readers dispatch on this field and upgrade old rows instead of misreading them as the current version.

class roboto.domain.views.ViewDisplay(/, **data)#

Bases: pydantic.BaseModel

How a View presents its results: which columns, in what order, sorted how, how many rows.

Presentation state only. Nothing here changes which records match.

Parameters:

data (Any)

page_size: int | None = None#

Rows per page, or None to accept whatever the client’s table would pick on its own.

sort_by: str | None = None#

Field to sort results by, or None to leave the target’s default sort in place.

sort_direction: roboto.query.SortDirection | None = None#

Direction to sort in. Only meaningful alongside sort_by.

visible_columns: list[str] = None#

Columns to show, in display order.

Visibility and ordering are carried by this one list rather than a visibility map plus a separate order: two fields could disagree about a column, and there is no sensible way to resolve that. A column absent from the list is hidden. An empty list means the client falls back to its own defaults, which is what a View saved before a new column shipped will do.

class roboto.domain.views.ViewRecord(/, **data)#

Bases: pydantic.BaseModel

A wire-transmissible representation of a View.

A View is a named, org-scoped, shareable search over one resource type. Who may see or edit it is held in the authorization service rather than on this record, so there is no accessibility field here.

Parameters:

data (Any)

created: datetime.datetime#

When the View was first saved.

created_by: str#

User who created the View. The author, who alone may delete it or change who can see it.

definition: ViewDefinition#

The saved query and presentation state.

modified: datetime.datetime#

When the View’s name or definition last changed. Shown in the picker alongside modified_by, so a shared View can be judged on how current it is.

modified_by: str#

User who last changed the View. Surfaced in the picker so a shared View can be judged.

name: str#

Display name. Not unique — Views are addressed by view_id, never by name.

org_id: str#

Organization that owns the View.

schema_version: int#

Version of definition’s shape, mirroring its scheme so rows can be selected by version in SQL without parsing the JSON.

target: roboto.query.QueryTarget#

The resource type this View searches, e.g. datasets or files.

Fixed at creation: a View’s conditions are written against one target’s fields.

view_id: str#

Unique identifier for the View, and the token that addresses it in a shareable URL.