Files
opencode-skill/skills/website-creator/templates/consent
Kunthawat Greethong 628298183a feat: migrate website-creator from Next.js+Payload to Astro+Tina CMS
Major changes:
- Replace Payload CMS with Tina CMS (self-hosted)
- Add Astro DB for consent logging (PDPA compliant)
- Update Tailwind v3 to v4 (@tailwindcss/vite plugin)
- Add astro-tina-starter template
- Rewrite consent template for Astro (ConsentBanner.astro, Astro DB, Nano Stores)
- Add install-tina-backend.sh for self-hosted Tina per customer
- Rename convert-astro.sh to migrate-tina.sh
- Add AGENTS.md template for generated websites
- Delete all Payload/Next.js files

Technical updates:
- Astro DB using defineDb with eq operators for queries
- Tailwind v4 with @theme block
- Tina CMS local development mode
- Proper Astro API routes for consent

Research-verified with official documentation (April 2026)
2026-04-17 14:52:59 +07:00
..

PDPA Consent Logging Template

Template สำหรับเพิ่ม PDPA consent logging ใน Astro + Tina (Astro DB)

Files

consent/
├── ConsentBanner.astro      # Consent banner component
├── api/
│   └── consent.ts           # API endpoints (GET, POST, DELETE)
├── db/
│   └── config.ts            # Astro DB schema (defineTable)
├── stores/
│   └── consent.ts          # Nano Stores for client state
└── README.md               # This file

วิธีใช้ (Astro)

1. เพิ่ม Astro DB Schema

Copy db/config.ts ไปที่ src/db/config.ts:

// src/db/config.ts
import { defineTable, column } from 'astro:db';

export const ConsentLog = defineTable({
  columns: {
    id: column.number({ primaryKey: true }),
    action: column.text(),
    purpose: column.text(),
    analytics: column.boolean({ default: false }),
    marketing: column.boolean({ default: false }),
    functional: column.boolean({ default: false }),
    userAgent: column.text({ optional: true }),
    ip: column.text({ optional: true }),
    timestamp: column.date(),
    sessionId: column.text({ optional: true }),
  },
});

2. สร้าง API Endpoint

Copy api/consent.ts ไปที่ src/pages/api/consent.ts

3. เพิ่ม ConsentBanner Component

Copy ConsentBanner.astro ไปที่ src/components/consent/ConsentBanner.astro

4. เพิ่มใน Layout

เพิ่ม <ConsentBanner /> ใน src/layouts/Layout.astro:

---
import ConsentBanner from '../components/consent/ConsentBanner.astro';
---

<html lang="th">
  <body>
    <slot />
    <ConsentBanner />
  </body>
</html>

API

POST /api/consent

บันทึก consent action

Request:

{
  "action": "accept",
  "purpose": "all",
  "analytics": true,
  "marketing": false,
  "functional": true
}

Response:

{
  "success": true,
  "doc": {
    "id": 1,
    "action": "accept",
    "purpose": "all",
    "analytics": true,
    "marketing": false,
    "functional": true,
    "userAgent": "Mozilla/5.0...",
    "ip": "127.0.0.1",
    "timestamp": "2026-04-10T00:00:00.000Z"
  }
}

GET /api/consent

ดึง consent logs

curl "http://localhost:4321/api/consent"

DELETE /api/consent

Right to be forgotten (ลบข้อมูลตาม พ.ร.บ.)

curl -X DELETE "http://localhost:4321/api/consent?sessionId=xxx"

Nano Stores Usage

import { consentStore, hasAnalyticsConsent, hasMarketingConsent } from './stores/consent';

// Subscribe to changes
consentStore.subscribe((state) => {
  console.log('Consent changed:', state);
});

// Check consent
if (hasAnalyticsConsent()) {
  // Load analytics
}

UX

  • ยอมรับทั้งหมด - เปิดทุกคุกกี้
  • ปฏิเสธทั้งหมด - ปิดทุกคุกกี้ (ยกเว้น functional)
  • ตั้งค่าคุกกี้ - แผงปรับแต่งเอง

⚠️ Pitfalls สำคัญ

  1. Astro DB ต้องรันบน server-side - ใช้ APIRoute import
  2. Nano Stores รันบน client-side - ใช้ <script> tag ใน Astro
  3. import ถูกต้อง - ใช้ import { db } from 'astro:db' ไม่ใช่ defineDb