Definir modelos de dados para aplicativos Fabric

Fabric Apps usa decoradores TypeScript para definir modelos de dados que geram tabelas de banco de dados e APIs. Você define cada entidade como uma classe decorada com @entity(), adiciona decoradores de campo para tipos de dados e mapeia relações entre entidades.

Para obter diretrizes de autorização e controle de acesso, consulte Definir permissões de dados.

Pré-requisitos

  • Um projeto Fabric Apps criado com npm create @microsoft/rayfin@latest ou inicializado com npx rayfin init.
  • Noções básicas sobre classes TypeScript e decoradores.

Definir uma entidade

Para criar um modelo de dados, adicione o @entity() decorador a uma classe TypeScript. Em seguida, importe os decoradores necessários de @microsoft/rayfin-core:

import { entity, uuid, text, date } from '@microsoft/rayfin-core';

@entity()
export class Todo {
  @uuid() id!: string;
  @text() title!: string;
  @text({ optional: true }) description?: string;
  @date() createdAt!: Date;
  @date() updatedAt!: Date;
}

Essa entidade gera uma Todo tabela com colunas para id, , title, descriptione createdAtupdatedAt.

Chaves primárias

Cada entidade usa um campo UUID string nomeado id como sua chave primária. Se você não declarar id explicitamente, Fabric Apps o adicionará ao esquema automaticamente.

  • O id campo é opcional durante as operações de criação– o servidor gera uma UUID se você omitir.
  • Você pode fornecer sua própria UUID no momento da criação se preferir identificadores gerados pelo cliente.
  • Não há suporte para chaves primárias compostas e nomes de chave personalizados.
@entity()
export class Note {
  @uuid() id!: string;  // UUID primary key, auto-generated when omitted
  @text() title!: string;
  @text() content!: string;
}

Tipos de dados com suporte

Use estes decoradores para definir tipos de campo:

Decorador Tipo Description
@uuid() cadeia Campo Identificador exclusivo.
@text() cadeia Campo de texto com restrições de comprimento opcionais.
@int() número Campo de número inteiro.
@decimal() número Campo decimal ou numérico.
@boolean() boolean Campo true ou false.
@date() Data Campo de data e hora, serializa a partir de cadeias de caracteres ISO ou objetos Date.
@email() cadeia Campo de texto com validação de email.
@set() cadeia Conjunto enumerado de literais de cadeia de caracteres.

Exemplo com vários tipos

import { entity, uuid, text, int, decimal, boolean, date, set } from '@microsoft/rayfin-core';

@entity()
export class Product {
  @uuid() id!: string;
  @text() name!: string;
  @decimal() price!: number;
  @int() stockQuantity!: number;
  @boolean() isAvailable!: boolean;
  @date() createdAt!: Date;
  @set('draft', 'published', 'archived') status!: 'draft' | 'published' | 'archived';
}

Modificadores de tipo

Adicione modificadores aos decoradores de campo para configurar a validação e as restrições:

Modificador Description
{ optional: true } Permitir valores NULL. Os campos são exigidos por padrão.
{ unique: true } Adicione uma restrição exclusiva.
{ default: value } Defina uma expressão de valor padrão.
{ max: n }, { min: n } Restrições de comprimento da cadeia de caracteres (número máximo e mínimo de caracteres).
{ min: n }, { max: n } Restrições de valor numérico.

Note

O marcador opcional TypeScript (? após um nome de propriedade) afeta apenas o tipo TypeScript estático. Ele não torna a coluna de banco de dados anulável. Para tornar um campo anulável, adicione { optional: true } ao decorador. Use ! para afirmar que um campo necessário é inicializado pela estrutura.

Exemplo com modificadores

@entity()
export class User {
  @uuid() id!: string;
  @email({ unique: true }) email!: string;
  @text({ min: 3, max: 50 }) username!: string;
  @text({ optional: true, max: 500 }) bio?: string;
  @int({ min: 0, max: 150 }) age!: number;
  @boolean({ default: false }) isVerified!: boolean;
}

Definir relações

Use os decoradores @one() e @many() para definir propriedades de navegação entre entidades. O Fabric Apps gera automaticamente colunas de chave estrangeira quando você define relacionamentos.

  • Um para muitos – Use @many() no pai e @one() no filho.
  • Muitos para um – use @one() no filho para fazer referência ao pai.
  • Não há suporte para relações muitos para muitos: use uma entidade de junção explícita.

Exemplo com uma relação de um para muitos

import { entity, uuid, text, date, one, many } from '@microsoft/rayfin-core';

@entity()
export class Notebook {
  @uuid() id!: string;
  @text() name!: string;
  @date() createdAt!: Date;
  @many(() => Note) notes?: Note[];
}

@entity()
export class Note {
  @uuid() id!: string;
  @text() title!: string;
  @text() content!: string;
  @date() createdAt!: Date;
  @text() notebook_id!: string;
  @one(() => Notebook) notebook?: Notebook;
}

Quando você define @one(() => Notebook) na entidade Note, Fabric Apps cria automaticamente uma coluna de chave estrangeira notebook_id. Declare o campo de chave estrangeira explicitamente somente se você planeja lê-lo ou defini-lo no código do aplicativo.

Convenção de nomenclatura de chave estrangeira

Ao definir um campo de chave estrangeira, use a convenção de nomenclatura {property}_id :

@entity()
export class Note {
  @uuid() id!: string;
  @text() notebook_id!: string;      // Foreign key field
  @one(() => Notebook) notebook?: Notebook;  // Navigation property
}

Não há suporte para nomes personalizados de chave estrangeira (foreignKey, opções targetKey).

Entidades do sistema de referência

Fabric Apps não dá suporte a relações @one() que apontam para entidades do sistema, como a entidade USER interna. Para associar uma linha ao usuário conectado, adicione um campo simples user_id do tipo @text() e preencha-o a partir das claims de autenticação (normalmente claims.sub):

@entity()
export class Task {
  @uuid() id!: string;
  @text() title!: string;
  @text() user_id!: string;  // System user ID from claims.sub
}

Filtre as linhas por user_id em suas políticas de função para aplicar o acesso por usuário.

Registrar entidades no esquema

Adicione todas as classes de entidade a rayfin/data/schema.ts, para que o cliente possa gerar proxies GraphQL:

import type { Note } from './Note.js';
import type { Notebook } from './Notebook.js';

export type NotesAppSchema = {
  Note: Note;
  Notebook: Notebook;
};

Atualize esse tipo sempre que você criar uma nova entidade.

Aplique alterações de esquema

Depois de definir ou modificar entidades, aplique as alterações ao banco de dados:

  1. Implante o esquema atualizado para Fabric:

    npx rayfin up db apply
    
  2. Se a alteração do esquema incluir operações destrutivas (remover colunas, renomear tabelas), a CLI avisará você e se recusará a continuar. Use --force para substituir a verificação de segurança:

    npx rayfin up db apply --force
    

Note

O uso --force pode causar perda de dados. Examine as operações listadas cuidadosamente antes de prosseguir.

Práticas recomendadas

  • Defina campos de chave estrangeira somente quando precisar lê-los ou atribuí-los no código — o Fabric Apps os gera automaticamente com base nos decoradores de navegação.
  • Use importações relativas com extensões .js em arquivos de entidade para que o JavaScript ESM gerado seja resolvido corretamente.
  • Para obter padrões de autorização e acesso baseado em função, consulte Definir permissões de dados.

Resolução de problemas

Relações ausentes

Se as relações não aparecerem na API, verifique se:

  • O decorador de navegação (@one() ou @many()) está presente.
  • A entidade está registrada em rayfin/data/schema.ts.