Files
Webklar-Kundenbereich/server/services/appwriteAdmin.js
2026-05-23 00:21:31 +02:00

144 lines
3.8 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.
import { randomUUID } from 'node:crypto'
import { config, WOMS_DATABASE_ID } from '../config.js'
function buildQueries(queries = []) {
return queries.map((q) => {
if (typeof q === 'string') return q
return JSON.stringify(q)
})
}
function adminHeaders() {
return {
'Content-Type': 'application/json',
'X-Appwrite-Project': config.appwrite.projectId,
'X-Appwrite-Key': config.appwrite.apiKey,
}
}
async function adminFetch(path, { method = 'GET', body, queries = [] } = {}) {
if (!config.appwrite.apiKey) {
const error = new Error('APPWRITE_API_KEY fehlt in .env')
error.status = 500
throw error
}
const url = new URL(`${config.appwrite.endpoint}${path}`)
for (const q of buildQueries(queries)) {
url.searchParams.append('queries[]', q)
}
const response = await fetch(url.toString(), {
method,
headers: adminHeaders(),
body: body ? JSON.stringify(body) : undefined,
})
const text = await response.text()
let data = null
if (text) {
try {
data = JSON.parse(text)
} catch {
data = { message: text }
}
}
if (!response.ok) {
const error = new Error(data?.message || `Appwrite ${response.status}`)
error.status = response.status >= 500 ? 500 : response.status
error.code = data?.code
throw error
}
return data
}
/** Appwrite Query-Helper (kompatibel zu bisherigen Aufrufen) */
export const Query = {
equal: (attribute, value) => ({
method: 'equal',
attribute,
values: Array.isArray(value) ? value : [value],
}),
limit: (n) => ({ method: 'limit', values: [n] }),
orderDesc: (attribute) => ({ method: 'orderDesc', attribute }),
orderAsc: (attribute) => ({ method: 'orderAsc', attribute }),
}
export const ID = {
unique: () => randomUUID(),
}
function collectionPath(collectionId) {
return `/databases/${config.appwrite.databaseId}/collections/${collectionId}/documents`
}
export async function getUserById(userId) {
return adminFetch(`/users/${userId}`)
}
export async function deleteUserSession(userId, sessionId) {
return adminFetch(`/users/${userId}/sessions/${sessionId}`, { method: 'DELETE' })
}
export async function listDocuments(collectionId, queries = []) {
const result = await adminFetch(collectionPath(collectionId), { queries })
return result.documents
}
export async function getCustomerByAppwriteUserId(appwriteUserId) {
const docs = await listDocuments(config.collections.customers, [
Query.equal('appwriteUserId', appwriteUserId),
Query.limit(1),
])
return docs[0] || null
}
export async function getPortalAccessByCustomerId(customerId) {
const docs = await listDocuments(config.collections.customerPortalAccess, [
Query.equal('customerId', customerId),
Query.limit(1),
])
return docs[0] || null
}
export async function updateDocument(collectionId, documentId, data) {
return adminFetch(`${collectionPath(collectionId)}/${documentId}`, {
method: 'PATCH',
body: data,
})
}
export async function upsertWebsiteProjectByRepo(repoFullName, data) {
const existing = await listDocuments(config.collections.websiteProjects, [
Query.equal('repoFullName', repoFullName),
Query.limit(1),
])
const now = new Date().toISOString()
const payload = { ...data, updatedAt: now }
if (existing[0]) {
return updateDocument(
config.collections.websiteProjects,
existing[0].$id,
payload
)
}
return adminFetch(collectionPath(config.collections.websiteProjects), {
method: 'POST',
body: { ...payload, createdAt: now, documentId: ID.unique() },
})
}
/** @deprecated Nur für Kompatibilität nutzt native fetch */
export function createAdminClient() {
return { usesNativeFetch: true, databaseId: WOMS_DATABASE_ID }
}
export function createUserClient() {
return { usesNativeFetch: true }
}