Files
Webklar-Kundenbereich/scripts/portal-setup.mjs
2026-05-23 01:18:44 +02:00

159 lines
5.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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)
})