name: stem-service-hardening description: Production-harden Shothik AI services for STEM researchers. Use when auditing, fixing, or building any tool service (AI Detector, Paraphrase, Humanize GPT, etc.) to ensure reliability, proper error handling, and STEM content awareness.
STEM Service Hardening Skill
Systematic production hardening playbook for Shothik AI services. Apply when working on any of the 12 services.
Pre-Hardening Audit Checklist
1. Console Error Scan
Search for broken console.log artifacts — a known pattern across the codebase:
# Find broken console statements (missing function calls)
grep -n "console\.\(log\|warn\|error\)" <file> | head -20
Common broken patterns to fix:
console.log(followed by object property syntax withoutconsole.log(- Orphaned
)on next lines - Debug logging left in production code
Fix: Remove all debug console.log statements. Keep only console.error for genuine error paths.
2. API Timeout Handling
Every API call MUST have:
- AbortController with 5-minute timeout
- AbortSignal passed to the request
- Cleanup on component unmount
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 300000); // 5 min
try {
const response = await api.post(endpoint, payload, { signal: controller.signal });
} finally {
clearTimeout(timeoutId);
}
3. Error Message Standards
- NEVER expose raw API error messages to users
- Map technical errors to user-friendly messages
- Use toast notifications for transient errors
- Use
role="alert"components for persistent errors
Error mapping pattern:
const error = err?.data;
if (/LIMIT_REQUEST|PACAKGE_EXPIRED/.test(error?.error)) {
dispatch(setShowAlert(true));
dispatch(setAlertMessage(error?.message));
} else if (error?.error === "UNAUTHORIZED") {
dispatch(setShowLoginModal(true));
} else {
toast.error(error?.message || "Something went wrong. Please try again.");
}
4. Event Tracking
- Verify
trackEventcalls use correct service name (not another service's name) - Pattern:
trackEvent("click", "<service-name>", "<service-name>_click", 1)
STEM Preprocessing Integration
When to Apply
Add STEM preprocessing to any service that processes user text where LaTeX/code content could cause issues:
- AI Detector (false positives on technical writing)
- Paraphrase (preserve formulas)
- Humanize GPT (don't alter code blocks)
How to Integrate
import { preprocessText } from '@/services/stemPreprocessor';
// In the component
const preprocessResult = useMemo(() => {
return preprocessText(inputText, {
detectLatex: excludeLatex,
detectCode: excludeCode,
stripReferences: excludeReferences,
stripQuotes: excludeQuotes,
});
}, [inputText, excludeLatex, excludeCode, excludeReferences, excludeQuotes]);
// Send preprocessResult.processedText to API instead of raw text
Key Files
src/services/stemPreprocessor.ts— Core preprocessing logicsrc/services/citationDetector.ts— Citation pattern detectionsrc/hooks/useCitationAnalysis.ts— Citation analysis hook
Service-Specific Patterns
Redux Integration
Each service typically has:
- RTK Query mutations in
src/redux/api/tools/toolsApi - A Redux slice in
src/redux/slices/ - Service functions in
src/services/
Session Storage Pattern
Some services use sessionStorage for cross-page content passing:
sessionStorage.setItem("ai-detect-content", JSON.stringify(text));
router.push("/ai-detector");
Word/Character Limits
- Use
useWordLimit(serviceName)hook for package-based limits - Show
UsesLimitBarcomponent when no input present - Validate minimum character counts before submission
Post-Hardening Verification
- Page loads without console errors
- API calls have timeout handling
- Error messages are user-friendly
- No debug logging in production paths
- Event tracking uses correct service name
- Loading states show proper feedback
- Component unmount cleans up resources