- name
- write-docs-tutorial
- description
- Write a tutorial for the Tiger Data Docs site following established conventions. Use when creating a new tutorial, cookbook, or step-by-step guide for the /learn/tutorials section — especially for database, search, AI, or data engineering topics.
- user-invocable
- true
- allowed-tools
- Read Grep Glob Edit Write Bash Agent
- argument-hint
- [topic or source URL]
- effort
- high
# Write a Tiger Data Docs tutorial
You are writing a tutorial for the Tiger Data Docs site (Astro + Starlight + Stainless Docs). Follow these conventions exactly.
## What you're building
A self-contained, step-by-step tutorial MDX file that lives in `src/content/docs/learn/tutorials/`. The tutorial should be followable from scratch — a reader with no prior setup should be able to go from zero to a working result by following every step in order.
If given a source URL (e.g., a GitHub cookbook repo), adapt that content into the docs format. If given a topic, research the codebase and write from scratch.
## File structure
Create the tutorial at: `src/content/docs/learn/tutorials/<slug>.mdx`
### Frontmatter
```yaml
---
title: <Action verb> <what the tutorial builds> — sentence case
description: One sentence, sentence case, for search and cards.
products: [cloud, self_hosted]
keywords: [tutorials, <topic>, <level>, <technologies>, ...]
---
```
### Imports — always include these
```tsx
import * as C from "@constants";
import { Callout } from "@stainless-api/docs/components";
import { NumberedList, NumberedItem } from "@components/NumberedList";
import { RelatedContentCards, RelatedContentCard } from "@components/RelatedContentCards";
import { Prerequisites } from "@components/Prerequisites";
```
## Page layout (in order)
1. **Opening hook** — A conversational sentence or two that frames why the reader cares. Add personality without being cheesy. Then a brief explanation of what the tutorial covers.
2. **GitHub repo callout** (if applicable) — Immediately after the opening, link to the source repo:
```mdx
<Callout variant="tip">
The complete source code for this tutorial is available in the
[repo-name on GitHub](https://github.com/...).
You can clone the repository to get started quickly, or follow this tutorial step by
step to build everything from scratch.
</Callout>
```
3. **Bullet point summary** — What the two (or more) technologies/approaches do, with a touch of personality.
4. **"By the end" list** — Learning objectives as bullet points.
5. **Prerequisites component**:
```mdx
<Prerequisites>
- A [Tiger Cloud service](/get-started/quickstart/create-service) running PostgreSQL 17+,
or a [self-hosted instance](/get-started/choose-your-path/install-timescaledb)
- Other requirements with install links
</Prerequisites>
```
6. **Horizontal rule** — `---` to visually separate intro from tutorial steps.
7. **Steps** — Each major section is `## Step N: <Action phrase>`.
8. **Going further** — Production tips, advanced patterns.
9. **Current limitations** (if applicable).
10. **Next steps** — `RelatedContentCards` linking to related docs.
## Step conventions
### Headings
- Major sections: `## Step N: <Action phrase in sentence case>`
- Sub-sections within a step: `### <Phrase>`
- CI enforces **sentence case** headings. Proper nouns and acronyms are exceptions.
### Numbered sub-steps
Use `NumberedList` and `NumberedItem` for sequential procedures within a step:
```mdx
<NumberedList>
<NumberedItem title="Do the thing">
Explanation of what to do and why.
\`\`\`sql
-- the code
\`\`\`
What the user should see or verify after this step.
</NumberedItem>
</NumberedList>
```
### Code snippets — ALWAYS add context
Every code block MUST have surrounding text that tells the reader:
- **Where to run it**: "Run the following SQL in your SQL client", "In your terminal, run...", "In the same SQL session..."
- **What it does**: Brief explanation of what the code accomplishes
- **What to expect**: Expected output or what to verify after running
Never drop a bare code block without context.
### Callout variants
- `variant="tip"` — Helpful shortcuts, alternative approaches
- `variant="note"` — Important context, supplementary info
- `variant="warning"` — Security concerns (.env files, secrets), destructive actions
### Collapsible sections
Use `<details>`/`<summary>` for:
- Multiple setup options (e.g., Tiger Cloud vs Docker vs manual install)
- Alternative paths (clone repo vs build from scratch)
- Verbose content that not every reader needs
The **default path should be from scratch** (not collapsed). The shortcut/clone path should be the collapsible one.
```mdx
<details>
<summary>**Already cloned the repo?** Skip to the shortcut</summary>
Shortcut content here...
</details>
Follow the steps below to build from scratch.
```
## Constants — CRITICAL
Import constants once at the top of every tutorial:
```tsx
import * as C from "@constants";
```
Then use the matching constant for every product, brand, or term it covers. **The full list of available constants lives in `src/constants.ts` — read it directly when you need to find the right key, and treat that file as the source of truth.** Common ones include `{C.PG}` (PostgreSQL), `{C.CLOUD_LONG}` (Tiger Cloud), `{C.TIMESCALE_DB}`, `{C.SERVICE_LONG}` (Tiger Cloud service), `{C.SELF_LONG}` (self-hosted TimescaleDB), `{C.CLOUD_EDITOR}` (Tiger Cloud SQL editor), `{C.PGVECTORSCALE}`, and `{C.COMPANY}` (Tiger Data) — but any constant defined in `constants.ts` is fair game when it matches what you're writing.
**Never hardcode** a product or brand name in prose when a constant exists for it. The `TigerData.ProductConstants` Vale rule (run by the `vale.yml` CI check) nudges literal product/brand names toward their constant, including `{C.PG}`.
**Exception:** Inside backticks or URLs, use the literal string. Extension names that appear as code (`pg_textsearch`, `pgvectorscale`) should be in backticks in prose for consistent formatting.
## Use current columnstore/hypercore APIs
TimescaleDB 2.18.0 renamed the compression API to columnstore/hypercore (`compress_chunk` → `convert_to_columnstore`, `*_compression_policy` → `*_columnstore_policy`, `timescaledb.compress` → `timescaledb.enable_columnstore`, etc.). The old names still work as backwards-compat aliases but **must not appear in new tutorials** — in prose, SQL, GitHub repo code excerpts, or screenshots. If you're adapting from a cookbook, blog post, or vendor doc that uses the old names, translate as you write.
Full mapping table, carve-outs (`compress_chunk_time_interval` and `compress_sparse_index` are NOT deprecated), and verification grep one-liner live in `.claude/references/deprecated-compression-apis.md`. Read that file before writing SQL or pasting code from a source repo, and again before saving the tutorial.
## .env file handling
When a tutorial involves environment variables:
1. Explain that the user should **create** (or **duplicate from .env.example**) a `.env` file
2. Include a **warning callout** about adding `.env` to `.gitignore`
3. Explain **what each variable is for** (not just what to set)
4. Show connection variables for both local and Tiger Cloud scenarios
## Cross-linking
Link to existing docs wherever relevant:
- `/learn/search/using-pg-textsearch` — BM25 concepts
- `/learn/search/pgvector-pgvectorsearch` — vector search concepts, including pgvectorscale and StreamingDiskANN
- `/get-started/quickstart/create-service` — creating a service
- `/get-started/choose-your-path/install-timescaledb` — self-hosted setup
- Deploy guides under `/deploy/tiger-cloud/`
Use `Grep` to find existing pages about the tutorial's technologies before writing.
## Tone and personality
- Write like a knowledgeable friend walking someone through the process
- Add light personality to transitions between steps ("Time to take your indexes for a spin", "Here's where things get interesting")
- Use analogies sparingly to explain complex concepts
- Keep the humor encouraging, never condescending
- The personality should enhance the reading experience without distracting from the technical content
## After writing the tutorial
You MUST also:
1. **Add a sidebar entry** in `astro.config.ts` under the "Tutorials" section (~line 514):
```ts
{ label: "<Tutorial title>", link: "/learn/tutorials/<slug>" },
```
2. **Add a card** to `src/content/docs/learn/tutorials/index.mdx`:
```mdx
<RelatedContentCard title="<Title>" description={`<Description using ${C.CONSTANT} if needed>`} href="/learn/tutorials/<slug>" />
```
3. **Add glossary entries** for any new terms introduced. Edit `src/lib/glossary-data.ts` and insert alphabetically. Use the appropriate category from: TimescaleDB, Storage, Time-series, Cloud, Security, Operations, Observability, AI & vectors, PostgreSQL, Data & migration.
4. **Verify the build** passes with `pnpm build`.
## Checklist before finishing
- [ ] Frontmatter has title (sentence case), description, products, keywords
- [ ] GitHub repo linked at top in a callout (if applicable)
- [ ] All product names use constants (no hardcoded "PostgreSQL" in prose)
- [ ] Extension names formatted in backticks consistently
- [ ] Every code block has context (where to run, what it does, what to expect)
- [ ] Prerequisites component lists all requirements with install links
- [ ] `---` separator between prerequisites and Step 1
- [ ] Steps numbered as `## Step N: <Action>`
- [ ] Default path is "from scratch", clone shortcut is collapsible
- [ ] .env handling includes gitignore warning
- [ ] Cross-links to related existing docs
- [ ] RelatedContentCards in Next steps section
- [ ] Sidebar entry added in astro.config.ts
- [ ] Card added to examples index page
- [ ] Glossary entries for new terms
- [ ] `pnpm build` passes cleanly
- [ ] Headings are sentence case
- [ ] No deprecated compression APIs anywhere on the page — `compress_chunk` / `decompress_chunk` / `recompress_chunk` / `*_compression_policy` / `*_compression_stats` / `*_compression_settings` views / `timescaledb.compress(_orderby|_segmentby)` are all replaced with their columnstore/hypercore equivalents (see [the mapping](#use-current-columnstorehypercore-apis))
View on GitHub