A full-stack web application for an appliance repair service (fridges, washing machines, ovens, water heaters). Features a React/Next.js frontend consuming a secured Flask REST API backend, deployed separately on Railway.
┌─────────────────────────┐ ┌──────────────────────────┐
│ Frontend │ │ Backend │
│ Next.js 14 │◄──────►│ Flask REST API │
│ TypeScript │ HTTPS │ JWT Auth │
│ TailwindCSS │ CORS │ SQLAlchemy │
│ Railway │ │ Railway │
└─────────────────────────┘ └──────────────────────────┘
- Service catalog — browsable by appliance category (fridges, washers, ovens, water heaters)
- Repair request submission — validated multi-field form with phone regex, length constraints
- Price list — per-category pricing, sorted display
- Customer reviews — active reviews feed, capped at 50
- Admin panel — JWT-authenticated CRUD for services, prices, reviews, site content
- Push notifications — new repair request alerts to admin
- JWT authentication —
flask-jwt-extendedfor all admin API routes - Brute-force protection — IP-based login rate limiter: max 5 attempts per 5-minute window, then HTTP 429
- Request rate limiting — repair request submissions limited to 3/minute per IP
- Input validation —
marshmallowschema with strict field types, length limits, phone regex - Input sanitization —
bleach.clean()on all user-submitted text fields - CORS — origin allowlist via
ALLOWED_ORIGINSenv var, restricted to/api/*routes - Payload size limit — hard 1MB cap (
MAX_CONTENT_LENGTH+before_requestcheck → HTTP 413) - Security headers applied globally on every response:
Content-Security-PolicyStrict-Transport-Security(HSTS, 1 year)X-Frame-Options: DENYX-Content-Type-Options: nosniffReferrer-Policy: strict-origin-when-cross-originPermissions-PolicyX-Permitted-Cross-Domain-Policies: noneCache-Control: no-store(prevents sensitive data caching)
- Environment-based API URL configuration (
.env.example) - No secrets or tokens in client-side code
| Layer | Technology |
|---|---|
| Frontend | Next.js 14, TypeScript, TailwindCSS |
| Backend | Flask, SQLAlchemy, Flask-JWT-Extended |
| Validation | marshmallow, bleach |
| Auth | JWT (access tokens) |
| Notifications | Custom notifications.py |
| Deployment | Railway (separate frontend + backend services) |
gmaster/
├── backend/
│ ├── app.py ← Flask API routes + security middleware
│ ├── models.py ← SQLAlchemy models
│ ├── config.py ← environment config
│ ├── notifications.py ← admin alert system
│ ├── requirements.txt
│ └── railway.toml
└── frontend/
├── src/ ← Next.js pages and components
├── public/
├── tailwind.config.ts
└── railway.toml
Backend:
cd backend
pip install -r requirements.txt
cp .env.example .env # fill in values
flask runFrontend:
cd frontend
npm install
cp .env.example .env.local # set NEXT_PUBLIC_API_URL
npm run dev# backend/.env
SECRET_KEY=
JWT_SECRET_KEY=
DATABASE_URL=
ALLOWED_ORIGINS=https://yourdomain.com
# frontend/.env.local
NEXT_PUBLIC_API_URL=https://your-backend.railway.app