| name | code-review |
| description | Activates when reviewing code, checking for security issues, or validating best practices.
Use this skill for: security audits, performance reviews, React 19 pattern validation,
TypeScript strict mode compliance, and OWASP vulnerability checks.
Keywords: review, security, performance, audit, OWASP, vulnerability, best practice, lint
|
Code Review Skill
This skill provides guidance for reviewing code quality, security, and best practices in Landbruget.dk.
Activation Context
This skill activates when:
- Reviewing code for security vulnerabilities
- Checking performance patterns
- Validating React 19 best practices
- Ensuring TypeScript strict mode compliance
- Auditing for OWASP top 10 vulnerabilities
Security Checklist (OWASP Top 10)
1. Injection Prevention
SQL Injection:
const { data } = await supabase.rpc('search', { query: `%${userInput}%` });
const { data } = await supabase
.from('table')
.select('*')
.ilike('column', `%${userInput}%`);
Command Injection:
exec(`ls ${userInput}`);
2. XSS Prevention
<div dangerouslySetInnerHTML={{ __html: userContent }} />
<div>{userContent}</div>
import DOMPurify from 'dompurify';
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(content) }} />
3. Sensitive Data Exposure
console_log('User data:', userData);
console_log('User ID:', userData.id);
const apiKey = process.env.SUPABASE_KEY;
const apiKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
4. Authentication Issues
localStorage.setItem('token', authToken);
const { data: { session } } = await supabase.auth.getSession();
5. Access Control
SELECT * FROM sensitive_data;
ALTER TABLE sensitive_data ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can only see own data"
ON sensitive_data FOR SELECT
USING (auth.uid() = user_id);
React 19 Best Practices
Component Patterns
export function FeatureComponent({ data }: Props) {
return <div>{data}</div>;
}
export const FeatureComponent = ({ data }: Props) => <div>{data}</div>;
Server vs Client Components
export default async function Page() {
const data = await fetchData();
return <ClientComponent data={data} />;
}
'use client';
export function Feature() {
const [state, setState] = useState();
return <div onClick={() => setState(...)}>...</div>;
}
Hooks Rules
if (condition) {
useEffect(() => {}, []);
}
useEffect(() => {
if (condition) {
}
}, [condition]);
useEffect(() => {
fetchData(userId);
}, []);
useEffect(() => {
fetchData(userId);
}, [userId]);
Memoization
const filteredData = useMemo(
() => data.filter(item => item.type === filter),
[data, filter]
);
const handleClick = useCallback(
(id: string) => setSelected(id),
[setSelected]
);
const sum = useMemo(() => a + b, [a, b]);
TypeScript Strict Mode
No any Types
function process(data: any) { ... }
interface DataType {
id: string;
value: number;
}
function process(data: DataType) { ... }
function process(data: unknown) {
if (isDataType(data)) { ... }
}
Explicit Return Types
function getData() {
return fetch('/api/data');
}
function getData(): Promise<Response> {
return fetch('/api/data');
}
Null Handling
const value = data!.field;
const value = data?.field ?? defaultValue;
if (data) {
const value = data.field;
}
Performance Patterns
Data Fetching
for (const id of ids) {
const data = await fetch(`/api/${id}`);
}
const results = await Promise.all(
ids.map(id => fetch(`/api/${id}`))
);
List Rendering
{items.map((item, index) => <Item key={index} />)}
{items.map(item => <Item key={item.id} />)}
import { useVirtualizer } from '@tanstack/react-virtual';
Image Optimization
<img src="/large-image.jpg" />
import Image from 'next/image';
<Image
src="/image.jpg"
alt="Description"
width={800}
height={600}
loading="lazy"
/>
Data Pipeline Review (Backend Python)
CRS/Geospatial Checks
CRITICAL: Buffer operations must use metric CRS!
ST_Buffer(geometry, 1000)
from common.crs_utils import sql_buffer_meters
buffer_sql = sql_buffer_meters("geometry", 1000)
Check for these patterns in PR reviews:
ST_Buffer without ST_Transform on EPSG:4326 data = BUG
ST_Distance comparisons with large numbers on degree data = BUG
- Buffer distances > 1 on WGS84 data = likely wrong CRS
DuckDB Spatial Patterns
ST_Intersects(
ST_Transform(geom1, 'EPSG:4326', 'EPSG:25832'),
ST_Buffer(ST_Transform(geom2, 'EPSG:4326', 'EPSG:25832'), 1000)
)
ST_Intersects(geom1, ST_Buffer(geom2, 1000))
Code Review Checklist
Security
Data Pipeline (Backend)
Performance
React 19
TypeScript
Code Quality
Running Automated Checks
cd frontend && npm run build
cd frontend && npm run lint
cd frontend && npm run lint && npm run build && npm test
Note: This project uses oxlint (50-100x faster than ESLint) with default configuration. No .oxlintrc.json file is needed.