Skip to content
Back to skills

Ffp Code Review

ASecurity

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.

  • 666 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added February 8, 2026
code-qualitytypescriptgobashsqlcode-reviewgitapidatabasesecurityperformance

Works with

  • cli
  • api

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill ffp-code-review --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ffp Code Review?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ffp Code Review
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-ffp-code-review/badge)](https://www.skillsdirectory.com/skills/majiayu000-ffp-code-review)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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:**

```bash
git diff main...HEAD              # All changes on current branch
git log main..HEAD --oneline      # Recent commits
git branch --show-current         # Current branch name
```

**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:

```markdown
# 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

```typescript
// Set RLS context in transaction
await db.transaction(async (tx) => {
  await setRLSContext(tx, context.tenantId);
  return await tx.query.users.findMany();
});
```

### Wrong RLS Pattern

```typescript
// WRONG: Direct query without RLS context - LEAKS DATA!
await db.query.users.findMany();
```

### Correct Cognito Claims

```typescript
// Use custom: prefix
const tenantId = claims['custom:tenantId'];
const role = claims['custom:role'];
```

### Wrong Cognito Claims

```typescript
// WRONG: Missing custom: prefix - won't work!
const tenantId = claims.tenantId; // undefined
```

### Correct Tenant Validation

```typescript
// Always validate tenant_id in queries
const user = await tx.query.users.findFirst({
  where: and(
    eq(users.id, userId),
    eq(users.tenant_id, tenantId) // CRITICAL
  ),
});
```

### Wrong Tenant Validation

```typescript
// WRONG: Missing tenant check - DATA LEAK!
const user = await tx.query.users.findFirst({
  where: eq(users.id, userId),
});
```

## Architecture Flow Validation

### Correct Handler Pattern

```typescript
// Handler = HTTP interface only, NO business logic
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

```typescript
// WRONG: Handler with business logic
export const handler = async (event: APIGatewayProxyEvent) => {
  const data = JSON.parse(event.body);

  // WRONG: Business logic in handler
  if (data.age < 18) {
    throw new Error('Must be 18+');
  }

  // WRONG: Direct data access in handler
  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

```typescript
// WRONG: Raw HTML 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>

// CORRECT: Use Title and Text components
<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: 'destructive' }}>Error message</Text>
```

### Buttons

```typescript
// WRONG: Raw button element
<button className="bg-blue-600 text-white px-4 py-2 rounded-md">
  Click me
</button>

// CORRECT: Use Button component
<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

```typescript
// WRONG: Hard-coded colour classes
className="text-gray-900"
className="text-gray-600"
className="text-red-600"
className="bg-blue-50"
className="border-green-200"

// CORRECT: Use theme colours via components
<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

1. **Security first**: Healthcare data = zero tolerance for vulnerabilities
2. **Constructive feedback**: Explain why, show how to fix
3. **Specific examples**: Provide remediation code, not just descriptions
4. **Positive reinforcement**: Acknowledge good practices
5. **Phase 1 context**: Don't over-engineer; ship fast, iterate on feedback
6. **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
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.