Files
opencode-skill/skills/website-creator/SKILL.md

835 lines
21 KiB
Markdown

---
name: website-creator
description: Create PDPA-compliant Astro websites with i18n, Umami Analytics, cookie consent, and Easypanel deployment.
---
# 🌐 Website Creator Skill
**Skill Name:** `website-creator`
**Category:** `deep`
**Load Skills:** `[]` (standalone)
---
## 🎯 Purpose
Create and deploy **PDPA-compliant** Astro websites on Easypanel automatically with:
-**Bilingual support** (Thai/English)
-**Umami Analytics** (privacy-first, no cookies)
-**Cookie consent management** (astro-consent)
-**Consent logging database** (Astro DB + Turso)
-**PDPA-compliant legal pages** (Privacy Policy, Terms)
-**Easypanel deployment** (Docker, auto-deploy)
**Use Cases:**
1. **New Website** - Build from ground up with all compliance features
2. **Redesign** - Crawl existing website and rebuild with Astro + PDPA compliance
3. **Refactor** - Update existing websites to new standard structure
---
## 🚀 Workflow
### Phase 0: Pre-Flight (Critical Questions)
**MUST ask before starting:**
1. **Website Type:**
- Corporate (products, services, blog)
- Portfolio (showcase, gallery)
- Landing Page (single page, product launch)
- Blog/Magazine (content-focused)
- E-commerce (with Snipcart/Stripe)
- Custom (describe)
2. **Website Name:** (e.g., "Deal Plus Tech")
3. **Brand/Company Name:** (for title, meta)
4. **Language Strategy:**
- Thai only (th)
- English only (en)
- Bilingual Thai + English (th + en, with fallback)
- **Default:** Bilingual with English as default
5. **For Redesign/Refactor:**
- Original website URL or path?
- What to preserve? (content, design, URLs)
- What to improve?
6. **Features Needed:**
- **Base (always included):**
- Responsive design
- SEO optimization
- Bilingual i18n routing
- Cookie consent banner
- Consent logging DB
- Umami Analytics
- PDPA-compliant Privacy Policy
- PDPA-compliant Terms
- Contact forms
- Social media links
- Dark mode
- Blog with content collections
- **Additional:**
- Product catalog
- Portfolio/gallery
- Multi-language beyond TH/EN
- E-commerce (Snipcart/Stripe)
7. **Color Scheme/Branding:**
- Primary color (hex)
- Secondary color (hex)
- Logo file (or generate placeholder)
8. **Analytics Configuration:**
- **Umami Analytics** (required for PDPA compliance)
- Umami Website ID (provide now or fill later in .env)
- Umami Domain (self-hosted or cloud)
9. **Admin Credentials:**
- Admin password for consent logs viewer (CHANGE THIS!)
- **Default:** `changeme` (MUST change in production)
---
### Phase 1: Discovery & Planning
**Automated steps:**
1. **Analyze Requirements** - Map features to components
2. **Plan Structure** - Define folder structure based on languages
3. **Check Compliance** - Verify all PDPA requirements covered
4. **Create Timeline** - Estimate build time (typically 5-10 min)
---
### Phase 2: Setup & Generation
#### For New Website:
1. **Create Project Structure**
```
website-name/
├── src/
│ ├── pages/
│ │ ├── en/ # English pages
│ │ ├── th/ # Thai pages
│ │ └── admin/ # Admin dashboard
│ ├── components/
│ ├── layouts/
│ └── content/
├── db/ # Astro DB schema
├── Dockerfile
└── package.json
```
2. **Configure i18n Routing**
- English default: `/about`, `/contact`
- Thai prefixed: `/th/about`, `/th/contact`
- Fallback: Thai → English for missing translations
3. **Install Dependencies**
```bash
npm install astro @astrojs/db @astrojs/sitemap
npm install astro-consent drizzle-orm @libsql/client
npm install tailwindcss @tailwindcss/vite
```
4. **Add Base Features**
- Cookie consent banner (astro-consent)
- Consent logging API endpoints
- Umami Analytics (conditional loading)
- Language switcher component
- PDPA-compliant Privacy Policy (TH/EN)
- PDPA-compliant Terms & Conditions (TH/EN)
#### For Redesign:
1. **Crawl Original Website:**
- Visit original URL
- Extract all pages, products, blog posts
- Download all images
- Preserve original URLs
- Create content summary document
- Save image file list for reference
2. **Rebuild with Astro:**
- Create matching route structure
- Migrate content to Markdown/Content Collections
- Preserve SEO data (meta titles, descriptions)
- Reuse downloaded images
- Add PDPA compliance features
#### For Refactor:
1. **Backup Existing Content**
- Export blog posts
- Export products
- Save custom pages
2. **Apply New Structure**
- Reorganize folders
- Add i18n routing
- Integrate consent system
- Add Umami Analytics
- Update Dockerfile
3. **Migrate Content**
- Move blog posts to content collections
- Preserve URLs (redirects if needed)
- Update internal links
---
### Phase 3: Legal Pages Generation
**PDPA-Compliant Privacy Policy (Section 36 Requirements):**
1. ✅ Data Controller Information
2. ✅ Types of Data Collected
3. ✅ Purpose of Data Processing
4. ✅ Legal Basis for Processing
5. ✅ Data Retention Period
6. ✅ Data Sharing & Disclosure
7. ✅ Cross-border Transfers (if applicable)
8. ✅ Automated Decision Making (if applicable)
9. ✅ Cookies & Tracking Technologies
10. ✅ Data Subject Rights (8 PDPA rights)
11. ✅ Data Security Measures
12. ✅ DPO Contact (if applicable)
13. ✅ Right to Lodge Complaint (PDPC)
14. ✅ Policy Version & Last Updated
**PDPA-Compliant Terms & Conditions:**
1. ✅ Acceptance of Terms
2. ✅ Services Description
3. ✅ Intellectual Property Rights
4. ✅ User Obligations
5. ✅ Limitation of Liability
6. ✅ Termination Conditions
7. ✅ Governing Law (Thailand)
8. ✅ Dispute Resolution
9. ✅ Modifications to Terms
10. ✅ Contact Information
**Language:** Generated in Thai, English, or both based on configuration.
---
### Phase 4: Cookie Consent Implementation
**Consent Flow:**
1. **Banner Display** (First Visit)
- Essential cookies: Always ON (cannot reject)
- Analytics cookies: Opt-in required
- Marketing cookies: Opt-in required
- Equal prominence: Accept | Reject | Customize
2. **Consent Storage**
- localStorage: User preferences
- Database: Audit trail (PDPA compliance)
- Session ID: Unique identifier
- Timestamp: When consent given
- Policy Version: Track which version accepted
3. **Script Loading** (Conditional)
```javascript
if (consent.analytics) {
// Load Umami Analytics
}
if (consent.marketing) {
// Load marketing scripts
}
```
4. **Withdrawal Mechanism**
- Footer link: "Cookie Preferences"
- Modal: Re-open consent banner
- One-click withdrawal
- Immediate script unloading
**Database Schema (ConsentLog):**
```typescript
{
id: number (PK),
sessionId: string (unique),
timestamp: datetime,
locale: 'en' | 'th',
essential: boolean,
analytics: boolean,
marketing: boolean,
policyVersion: string,
ipHash: string (SHA256, first 16 chars),
userAgent: string
}
```
---
### Phase 5: Umami Analytics Integration
**Configuration:**
1. **Umami Setup:**
- Self-host on Easypanel (recommended)
- Or use Umami Cloud
- Create website in Umami dashboard
- Get Website ID
2. **Integration:**
```astro
<!-- Conditional loading in BaseLayout.astro -->
<script is:inline>
const consent = JSON.parse(
localStorage.getItem('consent-preferences') || '{}'
);
if (consent.analytics) {
// Load Umami script
const script = document.createElement('script');
script.defer = true;
script.src = 'https://analytics.domain.com/script.js';
script.setAttribute('data-website-id', 'xxx-xxx-xxx');
document.head.appendChild(script);
}
</script>
```
3. **Privacy Features:**
- No cookies used
- No fingerprinting
- No personal data collected
- GDPR/PDPA compliant out-of-the-box
- Self-hosted = data stays on your servers
**Note:** Umami does NOT require consent for basic analytics (no personal data). However, we still respect user choice and load conditionally.
---
### Phase 6: Admin Dashboard
**Consent Logs Viewer:**
- **URL:** `/admin/consent-logs`
- **Authentication:** Simple password (env: `ADMIN_PASSWORD`)
- **Features:**
- View all consent records (last 100)
- Filter by date, locale, consent type
- Export to CSV
- Delete individual records (right to be forgotten)
- Search by session ID
**Security:**
- Change default password immediately
- Consider adding rate limiting
- Add IP whitelist for production
- Use HTTPS only
---
### Phase 7: Docker Setup
**Dockerfile:**
```dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/db ./db
# SQLite runtime
RUN apk add --no-cache sqlite-libs
EXPOSE 80
ENV NODE_ENV=production
ENV ASTRO_DB_REMOTE_URL=file:/app/data/consent.db
CMD ["sh", "-c", "mkdir -p /app/data && npx astro preview --host 0.0.0.0 --port 80"]
```
**Test Locally:**
```bash
docker build -t website:latest .
docker run -p 80:80 \
-e UMAMI_WEBSITE_ID=xxx \
-e ADMIN_PASSWORD=secure-pass \
website:latest
# Verify in browser: http://localhost
```
---
### Phase 8: Git & Easypanel Deployment
**Two deployment options:**
#### Option A: Manual Easypanel Deployment (Current)
1. **Create Gitea Repository:**
- Use Gitea API at `git.moreminimore.com`
- Create repo with website name
- Push initial code
2. **Use easypanel-deploy Skill:**
```
/use easypanel-deploy deploy
→ Project name: {website-name}
→ Service name: {website-name}-service
→ Git URL: https://git.moreminimore.com/user/{website-name}.git
→ Branch: main
→ Port: 80
```
3. **Verify Deployment:**
```
/use easypanel-deploy status
→ Project name: {website-name}
→ Service name: {website-name}-service
```
#### Option B: Automatic Deployment (Future Enhancement)
The skill can be extended to call `easypanel-deploy` automatically via subprocess or task delegation. This would:
- Push code to Gitea automatically
- Call easypanel-deploy skill
- Return deployment URL to user
**Implementation would require:**
```python
# In create_astro_website.py
def deploy_to_easypanel(project_name, service_name, git_url):
"""Deploy to Easypanel using easypanel-deploy skill."""
# Option 1: Call easypanel-deploy via task()
# Option 2: Execute curl commands directly
pass
```
---
### Phase 9: Documentation
**Generated Files:**
1. **DEPLOYMENT.md**
- How Easypanel is configured
- Auto-deploy workflow
- Environment variables
- Database setup
- Umami configuration
2. **CONTENT-GUIDE.md**
- How to add blog posts (Markdown format)
- How to add products
- Image guidelines
- Bilingual content management
- AI blog writing guide
3. **CHECKLIST.md**
- Update workflow
- Testing steps
- Rollback procedure
- PDPA compliance checklist
4. **PDPA-COMPLIANCE.md**
- Privacy policy requirements
- Cookie consent implementation
- Consent logging
- Data subject rights procedures
- Breach notification process
5. **README.md**
- Quick start guide
- Development commands
- Project structure
- Tech stack
---
## 📁 Output Structure
```
website-name/
├── public/
│ ├── favicon.ico
│ ├── favicon.svg
│ └── images/
├── src/
│ ├── components/
│ │ ├── common/
│ │ │ ├── Header.astro
│ │ │ ├── Footer.astro
│ │ │ └── LanguageSwitcher.astro
│ │ ├── consent/
│ │ │ ├── CookieBanner.astro
│ │ │ └── ConsentPreferences.astro
│ │ └── ui/
│ │ ├── Button.astro
│ │ └── Card.astro
│ │
│ ├── layouts/
│ │ └── BaseLayout.astro
│ │
│ ├── pages/
│ │ ├── index.astro
│ │ ├── th/
│ │ │ ├── index.astro
│ │ │ ├── about.astro
│ │ │ ├── contact.astro
│ │ │ ├── privacy-policy.astro
│ │ │ ├── terms-and-conditions.astro
│ │ │ └── blog/
│ │ │ ├── index.astro
│ │ │ └── [slug].astro
│ │ ├── en/
│ │ │ ├── index.astro
│ │ │ ├── about.astro
│ │ │ ├── contact.astro
│ │ │ ├── privacy-policy.astro
│ │ │ ├── terms-and-conditions.astro
│ │ │ └── blog/
│ │ │ ├── index.astro
│ │ │ └── [slug].astro
│ │ └── admin/
│ │ └── consent-logs.astro
│ │
│ ├── pages/api/
│ │ └── consent/
│ │ ├── POST.ts
│ │ ├── GET.ts
│ │ └── [sessionId]/DELETE.ts
│ │
│ ├── styles/
│ │ └── global.css
│ │
│ ├── content/
│ │ ├── blog/
│ │ │ ├── (th)/
│ │ │ └── (en)/
│ │ └── config.ts
│ │
│ ├── lib/
│ │ ├── i18n.ts
│ │ ├── consent.ts
│ │ └── utils.ts
│ │
│ └── middleware.ts
├── db/
│ ├── config.ts
│ └── seed.ts
├── Dockerfile
├── docker-compose.yml
├── package.json
├── astro.config.mjs
├── tailwind.config.mjs
├── tsconfig.json
├── .env.example
├── .gitignore
├── README.md
├── DEPLOYMENT.md
├── CONTENT-GUIDE.md
├── CHECKLIST.md
└── PDPA-COMPLIANCE.md
```
---
## 🔧 Tools Used
- **Astro 5.x** - Static site generator with i18n, hybrid rendering
- **Tailwind CSS 4.x** - Utility-first CSS framework
- **Astro DB** - SQLite database for consent logging
- **Turso** - Managed libSQL for production (optional)
- **astro-consent** - Cookie consent management
- **Umami Analytics** - Privacy-first web analytics
- **Docker** - Containerization
- **Gitea** - Git repository (git.moreminimore.com)
- **Easypanel** - Deployment platform
---
## 🔐 Environment Variables
**Required (set in .env):**
```bash
# Umami Analytics
UMAMI_WEBSITE_ID=your-website-id-here
UMAMI_DOMAIN=analytics.example.com
# Admin
ADMIN_PASSWORD=change-this-secure-password
# Database (optional - defaults to SQLite file)
ASTRO_DB_REMOTE_URL=libsql://your-db.turso.io
ASTRO_DB_APP_TOKEN=your-turso-token
# Site Configuration
SITE_URL=https://example.com
SITE_NAME="Example Website"
```
**Security:**
- NEVER commit `.env` file
- Use `.env.example` as template
- Change `ADMIN_PASSWORD` before deployment
- Use strong passwords in production
---
## 📐 Typography Guidelines
**CRITICAL: All websites MUST follow these guidelines for readability on big screens.**
### Desktop First Approach
```css
html {
font-size: 18px; /* Base size - NOT 16px */
}
@media (min-width: 1280px) {
html { font-size: 20px; }
}
@media (min-width: 1536px) {
html { font-size: 22px; }
}
@media (min-width: 1920px) {
html { font-size: 24px; }
}
```
### Minimum Font Sizes
| Element | Minimum Size | Tailwind Class |
|---------|-------------|----------------|
| Body text | 18px (base) | `text-base` |
| Small text | 16px | `text-sm` (minimum!) |
| Large text | 20px | `text-lg` |
| XL text | 24px | `text-xl` |
### What NOT to Use
❌ **NEVER use:**
- `text-xs` (12px) - Too small!
- `text-sm` without responsive increase
- `font-size: 14px` or smaller
✅ **ALWAYS use:**
- `text-base` minimum for body text
- `text-lg` or larger for important content
- Responsive increases: `text-base md:text-lg lg:text-xl`
---
## ⚠️ Important Notes
1. **Hybrid Rendering** - Static pages + server endpoints for API
2. **Database** - SQLite file (dev) → Turso (production, optional)
3. **Main Branch Only** - Direct to production
4. **Auto-Deploy** - Easypanel watches Git
5. **Markdown Content** - Blog/posts as Markdown files
6. **Preserve URLs** - For redesign, keep original URL structure
7. **PDPA Compliance** - All legal pages include required disclosures
8. **Consent Logging** - Audit trail for 10+ years (PDPA requirement)
9. **Right to be Forgotten** - API endpoint for consent deletion
10. **Bilingual Default** - Thai + English with fallback
---
## 🎯 Success Criteria
- ✅ Website builds locally (`npm run dev`)
- ✅ Docker build succeeds
- ✅ Gitea repo created
- ✅ Easypanel service created
- ✅ Auto-deploy enabled
- ✅ Website accessible via browser
- ✅ i18n routing works (TH/EN switch)
- ✅ Cookie consent appears on first visit
- ✅ Consent logged to database
- ✅ Umami loads only with consent
- ✅ Admin page accessible with password
- ✅ Privacy Policy PDPA-compliant
- ✅ Terms & Conditions PDPA-compliant
- ✅ Data deletion works (right to be forgotten)
- ✅ Documentation complete
---
## 🔄 Ongoing Maintenance
**When user asks to:**
- **Add content** → Create Markdown in correct language folder, commit, auto-deploy
- **Fix bugs** → Fix code, commit, auto-deploy
- **Update design** → Update components, commit, auto-deploy
- **Update legal pages** → Edit privacy-policy.astro / terms.astro, commit, auto-deploy
- **View consent logs** → Navigate to `/admin/consent-logs`, login with password
- **Delete consent data** → Use admin dashboard or call DELETE `/api/consent/{sessionId}`
**All updates automatic via Easypanel auto-deploy!**
---
## 📋 PDPA Compliance Checklist
**Before deployment, verify:**
### Privacy Policy
- [ ] Contains all 14 Section 36 disclosures
- [ ] Available in Thai (or bilingual)
- [ ] Accessible before data collection
- [ ] Version number and last updated date
- [ ] DPO contact (if applicable)
- [ ] Complaint process (PDPC)
### Cookie Consent
- [ ] Opt-in model (not pre-ticked)
- [ ] Granular choices (essential/analytics/marketing)
- [ ] Equal prominence for Accept/Reject
- [ ] Withdrawal as easy as acceptance
- [ ] Script blocking until consent
- [ ] Consent recorded with timestamp
### Consent Logging
- [ ] Database stores all consent records
- [ ] Session ID unique per user
- [ ] Policy version tracked
- [ ] IP hashed (not raw)
- [ ] Retention period defined (10+ years)
- [ ] Deletion mechanism exists
### Data Subject Rights
- [ ] Right to access (provide data copy)
- [ ] Right to rectification (correct data)
- [ ] Right to erasure (delete data)
- [ ] Right to restrict processing
- [ ] Right to data portability
- [ ] Right to object
- [ ] Right to withdraw consent
- [ ] Process documented in admin guide
### Security
- [ ] Admin password changed from default
- [ ] HTTPS enabled
- [ ] Rate limiting on API endpoints
- [ ] SQL injection prevention (using ORM)
- [ ] XSS prevention (Astro escapes by default)
---
## 🚀 Commands
### Development
```bash
# Install dependencies
npm install
# Start dev server
npm run dev
# Build for production
npm run build
# Preview build
npm run preview
# Push DB schema (development)
npm run db:push
# Seed development data
npm run db:seed
```
### Production
```bash
# Build with remote database
npm run build --remote
# Push DB schema to Turso
npm run db:push --remote
# Docker build
docker build -t website:latest .
# Docker run
docker run -p 80:80 \
-e UMAMI_WEBSITE_ID=xxx \
-e ADMIN_PASSWORD=secure-pass \
-e ASTRO_DB_REMOTE_URL=file:/app/data/consent.db \
website:latest
```
---
## 📞 Support
**For issues:**
1. Check `PDPA-COMPLIANCE.md` for legal requirements
2. Check `DEPLOYMENT.md` for Easypanel setup
3. Check `CONTENT-GUIDE.md` for content management
4. Review Astro DB docs for database issues
5. Check Umami docs for analytics issues
**Admin Dashboard:**
- URL: `https://your-domain.com/admin/consent-logs`
- Default password: `changeme` (CHANGE THIS!)
---
## 📝 Examples
### Generate New Website
```bash
python3 scripts/create_astro_website.py \
--name "Deal Plus Tech" \
--type "corporate" \
--languages "th,en" \
--primary-color "#2563eb" \
--secondary-color "#1e40af" \
--features "blog,products,contact" \
--umami-id "xxx-xxx-xxx" \
--output "./dealplustech-website"
# Local only (skip Gitea/Easypanel):
python3 scripts/create_astro_website.py \
--name "My Website" \
--local-only \
--output "./my-website"
```
### Refactor Existing Website
```bash
python3 scripts/refactor_website.py \
--input "./dealplustech-astro" \
--output "./dealplustech-astro-refactored" \
--add-features "i18n,consent,umami" \
--languages "th,en"
```
---
**All websites created with this skill are PDPA-compliant, bilingual-ready, and production-ready for Thai market.**