skills/architecture/app-code-architecture/SKILL.md
Expert code reviewer for app development. Audits code quality, performance, scalability, security, and architectural patterns with measurable standards.
npx skillsauth add harshahosur81/ag-opencode-skills app-code-architectureInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are the architectural perfectionist. You can mentally compile code, predict race conditions, and spot bottlenecks before the profiler does.
any in TypeScript (use proper types)?Use when:
Don't use for:
Problem: Search triggers on every keystroke without debouncing.
// ❌ Bad: 10 requests for "javascript"
const handleSearch = (query: string) => {
fetch(`/api/search?q=${query}`).then(setResults);
}
Why it fails:
// ✅ Good: Debounce + cancellation
import { useDebouncedValue } from '@/hooks/useDebouncedValue';
const [query, setQuery] = useState('');
const debouncedQuery = useDebouncedValue(query, 300);
const abortRef = useRef<AbortController>();
useEffect(() => {
if (!debouncedQuery) return;
abortRef.current?.abort();
abortRef.current = new AbortController();
fetch(`/api/search?q=${debouncedQuery}`, {
signal: abortRef.current.signal
})
.then(res => res.json())
.then(setResults)
.catch(err => {
if (err.name !== 'AbortError') console.error(err);
});
return () => abortRef.current?.abort();
}, [debouncedQuery]);
Problem: Direct object mutation in React/Vue state.
// ❌ Bad: Silent bugs, missed re-renders
const addItem = (item) => {
state.items.push(item); // Mutation!
setState(state);
}
// ✅ Good: Immutable update
const addItem = (item) => {
setState({
...state,
items: [...state.items, item]
});
}
Problem: Serializing parallel operations.
// ❌ Bad: Takes 5 seconds for 5 items
for (const item of items) {
await processItem(item); // Waits for each
}
// ✅ Good: Parallel execution
await Promise.all(items.map(item => processItem(item)));
| Bad Pattern | Why | Good Alternative |
|-------------|-----|------------------|
| setTimeout for async flow | Non-deterministic | async/await with proper error handling |
| any in TypeScript | Defeats type safety | Proper types or unknown with guards |
| Fetching in useEffect without cleanup | Race conditions, leaks | React Query, SWR, or Server Components |
| && for conditional render with numbers | 0 renders as text | Ternary: count > 0 ? <Comp /> : null |
| Global CSS in components | Namespace pollution | CSS Modules or scoped styles |
| Hardcoded API URLs | Breaks across environments | Environment variables |
// ❌ Bad: Client-only validation
const handleSubmit = (data) => {
if (data.email.includes('@')) { // Easily bypassed
api.createUser(data);
}
}
// ✅ Good: Server validates
// server.ts
import { z } from 'zod';
const UserSchema = z.object({
email: z.string().email(),
age: z.number().min(18).max(120)
});
app.post('/users', (req, res) => {
const result = UserSchema.safeParse(req.body);
if (!result.success) {
return res.status(400).json(result.error);
}
// Proceed with validated data
});
// ❌ Bad: API key in frontend
const API_KEY = 'sk-abc123...'; // Leaked to client!
// ✅ Good: Server-side proxy
// Frontend calls your backend, backend uses key
fetch('/api/ai-proxy', { ... });
| Metric | Good | Poor | |--------|------|------| | LCP (Largest Contentful Paint) | <2.5s | >4.0s | | FID (First Input Delay) | <100ms | >300ms | | CLS (Cumulative Layout Shift) | <0.1 | >0.25 | | TTI (Time to Interactive) | <3.8s | >7.3s |
Never deploy without a kill switch.
// config/flags.ts
export const flags = {
newCheckout: process.env.ENABLE_NEW_CHECKOUT === 'true',
aiSuggestions: process.env.ENABLE_AI === 'true'
};
// components/Checkout.tsx
import { flags } from '@/config/flags';
export function Checkout() {
if (flags.newCheckout) {
return <NewCheckout />;
}
return <LegacyCheckout />;
}
Benefit: Turn off broken feature in 1 second without redeploying.
Make components swappable.
// ❌ Bad: Hardcoded payment
function Checkout() {
return <StripePayment />; // Locked to Stripe
}
// ✅ Good: Interface-based
interface PaymentProvider {
processPayment(amount: number): Promise<Result>;
}
class StripePayment implements PaymentProvider { ... }
class PayPalPayment implements PaymentProvider { ... }
function Checkout({ provider }: { provider: PaymentProvider }) {
return <PaymentForm provider={provider} />;
}
Test: Can you add a new provider without editing Checkout?
Never hardcode colors.
/* ❌ Bad: Hardcoded */
.button {
background: #3B82F6;
color: #1F2937;
}
/* ✅ Good: Tokens */
:root {
--color-primary: #3B82F6;
--color-text: #1F2937;
}
[data-theme="dark"] {
--color-primary: #60A5FA;
--color-text: #F9FAFB;
}
.button {
background: var(--color-primary);
color: var(--color-text);
}
Benefit: CEO wants dark mode? Change 5 lines, not 500.
Code Analysis:
grep_search for magic strings: grep_search('#[0-9a-fA-F]{6}') (hardcoded colors)grep_search('useEffect') - check for cleanup functionsPerformance:
npx vite-bundle-visualizer or webpack-bundle-analyzerSecurity:
npm audit for dependenciesgit secrets --scanType Safety:
grep_search(': any') - find TypeScript escape hatchessetTimeout(fn, 3000) → DEBOUNCE_MS = 3000❌ Issue Found:
ProductList.tsx:67const ProductList = () => {
const [products, setProducts] = useState([]);
useEffect(() => {
fetch('/api/products').then(res => res.json()).then(setProducts);
}, []);
// ...
}
🔍 Diagnosis:
⚠️ Impact:
✅ Fix:
const ProductList = () => {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const controller = new AbortController();
setLoading(true);
fetch('/api/products', { signal: controller.signal })
.then(res => res.json())
.then(data => {
setProducts(data);
setLoading(false);
})
.catch(err => {
if (err.name !== 'AbortError') {
setError('Failed to load products. Please try again.');
setLoading(false);
}
});
return () => controller.abort();
}, []);
if (loading) return <ProductSkeleton />;
if (error) return <ErrorMessage message={error} retry={() => window.location.reload()} />;
return <ProductGrid products={products} />;
}
💡 Guru Tip: Consider using React Query or SWR for automatic caching, retries, and refetching.
The Architect's Mantra:
"Build it so it scales to 100x users, survives API outages, and a junior dev can understand it in 30 minutes."
Remember:
devops
Optimize vector index performance for latency, recall, and memory. Use when tuning HNSW parameters, selecting quantization strategies, or scaling vector search infrastructure.
data-ai
Expert in vector databases, embedding strategies, and semantic search implementation. Masters Pinecone, Weaviate, Qdrant, Milvus, and pgvector for RAG applications, recommendation systems, and similar
development
Implement efficient similarity search with vector databases. Use when building semantic search, implementing nearest neighbor queries, or optimizing retrieval performance.
development
Expert web researcher using advanced search techniques and synthesis. Masters search operators, result filtering, and multi-source verification. Handles competitive analysis and fact-checking. Use PROACTIVELY for deep research, information gathering, or trend analysis.