# FBaseTableRecord

- Human documentation: [https://docs.univer.ai/reference/facade/base-table-record](https://docs.univer.ai/reference/facade/base-table-record)

- Agent Markdown: [https://docs.univer.ai/reference/facade/base-table-record.md](https://docs.univer.ai/reference/facade/base-table-record.md)

- Requested language: `en-US`

- Content language: `en-US`

- Documentation version: `1.0.0-rc.0`

- Source: [facade/base-table-record.mdx](https://github.com/dream-num/documentation/blob/dev/content/reference/facade/base-table-record.mdx)

---

Facade API object bound to a Base record.

A Base record is equivalent to a row in a table.
Record values are keyed by field id. Use field ids from `FField` or
`table.getPrimaryFieldId()` instead of display names when reading or writing.

## Access

Access through:

* [`FBaseTable.getRecords()`](https://docs.univer.ai/reference/facade/base-table.md#getrecords)
* [`FBaseTable.getRecordById()`](https://docs.univer.ai/reference/facade/base-table.md#getrecordbyid)
* [`FBaseTable.addRecord()`](https://docs.univer.ai/reference/facade/base-table.md#addrecord)
* [`FBaseTable.addRecords()`](https://docs.univer.ai/reference/facade/base-table.md#addrecords)

## Example

Read, update, and duplicate a record

```ts
const fBase = univerAPI.getActiveBase()
const fBaseTable = fBase.getTableById('table-1')

const record = fBaseTable.getRecordById('task-1')
if (record) {
  record.setValue('status', 'done')
  record.setValues({ progress: 100 })
  const copy = record.duplicate({
    values: { ...record.getValues(), status: 'todo' },
  })
  console.log(copy.getId())
}
```

## Setup

Register [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) or a preset that includes it. In plugin mode, import `@univerjs-pro/bases/facade`. Additional methods below require their listed plugin packages. See [Facade setup](https://docs.univer.ai/guides/bases/getting-started/facade.md).

## `@univerjs-pro/bases`

### `FBaseTableRecord.addChild`

Create a direct child of this record as one undoable operation.

The initial record values and Parent edge are written together. If this is the
table's first hierarchy write, the canonical same-table, single-value
RecordLink field is also created in the same command and the same Undo entry.
Subscribers therefore never observe a committed child without its Parent.
The call is synchronous and returns the new record Facade directly; do not
prefix it with `await`.

Value keys are field ids by default. Pass
`univerAPI.Enum.BaseFieldKeyEnum.Name` to use display names. The optional
`record` object can set metadata such as `orderKey`, `createdAt`, `updatedAt`,
`createdBy`, or `updatedBy`; the record id is always generated by this method.

```typescript
addChild(fieldId: FieldId, values: Record<FieldId, BaseCellValue>, fieldKey?: BaseFieldKeyEnum, record?: Partial<Omit<IRecordSnapshot, 'id'>>): FBaseTableRecord
```

**Parameters**

* `fieldId` — Required. The id returned by `table.getHierarchyFieldId()`.
* `values` — Required. Initial field values. Do not
  include the Parent field; this method writes it from the current record.
* `fieldKey` — Optional. Default: `BaseFieldKeyEnum.Id`. Whether `values` keys are field ids or
  field display names. Defaults to `BaseFieldKeyEnum.Id`.
* `record` — Optional. Optional record metadata.

**Returns**

A Facade object for the newly created child,
returned immediately after the synchronous command succeeds.

**Throws**

With a code from
`univerAPI.Enum.BaseHierarchyErrorCode` for an invalid field, missing parent,
or depth overflow.

If record validation or the atomic command fails.

**Examples**

Create the first hierarchy edge using field ids

```ts
const base = univerAPI.getActiveBase()
if (!base) throw new Error('No active Base.')

const table = base.getTableById('tasks')
if (!table) throw new Error('Tasks table not found.')

const parent = table.getRecordById('task-1')
if (!parent) throw new Error('Parent record not found.')

const fieldId = table.getHierarchyFieldId()
const child = parent.addChild(fieldId, {
  [table.getPrimaryFieldId()]: 'Write integration tests',
})

console.log(child.getParent(fieldId)?.getId()) // 'task-1'
console.log(parent.getChildren(fieldId).map((record) => record.getId()))
```

Create a child using field display names

```ts
const child = parent.addChild(
  table.getHierarchyFieldId(),
  { Title: 'Document the Facade API', Status: 'Todo' },
  univerAPI.Enum.BaseFieldKeyEnum.Name,
  { orderKey: '000030', createdBy: 'agent-1', updatedBy: 'agent-1' },
)
console.log(child.getId())
```

**Types:** [`FBaseTableRecord`](https://docs.univer.ai/reference/facade/base-table-record.md) · [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts) · [`Record`](https://unpkg.com/@typescript/typescript-darwin-arm64@7.0.2/lib/lib.es5.d.ts) · [`BaseCellValue`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts) · [`BaseFieldKeyEnum`](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/field-key.d.ts) · [`Partial`](https://unpkg.com/@typescript/typescript-darwin-arm64@7.0.2/lib/lib.es5.d.ts) · [`Omit`](https://unpkg.com/@typescript/typescript-darwin-arm64@7.0.2/lib/lib.es5.d.ts) · [`IRecordSnapshot`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.addLinkedRecord`

Add one target record to a RecordLink field.

A multi-link field appends a new ID and treats an existing ID as a successful
no-op. A single-link field replaces its current target.

```typescript
addLinkedRecord(fieldId: FieldId, recordId: string): boolean
```

**Parameters**

* `fieldId` — Required. The RecordLink field id.
* `recordId` — Required. The target Record ID.

**Returns**

Whether the undoable command succeeded.

**Throws**

If the field or target record is invalid.

**Examples**

```ts
const task = univerAPI.getActiveBase().getTableById('tasks-table')?.getRecordById('task-1')
task?.addLinkedRecord('related-projects', 'project-3')
```

**Types:** [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.delete`

Delete this record.

```typescript
delete(): boolean
```

**Returns**

`true` if the command succeeded, `false` otherwise.

**Examples**

```ts
const fBase = univerAPI.getActiveBase()
const fBaseTable = fBase.getTableById('table-1')
const record = fBaseTable.getRecordById('task-1')
const success = record.delete()
console.log(success)
```

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.deleteAttachments`

Delete attachments from one attachment field through the Base command path.

Like `FWorksheet.deleteImages(images)`, this method accepts a batch. It removes
matching attachment references from the record while preserving the order of
every remaining attachment. Uploaded file lifecycle is owned by the attachment
storage provider and is not changed by this method.

```typescript
deleteAttachments(fieldId: FieldId, attachments: readonly IBaseAttachment[]): boolean
```

**Parameters**

* `fieldId` — Required. The attachment field id.
* `attachments` — Required. The attachment descriptors to delete.

**Returns**

`true` if the undoable command succeeded or no matching attachment exists.

**Throws**

If `fieldId` is missing or is not an Attachment field.

**Examples**

Delete selected attachments

```ts
const record = univerAPI.getActiveBase().getTableById('table-1')?.getRecordById('record-1')
const attachments = record?.getAttachments('attachments') ?? []
record?.deleteAttachments('attachments', attachments.slice(0, 2))
```

**Types:** [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts) · [`IBaseAttachment`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.duplicate`

Duplicate this record.

The system Record ID is regenerated by the command and is never copied from
the source record. If the source or override values include the table's
canonical Parent field, that edge is validated and committed atomically with
the duplicate. The operation emits hierarchy events with `Facade` source and
rejects a resulting depth overflow.

```typescript
duplicate(record?: Partial<Omit<IRecordSnapshot, 'id'>>): FBaseTableRecord
```

**Parameters**

* `record` — Optional. Optional record snapshot to override the source record.

**Returns**

The new record.

**Throws**

If the duplicated Parent edge is invalid.

**Examples**

```ts
const fBase = univerAPI.getActiveBase()
const fBaseTable = fBase.getTableById('table-1')
const record = fBaseTable.getRecordById('task-1')
const copy = record.duplicate()
console.log(copy)
```

**Types:** [`FBaseTableRecord`](https://docs.univer.ai/reference/facade/base-table-record.md) · [`Partial`](https://unpkg.com/@typescript/typescript-darwin-arm64@7.0.2/lib/lib.es5.d.ts) · [`Omit`](https://unpkg.com/@typescript/typescript-darwin-arm64@7.0.2/lib/lib.es5.d.ts) · [`IRecordSnapshot`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.getAncestors`

Get the effective parent chain, nearest parent first.

The current record is not included. For `root -> section -> task`, calling
this method on `task` returns `[section, root]`.

```typescript
getAncestors(fieldId: FieldId): FBaseTableRecord[]
```

**Parameters**

* `fieldId` — Required. The id returned by `table.getHierarchyFieldId()`.

**Returns**

Ancestors from the direct parent to the root.

**Throws**

If `fieldId` is not the table's actual or virtual Parent field.

**Examples**

```ts
const fieldId = table.getHierarchyFieldId()
const task = table.getRecordById('task-3')
if (!task) throw new Error('Task not found.')

console.log(task.getAncestors(fieldId).map((record) => record.getId()))
```

**Types:** [`FBaseTableRecord`](https://docs.univer.ai/reference/facade/base-table-record.md) · [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.getAttachments`

Get the attachments stored in one attachment field.

The returned array and descriptors are snapshots and can be modified safely.

```typescript
getAttachments(fieldId: FieldId): IBaseAttachment[]
```

**Parameters**

* `fieldId` — Required. The attachment field id.

**Returns**

Attachment descriptors in display order.

**Throws**

If `fieldId` is missing or is not an Attachment field.

**Examples**

Read attachments

```ts
const record = univerAPI.getActiveBase().getTableById('table-1')?.getRecordById('record-1')
const attachments = record?.getAttachments('attachments') ?? []
console.log(attachments.map((attachment) => attachment.name))
```

**Types:** [`IBaseAttachment`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts) · [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.getChildren`

Get this record's direct effective children in deterministic table order.

The result excludes deeper descendants. It is safe to call before the first
hierarchy write and returns an empty array in that state.

```typescript
getChildren(fieldId: FieldId): FBaseTableRecord[]
```

**Parameters**

* `fieldId` — Required. The id returned by `table.getHierarchyFieldId()`.

**Returns**

Direct children ordered by the table's manual
record order. The returned array is a snapshot and can be modified safely.

**Throws**

If `fieldId` is not the table's actual or virtual Parent field.

**Examples**

```ts
const fieldId = table.getHierarchyFieldId()
const parent = table.getRecordById('task-1')
if (!parent) throw new Error('Parent record not found.')

const childIds = parent.getChildren(fieldId).map((record) => record.getId())
console.log(childIds)
```

**Types:** [`FBaseTableRecord`](https://docs.univer.ai/reference/facade/base-table-record.md) · [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.getDescendants`

Get every effective descendant in depth-first display order.

The current record is not included. Each parent's children follow the
deterministic table order, matching the expanded hierarchy projection before
a view-specific filter or sort is applied.

```typescript
getDescendants(fieldId: FieldId): FBaseTableRecord[]
```

**Parameters**

* `fieldId` — Required. The id returned by `table.getHierarchyFieldId()`.

**Returns**

All descendants in pre-order depth-first order.

**Throws**

If `fieldId` is not the table's actual or virtual Parent field.

**Examples**

```ts
const fieldId = table.getHierarchyFieldId()
const epic = table.getRecordById('epic-1')
if (!epic) throw new Error('Epic not found.')

const subtreeRecordIds = epic.getDescendants(fieldId).map((record) => record.getId())
console.log(subtreeRecordIds)
```

**Types:** [`FBaseTableRecord`](https://docs.univer.ai/reference/facade/base-table-record.md) · [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.getId`

Get the record id.

```typescript
getId(): string
```

**Returns**

The record id.

**Examples**

```ts
const fBase = univerAPI.getActiveBase()
const fBaseTable = fBase.getTableById('table-1')
const records = fBaseTable.getRecords()
console.log(records[0]?.getId())
```

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.getLinkedRecordIds`

Return the ordered target Record IDs stored in a RecordLink field.

This method returns IDs, not the configured display labels. Resolve a target
record through the target table when more data is needed. Dangling IDs remain
visible so callers can diagnose or remove links left by imported snapshots.

```typescript
getLinkedRecordIds(fieldId: FieldId): string[]
```

**Parameters**

* `fieldId` — Required. The RecordLink field id.

**Returns**

Ordered target Record IDs.

**Throws**

If `fieldId` is missing or is not a RecordLink field.

**Examples**

Read linked records

```ts
const fBase = univerAPI.getActiveBase()
const tasks = fBase.getTableById('tasks-table')
const projects = fBase.getTableById('projects-table')
if (!tasks || !projects) {
  throw new Error('Expected the Tasks and Projects tables.')
}
const task = tasks.getRecordById('task-1')
const linkField = tasks.getFieldByName('Related projects')

if (task && linkField) {
  const linkedProjects = task
    .getLinkedRecordIds(linkField.getId())
    .map((recordId) => projects.getRecordById(recordId))
    .filter((record) => record !== null)
  console.log(linkedProjects.map((record) => record.getValues()))
}
```

**Types:** [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.getParent`

Get this record's effective parent.

Invalid stored edges, including a missing parent, self-parent, cycle, or an
edge beyond the five-level limit, are preserved in record data but cut from
the effective tree. Such a record is exposed as a root and this method returns
`null`.

```typescript
getParent(fieldId: FieldId): FBaseTableRecord | null
```

**Parameters**

* `fieldId` — Required. The id returned by `table.getHierarchyFieldId()`.
  The deterministic virtual id is valid before the first hierarchy write.

**Returns**

The effective parent, or `null` when this
record is a root or its stored Parent edge is invalid.

**Throws**

If `fieldId` is neither the table's materialized Parent field
nor its deterministic virtual Parent field.

**Examples**

```ts
const base = univerAPI.getActiveBase()
if (!base) throw new Error('No active Base.')

const table = base.getTableById('tasks')
if (!table) throw new Error('Tasks table not found.')

const record = table.getRecordById('task-2')
if (!record) throw new Error('Task not found.')

const fieldId = table.getHierarchyFieldId()
console.log(record.getParent(fieldId)?.getId() ?? 'root')
```

**Types:** [`FBaseTableRecord`](https://docs.univer.ai/reference/facade/base-table-record.md) · [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.getPermission`

Returns the Record object permission facade.

```typescript
getPermission(): FBaseObjectPermission
```

**Returns**

Permission facade combining the Base, Table, and Record Edit points.

**Examples**

```ts
const table = univerAPI.getActiveBase()?.getTables()[0]
const record = table?.getRecords()[0]
if (!record) throw new Error('Record not found.')
await record.getPermission().setReadOnly()
```

**Types:** [`FBaseObjectPermission`](https://docs.univer.ai/reference/facade/base-object-permission.md)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.getRecord`

Get the record snapshot.

```typescript
getRecord(): IRecordSnapshot
```

**Returns**

The record snapshot.

**Examples**

```ts
const fBase = univerAPI.getActiveBase()
const fBaseTable = fBase.getTableById('table-1')
const records = fBaseTable.getRecords()
console.log(records[0]?.getRecord())
```

**Types:** [`IRecordSnapshot`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.getValue`

Get a field value from this record.

For a RecordLink field, this returns its canonical storage string. Prefer
`getLinkedRecordIds()` when consuming RecordLink values.

```typescript
getValue(fieldId: FieldId): BaseCellValue
```

**Parameters**

* `fieldId` — Required. The field id.

**Returns**

The cell value, or `null` if the field is empty.

**Examples**

```ts
const fBase = univerAPI.getActiveBase()
const fBaseTable = fBase.getTableById('table-1')
const record = fBaseTable.getRecords()[0]
console.log(record.getValue('status'))
```

**Types:** [`BaseCellValue`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts) · [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.getValues`

Get all values from this record.

```typescript
getValues(): IRecordSnapshot['values']
```

**Returns**

A field-id keyed value map.

**Examples**

```ts
const fBase = univerAPI.getActiveBase()
const fBaseTable = fBase.getTableById('table-1')
const record = fBaseTable.getRecords()[0]
console.log(record.getValues())
```

**Types:** [`IRecordSnapshot`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.removeLinkedRecord`

Remove one target record while retaining the order of the remaining IDs.
Removing an ID that is not linked is a successful no-op.

```typescript
removeLinkedRecord(fieldId: FieldId, recordId: string): boolean
```

**Parameters**

* `fieldId` — Required. The RecordLink field id.
* `recordId` — Required. The target Record ID.

**Returns**

Whether the undoable command succeeded.

**Throws**

If `fieldId` is missing or is not a RecordLink field.

**Examples**

```ts
const task = univerAPI.getActiveBase().getTableById('tasks-table')?.getRecordById('task-1')
task?.removeLinkedRecord('related-projects', 'project-3')
```

**Types:** [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.setAttachments`

Set the attachments stored in one attachment field through the Base command path.
Uploading or encoding the file is intentionally handled by the caller, so this API works in browser and
headless environments and participates in collaboration and undo/redo.

```typescript
setAttachments(fieldId: FieldId, attachments: IBaseAttachment[]): boolean
```

**Parameters**

* `fieldId` — Required. The attachment field id.
* `attachments` — Required. Attachment descriptors to store. Pass an empty array to clear the field.

**Returns**

`true` if the undoable command succeeded, `false` otherwise.

**Examples**

Store a public URL

```ts
const record = univerAPI.getActiveBase().getTableById('table-1').getRecordById('record-1')
const success = record.setAttachments('attachments', [
  {
    id: 'product-image',
    name: 'product.webp',
    source: 'https://example.com/product.webp',
    sourceType: univerAPI.Enum.ImageSourceType.URL,
    mimeType: 'image/webp',
  },
])
console.log(success)
```

Store the file id returned by a gRPC upload in a headless process

```ts
const fBase = univerAPI.getActiveBase()
if (!fBase) throw new Error('No active Base.')
const table = fBase.getTableById('table-1')
if (!table) throw new Error('Table not found.')
const record = table.getRecordById('record-1')
if (!record) throw new Error('Record not found.')

const uploadedFileId = 'file-id-returned-by-grpc'
const success = record.setAttachments('attachments', [
  {
    id: uploadedFileId,
    name: 'report.pdf',
    mimeType: 'application/pdf',
    sourceType: univerAPI.Enum.ImageSourceType.UUID,
    source: uploadedFileId,
  },
])
console.log(success)
```

Encode a local file in a Node/headless process and store it directly

```ts
import { readFile } from 'node:fs/promises'

const fBase = univerAPI.getActiveBase()
if (!fBase) throw new Error('No active Base.')
const table = fBase.getTableById('table-1')
if (!table) throw new Error('Table not found.')
const record = table.getRecordById('record-1')
if (!record) throw new Error('Record not found.')

const file = await readFile('/path/to/hello.txt')
const source = `data:text/plain;base64,${file.toString('base64')}`
const success = record.setAttachments('attachments', [
  {
    id: `local-${Date.now()}`,
    name: 'hello.txt',
    mimeType: 'text/plain',
    size: file.byteLength,
    sourceType: univerAPI.Enum.ImageSourceType.BASE64,
    source,
  },
])
console.log(success)
```

**Types:** [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts) · [`IBaseAttachment`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.setLinkedRecordIds`

Replace a RecordLink with an ordered list of target Record IDs.

The supplied order is preserved and duplicate IDs keep only their first
occurrence. Pass `[]` to clear the link. Every target record must exist in
the configured target table, and a single-link field accepts at most one ID.

```typescript
setLinkedRecordIds(fieldId: FieldId, recordIds: readonly string[]): boolean
```

**Parameters**

* `fieldId` — Required. The RecordLink field id.
* `recordIds` — Required. Target Record IDs in display order. Pass `[]` to clear the field.

**Returns**

Whether the undoable command succeeded.

**Throws**

If the field is not a RecordLink, its config is invalid, a target is missing, or a single-link field receives multiple IDs.

**Examples**

Replace or clear linked records

```ts
const task = univerAPI.getActiveBase().getTableById('tasks-table')?.getRecordById('task-1')

task?.setLinkedRecordIds('related-projects', ['project-2', 'project-1'])
task?.setLinkedRecordIds('related-projects', []) // Clear all links.
```

**Types:** [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.setOrderKey`

Set this record's order key.

```typescript
setOrderKey(orderKey: string): boolean
```

**Parameters**

* `orderKey` — Required. The new order key.

**Returns**

`true` if the command succeeded, `false` otherwise.

**Examples**

```ts
const fBase = univerAPI.getActiveBase()
const fBaseTable = fBase.getTableById('table-1')
const records = fBaseTable.getRecords()
const lastRecord = records[records.length - 1]

// "0000" sorts before the timestamp-like order keys used by newly
// created records, so the last record moves to the top immediately.
// Clear the view's field sort first to see the underlying record order.
const success = lastRecord?.setOrderKey('0000') ?? false
console.log(success ? 'Record moved to the top' : 'Failed to move record')
```

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.setParent`

Move this record and its entire implicit subtree under another record.

Pass `null` to move the record to the root level. When `orderKey` is supplied,
the Parent change and manual table-order change are applied by one command,
one JSON1 operation, and one Undo entry. A view Sort is independent of the
table-level `orderKey` and may hide the manual-order result until Sort is removed.

Before the Parent field exists, a successful non-root move materializes it in
the same atomic command. The command rejects a self-parent, a cycle, a missing
record, and a move whose resulting tree would exceed five levels.

```typescript
setParent(fieldId: FieldId, parentRecordId: string | null, orderKey?: string): boolean
```

**Parameters**

* `fieldId` — Required. The id returned by `table.getHierarchyFieldId()`.
* `parentRecordId` — Required. The new direct parent's record id, or
  `null` to move this record to the root level.
* `orderKey` — Optional. Optional table-level manual order key to update in
  the same undoable command.

**Returns**

`true` when the atomic command succeeds. Moving to the same
parent and order is a successful no-op.

**Throws**

With a code from
`univerAPI.Enum.BaseHierarchyErrorCode` for an invalid field, missing record,
self-parent, cycle, or depth overflow.

**Examples**

Move a subtree and handle a depth failure

```ts
import { BaseHierarchyError } from '@univerjs-pro/bases'

const base = univerAPI.getActiveBase()
if (!base) throw new Error('No active Base.')

const table = base.getTableById('tasks')
if (!table) throw new Error('Tasks table not found.')

const task = table.getRecordById('task-3')
if (!task) throw new Error('Task not found.')

const fieldId = table.getHierarchyFieldId()
try {
  task.setParent(fieldId, 'task-1', '000020')
} catch (error) {
  if (
    error instanceof BaseHierarchyError &&
    error.code === univerAPI.Enum.BaseHierarchyErrorCode.MaxDepth
  ) {
    console.error('The resulting hierarchy would exceed five levels.')
  } else {
    throw error
  }
}

// Move the same subtree back to the root.
task.setParent(fieldId, null)
```

**Types:** [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.setValue`

Set one field value in this record.

For a RecordLink field, prefer `setLinkedRecordIds()`, `addLinkedRecord()`,
or `removeLinkedRecord()`. Those methods accept Record IDs directly and
document the single-link and multi-link behavior.

```typescript
setValue(fieldId: FieldId, value: BaseCellValue): boolean
```

**Parameters**

* `fieldId` — Required. The field id to write.
* `value` — Required. The new cell value. Pass `null` to clear the cell.

**Examples**

```ts
const fBase = univerAPI.getActiveBase()
const fBaseTable = fBase.getTableById('table-1')
const record = fBaseTable.getRecordById('task-1')
const success = record.setValue('status', 'done')
console.log(success)
```

**Types:** [`FieldId`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts) · [`BaseCellValue`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.setValues`

Set multiple field values in this record.

```typescript
setValues(values: Record<string, BaseCellValue>, fieldKey?: BaseFieldKeyEnum): boolean
```

**Parameters**

* `values` — Required. Field-id keyed values to write. Only the provided fields are
  patched; omitted fields keep their existing values.
* `fieldKey` — Optional. Default: `BaseFieldKeyEnum.Id`. How to interpret the keys in `values`. Defaults to `BaseFieldKeyEnum.Id`.

**Returns**

`true` if the command succeeded, `false` otherwise.

**Examples**

```ts
const fBase = univerAPI.getActiveBase()
const fBaseTable = fBase.getTableById('table-1')
const record = fBaseTable.getRecordById('task-1')
const success = record.setValues({
  status: 'done',
  progress: 100,
})
console.log(success)
```

```ts
const fBase = univerAPI.getActiveBase()
const fBaseTable = fBase.getTableById('table-1')
const record = fBaseTable.getRecordById('task-1')
const success = record.setValues(
  {
    Status: 'done',
    Progress: 100,
  },
  univerAPI.Enum.BaseFieldKeyEnum.Name,
)
console.log(success)
```

**Types:** [`Record`](https://unpkg.com/@typescript/typescript-darwin-arm64@7.0.2/lib/lib.es5.d.ts) · [`BaseCellValue`](https://unpkg.com/@univerjs/core@1.0.0-rc.0/lib/types/bases/typedef.d.ts) · [`BaseFieldKeyEnum`](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/field-key.d.ts)

**Package:** [`@univerjs-pro/bases`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

## `@univerjs-pro/bases-thread-comment`

### `FBaseTableRecord.createCommentAsync`

Creates a comment anchored to this record. The same record anchor is used in Grid, Kanban, Gallery, Calendar, and Gantt views.

```typescript
createCommentAsync(content: ThreadComment.ThreadCommentContent, options?: IBaseRecordCommentCreateOptions): Promise<boolean>
```

**Parameters**

* `content` — Required. Plain text or a Univer document body for rich comment content.
* `options` — Optional. Default: `{}`. Optional stable IDs, author, attachments, and creation time.

**Returns**

`true` when the create command succeeds; otherwise, `false`.

**Throws**

If the content is empty.

**Examples**

```ts
const table = univerAPI.getActiveBase()?.getTables()[0]
const record = table?.getRecords()[0]
await record?.createCommentAsync('Confirm this record.', { id: 'review-record-1' })
```

**Types:** [`Promise`](https://unpkg.com/@typescript/typescript-darwin-arm64@7.0.2/lib/lib.es5.d.ts) · [`ThreadComment.ThreadCommentContent`](https://unpkg.com/@univerjs/thread-comment@1.0.0-rc.0/lib/types/services/thread-comment-api.service.d.ts) · [`IBaseRecordCommentCreateOptions`](https://unpkg.com/@univerjs-pro/bases-thread-comment@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

**Package:** [`@univerjs-pro/bases-thread-comment`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases-thread-comment.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases-thread-comment@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.getComments`

Returns locally loaded comments anchored to this record.

```typescript
getComments(): ThreadComment.IFacadeThreadCommentInfo[]
```

**Returns**

Matching comment threads for this exact Base, table, and record ID.

**Examples**

```ts
const record = univerAPI.getActiveBase()?.getTables()[0]?.getRecords()[0]
const comments = record?.getComments() ?? []
comments.forEach(({ root, children }) => console.log(root.id, children.length))
```

**Types:** [`ThreadComment.IFacadeThreadCommentInfo`](https://unpkg.com/@univerjs/thread-comment@1.0.0-rc.0/lib/types/services/thread-comment-api.service.d.ts)

**Package:** [`@univerjs-pro/bases-thread-comment`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases-thread-comment.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases-thread-comment@1.0.0-rc.0/lib/types/facade/f-record.d.ts)

### `FBaseTableRecord.listCommentsAsync`

Synchronizes known threads and returns comments anchored to this record.

```typescript
listCommentsAsync(): Promise<ThreadComment.IFacadeThreadCommentInfo[]>
```

**Returns**

A promise resolving to matching synchronized comment threads.

**Examples**

```ts
const record = univerAPI.getActiveBase()?.getTables()[0]?.getRecords()[0]
const comments = record ? await record.listCommentsAsync() : []
console.log(comments.length)
```

**Types:** [`ThreadComment.IFacadeThreadCommentInfo`](https://unpkg.com/@univerjs/thread-comment@1.0.0-rc.0/lib/types/services/thread-comment-api.service.d.ts) · [`Promise`](https://unpkg.com/@typescript/typescript-darwin-arm64@7.0.2/lib/lib.es5.d.ts)

**Package:** [`@univerjs-pro/bases-thread-comment`](https://docs.univer.ai/reference/packages/plugins/univerjs-pro/bases-thread-comment.md) · [Type definitions](https://unpkg.com/@univerjs-pro/bases-thread-comment@1.0.0-rc.0/lib/types/facade/f-record.d.ts)
