| name | review |
| description | Review the files changed in this session for 100cims-specific bad patterns, type safety, backwards compatibility, and package-specific concerns (mobile + API). Runs lint + type-check verification at the end. |
Review all files you changed in this session. Focus on patterns specific to this codebase. This is a cross-cutting review — it also touches on backwards compatibility and types/api.ts regeneration, which are commonly-forgotten 100cims specifics.
What to flag
1. Bad TypeScript patterns
as any / as SomeType (except as const) — prefer type guards, satisfies, or generics.
- Non-null assertions (
! postfix, e.g. x!.foo, map.get(k)!) — prefer explicit null checks, ??, or optional chaining.
@ts-ignore / @ts-expect-error without a -- reason comment.
console.log left in committed code.
- Hardcoded values that belong in a constant / env var.
- Re-exports of symbols the file doesn't define.
export { X } from "./other" and export type { X } from "./other" are both violations unless the file is explicitly a package's public-API barrel (e.g. components/ui/atoms/index.ts). Callsites import X from where X lives — re-exporting "alongside related hooks for convenience" still drifts, fragments ownership, and pads the bundle. The global rule lives in ~/.claude/CLAUDE.md "Critical Rules"; this skill's job is to catch its violations.
2. Manually edited generated types
If packages/app/types/api.ts is in the diff, flag it. This file is regenerated by yarn app generate-api-types against the running API's Swagger — never hand-edit.
3. Mobile app (packages/app)
- User-facing strings not wrapped in
useIntl / translation keys.
- Direct
fetch / apiClient calls from components — should go through react-query hooks in domains/<entity>/*.api.ts.
- Missing loading / error states on screens that fetch data.
- Inline styles instead of NativeWind classes.
- Env vars without the
EXPO_PUBLIC_ prefix (those don't reach the client).
- Translations not extracted + filled in. Adding
<FormattedMessage defaultMessage="..."> or intl.formatMessage({ defaultMessage: "..." }) is only step 1 — you MUST also:
- Run
yarn workspace @100cims/app translations (extracts new keys into translations/raw-en.json and compiles translations/en.json).
- Add the new keys to both
packages/app/translations/ca.json (Catalan) and packages/app/translations/es.json (Spanish), inserted in alphabetical order by key hash.
- Verify with
grep that all three locale files contain the new key(s). Never ship English-only strings — the app runs in Catalan/Spanish for most users.
4. API (packages/api)
- Missing TypeBox schema validation on route bodies / queries / params / responses.
- Routes under
public/ or protected/ that should be admin-only (or vice-versa).
- Missing
onError logging hook coverage for new error paths.
- New DB query patterns that would be slow without an index — flag for review.
- S3 upload endpoints without image size / MIME validation.
- Multiple Elysia endpoints bundled into one file — one file = one endpoint (see
AGENTS.md).
- Routes added but not mounted in the parent
index.ts composer.
- Hand-authored migration files under
packages/api/src/db/drizzle/ or hand-edited drizzle/meta/_journal.json — flag either. Migration files must be produced by drizzle-kit: yarn api db:generate for schema changes, yarn api db:generate --custom --name <slug> for pure data changes (backfills, renames, merges). See AGENTS.md for the full flow.
- CRITICAL — custom migration SQL must use snake_case column identifiers, NOT camelCase. Drizzle's
text()/boolean()/uuid() builders map TS field imageUrl to DB column image_url; quoting "imageUrl" in raw SQL references a column that doesn't exist. drizzle-kit swallows the PG error and just prints exit code: 1, which silently breaks every Railway build until the migration is fixed. For every new *.sql file under packages/api/src/db/drizzle/, scan each INSERT (...), UPDATE ... SET, and WHERE clause and confirm every identifier matches a real column (cross-check against an existing migration like 0001_seed-data.sql or against information_schema.columns).
5. API backwards compatibility (CRITICAL)
Mobile app versions in the wild cannot be updated reliably — users may be on months-old versions. Every API change MUST be backwards-compatible:
- Never remove fields from response schemas — old clients depend on them.
- Never rename fields — add a new one alongside the old.
- Never change field types — a string stays a string.
- Never remove endpoints — deprecate instead.
- New required body fields must have sane defaults or be optional.
- Body field renames must accept both old and new names simultaneously.
Flag any diff that violates the above. If a response shape genuinely needs to shrink, call it out and ask the user.
6. Skill drift
Scan .claude/skills/ (both project-local and ~/.claude/skills/) for skills that are adjacent to the work you did. If your change introduced a new pattern, utility, or gotcha that a future agent should know, update the relevant skill. Do NOT update skills speculatively — only when a concrete, reusable fact emerged from this session.
How to review
git diff --name-only HEAD (or compare to main) to list changed files. Group by package.
- For each file, read it and scan for the categories above relevant to that file's area.
- Report findings grouped by file with line numbers and exact suggestions.
- After reporting, fix anything mechanical (typos, missing validation, console.log, obvious backwards-compat issues). Leave preference-driven suggestions as a list for the user.
Verification (always run at the end)
After reviewing + fixing, run lint and type-check for any package you touched:
yarn app lint
./node_modules/.bin/tsc --noEmit -p packages/app/tsconfig.json
yarn api lint
./packages/api/node_modules/.bin/tsc --noEmit -p packages/api/tsconfig.json
If errors exist in files you modified, fix them before reporting done. If errors exist in files you did NOT touch, list them as "pre-existing" and move on.
Regenerate types if API surface changed
If you added / changed / removed an Elysia route or its schema, regenerate the mobile-side OpenAPI types:
yarn app generate-api-types
This requires the API dev server running (yarn api dev). Commit the resulting packages/app/types/api.ts change with the same PR as the route change.
Output
End with one of:
No issues found. Lint + type-check pass.
- A short list of issues, what you fixed, and what still needs the user's judgement.