A production-ready, full-stack personal portfolio and headless CMS β built entirely from scratch. No WordPress. No templates. Just pure code.
- Added admin-managed Home Media controls: upload profile photo (Cloudinary), upload intro video, and toggle video visibility.
- Added Blog cover image upload support from admin, with rendering on blog list and blog detail pages.
- Enabled Skills icon rendering on home page using React Icons names (Fa*/Si*) or direct image URLs.
- Added daily message digest email and instant security log alert emails.
- Added admin Forgot Password flow with secure reset key validation.
- Upgraded Skills Manager: choosing
Othernow reveals a required details textarea. - Fixed public Projects page loading issue caused by API response shape mismatch.
- Simplified Projects discovery UX: removed text search and kept focused filters by Tech Stack and Language.
- Expanded Home page with featured projects, latest writing, capabilities section, and stronger portfolio storytelling.
- Applied a full visual refresh with a new global color language, glass-surface cards, and updated shared components.
- Resume/Drive CV links are handled as external links and always open in a new browser tab.
This is not just a static portfolio. It is a complete full-stack web application split into two main parts:
| Part | Tech | Description |
|---|---|---|
portfolio-frontend |
Next.js 16 + React 19 | A blazing-fast UI with an interactive hacker-mode terminal, custom cursor, magnetic buttons, and a hidden admin panel |
portfolio-api |
Node.js + Express | A secure REST API server with JWT auth, MongoDB storage, Cloudinary image hosting, and layered security middleware |
This application uses a modern decoupled architecture. The frontend and backend run as separate entities but communicate securely.
To protect the server from being exposed to the public internet, the Next.js frontend acts as a Reverse Proxy via next.config.mjs. All /api/* traffic is silently forwarded to the Express backend β the real server URL is never visible to the browser.
sequenceDiagram
participant User as π» User (Browser)
participant NextJS as π Next.js (Frontend)
participant NextProxy as π‘οΈ API Proxy (next.config.mjs)
participant Express as βοΈ Express (Backend API)
participant DB as ποΈ MongoDB / Cloudinary
User->>NextJS: 1. Visits Portfolio / Clicks a Project
NextJS->>NextProxy: 2. Fetches Data (/api/projects)
Note over NextProxy: Real backend URL stays hidden
NextProxy->>Express: 3. Forwards Request (http://localhost:5000)
Express->>DB: 4. Queries Database / Storage
DB-->>Express: 5. Returns Data / Image URL
Express-->>NextProxy: 6. Sends JSON Response
NextProxy-->>NextJS: 7. Relays to Frontend
NextJS-->>User: 8. Renders UI
π¦ portfolio-2.0/
β£ π portfolio-frontend/ π Next.js UI Application
β β£ π src/
β β β£ π app/ π Next.js App Router pages
β β β β£ π page.js π Home β hero, skills matrix, education timeline
β β β β£ π layout.js π Root layout (CustomCursor, HackerMode, Footer)
β β β β£ π projects/ π /projects β filterable project showcase
β β β β£ π blogs/ π /blogs β article listing
β β β β β π [slug]/ π /blogs/:slug β individual blog post
β β β β£ π contact/ π /contact β guest message form
β β β β£ π diary/ π /diary β private diary entries
β β β β π admin/ π /admin β login gate
β β β β π dashboard/ π /admin/dashboard β full CMS
β β β π components/
β β β£ π navbar.js π Top navigation bar
β β β£ π Footer.js π Site footer
β β β£ π HackerMode.js π Ctrl+\ terminal overlay
β β β£ π CustomCursor.js π Custom animated cursor
β β β£ π MagneticButton.js π Magnetic hover-effect button
β β β π admin/ π CMS panel components
β β β£ π BlogManager.js
β β β£ π DiaryManager.js
β β β£ π EducationManager.js
β β β£ π MessageManager.js
β β β£ π ProjectManager.js
β β β£ π SecurityManager.js
β β β£ π SettingsManager.js
β β β π SkillManager.js
β β£ π next.config.mjs π Reverse proxy rewrite rules
β β π .env π Frontend env variables (gitignored)
β
β π portfolio-api/ π Node.js / Express Backend
β£ π config/ π DB (Mongoose) & Cloudinary setup
β£ π controllers/ π Business logic per resource
β£ π middleware/
β β£ π authMiddleware.js π JWT verification guard
β β π honeypot.js π Bot trap & IP logger
β£ π models/ π Mongoose schemas
β β£ π Admin.js
β β£ π Blog.js
β β£ π Diary.js
β β£ π Education.js
β β£ π Message.js
β β£ π Project.js
β β£ π SecurityLog.js
β β£ π Setting.js
β β π Skill.js
β£ π routes/ π Express route definitions
β£ π seedAdmin.js π One-time admin account seeder
β π server.js π App entry point & security middleware stack
Accessible at /admin β protected behind JWT authentication. Once logged in, you get full CRUD control over every piece of content via dedicated manager panels:
| Manager | What you can control |
|---|---|
| ProjectManager | Add / edit / delete portfolio projects with images, tech stack tags, GitHub & live links |
| BlogManager | Write Markdown blogs with AI-generated 3-point summaries, tags, read-time, and cover image uploads |
| DiaryManager | Create private diary entries (visibility-toggled) |
| EducationManager | Manage education timeline entries |
| SkillManager | Add skills with proficiency percentages and optional custom details for Other category |
| MessageManager | Read contact messages sent by visitors |
| SecurityManager | View the honeypot security log β trapped IPs & attempted endpoints |
| SettingsManager | Edit hero text, primary accent color, social links, resume URL, hiring status, profile image, and home video visibility |
A custom honeypot.js middleware silently guards the server from automated scanners:
- Trap routes monitored:
/wp-admin,/.env,/admin.php,/config.json,/db-backup.zip - On hit: The attacker's IP, the attempted endpoint, and any request payload are saved to the
SecurityLogcollection in MongoDB, and a403response is returned. - Logs are viewable in real time from the SecurityManager panel inside the admin dashboard.
The Express server (server.js) applies 10 security layers before any route handler runs:
| # | Middleware | Protection |
|---|---|---|
| 1 | helmet |
Secure HTTP headers (XSS, clickjacking, MIME sniffing, etc.) |
| 2 | cors |
Strict allow-list β only your frontend origins can call the API |
| 3 | express.json({ limit: '10kb' }) |
Payload size cap β prevents oversized body attacks |
| 4 | express-mongo-sanitize |
Strips $ operators β blocks NoSQL injection |
| 5 | xss-clean |
Sanitises HTML in input β blocks Cross-Site Scripting |
| 6 | hpp |
Strips duplicate query params β blocks HTTP Parameter Pollution |
| 7 | Global rate limiter | 20 requests / 15 min per IP across all /api/ routes |
| 8 | Contact rate limiter | 5 messages / hour per IP on /api/messages |
| 9 | Auth rate limiter | 10 login attempts / 15 min per IP on /api/auth |
| 10 | Custom Honeypot | Traps & logs bots scanning for known vulnerability paths |
next.config.mjs rewrites every /api/* request to the Express server at INTERNAL_BACKEND_URL. The real backend address is never exposed to the browser.
Press Ctrl + \ anywhere on the site to open a full Linux-style terminal overlay (HackerMode.js). Supported commands:
help Show available commands
ls List virtual directories (projects/, skills/, education/)
cat <dir> Fetch live data from the API and print it
sudo login Redirect to the /admin login portal
game / hack Launch an in-terminal cybersecurity mini-game
clear Clear terminal output
exit Close the terminal
- Custom Cursor (
CustomCursor.js) β replaces the default browser cursor with a styled animated dot. - Magnetic Buttons (
MagneticButton.js) β interactive Framer Motion buttons that follow the cursor on hover. - Skills Matrix β live-fetched proficiency bars rendered on the home page.
- Skills Icons β rendered from React Icons names (Fa*/Si*) or direct image URLs stored in admin.
- Education Timeline β chronological timeline built from the
Educationcollection. - Blog Posts β Markdown-rendered articles with slug-based routing (
/blogs/:slug), tags, read time, AI-generated TL;DR summaries, and cover images. - Project Cards β filterable by tech stack and language, grayscale-to-color image reveal on hover, and links to GitHub / live demo.
- Home Experience β richer hero storytelling, project and skill highlights, admin-managed profile image, optional intro video, and explicit public notice of the private admin portal.
| Technology | Version | Role |
|---|---|---|
| Next.js | 16.2.1 | Framework β App Router, SSR, API rewrites |
| React | 19.2.4 | UI library |
| React Icons | ^5.6 | Skill icon rendering from icon names |
| Tailwind CSS | v4 | Utility-first styling |
| Framer Motion | v12 | Animations & magnetic button interactions |
| Technology | Version | Role |
|---|---|---|
| Node.js | v18+ | Runtime environment |
| Express | ^4.22 | REST API framework |
| Mongoose | ^9.3 | MongoDB ODM |
| bcrypt | ^6.0 | Password hashing |
| jsonwebtoken | ^9.0 | JWT authentication |
| Cloudinary | ^1.41 | Image upload & hosting |
| Multer + multer-storage-cloudinary | ^2.1 | Multipart file handling |
| Helmet | ^8.1 | Secure HTTP headers |
| express-rate-limit | ^8.3 | API rate limiting |
| express-mongo-sanitize | ^2.2 | NoSQL injection prevention |
| xss-clean | ^0.1 | XSS input sanitisation |
| hpp | ^0.2 | HTTP Parameter Pollution prevention |
| express-validator | ^7.3 | Input validation |
| nodemailer | ^8.0 | SMTP mail delivery (digest + alerts) |
| node-cron | ^4.2 | Daily scheduler for message digest |
| dotenv | ^17.3 | Environment variable loading |
| cors | ^2.8 | Cross-Origin Resource Sharing |
In the Skills Manager, the Icon field stores a string value (example: FaReact) or a direct image URL.
Current behavior:
- Icon values are saved in the database.
- Public skills cards render icons from React Icons names or image URLs.
- This reference helps you enter consistent icon names now, so you can render them later without cleanup.
Use these names in the Icon field.
- FaReact
- SiNextdotjs
- SiJavascript
- SiTypescript
- SiHtml5
- SiCss3
- SiTailwindcss
- SiRedux
- SiFramer
- SiVite
- FaNodeJs
- SiExpress
- SiNestjs
- SiDjango
- SiFlask
- FaJava
- SiSpring
- SiDotnet
- SiGraphql
- SiSocketdotio
- SiMongodb
- SiPostgresql
- SiMysql
- SiRedis
- SiFirebase
- SiSupabase
- SiSqlite
- SiPrisma
- SiMongoose
- FaDocker
- SiKubernetes
- FaAws
- SiGooglecloud
- SiVercel
- SiNetlify
- SiRender
- SiGithubactions
- SiNginx
- SiCloudinary
- FaGitAlt
- FaGithub
- SiPostman
- SiInsomnia
- SiJest
- SiCypress
- SiWebpack
- SiBabel
- SiEslint
- SiPrettier
- SiFigma
- SiNotion
- SiSlack
- SiLinux
- Open the React Icons website:
- Search your technology name (example: Docker, PostgreSQL, Tailwind).
- Copy the exact component name shown by the website (example: FaDocker, SiPostgresql).
- Paste that exact name into Admin -> Skills -> Icon field.
Notes:
- Prefix guide: Fa = Font Awesome, Si = Simple Icons, Io = Ionicons, Tb = Tabler, etc.
- Names are case-sensitive.
- If you cannot find a good icon, you can paste a direct image URL instead.
- If multiple icons exist, prefer the official brand icon from the Si set.
- Pick one skill.
- Enter icon name from React Icons.
- Save and verify in admin data.
- Repeat for other skills.
If you want, I can also add a live icon preview in the Skills Manager so you can test icon names instantly while typing.
This section explains the whole app in simple language, from user click to database response.
No separate ARCHITECTURE.md file is currently used.
All architecture and internal behavior documentation is maintained in this README.md (this section + deep-dive section below), so you can find everything in one place.
Think of this project as two apps working together:
- Frontend app (
portfolio-frontend): what users see in the browser. - Backend app (
portfolio-api): where data, auth, security checks, and business logic run.
When someone opens Projects page:
- Browser asks frontend page to load.
- Frontend requests project data from API endpoint.
- Backend receives request and runs security middleware first.
- Backend controller reads projects from MongoDB.
- JSON response goes back to frontend.
- Frontend renders cards on screen.
- Admin logs in with username/password.
- Backend verifies credentials and issues secure auth token cookie.
- Admin dashboard loads manager components (projects/blogs/skills/etc.).
- Each manager can create, edit, delete records via protected API routes.
Contact form is protected by multiple layers:
- Honeypot bot trap field.
- Captcha verification.
- Rate limiting.
- Input validation and sanitization.
- Security event logging.
If suspicious activity is detected, security log entries are created and alert flows can notify admin.
- Admin selects image/video in dashboard.
- File is uploaded through backend upload route.
- Backend stores file in Cloudinary.
- Cloudinary URL is saved in MongoDB.
- Frontend uses stored URL for rendering.
This README intentionally explains architecture and security strategy but does not include real secrets.
Never place real values for:
- JWT secret
- DB credentials
- SMTP password
- reset/admin private keys
Use .env placeholders only.
This section is intentionally detailed so you can understand exactly how each part behaves, how data moves, and where security is enforced.
When a user opens a page:
- Next.js renders the route (server or client side depending on page).
- UI components call API endpoints (through
/api/*path from browser). - Next.js rewrites/proxies those requests to Express backend.
- Express middleware stack executes first (security, parsers, sanitizers, rate limits, honeypot).
- Route handler runs controller logic.
- Controller reads/writes MongoDB through Mongoose models.
- Response comes back as JSON and components render data.
Important: security controls are not in one place only. They are distributed in middleware, controllers, model hooks, validators, and route-level protections.
-
src/app/page.js(Home):- Fetches settings, skills, education, projects, blogs.
- Builds hero section, feature cards, skill matrix, and education timeline.
- Uses server-side fetching for fast first render.
-
src/app/projects/page.js:- Fetches project list.
- Supports filter by tech stack and language.
- Splits output into
ongoingandcompletedgroups usingproject.statusfirst and fallback logic if old records exist.
-
src/app/blogs/page.js:- Lists blogs with card metadata and tags.
- Includes social share actions (X, LinkedIn, WhatsApp, Facebook) and copy-link with visible feedback state.
-
src/app/blogs/[slug]/page.js:- Fetches one blog by slug.
- Renders markdown using
react-markdown+remark-gfm. - Provides GitHub-style content styling and share actions.
- Shows
AI Summaryblock if present.
-
src/app/contact/page.js:- Handles visitor message submission.
- Requests captcha payload first, then posts message + captcha verification fields.
- Works with honeypot protection and backend validation.
-
src/app/diary/page.js:- Shows diary entries with timeline/date-time format.
-
src/app/admin/*:- Admin login and dashboard.
- Dashboard loads manager modules for all content collections.
-
navbar.jsandFooter.js:- Fetch settings to show dynamic status/social links/colors.
- Includes robust API URL normalization to avoid wrong endpoint shape.
-
HackerMode.js:- Terminal-like command overlay.
- Provides interactive command simulation and admin shortcut.
-
CustomCursor.js:- Custom pointer effect for stronger visual identity.
-
MagneticButton.js:- Motion-based hover attraction effect for CTA elements.
Each manager implements a similar pattern:
- Fetch list on mount.
- Provide form state for create/edit.
- On submit, call
POSTfor create orPUTfor update. - Use
credentials: includeon protected routes. - Refresh list after changes.
Manager-specific responsibilities:
ProjectManager: ordering, visibility, status (ongoing/completed), image upload, tech parsing.BlogManager: markdown content, tags, slug, read-time, cover image.DiaryManager: dev logs with status and visibility.EducationManager: timeline + extended metadata fields.SkillManager: percentage/category/details/icon.SettingsManager: site text/colors/social/profile media/home video.MessageManager: inbox viewer for contact messages.SecurityManager: security event log viewer.
Routes in portfolio-api/routes are thin and map endpoints to controller functions. Protected mutations (POST/PUT/DELETE) are guarded by protect middleware where needed.
authController: login/logout/session check + forgot/reset password operations.projectController: public/admin project read and admin CRUD with normalized status + custom ordering.blogController: blog CRUD and slug-based fetch.diaryController: diary CRUD.educationController: education CRUD.skillController: skills CRUD.settingController: singleton-style site settings document read/update.messageController: contact intake, captcha endpoint/verification, logging and message persistence.securityController: read security logs.
Controllers do business rules and response shaping. Models define schema constraints and data lifecycle hooks.
Admin: credentials and auth-related fields.Project: title/description/status/order/visibility/tech links/media.Blog: markdown content, slug, tags, cover image, aiSummary, publish state.Diary: timeline entries and visibility.Education: institution, degree, dates + extra metadata (location,specialization,boardOrUniversity,score,activities).Skill: name/category/percentage/icon/details.Setting: global site-level configurable values.Message: contact submissions.SecurityLog: detected suspicious actions/events.
Security is intentionally layered so one bypass does not compromise the entire app.
Before controller logic, Express applies:
- Header hardening with
helmet. - CORS allow-list checks.
- JSON body size limits.
- NoSQL injection sanitization.
- XSS cleaning.
- HTTP parameter pollution mitigation.
- Global rate limiter.
- Route-specific limiters for auth/messages/captcha-sensitive flows.
- Honeypot detection for suspicious scanner routes.
- Admin login uses hashed password verification.
- Protected routes require auth middleware.
- Session/token validation occurs before protected controller execution.
- Auth rate limits reduce brute-force risk.
- Honeypot field traps bot submissions.
- Captcha verification includes expiry and anti-replay behavior.
- Input validation + escaping runs server-side.
- Message submission rate limiting prevents abuse/spam bursts.
- Security events are written to
SecurityLog. - Alert emails can be triggered for critical/suspicious events.
- Daily digest summarizes contact events.
- Security manager in admin provides visibility for incident review.
- Never commit
.envfiles. - Use strong
JWT_SECRETand rotate if exposed. - Use app passwords for SMTP providers.
- Restrict allowed CORS origins to your frontend domain.
- Run backend behind HTTPS in production.
statusis stored asongoingorcompleted.orderdetermines rendered sequence.- Admin can reorder items and set status explicitly.
- Public projects page uses status-first grouping with backward-compatible fallback for old records.
- Blog content is stored as raw markdown in DB.
- Detail page renders markdown using
react-markdownwithremark-gfm. - Custom render components style headings, tables, code blocks, links, lists, and blockquotes.
- Share links are generated per blog URL.
- Each platform uses its official URL-based share endpoint.
- Copy-link action uses clipboard API and temporary UI confirmation.
- Admin selects file in manager form.
- Frontend uploads file to upload endpoint as
FormData. - Backend uploads to Cloudinary.
- Cloudinary URL is returned.
- URL is saved in relevant document (project/blog/settings).
-
Status not changing:
- Confirm backend restarted after controller/model changes.
- Verify admin
PUT /api/projects/:idpayload includesstatus.
-
Settings not loading in navbar/footer:
- Verify
NEXT_PUBLIC_API_URLshape (/apivs full host). - Confirm settings endpoint returns JSON, not HTML.
- Verify
-
Email not delivered:
- Verify SMTP env values and app password.
- Check backend logs for transporter/auth/network errors.
-
Share links not opening:
- Ensure direct anchor-based share links are used.
- Confirm
window.location.originor site URL resolves correctly.
When you modify this project, always think in this order:
- Input safety (validation/sanitization).
- Access control (is this route protected?).
- Abuse control (rate limit/honeypot/captcha).
- Data integrity (schema validation/defaults).
- Audit visibility (security logs/alerts).
- User feedback (clear but non-sensitive errors).
If you follow this order, you can add features without weakening the system.
- Node.js v18 or higher
- A MongoDB URI (local or MongoDB Atlas)
- A Cloudinary account for image hosting
Open two terminal windows β one for the backend, one for the frontend.
Terminal 1 β Backend:
cd portfolio-api
npm installTerminal 2 β Frontend:
cd portfolio-frontend
npm installportfolio-api/.env
PORT=5000
MONGO_URI=your_mongodb_connection_string
JWT_SECRET=your_super_secret_key
ADMIN_RESET_KEY=your_private_admin_reset_key
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
FRONTEND_URL=http://localhost:3000
# Alert destination email
ALERT_EMAIL_TO=your_alert_email@example.com
# SMTP settings (example shown for Gmail)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your_gmail_address@gmail.com
SMTP_PASS=your_gmail_app_password
SMTP_FROM=your_gmail_address@gmail.com
# SMTP network reliability options (recommended for servers with IPv6 issues)
SMTP_FORCE_IPV4=true
SMTP_DNS_RESULT_ORDER=ipv4first
SMTP_CONNECTION_TIMEOUT_MS=20000
SMTP_GREETING_TIMEOUT_MS=15000
SMTP_SOCKET_TIMEOUT_MS=30000
# Daily message digest schedule (11:55 PM every day, before 12:00 AM)
DAILY_MESSAGE_DIGEST_CRON=55 23 * * *
DAILY_MESSAGE_DIGEST_TIMEZONE=Asia/Kolkataportfolio-frontend/.env
# Internal URL the Next.js server uses to call the backend directly
INTERNAL_BACKEND_URL=http://localhost:5000
# Public base path used by client-side fetches (triggers the proxy)
NEXT_PUBLIC_API_URL=/apiFollow this once to make sure daily digest + instant security emails work:
- Use a real SMTP account in
portfolio-api/.env. - If you use Gmail, enable 2-Step Verification.
- Generate a Gmail App Password and use it as
SMTP_PASS. - Keep
ALERT_EMAIL_TO=narayanpaulnitdgp@gmail.com. - Restart backend after env updates.
What gets emailed:
- Daily digest before midnight if new contact messages arrived that day.
- Instant alert whenever a new security log is created.
DAILY_MESSAGE_DIGEST_CRON uses 5 fields:
minute hour day-of-month month day-of-week
Examples:
55 23 * * *β Every day at 11:55 PM50 23 * * *β Every day at 11:50 PM0 0 * * *β Every day at 12:00 AM
Recommended value for your requirement (before 12:00 AM):
DAILY_MESSAGE_DIGEST_CRON=55 23 * * *
Timezone is controlled by:
DAILY_MESSAGE_DIGEST_TIMEZONE=Asia/Kolkata
cd portfolio-api
node seedAdmin.jsThis creates the initial admin user in MongoDB.
Start the Backend:
cd portfolio-api
node server.js
# Expected: "Secure Server locked and loaded on port 5000"Start the Frontend:
cd portfolio-frontend
npm run dev
# Expected: "ready on http://localhost:3000"π Open http://localhost:3000 in your browser. To access the admin dashboard, navigate to /admin or press Ctrl + \ and type sudo login.
All endpoints are prefixed with
/apiβ via the Next.js proxy, or directly on port5000. π = RequiresAuthorization: Bearer <token>header.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/auth/login |
Authenticate admin and set secure session cookie |
POST |
/api/auth/logout |
Clear secure admin session cookie |
GET |
/api/auth/session |
π Verify active admin session |
POST |
/api/auth/forgot-password/request-token |
Request one-time reset token using username + server reset key |
POST |
/api/auth/forgot-password/reset |
Reset password using username + one-time token + new password |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/projects |
Fetch all visible projects |
POST |
/api/projects |
π Create a new project |
PUT |
/api/projects/:id |
π Update a project |
DELETE |
/api/projects/:id |
π Delete a project |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/blogs |
Fetch all published blogs |
GET |
/api/blogs/:slug |
Fetch a single blog by slug |
POST |
/api/blogs |
π Create a blog post |
PUT |
/api/blogs/:id |
π Update a blog post |
DELETE |
/api/blogs/:id |
π Delete a blog post |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/diary |
π Fetch all diary entries |
POST |
/api/diary |
π Create a diary entry |
PUT |
/api/diary/:id |
π Update a diary entry |
DELETE |
/api/diary/:id |
π Delete a diary entry |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/messages |
Submit a contact message (rate-limited: 5/hr) |
GET |
/api/messages |
π Read all inbox messages |
DELETE |
/api/messages/:id |
π Delete a message |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/skills |
Fetch all skills |
POST |
/api/skills |
π Add a skill |
PUT |
/api/skills/:id |
π Update a skill |
DELETE |
/api/skills/:id |
π Delete a skill |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/education |
Fetch all education entries |
POST |
/api/education |
π Add an education entry |
PUT |
/api/education/:id |
π Update an entry |
DELETE |
/api/education/:id |
π Delete an entry |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/settings |
Fetch global site settings |
PUT |
/api/settings |
π Update site settings |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/upload |
π Upload an image to Cloudinary |
POST |
/api/upload/video |
π Upload a video to Cloudinary |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/security/logs |
π View all honeypot-captured bot logs |
Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
Built with β€οΈ to showcase Full-Stack Architecture, Security Engineering, and UI Design.