Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 85143c0b05 | |||
| 8c11722608 | |||
| f252241f9e | |||
| e7fd109a7a |
+24
@@ -0,0 +1,24 @@
|
|||||||
|
# build output
|
||||||
|
dist/
|
||||||
|
# generated types
|
||||||
|
.astro/
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# logs
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
|
||||||
|
# environment variables
|
||||||
|
.env
|
||||||
|
.env.production
|
||||||
|
|
||||||
|
# macOS-specific files
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# jetbrains setting folder
|
||||||
|
.idea/
|
||||||
+527
@@ -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
|
||||||
@@ -0,0 +1,300 @@
|
|||||||
|
# Personal Portfolio Implementation Roadmap
|
||||||
|
|
||||||
|
**Project**: davidaragon.impresion3d.pro
|
||||||
|
**Goal**: Professional portfolio + dev blog for indie builder
|
||||||
|
**Timeline**: 4 weeks (3 weeks implementation + 1 week content/polish)
|
||||||
|
**Methodology**: Atomic task decomposition → Parallel implementation → Sequential deployment
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task Dependency Graph
|
||||||
|
|
||||||
|
```
|
||||||
|
Foundation (Week 1)
|
||||||
|
====================
|
||||||
|
t_28db7e16: [#29-impl-1] Initialize Astro + Tailwind + TypeScript
|
||||||
|
└── t_0078b4b3: [#29-impl-2] Content collections (blog + projects schemas)
|
||||||
|
├── t_0ec36bde: [#29-impl-3] Base layout (Header, Footer, Nav)
|
||||||
|
│ ├── t_6e85e022: [#29-impl-4] About page ║
|
||||||
|
│ ├── t_7aa42f76: [#29-impl-5] Homepage (hero + featured) ║
|
||||||
|
│ ├── t_b7d940a1: [#29-impl-6] Blog pages + RSS ║
|
||||||
|
│ └── t_26ed02cc: [#29-impl-7] Projects pages ║
|
||||||
|
└── (All above) ──→ t_66684b8f: [#29-impl-8] Docker deployment
|
||||||
|
|
||||||
|
Content & Polish (Week 3-4)
|
||||||
|
============================
|
||||||
|
t_c4e23cc8: [#29-impl-9] Blog content (5 posts) ║
|
||||||
|
t_637198bd: [#29-impl-10] Project case studies (3 projects) ║
|
||||||
|
t_8f00b91a: [#29-impl-11] SEO optimization (structured data, OG, analytics)
|
||||||
|
|
||||||
|
Legend:
|
||||||
|
║ = Can run in parallel
|
||||||
|
└── = Must wait for parent
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase Breakdown
|
||||||
|
|
||||||
|
### Phase 1: Foundation (Week 1)
|
||||||
|
|
||||||
|
**Priority: P1** (all tasks blocking)
|
||||||
|
|
||||||
|
| Task ID | Title | Assignee | Est. Time | Blocks |
|
||||||
|
|---------|-------|----------|-----------|--------|
|
||||||
|
| t_28db7e16 | Initialize Astro + Tailwind | wh-implementer | 2-3h | ALL |
|
||||||
|
| t_0078b4b3 | Content collections | wh-implementer | 3-4h | Layouts + Pages |
|
||||||
|
| t_0ec36bde | Base layout | wh-implementer | 3-4h | All pages |
|
||||||
|
| t_6e85e022 | About page | wh-implementer | 2-3h | - |
|
||||||
|
| t_7aa42f76 | Homepage hero | wh-implementer | 3-4h | - |
|
||||||
|
|
||||||
|
**Parallelization opportunity**: After #29-impl-3 completes, tasks #29-impl-4, #29-impl-5, #29-impl-6, #29-impl-7 can ALL run simultaneously (4 parallel tracks).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 2: Pages & Features (Week 2)
|
||||||
|
|
||||||
|
**Priority: P1-P2**
|
||||||
|
|
||||||
|
| Task ID | Title | Assignee | Est. Time | Parallel? |
|
||||||
|
|---------|-------|----------|-----------|-----------|
|
||||||
|
| t_b7d940a1 | Blog pages + RSS | wh-implementer | 4-5h | YES ║ |
|
||||||
|
| t_26ed02cc | Projects pages | wh-implementer | 3-4h | YES ║ |
|
||||||
|
|
||||||
|
**Can run in parallel** with #29-impl-4 and #29-impl-5.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 3: Deployment (Week 2-3)
|
||||||
|
|
||||||
|
**Priority: P1** (blocks launch)
|
||||||
|
|
||||||
|
| Task ID | Title | Assignee | Est. Time | Depends on |
|
||||||
|
|---------|-------|----------|-----------|------------|
|
||||||
|
| t_66684b8f | Docker + Nginx + Portainer | wh-implementer | 4-5h | ALL pages (impl-1 through impl-7) |
|
||||||
|
|
||||||
|
**Must wait** for all page implementation tasks to complete (can't deploy empty site).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 4: Content Creation (Week 3-4)
|
||||||
|
|
||||||
|
**Priority: P2** (nice-to-have for MVP, critical for launch)
|
||||||
|
|
||||||
|
| Task ID | Title | Assignee | Est. Time | Parallel? |
|
||||||
|
|---------|-------|----------|-----------|-----------|
|
||||||
|
| t_c4e23cc8 | Blog posts (5 articles) | wh-writer | 6-8h | YES ║ |
|
||||||
|
| t_637198bd | Project case studies (3 projects) | wh-writer | 4-5h | YES ║ |
|
||||||
|
|
||||||
|
**Can run in parallel** (different content types, no dependencies).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 5: SEO & Polish (Week 4)
|
||||||
|
|
||||||
|
**Priority: P3** (launch enhancement)
|
||||||
|
|
||||||
|
| Task ID | Title | Assignee | Est. Time | Depends on |
|
||||||
|
|---------|-------|----------|-----------|------------|
|
||||||
|
| t_8f00b91a | SEO optimization | wh-implementer | 2-3h | ALL pages |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Critical Path Analysis
|
||||||
|
|
||||||
|
**Longest sequential path** (critical path):
|
||||||
|
|
||||||
|
```
|
||||||
|
impl-1 (3h) → impl-2 (4h) → impl-3 (4h) → impl-8 (5h) = 16 hours
|
||||||
|
```
|
||||||
|
|
||||||
|
**With parallelization**:
|
||||||
|
|
||||||
|
```
|
||||||
|
Week 1: impl-1 (3h) → impl-2 (4h) → impl-3 (4h) = 11h
|
||||||
|
Week 2: impl-4, impl-5, impl-6, impl-7 in parallel (max 5h)
|
||||||
|
Week 2: impl-8 (5h)
|
||||||
|
Week 3-4: impl-9, impl-10 in parallel (max 8h)
|
||||||
|
Week 4: impl-11 (3h)
|
||||||
|
|
||||||
|
Total calendar time: 3-4 weeks
|
||||||
|
Total sequential hours: 16h (foundation) + 5h (pages) + 5h (deploy) + 8h (content) + 3h (SEO) = 37 hours
|
||||||
|
With parallelization: ~27 hours of actual work
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Assignee Profiles
|
||||||
|
|
||||||
|
| Profile | Responsibilities | Skills | Tasks |
|
||||||
|
|---------|------------------|--------|-------|
|
||||||
|
| **wh-implementer** | Code implementation | Astro, React, Docker, FastAPI | impl-1 through impl-8, impl-11 |
|
||||||
|
| **wh-writer** | Content creation | Spanish writing, technical writing, SEO | impl-9, impl-10 |
|
||||||
|
| **wh-leader** | Orchestration | Planning, Gitea issues, monitoring | This task (t_22a3d7db) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Kanban Board States
|
||||||
|
|
||||||
|
All tasks created in **`todo`** state.
|
||||||
|
|
||||||
|
Transition rules:
|
||||||
|
- `todo` → `ready`: When all parent tasks in `done`
|
||||||
|
- `ready` → `running`: Dispatcher assigns to available worker
|
||||||
|
- `running` → `done`: Worker calls `kanban_complete(...)`
|
||||||
|
- `running` → `blocked`: Worker needs human input
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Acceptance Gates
|
||||||
|
|
||||||
|
### Gate 1: Foundation Complete (Week 1)
|
||||||
|
- [ ] Tasks impl-1, impl-2, impl-3 in `done`
|
||||||
|
- [ ] `npm run dev` starts without errors
|
||||||
|
- [ ] Tailwind CSS working (test with colored elements)
|
||||||
|
- [ ] Content collections validated (no schema errors)
|
||||||
|
- [ ] Header, Footer, Navigation visible
|
||||||
|
|
||||||
|
### Gate 2: Pages Complete (Week 2)
|
||||||
|
- [ ] Tasks impl-4, impl-5, impl-6, impl-7 in `done`
|
||||||
|
- [ ] All pages accessible (`/`, `/about`, `/blog`, `/projects`)
|
||||||
|
- [ ] No TypeScript errors
|
||||||
|
- [ ] No broken links
|
||||||
|
- [ ] Responsive design works (mobile, tablet, desktop)
|
||||||
|
|
||||||
|
### Gate 3: Deployment Ready (Week 2-3)
|
||||||
|
- [ ] Task impl-8 in `done`
|
||||||
|
- [ ] Docker image builds successfully
|
||||||
|
- [ ] Final image size <50MB
|
||||||
|
- [ ] Health check passes
|
||||||
|
- [ ] Site accessible at http://localhost:3010
|
||||||
|
- [ ] Nginx serves static files with gzip compression
|
||||||
|
|
||||||
|
### Gate 4: Content Published (Week 3-4)
|
||||||
|
- [ ] Tasks impl-9, impl-10 in `done`
|
||||||
|
- [ ] At least 3 blog posts published
|
||||||
|
- [ ] At least 2 project case studies published
|
||||||
|
- [ ] All content validates against schemas
|
||||||
|
- [ ] No typos or grammar errors
|
||||||
|
|
||||||
|
### Gate 5: SEO Optimized (Week 4)
|
||||||
|
- [ ] Task impl-11 in `done`
|
||||||
|
- [ ] Sitemap generated and accessible
|
||||||
|
- [ ] robots.txt present
|
||||||
|
- [ ] Structured data validates (Google Rich Results Test)
|
||||||
|
- [ ] OG preview looks correct (opengraph.xyz)
|
||||||
|
- [ ] Analytics configured (if using)
|
||||||
|
|
||||||
|
### Gate 6: Production Launch
|
||||||
|
- [ ] All 11 implementation tasks in `done`
|
||||||
|
- [ ] All 6 acceptance gates passed
|
||||||
|
- [ ] Portainer stack deployed to 192.168.1.30:3010
|
||||||
|
- [ ] HTTPS working via Traefik (davidaragon.impresion3d.pro)
|
||||||
|
- [ ] DNS pointing to correct server
|
||||||
|
- [ ] Health check passing
|
||||||
|
- [ ] Site accessible publicly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gitea Issue Mapping
|
||||||
|
|
||||||
|
All tasks map to **Gitea Issue #29**: "Build personal portfolio with blog and projects showcase"
|
||||||
|
|
||||||
|
Task naming convention: `[#29-impl-N] Description`
|
||||||
|
|
||||||
|
This allows tracking all work back to the single strategic Gitea issue while maintaining atomic Kanban tasks for execution.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Known Blockers & Mitigations
|
||||||
|
|
||||||
|
### Blocker 1: Git Push Authentication
|
||||||
|
**Status**: BLOCKED
|
||||||
|
**Impact**: Cannot push commits to GitLab
|
||||||
|
**Mitigation**:
|
||||||
|
- Commits created locally (all changes staged)
|
||||||
|
- Push manually after SSH key configured
|
||||||
|
- Or: use personal access token with HTTPS
|
||||||
|
|
||||||
|
**Resolution needed**: SSH key or GitLab personal access token
|
||||||
|
|
||||||
|
### Blocker 2: Real Images (OG, Favicon, Avatar)
|
||||||
|
**Status**: LOW PRIORITY
|
||||||
|
**Impact**: Site uses placeholders for images
|
||||||
|
**Mitigation**:
|
||||||
|
- Create placeholders in implementation tasks
|
||||||
|
- Replace with real images before launch
|
||||||
|
- Can launch with placeholders if needed (not blocking)
|
||||||
|
|
||||||
|
**Resolution**: Create professional OG image (1200x630), favicon set, avatar photo
|
||||||
|
|
||||||
|
### Blocker 3: Analytics Configuration
|
||||||
|
**Status**: OPTIONAL
|
||||||
|
**Impact**: No traffic analytics initially
|
||||||
|
**Mitigation**:
|
||||||
|
- Launch without analytics (privacy-first)
|
||||||
|
- Or: set up self-hosted Plausible later
|
||||||
|
- Not blocking for MVP
|
||||||
|
|
||||||
|
**Resolution**: Optional - configure Plausible after launch
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Success Metrics
|
||||||
|
|
||||||
|
### Development Metrics
|
||||||
|
- [ ] 11 tasks completed in 4 weeks
|
||||||
|
- [ ] Zero P1 bugs at launch
|
||||||
|
- [ ] <50MB Docker image size
|
||||||
|
- [ ] >80% test coverage (if tests added)
|
||||||
|
- [ ] 100% TypeScript strict compliance
|
||||||
|
|
||||||
|
### Product Metrics (post-launch)
|
||||||
|
- Lighthouse Score: >90 (all categories)
|
||||||
|
- Core Web Vitals: Pass (LCP <2.5s, FID <100ms, CLS <0.1)
|
||||||
|
- Uptime: >99% (monitor with UptimeRobot)
|
||||||
|
- Page load: <2s (first contentful paint)
|
||||||
|
|
||||||
|
### Content Metrics (Month 1)
|
||||||
|
- 3-5 blog posts published
|
||||||
|
- 2-3 project case studies published
|
||||||
|
- RSS subscribers: goal 50+
|
||||||
|
- Organic traffic: goal 100+ visitors/month
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Post-Launch Roadmap
|
||||||
|
|
||||||
|
### Month 1-2: Content Cadence
|
||||||
|
- Publish 2 blog posts per week
|
||||||
|
- Update project case studies with metrics
|
||||||
|
- Add 1-2 more projects (Garage61 API, etc.)
|
||||||
|
|
||||||
|
### Month 3-4: Features
|
||||||
|
- Newsletter signup backend (ConvertKit/Mailchimp)
|
||||||
|
- Comments system (Giscus/Utterances)
|
||||||
|
- Search functionality
|
||||||
|
- Dark/light mode toggle
|
||||||
|
|
||||||
|
### Month 5-6: Growth
|
||||||
|
- Guest posts on Spanish indie blogs
|
||||||
|
- X (Twitter) thread automation from blog posts
|
||||||
|
- SEO optimization (internal linking, backlinks)
|
||||||
|
- Analytics dashboard (public metrics page)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contact & Support
|
||||||
|
|
||||||
|
**Project Owner**: David Aragón (caleidos)
|
||||||
|
**Primary Agent**: wh-leader (orchestrator)
|
||||||
|
**Repository**: https://gitlab.impresion3d.pro/root/davidaragon-portfolio
|
||||||
|
**Deployment**: 192.168.1.30:3010 → davidaragon.impresion3d.pro
|
||||||
|
|
||||||
|
**Blockers?** Comment on Kanban task or create Gitea issue.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Generated**: 2026-05-08
|
||||||
|
**Last Updated**: 2026-05-08
|
||||||
|
**Status**: ✅ Ready for execution
|
||||||
@@ -0,0 +1,231 @@
|
|||||||
|
# Portfolio Project Status - Orchestration Summary
|
||||||
|
|
||||||
|
**Date**: 2026-05-08
|
||||||
|
**Orchestrator**: wh-leader
|
||||||
|
**Task**: t_22a3d7db
|
||||||
|
**Gitea Issue**: #29
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ Orchestration Complete
|
||||||
|
|
||||||
|
Successfully decomposed personal portfolio project into **11 atomic implementation tasks** with clear dependencies, assignees, and acceptance criteria.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Tasks Created
|
||||||
|
|
||||||
|
| ID | Title | Assignee | Phase | Priority | Status |
|
||||||
|
|----|-------|----------|-------|----------|--------|
|
||||||
|
| t_28db7e16 | [#29-impl-1] Initialize Astro + Tailwind + TypeScript | wh-implementer | Foundation | P1 | todo |
|
||||||
|
| t_0078b4b3 | [#29-impl-2] Content collections (blog + projects) | wh-implementer | Foundation | P1 | todo |
|
||||||
|
| t_0ec36bde | [#29-impl-3] Base layout (Header, Footer, Nav) | wh-implementer | Foundation | P1 | todo |
|
||||||
|
| t_6e85e022 | [#29-impl-4] About page | wh-implementer | Foundation | P2 | todo |
|
||||||
|
| t_7aa42f76 | [#29-impl-5] Homepage (hero + featured) | wh-implementer | Foundation | P1 | todo |
|
||||||
|
| t_b7d940a1 | [#29-impl-6] Blog pages + RSS feed | wh-implementer | Pages | P2 | todo |
|
||||||
|
| t_26ed02cc | [#29-impl-7] Projects pages | wh-implementer | Pages | P2 | todo |
|
||||||
|
| t_66684b8f | [#29-impl-8] Docker deployment | wh-implementer | Deployment | P1 | todo |
|
||||||
|
| t_c4e23cc8 | [#29-impl-9] Blog content (5 posts) | wh-writer | Content | P2 | todo |
|
||||||
|
| t_637198bd | [#29-impl-10] Project case studies (3 projects) | wh-writer | Content | P2 | todo |
|
||||||
|
| t_8f00b91a | [#29-impl-11] SEO optimization | wh-implementer | Polish | P3 | todo |
|
||||||
|
|
||||||
|
**Total**: 11 tasks
|
||||||
|
**Estimated effort**: 37 hours sequential, ~27 hours with parallelization
|
||||||
|
**Timeline**: 4 weeks
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 Dependency Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
Foundation (Sequential)
|
||||||
|
=======================
|
||||||
|
impl-1 → impl-2 → impl-3
|
||||||
|
↓
|
||||||
|
Pages (Parallel after impl-3)
|
||||||
|
==============================
|
||||||
|
impl-4 ║ impl-5 ║ impl-6 ║ impl-7
|
||||||
|
↓
|
||||||
|
Deployment (Sequential, waits for all pages)
|
||||||
|
============================================
|
||||||
|
impl-8
|
||||||
|
|
||||||
|
Content (Parallel, independent)
|
||||||
|
================================
|
||||||
|
impl-9 ║ impl-10
|
||||||
|
|
||||||
|
Polish (Sequential, waits for all pages)
|
||||||
|
=========================================
|
||||||
|
impl-11
|
||||||
|
```
|
||||||
|
|
||||||
|
**Critical Path**: impl-1 → impl-2 → impl-3 → impl-8 (16 hours)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📄 Documentation Created
|
||||||
|
|
||||||
|
1. **ARCHITECTURE.md** (15.7KB)
|
||||||
|
- Complete technical architecture
|
||||||
|
- Tech stack breakdown (Astro, Tailwind, Docker, Nginx)
|
||||||
|
- Directory structure
|
||||||
|
- Deployment strategy
|
||||||
|
- Content types and schemas
|
||||||
|
- SEO and performance requirements
|
||||||
|
|
||||||
|
2. **IMPLEMENTATION-ROADMAP.md** (9.4KB)
|
||||||
|
- Task dependency graph
|
||||||
|
- Phase breakdown with timing
|
||||||
|
- Critical path analysis
|
||||||
|
- Assignee profiles
|
||||||
|
- Acceptance gates (6 gates)
|
||||||
|
- Known blockers and mitigations
|
||||||
|
- Success metrics
|
||||||
|
- Post-launch roadmap
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Key Decisions
|
||||||
|
|
||||||
|
### Tech Stack
|
||||||
|
- **Framework**: Astro (static site generation, fast)
|
||||||
|
- **Styling**: Tailwind CSS (design system, dark mode)
|
||||||
|
- **Language**: TypeScript strict mode (type safety)
|
||||||
|
- **Content**: Astro Content Collections (type-safe markdown)
|
||||||
|
- **Deployment**: Docker + Nginx (production-ready)
|
||||||
|
- **Orchestration**: Portainer (container management)
|
||||||
|
- **Proxy**: Traefik (automatic HTTPS)
|
||||||
|
|
||||||
|
### Architecture Patterns
|
||||||
|
- **Spanish-first**: All UI text in Spanish (es-ES locale)
|
||||||
|
- **Dark mode only**: No light mode toggle (simplicity)
|
||||||
|
- **Static generation**: All pages pre-rendered (performance)
|
||||||
|
- **Content types**: Blog posts + project case studies
|
||||||
|
- **SEO-first**: Sitemap, structured data, OG tags
|
||||||
|
- **Privacy-focused**: No cookies, optional analytics (Plausible)
|
||||||
|
|
||||||
|
### Deployment Strategy
|
||||||
|
- **Host**: 192.168.1.30:3010
|
||||||
|
- **Domain**: davidaragon.impresion3d.pro
|
||||||
|
- **HTTPS**: Via Traefik with Let's Encrypt
|
||||||
|
- **Image**: Multi-stage Docker build (<50MB)
|
||||||
|
- **Server**: Nginx with gzip, caching, security headers
|
||||||
|
- **Health checks**: Built-in for monitoring
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ Known Blockers
|
||||||
|
|
||||||
|
### 1. Git Push Authentication
|
||||||
|
**Status**: BLOCKED
|
||||||
|
**Impact**: Cannot push commits to GitLab (2 commits staged locally)
|
||||||
|
**Mitigation**: Commits created locally, will push when SSH key configured
|
||||||
|
**Action needed**: Configure SSH key or personal access token
|
||||||
|
|
||||||
|
### 2. Real Images
|
||||||
|
**Status**: OPTIONAL
|
||||||
|
**Impact**: Placeholders for OG image, favicon, avatar
|
||||||
|
**Mitigation**: Launch with placeholders, replace later
|
||||||
|
**Action needed**: Create 1200x630 OG image, favicon set, avatar photo
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Success Criteria
|
||||||
|
|
||||||
|
### Development (Gates 1-3)
|
||||||
|
- [ ] All foundation tasks complete (impl-1, impl-2, impl-3)
|
||||||
|
- [ ] All page tasks complete (impl-4 through impl-7)
|
||||||
|
- [ ] Docker deployment working (impl-8)
|
||||||
|
- [ ] Site accessible locally at http://localhost:3010
|
||||||
|
- [ ] No TypeScript errors, no broken links
|
||||||
|
|
||||||
|
### Content (Gate 4)
|
||||||
|
- [ ] 3-5 blog posts published (impl-9)
|
||||||
|
- [ ] 2-3 project case studies (impl-10)
|
||||||
|
- [ ] All content validates against schemas
|
||||||
|
|
||||||
|
### SEO (Gate 5)
|
||||||
|
- [ ] Structured data validates (Google Rich Results Test)
|
||||||
|
- [ ] OG preview looks correct (opengraph.xyz)
|
||||||
|
- [ ] Sitemap generated and accessible
|
||||||
|
|
||||||
|
### Launch (Gate 6)
|
||||||
|
- [ ] HTTPS working via Traefik
|
||||||
|
- [ ] DNS pointing to davidaragon.impresion3d.pro
|
||||||
|
- [ ] Health check passing
|
||||||
|
- [ ] Uptime monitoring configured
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Next Steps
|
||||||
|
|
||||||
|
### Immediate (Dispatcher)
|
||||||
|
1. Dispatcher picks up tasks in `todo` state
|
||||||
|
2. Promotes impl-1 to `ready` (no dependencies)
|
||||||
|
3. Assigns to wh-implementer profile
|
||||||
|
4. Worker executes impl-1 → impl-2 → impl-3 sequentially
|
||||||
|
|
||||||
|
### Week 1 (Foundation)
|
||||||
|
- wh-implementer completes impl-1, impl-2, impl-3
|
||||||
|
- Gate 1 acceptance: Foundation complete
|
||||||
|
|
||||||
|
### Week 2 (Pages - Parallel)
|
||||||
|
- wh-implementer can work on impl-4, impl-5, impl-6, impl-7 in parallel
|
||||||
|
- All 4 tasks can be dispatched simultaneously
|
||||||
|
- Gate 2 acceptance: Pages complete
|
||||||
|
|
||||||
|
### Week 2-3 (Deployment)
|
||||||
|
- wh-implementer completes impl-8
|
||||||
|
- Test locally before Portainer deployment
|
||||||
|
- Gate 3 acceptance: Deployment ready
|
||||||
|
|
||||||
|
### Week 3-4 (Content)
|
||||||
|
- wh-writer completes impl-9 and impl-10 in parallel
|
||||||
|
- Gate 4 acceptance: Content published
|
||||||
|
|
||||||
|
### Week 4 (Polish + Launch)
|
||||||
|
- wh-implementer completes impl-11 (SEO)
|
||||||
|
- Gate 5 acceptance: SEO optimized
|
||||||
|
- Manual Portainer deployment to 192.168.1.30
|
||||||
|
- Gate 6 acceptance: Production launch
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Lessons & Patterns
|
||||||
|
|
||||||
|
### Atomic Task Design
|
||||||
|
- Each task touches 1-3 files maximum
|
||||||
|
- Clear acceptance criteria (checkboxes)
|
||||||
|
- One implementer can complete without coordination
|
||||||
|
- Verifiable in single session (<5 hours)
|
||||||
|
|
||||||
|
### Dependency Management
|
||||||
|
- Sequential where necessary (foundation)
|
||||||
|
- Parallel where possible (pages, content)
|
||||||
|
- Clear parent-child relationships in Kanban
|
||||||
|
|
||||||
|
### Documentation First
|
||||||
|
- ARCHITECTURE.md before any code
|
||||||
|
- IMPLEMENTATION-ROADMAP.md before any tasks
|
||||||
|
- Both docs committed to repo (source of truth)
|
||||||
|
|
||||||
|
### Assignee Specialization
|
||||||
|
- wh-implementer: Code, infra, deployment (9 tasks)
|
||||||
|
- wh-writer: Content, Spanish writing (2 tasks)
|
||||||
|
- wh-leader: Orchestration, planning (1 task)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔗 References
|
||||||
|
|
||||||
|
- **Repository**: https://gitlab.impresion3d.pro/root/davidaragon-portfolio
|
||||||
|
- **Gitea Issue**: #29 (Build personal portfolio)
|
||||||
|
- **Architecture**: /home/caleidos/code_ubuntu/davidaragon-portfolio/ARCHITECTURE.md
|
||||||
|
- **Roadmap**: /home/caleidos/code_ubuntu/davidaragon-portfolio/IMPLEMENTATION-ROADMAP.md
|
||||||
|
- **Strategic Plan**: /home/caleidos/code_ubuntu/planificacion_empresarial/ideas/019-personal-portfolio-blog/
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Orchestrator**: wh-leader
|
||||||
|
**Completed**: 2026-05-08
|
||||||
|
**Status**: ✅ Ready for dispatcher to assign workers
|
||||||
@@ -1,3 +1,43 @@
|
|||||||
# davidaragon-portfolio
|
# Astro Starter Kit: Minimal
|
||||||
|
|
||||||
Personal tech portfolio and dev blog - davidaragon.impresion3d.pro
|
```sh
|
||||||
|
npm create astro@latest -- --template minimal
|
||||||
|
```
|
||||||
|
|
||||||
|
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||||
|
|
||||||
|
## 🚀 Project Structure
|
||||||
|
|
||||||
|
Inside of your Astro project, you'll see the following folders and files:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/
|
||||||
|
├── public/
|
||||||
|
├── src/
|
||||||
|
│ └── pages/
|
||||||
|
│ └── index.astro
|
||||||
|
└── package.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
||||||
|
|
||||||
|
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
||||||
|
|
||||||
|
Any static assets, like images, can be placed in the `public/` directory.
|
||||||
|
|
||||||
|
## 🧞 Commands
|
||||||
|
|
||||||
|
All commands are run from the root of the project, from a terminal:
|
||||||
|
|
||||||
|
| Command | Action |
|
||||||
|
| :------------------------ | :----------------------------------------------- |
|
||||||
|
| `npm install` | Installs dependencies |
|
||||||
|
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
||||||
|
| `npm run build` | Build your production site to `./dist/` |
|
||||||
|
| `npm run preview` | Preview your build locally, before deploying |
|
||||||
|
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||||
|
| `npm run astro -- --help` | Get help using the Astro CLI |
|
||||||
|
|
||||||
|
## 👀 Want to learn more?
|
||||||
|
|
||||||
|
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { defineConfig } from 'astro/config';
|
||||||
|
import tailwind from '@astrojs/tailwind';
|
||||||
|
import sitemap from '@astrojs/sitemap';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
site: 'https://davidaragon.impresion3d.pro',
|
||||||
|
integrations: [
|
||||||
|
tailwind(),
|
||||||
|
sitemap(),
|
||||||
|
],
|
||||||
|
markdown: {
|
||||||
|
shikiConfig: {
|
||||||
|
theme: 'dark-plus',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
Generated
+6841
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "davidaragon-portfolio",
|
||||||
|
"type": "module",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.14.1"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "astro dev",
|
||||||
|
"build": "astro build",
|
||||||
|
"preview": "astro preview",
|
||||||
|
"astro": "astro"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"astro": "^5.0.0",
|
||||||
|
"zod": "^3.23.8"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@astrojs/rss": "^4.0.18",
|
||||||
|
"@astrojs/sitemap": "^3.7.2",
|
||||||
|
"@astrojs/tailwind": "^6.0.2",
|
||||||
|
"tailwindcss": "^3.4.17",
|
||||||
|
"@tailwindcss/typography": "^0.5.15"
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 655 B |
@@ -0,0 +1,9 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
|
||||||
|
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
|
||||||
|
<style>
|
||||||
|
path { fill: #000; }
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
path { fill: #FFF; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 749 B |
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta name="generator" content={Astro.generator} />
|
||||||
|
<title>Astro</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Astro</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
body {
|
||||||
|
@apply bg-background text-text-primary font-sans;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
module.exports = {
|
||||||
|
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,ts,tsx}'],
|
||||||
|
darkMode: 'class',
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
background: '#0a0e27',
|
||||||
|
surface: '#131729',
|
||||||
|
primary: '#60a5fa',
|
||||||
|
secondary: '#a78bfa',
|
||||||
|
text: {
|
||||||
|
primary: '#f1f5f9',
|
||||||
|
secondary: '#94a3b8',
|
||||||
|
tertiary: '#64748b',
|
||||||
|
},
|
||||||
|
accent: {
|
||||||
|
green: '#34d399',
|
||||||
|
red: '#f87171',
|
||||||
|
yellow: '#fbbf24',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
sans: ['Inter', 'sans-serif'],
|
||||||
|
mono: ['JetBrains Mono', 'monospace'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [require('@tailwindcss/typography')],
|
||||||
|
};
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"extends": "astro/tsconfigs/strict",
|
||||||
|
"include": [".astro/types.d.ts", "**/*"],
|
||||||
|
"exclude": ["dist"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user