Projekt-Ablauf im Ticketsystem: Anlegen, Archivieren, Import repariert

- Neues Projekt ohne Subdomain: subdomain null statt '' (Unique-Index
  subdomain_unique, jedes weitere scheiterte mit "Document with the
  requested ID already exists"); ebenso Typ "Internes Projekt"
- Anlegen unter derselben Repo-Sperre wie der Webhook repository/created;
  upsertWebsiteProjectByRepo macht aus einem 409 ein Update
- Gitea-Beschreibung = Anzeigename; Art (kind) beim Anlegen aus dem Ticket
- Reaktivieren setzt status zurueck (vorher blieb 'archived' stehen)
- Import: archivierte Repos als archiviert, Archiv-Stand aus Gitea wird
  gespiegelt, ein fehlerhaftes Repo bricht den Lauf nicht mehr ab
- Abgleich ueberschreibt Projektnamen nicht mehr
- CORS erlaubt PUT (Preview-Variablen speichern)
- Vorlage zieht beim Zuweisen nie in die Org um
- Erinnerungs-Lauf ueberspringt archivierte Projekte
- kaputte Umlaute (U+FFFD) in drei Fehlermeldungen

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-04 13:22:53 +00:00
1 parent 3a0b0089dd
commit e43cdb667b
13 files changed
+498 -83

No files matched your search

+26 -13
View File
@@ -300,19 +300,32 @@ export async function upsertWebsiteProjectByRepo(repoFullName, data) {
}
const now = new Date().toISOString()
return adminFetch(collectionPath(config.collections.websiteProjects), {
method: 'POST',
body: {
...payload,
customerId: payload.customerId ?? '',
ticketId: payload.ticketId ?? '',
status: payload.status ?? 'pending',
provisioningStatus: payload.provisioningStatus ?? 'pending',
projectName: payload.projectName || repoFullName.split('/').pop() || repoFullName,
createdAt: now,
documentId: ID.unique(),
},
})
try {
return await adminFetch(collectionPath(config.collections.websiteProjects), {
method: 'POST',
body: {
...payload,
customerId: payload.customerId ?? '',
ticketId: payload.ticketId ?? '',
status: payload.status ?? 'pending',
provisioningStatus: payload.provisioningStatus ?? 'pending',
projectName: payload.projectName || repoFullName.split('/').pop() || repoFullName,
createdAt: now,
documentId: ID.unique(),
},
})
} catch (err) {
// Ein anderer Schreiber ohne gemeinsame Sperre hat das Dokument zwischen Suche und Anlage
// angelegt: der Unique-Index auf repoFullName meldet 409. Dann das vorhandene Dokument
// aktualisieren, statt den Fehler bis in die Oberflaeche zu reichen.
if (err.status !== 409) throw err
const raced = await listDocuments(config.collections.websiteProjects, [
Query.equal('repoFullName', repoFullName),
Query.limit(1),
])
if (!raced[0]) throw err
return updateDocument(config.collections.websiteProjects, raced[0].$id, buildProjectPayload(raced[0], data))
}
}
export async function verifyDatabaseAccess() {