A lot of AI slop
All checks were successful
Build and Deploy Nuxt / build (push) Successful in 35s

This commit is contained in:
2026-06-08 19:36:45 +02:00
parent 8859ee5a5f
commit bbc34c1b12
20 changed files with 1606 additions and 324 deletions

112
AGENTS.md Normal file
View File

@@ -0,0 +1,112 @@
# aranroig.com
Monorepo for aranroig.com — a personal portfolio website with blog, art gallery, and project showcase.
## Stack
- **Frontend**: Nuxt 4 + Vue 3 + TypeScript + SCSS
- **Backend**: Express 5 + Mongoose (MongoDB)
- **i18n**: @nuxtjs/i18n (English, Spanish, Catalan)
- **Content**: Nuxt Content v3 with Zod-sourced Markdown collections
- **Image optimization**: @nuxt/image
- **Build**: Vite
- **Deployment**: Docker Compose + Nginx reverse proxy + Gitea Actions CI/CD
- **Process management**: PM2 (production)
## Project Structure
```
├── backend/ # Express API server (port 5000)
│ └── src/
│ ├── index.js # Entry point, single /api/test endpoint
│ └── db.js # MongoDB connection via Mongoose
├── frontend/ # Nuxt application
│ ├── app/
│ │ ├── assets/css/ # Global SCSS: colors.scss (themes), fonts.scss, main.scss
│ │ ├── components/ # Vue components (TUI-styled)
│ │ │ ├── layouts/ # Page layout wrappers
│ │ │ ├── parts/ # Header, footer, navigation pieces
│ │ │ └── content/ # Blog, art content components
│ │ ├── composables/ # useApi(), theme.ts (light/dark + accent colors)
│ │ ├── i18n.config.ts# VueI18n fallback locale setup
│ │ └── pages/ # File-based routing (index, blog, art, contact)
│ ├── content/ # Markdown collections organized by locale
│ │ ├── fixed/ # Static pages per locale
│ │ ├── blog/ # Blog posts
│ │ ├── art/ # Art pieces
│ │ └── projects/ # Project cards
│ ├── i18n/locales/ # en.json, es.json, ca.json translation files
│ ├── content.config.ts # Content collection schemas (Zod)
│ └── nuxt.config.ts # Nuxt config: modules, i18n, runtime config
├── docker-compose.yml # Services: nginx, frontend, backend
├── nginx.conf # Reverse proxy routing /api/ → backend:5000
├── ecosystem.config.js # PM2 production deployment config
└── .gitea/workflows/ # Gitea Actions CI/CD (deploy on master push)
```
## Commands
From repo root:
| Command | Description |
|---------|-------------|
| `npm run dev` | Run frontend + backend concurrently with logging prefixes `[BACKEND]` and `[FRONTEND]` |
| `npm install` | Install monorepo dependencies (triggers `frontend/postinstall`) |
In `frontend/`:
| Command | Description |
|---------|-------------|
| `npm run dev` | Nuxt dev server with live reload |
| `npm run build` | Production build with `.env.production` |
| `npm run generate` | Static site generation |
| `npm run preview` | Preview built production output |
In `backend/`:
| Command | Description |
|---------|-------------|
| `npm run dev` | Nodemon on `src/index.js` (auto-restart, port 5000) |
## Development
- Use the monorepo root script: `npm run dev` — runs both frontend and backend in parallel.
- Frontend uses the `~/` alias mapping to `frontend/app/`. Auto-imported composables include `useAsyncData`, `useI18n`, `useRoute`, `useLocalePath`, etc.
- Backend reads `.env.development` or `.env.production` based on `NODE_ENV`. Requires `DB_URI` for MongoDB.
- Frontend runtime config key `public.apiBaseUrl` sets the backend API URL used by `useApi()`.
- Content lives in `frontend/content/` under collection folders (`blog`, `fixed`, `art`, `projects`), each with locale subdirectories (`en`, `es`, `ca`).
## Code Style
- Vue SFCs use `<script setup>` (TypeScript via `lang="ts"` where needed, plain JS otherwise).
- All styling is SCSS with scoped styles per component. Page-level blog/art pages use global styles.
- Mobile-first breakpoints: `600px`, `900px`, `1200px` (max-width queries).
- File names: kebab-case for components and pages.
- CSS variables driven by SCSS maps define themes (light/dark) and accent colors.
- TUI aesthetic: box-drawing characters, monospace font (**Hermit** / "Hurmit" via Nerd Fonts), `steps()` easing transitions, pixel-art SVG elements.
## Content Collections
Content frontmatter is validated with Zod schemas defined in `frontend/content.config.ts`:
| Collection | Fields |
|------------|--------|
| `blog` | title, slug, date, description |
| `art` | title, slug, thumb, date |
| `projects` | title, slug, description, link, tech (array) |
| `fixed` | title, slug, description |
Write Markdown files under the corresponding collection folder with locale subdirectories. Frontmatter must conform to the Zod schema.
## Theming
- Theme selector switches between light/dark modes and accent color palettes (dragon-themed names: katlum, solus, silang, nozt, albor).
- Preferences persist in `localStorage`. Respects `prefers-color-scheme` on first visit.
- Theme setup runs via `setupTheme()` composable called on app mount (`app.vue`).
## Deployment
1. Gitea Actions CI/CD triggers on push to `master`, builds Docker images, pushes to Gitea registry.
2. SSHs into deploy host and runs `docker-compose pull && docker-compose up -d`.
3. For manual deployment, `docker-compose.yml` orchestrates nginx + frontend + backend services.
4. Production process management uses PM2 via `ecosystem.config.js`.