Implementiere Kundenportal mit zentraler Appwrite-Anbindung.

Express-Server für Appwrite-Auth, Session, Projekt-Dashboard und Gitea-Webhook; statisches Frontend und Schema-Dokumentation für woms-database.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-22 23:38:38 +02:00
commit f31727aeb4
23 changed files with 2056 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
import { Client, Account, Databases, ID, Query } from 'node-appwrite'
import { config } from '../config.js'
export function createAdminClient() {
const client = new Client()
.setEndpoint(config.appwrite.endpoint)
.setProject(config.appwrite.projectId)
.setKey(config.appwrite.apiKey)
return {
client,
databases: new Databases(client),
}
}
export function createUserClient() {
const client = new Client()
.setEndpoint(config.appwrite.endpoint)
.setProject(config.appwrite.projectId)
return {
client,
account: new Account(client),
}
}
export async function listDocuments(collectionId, queries = []) {
const { databases } = createAdminClient()
const response = await databases.listDocuments(
config.appwrite.databaseId,
collectionId,
queries
)
return response.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) {
const { databases } = createAdminClient()
return databases.updateDocument(
config.appwrite.databaseId,
collectionId,
documentId,
data
)
}
export async function upsertWebsiteProjectByRepo(repoFullName, data) {
const { databases } = createAdminClient()
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 databases.updateDocument(
config.appwrite.databaseId,
config.collections.websiteProjects,
existing[0].$id,
payload
)
}
return databases.createDocument(
config.appwrite.databaseId,
config.collections.websiteProjects,
ID.unique(),
{ ...payload, createdAt: now }
)
}

View File

@@ -0,0 +1,24 @@
import { createUserClient } from './appwriteAdmin.js'
export async function loginWithAppwrite(email, password) {
const { client, account } = createUserClient()
try {
await account.createEmailPasswordSession(email, password)
} catch (err) {
const message = err?.message || 'Anmeldung fehlgeschlagen'
const error = new Error(message)
error.status = 401
throw error
}
const user = await account.get()
try {
await account.deleteSession('current')
} catch {
// Portal nutzt eigene Session; Appwrite-Session wird nicht persistiert
}
return user
}