feat(thai-frontend-dev): update consent system to better-sqlite3

- Replace Astro DB with better-sqlite3 (bypasses remote SQLite limitation)
- Add consent API with auto-create table pattern
- Update admin dashboard to fetch from API instead of Astro DB
- Add IP hashing and rate limiting for GDPR compliance
- Add seo-utils-mcp-guide skill
- Update legal templates with business placeholders
This commit is contained in:
Kunthawat Greethong
2026-04-01 18:36:51 +07:00
parent e4d41e3ae5
commit 5053ccdba2
6 changed files with 539 additions and 499 deletions

View File

@@ -0,0 +1,67 @@
---
name: seo-utils-mcp-guide
description: |
Background knowledge for using SEO Utils MCP tools correctly. Helps choose the right tool
(local database vs API) for SEO data queries. Use when: user asks about SEO data, rank tracker,
keyword research, GSC data, backlink analysis, or any SEO-related queries.
---
# SEO Utils MCP Tool Selection Guide
When the user asks about SEO data, use this guide to pick the correct tool.
## Rule 1: Local Data vs API Data
The user has TWO types of SEO data:
**Local database** (synced/tracked over time) — use `query_database` or `query_gsc`:
- Organic Rank Tracker reports → `organic_rank_tracker_*` tables
- Google Business Rank Tracker → `google_business_rank_tracker_*` tables
- Google Search Console data → `search_console_*` tables (use `query_gsc`)
- LLM Rank Tracker → `llm_rank_tracker_*` tables
- Content Struct outlines → `content_struct*` tables
- NLP Analysis → `nlp_analysis_*` tables
- NAP Finder → `nap_finder_*` tables
- Saved Keywords → `saved_keywords_*` tables
- Automations → `automations`, `automation_*` tables
- Indexing status → `site_urls`, `index_now_urls` tables
- Log Analysis → `log_analysis_*` tables
- SEO Tests → `tests`, `test_*` tables
**DataForSEO API** (on-demand, third-party estimates) — use action tools:
- `get_keyword_suggestions` / `get_bing_related_keywords` — keyword research
- `get_organic_keywords` — what keywords a domain ranks for (estimated)
- `get_traffic_summary` / `get_historical_rank` — traffic estimates
- `get_traffic_competitors` / `get_top_pages` — competitor/page analysis
- `fetch_backlinks` / `get_backlink_summary` / etc. — backlink data
- `bulk_traffic_analysis` / `bulk_backlink_analysis` — multi-domain comparison
- `check_keyword_metrics` — search volume, KD, CPC
- `fetch_serp_data` — live SERP results
## Rule 2: Common Mistakes to Avoid
| User says | WRONG tool | CORRECT approach |
|-----------|-----------|-----------------|
| "rank tracker report" or "my rankings" | `get_organic_keywords` | `query_database` on `organic_rank_tracker_*` tables |
| "keyword cannibalization" | `get_organic_keywords` | `query_database` on `search_console_query_pages` |
| "trending queries" or "GSC data" | `get_organic_keywords` | `query_gsc` on `search_console_queries` |
| "my backlink history" | `fetch_backlinks` | Could be either — ask if they mean tracked data or fresh API data |
| "optimization opportunities" | `get_organic_keywords` | `query_database` on `search_console_query_pages` + `search_console_query_page_mentions` |
| "weak pages" or "low CTR pages" | `get_organic_keywords` | `query_gsc` on `search_console_pages` or `search_console_queries` |
| "my automations" | N/A | `query_database` on `automations` table |
| "content brief" or "content outline" | N/A | `query_database` on `content_struct_layout_headings` + `content_struct_layout_metadata` |
## Rule 3: When to Use API Tools
Use DataForSEO API action tools ONLY when:
- User asks about a **domain they don't track** (competitor research)
- User explicitly asks for **fresh/live data** from DataForSEO
- User wants **keyword suggestions** or **keyword metrics** for new keywords
- User wants **backlink data** for any domain
- User wants to **compare multiple domains** (bulk analysis)
## Rule 4: Export and Send
- `send_email` — send any email with SMTP. Check `smtp_credentials` table first
- Automations — use `create_automation` for recurring workflows (triggered by events)
- For one-time exports, generate the content and use `send_email` to deliver it

View File

@@ -22,7 +22,7 @@ Create and deploy **PDPA-compliant** Astro websites on Easypanel automatically w
-**Bilingual support** (Thai/English) -**Bilingual support** (Thai/English)
-**Umami Analytics** (privacy-first, no cookies) -**Umami Analytics** (privacy-first, no cookies)
-**Cookie consent management** (astro-consent) -**Cookie consent management** (astro-consent)
-**Consent logging database** (Astro DB + Turso) -**Consent logging database** (better-sqlite3 - direct SQLite, bypasses Astro DB limitation)
-**PDPA-compliant legal pages** (Privacy Policy, Terms) -**PDPA-compliant legal pages** (Privacy Policy, Terms)
-**Easypanel deployment** (Docker, auto-deploy) -**Easypanel deployment** (Docker, auto-deploy)
@@ -256,22 +256,26 @@ Create and deploy **PDPA-compliant** Astro websites on Easypanel automatically w
- One-click withdrawal - One-click withdrawal
- Immediate script unloading - Immediate script unloading
**Database Schema (ConsentLog):** **Database Schema (ConsentLog - better-sqlite3):**
```typescript ```typescript
{ {
id: number (PK), id: number (PK, autoincrement),
sessionId: string (unique), sessionId: string (UNIQUE),
timestamp: datetime, timestamp: datetime (ISO string),
locale: 'en' | 'th', essential: boolean (0/1),
essential: boolean, analytics: boolean (0/1),
analytics: boolean, marketing: boolean (0/1),
marketing: boolean,
policyVersion: string, policyVersion: string,
ipHash: string (SHA256, first 16 chars), ipHash: string (SHA256, first 16 chars),
userAgent: string userAgent: string
} }
``` ```
**Why better-sqlite3 instead of Astro DB?**
- Astro DB cannot create new tables with remote SQLite (`ASTRO_DB_REMOTE_URL=file:...`)
- better-sqlite3 bypasses this limitation completely
- Auto-creates table on API startup (`CREATE TABLE IF NOT EXISTS`)
--- ---
### Phase 5: Umami Analytics Integration ### Phase 5: Umami Analytics Integration
@@ -336,34 +340,36 @@ Create and deploy **PDPA-compliant** Astro websites on Easypanel automatically w
### Phase 7: Docker Setup ### Phase 7: Docker Setup
**Dockerfile:** **Dockerfile (better-sqlite3):**
```dockerfile ```dockerfile
FROM node:20-alpine AS builder FROM node:20-alpine
WORKDIR /app WORKDIR /app
# Install build dependencies for better-sqlite3 native module
RUN apk add --no-cache python3 make g++
# Install dependencies
COPY package*.json ./ COPY package*.json ./
RUN npm ci RUN npm install
# Copy source
COPY . . COPY . .
# Build
RUN npm run build RUN npm run build
FROM node:20-alpine # Serve
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 EXPOSE 80
CMD ["npm", "run", "preview"]
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"]
``` ```
**Key differences from Astro DB approach:**
- Uses `node:20-alpine` with build tools for native module compilation
- `better-sqlite3` creates SQLite file at `data/consent.db` automatically
- No `ASTRO_DB_REMOTE_URL` needed - bypasses Astro DB limitation
**Test Locally:** **Test Locally:**
```bash ```bash
@@ -513,9 +519,8 @@ website-name/
│ │ │ │
│ ├── pages/api/ │ ├── pages/api/
│ │ └── consent/ │ │ └── consent/
│ │ ├── POST.ts │ │ ├── index.ts # GET, POST
│ │ ── GET.ts │ │ ── [sessionId].ts # DELETE
│ │ └── [sessionId]/DELETE.ts
│ │ │ │
│ ├── styles/ │ ├── styles/
│ │ └── global.css │ │ └── global.css
@@ -529,13 +534,12 @@ website-name/
│ ├── lib/ │ ├── lib/
│ │ ├── i18n.ts │ │ ├── i18n.ts
│ │ ├── consent.ts │ │ ├── consent.ts
│ │ └── utils.ts │ │ └── db.ts # better-sqlite3 setup
│ │ │ │
│ └── middleware.ts │ └── middleware.ts
├── db/ ├── data/ # SQLite database (auto-created)
── config.ts ── consent.db
│ └── seed.ts
├── Dockerfile ├── Dockerfile
├── docker-compose.yml ├── docker-compose.yml
@@ -558,11 +562,10 @@ website-name/
- **Astro 5.x** - Static site generator with i18n, hybrid rendering - **Astro 5.x** - Static site generator with i18n, hybrid rendering
- **Tailwind CSS 4.x** - Utility-first CSS framework - **Tailwind CSS 4.x** - Utility-first CSS framework
- **Astro DB** - SQLite database for consent logging - **better-sqlite3** - Direct SQLite for consent logging (bypasses Astro DB limitation)
- **Turso** - Managed libSQL for production (optional)
- **astro-consent** - Cookie consent management - **astro-consent** - Cookie consent management
- **Umami Analytics** - Privacy-first web analytics - **Umami Analytics** - Privacy-first web analytics
- **Docker** - Containerization - **Docker** - Containerization (alpine for native module support)
- **Gitea** - Git repository (git.moreminimore.com) - **Gitea** - Git repository (git.moreminimore.com)
- **Easypanel** - Deployment platform - **Easypanel** - Deployment platform
@@ -580,15 +583,13 @@ UMAMI_DOMAIN=analytics.example.com
# Admin # Admin
ADMIN_PASSWORD=change-this-secure-password 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 Configuration
SITE_URL=https://example.com SITE_URL=https://example.com
SITE_NAME="Example Website" SITE_NAME="Example Website"
``` ```
**Note:** Database (SQLite) is created automatically at `data/consent.db`. No external database needed.
**Security:** **Security:**
- NEVER commit `.env` file - NEVER commit `.env` file
- Use `.env.example` as template - Use `.env.example` as template
@@ -647,7 +648,7 @@ html {
## ⚠️ Important Notes ## ⚠️ Important Notes
1. **Hybrid Rendering** - Static pages + server endpoints for API 1. **Hybrid Rendering** - Static pages + server endpoints for API
2. **Database** - SQLite file (dev) → Turso (production, optional) 2. **Database** - better-sqlite3 (direct SQLite, auto-creates tables)
3. **Main Branch Only** - Direct to production 3. **Main Branch Only** - Direct to production
4. **Auto-Deploy** - Easypanel watches Git 4. **Auto-Deploy** - Easypanel watches Git
5. **Markdown Content** - Blog/posts as Markdown files 5. **Markdown Content** - Blog/posts as Markdown files
@@ -656,6 +657,7 @@ html {
8. **Consent Logging** - Audit trail for 10+ years (PDPA requirement) 8. **Consent Logging** - Audit trail for 10+ years (PDPA requirement)
9. **Right to be Forgotten** - API endpoint for consent deletion 9. **Right to be Forgotten** - API endpoint for consent deletion
10. **Bilingual Default** - Thai + English with fallback 10. **Bilingual Default** - Thai + English with fallback
11. **Docker Alpine** - Uses alpine for better-sqlite3 native module compilation
--- ---
@@ -757,23 +759,11 @@ npm run build
# Preview build # Preview build
npm run preview npm run preview
# Push DB schema (development)
npm run db:push
# Seed development data
npm run db:seed
``` ```
### Production ### Production
```bash ```bash
# Build with remote database
npm run build --remote
# Push DB schema to Turso
npm run db:push --remote
# Docker build # Docker build
docker build -t website:latest . docker build -t website:latest .
@@ -781,7 +771,6 @@ docker build -t website:latest .
docker run -p 80:80 \ docker run -p 80:80 \
-e UMAMI_WEBSITE_ID=xxx \ -e UMAMI_WEBSITE_ID=xxx \
-e ADMIN_PASSWORD=secure-pass \ -e ADMIN_PASSWORD=secure-pass \
-e ASTRO_DB_REMOTE_URL=file:/app/data/consent.db \
website:latest website:latest
``` ```

View File

@@ -193,7 +193,6 @@ def ask_analytics_setup():
ASTRO_CONFIG_TEMPLATE = """import {{ defineConfig }} from 'astro/config'; ASTRO_CONFIG_TEMPLATE = """import {{ defineConfig }} from 'astro/config';
import tailwindcss from '@tailwindcss/vite'; import tailwindcss from '@tailwindcss/vite';
import db from '@astrojs/db';
import sitemap from '@astrojs/sitemap'; import sitemap from '@astrojs/sitemap';
export default defineConfig({{ export default defineConfig({{
@@ -212,13 +211,22 @@ export default defineConfig({{
}}, }},
integrations: [ integrations: [
tailwindcss(), tailwindcss(),
db(),
sitemap({{ sitemap({{
i18n: {{ i18n: {{
defaultLocale: '{default_locale}', defaultLocale: '{default_locale}',
}}, }},
}}), }}),
], ],
vite: {{
optimizeDeps: {{
exclude: ['better-sqlite3']
}},
build: {{
rollupOptions: {{
external: ['better-sqlite3']
}}
}}
}}
}}); }});
""" """
@@ -228,25 +236,217 @@ PACKAGE_JSON_TEMPLATE = """{{
"version": "1.0.0", "version": "1.0.0",
"scripts": {{ "scripts": {{
"dev": "astro dev", "dev": "astro dev",
"build": "astro build --remote", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"astro": "astro", "astro": "astro"
"db:push": "astro db push --remote",
"db:seed": "astro db seed"
}}, }},
"dependencies": {{ "dependencies": {{
"astro": "^5.17.1", "astro": "^5.17.1",
"@astrojs/db": "^0.14.0",
"@astrojs/sitemap": "^3.2.0", "@astrojs/sitemap": "^3.2.0",
"@tailwindcss/vite": "^4.2.1", "@tailwindcss/vite": "^4.2.1",
"tailwindcss": "^4.2.1", "tailwindcss": "^4.2.1",
"astro-consent": "^1.0.0", "better-sqlite3": "^11.0.0"
"drizzle-orm": "^0.38.0", }},
"@libsql/client": "^0.14.0" "devDependencies": {{
"@types/better-sqlite3": "^7.6.8"
}} }}
}} }}
""" """
# ==============================================================================
# CONSENT API TEMPLATES (using better-sqlite3 directly)
# ==============================================================================
CONSENT_DB_TEMPLATE = """import Database from 'better-sqlite3';
import {{ join }} from 'path';
import {{ mkdirSync, existsSync }} from 'fs';
const DATA_DIR = join(process.cwd(), 'data');
const DB_PATH = join(DATA_DIR, 'consent.db');
export function getDb() {{
// 1. Create directory if not exists
if (!existsSync(DATA_DIR)) {{
mkdirSync(DATA_DIR, {{ recursive: true }});
}}
// 2. Open database
const db = new Database(DB_PATH);
// 3. Auto-create table (works with remote SQLite!)
db.exec(`
CREATE TABLE IF NOT EXISTS ConsentLog (
id INTEGER PRIMARY KEY AUTOINCREMENT,
sessionId TEXT UNIQUE NOT NULL,
timestamp TEXT NOT NULL,
essential INTEGER NOT NULL DEFAULT 0,
analytics INTEGER NOT NULL DEFAULT 0,
marketing INTEGER NOT NULL DEFAULT 0,
policyVersion TEXT NOT NULL,
ipHash TEXT,
userAgent TEXT
)
`);
return db;
}}
// Rate limiting map
const rateLimitMap = new Map<string, {{ count: number; resetTime: number }}>();
const RATE_LIMIT = 10;
const RATE_WINDOW = 60000; // 1 minute
export function checkRateLimit(ip: string): boolean {{
const now = Date.now();
const record = rateLimitMap.get(ip);
if (!record || now > record.resetTime) {{
rateLimitMap.set(ip, {{ count: 1, resetTime: now + RATE_WINDOW }});
return true;
}}
if (record.count >= RATE_LIMIT) {{
return false;
}}
record.count++;
return true;
}}
// IP Hashing for privacy (GDPR compliance)
export async function hashIP(ip: string): Promise<string> {{
try {{
if (crypto.subtle) {{
const hashBuffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(ip));
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
return hashHex.substring(0, 16);
}}
}} catch {{}}
return `fallback-${Date.now()}`;
}}
"""
CONSENT_API_INDEX_TEMPLATE = """import type {{ APIRoute }} from 'astro';
import {{ getDb, checkRateLimit, hashIP }} from '../../../../lib/db';
export const GET: APIRoute = async ({{ clientAddress }}) => {{
// Rate limit check
const ip = clientAddress || 'unknown';
if (!checkRateLimit(ip)) {{
return new Response(
JSON.stringify({{ error: 'Rate limit exceeded' }}),
{{ status: 429, headers: {{ 'Content-Type': 'application/json' }} }}
);
}}
try {{
const db = getDb();
const logs = db.prepare(`
SELECT * FROM ConsentLog
ORDER BY timestamp DESC
LIMIT 100
`).all();
db.close();
return new Response(
JSON.stringify({{ logs }}),
{{ status: 200, headers: {{ 'Content-Type': 'application/json' }} }}
);
}} catch (error) {{
return new Response(
JSON.stringify({{ error: 'Failed to fetch logs' }}),
{{ status: 500 }}
);
}}
}};
export const POST: APIRoute = async ({{ request, clientAddress }}) => {{
try {{
const body = await request.json();
const {{ sessionId, essential, analytics, marketing, policyVersion, userAgent }} = body;
// Validate required fields
if (!sessionId || essential === undefined || !policyVersion) {{
return new Response(
JSON.stringify({{ error: 'Missing required fields' }}),
{{ status: 400, headers: {{ 'Content-Type': 'application/json' }} }}
);
}}
const db = getDb();
const ipHash = await hashIP(clientAddress || 'unknown');
const timestamp = new Date().toISOString();
// Insert with prepared statement (prevents SQL injection)
const stmt = db.prepare(`
INSERT INTO ConsentLog (sessionId, timestamp, essential, analytics, marketing, policyVersion, ipHash, userAgent)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
`);
stmt.run(
sessionId,
timestamp,
essential ? 1 : 0,
analytics ? 1 : 0,
marketing ? 1 : 0,
policyVersion,
ipHash,
userAgent || 'unknown'
);
db.close();
return new Response(
JSON.stringify({{ success: true, sessionId }}),
{{ status: 201, headers: {{ 'Content-Type': 'application/json' }} }}
);
}} catch (error) {{
return new Response(
JSON.stringify({{ error: 'Failed to log consent' }}),
{{ status: 500 }}
);
}}
}};
"""
CONSENT_API_DELETE_TEMPLATE = """import type {{ APIRoute }} from 'astro';
import {{ getDb }} from '../../../../lib/db';
export const DELETE: APIRoute = async ({{ params }}) => {{
const {{ sessionId }} = params;
if (!sessionId) {{
return new Response(
JSON.stringify({{ error: 'Session ID required' }}),
{{ status: 400, headers: {{ 'Content-Type': 'application/json' }} }}
);
}}
try {{
const db = getDb();
const stmt = db.prepare('DELETE FROM ConsentLog WHERE sessionId = ?');
const result = stmt.run(sessionId);
db.close();
if (result.changes === 0) {{
return new Response(
JSON.stringify({{ error: 'Record not found' }}),
{{ status: 404 }}
);
}}
return new Response(
JSON.stringify({{ success: true }}),
{{ status: 200, headers: {{ 'Content-Type': 'application/json' }} }}
);
}} catch (error) {{
return new Response(
JSON.stringify({{ error: 'Failed to delete' }}),
{{ status: 500 }}
);
}}
}};
"""
# ... (rest of templates remain the same) # ... (rest of templates remain the same)
@@ -506,10 +706,12 @@ def create_project(args, languages, default_locale, features):
output_path / "src" / "layouts", output_path / "src" / "layouts",
output_path / "src" / "pages", output_path / "src" / "pages",
output_path / "src" / "pages" / default_locale, output_path / "src" / "pages" / default_locale,
output_path / "src" / "pages" / "admin",
output_path / "src" / "pages" / "api" / "consent",
output_path / "src" / "styles", output_path / "src" / "styles",
output_path / "src" / "content" / "blog", output_path / "src" / "content" / "blog",
output_path / "src" / "lib", output_path / "src" / "lib",
output_path / "db", output_path / "data",
] ]
for d in dirs: for d in dirs:
@@ -636,11 +838,42 @@ import Footer from '../components/common/Footer.astro';
print(" ✓ Basic pages created") print(" ✓ Basic pages created")
# Create Dockerfile # Create consent API with better-sqlite3 (bypasses Astro DB limitation)
dockerfile = f"""FROM node:20-slim lib_db_content = CONSENT_DB_TEMPLATE
(output_path / "src" / "lib" / "db.ts").write_text(lib_db_content, encoding="utf-8")
print(" ✓ Consent database library created (better-sqlite3)")
# Create consent API endpoints
consent_index = CONSENT_API_INDEX_TEMPLATE
(output_path / "src" / "pages" / "api" / "consent" / "index.ts").write_text(
consent_index, encoding="utf-8"
)
consent_delete = CONSENT_API_DELETE_TEMPLATE
consent_delete = consent_delete.replace("{{", "{").replace("}}", "}")
consent_delete = consent_delete.replace("[sessionId]", "[sessionId]")
(output_path / "src" / "pages" / "api" / "consent" / "[sessionId].ts").write_text(
consent_delete, encoding="utf-8"
)
print(" ✓ Consent API endpoints created")
# Create admin consent logs page
admin_consent_src = template_dir / "admin-consent-logs.astro"
if admin_consent_src.exists():
shutil.copy(
admin_consent_src,
output_path / "src" / "pages" / "admin" / "consent-logs.astro",
)
print(" ✓ Admin consent logs page copied")
# Create Dockerfile (using alpine for better-sqlite3 native module support)
dockerfile = f"""FROM node:20-alpine
WORKDIR /app WORKDIR /app
# Install build dependencies for better-sqlite3
RUN apk add --no-cache python3 make g++
# Install dependencies # Install dependencies
COPY package*.json ./ COPY package*.json ./
RUN npm install RUN npm install
@@ -656,7 +889,7 @@ EXPOSE 80
CMD ["npm", "run", "preview"] CMD ["npm", "run", "preview"]
""" """
(output_path / "Dockerfile").write_text(dockerfile, encoding="utf-8") (output_path / "Dockerfile").write_text(dockerfile, encoding="utf-8")
print(" ✓ Dockerfile created") print(" ✓ Dockerfile created (alpine for better-sqlite3)")
# Create .gitignore # Create .gitignore
gitignore = """# Dependencies gitignore = """# Dependencies

View File

@@ -1,8 +1,7 @@
--- ---
// Password-protected admin page for viewing consent logs // Password-protected admin page for viewing consent logs
import { db, ConsentLog, desc } from 'astro:db'; // Uses API instead of Astro DB (better-sqlite3) to bypass remote SQLite limitation
// Simple password protection (in production, use proper auth)
const ADMIN_PASSWORD = Astro.env.ADMIN_PASSWORD || 'changeme'; const ADMIN_PASSWORD = Astro.env.ADMIN_PASSWORD || 'changeme';
let logs = []; let logs = [];
@@ -16,9 +15,11 @@ if (Astro.request.method === 'POST') {
if (password === ADMIN_PASSWORD) { if (password === ADMIN_PASSWORD) {
isAuthenticated = true; isAuthenticated = true;
try { try {
logs = await db.select().from(ConsentLog).orderBy(desc(ConsentLog.timestamp)).limit(100); const response = await fetch('/api/consent');
const data = await response.json();
logs = data.logs || [];
} catch (err) { } catch (err) {
error = 'Failed to load consent logs. Make sure database is initialized.'; error = 'Failed to load consent logs. Make sure the API is running.';
console.error(err); console.error(err);
} }
} else { } else {
@@ -27,7 +28,7 @@ if (Astro.request.method === 'POST') {
} }
--- ---
<html lang="en"> <html lang="th">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
@@ -134,6 +135,8 @@ if (Astro.request.method === 'POST') {
} }
.actions { .actions {
margin-bottom: 1rem; margin-bottom: 1rem;
display: flex;
gap: 1rem;
} }
.btn { .btn {
display: inline-block; display: inline-block;
@@ -150,6 +153,15 @@ if (Astro.request.method === 'POST') {
.btn-primary:hover { .btn-primary:hover {
background: #1d4ed8; background: #1d4ed8;
} }
.btn-success {
background: #16a34a;
color: white;
border: none;
cursor: pointer;
}
.btn-success:hover {
background: #15803d;
}
.btn-danger { .btn-danger {
background: #dc2626; background: #dc2626;
color: white; color: white;
@@ -174,6 +186,24 @@ if (Astro.request.method === 'POST') {
background: #fee2e2; background: #fee2e2;
color: #dc2626; color: #dc2626;
} }
.info-box {
margin-top: 1rem;
padding: 1rem;
background: #fef3c7;
border-radius: 0.375rem;
}
.info-box h3 {
font-size: 0.875rem;
font-weight: 600;
margin-bottom: 0.5rem;
color: #92400e;
}
.info-box ul {
font-size: 0.75rem;
color: #92400e;
list-style: disc;
padding-left: 1.5rem;
}
</style> </style>
</head> </head>
<body> <body>
@@ -182,7 +212,7 @@ if (Astro.request.method === 'POST') {
{!isAuthenticated ? ( {!isAuthenticated ? (
<div class="login-form"> <div class="login-form">
<h2 class="text-xl font-bold mb-4">Admin Login</h2> <h2 style="font-size: 1.25rem; font-weight: bold; margin-bottom: 1rem;">Admin Login</h2>
{error && <div class="error">{error}</div>} {error && <div class="error">{error}</div>}
<form method="POST"> <form method="POST">
<div class="form-group"> <div class="form-group">
@@ -197,14 +227,15 @@ if (Astro.request.method === 'POST') {
</div> </div>
<button type="submit">Login</button> <button type="submit">Login</button>
</form> </form>
<p class="mt-4 text-sm text-gray-600"> <p style="margin-top: 1rem; font-size: 0.875rem; color: #6b7280;">
Default password: <code>changeme</code> (change in .env) Default password: <code>changeme</code> (change in .env)
</p> </p>
</div> </div>
) : ( ) : (
<div> <div>
<div class="actions flex gap-4 mb-4"> <div class="actions">
<a href="/admin/consent-logs" class="btn btn-primary">Refresh</a> <a href="/admin/consent-logs" class="btn btn-primary">Refresh</a>
<button class="btn btn-success" onclick="exportCSV()">Export CSV</button>
<a href="/" class="btn" style="background: #6b7280; color: white;">← Back to Site</a> <a href="/" class="btn" style="background: #6b7280; color: white;">← Back to Site</a>
</div> </div>
@@ -215,7 +246,6 @@ if (Astro.request.method === 'POST') {
<thead> <thead>
<tr> <tr>
<th>Date/Time</th> <th>Date/Time</th>
<th>Locale</th>
<th>Session ID</th> <th>Session ID</th>
<th>Essential</th> <th>Essential</th>
<th>Analytics</th> <th>Analytics</th>
@@ -228,15 +258,14 @@ if (Astro.request.method === 'POST') {
<tbody> <tbody>
{logs.length === 0 ? ( {logs.length === 0 ? (
<tr> <tr>
<td colspan="9" style="text-align: center; padding: 2rem;"> <td colspan="8" style="text-align: center; padding: 2rem;">
No consent logs found. Make sure the website has received consent. No consent logs found. Make sure the website has received consent.
</td> </td>
</tr> </tr>
) : ( ) : (
logs.map((log) => ( logs.map((log) => (
<tr> <tr>
<td>{new Date(log.timestamp).toLocaleString('en-GB')}</td> <td>{new Date(log.timestamp).toLocaleString('th-TH')}</td>
<td>{log.locale.toUpperCase()}</td>
<td style="font-family: monospace; font-size: 0.75rem;">{log.sessionId}</td> <td style="font-family: monospace; font-size: 0.75rem;">{log.sessionId}</td>
<td> <td>
<span class="badge badge-green">{log.essential ? 'Yes' : 'No'}</span> <span class="badge badge-green">{log.essential ? 'Yes' : 'No'}</span>
@@ -273,13 +302,13 @@ if (Astro.request.method === 'POST') {
</table> </table>
</div> </div>
<div style="margin-top: 1rem; padding: 1rem; background: #fef3c7; border-radius: 0.375rem;"> <div class="info-box">
<h3 style="font-size: 0.875rem; font-weight: 600; margin-bottom: 0.5rem;">⚠️ Important Notes:</h3> <h3>⚠️ Important Notes (PDPA Compliance):</h3>
<ul style="font-size: 0.75rem; color: #92400e; list-style: disc; padding-left: 1.5rem;"> <ul>
<li>Consent records must be retained for 10 years (PDPA requirement)</li> <li>Consent records must be retained for 10 years</li>
<li>Only delete records when user exercises "right to be forgotten"</li> <li>Only delete records when user exercises "right to be forgotten"</li>
<li>Document all deletions for compliance audit</li> <li>IP addresses are hashed (SHA-256, first 16 chars) for privacy</li>
<li>IP addresses are hashed for privacy protection</li> <li>Rate limiting: 10 requests/minute per IP</li>
</ul> </ul>
</div> </div>
</div> </div>
@@ -308,6 +337,46 @@ if (Astro.request.method === 'POST') {
alert('Error deleting consent record'); alert('Error deleting consent record');
} }
} }
async function exportCSV() {
try {
const response = await fetch('/api/consent');
const data = await response.json();
const logs = data.logs || [];
const headers = ['วันที่/เวลา', 'Session ID', 'Essential', 'Analytics', 'Marketing', 'Policy Version', 'IP Hash', 'User Agent'];
const csvRows = [headers.join(',')];
for (const log of logs) {
const row = [
new Date(log.timestamp).toLocaleString('th-TH'),
log.sessionId,
log.essential ? 'Yes' : 'No',
log.analytics ? 'Yes' : 'No',
log.marketing ? 'Yes' : 'No',
log.policyVersion,
log.ipHash || '',
(log.userAgent || '').replace(/,/g, ';')
];
csvRows.push(row.join(','));
}
// UTF-8 BOM for Excel compatibility
const csvContent = '\ufeff' + csvRows.join('\n');
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `consent-logs-${new Date().toISOString().split('T')[0]}.csv`;
link.click();
URL.revokeObjectURL(url);
} catch (error) {
console.error('Export error:', error);
alert('Failed to export CSV');
}
}
</script> </script>
</body> </body>
</html> </html>

View File

@@ -1,12 +1,12 @@
# นโยบายความเป็นส่วนตัว (Privacy Policy) # นโยบายความเป็นส่วนตัว (Privacy Policy)
**ชื่อเว็บไซต์:** [WEBSITE_NAME] **ชื่อเว็บไซต์:** {SITE_NAME}
**มีผลบังคับใช้วันที่:** [DATE] **มีผลบังคับใช้วันที่:** {EFFECTIVE_DATE}
**แก้ไขล่าสุด:** [DATE] **แก้ไขล่าสุด:** {LAST_UPDATED}
## 1. บทนำ ## 1. บทนำ
บริษัท [COMPANY_NAME] ("เรา", "ของเรา" หรือ "บริษัท") ให้คำมั่นสัญญาที่จะปกป้องข้อมูลส่วนบุคคลของผู้ใช้บริการ ("ผู้ใช้", "ของคุณ" หรือ "ท่าน") ที่ใช้งานเว็บไซต์ [WEBSITE_URL] ("เว็บไซต์") นโยบายความเป็นส่วนตัวฉบับนี้อธิบายถึงวิธีการเก็บรวบรวม ใช้ เปิดเผย และคุ้มครองข้อมูลส่วนบุคคลของท่าน บริษัท {COMPANY_NAME} ("เรา", "ของเรา" หรือ "บริษัท") ให้คำมั่นสัญญาที่จะปกป้องข้อมูลส่วนบุคคลของผู้ใช้บริการ ("ผู้ใช้", "ของคุณ" หรือ "ท่าน") ที่ใช้งานเว็บไซต์ {SITE_URL} ("เว็บไซต์") นโยบายความเป็นส่วนตัวฉบับนี้อธิบายถึงวิธีการเก็บรวบรวม ใช้ เปิดเผย และคุ้มครองข้อมูลส่วนบุคคลของท่าน
นโยบายนี้จัดทำขึ้นตามกฎหมายคุ้มครองข้อมูลส่วนบุคคล พ.ศ. 2562 (PDPA) และกฎหมายที่เกี่ยวข้องของประเทศไทย นโยบายนี้จัดทำขึ้นตามกฎหมายคุ้มครองข้อมูลส่วนบุคคล พ.ศ. 2562 (PDPA) และกฎหมายที่เกี่ยวข้องของประเทศไทย
@@ -32,11 +32,6 @@
- ข้อมูลบัญชีธนาคาร - ข้อมูลบัญชีธนาคาร
- ประวัติการทำธุรกรรม - ประวัติการทำธุรกรรม
**ข้อมูลอื่นๆ:**
- ความคิดเห็น ข้อเสนอแนะ
- แบบสำรวจความพึงพอใจ
- เนื้อหาที่ท่านส่งมา
### 2.2 ข้อมูลที่เก็บรวบรวมโดยอัตโนมัติ ### 2.2 ข้อมูลที่เก็บรวบรวมโดยอัตโนมัติ
เมื่อท่านใช้งานเว็บไซต์ เราอาจเก็บรวบรวมข้อมูลต่อไปนี้โดยอัตโนมัติ: เมื่อท่านใช้งานเว็บไซต์ เราอาจเก็บรวบรวมข้อมูลต่อไปนี้โดยอัตโนมัติ:
@@ -54,329 +49,106 @@
- ลิงก์ที่ท่านคลิก - ลิงก์ที่ท่านคลิก
- ข้อมูล Cookie - ข้อมูล Cookie
**ข้อมูลตำแหน่ง:**
- ข้อมูลตำแหน่งทางภูมิศาสตร์ (หากท่านอนุญาต)
## 3. วัตถุประสงค์ในการใช้ข้อมูล ## 3. วัตถุประสงค์ในการใช้ข้อมูล
เราใช้ข้อมูลส่วนบุคคลของท่านเพื่อวัตถุประสงค์ดังต่อไปนี้: เราใช้ข้อมูลส่วนบุคคลของท่านเพื่อวัตถุประสงค์ดังต่อไปนี้:
### 3.1 การให้บริการ
- ให้บริการและบำรุงรักษาเว็บไซต์ - ให้บริการและบำรุงรักษาเว็บไซต์
- ประมวลผลคำขอและธุรกรรมของท่าน - ประมวลผลคำขอและธุรกรรมของท่าน
- ส่งมอบสินค้าหรือบริการที่ท่านสั่งซื้อ - ส่งมอบสินค้าหรือบริการที่ท่านสั่งซื้อ
- จัดการบัญชีผู้ใช้ของท่าน - จัดการบัญชีผู้ใช้ของท่าน
### 3.2 การสื่อสาร
- ตอบกลับคำถามและข้อร้องเรียน - ตอบกลับคำถามและข้อร้องเรียน
- ส่งข้อมูลเกี่ยวกับบริการของเรา - ส่งข้อมูลเกี่ยวกับบริการของเรา
- แจ้งเตือนเกี่ยวกับการอัปเดตหรือการเปลี่ยนแปลง - แจ้งเตือนเกี่ยวกับการอัปเดตหรือการเปลี่ยนแปลง
- ส่งข่าวสารโปรโมชั่น (หากท่านยินยอม) - ส่งข่าวสารโปรโมชั่น (หากท่านยินยอม)
- วิเคราะห์การใช้งานเว็บไซต์และปรับปรุงบริการ
### 3.3 การปรับปรุงบริการ
- วิเคราะห์การใช้งานเว็บไซต์
- พัฒนาและปรับปรุงบริการ
- ทดสอบฟีเจอร์ใหม่
- วิจัยตลาด
### 3.4 ความปลอดภัย
- ระบุและป้องกันภัยคุกคามด้านความปลอดภัย - ระบุและป้องกันภัยคุกคามด้านความปลอดภัย
- ตรวจสอบกิจกรรมที่อาจเป็นการฉ้อโกง
- บังคับใช้นโยบายและข้อกำหนดของเรา
- ปฏิบัติตามข้อกำหนดทางกฎหมาย - ปฏิบัติตามข้อกำหนดทางกฎหมาย
### 3.5 ตามกฎหมาย
- ปฏิบัติตามภาระผูกพันทางกฎหมาย
- ตอบสนองต่อคำขอจากหน่วยงานราชการ
- ป้องกันสิทธิและทรัพย์สินของเรา
- ป้องกันอันตรายต่อสาธารณะ
## 4. ฐานทางกฎหมายในการประมวลผลข้อมูล ## 4. ฐานทางกฎหมายในการประมวลผลข้อมูล
เราประมวลผลข้อมูลส่วนบุคคลของท่านบนฐานทางกฎหมายดังต่อไปนี้: เราประมวลผลข้อมูลส่วนบุคคลของท่านบนฐานทางกฎหมายดังต่อไปนี้:
### 4.1 ความยินยอม (Consent) - **ความยินยอม (Consent):** การส่งข่าวสารทางอีเมล, การใช้ Cookie สำหรับการตลาด
- **การปฏิบัติตามสัญญา (Contract):** การประมวลผลการสั่งซื้อ, การให้บริการที่ท่านร้องขอ
ท่านได้ให้ความยินยอมให้เราประมวลผลข้อมูลส่วนบุคคลของท่านเพื่อวัตถุประสงค์เฉพาะ เช่น: - **หน้าที่ทางกฎหมาย (Legal Obligation):** การเก็บรักษาบันทึกทางการเงิน, การรายงานต่อหน่วยงานราชการ
- การส่งข่าวสารทางอีเมล - **ผลประโยชน์โดยชอบด้วยกฎหมาย (Legitimate Interest):** การป้องกันและตรวจสอบการฉ้อโกง, ความปลอดภัยของเครือข่าย
- การใช้ Cookie สำหรับการตลาด
- การเก็บข้อมูลสุขภาพหรือข้อมูลอ่อนไหวอื่นๆ
### 4.2 การปฏิบัติตามสัญญา (Contract)
การประมวลผลจำเป็นสำหรับการปฏิบัติตามสัญญาที่ท่านทำกับเรา เช่น:
- การประมวลผลการสั่งซื้อ
- การให้บริการที่ท่านร้องขอ
- การจัดการบัญชีผู้ใช้
### 4.3 หน้าที่ทางกฎหมาย (Legal Obligation)
การประมวลผลจำเป็นเพื่อปฏิบัติตามภาระผูกพันทางกฎหมาย เช่น:
- การเก็บรักษาบันทึกทางการเงิน
- การรายงานต่อหน่วยงานราชการ
- การปฏิบัติตามคำสั่งศาล
### 4.4 ผลประโยชน์โดยชอบด้วยกฎหมาย (Legitimate Interest)
การประมวลผลจำเป็นเพื่อประโยชน์โดยชอบด้วยกฎหมายของเรา เช่น:
- การป้องกันและการตรวจสอบการฉ้อโกง
- ความปลอดภัยของเครือข่ายและข้อมูล
- การปรับปรุงบริการ
## 5. การเปิดเผยข้อมูลให้กับบุคคลที่สาม ## 5. การเปิดเผยข้อมูลให้กับบุคคลที่สาม
เราไม่ขายหรือให้เช่าข้อมูลส่วนบุคคลของท่านให้กับบุคคลที่สาม อย่างไรก็ตาม เราอาจเปิดเผยข้อมูลของท่านในกรณีต่อไปนี้: เราไม่ขายหรือให้เช่าข้อมูลส่วนบุคคลของท่านให้กับบุคคลที่สาม อย่างไรก็ตาม เราอาจเปิดเผยข้อมูลของท่านในกรณีต่อไปนี้:
### 5.1 ผู้ให้บริการ (Service Providers) - **ผู้ให้บริการ:** ผู้ให้บริการชำระเงิน, ผู้ให้บริการจัดส่ง, ผู้ให้บริการคลาวด์, ผู้ให้บริการอีเมล, ผู้ให้บริการวิเคราะห์ข้อมูล
- **หน่วยงานราชการ:** ศาล, หน่วยงานบังคับใช้กฎหมาย, หน่วยงานกำกับดูแล, หน่วยงานภาษี
เราอาจแบ่งปันข้อมูลกับผู้ให้บริการที่ช่วยเราดำเนินธุรกิจ: - **การโอนกิจการ:** กรณีควบรวมกิจการหรือขายทรัพย์สิน
- **ผู้ให้บริการชำระเงิน:** เช่น ธนาคาร, ผู้ให้บริการบัตรเครดิต
- **ผู้ให้บริการจัดส่ง:** เช่น ไปรษณีย์ไทย, Kerry, Flash Express
- **ผู้ให้บริการคลาวด์:** เช่น AWS, Google Cloud, Azure
- **ผู้ให้บริการอีเมล:** เช่น SendGrid, Mailchimp
- **ผู้ให้บริการวิเคราะห์ข้อมูล:** เช่น Google Analytics
### 5.2 หน่วยงานราชการ
เราอาจเปิดเผยข้อมูลเมื่อได้รับคำสั่งตามกฎหมาย:
- ศาลหรือกระบวนการยุติธรรม
- หน่วยงานบังคับใช้กฎหมาย
- หน่วยงานกำกับดูแล
- หน่วยงานภาษี
### 5.3 การโอนกิจการ
ในกรณีที่มีการควบรวมกิจการ ขายทรัพย์สิน หรือการโอนกิจการ ข้อมูลของท่านอาจถูกโอนไปยังผู้ซื้อหรือผู้รับโอน
### 5.4 เพื่อปกป้องสิทธิ
เราอาจเปิดเผยข้อมูลเพื่อ:
- ปกป้องสิทธิ ทรัพย์สิน หรือความปลอดภัยของเรา
- ป้องกันการฉ้อโกง
- ปฏิบัติตามข้อกำหนดการใช้งาน
## 6. การเก็บรักษาข้อมูล ## 6. การเก็บรักษาข้อมูล
เราเก็บรักษาข้อมูลส่วนบุคคลของท่านไว้เฉพาะเท่าที่จำเป็นเพื่อวัตถุประสงค์ที่ระบุไว้ในนโยบายนี้: เราเก็บรักษาข้อมูลส่วนบุคคลของท่านไว้เฉพาะเท่าที่จำเป็น:
### 6.1 ระยะเวลาการเก็บรักษา - **ข้อมูลบัญชีผู้ใช้:** เก็บรักษาตลาบเท่าที่ท่านเป็นผู้ใช้บริการ และ {DATA_RETENTION_CUSTOMER_YEARS} ปีหลังจากนั้น
- **ข้อมูลธุรกรรม:** {DATA_RETENTION_PAYMENT_YEARS} ปี ตามข้อกำหนดของกฎหมายภาษี
- **ข้อมูลบัญชีผู้ใช้:** เก็บรักษาตราบเท่าที่ท่านเป็นผู้ใช้บริการ และ 3 ปีหลังจากนั้น - **ข้อมูลการติดต่อ:** {DATA_RETENTION_CONTACT_YEARS} ปีหลังจากการติดต่อล่าสุด
- **ข้อมูลธุรกรรม:** 5 ปี ตามข้อกำหนดของกฎหมายภาษี
- **ข้อมูลการติดต่อ:** 2 ปีหลังจากการติดต่อล่าสุด
- **ข้อมูล Cookie:** ตามการตั้งค่า Cookie ของท่าน - **ข้อมูล Cookie:** ตามการตั้งค่า Cookie ของท่าน
### 6.2 การทำลายข้อมูล
เมื่อไม่จำเป็นต้องเก็บรักษาข้อมูลต่อไป เราจะ:
- ลบข้อมูลจากระบบอิเล็กทรอนิกส์
- ทำลายเอกสารที่เป็นกระดาษ
- ทำให้ข้อมูลไม่สามารถระบุตัวตนได้
## 7. สิทธิของท่าน ## 7. สิทธิของท่าน
ภายใต้ PDPA ท่านมีสิทธิดังต่อไปนี้เกี่ยวกับข้อมูลส่วนบุคคลของท่าน: ภายใต้ PDPA ท่านมีสิทธิดังต่อไปนี้เกี่ยวกับข้อมูลส่วนบุคคลของท่าน:
### 7.1 สิทธิในการเข้าถึง (Right to Access) 1. **สิทธิในการเข้าถึง:** ขอสำเนาข้อมูลส่วนบุคคล
2. **สิทธิในการแก้ไข:** ขอให้แก้ไขข้อมูลที่ไม่ถูกต้อง
ท่านมีสิทธิขอเข้าถึงข้อมูลส่วนบุคคลที่ท่านเป็นเจ้าของ: 3. **สิทธิในการลบ:** ขอให้ลบข้อมูลในกรณีที่ไม่จำเป็นต้องใช้แล้ว หรือถอนความยินยอม
- ขอสำเนาข้อมูลส่วนบุคคล 4. **สิทธิในการจำกัดการประมวลผล:** ขอให้ระงับการใช้ข้อมูลชั่วคราว
- ทราบวัตถุประสงค์ของการประมวลผล 5. **สิทธิในการโอนย้ายข้อมูล:** ขอให้โอนข้อมูลไปยังผู้ควบคุมข้อมูลอื่น
- ทราบแหล่งที่มาของข้อมูล 6. **สิทธิในการคัดค้าน:** คัดค้านการประมวลผลเพื่อประโยชน์โดยชอบด้วยกฎหมาย
7. **สิทธิในการถอนความยินยอม:** ถอนความยินยอมเมื่อใดก็ได้
### 7.2 สิทธิในการแก้ไข (Right to Rectification) 8. **สิทธิในการร้องเรียน:** ร้องเรียนต่อสำนักงานคณะกรรมการคุ้มครองข้อมูลส่วนบุคคล (สคส.)
ท่านมีสิทธิขอให้แก้ไขข้อมูลส่วนบุคคลที่ไม่ถูกต้อง:
- แก้ไขข้อมูลการติดต่อ
- อัปเดตข้อมูลบัญชี
- แก้ไขข้อมูลอื่นๆ
### 7.3 สิทธิในการลบ (Right to Erasure)
ท่านมีสิทธิขอให้ลบข้อมูลส่วนบุคคลในกรณีต่อไปนี้:
- ข้อมูลไม่จำเป็นต้องใช้แล้ว
- ท่านถอนความยินยอม
- ข้อมูลถูกประมวลผลโดยมิชอบด้วยกฎหมาย
### 7.4 สิทธิในการจำกัดการประมวลผล (Right to Restriction)
ท่านมีสิทธิขอให้จำกัดการประมวลผลข้อมูล:
- ขณะตรวจสอบความถูกต้องของข้อมูล
- เมื่อการประมวลผลเป็นการมิชอบด้วยกฎหมาย
- เมื่อเราไม่จำเป็นต้องใช้ข้อมูลแล้ว แต่ท่านต้องการให้เก็บไว้เพื่อการใช้สิทธิทางกฎหมาย
### 7.5 สิทธิในการคัดค้าน (Right to Object)
ท่านมีสิทธิคัดค้านการประมวลผลข้อมูล:
- การประมวลผลเพื่อประโยชน์โดยชอบด้วยกฎหมาย
- การประมวลผลเพื่อการตลาดโดยตรง
- การประมวลผลเพื่อวัตถุประสงค์ทางสถิติ
### 7.6 สิทธิในการโอนย้ายข้อมูล (Right to Data Portability)
ท่านมีสิทธิขอให้โอนข้อมูลส่วนบุคคลไปยังผู้ควบคุมข้อมูลอื่น:
- ข้อมูลที่ท่านให้ไว้
- ข้อมูลที่ประมวลผลโดยอัตโนมัติ
- เมื่อการประมวลผลอาศัยความยินยอมหรือสัญญา
### 7.7 สิทธิในการถอนความยินยอม (Right to Withdraw Consent)
หากการประมวลผลอาศัยความยินยอม ท่านมีสิทธิถอนความยินยอมเมื่อใดก็ได้:
- การถอนความยินยอมไม่กระทบต่อการประมวลผลก่อนหน้า
- ท่านอาจไม่สามารถใช้บริการบางอย่างได้หลังถอนความยินยอม
### 7.8 สิทธิในการร้องเรียน (Right to Complaint)
หากท่านเชื่อว่าข้อมูลของท่านถูกประมวลผลโดยมิชอบด้วยกฎหมาย ท่านมีสิทธิร้องเรียนต่อ:
- สำนักงานคณะกรรมการคุ้มครองข้อมูลส่วนบุคคล (สคส.)
- เว็บไซต์: www.pdpc.or.th
- โทรศัพท์: 0-2141-6900
## 8. Cookie และเทคโนโลยีการติดตาม ## 8. Cookie และเทคโนโลยีการติดตาม
### 8.1 Cookie คืออะไร ### ประเภทของ Cookie ที่เราใช้:
Cookie เป็นไฟล์ข้อความขนาดเล็กที่เว็บไซต์บันทึกลงในอุปกรณ์ของท่านเมื่อท่านเข้าชมเว็บไซต์ - **Cookie ที่จำเป็น (Necessary):** จำเป็นสำหรับการทำงานของเว็บไซต์ ไม่สามารถปิดใช้งานได้
- **Cookie เพื่อประสิทธิภาพ (Performance):** รวบรวมข้อมูลการใช้เว็บไซต์เพื่อปรับปรุง
### 8.2 ประเภทของ Cookie ที่เราใช้ - **Cookie เพื่อการทำงาน (Functional):** จดจำการตั้งค่าของท่าน
- **Cookie เพื่อการตลาด (Marketing):** ติดตามกิจกรรมการท่องเว็บเพื่อแสดงโฆษณาที่เกี่ยวข้อง (ต้องได้รับความยินยอม)
**Cookie ที่จำเป็น (Necessary Cookies):**
- จำเป็นสำหรับการทำงานของเว็บไซต์
- ไม่สามารถปิดใช้งานได้
- ไม่เก็บข้อมูลส่วนบุคคล
**Cookie เพื่อประสิทธิภาพ (Performance Cookies):**
- รวบรวมข้อมูลเกี่ยวกับวิธีการใช้เว็บไซต์
- ช่วยให้เราปรับปรุงเว็บไซต์
- ข้อมูลเป็นแบบรวมกลุ่มและไม่ระบุตัวตน
**Cookie เพื่อการทำงาน (Functional Cookies):**
- จดจำการตั้งค่าของท่าน
- ให้องค์ประกอบที่เป็นส่วนตัวมากขึ้น
**Cookie เพื่อการตลาด (Marketing Cookies):**
- ติดตามกิจกรรมการท่องเว็บ
- ใช้เพื่อแสดงโฆษณาที่เกี่ยวข้อง
- แบ่งปันข้อมูลกับบุคคลที่สาม
### 8.3 การจัดการ Cookie
ท่านสามารถจัดการ Cookie ได้โดย:
- **การตั้งค่าเบราว์เซอร์:** ปิดการใช้งาน Cookie ทั้งหมดหรือบางประเภท
- **การตั้งค่า Cookie ของเรา:** เลือกประเภท Cookie ที่ท่านยินยอม
- **เครื่องมือของบุคคลที่สาม:** เช่น Google Analytics Opt-out
### 8.4 ผลกระทบจากการปิด Cookie
หากท่านปิดการใช้งาน Cookie:
- ฟีเจอร์บางอย่างของเว็บไซต์อาจไม่ทำงาน
- ท่านอาจไม่สามารถเข้าสู่ระบบได้
- การตั้งค่าของท่านอาจไม่ถูกจดจำ
## 9. ความปลอดภัยของข้อมูล ## 9. ความปลอดภัยของข้อมูล
เราใช้มาตรการรักษาความปลอดภัยที่เหมาะสมเพื่อคุ้มครองข้อมูลส่วนบุคคลของท่าน: เราใช้มาตรการรักษาความปลอดภัยที่เหมาะสม:
### 9.1 มาตรการทางเทคนิค
- **การเข้ารหัส:** ข้อมูลถูกเข้ารหัสระหว่างการส่ง (SSL/TLS) - **การเข้ารหัส:** ข้อมูลถูกเข้ารหัสระหว่างการส่ง (SSL/TLS)
- **การควบคุมการเข้าถึง:** จำกัดการเข้าถึงข้อมูลเฉพาะผู้ที่จำเป็น - **การควบคุมการเข้าถึง:** จำกัดการเข้าถึงข้อมูลเฉพาะผู้ที่จำเป็น
- **Firewall:** ป้องกันการเข้าถึงโดยไม่ได้รับอนุญาต - **Firewall:** ป้องกันการเข้าถึงโดยไม่ได้รับอนุญาต
- **การตรวจจับการบุกรุก:** ตรวจสอบกิจกรรมที่ผิดปกติ - **การสำรองข้อมูล:** สำรองข้อมูลเป็นประจำ
- **การตรวจสอบ:** ทบทวนและปรับปรุงมาตรการความปลอดภัยอย่างสม่ำเสมอ
### 9.2 มาตรการทางองค์กร ## 10. การแจ้งเหตุละเมิดข้อมูล
- **นโยบายความปลอดภัย:** นโยบายและขั้นตอนที่ชัดเจน
- **การฝึกอบรม:** พนักงานได้รับการฝึกอบรมเรื่องความปลอดภัยของข้อมูล
- **การตรวจสอบ:** ทบทวนและปรับปรุงมาตรการอย่างสม่ำเสมอ
- **การจัดการผู้ให้บริการ:** ประเมินความปลอดภัยของผู้ให้บริการ
### 9.3 มาตรการทางกายภาพ
- **การควบคุมการเข้าถึง:** จำกัดการเข้าถึงศูนย์ข้อมูล
- **การป้องกันสิ่งแวดล้อม:** ระบบป้องกันอัคคีภัยและน้ำท่วม
- **การทำลายสื่อ:** ทำลายสื่อเก็บข้อมูลอย่างปลอดภัย
### 9.4 การแจ้งเหตุละเมิดข้อมูล
ในกรณีที่มีการละเมิดข้อมูลส่วนบุคคล เราจะ: ในกรณีที่มีการละเมิดข้อมูลส่วนบุคคล เราจะ:
- แจ้งสำนักงานคณะกรรมการคุ้มครองข้อมูลส่วนบุคคลภายใน 72 ชั่วโมง - แจ้งสำนักงานคณะกรรมการคุ้มครองข้อมูลส่วนบุคคลภายใน 72 ชั่วโมง
- แจ้งให้ท่านทราบหากมีความเสี่ยงสูงต่อสิทธิและเสรีภาพของท่าน - แจ้งให้ท่านทราบหากมีความเสี่ยงสูงต่อสิทธิและเสรีภาพของท่าน
- ดำเนินการเพื่อลดผลกระทบ
## 10. การโอนข้อมูลข้ามพรมแดน
เราอาจโอนข้อมูลส่วนบุคคลของท่านไปยังประเทศนอกประเทศไทย:
### 10.1 ประเทศปลายทาง
ข้อมูลอาจถูกโอนไปยัง:
- ประเทศที่มีมาตรฐานการคุ้มครองข้อมูลที่เพียงพอ
- ประเทศที่มีมาตรการคุ้มครองที่เหมาะสม
- ประเทศที่กฎหมายกำหนด
### 10.2 มาตรการคุ้มครอง
การโอนข้อมูลข้ามพรมแดนอยู่ภายใต้:
- มาตรฐานข้อบทเชิงสัญญา (Standard Contractual Clauses)
- กฎบัตรบริษัท (Binding Corporate Rules)
- การรับรองมาตรฐาน (Certification)
## 11. เด็กและเยาวชน ## 11. เด็กและเยาวชน
### 11.1 อายุขั้นต่ำ เว็บไซต์ของเราไม่ได้ออกแบบมาสำหรับเด็กอายุต่ำกว่า 20 ปี หากท่านอายุต่ำกว่า 20 ปี กรุณาให้ผู้ปกครองอ่านและยินยอมแทน
เว็บไซต์ของเราไม่ได้ออกแบบมาสำหรับเด็กอายุต่ำกว่า 20 ปี: ## 12. การติดต่อ
- เราไม่เก็บรวบรวมข้อมูลจากเด็กโดยรู้เท่าไม่ถึงการณ์
- หากท่านอายุต่ำกว่า 20 ปี กรุณาอย่าให้ข้อมูลส่วนบุคคล
### 11.2 ความยินยอมจากผู้ปกครอง ### เจ้าหน้าที่คุ้มครองข้อมูลส่วนบุคคล (DPO)
หากเราทราบ bahwaเราเก็บรวบรวมข้อมูลจากเด็กอายุต่ำกว่า 20 ปี: **ชื่อ:** {DPO_NAME}
- เราจะขอความยินยอมจากผู้ปกครอง **อีเมล:** {DPO_EMAIL}
- หากไม่ได้รับความยินยอม เราจะลบข้อมูลดังกล่าว **โทรศัพท์:** {DPO_PHONE}
**ที่อยู่:** {COMPANY_ADDRESS}
## 12. การเปลี่ยนแปลงนโยบายความเป็นส่วนตัว ### ช่องทางการติดต่อ
เราอาจอัปเดตนโยบายความเป็นส่วนตัวนี้เป็นครั้งคราว: **อีเมล:** {CONTACT_EMAIL}
**โทรศัพท์:** {CONTACT_PHONE}
**ที่อยู่:** {COMPANY_ADDRESS}
### 12.1 การแจ้งการเปลี่ยนแปลง ### หน่วยงานกำกับดูแล
เราจะแจ้งท่านเกี่ยวกับการเปลี่ยนแปลงโดย:
- โพสต์นโยบายที่อัปเดตบนเว็บไซต์
- ส่งอีเมลแจ้งให้ทราบ
- แสดงประกาศบนเว็บไซต์
### 12.2 การยอมรับการเปลี่ยนแปลง
การใช้งานเว็บไซต์ของท่านหลังจากการเปลี่ยนแปลงแสดงว่าท่านยอมรับนโยบายที่อัปเดต:
- หากท่านไม่เห็นด้วย กรุณาหยุดใช้งานเว็บไซต์
- ท่านมีสิทธิถอนความยินยอมหรือลบบัญชี
## 13. การติดต่อ
หากท่านมีคำถามหรือข้อกังวลเกี่ยวกับนโยบายความเป็นส่วนตัว:
### 13.1 เจ้าหน้าที่คุ้มครองข้อมูลส่วนบุคคล (DPO)
**ชื่อ:** [DPO_NAME]
**อีเมล:** [DPO_EMAIL]
**โทรศัพท์:** [DPO_PHONE]
**ที่อยู่:** [COMPANY_ADDRESS]
### 13.2 ช่องทางการติดต่ออื่นๆ
**แบบฟอร์มติดต่อ:** [CONTACT_FORM_URL]
**อีเมล:** [CONTACT_EMAIL]
**โทรศัพท์:** [CONTACT_PHONE]
**ที่อยู่:** [COMPANY_ADDRESS]
### 13.3 หน่วยงานกำกับดูแล
หากท่านไม่พอใจกับการตอบสนองของเรา ท่านสามารถติดต่อ: หากท่านไม่พอใจกับการตอบสนองของเรา ท่านสามารถติดต่อ:
@@ -386,37 +158,21 @@ Cookie เป็นไฟล์ข้อความขนาดเล็กท
อีเมล: ocppd@pdpc.or.th อีเมล: ocppd@pdpc.or.th
เว็บไซต์: www.pdpc.or.th เว็บไซต์: www.pdpc.or.th
## 14. คำจำกัดความ ## 13. กฎหมายที่ใช้บังคับ
**"ข้อมูลส่วนบุคคล"** หมายถึง ข้อมูลเกี่ยวกับบุคคลซึ่งทำให้สามารถระบุตัวตนของบุคคลนั้นได้ ไม่ว่าทางตรงหรือทางอ้อม
**"การประมวลผล"** หมายถึง การเก็บรวบรวม ใช้ เปิดเผย ส่งต่อ ปรับเปลี่ยน เปรียบเทียบ ทำลาย หรือการดำเนินการใดๆ กับข้อมูลส่วนบุคคล
**"ผู้ควบคุมข้อมูล"** หมายถึง บุคคลหรือนิติบุคคลซึ่งมีอำนาจหน้าที่ตัดสินใจเกี่ยวกับการเก็บรวบรวม ใช้ หรือเปิดเผยข้อมูลส่วนบุคคล
**"ผู้ประมวลผลข้อมูล"** หมายถึง บุคคลหรือนิติบุคคลซึ่งดำเนินการเกี่ยวกับการเก็บรวบรวม ใช้ หรือเปิดเผยข้อมูลส่วนบุคคลตามคำสั่งหรือในนามของผู้ควบคุมข้อมูล
## 15. กฎหมายที่ใช้บังคับ
นโยบายความเป็นส่วนตัวนี้ตีความและบังคับใช้ตามกฎหมายแห่งราชอาณาจักรไทย: นโยบายความเป็นส่วนตัวนี้ตีความและบังคับใช้ตามกฎหมายแห่งราชอาณาจักรไทย:
- พระราชบัญญัติคุ้มครองข้อมูลส่วนบุคคล พ.ศ. 2562 - พระราชบัญญัติคุ้มครองข้อมูลส่วนบุคคล พ.ศ. 2562
- พระราชบัญญัติว่าด้วยการกระทำความผิดเกี่ยวกับคอมพิวเตอร์ - พระราชบัญญัติว่าด้วยการกระทำความผิดเกี่ยวกับคอมพิวเตอร์
- กฎหมายคุ้มครองผู้บริโภค - กฎหมายคุ้มครองผู้บริโภค
## 16. การแยกความมีผลบังคับใช้
หากข้อกำหนดใดในนโยบายนี้ถูกพิจารณาว่าเป็นโมฆะหรือบังคับไม่ได้:
- ข้อกำหนดดังกล่าวจะถูกตัดออก
- ข้อกำหนดที่เหลือจะยังคงมีผลบังคับใช้เต็มที่
--- ---
**ลงชื่อ:** _________________________ **ลงชื่อ:** _________________________
**ชื่อ:** [AUTHORIZED_NAME] **ชื่อ:** {AUTHORIZED_NAME}
**ตำแหน่ง:** [AUTHORIZED_TITLE] **ตำแหน่ง:** {AUTHORIZED_TITLE}
**วันที่:** [DATE] **วันที่:** {SIGN_DATE}
**บริษัท [COMPANY_NAME]** **บริษัท {COMPANY_NAME}**
--- ---

View File

@@ -1,15 +1,15 @@
# เงื่อนไขการให้บริการ (Terms of Service) # เงื่อนไขการให้บริการ (Terms of Service)
**ชื่อเว็บไซต์:** [WEBSITE_NAME] **ชื่อเว็บไซต์:** {SITE_NAME}
**เว็บไซต์:** [WEBSITE_URL] **เว็บไซต์:** {SITE_URL}
**มีผลบังคับใช้วันที่:** [DATE] **มีผลบังคับใช้วันที่:** {EFFECTIVE_DATE}
**แก้ไขล่าสุด:** [DATE] **แก้ไขล่าสุด:** {LAST_UPDATED}
## 1. การยอมรับเงื่อนไข ## 1. การยอมรับเงื่อนไข
### 1.1 ข้อตกลง ### 1.1 ข้อตกลง
ด้วยการเข้าถึงและใช้งานเว็บไซต์ [WEBSITE_URL] ("เว็บไซต์") ของบริษัท [COMPANY_NAME] ("เรา", "ของเรา" หรือ "บริษัท") ท่าน ("ผู้ใช้", "ท่าน" หรือ "ของคุณ") ยอมรับและตกลงที่จะถูกผูกมัดด้วยเงื่อนไขการให้บริการฉบับนี้ ("เงื่อนไข") ด้วยการเข้าถึงและใช้งานเว็บไซต์ {SITE_URL} ("เว็บไซต์") ของบริษัท {COMPANY_NAME} ("เรา", "ของเรา" หรือ "บริษัท") ท่าน ("ผู้ใช้", "ท่าน" หรือ "ของคุณ") ยอมรับและตกลงที่จะถูกผูกมัดด้วยเงื่อนไขการให้บริการฉบับนี้ ("เงื่อนไข")
### 1.2 การแก้ไขเงื่อนไข ### 1.2 การแก้ไขเงื่อนไข
@@ -28,10 +28,11 @@
### 2.1 คำอธิบายบริการ ### 2.1 คำอธิบายบริการ
เว็บไซต์ของเราให้บริการ: {BUSINESS_NAME} ให้บริการ:
- [SERVICE_DESCRIPTION]
- ข้อมูลและเนื้อหาเกี่ยวกับ [TOPIC] 1. **{SERVICE_1}** - {SERVICE_1_DESC}
- เครื่องมือและฟีเจอร์ต่างๆ 2. **{SERVICE_2}** - {SERVICE_2_DESC}
3. **{SERVICE_3}** - {SERVICE_3_DESC}
### 2.2 การเปลี่ยนแปลงบริการ ### 2.2 การเปลี่ยนแปลงบริการ
@@ -66,14 +67,14 @@
เราขอสงวนสิทธิในการระงับหรือลบบัญชีของท่านหาก: เราขอสงวนสิทธิในการระงับหรือลบบัญชีของท่านหาก:
- ท่านละเมิดเงื่อนไขนี้ - ท่านละเมิดเงื่อนไขนี้
- มีการ_activity_ที่น่าสงสัยหรือเป็นอันตราย - มีกิจกรรมที่น่าสงสัยหรือเป็นอันตราย
- มีการร้องเรียนจากผู้ใช้รายอื่น - มีการร้องเรียนจากผู้ใช้รายอื่น
- ตามข้อกำหนดของกฎหมาย - ตามข้อกำหนดของกฎหมาย
### 3.4 การลบบัญชี ### 3.4 การลบบัญชี
ท่านสามารถลบบัญชีของท่านเมื่อใดก็ได้: ท่านสามารถลบบัญชีของท่านเมื่อใดก็ได้:
- ติดต่อเราที่ [CONTACT_EMAIL] - ติดต่อเราที่ {CONTACT_EMAIL}
- ข้อมูลบางอย่างอาจถูกเก็บไว้ตามข้อกำหนดของกฎหมาย - ข้อมูลบางอย่างอาจถูกเก็บไว้ตามข้อกำหนดของกฎหมาย
- การลบบัญชีไม่สามารถย้อนกลับได้ - การลบบัญชีไม่สามารถย้อนกลับได้
@@ -94,7 +95,7 @@
### 4.3 สิทธิของท่าน ### 4.3 สิทธิของท่าน
ท่าน retainsสิทธิในเนื้อหาที่ท่านส่งมา: ท่านยังคงเป็นเจ้าของเนื้อหาที่ท่านส่งมา:
- ท่านยังคงเป็นเจ้าของเนื้อหาของท่าน - ท่านยังคงเป็นเจ้าของเนื้อหาของท่าน
- ท่านให้ใบอนุญาตแก่เราในการใช้เนื้อหานั้น - ท่านให้ใบอนุญาตแก่เราในการใช้เนื้อหานั้น
- ท่านรับประกันว่ามีสิทธิในการให้ใบอนุญาต - ท่านรับประกันว่ามีสิทธิในการให้ใบอนุญาต
@@ -130,12 +131,6 @@
- ส่งสแปมหรือข้อความเชิงพาณิชย์ที่ไม่พึงประสงค์ - ส่งสแปมหรือข้อความเชิงพาณิชย์ที่ไม่พึงประสงค์
- ปลอมแปลงตัวตนหรือแหล่งที่มาของเนื้อหา - ปลอมแปลงตัวตนหรือแหล่งที่มาของเนื้อหา
**กิจกรรมที่ผิดจริยธรรม:**
- ส่งเนื้อหาที่หยาบคาย อนาจาร หรือผิดศีลธรรม
- ส่งเสริมการเลือกปฏิบัติหรือความเกลียดชัง
- ส่งเสริมความรุนแรงหรือการทำร้ายตนเอง
- ส่งเสริมการพนันหรือยาเสพติดที่ผิดกฎหมาย
### 5.2 ผลของการละเมิด ### 5.2 ผลของการละเมิด
หากท่านละเมิดข้อห้าม: หากท่านละเมิดข้อห้าม:
@@ -174,34 +169,26 @@
- ลบเนื้อหาที่ละเมิดเงื่อนไข - ลบเนื้อหาที่ละเมิดเงื่อนไข
- รายงานกิจกรรมที่ผิดกฎหมายต่อเจ้าหน้าที่ - รายงานกิจกรรมที่ผิดกฎหมายต่อเจ้าหน้าที่
### 6.5 การตอบสนองต่อการละเมิด
หากท่านเชื่อว่ามีการละเมิดลิขสิทธิ์:
- แจ้งเราที่ [CONTACT_EMAIL]
- ให้ข้อมูลการละเมิดโดยละเอียด
- เราจะดำเนินการตาม DMCA และกฎหมายที่เกี่ยวข้อง
## 7. การชำระเงิน ## 7. การชำระเงิน
### 7.1 ราคาและค่าธรรมเนียม ### 7.1 ราคาและค่าธรรมเนียม
- ราคาทั้งหมดแสดงเป็นเงินบาทไทย (THB) - ราคาทั้งหมดแสดงเป็นเงินบาทไทย (THB)
- ราคานี้รวม/ไม่รวมภาษีมูลค่าเพิ่ม - ราคานี้ {PRICE_INCLUDES_VAT}
- เราขอสงวนสิทธิในการเปลี่ยนราคาเมื่อใดก็ได้ - เราขอสงวนสิทธิในการเปลี่ยนราคาเมื่อใดก็ได้
### 7.2 การชำระเงิน ### 7.2 การชำระเงิน
การชำระเงินต้องชำระล่วงหน้า: การชำระเงินต้องชำระล่วงหน้า:
- เรายอมรับการชำระเงินผ่าน [PAYMENT_METHODS] - เรายอมรับการชำระเงินผ่าน {PAYMENT_METHODS}
- การชำระเงินจะประมวลผลโดยบุคคลที่สาม - การชำระเงินจะประมวลผลโดยบุคคลที่สาม
- ท่านต้องให้ข้อมูลการชำระเงินที่ถูกต้อง - ท่านต้องให้ข้อมูลการชำระเงินที่ถูกต้อง
### 7.3 การคืนเงิน ### 7.3 การคืนเงิน
นโยบายการคืนเงิน: นโยบายการคืนเงิน:
- [REFUND_POLICY_DETAILS] - ผู้ใช้สามารถขอคืนเงินได้ภายใน {REFUND_DAYS} วันนับจากวันที่ชำระเงิน
- คำขอคืนเงินต้องส่งภายใน [X] วัน - การคืนเงินจะดำเนินการภายใน {REFUND_PROCESSING_DAYS} วันทำการ
- การคืนเงินจะประมวลผลภายใน [X] วันทำการ
### 7.4 การต่ออายุอัตโนมัติ ### 7.4 การต่ออายุอัตโนมัติ
@@ -231,11 +218,11 @@
ความรับผิดรวมของเราจะไม่เกิน: ความรับผิดรวมของเราจะไม่เกิน:
- จำนวนที่ท่านจ่ายให้เราในช่วง 12 เดือนที่ผ่านมา - จำนวนที่ท่านจ่ายให้เราในช่วง 12 เดือนที่ผ่านมา
- หรือ 1,000 บาท แล้วแต่จำนวนใดมากกว่า - หรือ {LIABILITY_MAX_AMOUNT} บาท แล้วแต่จำนวนใดมากกว่า
### 8.4 ข้อยกเว้น ### 8.4 ข้อยกเว้น
ข้อจำกัดบางอย่างไม่ใชบังคับกับ: ข้อจำกัดบางอย่างไม่ใชบังคับกับ:
- การเสียชีวิตหรือการบาดเจ็บส่วนบุคคล - การเสียชีวิตหรือการบาดเจ็บส่วนบุคคล
- การฉ้อโกงหรือการแสดงโดยประมาทเลินเล่ออย่างร้ายแรง - การฉ้อโกงหรือการแสดงโดยประมาทเลินเล่ออย่างร้ายแรง
- หน้าที่ที่ไม่สามารถถูกจำกัดตามกฎหมาย - หน้าที่ที่ไม่สามารถถูกจำกัดตามกฎหมาย
@@ -262,7 +249,7 @@
### 10.1 นโยบายความเป็นส่วนตัว ### 10.1 นโยบายความเป็นส่วนตัว
การใช้ข้อมูลส่วนบุคคลอยู่ภายใต้นโยบายความเป็นส่วนตัว: การใช้ข้อมูลส่วนบุคคลอยู่ภายใต้นโยบายความเป็นส่วนตัว:
- อ่านนโยบายความเป็นส่วนตัวของเรา - อ่านนโยบายความเป็นส่วนตัวของเราที่ {PRIVACY_POLICY_URL}
- นโยบายความเป็นส่วนตัวเป็นส่วนหนึ่งของเงื่อนไขนี้ - นโยบายความเป็นส่วนตัวเป็นส่วนหนึ่งของเงื่อนไขนี้
- ในกรณีที่มีความขัดแย้ง เงื่อนไขนี้จะมีผลบังคับใช้ - ในกรณีที่มีความขัดแย้ง เงื่อนไขนี้จะมีผลบังคับใช้
@@ -273,48 +260,32 @@
- ท่านสามารถจัดการการตั้งค่า Cookie ได้ - ท่านสามารถจัดการการตั้งค่า Cookie ได้
- การปิดการใช้งาน Cookie อาจจำกัดการทำงานของเว็บไซต์ - การปิดการใช้งาน Cookie อาจจำกัดการทำงานของเว็บไซต์
## 11. ลิงก์ไปยังเว็บไซต์ภายนอก ## 11. การยุติบริการ
### 11.1 ลิงก์ของบุคคลที่สาม ### 11.1 การยุติโดยท่าน
เว็บไซต์อาจมีลิงก์ไปยังเว็บไซต์ของบุคคลที่สาม:
- เราไม่ควบคุมเว็บไซต์เหล่านั้น
- เราไม่รับผิดชอบเนื้อหาหรือการปฏิบัติของเว็บไซต์เหล่านั้น
- การเข้าถึงเว็บไซต์เหล่านั้นเป็นความเสี่ยงของท่าน
### 11.2 การโฆษณา
เว็บไซต์อาจมีโฆษณาของบุคคลที่สาม:
- เราไม่รับผิดชอบผลิตภัณฑ์หรือบริการที่โฆษณา
- ธุรกรรมกับเจ้าของโฆษณาอยู่ระหว่างท่านและเจ้าของโฆษณา
- เราไม่ตรวจสอบหรือรับรองการโฆษณา
## 12. การยุติบริการ
### 12.1 การยุติโดยท่าน
ท่านสามารถยุติการใช้งานเว็บไซต์เมื่อใดก็ได้: ท่านสามารถยุติการใช้งานเว็บไซต์เมื่อใดก็ได้:
- หยุดใช้งานเว็บไซต์ - หยุดใช้งานเว็บไซต์
- ลบบัญชีของท่าน - ลบบัญชีของท่าน
- ส่งคำขอเป็นลายลักษณ์อักษร - ส่งคำขอเป็นลายลักษณ์อักษรที่ {CONTACT_EMAIL}
### 12.2 การยุติโดยเรา ### 11.2 การยุติโดยเรา
เราขอสงวนสิทธิในการยุติการเข้าถึงของท่าน: เราขอสงวนสิทธิในการยุติการเข้าถึงของท่าน:
- โดยไม่แจ้งล่วงหน้า - โดยไม่แจ้งล่วงหน้า
- ด้วยเหตุผลใดๆ หรือไม่มีเหตุผล - ด้วยเหตุผลใดๆ หรือไม่มีเหตุผล
- ทันทีที่มีผล - ทันทีที่มีผล
### 12.3 ผลของการยุติ ### 11.3 ผลของการยุติ
เมื่อการเข้าถึงถูกยุติ: เมื่อการเข้าถึงถูกยุติ:
- สิทธิ์ในการใช้งานเว็บไซต์สิ้นสุดลง - สิทธิ์ในการใช้งานเว็บไซต์สิ้นสุดลง
- ท่านต้องหยุดใช้งานเว็บไซต์ทันที - ท่านต้องหยุดใช้งานเว็บไซต์ทันที
- ข้อกำหนดบางประการยังคงมีผล (ดูข้อ 15) - ข้อกำหนดบางประการยังคงมีผล
## 13. กฎหมายที่ใช้บังคับ ## 12. กฎหมายที่ใช้บังคับ
### 13.1 กฎหมายไทย ### 12.1 กฎหมายไทย
เงื่อนไขนี้ถูกควบคุมและตีความตามกฎหมายแห่งราชอาณาจักรไทย: เงื่อนไขนี้ถูกควบคุมและตีความตามกฎหมายแห่งราชอาณาจักรไทย:
- พระราชบัญญัติคุ้มครองผู้บริโภค - พระราชบัญญัติคุ้มครองผู้บริโภค
@@ -322,94 +293,49 @@
- พระราชบัญญัติลิขสิทธิ์ - พระราชบัญญัติลิขสิทธิ์
- กฎหมายที่เกี่ยวข้องอื่นๆ - กฎหมายที่เกี่ยวข้องอื่นๆ
### 13.2 เขตอำนาจศาล ### 12.2 เขตอำนาจศาล
ข้อพิพาทใดๆ อยู่ภายใต้เขตอำนาจศาลของ: ข้อพิพาทใดๆ อยู่ภายใต้เขตอำนาจศาลของ:
- ศาลไทย - ศาลแพ่ง/ศาลล้มละลายกลาง {COURT_LOCATION}
- กรุงเทพมหานคร - หรือศาลที่มีเขตอำนาจในประเทศไทย
- หรือศาลที่มีเขตอำนาจ
### 13.3 การระงับข้อพิพาท ### 12.3 การระงับข้อพิพาท
ก่อนดำเนินการทางกฎหมาย: ก่อนดำเนินการทางกฎหมาย:
- พยายามเจรจาเพื่อระงับข้อพิพาท - พยายามเจรจาเพื่อระงับข้อพิพาท
- ใช้เวลา 30 วันในการเจรจา - ใช้เวลา {NEGOTIATION_DAYS} วันในการเจรจา
- หากไม่สำเร็จ จึงดำเนินการทางกฎหมาย - หากไม่สำเร็จ จึงดำเนินการทางกฎหมาย
## 14. ข้อกำหนดทั่วไป ## 13. การติดต่อ
### 14.1 การสละสิทธิ
การไม่บังคับใช้สิทธิใดๆ ไม่ถือเป็นการสละสิทธิ:
- การสละสิทธิต้องเป็นลายลักษณ์อักษร
- การสละสิทธิครั้งหนึ่งไม่ถือเป็นการสละสิทธิในอนาคต
### 14.2 การโอนสิทธิ
ท่านไม่สามารถโอนสิทธิหรือหน้าที่ภายใต้เงื่อนไขนี้:
- การโอนที่พยายามทำจะถือเป็นโมฆะ
- เราสามารถโอนสิทธิของเราได้โดยไม่ต้องแจ้งให้ท่านทราบ
### 14.3 ความสัมพันธ์ระหว่างคู่สัญญา
เงื่อนไขนี้ไม่สร้างความสัมพันธ์:
- ไม่มีความสัมพันธ์การจ้างงาน
- ไม่มีความสัมพันธ์หุ้นส่วน
- ไม่มีความสัมพันธ์ร่วมทุน
### 14.4 การแยกความมีผลบังคับใช้
หากข้อกำหนดใดถูกพิจารณาว่าเป็นโมฆะ:
- ข้อกำหนดนั้นจะถูกตัดออก
- ข้อกำหนดที่เหลือจะยังคงมีผลบังคับใช้เต็มที่
### 14.5 ข้อกำหนดทั้งหมด
เงื่อนไขนี้เป็นข้อตกลงทั้งหมดระหว่างท่านและเรา:
- แทนที่ข้อตกลงหรือความเข้าใจก่อนหน้าทั้งหมด
- ไม่ว่าจะด้วยลายลักษณ์อักษรหรือด้วยวาจา
- ไม่มีการแก้ไขด้วยวาจามีผลบังคับใช้
## 15. ข้อกำหนดที่ยังคงมีผล
ข้อกำหนดดังต่อไปนี้จะยังคงมีผลหลังการยุติ:
- ความเป็นเจ้าของทรัพย์สินทางปัญญา
- การปฏิเสธความรับผิดชอบ
- ข้อจำกัดความรับผิด
- การชดเชย
- กฎหมายที่ใช้บังคับ
## 16. การติดต่อ
หากท่านมีคำถามเกี่ยวกับเงื่อนไขนี้: หากท่านมีคำถามเกี่ยวกับเงื่อนไขนี้:
**อีเมล:** [CONTACT_EMAIL] **อีเมล:** {CONTACT_EMAIL}
**โทรศัพท์:** [CONTACT_PHONE] **โทรศัพท์:** {CONTACT_PHONE}
**ที่อยู่:** [COMPANY_ADDRESS] **ที่อยู่:** {COMPANY_ADDRESS}
**แบบฟอร์มติดต่อ:** [CONTACT_FORM_URL]
--- ---
## ภาคผนวก: คำจำกัดความ ## ภาคผนวก: คำจำกัดความ
**"บัญชี"** หมายถึง บัญชีผู้ใช้ที่ท่านสร้างบนเว็บไซต์ **"บัญชี"** หมายถึง บัญชีผู้ใช้ที่ท่านสร้างบนเว็บไซต์
**"เนื้อหา"** หมายถึง ข้อมูล ข้อความ กราฟิก ภาพ วิดีโอ ซอฟต์แวร์ หรือวัสดุอื่นๆ **"เนื้อหา"** หมายถึง ข้อมูล ข้อความ กราฟิก ภาพ วิดีโอ ซอฟต์แวร์ หรือวัสดุอื่นๆ
**"เว็บไซต์"** หมายถึง เว็บไซต์ [WEBSITE_URL] และบริการที่เกี่ยวข้องทั้งหมด **"เว็บไซต์"** หมายถึง เว็บไซต์ {SITE_URL} และบริการที่เกี่ยวข้องทั้งหมด
**"เรา" "ของเรา"** หมายถึง บริษัท [COMPANY_NAME] **"เรา" "ของเรา"** หมายถึง บริษัท {COMPANY_NAME}
**"ท่าน" "ผู้ใช้"** หมายถึง บุคคลหรือนิติบุคคลที่เข้าถึงหรือใช้งานเว็บไซต์ **"ท่าน" "ผู้ใช้"** หมายถึง บุคคลหรือนิติบุคคลที่เข้าถึงหรือใช้งานเว็บไซต์
--- ---
**ลงชื่อ:** _________________________ **ลงชื่อ:** _________________________
**ชื่อ:** [AUTHORIZED_NAME] **ชื่อ:** {AUTHORIZED_NAME}
**ตำแหน่ง:** [AUTHORIZED_TITLE] **ตำแหน่ง:** {AUTHORIZED_TITLE}
**วันที่:** [DATE] **วันที่:** {SIGN_DATE}
**บริษัท [COMPANY_NAME]** **บริษัท {COMPANY_NAME}**
--- ---