Skip to content
Back to skills

Store Conventions

ASecurity

Naming and transaction rules for server store functions in `server/**/store.ts`. Use when adding, renaming, or calling a store function, writing a bulk or singular CRUD helper, or wiring a query into a transaction.

  • 6,969 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 3, 2026
ai-agentsdatabase

Security analysis

A100/100

Scanned September 3, 2026

npx -y skills add BuilderIO/agent-native --skill store-conventions --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Store Conventions?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Store Conventions
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/builderio-store-conventions/badge)](https://www.skillsdirectory.com/skills/builderio-store-conventions)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: store-conventions
description: >-
  Naming and transaction rules for server store functions in
  `server/**/store.ts`. Use when adding, renaming, or calling a store function,
  writing a bulk or singular CRUD helper, or wiring a query into a transaction.
---

# Store Functions And Transactions

Every store in `server/**/store.ts` exposes full CRUD for its entity: `create`,
`get` + `list`, `update`, `delete`. Naming follows three rules:

- **Unsuffixed means "by ids."** `deleteCustomFieldValues({ ids })` deletes by
  value id. Any other selector is explicit: `deleteCustomFieldValuesByTaskIds`,
  `deleteCustomFieldValuesByFieldIds`, `updateCustomFieldValuesByTaskId`.
- **The plural is the implementation; the singular delegates to it** with a
  one-element id list. `deleteTask` calls `deleteTasks`, `updateCustomFieldValue`
  calls `updateCustomFieldValues`. Never write the same query twice.
- **`list` takes every selector as optional** rather than splitting into `ByX`
  variants — `listStoredItems({ ids?, includeDone? })`,
  `listCustomFieldValues({ ids?, taskIds?, fieldIds? })`.

Where a patch is genuinely per-row (custom field title/config, a task's field
values), the bulk form takes one entry per id instead of one patch across ids.
Upsert counts as create; do not add a separate `create` for upserted rows.

Action names are a separate public surface and do not follow this convention:
the `bulk-delete-tasks` action still exists and calls `deleteTasks`.

Every function takes the database handle as an **optional trailing argument**,
so it runs standalone or joins a caller's transaction. The handle is defined
once, in `server/db/transaction.ts`:

```ts
export type DbHandle = Pick<
  ReturnType<typeof getDb>,
  "select" | "insert" | "update" | "delete" | "transaction"
>;
```

## Related Skills

- **actions** — actions are the callers that compose these store functions.
- **task-inbox-workflow** — the task/inbox operations backed by these stores.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…