feat: Projekte ohne Subdomain, Portal-Zugang unter Uebersicht, Kunden-Zuordnung

- ProjectsPage: Subdomain optional (ohne = normales Projekt, nur Gitea-Repo);
  Kunde direkt in der Tabelle zuordnen; Button 'Gitea-Repos synchronisieren'
- CustomerDetailPage: Card 'Portal-Zugang' unter Uebersicht - Passwort setzen/
  aendern (min. 8 Zeichen), Login+Passwort kopierbar, Link zum Kundenportal
- leads.js: uebrig gebliebene Debug-Instrumentierung entfernt

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 16:40:10 +00:00
parent f76b738f5f
commit 4be20237a1
3 changed files with 161 additions and 30 deletions

View File

@@ -84,24 +84,13 @@ export async function createAcquisitionTicket(customer, user) {
/** Legt einen Lead an (nur Unternehmen + E-Mail) und erstellt das Akquise-Ticket. */
export async function createLead({ company, email }, user) {
let customer
try {
customer = await databases.createDocument(DATABASE_ID, COLLECTIONS.CUSTOMERS, ID.unique(), {
name: company,
companyName: company,
email: email || '',
customerStatus: 'lead',
updatedAt: new Date().toISOString(),
})
// #region agent log
fetch('http://127.0.0.1:7284/ingest/0747da40-b90b-4354-9b84-c9b550a81ec9', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Debug-Session-Id': '693b5f' }, body: JSON.stringify({ sessionId: '693b5f', runId: 'post-fix', hypothesisId: 'A', location: 'leads.js:createLead', message: 'lead created ok', data: { id: customer.$id }, timestamp: Date.now() }) }).catch(() => {})
// #endregion
} catch (err) {
// #region agent log
fetch('http://127.0.0.1:7284/ingest/0747da40-b90b-4354-9b84-c9b550a81ec9', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Debug-Session-Id': '693b5f' }, body: JSON.stringify({ sessionId: '693b5f', runId: 'post-fix', hypothesisId: 'A', location: 'leads.js:createLead', message: 'lead create FAILED', data: { error: String(err && err.message) }, timestamp: Date.now() }) }).catch(() => {})
// #endregion
throw err
}
const customer = await databases.createDocument(DATABASE_ID, COLLECTIONS.CUSTOMERS, ID.unique(), {
name: company,
companyName: company,
email: email || '',
customerStatus: 'lead',
updatedAt: new Date().toISOString(),
})
let ticket = null
try {
ticket = await createAcquisitionTicket(customer, user)