Skip to content
ShramkowebPublic

Latest commit

 

History

1,086 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

shramko.dev

Portfolio · blog · digital garden

Visit the site →

CI Lighthouse CI Maintainability Test Coverage License: MIT

My personal site: long-form posts, a copy-paste snippet library, and the notes-in-public part of a digital garden. One Next.js app, one deployment target, no CMS — content is MDX in the repo, so a post ships through the same pipeline as a code change.

What's inside

Area Notes
Blog MDX posts with category pages, reading time, a table of contents and Shiki-highlighted code
Snippets Short copy-paste MDX snippets under /snippets
Garden pages /bookmarks, /learning, /gear — curated lists that get edited rather than versioned as posts
Dashboard /dashboard aggregates total page views (Postgres) and GitHub stars/followers behind one cached API route
Engagement Per-slug view counter and heart / beer / trophy reactions, both backed by Prisma + Postgres
Social images OG images rendered by @vercel/og at /api/og
Syndication RSS at /feed.xml, sitemap generated by next-sitemap, JSON-LD on content pages
AI readability Hand-maintained llms.txt / llms-full.txt for assistants that are welcome
Side projects Landing pages for my browser extensions

Tech Stack

Layer Tools
Framework Next.js (Pages Router), React
Language TypeScript (strict)
Styling Tailwind CSS, @tailwindcss/typography, next-themes for dark mode
Content MDX via next-mdx-remote, Shiki for syntax highlighting, gray-matter
Data Prisma with @prisma/adapter-pg, Postgres (Neon in production)
State / Fetch SWR
Monitoring Sentry, Checkly, UptimeRobot, Vercel Analytics
Testing Jest, Testing Library, Playwright (Chromium)
Tooling oxlint, oxfmt, commitlint, Renovate, pnpm
Hosting Vercel

Versions are pinned in package.json.

Getting Started

Prerequisites

  • Node, at the version in .nvmrc
  • pnpm — the exact version is pinned in the packageManager field of package.json; corepack picks it up automatically
  • Postgres database (local or hosted, e.g. Neon) — only needed for the view counter, reactions and dashboard

Setup

git clone https://github.com/Shramkoweb/Portfolio.git
cd Portfolio
pnpm install          # postinstall runs `prisma generate`
cp .env.example .env
pnpm dev

App runs at http://localhost:3000.

Every variable is documented inline in .env.example, including where to obtain it. None are required to browse the site locally — DATABASE_URL powers the view counter, reactions and dashboard, GITHUB_TOKEN powers the GitHub stats card, and the Sentry variables only matter for production builds.

Project layout

Path Purpose
pages/ Routes and API endpoints (pages/api/)
components/ Shared React components, with unit tests alongside them
lib/ Utilities, JSON-LD schema, GitHub/feed helpers, bot blocklist
_posts/ Blog post MDX sources
_snippets/ Code-snippet MDX sources
public/ Static assets, post images, robots.txt, llms.txt
prisma/ Schema and migrations
__tests__/ Page-level and API-route tests
tests/visual/ Playwright behavior and visual regression tests
styles/ Global CSS and Tailwind directives

Scripts

Command Purpose
pnpm dev start the dev server
pnpm verify lint + format:check + typecheck + test:ci
pnpm verify:full verify + production build
pnpm verify:all verify:full + all Playwright tests
pnpm test:visual Playwright behavior and visual tests (Docker)
pnpm article scaffold a new blog post

The rest (formatting, linting, coverage, audits, CSP check) is in the scripts field of package.json.

pnpm verify is the fast loop and what the pre-push hook runs. pnpm verify:full adds next build and is what CI effectively reproduces — run it before opening a PR. pnpm verify:all runs every local check, including Jest with coverage, the production build, and all Playwright behavior and visual regression tests. Start Docker first as described below; the command stops on the first failed step.

Testing

Unit, component and API tests use Jest with Testing Library. Run pnpm test for the Jest suite or pnpm test:coverage for a coverage report. Run pnpm verify:all to include the Playwright suite and all build and static checks.

Unit tests sit next to the code they cover (components/**/*.test.tsx, lib/**/*.test.ts); page-level and API-route tests live in __tests__/.

Coverage is collected on every run, scoped by collectCoverageFrom in jest.config.js to the logic layer — lib/, pages/api/ and middleware.ts. Presentational pages and components render in the test suite but are not counted, so the number reports how well the logic is exercised rather than how much JSX was touched. Jest exits non-zero when coverage on that scope drops below the thresholds set in jest.config.js. CI publishes coverage/lcov.info to Qlty, which backs the coverage badge above.

Local visual regression tests

Start Docker, then run the harness:

pnpm test:visual
pnpm test:visual:report

tests/visual/docker.sh runs the suite in the pinned Playwright Linux image that CI also uses, as linux/amd64 even on Apple silicon. Inside it, Playwright builds and starts an isolated production server on port 3100 using .next-visual/. No database, API credentials or CI setup is required. Browser API requests use fixtures; external requests are blocked. Dates are fixed in prerendering and the browser. Runtime errors fail the tests.

The harness covers behavior and UI states, not full-page screenshots of content. Visual baselines capture small UI regions on mobile and desktop, in light and dark themes, plus the Open Graph images. Behavior tests exercise interactive flows such as search, theme switching, sharing, reactions and API loading and error states. Backend API validation stays in the Jest suite. The specs in tests/visual/ are the full list.

For a shorter feedback loop, select a project, file or test:

pnpm test:visual --project=chromium-mobile-dark
pnpm test:visual content.spec.ts
pnpm test:visual --grep 'optimistic reaction'

pnpm test:visual:native runs the same specs on the host Chromium without Docker (install it once with pnpm exec playwright install chromium). It skips screenshot comparison and is the way to use --ui.

Baselines live in tests/visual/__screenshots__/linux, per project. They render only inside the Docker image: text depends on the system font stack, and a macOS update once shifted 26 macOS baselines with no code change. Missing baselines fail ordinary runs; they are never silently accepted. After an intentional UI change, update only the affected screenshots and review the image diff before committing:

pnpm test:visual:update visual.spec.ts --grep 'copy control'

Commit baseline PNGs with the corresponding change. Reports, traces, actual and diff images remain local in playwright-report/ and test-results/. The visual suite is included in pnpm verify:all. CI runs it on every pull request in the same image, screenshots included.

Security

  • Response headers — CSP, HSTS with preload, X-Frame-Options: DENY, nosniff, Referrer-Policy and a Permissions-Policy that denies camera, microphone and geolocation. All defined in next.config.js.
  • CSP drift check — the production CSP allow-lists inline scripts by hash. pnpm csp:check compares those hashes against the built output and runs in CI on every pull request, so a new inline script can't silently ship behind a stale policy.
  • AI crawler policy — training and scraping crawlers are declined in robots.txt and get a 403 from edge middleware. Search engines, AI search, link previews and assistants fetching a page for a user are allowed. The middleware list lives in lib/bot-blocklist/tokens.ts, and a test fails if robots.txt drifts from it. Reader exceptions in the Vercel firewall are managed directly in the Vercel dashboard, independently of deployments.
  • Supply chain — Renovate opens dependency PRs on the schedule in renovate.json, auto-merging small updates and leaving larger ones for review. A production dependency audit runs as its own CI job.
  • Scanning — GitHub secret scanning and CodeQL are enabled on the repo.

Vulnerability reports go through the process in SECURITY.md — please don't open a public issue.

Performance budget

Lighthouse CI audits every Vercel preview deployment against .github/lighthouse-budget.json, which sets budgets for Core Web Vitals timings and for script, stylesheet and total size. The audited pages and the number of runs are set in lighthouse.yml, and the results are posted back to the pull request as a table.

Deployment

Deploys automatically to Vercel on push to main. The postbuild script regenerates the sitemap via next-sitemap.

.github/workflows/ci.yml runs lint, type checks, tests and a dependency audit on every push to main and every pull request. Pull requests also build the site, check the CSP hashes and run the Playwright suite with screenshot comparison off. Test coverage goes to Qlty over OIDC.

.github/workflows/lighthouse.yml is triggered by a successful Vercel Preview deployment rather than by the push itself, so it audits the real deployed preview instead of a local build.

Monitors

Writing a post

pnpm article scaffolds _posts/<slug>.md with the frontmatter the build expects. Categories must already exist in the PostCategory enum in lib/types.ts, images go in public/static/images/, and public/llms.txt and public/llms-full.txt are updated by hand. Illustrations follow one hand-drawn house style. The full checklist, the illustration guide and the failure modes that don't surface until build time live in AGENTS.md.

Contributing

  • Commits follow Conventional Commits (Angular convention). Enforced by commitlint.config.ts.
  • A pre-commit hook auto-formats staged JS/TS via oxfmt (installed by pnpm install through the prepare script).
  • A pre-push hook (.git-hooks/pre-push) runs pnpm verify automatically before each push. Run pnpm verify:full (adds next build) before opening a PR.
  • See AGENTS.md if you're using an AI coding agent. Full policy in CONTRIBUTING.md.

License

MIT — see LICENSE.

Releases

Packages

Used by

Contributors

Languages