К основному содержанию
скилл CX Codex

platform-custom-report-type-generate — скилл для Claude Code

Помогает агенту создавать и проверять метаданные Salesforce Custom Report Type: база, связи, доступные поля. Пригодится при разборе ошибок деплоя .reportType-meta.xml.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add forcedotcom/sf-skills --skill platform-custom-report-type-generate -a claude-code
Открыть на GitHub

Что делает platform-custom-report-type-generate

Скилл задаёт агенту правила работы с файлами .reportType-meta.xml. Один CRT — один файл, имя файла становится developer name типа отчёта. Внутри описаны обязательные элементы: <fullName>, <label>, <baseObject>, <deployed>, а также <join> и <sections> с колонками.

Отдельный блок — критические правила. Если <fullName> указан, он должен посимвольно совпадать с именем файла, включая регистр и подчёркивания. Для каждой связи важен <outerJoin>: false оставляет только записи с дочерними, true берёт все. Объектов в цепочке связей не больше четырёх, и внутреннее соединение после внешнего недопустимо. Поля указывают API-именами, а не подписями.

Скилл рассчитан на авторинг метаданных, а не на работу с готовыми отчётами. Запуск, правку и фильтрацию существующих отчётов, папки, дашборды и списки он не трогает. Нужен API 51.0 или выше, иначе часть элементов просто не пройдёт валидацию при деплое.

Какие задачи решает

  • собрать CRT по кастомным объектам и их связям
  • выбрать inner или outer join для цепочки объектов
  • проверить соответствие <fullName> и имени файла
  • разобрать ошибку деплоя .reportType-meta.xml
  • выставить набор полей, видимых в report builder

Примеры запросов агенту

  • Создай Custom Report Type для объектов Account и Project__c, поля из обоих, внешнее соединение
  • Проверь мой файл AccountsWithProjects.reportType-meta.xml — почему падает деплой?
  • Добавь в CRT связь с Contact через Contacts, но без внутреннего join после внешнего

Как установить platform-custom-report-type-generate

1Через Skills CLI (Vercel)

npx skills add forcedotcom/sf-skills --skill platform-custom-report-type-generate -a claude-code

2Вручную: положить файлы

~/.claude/skills/platform-custom-report-type-generate/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/platform-custom-report-type-generate/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о platform-custom-report-type-generate

Как установить platform-custom-report-type-generate в Claude?

Выполните npx skills add forcedotcom/sf-skills --skill platform-custom-report-type-generate -a claude-code. Файл скилла окажется в ~/.claude/skills/platform-custom-report-type-generate/SKILL.md.

Что делает platform-custom-report-type-generate?

Помогает агенту писать и проверять метаданные Salesforce Custom Report Type: базовый объект, связи, секции с полями. Также разбирает ошибки деплоя таких файлов.

Сработает ли скилл на существующих отчётах?

Нет. Он рассчитан только на создание и валидацию метаданных. Запуск, редактирование и фильтрация готовых отчётов, а также папки, дашборды и списки вне его области.

Исходный текст

SKILL.md · Apache-2.0
---
name: platform-custom-report-type-generate
description: "Use to create, generate, or validate Salesforce Custom Report Type metadata. Trigger on custom report types, CRTs, cross-object reports, report builder data sources, exposing fields for reporting across related objects, inner vs outer joins in reports, report type categories, or deployment errors for .reportType-meta.xml files. Do NOT trigger for running, editing, or filtering existing reports; creating report folders, dashboards, or list views; or non-authoring reporting questions."
metadata:
  version: "1.0"
  domains: ["Platform"]
  minApiVersion: "51.0"
---

## Specification

# Salesforce Custom Report Type Metadata Knowledge

## Overview
Custom Report Types (CRTs) define the **data framework** for Salesforce reports. They specify a primary object, up to 3 related objects, the relationship (join) between them, and which fields are available in the report builder.

## Purpose
- Enable reporting across custom objects and custom relationships not covered by standard report types
- Curate a focused set of fields for report builders (including fields reached via lookup)
- Control inner/outer join behavior to include or exclude primary records without related records

## Configuration

**File extension:** `.reportType-meta.xml`. The file basename is the report type's developer name (e.g. `AccountsWithProjects.reportType-meta.xml`). Each CRT is a single file, not nested under an object folder.

### Key Elements

Top-level `<ReportType>` children:

| Element | Required | Notes |
|---------|----------|-------|
| `<fullName>` | Yes | API identifier; must match the file name. Letters, numbers, underscores; must begin with a letter; no spaces; no trailing underscore; no consecutive underscores |
| `<label>` | Yes | Human-friendly name shown in the report type picker |
| `<description>` | Recommended | State the business "why" — who uses this and what they learn |
| `<baseObject>` | Yes | API name of the primary object (e.g. `Account`, `Project__c`). Cannot be changed after initial creation. All objects, including custom and external, are supported (external objects from API 38.0+) |
| `<category>` | Recommended | Report builder category — see `references/category-values.md` |
| `<deployed>` | Yes | `true` to expose to users; `false` while building/iterating |
| `<join>` | Conditional | Adds a related object and its join behavior. Nest further `<join>` blocks for deeper relationships |
| `<sections>` | Recommended | Groups of columns available to the report type. Though not strictly required, a report without columns isn't useful |

`<sections>` (group of columns) sub-elements:

| Element | Required | Notes |
|---------|----------|-------|
| `<masterLabel>` | Yes | Section heading shown in the report builder |
| `<columns>` | Conditional | One per field exposed in the section |

`<columns>` (single field) sub-elements:

| Element | Required | Notes |
|---------|----------|-------|
| `<field>` | Yes | Field API name (or dotted lookup-traversal path) |
| `<table>` | Yes | The object the field belongs to — base object name or dotted relationship path |
| `<checkedByDefault>` | Yes | `true` if the column is selected by default in the report builder |
| `<displayNameOverride>` | No | Custom column label shown in the report builder, overriding the field's default label |

## Critical Rules (Read First)

### Rule 1: If `<fullName>` Is Present, It Must Match the File Name
In source format, `fullName` is inherited from `Metadata` and derived from the file name, so the `<fullName>` element is technically optional. The repo convention is to include it. **If you include `<fullName>`, its value must equal the file name (everything before `.reportType-meta.xml`) exactly — same characters, same casing, same underscores.**

**Wrong** — file name and `<fullName>` differ:
- File: `account_projects.reportType-meta.xml`
- `<fullName>AccountProjects</fullName>`
  (Mismatch: file uses `account_projects`, fullName uses `AccountProjects`)

**Right** — file name and `<fullName>` are identical:
- File: `AccountProjects.reportType-meta.xml`
- `<fullName>AccountProjects</fullName>`

### Rule 2: Join Semantics — `outerJoin` Controls Inclusion

Each `<join>` block has an `<outerJoin>` element that determines which primary records appear in the report:

| `<outerJoin>` value | Behavior | Report Builder Label |
|---------------------|----------|----------------------|
| `false` | Inner join — only primary records that HAVE at least one related record | "Each 'A' record must have at least one related 'B' record" |
| `true` | Outer join — all primary records, with or without related records | "'A' records may or may not have related 'B' records" |

**Default when unspecified:** Use `true` (outer join) when the user wants to see all primary records regardless of children. Use `false` when the report only makes sense if children exist.

### Rule 3: Each Object Needs Its Own `<sections>` Block

Every object in the CRT (primary + each joined object) must have a corresponding `<sections>` block that lists the fields exposed for reporting. Without a section for an object, none of its fields appear in the report builder.

- `<masterLabel>` on each section is the section heading in the report builder
- `<columns>` entries list the fields — each with a `<field>` (API name) and `<table>` (object API name)
- For fields reached via lookup, use the relationship path in `<field>` (e.g. `Owner.Name` with `<table>` set to the owning object)

### Rule 4: Field API Names, Not Labels

Use exact API names for fields: standard fields use their defined names (`Name`, `CreatedDate`, `OwnerId`), custom fields use `Field__c`. Custom objects must include `__c`.

**Wrong:**
- `<field>Account Name</field>`

**Right:**
- `<field>Name</field>` with `<table>Account</table>`

### Rule 5: Relationship Path for Joined Objects

When adding a `<join>`, the `<relationship>` element must use the **child relationship name** as defined on the lookup/master-detail field pointing from the child object to the parent. For custom relationships, this typically ends in `__r`.

**Wrong:**
- `<relationship>Project</relationship>` (for a custom child relationship)

**Right:**
- `<relationship>Projects__r</relationship>` (child relationship name)
- `<relationship>Contacts</relationship>` (standard, non-custom child relationship)

### Rule 6: Maximum 4 Objects Total in a Join Chain

A single CRT can join a maximum of **four objects total** (the base object + up to 3 additional objects via nested `<join>` blocks).

### Rule 7: No Inner Join After an Outer Join

Once the join chain contains an outer join (`<outerJoin>true</outerJoin>`), every subsequent nested join must also be an outer join. An inner join that follows an outer join earlier in the sequence is not allowed.

**Wrong:**
```xml
<join>
    <outerJoin>true</outerJoin>        <!-- outer join first -->
    <relationship>Contacts</relationship>
    <join>
        <outerJoin>false</outerJoin>   <!-- WRONG: inner join after outer -->
        <relationship>Assets</relationship>
    </join>
</join>
```

**Right:**
```xml
<join>
    <outerJoin>true</outerJoin>
    <relationship>Contacts</relationship>
    <join>
        <outerJoin>true</outerJoin>    <!-- outer stays outer -->
        <relationship>Assets</relationship>
    </join>
</join>
```

### Rule 8: `<table>` for Joined Objects Uses Dotted Path

In `<sections>`, the `<table>` element identifies which object in the join chain each column belongs to. For the base object, use the object name directly (e.g. `Account`). For joined objects, use the **dotted relationship path** from the base object.

| Object in chain | `<table>` value |
|-----------------|-----------------|
| Base (Account) | `Account` |
| First join (Account → Contacts) | `Account.Contacts` |
| Nested join (Account → Contacts → Assets) | `Account.Contacts.Assets` |

### Rule 9: Field Paths Can Traverse Lookups

`<field>` values may reference fields reached via lookup relationships using dot notation — for example `Owner.Email` (owner User's email) or `ReportsTo.CreatedBy.Contact.Owner.MobilePhone`. The `<table>` must still be the object that owns the starting field.

### Rule 10: Historical Trending Fields Use `_hst` Suffix

For a field with `trackTrending=true`, the API name in `<field>` and `<table>` uses the `_hst` suffix:

```xml
<columns>
    <checkedByDefault>false</checkedByDefault>
    <field>Field2__c_hst</field>
    <table>CustomTrendedObject__c.CustomTrendedObject__c_hst</table>
</columns>
```

### Rule 11: Primary Object Cannot Be Changed After Deployment

Once deployed, the `<baseObject>` of a CRT is locked. To change the primary object, create a new CRT and retire the old one.

### Rule 12: `autogenerated` Is Reserved for Historical Trending

The `<autogenerated>` element (API 29.0+) marks CRTs that Salesforce created automatically when historical trending was enabled on an object. Do not set this manually on hand-authored CRTs.

## Generation Workflow

### Step 1: Gather Requirements
- Primary object API name (e.g. `Account`, `Project__c`)
- Related objects and the relationship between each (which has the lookup/master-detail to which)
- For each relationship: inner join (children required) or outer join (children optional)?
- Which fields to expose per object — aim for task-relevant, not the full field list
- Audience and category — where should this appear in the report builder picker?
- Whether this ships as `deployed=true` now or stays `deployed=false` during iteration

### Step 2: Examine Existing Examples
- Look in the project for in-project CRT patterns
- If existing report types have been retrieved from an org, compare against those structures

### Step 3: Write the Specification
Document before authoring:
- `fullName` and `label`
- `baseObject`
- Category and `deployed` state
- Join chain: for each related object — relationship name, outer vs inner join
- Section layout: one section per object, ordered list of fields
- Acceptance criteria: which records should appear when the report runs, which fields are available in the builder

### Step 4: Author the Metadata File

Start from the closest example in `examples/` and adapt it to the user's scenario:

- Primary object only (no joins) → `examples/AccountsWithIndustry.reportType-meta.xml`
- Outer join (primary records included even without children) → `examples/AccountsWithProjects.reportType-meta.xml`
- Nested inner join (every level requires children) → `examples/AccountProjectsWithTasks.reportType-meta.xml`

Name the file `<DeveloperName>.reportType-meta.xml`.

### Step 5: Validate
- Well-formed XML with correct namespace (`xmlns="http://soap.sforce.com/2006/04/metadata"`)
- File name (without `.reportType-meta.xml`) matches `<fullName>` when `<fullName>` is included
- `<baseObject>` is a valid API name and the object is deployed
- Every `<relationship>` uses the correct child relationship name (`__r` suffix for custom)
- Each object referenced in `<sections>` is part of the CRT (primary or joined)
- All `<field>` references exist on the parent `<table>` and use API names (not labels)
- `<category>` is a valid Salesforce category value
- `<deployed>` is `true` if users need to access the CRT immediately

## Reference File Index

| File | When to read |
|------|--------------|
| `examples/AccountsWithIndustry.reportType-meta.xml` | Step 2 / Step 4 — primary-object-only template |
| `examples/AccountsWithProjects.reportType-meta.xml` | Step 2 / Step 4 — outer-join template (primary included even without children) |
| `examples/AccountProjectsWithTasks.reportType-meta.xml` | Step 2 / Step 4 — nested inner-join template (every level requires children) |
| `references/category-values.md` | Step 3 — to choose a valid `<category>` value from the `ReportTypeCategory` enum |
| `references/errors-and-troubleshooting.md` | When fields don't appear in the report builder or join requirements conflict |

## Verification Checklist

### Universal Checks
- [ ] File extension is `.reportType-meta.xml`
- [ ] File basename satisfies the developer-name rules (begins with a letter, only letters/numbers/underscores, no spaces, no trailing underscore, no consecutive underscores)
- [ ] If `<fullName>` is included, it matches the file basename exactly (same characters, casing, and underscores)
- [ ] `<label>` is human-readable and under 40 characters
- [ ] `<description>` explains the business purpose
- [ ] `<baseObject>` uses a valid API name and that object is deployed
- [ ] `<category>` is a valid `ReportTypeCategory` enum value
- [ ] `<deployed>` is set appropriately (`true` for user access, `false` for in-progress iteration)
- [ ] `<autogenerated>` is NOT set manually (reserved for historical-trending CRTs)

### Join Checks
- [ ] Each `<join>` uses the correct child **relationship name** (not the lookup field API name)
- [ ] Custom relationships use `__r` suffix
- [ ] `<outerJoin>` is set intentionally: `true` = optional children, `false` = required children
- [ ] No inner join (`<outerJoin>false</outerJoin>`) appears after an outer join earlier in the sequence
- [ ] Total object count (base + joins, including nested) is 4 or fewer

### Section Checks
- [ ] Every object in the CRT has a corresponding `<sections>` block
- [ ] `<masterLabel>` on each section is descriptive
- [ ] Every `<columns>` has both `<field>` (API name) and `<table>` (object API name or dotted path)
- [ ] `<checkedByDefault>` is set for each column
- [ ] `<table>` for base object is the object API name (e.g. `Account`)
- [ ] `<table>` for joined objects uses the dotted relationship path (e.g. `Account.Projects__r`, `Account.Projects__r.Tasks__r`)
- [ ] Field references use API names (not labels); custom fields use `__c`
- [ ] Lookup traversal fields use dot notation (e.g. `Owner.Email`) with `<table>` set to the object owning the starting field
- [ ] Historical trending fields use `_hst` suffix in both `<field>` and `<table>` when applicable
- [ ] No duplicate fields within a section

© forcedotcom · Apache-2.0 · forcedotcom/sf-skills

Похожие скиллы

Все скиллы по теме «Данные и базы» →
recipe-generate-report-from-sheet официальный googleworkspace Читает данные из Google Sheets и оформляет их как отчёт в Google Docs. Подойдёт, когда нужно собрать документ по таблице и поделиться им с коллегами. CX Codex +1 30 600установок planetscale-customer-report-template planetscale Собирает итоговый отчёт о лучших практиках PlanetScale по базе клиента: сначала инвентаризация и проверки, потом один markdown-документ с рекомендациями. CX Codex +1 1 700установок mantis-report официальный google Преобразует результаты проверки безопасности в профессиональный markdown-отчёт с цепочками эксплуатации. Используй в конце цикла рецензирования, чтобы подготовить документацию для разработчиков и заинтересованных сторон. CX Codex +1 1 500установок report-generator aaron-he-zhu Собирает готовые отчёты по инфлюенсер-кампаниям под конкретную аудиторию: руководство, клиент, команда или совет директоров. CX Codex +1 1 000установок asb-interview-report asmartbear Собирает итоги раунда клиентских интервью в один FINAL-REPORT.md: что подтвердилось, что опровергнуто, что ещё не проверено. CX Codex +1 631установок crm-automation claude-office-skills Скилл для автоматизации продаж: захват и скоринг лидов, движение сделок по стадиям, синхронизация HubSpot, Salesforce и Pipedrive. CX Codex +1 5 500установок

Из того же набора167

mobile-platform-native-capabilities-integrate Помогает собрать Salesforce LWC с нативными функциями мобильного устройства: сканированием, геолокацией, NFC и платежами. Нужен при работе с lightning/mobileCapabilities. CX Codex +1 4 700установок commerce-b2b-open-code-components-replace Меняет стандартные B2B Commerce компоненты на открытые аналоги в content.json метаданных сайта. Или просто показывает соответствия, если менять файлы не нужно. CX Codex +1 4 600установок commerce-b2b-open-code-components-integrate Копирует открытые компоненты Salesforce B2B Commerce из GitHub в метаданные сайта магазина, чтобы они появились в палитре Experience Builder. CX Codex +1 4 600установок platform-policy-rule-generate Помогает писать метаданные PolicyRuleDefinition и PolicyRuleDefinitionSet для Salesforce Data Cloud: схема, дерево категорий, проверки перед деплоем. CX Codex +1 4 100установок platform-sharing-owd-configure Скилл читает и меняет Organization-Wide Default для объектов Salesforce: показывает текущие уровни доступа и правит sharingModel в метаданных. CX Codex +1 3 700установок platform-encryption-configure Скилл для настройки Salesforce Shield Platform Encryption через метаданные и консультаций по архитектуре управления ключами. CX Codex +1 3 600установок platform-dataspace-access-configure Настраивает и проверяет доступ наборов разрешений к DataSpace в Salesforce Data Cloud. Нужен для областей DataSpace и объектных прав DMO, DLO или CIO. CX Codex +1 3 700установок dx-pkg-post-install-configure Настраивает Salesforce managed package после установки по его документации: права, FLS, макеты страниц и доступ к вкладкам. CX Codex +1 3 500установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой