# Portaljs Define Schema

Define a dataset's metadata profile, infer a Frictionless Table Schema from its data...

- Repository: https://github.com/datopian/portaljs (2370 stars)
- Category: Data and ML
- License: MIT
- Last updated: 2026-10-28
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add datopian/portaljs --skill portaljs-define-schema -g -a claude-code -y`
Codex: `npx skills add datopian/portaljs --skill portaljs-define-schema -g -a codex -y`
Cursor: `npx skills add datopian/portaljs --skill portaljs-define-schema -g -a cursor -y`
Gemini CLI: `npx skills add datopian/portaljs --skill portaljs-define-schema -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add datopian/portaljs`

## Description

Define a dataset's metadata profile, infer a Frictionless Table Schema from its data, add Data Package metadata (license, sources, keywords), and write it into datasets.json so the showcase renders a typed field table. Extend or customize via the L0-L3 profile ladder. Use when a registered dataset needs field types, constraints, or catalog metadata before publishing.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# PortalJS, Define Schema

## Overview

Define a dataset's metadata profile, the **authoring** skill for the metadata-profile
contract (`lib/metadata`). Where `portaljs-add-dataset` registers *that* a dataset exists,
this skill describes *what its data means*: infer a Frictionless **Table Schema** (fields,
types, constraints) from sampled data, add the **Data Package** fields a catalog surfaces
(title, licenses, sources, keywords), and write them onto the dataset's entry in
`datasets.json`. The showcase at `/@<namespace>/<slug>` then renders a typed field table
instead of a bare preview. The model is Frictionless-native; DCAT is a serialization layer
built on top later, not authored here.

The skill runs on a profile ladder, reach for higher levels only when needed:

| Level | What it is | When |
| --- | --- | --- |
| L0 | Default `frictionless-tabular` profile; declare schema + metadata. | Default. Standard tabular CSV/TSV. |
| L1 | L0 plus extra descriptive package fields. | Extra metadata, standard validation is fine. |
| L2 | Fully custom profile (own schema template + `validate()`). | A dataset type needing custom validation rules. |
| L3 | Multiple registered profiles, resolved per dataset. | A portal mixing dataset types. |

The skill is interactive and never dead-ends: if input is thin it interviews in short
rounds, infers defaults from the data, echoes the schema for confirmation, and accepts
"use defaults" to proceed with the inferred schema as-is.

## Prerequisites

- A scaffolded PortalJS portal with the metadata contract (`lib/metadata/types.ts`,
  `pages/[owner]/[slug].tsx`); see `portaljs-new-portal`.
- The target dataset already registered in `datasets.json` (see `portaljs-add-dataset`).
- For tabular schema inference, the dataset's CSV/TSV file present under
  `PORTAL_DIR/public/data/`. JSON/GeoJSON datasets get package metadata only, no `fields`.
- Node 18+; `tsx` optional, used for the schema-validation check.

## Instructions

The rest: https://github.com/datopian/portaljs/blob/HEAD/skills/portaljs-define-schema/SKILL.md
