{"id":"459a0eb1-e944-4ee9-830c-150620e99dcc","shortId":"9dP7aV","kind":"skill","title":"review-database","tagline":"Review database usage for migration safety, query performance, connection/transaction management, and schema design. Covers PostgreSQL and MySQL. Runs squawk for PostgreSQL migration linting if available. Use when the user asks for a database review, SQL review, migration review,","description":"# Database & SQL Review\n\nStructured database review producing actionable, prioritized findings with code-level references.\n\n## Workflow\n\n### 1. Scope and explore\n\n- Confirm scope with the user: full codebase, specific packages/directories, specific migrations, changed files only (PR or branch diff), or specific concern.\n- **Resolve scope to a file/package list.** Based on what the user requested:\n  - **Changed files (PR or branch):** Run `git diff --name-only --diff-filter=d <base>...HEAD` to get changed files (default `<base>` is `main`). If the user references a PR number, use `gh pr diff <number> --name-only` instead. Filter to relevant file types (`.go`, `.sql`). Derive affected Go packages from the file paths (unique parent directories containing `.go` files).\n  - **Explicit paths/packages:** The user may specify directories (e.g. `internal/store/`), Go package patterns (e.g. `./internal/store/...`), individual files, or specific migration files. When given a directory or package pattern, include all files under it.\n  - **Full codebase:** No filtering. Explore everything (default).\n- **Pass the resolved scope** (file list) to all exploration and investigation subagents so they only read and analyze scoped files.\n- Explore the scoped code using parallel subagents (`subagent_type=\"explore\"`). Read all in-scope `.sql` files, schema definitions, and source files that interact with the database (queries, connection setup, transaction handling).\n\n### 2. Launch investigation subagent\n\nLaunch a single investigation subagent (`subagent_type=\"generalPurpose\"`, `model: sonnet` per `subagent-model-routing`) with the list of in-scope files.\n\nPrompt it to:\n- Read all in-scope `.sql` files, schema definitions, and source files that interact with the database.\n- Detect which database engine is in use by checking imports (`pgx`, `pq`, `lib/pq` for PostgreSQL; `go-sql-driver/mysql` for MySQL), migration tool configs, and connection strings. Apply the appropriate engine-specific checklist from [reference.md](reference.md).\n- Analyze against all database categories: migration safety, query performance, connection & transaction management, and schema design (see [reference.md](reference.md)).\n- Detect if horizontal sharding is in use (VSchema files, Citus distribution config, Spanner interleaved tables, shard-routing middleware, or multi-column partition keys). If detected, analyze hot-path queries against the checklist in [reference-sharding.md](reference-sharding.md): flag scatter queries, missing sharding keys in WHERE clauses, cross-shard JOINs, and cross-shard transactions.\n- For PostgreSQL projects: check if `npx` is on PATH (`which npx`). If available, run `npx squawk-cli <migration_files>` against in-scope `.sql` migration files only (when scope is narrowed, limit to `.sql` files in the resolved file list). If `npx` is not available, check for `squawk` directly on PATH. If neither is available, note in Tool Availability and continue with manual review only.\n- Include a **Tool Availability** section listing each tool's status (ran / skipped + reason).\n- For each finding, search nearby code and project documentation for existing TODOs or notes.\n- Return findings using the **per-category findings** template with `DB-` prefixed IDs (e.g. `DB1`, `DB2`).\n- Every finding must include specific file paths, line numbers or function names, a severity rating (CRITICAL / HIGH / MEDIUM / LOW), and tracking status.\n\n### 3. Present results\n\nResolve the review output directory:\n\n```sh\nREVIEW_DATE=$(date +%Y-%m-%d)\nREVIEW_DIR=\"reviews/${REVIEW_DATE}\"\nif [ -d \"$REVIEW_DIR\" ]; then REVIEW_DIR=\"reviews/${REVIEW_DATE}-$(date +%H%M)\"; fi\nmkdir -p \"$REVIEW_DIR\"\n```\n\nCapture run metadata (see [Run metadata header](#run-metadata-header) below) and prepend the rendered block to `${REVIEW_DIR}/DATABASE-REVIEW.md`.\n\nWrite the output to `${REVIEW_DIR}/DATABASE-REVIEW.md`, structured as:\n1. Run metadata header\n2. Tool availability summary\n3. Findings table (with tracking status inline)\n4. Recommended fix order\n\nPresent the report to the user.\n\n---\n\n## Run metadata header\n\nCapture once near `REVIEW_DIR` resolution and prepend the rendered block to the output document:\n\n```sh\nRUN_DATETIME=$(date -u +\"%Y-%m-%d %H:%M UTC\")\nGIT_BRANCH=$(git rev-parse --abbrev-ref HEAD)\nGIT_COMMIT=$(git rev-parse --short HEAD)\nGIT_COMMIT_FULL=$(git rev-parse HEAD)\nGIT_SUBJECT=$(git log -1 --pretty=%s)\n# When scope is diff-based, also: BASE_REF=<base>; BASE_COMMIT=$(git rev-parse --short \"$BASE_REF\")\n```\n\nHeader template (placed at the top of the output `.md`, before the H1 title):\n\n```markdown\n> **Run:** {RUN_DATETIME}\n> **Branch:** {GIT_BRANCH} @ {GIT_COMMIT} (`{GIT_COMMIT_FULL}`)\n> **Subject:** {GIT_SUBJECT}\n> **Base:** {BASE_REF} @ {BASE_COMMIT}   <!-- omit when scope is not diff-based -->\n> **Scope:** {scope description}\n```\n\n---\n\n## Finding link wrapping (PR mode)\n\nWhen the review is scoped to a GitHub PR (`pr_url` is provided by the caller, or, when run standalone, `gh pr view --json url -q .url 2>/dev/null` returns one), wrap every `path:line` reference inside the finding tables below as a Markdown link:\n\n```sh\n~/.claude/scripts/pr-deeplink.sh \"$pr_url\" <path> <line>\n# pr_url set   → [path:line](https://github.com/.../pull/N/files#diff-<hash>R<line>)\n# pr_url empty → path:line   (plain text, unchanged)\n```\n\nThe display text stays `path:line` so plain and linked tables look identical; only the URL goes in the link target. Pass `L` as the fourth argument for findings about removed code (default is `R`). Omit `<line>` for file-level findings to get a file-anchor link. Apply the same wrapping to `path:line` references inside the Tracked column (e.g. `TODO in foo.go:42`). Findings themselves follow `terse-comments`: concrete fix, optional `bug:`/`risk:`/`nit:`/`unsure:` prefix, no praise or restating the diff.\n\n---\n\n## Output Templates\n\n### Per-category findings\n\n```markdown\n| # | Finding | Severity | Tracked |\n|---|---------|----------|---------|\n| DB1 | **Description.** Specific code reference (file:line). Explanation. | HIGH | — |\n| DB2 | Description with code reference. | MEDIUM | TODO in file:line |\n```\n\n**Tracked column values:** Use `—` for new findings. For already-captured findings: `TODO in file:line`, `FIXME in file:line`, `README`, `#123` (issue reference), etc.\n\n### Re-evaluation table (for follow-up reviews)\n\n```markdown\n| Finding | Status | What Changed |\n|---------|--------|--------------|\n| ~~1. Description~~ | FIXED | Brief explanation of the fix |\n| 2. Description | Still applicable | No changes |\n```\n\n---\n\n## Guidelines\n\n- Search the organization's codebase (Sourcegraph, GitHub) for existing patterns before recommending changes.\n- Include effort estimates to help prioritize implementation.\n- When the user asks for a follow-up review, find the most recent review directory (`ls -d reviews/*/ 2>/dev/null | sort | tail -1`) containing `DATABASE-REVIEW.md`, re-evaluate all prior findings, and update with the re-evaluation table appended.\n- For detailed framework categories, see [reference.md](reference.md).\n- **REVIEW.md integration**: If a `REVIEW.md` context section was provided by the review-all orchestrator (or exists at the repository root when running standalone), treat its rules as additional review criteria. \"Always check\" items are HIGH severity; domain-specific items (Database section) are MEDIUM severity. \"Skip\" patterns exclude matching files from review scope.\n- Findings must cite probed evidence (`path:line`, grep output, command result), not pattern-matched suspicion. Per `~/.claude/rules/probe-not-assume.md`.","tags":["review","database","skill","issue","paultyng","agent-skills","ai-tools","claude-code","cursor","dotfiles"],"capabilities":["skill","source-paultyng","skill-review-database","topic-agent-skills","topic-ai-tools","topic-claude-code","topic-cursor","topic-dotfiles"],"categories":["skill-issue"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/paultyng/skill-issue/review-database","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add paultyng/skill-issue","source_repo":"https://github.com/paultyng/skill-issue","install_from":"skills.sh"}},"qualityScore":"0.454","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 8 github stars · SKILL.md body (7,625 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:09:01.892Z","embedding":null,"createdAt":"2026-05-18T13:21:27.164Z","updatedAt":"2026-05-18T19:09:01.892Z","lastSeenAt":"2026-05-18T19:09:01.892Z","tsv":"'-1':685,1024 '/.../pull/n/files#diff-':804 '/.claude/rules/probe-not-assume.md':1120 '/.claude/scripts/pr-deeplink.sh':794 '/database-review.md':591,598 '/dev/null':776,1021 '/internal/store':167 '/mysql':311 '1':58,601,966 '123':948 '2':245,605,775,974,1020 '3':533,609 '4':616 'abbrev':662 'abbrev-ref':661 'action':49 'addit':1077 'affect':141 'alreadi':936 'already-captur':935 'also':694 'alway':1080 'analyz':210,330,375 'anchor':860 'append':1041 'appli':320,862 'applic':977 'appropri':322 'argument':840 'ask':33,1004 'avail':28,416,447,457,461,471,607 'base':89,693,695,697,704,735,736,738 'block':587,639 'branch':78,99,656,724,726 'brief':969 'bug':887 'caller':763 'captur':571,629,937 'categori':334,501,902,1045 'chang':73,95,113,965,979,993 'check':300,407,448,1081 'checklist':326,382 'cite':1105 'citus':357 'claus':394 'cli':421 'code':54,216,486,845,911,920 'code-level':53 'codebas':68,187,985 'column':370,873,928 'command':1112 'comment':883 'commit':666,674,698,728,730,739 'concern':82 'concret':884 'config':316,359 'confirm':62 'connect':241,318,339 'connection/transaction':12 'contain':151,1025 'context':1054 'continu':463 'cover':17 'criteria':1079 'critic':526 'cross':396,401 'cross-shard':395,400 'd':109,547,554,651,1018 'databas':3,5,36,42,46,239,291,294,333,1090 'database-review.md':1026 'date':543,544,552,562,563,647 'datetim':646,723 'db':505 'db1':509,908 'db2':510,917 'default':115,192,846 'definit':231,283 'deriv':140 'descript':742,909,918,967,975 'design':16,344 'detail':1043 'detect':292,348,374 'diff':79,102,107,128,692,897 'diff-bas':691 'diff-filt':106 'dir':549,556,559,570,590,597,633 'direct':451 'directori':150,160,177,540,1016 'display':815 'distribut':358 'document':489,643 'domain':1087 'domain-specif':1086 'driver':310 'e.g':161,166,508,874 'effort':995 'empti':808 'engin':295,324 'engine-specif':323 'estim':996 'etc':951 'evalu':954,1029,1039 'everi':511,780 'everyth':191 'evid':1107 'exclud':1097 'exist':491,989,1065 'explan':915,970 'explicit':154 'explor':61,190,201,213,222 'fi':566 'file':74,96,114,136,146,153,169,173,183,197,212,229,234,271,281,286,356,428,437,441,516,852,859,913,925,941,945,1099 'file-anchor':858 'file-level':851 'file/package':87 'filter':108,133,189 'find':51,483,496,502,512,610,743,786,842,854,878,903,905,933,938,962,1011,1032,1103 'fix':618,885,968,973 'fixm':943 'flag':386 'follow':880,958,1008 'follow-up':957,1007 'foo.go:42':877 'fourth':839 'framework':1044 'full':67,186,675,731 'function':521 'generalpurpos':256 'get':112,856 'gh':126,768 'git':101,655,657,665,667,673,676,681,683,699,725,727,729,733 'github':755,987 'github.com':803 'github.com/.../pull/n/files#diff-':802 'given':175 'go':138,142,152,163,308 'go-sql-driv':307 'goe':830 'grep':1110 'guidelin':980 'h':564,652 'h1':718 'handl':244 'head':110,664,672,680 'header':577,581,604,628,706 'help':998 'high':527,916,1084 'horizont':350 'hot':377 'hot-path':376 'id':507 'ident':826 'implement':1000 'import':301 'in-scop':225,268,277,423 'includ':181,468,514,994 'individu':168 'inlin':615 'insid':784,870 'instead':132 'integr':1050 'interact':236,288 'interleav':361 'internal/store':162 'investig':203,247,252 'issu':949 'item':1082,1089 'join':398 'json':771 'key':372,391 'l':836 'launch':246,249 'level':55,853 'lib/pq':304 'limit':434 'line':518,782,801,810,819,868,914,926,942,946,1109 'link':744,792,823,833,861 'lint':26 'list':88,198,266,442,473 'log':684 'look':825 'low':529 'ls':1017 'm':546,565,650,653 'main':117 'manag':13,341 'manual':465 'markdown':720,791,904,961 'match':1098,1117 'may':158 'md':715 'medium':528,922,1093 'metadata':573,576,580,603,627 'middlewar':366 'migrat':8,25,40,72,172,314,335,427 'miss':389 'mkdir':567 'mode':747 'model':257,262 'multi':369 'multi-column':368 'must':513,1104 'mysql':20,313 'name':104,130,522 'name-on':103,129 'narrow':433 'near':631 'nearbi':485 'neither':455 'new':932 'nit':889 'note':458,494 'npx':409,414,418,444 'number':124,519 'omit':849 'one':778 'option':886 'orchestr':1063 'order':619 'organ':983 'output':539,594,642,714,898,1111 'p':568 'packag':143,164,179 'packages/directories':70 'parallel':218 'parent':149 'pars':660,670,679,702 'partit':371 'pass':193,835 'path':147,378,412,453,517,781,800,809,818,867,1108 'paths/packages':155 'pattern':165,180,990,1096,1116 'pattern-match':1115 'per':259,500,901,1119 'per-categori':499,900 'perform':11,338 'pgx':302 'place':708 'plain':811,821 'postgresql':18,24,306,405 'pq':303 'pr':76,97,123,127,746,756,757,769,795,797,806 'prais':893 'prefix':506,891 'prepend':584,636 'present':534,620 'pretti':686 'prior':1031 'priorit':50,999 'probe':1106 'produc':48 'project':406,488 'prompt':272 'provid':760,1057 'q':773 'queri':10,240,337,379,388 'r':805,848 'ran':478 'rate':525 're':953,1028,1038 're-evalu':952,1027,1037 'read':208,223,275 'readm':947 'reason':480 'recent':1014 'recommend':617,992 'ref':663,696,705,737 'refer':56,121,783,869,912,921,950 'reference-sharding.md':384,385 'reference.md':328,329,346,347,1047,1048 'relev':135 'remov':844 'render':586,638 'report':622 'repositori':1068 'request':94 'resolut':634 'resolv':83,195,440,536 'restat':895 'result':535,1113 'return':495,777 'rev':659,669,678,701 'rev-pars':658,668,677,700 'review':2,4,37,39,41,44,47,466,538,542,548,550,551,555,558,560,561,569,589,596,632,750,960,1010,1015,1019,1061,1078,1101 'review-al':1060 'review-databas':1 'review.md':1049,1053 'risk':888 'root':1069 'rout':263,365 'rule':1075 'run':21,100,417,572,575,579,602,626,645,721,722,766,1071 'run-metadata-head':578 'safeti':9,336 'scatter':387 'schema':15,230,282,343 'scope':59,63,84,196,211,215,227,270,279,425,431,689,740,741,752,1102 'search':484,981 'section':472,1055,1091 'see':345,574,1046 'set':799 'setup':242 'sever':524,906,1085,1094 'sh':541,644,793 'shard':351,364,390,397,402 'shard-rout':363 'short':671,703 'singl':251 'skill' 'skill-review-database' 'skip':479,1095 'sonnet':258 'sort':1022 'sourc':233,285 'source-paultyng' 'sourcegraph':986 'spanner':360 'specif':69,71,81,171,325,515,910,1088 'specifi':159 'sql':38,43,139,228,280,309,426,436 'squawk':22,420,450 'squawk-c':419 'standalon':767,1072 'status':477,532,614,963 'stay':817 'still':976 'string':319 'structur':45,599 'subag':204,219,220,248,253,254,261 'subagent-model-rout':260 'subject':682,732,734 'summari':608 'suspicion':1118 'tabl':362,611,787,824,955,1040 'tail':1023 'target':834 'templat':503,707,899 'ters':882 'terse-com':881 'text':812,816 'titl':719 'todo':492,875,923,939 'tool':315,460,470,475,606 'top':711 'topic-agent-skills' 'topic-ai-tools' 'topic-claude-code' 'topic-cursor' 'topic-dotfiles' 'track':531,613,872,907,927 'transact':243,340,403 'treat':1073 'type':137,221,255 'u':648 'unchang':813 'uniqu':148 'unsur':890 'updat':1034 'url':758,772,774,796,798,807,829 'usag':6 'use':29,125,217,298,354,497,930 'user':32,66,93,120,157,625,1003 'utc':654 'valu':929 'view':770 'vschema':355 'workflow':57 'wrap':745,779,865 'write':592 'y':545,649","prices":[{"id":"a413523f-f6b3-4719-8d4a-db78cc8b54b3","listingId":"459a0eb1-e944-4ee9-830c-150620e99dcc","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"paultyng","category":"skill-issue","install_from":"skills.sh"},"createdAt":"2026-05-18T13:21:27.164Z"}],"sources":[{"listingId":"459a0eb1-e944-4ee9-830c-150620e99dcc","source":"github","sourceId":"paultyng/skill-issue/review-database","sourceUrl":"https://github.com/paultyng/skill-issue/tree/main/skills/review-database","isPrimary":false,"firstSeenAt":"2026-05-18T13:21:27.164Z","lastSeenAt":"2026-05-18T19:09:01.892Z"}],"details":{"listingId":"459a0eb1-e944-4ee9-830c-150620e99dcc","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"paultyng","slug":"review-database","github":{"repo":"paultyng/skill-issue","stars":8,"topics":["agent-skills","ai-tools","claude-code","cursor","dotfiles"],"license":"mit","html_url":"https://github.com/paultyng/skill-issue","pushed_at":"2026-05-18T18:26:54Z","description":"Personal Claude Code / Cursor agent skills, rules, and config","skill_md_sha":"c4d9d145982ebb33e75c72e4150622ac3e81fc73","skill_md_path":"skills/review-database/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/paultyng/skill-issue/tree/main/skills/review-database"},"layout":"multi","source":"github","category":"skill-issue","frontmatter":{"name":"review-database","description":"Review database usage for migration safety, query performance, connection/transaction management, and schema design. Covers PostgreSQL and MySQL. Runs squawk for PostgreSQL migration linting if available. Use when the user asks for a database review, SQL review, migration review, or schema review."},"skills_sh_url":"https://skills.sh/paultyng/skill-issue/review-database"},"updatedAt":"2026-05-18T19:09:01.892Z"}}