Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XtcZtnG4GQA1d6mW5PNrS9
65 lines
4.6 KiB
Markdown
65 lines
4.6 KiB
Markdown
# Emil Shanayev — resume site
|
|
|
|
Live at **https://shanaty.ru/resume/**. A static Next.js site whose content is read live from Gitea, so it is updated by editing repositories, not by redeploying.
|
|
|
|
## What comes from where
|
|
|
|
| On the page | Source |
|
|
|---|---|
|
|
| Name, role, bio, skills, experience, education, languages, contacts | [`data/resume.json`](data/resume.json) (English) and [`data/resume.ru.json`](data/resume.ru.json) (Russian) in this repo (`main` branch) |
|
|
| Projects | Public repos of `Emil_Shanaty` on Gitea that carry the topic **`resume`** |
|
|
| The "full portfolio" link and its project count | The site's `/portfolio/` page, which lists the public repos with the topic `portfolio` (button in the hero and a block after the project list; also in the top bar) |
|
|
| Project picture | Optional `demo.png`, `demo.jpg`, `demo.gif` or `demo.webp` in the root of that repo |
|
|
| Project title, kind, description, highlights, tech tags, links, order | Optional `resume-card.json` in the root of that repo |
|
|
|
|
A timer on the server (`resume_sync.py` in the `auto` repo) rebuilds `https://shanaty.ru/data/resume.json` every minute from these sources, so a change shows up within about a minute. If a source is broken (invalid JSON, missing fields, unsafe links) the previous published data stays and the problem is logged (`journalctl -u gitea-resume`).
|
|
|
|
## Adding a project
|
|
|
|
1. On Gitea, add the topic `resume` to the repository (it must be public).
|
|
2. Optional: put a `demo.png` (or `.jpg`, `.gif`, `.webp`) in the repo root. Up to 6 MB, any proportions; animated GIFs and WebP keep animating. Without one the project gets a generated picture.
|
|
3. Optional: put a `resume-card.json` in the repo root to control how the project reads:
|
|
|
|
```json
|
|
{
|
|
"title": "Cortex Engine",
|
|
"kind": "AI-native 3D game engine",
|
|
"description": "One or two sentences on what it is and what makes it interesting.",
|
|
"highlights": ["Pure Vulkan 1.3 backend", "Playable FPS demo"],
|
|
"tech": ["C#", "Vulkan", "MCP"],
|
|
"links": [{ "label": "Docs", "href": "https://example.com/docs" }],
|
|
"rank": 1,
|
|
"hidden": false
|
|
}
|
|
```
|
|
|
|
Every field is optional. Without a card the page uses the Gitea description, the repo language and its topics (the topics `resume`, `portfolio` and `featured` are not shown as tags). `rank` puts a project first (lower first, unranked ones follow, newest first); `"hidden": true` removes it from the page. The same values can also live centrally in `projectNotes` (keyed by repo name) in `data/resume.json`; a `resume-card.json` wins over it.
|
|
|
|
The layout adapts to any number of projects: rows of two or three plates with a wider feature plate first, no lone project left in the last row, and a single project gets the whole width.
|
|
|
|
## Languages
|
|
|
|
The site is bilingual and **Russian is the default** (the browser language is ignored). The RU/EN switch is in the top bar, the choice is stored in `localStorage` and is shared with the front page and the portfolio. Both languages are in the markup and `html[data-lang]` picks one, so there is no flash on load. `data/resume.ru.json` must keep the same structure as `data/resume.json`: skills, experience, education, languages, interests and contacts are paired **by position**, and anything missing in the Russian file falls back to the English text. Project names, descriptions and highlights come from the repositories (English) and are the same in both languages.
|
|
|
|
## Editing the text
|
|
|
|
To point the portfolio button somewhere else (or rename it), add `"portfolio": { "href": "https://...", "label": "All work" }` to `data/resume.json`.
|
|
|
|
Edit `data/resume.json` (and its Russian twin `data/resume.ru.json`), commit and **push to Gitea** (`git push gitea main`). No rebuild or deploy is needed.
|
|
|
|
## Development
|
|
|
|
```bash
|
|
npm install
|
|
npm run dev # http://localhost:3000, data from the public https://shanaty.ru/data/resume.json
|
|
npm run build # static export in out/
|
|
```
|
|
|
|
`BASE_PATH` sets the URL prefix (default `/Emil_Shanayev_Resume`, for GitHub Pages), `NEXT_PUBLIC_DATA_URL` the data URL and `NEXT_PUBLIC_SITE_ORIGIN` where the other pages of shanaty.ru live (empty in the production build, so the bar's links are root-relative). Fonts (Unbounded, Onest; SIL Open Font License) are bundled in `app/fonts`, so building needs no network.
|
|
|
|
## Deploy
|
|
|
|
Automatic: every push to `main` (except changes that only touch `data/**` or `*.md`) runs `.gitea/workflows/deploy.yml` on the server's Gitea Actions runner. It builds the site and swaps the
|
|
`resume/` folder of shanaty.ru in. Gitea runs `.gitea/workflows` instead of `.github/workflows`, so the GitHub Pages workflow (for the copy on GitHub) does not run on the server.
|
|
By hand, with the ssh key `~/.ssh/MyGitea`: `./deploy-shanaty.sh`.
|