#!/usr/bin/env node /** * Portal-Setup: API-Key prüfen, Kunde verknüpfen, Portal-Zugang aktivieren. * * Usage: * node scripts/portal-setup.mjs --check * node scripts/portal-setup.mjs --link --email kenso@webklar.com --appwrite-user-id 6a10d87f0003f576f126 */ import 'dotenv/config' import { randomUUID } from 'node:crypto' import { config, WOMS_DATABASE_ID } from '../server/config.js' import { getCustomerByEmail, getPortalAccessByCustomerId, listDocuments, updateDocument, Query, verifyDatabaseAccess, } from '../server/services/appwriteAdmin.js' function parseArgs(argv) { const args = { check: false, link: false, email: '', appwriteUserId: '' } for (let i = 2; i < argv.length; i++) { const a = argv[i] if (a === '--check') args.check = true else if (a === '--link') args.link = true else if (a === '--email') args.email = argv[++i] || '' else if (a === '--appwrite-user-id') args.appwriteUserId = argv[++i] || '' } return args } async function adminPost(collectionId, data) { const path = `/databases/${config.appwrite.databaseId}/collections/${collectionId}/documents` const url = `${config.appwrite.endpoint}${path}` const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Appwrite-Project': config.appwrite.projectId, 'X-Appwrite-Key': config.appwrite.apiKey, }, body: JSON.stringify({ documentId: randomUUID(), data }), }) const text = await response.text() const body = text ? JSON.parse(text) : {} if (!response.ok) throw new Error(body.message || `HTTP ${response.status}`) return body } async function checkCollections() { const names = [ config.collections.customers, config.collections.customerPortalAccess, config.collections.websiteProjects, config.collections.portalFeatures, ] const missing = [] for (const id of names) { const url = `${config.appwrite.endpoint}/databases/${config.appwrite.databaseId}/collections/${id}` const response = await fetch(url, { headers: { 'Content-Type': 'application/json', 'X-Appwrite-Project': config.appwrite.projectId, 'X-Appwrite-Key': config.appwrite.apiKey, }, }) if (!response.ok) missing.push(id) } return missing } async function linkCustomer(email, appwriteUserId) { const customer = await getCustomerByEmail(email) if (!customer) { throw new Error(`Kein Kunde mit E-Mail "${email}" in customers gefunden.`) } await updateDocument(config.collections.customers, customer.$id, { appwriteUserId, portalAccessEnabled: true, customerStatus: customer.customerStatus || 'active', updatedAt: new Date().toISOString(), }) let portalAccess = await getPortalAccessByCustomerId(customer.$id) if (portalAccess) { await updateDocument(config.collections.customerPortalAccess, portalAccess.$id, { enabled: true, appwriteUserId, passwordSet: true, }) } else { portalAccess = await adminPost(config.collections.customerPortalAccess, { customerId: customer.$id, enabled: true, appwriteUserId, passwordSet: true, }) } return { customerId: customer.$id, portalAccessId: portalAccess.$id } } async function main() { const args = parseArgs(process.argv) console.log(`Endpoint: ${config.appwrite.endpoint}`) console.log(`Database: ${WOMS_DATABASE_ID}`) console.log(`Project: ${config.appwrite.projectId}`) console.log('') const access = await verifyDatabaseAccess() if (!access.ok) { console.error('❌ APPWRITE_API_KEY: Kein Zugriff auf woms-database.') console.error(` Appwrite: ${access.reason}`) console.error(' Benötigt: Scopes databases.read + databases.write') process.exit(1) } console.log('✅ API-Key: databases.read OK') const sample = await listDocuments(config.collections.customers, [Query.limit(1)]) console.log(`✅ Collection "${config.collections.customers}": ${sample.length >= 0 ? 'erreichbar' : '?'}`) const missing = await checkCollections() if (missing.length) { console.warn(`⚠️ Fehlende Collections: ${missing.join(', ')}`) console.warn(' Siehe APPWRITE_SCHEMA.md – im Ticketsystem/Appwrite Console anlegen.') } else { console.log('✅ Alle Portal-Collections vorhanden') } if (args.link) { if (!args.email || !args.appwriteUserId) { console.error('❌ --link erfordert --email und --appwrite-user-id') process.exit(1) } const result = await linkCustomer(args.email.trim(), args.appwriteUserId.trim()) console.log('') console.log('✅ Kunde verknüpft:') console.log(` customerId: ${result.customerId}`) console.log(` appwriteUserId: ${args.appwriteUserId}`) console.log(` portalAccessId: ${result.portalAccessId}`) console.log(' portalAccessEnabled: true') console.log(' customerPortalAccess.enabled: true') } if (!args.check && !args.link) { console.log('') console.log('Nur Check ausgeführt. Für Verknüpfung:') console.log(' node scripts/portal-setup.mjs --link --email USER@example.com --appwrite-user-id USER_ID') } } main().catch((err) => { console.error('❌', err.message) process.exit(1) })