Skip to content

v1.0.0: Angular portfolio

Choose a tag to compare

@kamycoding kamycoding released this 08 Nov 23:00
· 121 commits to main since this release
89cb842

Overview

First stable release of kamycoding.com, the personal portfolio of Kamyar Zamanfar. This version is built with Angular and deployed on Netlify. It serves as the baseline before the v2 redesign.

Features

  • Single-page portfolio with hero, projects, experience, skills and contact sections
  • Internationalization in English and German, switchable at runtime
  • Contact form with validation on the client and on the server
  • Legal pages: legal notice (/legal-notice) and privacy policy (/privacy-policy)
  • Responsive layout for mobile, tablet and desktop

Contact form and backend

  • Serverless endpoint POST /api/contact running as a Netlify Function
  • Transactional email delivery through the Brevo API, with the sender set as reply-to
  • Strict request validation with a zod schema; unknown fields are rejected
  • Typed environment configuration, validated at startup
  • 15 second timeout on outgoing requests, with network, timeout and provider errors handled separately
  • Logs contain allow-listed diagnostics only, never API keys or personal data

Security and privacy

  • Rate limiting: 5 requests per 3 minutes per IP
  • Honeypot field against automated spam
  • No tracking, analytics or third-party scripts

Quality

  • Unit tests for the contact function with Vitest (success, validation, honeypot, provider errors, network errors, timeout, method handling, rate limit config)

Tech stack

Angular, TypeScript, SCSS, Netlify Functions, Brevo, zod, Vitest

Getting started

Requirements: Node.js 24 and npm.

git clone https://github.com/kamycoding/portfolio.git
cd portfolio
git checkout v1.0.0
npm ci
npm start

The app runs at http://localhost:4200.

What's next

v2 is in development on the redesign/v2 branch: a full redesign built with Next.js, React and TypeScript.

Full history: https://github.com/kamycoding/portfolio/commits/v1.0.0