144 lines
3.8 KiB
JavaScript
144 lines
3.8 KiB
JavaScript
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 }
|
||
}
|