AGENT SKILL

data-modeling

Use when the app needs to store or read data — records, a database, entities, CRUD, lists, "save/remember X", or per-user data with row-level security. This app's data layer is Rayfin's: you declare entities as TypeScript classes with decorators in packages/data/src/, register them in the schema, and read/write them through the typed rayfin-client. Covers: defining an @entity, field decorators, registering it, per-entity access with @role, owner-only row-level security, and the client query/mutation API. Triggers: data, database, model, entity, schema, table, record, CRUD, create, read, update, delete, list, store, save, persist, per-user, row-level security, RLS, access control, ownership.

适用职业数据分析师
使用场景后端与接口
License 许可
MIT
所属仓库
microsoft/rayfin
最近更新
2026-10-30
Stars
★ 655
Forks
73

01 前言 Front Matter

name
data-modeling
description
Use when the app needs to store or read data — records, a database, entities, CRUD, lists, "save/remember X", or per-user data with row-level security. This app's data layer is Rayfin's: you declare entities as TypeScript classes with decorators in packages/data/src/, register them in the schema, and read/write them through the typed rayfin-client. Covers: defining an @entity, field decorators, registering it, per-entity access with @role, owner-only row-level security, and the client query/mutation API. Triggers: data, database, model, entity, schema, table, record, CRUD, create, read, update, delete, list, store, save, persist, per-user, row-level security, RLS, access control, ownership.

02 资源文件 4

03 SKILL.md 正文

Data modeling — entities, schema, and row-level security

This app persists data with Rayfin data. You define entities as decorated TypeScript classes under packages/data/src/, register them in packages/data/src/index.ts, define their isomorphic contracts in packages/shared/src/index.ts, and read/write them with the typed client from packages/frontend/src/lib/rayfin-client.ts (await getRayfinClient()).

Read the docs first — they ship in the packages

Rayfin's data rules are owned by the installed packages, not by this skill. Decorators, field options, relationships, permissions, the query API and the platform's constraints all move between releases. Read them from disk:

You need… Read
@entity, every field decorator, and their options node_modules/@microsoft/rayfin-core/assets/docs/decorators.md
Permissions end to end — @role, the policy DSL, claims, include / exclude node_modules/@microsoft/rayfin-guide/assets/docs/data/permissions.md
The @anonymous / @authenticated shorthands node_modules/@microsoft/rayfin-core/assets/docs/permissions.md
Entity authoring end to end, relationships, schema registration node_modules/@microsoft/rayfin-guide/assets/docs/data/overview.md
Reading and writing with the client node_modules/@microsoft/rayfin-guide/assets/docs/data/graphql.md
Paging, cursors, text-field nullability node_modules/@microsoft/rayfin-data/assets/docs/index.md
Constraints that will bite you — text length, FK naming, many-to-many, dialect node_modules/@microsoft/rayfin-guide/assets/docs/known-limitations.md

Read known-limitations.md before you design entities. It is short, and it is where the platform tells you what it will not do.

Everything below is about this template — what it turns on, where files go, and how its build is wired. For anything about Rayfin itself, use the table.

Step 1 — turn the data service on

The base template keeps the data service off, because a dashboard over a semantic model does not need a database. Turn it on for an app that needs persistence:

npm run pack:add -- data-modeling

That flips data.enabled in rayfin/rayfin.yml and plants a starter entity in packages/data/src/Item.ts, registered in packages/data/src/index.ts, with its isomorphic contract in packages/shared/src/index.ts. Re-applying is safe: it keeps files you have edited, and --force-seeds is the explicit way back to the pack's version.

The template authenticates before rendering app content through its dynamic auth provider and gate. Keep that boundary intact and follow the installed rayfin-guide/assets/docs/auth/ pages for additional service-specific requirements. Preserve server-side entity permissions and row-level security. Do not replace an authentication failure with anonymous access or block the entire app because it is outside the Fabric portal.

Step 2 — write entity files

One file per entity under packages/data/src/, for example packages/data/src/Note.ts. Start from the seeded Item.ts — rename it and change the fields. Editing a working entity is more reliable than writing one from nothing. When the real model replaces the example, remove the unused starter Item runtime entity, its packages/data/src/index.ts registration, and its packages/shared/src/index.ts contract so it does not become user-visible. @microsoft/rayfin-core, @microsoft/rayfin-data and @microsoft/rayfin-client are already pinned in the base app — nothing to install.

For the decorator set, field options, relationship syntax, FK naming and the many-to-many rule, read rayfin-core/assets/docs/decorators.md and rayfin-guide/assets/docs/data/overview.md, then known-limitations.md.

Step 3 — register entities in this template's schema

packages/data/src/index.ts starts with the seeded Item registration, while packages/shared/src/index.ts owns its isomorphic record contract and schema type map. Add every entity, including join entities, to both packages:

// packages/shared/src/index.ts
export interface NoteRecord {
  id: number;
  title: string;
}

export type UniversalAppSchema = {
  Note: NoteRecord;
};

// packages/data/src/index.ts
import { Note } from './Note.js';

export const schema = [Note];

The client's generic type comes from UniversalAppSchema (already referenced by packages/frontend/src/lib/rayfin-client.ts), so add every entity to both the schema array: one registered in the array but missing from the type is reachable at runtime and invisible to the compiler.

Type-check with tsc -b, never tsc --noEmit. The workspace packages are referenced TypeScript projects, and the frontend client imports the shared schema type, so a bare tsc --noEmit fails with TS6305 until the referenced project has been built. Run npm run typecheck for the real referenced-project check. npm run build uses tsc -b --noCheck for speed and does not prove the entity types are correct.

Step 4 — read and write

The query chain, mutations, findById, filtering and paging are documented in rayfin-guide/assets/docs/data/graphql.md and rayfin-data/assets/docs/index.md. Use await getRayfinClient() from packages/frontend/src/lib/rayfin-client.ts inside an async query or mutation; that helper is this template's; the API it returns is the package's.

For the interface over your entities — optimistic updates, forms, and the loading / empty / error states — read crud-ui, which ships the kit.

Step 5 — per-user data

"Each person sees only their own …" is a server-side @role policy, never a filter in the UI. A client-side filter still leaves the rows fetchable.

Read rayfin-guide/assets/docs/data/permissions.md for the decorator, the typed policy DSL, the supported claims, logical composition, and field visibility — it is the fullest treatment. rayfin-core/assets/docs/permissions.md adds the @anonymous / @authenticated shorthands, owner-field typing, and owner stamping. Keep authentication and authorization on the data operations that require them.

Notes

  • Stable features only. Use @authenticated / @role('authenticated', …). Anonymous data access on Fabric requires a tenant admin switch — see rayfin-guide/assets/docs/data/overview.md. If asked for public data, say so and use authenticated access.
  • Deploying ships the data model. A schema change migrates on the next deploy. Read app-deployment and follow the installed, version-matched CLI guide.

<!-- MAINTAINERS: this skill owns this template — the data service toggle, the workspace schema shape, the tsc -b build note, and the auth pairing. It does not own Rayfin.

Rayfin's own rules are read at runtime from the installed packages' docs (rayfinDocs.dir, today assets/docs), so they cannot drift from the version a generated app actually has. That replaces the previous arrangement, where this file hand-mirrored rules from the CLI's bundled skill:rayfin and had to be diffed against it on every CLI bump. Drift under that arrangement had already shipped once: bare @text() appeared in every example here while the authoritative rule required an explicit max on MSSQL. -->

04 同仓库更多 Skills

microsoft
microsoft/rayfin

rayfin-getting-started

Use when starting or creating a NEW Rayfin app, or when a Rayfin task comes up and you are not yet inside a Rayfin project. Gets you into a project with the Rayfin CLI, then hands off to the authoritative, version-locked in-project rayfin skill/docs that own all in-project work. Triggers: build a Rayfin app, start a Rayfin project, create a new Rayfin app, create-rayfin, npm create @microsoft/rayfin, rayfin init, scaffold rayfin, rayfin CLI, rayfin template, universal app, awesome-rayfin gallery, get started with Rayfin

★ 655
microsoft
microsoft/rayfin

visuals

Use when user wants to incorporate charts, graphs, data grid, or other visual representations of data into their project. Use VegaVisual and DataGrid components to create these visuals, utilizing the shared DataTable input, formatting, theme, and interactivity. Covers the onInteraction selection/click events host apps consume, named multi-table data input for layered overlays and reference lines, and Vega-Lite native selections. Triggers: chart, graph, plot, dashboard, KPI, metric, trend, scorecard, data grid, visualize.

数据分析师分析与可视化
★ 655
microsoft
microsoft/rayfin

schema-discovery

Explore Power BI semantic model schemas using DAX INFO functions. Progressive metadata discovery strategy, scope estimation, and narrowing techniques for tables, columns, measures, and relationships.

★ 655
microsoft
microsoft/rayfin

query-design

Separates DAX data-fetching from TypeScript presentation. Guides when to use DAX vs. TypeScript vs. Vega-Lite for aggregation, total rows, FORMAT(), SELECTCOLUMNS, BLANK handling, filtering, multi-grain queries, cross-filtering and cross-highlight subset/overlay queries, and format strings.

设计师演示文稿视觉设计
★ 655
microsoft
microsoft/rayfin

functions-capability

Apply and build the Universal App functions capability. Use for trusted server-side logic, secrets, external APIs, custom model endpoints, published Fabric data agents, webhooks, or privileged operations.

★ 655
microsoft
microsoft/rayfin

fabric-sdk

How to query Fabric data from a running app through the Rayfin connectors client. Use getRayfinClient().connectors.<name>.executeQuery to run DAX against a semantic model, and toQueryResult to normalize the response.

★ 655