Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
# Sentry server-side DSN. Required for production builds, optional for local dev.
# Obtain: Sentry project → Settings → Client Keys (DSN).
SENTRY_DSN=

# Sentry browser DSN. Same value as SENTRY_DSN — Next.js exposes this to the client.
NEXT_PUBLIC_SENTRY_DSN=

# Sentry CLI auth token. Required for source-map upload during `pnpm build`.
# Obtain: Sentry → User Settings → Auth Tokens, scope `project:releases`.
SENTRY_AUTH_TOKEN=

# Sentry environment label. Defaults to `development` locally; Vercel sets `production`.
SENTRY_ENVIRONMENT=development
NEXT_PUBLIC_SENTRY_ENVIRONMENT=development

# Postgres connection string. Required for any feature that hits the DB
# (view counters, reactions, dashboard). Use Neon or local Postgres for dev.
DATABASE_URL=

# GitHub personal access token (read-only). Required by /api/github
# (powers the GitHub stats card on the homepage). `public_repo` scope is sufficient.
GITHUB_TOKEN=
3 changes: 1 addition & 2 deletions .git-hooks/pre-push
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
#!/usr/bin/env sh

pnpm run pre-push
exec pnpm run verify
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @Shramkoweb
66 changes: 66 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: Bug report
description: Something on shramko.dev is broken or behaves unexpectedly
labels: ['bug']
body:
- type: textarea
id: summary
attributes:
label: Summary
description: What went wrong, in one or two sentences.
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Steps to reproduce
description: Numbered steps that someone else can follow to see the bug.
placeholder: |
1. Go to https://shramko.dev/...
2. Click ...
3. See error
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual behavior
validations:
required: true
- type: input
id: browser
attributes:
label: Browser and version
placeholder: 'Chrome 130 / Safari 18 / Firefox 130'
validations:
required: true
- type: dropdown
id: viewport
attributes:
label: Viewport
options:
- Desktop
- Tablet
- Mobile
validations:
required: true
- type: dropdown
id: theme
attributes:
label: Theme
options:
- Light
- Dark
- System
validations:
required: true
- type: textarea
id: extra
attributes:
label: Anything else
description: Console errors, screenshots, related links.
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
blank_issues_enabled: false
26 changes: 26 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Feature request
description: Suggest an addition or change
labels: ['enhancement']
body:
- type: textarea
id: problem
attributes:
label: Problem
description: What user need or pain point does this address?
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposed solution
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives considered
description: Other approaches you thought about and why you chose the one above.
- type: textarea
id: extra
attributes:
label: Anything else
33 changes: 33 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## Summary

<!-- 1–3 bullets explaining what changes and why. -->

-

## Type

<!-- Tick exactly one. -->

- [ ] feat — new feature
- [ ] fix — bug fix
- [ ] docs — docs only
- [ ] style — formatting / whitespace
- [ ] refactor — internal restructuring
- [ ] perf — performance
- [ ] test — tests only
- [ ] build — build system / deps
- [ ] ci — CI config
- [ ] chore — maintenance

## Linked spec or plan

<!-- Optional. Specs live in `docs/superpowers/specs/` (gitignored) — paste the excerpt if relevant. -->

## Test plan

- [ ] `pnpm verify:full` exits 0 locally
- [ ] <add manual test steps if UI / API changes>

## Breaking changes

<!-- "None" or list them. -->
3 changes: 2 additions & 1 deletion .oxfmtrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"build/**",
"coverage/**",
"prisma/migrations/**",
"public/**"
"public/**",
"next-env.d.ts"
]
}
97 changes: 97 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# AGENTS.md

Brief for AI coding agents (Claude Code, Codex, Cursor, Copilot, Factory). Humans should read [README.md](README.md) first.

## Project at a glance

`shramko.dev` is a personal portfolio + blog + digital garden. Single deployment target: Vercel.

| Layer | Tools |
| ---------- | -------------------------------------------------------------- |
| Framework | Next.js 16 (Pages Router), React 19 |
| Language | TypeScript (strict) |
| Styling | Tailwind CSS v4 |
| Content | MDX via `next-mdx-remote`, Shiki for syntax highlighting |
| Data | Prisma 7, Postgres (Neon in prod) |
| Fetch | SWR |
| Monitoring | Sentry, Vercel Analytics, Speed Insights, Checkly, UptimeRobot |
| Testing | Jest + Testing Library |
| Tooling | oxlint, oxfmt, commitlint, pnpm |

## Setup

Prereqs: Node 24.x (see `.nvmrc`), pnpm 10.x, Postgres database for any DB-touching feature.

```bash
pnpm install # also runs prisma generate via postinstall
cp .env.example .env # each var is documented inline in .env.example
pnpm dev # http://localhost:3000
```

## The verify loop

**Two commands. Use the right one.**

- `pnpm verify` — fast (~1 s). Runs `lint`, `format:check`, `typecheck`, `test:ci`. The pre-push hook calls this. Use during tight iteration.
- `pnpm verify:full` — slower (~30–60 s). Adds `next build` on top. Matches what CI runs. **Run this before opening a PR.**

**Success criterion:** before claiming work is done, `pnpm verify:full` exits 0.

## Common tasks

| Goal | Command |
| ------------------------- | ------------------------------------- |
| Start dev server | `pnpm dev` |
| Run a single test file | `pnpm exec jest path/to/file.test.ts` |
| Run a single test by name | `pnpm exec jest -t "test name"` |
| Production build | `pnpm build` |
| Format only (write) | `pnpm format` |
| Lint only (auto-fix) | `pnpm lint:fix` |
| Type check only | `pnpm typecheck` |
| Scaffold a blog post | `pnpm article` |
| Regenerate Prisma client | `pnpm exec prisma generate` |

## Repo layout

| Path | Purpose |
| ------------------- | ---------------------------------------------------------- |
| `pages/` | Next.js Pages Router routes + API endpoints (`pages/api/`) |
| `components/` | Shared React components |
| `lib/` | Utilities, schema, GitHub/Sentry helpers, scripts |
| `_posts/` | Blog post MDX sources |
| `_snippets/` | Code-snippet MDX sources |
| `prisma/` | Prisma schema + migrations |
| `public/` | Static assets |
| `styles/` | Global CSS + Tailwind directives |
| `__tests__/` | Page-level and API-route tests |
| `__mocks__/` | Manual Jest mocks |
| `docs/superpowers/` | Local-only specs and plans (gitignored) |

## Conventions

- **Commits:** [Conventional Commits](https://www.conventionalcommits.org/) Angular convention. Enforced by `commitlint.config.ts`. Lowercase subject, ≤ 50 chars, no period. Allowed types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`.
- **Branches:** `feat/`, `fix/`, `chore/`, `ci/`, `docs/`, `refactor/`, `test/`, `perf/`.
- **Formatting:** `oxfmt`. Pre-commit hook auto-formats staged JS/TS. Don't fight it.
- **Before pushing:** the git pre-push hook (`.git-hooks/pre-push`) runs `pnpm verify` automatically. Don't bypass with `--no-verify`.
- **Before opening a PR:** run `pnpm verify:full` (adds `build`). PR template has a checkbox for this.

## Where things live

- **Env vars** are documented in `.env.example` with descriptions and where to obtain each value.
- **Secrets** live in Vercel project settings (`Sentry*`, `DATABASE_URL`, `GITHUB_TOKEN`). Read-only for agents — don't try to set them.
- **The Sentry public DSN** (`NEXT_PUBLIC_SENTRY_DSN`) is intentionally exposed to the client; this is by Sentry design, not a leak.
- **Specs and plans** for non-trivial work are in `docs/superpowers/specs/` and `docs/superpowers/plans/`. Both are gitignored — they live locally per-developer.

## Don't do

- Don't bypass git hooks with `--no-verify`.
- Don't commit `.env` (only `.env.example`).
- Don't hand-edit `pnpm-lock.yaml` — let `pnpm install` regenerate it.
- Don't push directly to `main`. PRs only.
- Don't add a dependency without a clear justification — this repo deliberately stays lean.
- Don't write `*.md` files outside what an issue requires; this project does not use docs-as-features.

## Notes for specific tools

- **Claude Code:** `CLAUDE.md` at the repo root is a symlink to this file. Edit `AGENTS.md`, not `CLAUDE.md`.
- **Pages Router / Sentry gap:** there is no `pages/_error.tsx` with `Sentry.captureUnderscoreErrorException`, so SSR errors from the Pages Router don't reach Sentry. Don't fix this inline as a side effect of unrelated work — open a focused PR for it.
1 change: 1 addition & 0 deletions CLAUDE.md
46 changes: 46 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Contributing

This is a personal, opinionated portfolio. Contributions are welcome but not the primary mode of development. If you're considering a non-trivial change, open an issue first to align on scope.

## Setup

See [README.md](README.md) for prerequisites and bootstrap steps.

## Branch naming

Use one of these prefixes (matches existing git history):

- `feat/<short-name>` — new feature
- `fix/<short-name>` — bug fix
- `chore/<short-name>` — maintenance / non-functional
- `ci/<short-name>` — CI configuration
- `docs/<short-name>` — documentation only
- `refactor/<short-name>` — internal restructuring
- `test/<short-name>` — tests only
- `perf/<short-name>` — performance work

## Commits

Conventional Commits (Angular convention) is enforced by `commitlint.config.ts`. Rules:

- Lowercase subject, ≤ 50 characters, no trailing period.
- Type required (one of: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`).
- Imperative mood: `add`, not `added`.

Examples: `feat: add OG image generator`, `fix(api): correct slug normalization`.

## Pre-PR checks

Run `pnpm verify:full` locally and confirm it exits 0. This runs:

```
oxlint → oxfmt --check → tsc --noEmit → jest --ci → next build
```

The PR template has a checkbox for this. Without it, CI will fail.

## Pull request description

- Explain the **why**, not just the what.
- Flag breaking changes explicitly.
- If the change has a spec under `docs/superpowers/specs/`, link it. Specs are local-only (gitignored), so paste the relevant excerpt rather than a path-only link.
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT">
</p>

<p align="center"><a href="README.ua.md">🇺🇦 Українською</a></p>

## Contents

- [Tech Stack](#tech-stack)
Expand Down Expand Up @@ -61,15 +59,17 @@ App runs at http://localhost:3000.

## Scripts

| Command | Purpose |
| ----------------------------------- | -------------------------- |
| `pnpm dev` | start dev server |
| `pnpm build` | production build + sitemap |
| `pnpm start` | start production server |
| `pnpm lint` / `pnpm lint:fix` | oxlint |
| `pnpm format` / `pnpm format:check` | oxfmt |
| `pnpm test` / `pnpm test:coverage` | Jest |
| `pnpm article` | scaffold a new blog post |
| Command | Purpose |
| ----------------------------------- | ------------------------------------------- |
| `pnpm dev` | start dev server |
| `pnpm build` | production build + sitemap |
| `pnpm start` | start production server |
| `pnpm lint` / `pnpm lint:fix` | oxlint |
| `pnpm format` / `pnpm format:check` | oxfmt |
| `pnpm test` / `pnpm test:coverage` | Jest |
| `pnpm verify` | lint + format:check + typecheck + test (CI) |
| `pnpm verify:full` | `verify` + production build |
| `pnpm article` | scaffold a new blog post |

## Testing

Expand All @@ -93,7 +93,8 @@ Deploys automatically to [Vercel](https://vercel.com) on push to `main`. The `po

- Commits follow [Conventional Commits](https://www.conventionalcommits.org) (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).
- Run `pnpm pre-push` before pushing — it runs lint and format checks.
- 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](AGENTS.md) if you're using an AI coding agent. Full policy in [CONTRIBUTING.md](CONTRIBUTING.md).

## License

Expand Down
Loading
Loading