`crud-with-billing` scaffolds a new account-scoped resource, in the exact shape as the kit's
example `Project` resource. It's the skill you reach for, or that Claude Code reaches for on its
own, any time you say something like "add invoices" or "let users create projects" in this repo.
The concept-level version of this page lives at
[Adding a Resource](/docs/building-features/adding-a-resource); this page is the skill's own
step-by-step.

## What it needs from you

Two things: the resource name (for example `Invoice`) and its attributes (`amount:integer
note:text`), and whether the feature is paid or free.

## What it generates

Pattern-matched against `app/models/project.rb`, `app/policies/project_policy.rb`,
`app/controllers/projects_controller.rb`, `app/views/projects/*`, and their specs:

1. A model and migration, via `bin/rails g model <Name> account:references <attrs>`, with
   `null: false` added where sensible and `belongs_to :account` plus validations on the model.
2. `has_many :<name>s, dependent: :destroy` on `Account`.
3. A Pundit policy subclassing `ApplicationPolicy`, copied from `ProjectPolicy`, whose inherited
   `Scope` already filters to `account_id`.
4. A controller that queries only through `Current.account.<name>s`, calling `authorize` and
   `policy_scope`, and including `RequireEntitlement` if (and only if) the feature is paid.
5. Views for `index`, `show`, `new`, `edit`, and `_form`, using the Terminal design system classes
   already defined in `application.css`.
6. A `resources :<name>s` route.
7. If the resource introduces a new plan or tier: an extension to `Billing::PLANS` and a new price
   id in `Billing::Stripe::PRICE_ENV`, with the Stripe side managed through the Stripe MCP server or
   `bin/rails console`.
8. Model, policy, and request specs, always including the tenant-isolation test (a foreign account's
   id must 404), and, for paid resources, an entitlement-gate test.

## Verify

`bin/check` green. The tenant-isolation test carries the most weight here: it's the one test that
catches a resource that quietly forgot to scope a query to the current account.

## Next

If the new resource needs to talk to an external service, see
[The add-integration Skill](/docs/claude-code/skill-add-integration).
