fix 4
This commit is contained in:
158
scripts/portal-setup.mjs
Normal file
158
scripts/portal-setup.mjs
Normal file
@@ -0,0 +1,158 @@
|
||||
#!/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)
|
||||
})
|
||||
Reference in New Issue
Block a user