plugins/lisa-expo-cursor/skills/ops-db-ops/SKILL.md
Database migrations, reverts, schema generation, GraphQL codegen, and the reset/seed/verify state operations for Expo + serverless backend projects. Operates on the backend (TypeORM) and frontend (GraphQL code generation).
npx skillsauth add codyswanngt/lisa ops-db-opsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Manage database migrations, schema generation, GraphQL code generation, and the project's reset/seed/verify state operations.
Argument: $ARGUMENTS — operation (migrate, revert, generate, schema, codegen, seed, reset, reset:verify, state:inventory, state:classify) and optional environment (default: dev)
.)${BACKEND_DIR:-../backend-v2} — set BACKEND_DIR in .claude/settings.local.json if your backend is elsewhereCRITICAL: Never run migrations or reverts against production without explicit human confirmation.
Destructive state operations are stricter than that. reset (and any seed that clears before
it writes) is governed by the reset-seed-coverage rule and never runs on the strength of a
confirmation alone:
--dry-run first, always, and read what it says it will change. A dry run that reports an
entity whose ownership it cannot establish is a STOP, not a warning.--stage, TEST_ENV, URL, host,
or public build-time variable is a request the adapter checks, never the answer. If the requested
stage and the resolved environment disagree, that is a refusal to investigate — not something to
re-run with a different flag.Read the backend package.json to discover available migration and schema scripts:
migration:run:* — run pending migrationsmigration:revert:* — revert last migrationmigration:generate:* — generate new migration from entity changesmigration:create — create empty migrationgenerate:sql-schema* — regenerate SQL schema for MCPaws:signin:* and any environment-backed remote profileRead the backend and frontend package.json to discover the state operations. Discover them; do not
assume these exact names — a project may expose them under its own, and this skill runs whatever the
project declares:
db:seed / seed:* — write the fixture baselinedb:reset / reset:* — converge state back to that baselinedb:reset:verify / reset:verify:* — prove the post-state, by exact countsstate:inventory — enumerate what the running environment actually holdscheck:state-classification — compare that inventory against the state contractRead the frontend package.json to discover codegen scripts:
fetch:graphql:schema:* — fetch GraphQL schemagenerate:types:* — generate TypeScript typesIf a state script the operation needs does not exist, report the absence and the scripts that DO exist. Do not substitute a different script, and do not fall back to running SQL by hand.
All database operations (except codegen) require AWS credentials. Verify the target profile first:
cd "${BACKEND_DIR:-../backend-v2}"
aws sts get-caller-identity --profile {aws-profile}
If this is an interactive local session and credentials are expired, refresh the backend's local AWS signin flow. In a headless or remote-routine session, use the preconfigured environment-backed assume-role profile and do not start an SSO browser/device flow.
Local database:
cd "${BACKEND_DIR:-../backend-v2}"
STAGE={env} bun run migration:run:local
Remote database:
cd "${BACKEND_DIR:-../backend-v2}"
STAGE={env} bun run migration:run:remote:local
Local database:
cd "${BACKEND_DIR:-../backend-v2}"
STAGE={env} bun run migration:revert:local
Remote database:
cd "${BACKEND_DIR:-../backend-v2}"
STAGE={env} bun run migration:revert:remote:local
cd "${BACKEND_DIR:-../backend-v2}"
NAME={migration_name} bun run migration:generate:{env}
cd "${BACKEND_DIR:-../backend-v2}"
NAME={migration_name} bun run migration:create
cd "${BACKEND_DIR:-../backend-v2}"
STAGE={env} bun run generate:sql-schema
Fetch schema:
bun run fetch:graphql:schema:{env}
Generate types:
bun run generate:types:{env}
Note: The backend must be running (locally or deployed) for schema fetching to work.
Run the project's discovered seed script for the target environment. A seed is additive or convergent, never a blind wipe; if the project's seed clears first, treat it as a reset and follow the reset sequence below.
cd "${BACKEND_DIR:-../backend-v2}"
{package-manager} run {discovered-seed-script} --stage {env}
Never a single command. The sequence is fixed:
{discovered-reset-script} --dry-run --stage {env}. Read the enumeration. Stop on
any entity of unknown ownership, on any forbidden-classified entity appearing at all, and on
any disagreement between the requested stage and the resolved environment.check:state-classification reports an
unclassified entity, the reset does not run — an unclassified entity is neither safe to keep nor
safe to delete. Fix the state contract, then start over at step 1.{discovered-reset-script} --stage {env} --idempotency-key {run-id}.reset:verify. A reset that mutated but did not verify is a failure, not a
partial success.{package-manager} run {discovered-verify-script} --stage {env}
Verification asserts exact expected counts per fixture entity. "At least one" passes against a leak, which is the condition being guarded.
Produces the runtime inventory the classification check compares against. A complete inventory covers more than rows: identity-provider objects, object storage prefixes, search indexes, queues and dead-letter backlogs, caches with a persistence tier, derived and materialized views, and runtime-created jobs. Record anything that could not be enumerated, with the reason.
node scripts/check-state-classification.mjs
Exit 0 = every entity the environment holds is classified and every policy obligation is met.
Nonzero = an unclassified entity, an unswept fixture-owned entity, a stale classification, an
incomplete inventory, or a missing assurance. Report the findings verbatim — each names the entity
and what is missing.
Every state operation returns the standard command envelope on stdout — one JSON object with
schemaVersion, capability, mode, operation, environment, contractVersion, dryRun,
status, correlationId, and summary{deleted,created,preserved}. Report from that envelope, not
from prose scraped off stderr. A destructive operation that produced no envelope has not been
verified, whatever its exit code said.
Report operation result:
| Operation | Environment | Target | Status | Details |
|-----------|-------------|--------|--------|---------|
| migrate | dev | local DB | SUCCESS | 2 migrations applied |
| codegen | dev | frontend | SUCCESS | Types regenerated |
| reset | dev | reset adapter | completed | deleted 12 / preserved 31, converged on second apply, correlation abc123 |
| state:classify | dev | state contract | failed | public.notes unclassified — fail closed |
development
Prepare a machine — a fresh laptop or a throwaway container — to run coding agents, before any repository exists. Detects which of Lisa's supported agents (Claude Code, Codex, Cursor, OpenCode, Antigravity, Copilot) are already installed, asks which credential manager the machine uses (Bitwarden, 1Password, Doppler, Vault, AWS, or none), and installs only what is missing, each by its vendor's own preferred method. Idempotent, headless by default, and emits a Dockerfile for a spin-up/spin-down environment. Run it on a new machine, in a container, or before cloning anything.
tools
Provision and verify a remote execution environment for a host project — Codex Cloud today, other remote surfaces as they are added. Generates a repository-owned setup script that installs the declared toolchain, materializes secrets through lisa-secrets-access, and runs the project's own hook. Provisions by API where one exists, by driving the vendor console where one does not, and by emitting exact config otherwise — then proves the result with the same read-back regardless of which tier did the work. Use before dispatching any work with executionEnv.
tools
Bring a developer's machine in line with the toolchain the project declares. Reports every tool in remoteEnv.tools that is missing, outdated, or unpinned for this platform, and installs the missing ones into ~/.local/bin from the same pinned, checksummed entries the remote surfaces use — but only when asked. Same manifest, same pins, same installers as lisa-setup-remote-env; what differs is consent and that the pin is a floor rather than an equality. Run it on a fresh checkout, after a manifest change, or when a tool fails at the moment of use.
tools
Route one unit of work to a remote execution surface. Reads the executionEnv parameter (local by default, codex-cloud or claude-web today), verifies the environment is provisioned and bound to this repository, submits a thin skill invocation, records the task identifier to .lisa/remote-dispatch.json, and exits without polling. Routing only — the remote runs the identical skill from the identical repository. Composable and inline: other skills invoke it via the Skill tool rather than users calling it directly.