|
| 1 | +--- |
| 2 | +name: Portfolio Site Architecture |
| 3 | +description: Astro 6 static export, React 19 hydrated portfolio island, GitHub GraphQL/REST build-time repository data, terminal UI theme, SEO/analytics strategy |
| 4 | +type: project |
| 5 | +--- |
| 6 | + |
| 7 | +## Rendering Strategy |
| 8 | + |
| 9 | +- **Astro pages/layouts**: `src/pages/index.astro` fetches repository data at build time and renders the React portfolio island with `client:load`; `src/pages/resume.astro` renders the print-optimized resume route. |
| 10 | +- **Hydrated React island**: `src/components/Portfolio.tsx` owns the interactive homepage UI, scroll/reveal effects, project workbench, contact actions, and terminal easter egg. |
| 11 | +- **Static export**: `astro.config.ts` sets `output: "static"` and `outDir: "out"`; `main-release.yml` uploads that artifact for GitHub Pages. |
| 12 | + |
| 13 | +**Why:** Build-time data fetching keeps the deployed site as static HTML/CSS/JS while preserving live GitHub profile/repository data when CI provides `GITHUB_TOKEN`. |
| 14 | + |
| 15 | +**How to apply:** New dynamic repository/profile data should be resolved during `bun run build` through `src/lib/github.ts` or committed static sources in `src/lib/data.ts`; the browser bundle should not depend on runtime GitHub API calls. |
| 16 | + |
| 17 | +## GitHub API Integration |
| 18 | + |
| 19 | +`src/lib/github.ts` fetches repositories with `GITHUB_TOKEN` when available: |
| 20 | + |
| 21 | +- GraphQL `user(login: OWNER).pinnedItems(first: 6, types: REPOSITORY)` preserves GitHub profile pinned-project order. |
| 22 | +- GraphQL `repositories(first: 100, ownerAffiliations: OWNER, privacy: PUBLIC, isFork: false)` builds the owned public repo ledger. |
| 23 | +- REST `GET /repos/jonathanperis/{repo}/pages` enriches repositories with live GitHub Pages URLs. |
| 24 | +- `FALLBACK_REPOS` keeps local builds and PR checks deterministic when API calls fail or no token is present. |
| 25 | +- `EXCLUDED_REPOS` removes metadata/profile repositories; pinned repos are excluded from the lower ledger to avoid duplicates. |
| 26 | + |
| 27 | +## Data Architecture |
| 28 | + |
| 29 | +`src/lib/data.ts` exports shared static content: |
| 30 | + |
| 31 | +- `PROFILE` — name, title, email, location, site, and GitHub identity. |
| 32 | +- `AVAILABILITY` — hiring/engagement status rendered in the portfolio and terminal. |
| 33 | +- `SKILLS` — categorized technology list. |
| 34 | +- `EXPERIENCES` — professional roles and highlights. |
| 35 | +- `FEATURED_PROJECTS` — hand-authored project cards. |
| 36 | +- `EDUCATION` — BTech from UNIESP. |
| 37 | +- `SOCIALS` — platform links. |
| 38 | + |
| 39 | +The same data feeds the homepage, resume route, terminal snippets, and `JsonLd.astro` structured data. |
| 40 | + |
| 41 | +## UI Features |
| 42 | + |
| 43 | +- Low-glare dark terminal/workbench aesthetic with Tailwind CSS 4 and custom global styles in `src/styles/globals.css`. |
| 44 | +- Scroll progress indicator via `useScrollProgress()`. |
| 45 | +- Reveal-on-scroll sections via `useReveal()` and `Reveal`. |
| 46 | +- Print-optimized resume at `/resume/`. |
| 47 | +- Konami-code terminal overlay with commands handled by `runCmd()` in `Portfolio.tsx`: `help`, `about`, `stack`, `contact`, `neofetch`, `git log`, `ls`, `cat availability.txt`, `whoami`, `pwd`, `date`, `sudo hire me`, `echo`, `clear`, `exit`, and `quit`. |
| 48 | + |
| 49 | +## SEO and Analytics |
| 50 | + |
| 51 | +- `src/layouts/RootLayout.astro` emits canonical, Open Graph, Twitter card, icon, manifest, alternate-language, font, and JSON-LD tags. |
| 52 | +- `src/components/Analytics.astro` loads Google Analytics 4 only when `PUBLIC_GA_ID` is set. |
| 53 | +- `public/robots.txt`, `public/sitemap.xml`, `public/manifest.json`, and icon assets are published with the static artifact. |
0 commit comments