| Category | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| Language | TypeScript 5 (strict mode) |
| Styling | Tailwind CSS v4 + shadcn/ui components |
| Forms | React Hook Form + Zod validation |
| Database | IndexedDB (via idb library) |
| Tables | TanStack Table |
| Testing | Vitest (unit) + Playwright (E2E) |
| Optional | Upstash Redis (rate limiting in production) |
- API Key Encryption: AES-GCM with PBKDF2-derived keys (600k iterations)
- Rate Limiting: In-memory (default) or Upstash Redis (production)
- API Authentication: Bearer token validation with constant-time comparison
- CSRF Protection: Origin/Referer header validation
- Input Validation: Zod schemas for all user inputs
- CSP Headers: Content-Security-Policy with 'unsafe-inline' for Next.js/Tailwind compatibility
- CSV Sanitization: Formula injection protection
- Set
API_ROUTE_SECRET— Generate withopenssl rand -hex 32 - Set
NEXT_PUBLIC_SITE_URL— Your production domain - Enable HTTPS — Required for CSP
upgrade-insecure-requests - Configure Upstash — For distributed rate limiting (optional)
- Review CSP — Adjust if adding new external resources
| Protection | Status |
|---|---|
| API keys encrypted before storage | ✅ |
| Rate limiting on import endpoint | ✅ |
| CSRF protection on state-changing APIs | ✅ |
| Input validation on all user inputs | ✅ |
| CSV formula injection prevented | ✅ |
| No data leaves the browser (local IndexedDB) | ✅ |
| Limitation | Note |
|---|---|
| Client-side data is not encrypted | IndexedDB is accessible via DevTools |
| No server-side authentication | Local-first design |
| No backup/recovery | Export your data regularly |