From e7fd109a7a52e3b6002ad7d0e20053d1a902490a Mon Sep 17 00:00:00 2001 From: wh-leader Date: Fri, 8 May 2026 12:49:22 +0200 Subject: [PATCH] docs: add complete portfolio architecture design --- ARCHITECTURE.md | 527 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 527 insertions(+) create mode 100644 ARCHITECTURE.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md new file mode 100644 index 0000000..8def314 --- /dev/null +++ b/ARCHITECTURE.md @@ -0,0 +1,527 @@ +# Personal Portfolio Architecture - davidaragon.impresion3d.pro + +**Project**: Personal Tech Portfolio & Dev Blog +**Tech Stack**: Astro + Tailwind CSS +**Deploy**: Docker + Portainer on 192.168.1.30 +**Investment**: €8,100 (4-week sprint) +**Strategic Value**: €45-95K 3-year value (477-1,118% ROI) + +--- + +## 1. Technology Stack + +### Core Framework +- **Astro 4.x**: Static site generator optimized for content-first sites + - Ultra-fast static HTML generation + - Markdown-first content workflow + - Minimal JavaScript (island architecture) + - Built-in SEO optimization + - Zero-config TypeScript support + +### Styling & UI +- **Tailwind CSS 3.x**: Utility-first CSS framework + - Dark mode optimized + - Responsive design system + - Custom color palette + - Typography plugin for blog content + +### Content Management +- **Astro Content Collections**: Type-safe content management + - Blog posts (Markdown + frontmatter) + - Project case studies + - Schema validation with Zod + - Automatic type generation + +### Build & Deploy +- **Docker**: Containerized deployment + - Nginx as static file server + - Multi-stage build (node build + nginx serve) + - Optimized image size (<50MB) +- **Portainer**: Container orchestration on 192.168.1.30 + - Stack deployment via docker-compose + - Environment variable management + - Persistent volume for logs + +--- + +## 2. Project Structure + +``` +davidaragon-portfolio/ +├── src/ +│ ├── components/ # Reusable UI components +│ │ ├── layout/ +│ │ │ ├── Header.astro +│ │ │ ├── Footer.astro +│ │ │ └── Navigation.astro +│ │ ├── blog/ +│ │ │ ├── PostCard.astro +│ │ │ ├── PostList.astro +│ │ │ └── PostLayout.astro +│ │ ├── projects/ +│ │ │ ├── ProjectCard.astro +│ │ │ └── ProjectGrid.astro +│ │ └── ui/ +│ │ ├── Button.astro +│ │ ├── Card.astro +│ │ └── Tag.astro +│ ├── content/ # Content collections +│ │ ├── config.ts # Collection schemas +│ │ ├── blog/ # Blog posts (Markdown) +│ │ │ ├── building-in-public.md +│ │ │ ├── spanish-saas.md +│ │ │ └── warrantyhub-pwa.md +│ │ └── projects/ # Project case studies +│ │ ├── warrantyhub.md +│ │ └── garage61.md +│ ├── layouts/ # Page layouts +│ │ ├── BaseLayout.astro +│ │ ├── BlogLayout.astro +│ │ └── ProjectLayout.astro +│ ├── pages/ # Routes (file-based routing) +│ │ ├── index.astro # Homepage +│ │ ├── about.astro # About page +│ │ ├── projects/ +│ │ │ ├── index.astro # Projects listing +│ │ │ └── [slug].astro # Individual project +│ │ ├── blog/ +│ │ │ ├── index.astro # Blog listing +│ │ │ └── [slug].astro # Individual post +│ │ └── rss.xml.ts # RSS feed generator +│ ├── styles/ # Global styles +│ │ ├── global.css # Base styles + Tailwind +│ │ └── syntax.css # Code syntax highlighting +│ └── utils/ # Helper functions +│ ├── dateFormat.ts +│ └── readingTime.ts +├── public/ # Static assets +│ ├── images/ +│ │ ├── avatar.jpg +│ │ └── projects/ +│ ├── favicon.ico +│ └── robots.txt +├── .docker/ +│ ├── Dockerfile # Multi-stage build +│ ├── nginx.conf # Nginx configuration +│ └── docker-compose.yml # Portainer stack +├── astro.config.mjs # Astro configuration +├── tailwind.config.cjs # Tailwind configuration +├── tsconfig.json # TypeScript configuration +└── package.json # Dependencies +``` + +--- + +## 3. Content Collections Schema + +### Blog Posts +```typescript +// src/content/config.ts +const blog = defineCollection({ + schema: z.object({ + title: z.string(), + description: z.string(), + publishDate: z.date(), + author: z.string().default('David Aragón'), + tags: z.array(z.string()), + category: z.enum(['technical', 'business', 'personal']), + featured: z.boolean().default(false), + draft: z.boolean().default(false), + image: z.string().optional(), + }), +}); +``` + +### Projects +```typescript +const projects = defineCollection({ + schema: z.object({ + title: z.string(), + description: z.string(), + url: z.string().url(), + github: z.string().url().optional(), + status: z.enum(['active', 'development', 'completed']), + tags: z.array(z.string()), + startDate: z.date(), + featured: z.boolean().default(false), + image: z.string().optional(), + }), +}); +``` + +--- + +## 4. Design System + +### Color Palette (Dark Mode Optimized) +```css +/* Tailwind config */ +colors: { + background: '#0a0e27', // Deep navy + surface: '#131729', // Card backgrounds + primary: '#60a5fa', // Blue accent + secondary: '#a78bfa', // Purple accent + text: { + primary: '#f1f5f9', // Light text + secondary: '#94a3b8', // Muted text + tertiary: '#64748b', // Subtle text + }, + accent: { + green: '#34d399', // Success + red: '#f87171', // Error + yellow: '#fbbf24', // Warning + } +} +``` + +### Typography +- **Headings**: Inter (font-weight: 600-800) +- **Body**: Inter (font-weight: 400-500) +- **Code**: JetBrains Mono (font-weight: 400) +- **Scale**: + - H1: 3rem (48px) + - H2: 2.25rem (36px) + - H3: 1.875rem (30px) + - Body: 1rem (16px) + - Small: 0.875rem (14px) + +### Component System +- **Cards**: Glassmorphism effect with subtle backdrop blur +- **Buttons**: Hover transitions, focus states +- **Navigation**: Sticky header with scroll-based styling +- **Links**: Underline on hover, smooth transitions +- **Code blocks**: Syntax highlighting with Shiki (VS Code Dark+ theme) + +--- + +## 5. SEO Strategy + +### Meta Tags +- **Title template**: `{page} | David Aragón - Indie Builder` +- **Description**: Dynamic per page +- **Open Graph**: Images for all blog posts and projects +- **Twitter Cards**: Summary with large image + +### Sitemap +- Auto-generated via Astro integration +- Includes all pages, blog posts, projects +- Priority: Homepage (1.0), Blog/Projects (0.8), Posts (0.6) + +### RSS Feed +- Full-text feed at `/rss.xml` +- Includes title, description, content, publish date +- Auto-updated on build + +### Performance +- **Target Lighthouse score**: 95+ across all metrics +- **Core Web Vitals**: + - LCP: <2.5s + - FID: <100ms + - CLS: <0.1 + +--- + +## 6. Docker Deployment Architecture + +### Multi-Stage Dockerfile +```dockerfile +# Stage 1: Build +FROM node:20-alpine AS builder +WORKDIR /app +COPY package*.json ./ +RUN npm ci +COPY . . +RUN npm run build + +# Stage 2: Serve +FROM nginx:alpine +COPY --from=builder /app/dist /usr/share/nginx/html +COPY .docker/nginx.conf /etc/nginx/nginx.conf +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] +``` + +### Nginx Configuration +- Serve static files from `/usr/share/nginx/html` +- Gzip compression for text assets +- Cache-Control headers (1 year for assets, 1 hour for HTML) +- 404 fallback to custom 404.html +- Security headers (CSP, X-Frame-Options, etc.) + +### Docker Compose (Portainer Stack) +```yaml +version: '3.8' +services: + portfolio: + build: + context: . + dockerfile: .docker/Dockerfile + container_name: davidaragon-portfolio + restart: unless-stopped + ports: + - "3010:80" + environment: + - NODE_ENV=production + labels: + - "traefik.enable=true" + - "traefik.http.routers.portfolio.rule=Host(`davidaragon.impresion3d.pro`)" + - "traefik.http.services.portfolio.loadbalancer.server.port=80" +``` + +### Deployment on 192.168.1.30 +1. **Portainer stack deployment**: + - Create new stack "davidaragon-portfolio" + - Upload docker-compose.yml + - Configure environment variables + - Deploy stack + +2. **Domain configuration**: + - DNS A record: `davidaragon.impresion3d.pro` → 192.168.1.30 + - Traefik reverse proxy for HTTPS + - Let's Encrypt SSL certificate + +3. **CI/CD (future)**: + - Gitea Actions on push to main branch + - Build Docker image + - Push to local registry or rebuild on server + - Portainer webhook to redeploy stack + +--- + +## 7. Content Strategy + +### Launch Content (5 Blog Posts) +1. **"Building in Public: My €4M ARR Portfolio Plan"** + - Category: Business + - Tags: indie hacker, SaaS portfolio, build-in-public + - Length: 1,500-2,000 words + +2. **"Why I'm Building Spanish-First SaaS Products"** + - Category: Business + - Tags: Spanish SaaS, European market, compliance + - Length: 1,200-1,500 words + +3. **"WarrantyHub: Building a PWA with 79% AI-Assisted Development"** + - Category: Technical + - Tags: PWA, AI-assisted coding, React, IndexedDB + - Length: 2,000-2,500 words + +4. **"Validating Business Ideas: My €4M Research Framework"** + - Category: Business + - Tags: business validation, market research + - Length: 1,800-2,200 words + +5. **"From Concept to €502K ARR: WarrantyHub Financial Model"** + - Category: Business + - Tags: SaaS financial model, ARR projections + - Length: 1,500-2,000 words + +### Project Case Studies (2) +1. **WarrantyHub**: Problem, solution, architecture, status +2. **Garage61 API**: Platform strategy, Python library, future plans + +--- + +## 8. Pages Architecture + +### Homepage (`/`) +- **Hero section**: Personal tagline + CTA +- **Featured projects**: 3-4 project cards +- **Latest blog posts**: 3 most recent posts +- **Newsletter signup**: Email collection form +- **Social links**: X, LinkedIn, GitHub + +### About Page (`/about`) +- **Personal story**: 400-600 word narrative +- **Professional photo**: Authentic builder vibe +- **Technical skills**: Tech stack showcase +- **Current focus**: Portfolio goals and timeline +- **Contact**: Email, social media + +### Projects Page (`/projects`) +- **Project grid**: All projects with filters (status, tech) +- **Project cards**: Title, description, tech stack, links +- **Featured projects**: Highlighted at top +- **Case study links**: Deep-dive for each project + +### Blog Page (`/blog`) +- **Post listing**: All posts with pagination (10 per page) +- **Category filters**: Technical, Business, Personal +- **Tag cloud**: Popular tags +- **Search**: Client-side search with Fuse.js +- **RSS link**: Subscribe to feed + +### Individual Post (`/blog/[slug]`) +- **Post metadata**: Publish date, reading time, tags +- **Table of contents**: Auto-generated from headings +- **Syntax highlighting**: Code blocks with copy button +- **Share buttons**: X, LinkedIn +- **Related posts**: 3 similar posts by tags + +### Individual Project (`/projects/[slug]`) +- **Project header**: Title, status, links (live, GitHub) +- **Hero image**: Screenshot or diagram +- **Overview**: Problem statement and solution +- **Tech stack**: Technologies used +- **Architecture**: Technical deep-dive +- **Learnings**: Challenges and insights +- **Next steps**: Future roadmap + +--- + +## 9. Performance Optimization + +### Build-Time Optimizations +- **Image optimization**: Astro Image component with automatic format conversion (WebP/AVIF) +- **Code splitting**: Per-route JavaScript bundles +- **CSS purging**: Unused Tailwind classes removed +- **HTML minification**: Whitespace removal +- **Asset hashing**: Cache-busting for updated files + +### Runtime Optimizations +- **Lazy loading**: Images load on scroll +- **Preload critical fonts**: Inter and JetBrains Mono +- **DNS prefetch**: External resources (analytics, CDN) +- **Service worker** (future): Offline support and caching + +### Bundle Size Targets +- **Total JS**: <50KB (gzipped) +- **Total CSS**: <30KB (gzipped) +- **First load**: <200KB total + +--- + +## 10. Analytics & Monitoring + +### Analytics +- **Plausible Analytics**: Privacy-friendly, GDPR-compliant + - Deployed on 192.168.1.30 (Docker container) + - Custom events: Newsletter signups, project clicks + - Traffic sources, top pages, referrers + +### Monitoring +- **Uptime monitoring**: Portainer health checks +- **Error tracking**: Browser console errors (future: Sentry) +- **Performance monitoring**: Lighthouse CI on builds + +--- + +## 11. Security Considerations + +### Headers +- **Content-Security-Policy**: Restrict script sources +- **X-Frame-Options**: Prevent clickjacking +- **X-Content-Type-Options**: Prevent MIME sniffing +- **Referrer-Policy**: Control referrer information + +### HTTPS +- **Let's Encrypt certificate**: Auto-renewal via Traefik +- **HSTS**: Force HTTPS after first visit +- **Redirect HTTP → HTTPS**: Automatic + +### Input Validation +- **Newsletter form**: Email validation, CSRF protection +- **Contact form** (future): Rate limiting, spam prevention + +--- + +## 12. Acceptance Criteria + +### Foundation Complete +- ✅ Astro project initialized with TypeScript +- ✅ Tailwind CSS configured with custom design system +- ✅ Content collections set up for blog and projects +- ✅ All core pages implemented (Home, About, Projects, Blog) +- ✅ Responsive design (mobile, tablet, desktop) +- ✅ Dark mode fully implemented + +### Content Complete +- ✅ 5 blog posts written and published +- ✅ 2 project case studies complete +- ✅ Visual assets created (images, diagrams, photos) +- ✅ RSS feed functional +- ✅ Sitemap generated + +### Deployment Complete +- ✅ Docker image built (<50MB) +- ✅ Nginx configured with security headers +- ✅ Portainer stack deployed on 192.168.1.30 +- ✅ Domain davidaragon.impresion3d.pro resolves correctly +- ✅ HTTPS working with valid certificate +- ✅ Analytics tracking functional + +### Performance & SEO +- ✅ Lighthouse score 95+ (all categories) +- ✅ Core Web Vitals pass +- ✅ All meta tags present +- ✅ Open Graph images for all posts +- ✅ Sitemap accessible at /sitemap.xml +- ✅ RSS feed accessible at /rss.xml + +--- + +## 13. Future Enhancements (Post-Launch) + +### Phase 2 (Month 2-3) +- Newsletter automation (email drip campaigns) +- Search functionality (Algolia or Fuse.js) +- Comment system (giscus or custom) +- Related posts algorithm improvement + +### Phase 3 (Month 4-6) +- Interactive demos for projects (embedded CodeSandbox) +- Video content (embedded YouTube) +- Spanish/English language toggle +- Progressive Web App features (offline support) + +### Phase 4 (Month 7+) +- Guest blog posts from community +- Podcast interviews (embedded player) +- Community forum or discussion board +- Advanced analytics dashboard + +--- + +## 14. Maintenance Plan + +### Weekly (6-9 hours) +- **Content**: 1 blog post (4-6 hours) +- **Engagement**: Social media, comments (2-3 hours) + +### Monthly +- **Review analytics**: Traffic, popular content +- **Update projects**: Status, screenshots +- **Dependency updates**: npm audit, security patches + +### Quarterly +- **Content audit**: Update outdated posts +- **SEO review**: Keyword performance, backlinks +- **Performance audit**: Lighthouse scores, Core Web Vitals + +--- + +## 15. Success Metrics + +### Launch (Month 1) +- 500+ unique visitors +- 50+ email subscribers +- 20+ social shares +- 5+ inbound inquiries + +### Growth (Month 3) +- 2,000+ unique visitors +- 100+ email subscribers +- 5+ qualified leads + +### Long-term (Year 1) +- 5,000+ monthly visitors +- 300+ email subscribers +- 50+ customers attributed to content +- €15K+ customer acquisition value saved + +--- + +**Architecture designed by**: wh-leader +**Date**: May 8, 2026 +**Status**: Ready for implementation +**Next**: Break into atomic implementer tasks