Add demo accounts and starter content to production
@slashclone/seed-through-the-real-path
Fill a production app with demo accounts and starter content safely, through its own API or CLI instead of raw database inserts. Validation and audit logs run as for any user. Idempotent scripts with a dry run, short-lived tokens in a private file, a cleanup step that revokes them, and a guard that shows which database you are about to write to. Never prints tokens.
- Activity
- New: be the first to try it
- Installs
- 0 installs
- Likes
- 0 likes
- Clones
- 0 clones
How this works
- It is a skill: written instructions Claude reads when your request matches what the skill is for. You do not call it by name; just ask for the task.
- While it works, it reads files in the places it lists, nowhere else.
- It runs these commands on your computer: node scripts/seed-guard.mjs.
- Nothing runs until you choose to use it, and you can remove it any time.
SKILL.md
Seed through the real path
Goal: production content that looks exactly like content a real user made, because it went through the same doors. Nothing skips validation, scanning, signing, or the audit log.
Why not insert rows
A row written straight into the database skips every check the app makes on a write. It can hold content the scanner would reject, miss a signature or a hash, skip counters and search indexes, and leave no audit record. It also hides bugs in the write path that your first real user will then find. Seed with the same CLI or API calls a user would make. Write rows directly only for the account records themselves when no public sign-up path exists, and keep that part as small as you can.
The shape
Split seeding into two kinds of script.
Account setup (an operator script that talks to the app's own server functions or admin API):
- Creates each house account if it is missing, looked up by handle, so a rerun changes nothing.
- Mints one short-lived token per account with the smallest scope that can publish. Name every token the same (for example
seeding) so cleanup can find them. - Writes the tokens to a file outside the repo, created with mode 0600. Never prints a token. Prints one line per account: the handle and "ready".
- Optional flags:
--only <handle>to touch one account,--seedingto lift a plan or rate limit while seeding.
Content seeding (a script that only calls the public CLI or API, with the tokens from the file):
- Reads a plan file in the repo (accounts, content, which items to feature).
- For each item, checks whether that exact version already exists and skips it if so. Published versions are usually immutable, so a rerun must never try to overwrite one; a change is a new version.
- Uses the app's normal admin actions for featuring or curation, acting as a named staff member, so those steps are audited too.
Required flags
--dry-runon every script. It resolves the target, reads the plan, and prints what it would create, skip, or change. It writes nothing. Always run it first and read the counts.--doneon the account script. It revokes every token with the seeding name, puts each account back on its normal plan and limits, and prints one line per account. Run it the moment seeding ends, even if seeding failed halfway. Then delete the token file.
Rules learned the hard way
- Mint tokens against the environment you will publish to. If production config lives in its own env file (for example
.env.production), mint from that file. A token minted with the dev env goes into the dev database, and production rejects it with a 401. Revoke the stray token in dev too. - Never read a token file in a way whose errors can print it. In Node,
require()on a file without a.jsonextension parses it as JavaScript, and the syntax error quotes the file, token included, into your log. UseJSON.parse(readFileSync(path, "utf8"))inside a try, and on failure print a generic message with no contents.scripts/seed-guard.mjsexportsreadTokenFile()that does this; import it rather than writing your own. If a token ever lands in a log, revoke it at once and say so. Confirm which database a script points at before it writes. Do not
sourcean env file in the shell. A value with&in it ends the assignment and backgrounds it, the variable stays unset, and many scripts then fall back to a default dev URL without a word. Let the runtime layer the files instead, in order, later files winning. In Node, pass--env-fileonce per file, base file first and production file last. Shared values stay in the base file and production values override them.Make every seeding script print the target host (never the full URL) as its first line, and check it before you continue. To check by hand:
node scripts/seed-guard.mjs target --env-file .env --env-file .env.production --var DATABASE_URL --expect <part of the production host>It exits non-zero if the host does not match. A count in the dry run (for example how many items exist) is a second check: dev and production rarely have the same number.
Token file checks
Before the content script runs, check the file:
node scripts/seed-guard.mjs tokens --file /path/outside/repo/seed-tokens.jsonIt fails if the file is inside the repo, readable by anyone but you, or not a JSON object of account to token. It prints account names only.
Audit trail
- The app's own audit log should show every step, because every step went through a real action. Do not add a quiet bypass.
- Keep a short session note: which accounts, which content and versions, the dry-run counts, the real counts, and when tokens were revoked. Counts only, never tokens, prompt text, or file contents from users.
- If something slipped (a wrong target, a leaked token), write down what happened, what you revoked, and the rule that prevents it next time.
Run order
- Dry run of the account script against production. Check the host and counts.
- Account script for real, with
--seedingif you need limits lifted. Tokens go to the private file. seed-guard.mjs tokenson the file.- Dry run of the content script. Check what it will create and skip.
- Content script for real. Check a few items in the live app as a signed-out visitor.
--done. Delete the token file. Note the session.
Do not
- Do not commit the token file, paste a token into chat, or pass a token on the command line where shell history keeps it. Read it from the file.
- Do not give seeding tokens broad scopes "just in case". Publish scope only.
- Do not leave plan or limit lifts in place after seeding.
- Do not seed from a branch that has not been reviewed: the content goes public.
Files
- SKILL.md
- examples/env.base
- examples/env.prod
- kit.json
- scripts/seed-guard.mjs
Did it work?
0worked for them0did not work
Sign in to say whether it worked for you.
Nobody has said yet. Tried it? Tell the next person.
