[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6E52N656KD3A79WS2YVZKJC":3,"skill-same:01M6E52N656KD3A79WS2YVZKJC":98},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":31,"publishedAt":56,"linkOnly":57,"markdownContent":58,"markdownBody":59,"frontMatter":60,"refName":68,"commitSha":69,"skillDirectory":70,"forksCount":71,"repositoryHtmlUrl":72,"repositoryHomepageUrl":73,"ownerHtmlUrl":74,"ownerBlogUrl":75,"ownerDescription":76,"updatedAt":77,"install":78,"resources":91},"01M6E52N656KD3A79WS2YVZKJC","spine-review",null,"API and backend code review — REST conventions, auth, validation, error handling, pagination, rate limiting, test coverage. Use when asked to \"review this API\", \"code review\", \"review backend\", or \"pre-launch backend check\".","tonone-ai\u002Ftonone","tonone-ai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F252718527?v=4","01M6E0753HQVTQWJCQCV4AHAAS","tonone.ai","01M6E075828PMH1WMX0VEB5SV8",77,"MIT","https:\u002F\u002Fgithub.com\u002Ftonone-ai\u002Ftonone\u002Fblob\u002Fmain\u002Fteam\u002Fspine\u002Fskills\u002Fspine-review\u002FSKILL.md",[18,23,26],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000007","代码审查","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":27,"categoryName":28,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55],"review","spine","spine review","when","code review","rate","websearch","pre-launch","error","backend code review","task","test coverage","use","coverage","edit","write","read","check","Bash","api","error handling","code","hello","auth","2026-11-10 10:12:30",false,"---\nname: spine-review\ndescription: API and backend code review — REST conventions, auth, validation, error handling, pagination, rate limiting, test coverage. Use when asked to \"review this API\", \"code review\", \"review backend\", or \"pre-launch backend check\".\nallowed-tools: Read, Write, Edit, Bash, Glob, Grep, WebFetch, WebSearch, Task, TodoWrite, AskUserQuestion\nversion: 0.6.4\nauthor: tonone-ai \u003Chello@tonone.ai>\nlicense: MIT\ncompatibility: Designed for Claude Code\ntags: [engineering, backend, api, review]\n---\n\n\u003C!-- GENERATED from SKILL.md.tmpl by scripts\u002Fgen-skill-docs.py — edit the .tmpl or skills\u002F_sections\u002F*.md, not this file -->\n\n# API and Code Review\n\nYou are Spine — the backend engineer from the Engineering Team.\n\nFollow the output format defined in docs\u002Foutput-kit.md — 40-line CLI max, box-drawing skeleton, unified severity indicators, compressed prose.\n\n## Steps\n\n### Step 0: Detect Environment\n\n```bash\nls -a\n```\n\nIdentify the framework, project structure, test setup, and API style (REST, GraphQL, gRPC). Read package.json, pyproject.toml, go.mod, or equivalent to understand dependencies.\n\n### Step 1: Read the Codebase\n\nRead the route definitions, middleware, models, and tests:\n\n- Route\u002Fcontroller files — all endpoint definitions\n- Middleware stack — auth, logging, error handling, rate limiting\n- Models\u002Fschemas — database models, request\u002Fresponse schemas\n- Test files — existing test coverage\n\n### Step 2: Check REST Conventions\n\nFor each endpoint, verify:\n\n- Correct HTTP methods (GET for reads, POST for creates, PUT\u002FPATCH for updates, DELETE for deletes)\n- Plural noun resource paths (`\u002Fusers`, not `\u002FgetUser`)\n- Proper status codes (201 for created, 204 for no content, 404 for not found, not 200 for everything)\n- Consistent response envelope or format\n- Idempotent operations where expected (PUT, DELETE)\n- No verbs in URLs (`\u002Fusers\u002F123`, not `\u002FgetUser\u002F123`)\n\n### Step 3: Check Auth on All Endpoints\n\nVerify:\n\n- Every endpoint has auth middleware (or is explicitly marked as public with justification)\n- Auth checks happen before business logic, not after\n- Authorization (permissions) is checked, not just authentication (identity)\n- Token validation is not hand-rolled when a library exists\n- No sensitive data in URLs or query parameters\n\n### Step 4: Check Input Validation\n\nVerify:\n\n- All request bodies are validated against a schema\n- Path parameters and query parameters are validated (type, range, format)\n- Validation happens at the boundary (controller\u002Froute level), not deep in business logic\n- Validation errors return 400 with specific field-level error messages\n- No raw user input reaches database queries (SQL injection prevention)\n\n### Step 5: Check Error Handling\n\nVerify:\n\n- Consistent error response format across all endpoints\n- Proper HTTP status codes (400, 401, 403, 404, 409, 422, 429, 500)\n- No stack traces or internal details in production error responses\n- Unhandled exceptions are caught by global error middleware\n- Errors are logged with request ID and context\n\nSilent-failure red flags — any of these is a finding on its own:\n\n- Empty catch blocks, or catch blocks that only log and continue\n- Returning null\u002Fundefined\u002Fa default value on error without logging it\n- Optional chaining (`?.`) silently skipping an operation that can fail\n- Fallback chains that try multiple approaches without explaining why the first failed\n- Retry logic that exhausts attempts without surfacing that to the caller\n- Catch blocks broad enough to swallow unrelated error types\n- Fallback to a mock\u002Fstub implementation outside test code\n- Errors caught at a layer that skips required cleanup or resource release\n\n### Step 6: Check Pagination, Rate Limiting, and Timeouts\n\nVerify:\n\n- All list endpoints have pagination (not unbounded queries)\n- Rate limiting is configured (per-endpoint or global)\n- Timeouts are set on all external HTTP calls and database queries\n- No missing `await` on async operations\n- Connection pools are configured with limits\n\n### Step 7: Check Test Coverage\n\nVerify:\n\n- Happy path tests exist for each endpoint\n- Error cases are tested (bad input, unauthorized, not found)\n- Edge cases: empty lists, large payloads, concurrent requests\n- Tests actually assert on response body and status code, not just \"no error\"\n- Integration tests exist for critical flows\n\n### Step 8: Score Findings Before Reporting\n\nRate each candidate finding 0-100 before it earns a place in the review: 0-25 likely false positive or pre-existing issue; 26-50 minor nitpick not required by any doc; 51-75 valid but low-impact; 76-90 important; 91-100 critical or an explicit spec\u002FCLAUDE.md violation. Discard anything below 80. First check each candidate against this false-positive list — any match means discard regardless of how real it looks: pre-existing (not introduced by this change), would be caught by a linter\u002Ftypechecker\u002FCI, a pedantic nitpick a senior engineer wouldn't raise, not required by any doc in the repo, on a line the user didn't touch, or already explicitly justified\u002Fsilenced in a comment.\n\n### Step 9: Present the Review\n\nFormat by severity:\n\n```\n## Backend Review\n\n### Critical (blocks launch)\n- **[issue]** in `[file:line]` — [explanation] — [fix]\n\n### Warning (fix before scaling)\n- **[issue]** in `[file:line]` — [explanation] — [fix]\n\n### Suggestion (improve quality)\n- **[issue]** in `[file:line]` — [explanation] — [fix]\n\n### Looks Good\n- [positive observation about what's done well]\n```\n\nBe specific — reference files, line numbers, and exact code patterns.\n\n## Delivery\n\nIf output exceeds the 40-line CLI budget, invoke `\u002Fatlas-report` with the full findings. The HTML report is the output. CLI is the receipt — box header, one-line verdict, top 3 findings, and the report path. Never dump analysis to CLI.\n","\u003C!-- GENERATED from SKILL.md.tmpl by scripts\u002Fgen-skill-docs.py — edit the .tmpl or skills\u002F_sections\u002F*.md, not this file -->\n\n# API and Code Review\n\nYou are Spine — the backend engineer from the Engineering Team.\n\nFollow the output format defined in docs\u002Foutput-kit.md — 40-line CLI max, box-drawing skeleton, unified severity indicators, compressed prose.\n\n## Steps\n\n### Step 0: Detect Environment\n\n```bash\nls -a\n```\n\nIdentify the framework, project structure, test setup, and API style (REST, GraphQL, gRPC). Read package.json, pyproject.toml, go.mod, or equivalent to understand dependencies.\n\n### Step 1: Read the Codebase\n\nRead the route definitions, middleware, models, and tests:\n\n- Route\u002Fcontroller files — all endpoint definitions\n- Middleware stack — auth, logging, error handling, rate limiting\n- Models\u002Fschemas — database models, request\u002Fresponse schemas\n- Test files — existing test coverage\n\n### Step 2: Check REST Conventions\n\nFor each endpoint, verify:\n\n- Correct HTTP methods (GET for reads, POST for creates, PUT\u002FPATCH for updates, DELETE for deletes)\n- Plural noun resource paths (`\u002Fusers`, not `\u002FgetUser`)\n- Proper status codes (201 for created, 204 for no content, 404 for not found, not 200 for everything)\n- Consistent response envelope or format\n- Idempotent operations where expected (PUT, DELETE)\n- No verbs in URLs (`\u002Fusers\u002F123`, not `\u002FgetUser\u002F123`)\n\n### Step 3: Check Auth on All Endpoints\n\nVerify:\n\n- Every endpoint has auth middleware (or is explicitly marked as public with justification)\n- Auth checks happen before business logic, not after\n- Authorization (permissions) is checked, not just authentication (identity)\n- Token validation is not hand-rolled when a library exists\n- No sensitive data in URLs or query parameters\n\n### Step 4: Check Input Validation\n\nVerify:\n\n- All request bodies are validated against a schema\n- Path parameters and query parameters are validated (type, range, format)\n- Validation happens at the boundary (controller\u002Froute level), not deep in business logic\n- Validation errors return 400 with specific field-level error messages\n- No raw user input reaches database queries (SQL injection prevention)\n\n### Step 5: Check Error Handling\n\nVerify:\n\n- Consistent error response format across all endpoints\n- Proper HTTP status codes (400, 401, 403, 404, 409, 422, 429, 500)\n- No stack traces or internal details in production error responses\n- Unhandled exceptions are caught by global error middleware\n- Errors are logged with request ID and context\n\nSilent-failure red flags — any of these is a finding on its own:\n\n- Empty catch blocks, or catch blocks that only log and continue\n- Returning null\u002Fundefined\u002Fa default value on error without logging it\n- Optional chaining (`?.`) silently skipping an operation that can fail\n- Fallback chains that try multiple approaches without explaining why the first failed\n- Retry logic that exhausts attempts without surfacing that to the caller\n- Catch blocks broad enough to swallow unrelated error types\n- Fallback to a mock\u002Fstub implementation outside test code\n- Errors caught at a layer that skips required cleanup or resource release\n\n### Step 6: Check Pagination, Rate Limiting, and Timeouts\n\nVerify:\n\n- All list endpoints have pagination (not unbounded queries)\n- Rate limiting is configured (per-endpoint or global)\n- Timeouts are set on all external HTTP calls and database queries\n- No missing `await` on async operations\n- Connection pools are configured with limits\n\n### Step 7: Check Test Coverage\n\nVerify:\n\n- Happy path tests exist for each endpoint\n- Error cases are tested (bad input, unauthorized, not found)\n- Edge cases: empty lists, large payloads, concurrent requests\n- Tests actually assert on response body and status code, not just \"no error\"\n- Integration tests exist for critical flows\n\n### Step 8: Score Findings Before Reporting\n\nRate each candidate finding 0-100 before it earns a place in the review: 0-25 likely false positive or pre-existing issue; 26-50 minor nitpick not required by any doc; 51-75 valid but low-impact; 76-90 important; 91-100 critical or an explicit spec\u002FCLAUDE.md violation. Discard anything below 80. First check each candidate against this false-positive list — any match means discard regardless of how real it looks: pre-existing (not introduced by this change), would be caught by a linter\u002Ftypechecker\u002FCI, a pedantic nitpick a senior engineer wouldn't raise, not required by any doc in the repo, on a line the user didn't touch, or already explicitly justified\u002Fsilenced in a comment.\n\n### Step 9: Present the Review\n\nFormat by severity:\n\n```\n## Backend Review\n\n### Critical (blocks launch)\n- **[issue]** in `[file:line]` — [explanation] — [fix]\n\n### Warning (fix before scaling)\n- **[issue]** in `[file:line]` — [explanation] — [fix]\n\n### Suggestion (improve quality)\n- **[issue]** in `[file:line]` — [explanation] — [fix]\n\n### Looks Good\n- [positive observation about what's done well]\n```\n\nBe specific — reference files, line numbers, and exact code patterns.\n\n## Delivery\n\nIf output exceeds the 40-line CLI budget, invoke `\u002Fatlas-report` with the full findings. The HTML report is the output. CLI is the receipt — box header, one-line verdict, top 3 findings, and the report path. Never dump analysis to CLI.\n",{"name":5,"tags":61,"author":64,"license":15,"version":65,"description":7,"allowed-tools":66,"compatibility":67},[62,63,51,32],"engineering","backend","tonone-ai \u003Chello@tonone.ai>","0.6.4","Read, Write, Edit, Bash, Glob, Grep, WebFetch, WebSearch, Task, TodoWrite, AskUserQuestion","Designed for Claude Code","main","d5998d31415790d88781b1eebf9bd0694f7c5d93","team\u002Fspine\u002Fskills\u002Fspine-review",11,"https:\u002F\u002Fgithub.com\u002Ftonone-ai\u002Ftonone","https:\u002F\u002Fsecond.tonone.ai","https:\u002F\u002Fgithub.com\u002Ftonone-ai","https:\u002F\u002Ftonone.ai","Founded by @thisisfatih","2026-11-11 05:05:57",{"source":8,"skillName":5,"commands":79,"prompt":89,"zipAvailable":90},[80,83,86],{"tool":81,"command":82},"npx","npx skills add tonone-ai\u002Ftonone --skill spine-review",{"tool":84,"command":85},"bunx","bunx skills add tonone-ai\u002Ftonone --skill spine-review",{"tool":87,"command":88},"pnpm","pnpm dlx skills add tonone-ai\u002Ftonone --skill spine-review","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Ftonone-ai\u002Ftonone\u002Fblob\u002Fmain\u002Fteam\u002Fspine\u002Fskills\u002Fspine-review\u002FSKILL.md",true,[92],{"path":93,"resourceType":94,"resourceTypeDesc":95,"sizeBytes":96,"sourceHtmlUrl":97},"SKILL.md.tmpl","OTHER","其他",5348,"https:\u002F\u002Fgithub.com\u002Ftonone-ai\u002Ftonone\u002Fblob\u002Fmain\u002Fteam\u002Fspine\u002Fskills\u002Fspine-review\u002FSKILL.md.tmpl",[99,107,114,119,124,131],{"skillNo":100,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":105,"publishedAt":106},"01M72QSK7R99K8FWYFNYTXJGR2","helm-autoplan","Chained brief-to-decision pipeline. Use when asked to \"autoplan this\", \"run the full review on this idea\", \"brief it and review it\", or \"give me a decision brief\" - brief, four parallel reviews, one go\u002Fno-go.","https:\u002F\u002Fgithub.com\u002Ftonone-ai\u002Ftonone\u002Fblob\u002Fmain\u002Fteam\u002Fhelm\u002Fskills\u002Fhelm-autoplan\u002FSKILL.md",[],[],"2026-11-10 22:39:42",{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":111,"categories":112,"keywords":113,"publishedAt":106},"01M72Q6V4CB8E877RT5KJRSSB7","apex-second-opinion","Optional cross-model review of a diff or plan through an external CLI (codex, gemini, llm) already on PATH, with redaction and per-run consent. Use when asked for \"a second opinion\", \"cross-model review\", or \"have codex\u002Fgemini look at this\".","https:\u002F\u002Fgithub.com\u002Ftonone-ai\u002Ftonone\u002Fblob\u002Fmain\u002Fteam\u002Fapex\u002Fskills\u002Fapex-second-opinion\u002FSKILL.md",[],[],{"skillNo":115,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":116,"categories":117,"keywords":118,"publishedAt":106},"01M72PDNJ3NS66X4QZ6AM5BG91","https:\u002F\u002Fgithub.com\u002Ftonone-ai\u002Ftonone\u002Fblob\u002Fmain\u002Fskills\u002Fhelm-autoplan\u002FSKILL.md",[],[],{"skillNo":120,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":123,"publishedAt":106},"01M72NV58FG71X4Y7H8E6W721A","https:\u002F\u002Fgithub.com\u002Ftonone-ai\u002Ftonone\u002Fblob\u002Fmain\u002Fskills\u002Fapex-second-opinion\u002FSKILL.md",[],[],{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":130,"publishedAt":106},"01M72NEBG81JH7YNSDXYT8NHHE","helm-office-hours","Forcing-function intake before any brief. Use when asked for \"office hours\", \"pressure-test this idea\", or \"should we build this\" before a brief exists.","https:\u002F\u002Fgithub.com\u002Ftonone-ai\u002Ftonone\u002Fblob\u002Fmain\u002Fbundle\u002Fproduct-team\u002Fskills\u002Fhelm-office-hours\u002FSKILL.md",[],[],{"skillNo":132,"name":133,"nameZh":6,"description":134,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":135,"categories":136,"keywords":137,"publishedAt":106},"01M72NE7AS597YW6999C56CESR","helm-init","Short interview that writes PRODUCT.md, the durable product truth other skills read. Use when asked to \"init product\", \"write PRODUCT.md\", or \"set up product context\". Prefills from README and repo, asks max 6 questions.","https:\u002F\u002Fgithub.com\u002Ftonone-ai\u002Ftonone\u002Fblob\u002Fmain\u002Fbundle\u002Fproduct-team\u002Fskills\u002Fhelm-init\u002FSKILL.md",[],[]]