| name | ffp-code-review |
| description | Review code changes for FFP project standards including multi-tenant security, British English, architecture patterns, and SOLID principles. Use when reviewing PRs, checking branch changes, or auditing code quality. |
| allowed-tools | Read, Grep, Glob, Bash(git diff:*), Bash(git log:*), Bash(git branch:*) |
FFP Code Review Skill
Capabilities
Senior-level code review specialising in:
- Multi-tenant security: RLS enforcement, tenant isolation, JWT validation
- Healthcare data compliance: OWASP Top 10, sensitive data protection
- FFP architecture patterns: Domain-organised structure, Handler → Service → Repository flow
- British English enforcement: Spelling, grammar, naming conventions
- TypeScript best practices: Strict mode, type safety, explicit signatures
Review Process
1. Gather Context
Check for review context (ALWAYS DO THIS FIRST):
- Try to read
.claude/review-context.md using Read tool
- If exists: Extract goals, requirements, changes made, focus areas, known limitations
- If missing: Note "No review context provided" and proceed with general review
Get git changes:
git diff main...HEAD
git log main..HEAD --oneline
git branch --show-current
Load project documentation:
CLAUDE.md - Team-wide project standards
CLAUDE.local.md - Personal preferences and FFP-specific gotchas
project-documentation/project-state.md - Current sprint and task context
project-documentation/architecture.md - Architecture patterns and decisions
project-documentation/security.md - Security requirements and RLS patterns
2. Analyse Changes
Search for critical patterns using Grep:
- SQL queries:
query|execute|transaction
- Tenant checks:
tenant_id|tenantId
- Auth claims:
claims\[|custom:
- Error handling:
throw|catch|Error
- Database access:
db\.|repository|Repository
- Raw HTML elements:
<h[1-5]|<p>|<p |<span>|<span |<button>|<button
- Hard-coded colours:
text-(gray|red|blue|green|yellow|purple|pink|indigo)-(100|200|300|400|500|600|700|800|900)|bg-(gray|red|blue|green|yellow|purple|pink|indigo)-(100|200|300|400|500|600|700|800|900)
Read modified files using Read tool:
- Focus on changed lines from git diff
- Check surrounding context for proper patterns
- Verify imports and dependencies
Find related files using Glob:
- Test files:
**/*.test.ts, **/*.spec.ts
- Type definitions:
**/*.d.ts, **/types/*.ts
- Related domain files:
packages/core/{domain}/**/*.ts
3. Prioritise Feedback
[CRITICAL] Security & Data Safety
- Missing RLS context in database transactions
- Unvalidated
tenant_id in queries
- SQL injection vulnerabilities (string concatenation)
- Exposed secrets or credentials
- Missing input validation
- Error messages leaking sensitive data
- Improper Cognito claim access (missing
custom: prefix)
[HIGH] Architecture & Type Safety
- Business logic in handlers
- Direct data access in services (should use repositories)
- Missing error handling
any types or missing type annotations
- Incorrect domain organisation
- Missing or improper entity usage
[MEDIUM] Code Quality
- American spelling in FFP-specific code (optimize, color, behavior)
- Exception: Framework/package integrations (TailwindCSS classes, library APIs)
- Emojis in code, comments, or user-facing strings
- Raw HTML elements instead of components (h1-h5, p, span, button)
- Hard-coded colours instead of theme variables
- Poor naming conventions
- Missing comments for complex logic
- Inconsistent formatting (not 2-space indentation)
[LOW] Style Preferences
- Minor code organisation improvements
- Variable naming suggestions
- Performance micro-optimisations
4. Format Output
Provide structured feedback:
# Code Review Summary
**Branch**: [branch-name]
**Files Changed**: X files, +Y/-Z lines
**Review Context**: [Yes/No] - [If yes, summarise key goals and focus areas]
**Review Focus**: [Security | Architecture | Quality]
## [CRITICAL] Issues (Must Fix Before Merge)
[Specific file:line references with remediation examples]
## [HIGH] Priority (Should Fix)
[Architecture violations, type safety issues]
## [MEDIUM] Suggestions (Consider)
[Code quality improvements with trade-offs]
## Positive Observations
[What was done well - reinforce good practices]
FFP-Specific Security Patterns
Correct RLS Pattern
await db.transaction(async (tx) => {
await setRLSContext(tx, context.tenantId);
return await tx.query.users.findMany();
});
Wrong RLS Pattern
await db.query.users.findMany();
Correct Cognito Claims
const tenantId = claims['custom:tenantId'];
const role = claims['custom:role'];
Wrong Cognito Claims
const tenantId = claims.tenantId;
Correct Tenant Validation
const user = await tx.query.users.findFirst({
where: and(
eq(users.id, userId),
eq(users.tenant_id, tenantId)
),
});
Wrong Tenant Validation
const user = await tx.query.users.findFirst({
where: eq(users.id, userId),
});
Architecture Flow Validation
Correct Handler Pattern
export const handler = async (event: APIGatewayProxyEvent) => {
const context = extractUserContext(event);
const input = parseInput(event.body);
const result = await userService.createUser(context, input);
return { statusCode: 201, body: JSON.stringify(result) };
};
Wrong Handler Pattern
export const handler = async (event: APIGatewayProxyEvent) => {
const data = JSON.parse(event.body);
if (data.age < 18) {
throw new Error('Must be 18+');
}
const user = await db.query.users.create({ ... });
return { statusCode: 201, body: JSON.stringify(user) };
};
Component Usage Enforcement
Use themed components instead of raw HTML elements:
Text Elements
<h1 className="text-3xl font-bold text-gray-900">Dashboard</h1>
<h2 className="text-xl text-gray-600">Welcome</h2>
<p className="text-sm text-gray-500">Description text</p>
<span className="text-red-600">Error message</span>
<Title as="h1" colour="foreground">Dashboard</Title>
<Title as="h2" colour="muted-foreground">Welcome</Title>
<Text as="p" styleProps={{ size: 'sm', colour: 'muted-foreground' }}>Description text</Text>
<Text styleProps={{ colour: '' }}>Error message
Buttons
<button className="bg-blue-600 text-white px-4 py-2 rounded-md">
Click me
</button>
<Button variant="primary">Click me</Button>
When raw HTML is acceptable:
- Form inputs (input, textarea, select) - use FormTextInput instead
- Structural elements (div, section, nav, header, footer)
- Semantic elements (ul, ol, li, table, tr, td)
- Special cases where component doesn't exist (rare)
Colour Theme Enforcement
Use theme colours instead of hard-coded values:
Hard-coded Colours to Avoid
className="text-gray-900"
className="text-gray-600"
className="text-red-600"
className="bg-blue-50"
className="border-green-200"
<Text styleProps={{ colour: 'foreground' }} />
<Text styleProps={{ colour: 'muted-foreground' }} />
<Text styleProps={{ colour: 'destructive' }} />
className="bg-info/10"
className="border-success/20"
Available Theme Colours
Text colours (use via Text or Title components):
foreground - Primary text (dark)
muted-foreground - Secondary text (medium gray)
primary - FFP primary blue
secondary - FFP light purple
success - Green
destructive - Red (errors)
warning - Yellow/amber
info - Blue (informational)
Background/border colours (use via Tailwind classes):
bg-background, bg-foreground
bg-primary, bg-secondary, bg-success, bg-destructive, bg-warning, bg-info
bg-muted, bg-accent, bg-card
- Use opacity for lighter shades:
bg-primary/10, border-destructive/20
When Hard-coded Colours Are Acceptable
- Gradients or complex visual effects (e.g.,
bg-gradient-to-r from-success to-info)
- Temporary dev-only components
- Very specific brand colours not in theme (must be rare)
Check files in scope:
- All
.tsx files in packages/web/src/pages/
- All
.tsx files in packages/web/src/components/
- Focus on production components (not dev pages)
British English Enforcement
Important: British English applies to FFP-specific code only. Framework/package integrations (e.g., TailwindCSS classes, library APIs) should use the framework's expected spelling.
Common mistakes to catch in FFP code:
| American (Wrong) | British (Correct) |
|---|
| optimize (in FFP code) | optimise |
| organize (in FFP code) | organise |
| customize (in FFP code) | customise |
| color (in FFP code) | colour |
| behavior (in FFP code) | behaviour |
| center (in FFP code) | centre |
| license (noun, FFP code) | licence (noun) |
Check in:
- FFP variable/function names:
optimizeWorkout → optimiseWorkout
- FFP comments: "// Optimize the query" → "// Optimise the query"
- FFP string literals: "Customization" → "Customisation"
- User-facing messages: "Authorization failed" → "Authorisation failed"
DO NOT flag as errors:
- TailwindCSS classes:
text-center, bg-color-blue-500 (framework convention)
- Library APIs:
color, initialize, center (when part of framework interface)
- Package configuration:
color, behavior (when required by package)
Review Philosophy
- Security first: Healthcare data = zero tolerance for vulnerabilities
- Constructive feedback: Explain why, show how to fix
- Specific examples: Provide remediation code, not just descriptions
- Positive reinforcement: Acknowledge good practices
- Phase 1 context: Don't over-engineer; ship fast, iterate on feedback
- Senior perspective: Mentor, don't just criticise
Usage Examples
Invoke directly:
Use the ffp-code-review skill to review my changes
Focus on specific area:
Use ffp-code-review to check security in my authentication code
After making changes:
Review my latest commit with ffp-code-review before I push