Öffnungszeiten: Einschalten im Wartungs-Abo

POST /api/funktionen/zeiten/einschalten (Gratisweg, Spec 3.2): Abo frisch
prüfen, Zustimmung (consentFrei) und Nachweis ohne Stripe-Sitzung, Zustand
setup mit unlockedBy abo, dann Neubau, Einbau-Ticket und K24; ein zweiter
Klick holt Fehlendes nach (holeZeitenNach, eigene Sperre). GET /api/funktionen
liefert das Angebot (zeiten), features.zeiten mit unlockedBy, aboEndeAt, einbau,
loeschungAm sowie zeitenStatus und zeitenLeer je Projekt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-05 02:03:49 +00:00
1 parent 8d670ca5dc
commit 66793d06d5
9 files changed
+1124 -58

No files matched your search

+13
View File
@@ -120,6 +120,19 @@ test('Checkout je Funktion ist in der Kundenansicht gesperrt (Schleife trifft /a
}
})
// Gratisweg "Einschalten" der Oeffnungszeiten (POST /api/funktionen/zeiten/einschalten): eine Schreib-Route, die nicht auf der Erlaubnisliste
// steht; Mitarbeiter schalten nicht fuer den Kunden ein. Der Waechter sperrt sie vor dem Router (die Route prueft zusaetzlich selbst viewAs).
test('Einschalten der Öffnungszeiten ist in der Kundenansicht gesperrt (Route gefunden, nicht erlaubt, 403 view_blocked)', async () => {
const routes = writeRoutes(MOUNTS)
assert.ok(routes.some(({ method, path: p }) => method === 'POST' && p === '/api/funktionen/zeiten/einschalten'), 'Route gefunden')
const p = '/api/funktionen/zeiten/einschalten'
assert.ok(!allowed('POST', p), p)
assert.ok(!allowed('POST', `${p}/`), `${p}/`)
const res = await call('POST', p, { ...kv(), body: { projectId: 'p1', zustimmung: { version: '2026-10-04', haken: ['leistung'] } } })
assert.equal(res.status, 403)
assert.equal(res.body.code, 'view_blocked')
})
test('Erlaubnisliste: genau News, Terminplaner, Öffnungszeiten, Analyse-Link, Ende, Logout und Login', () => {
const ok = [
['POST', '/api/news'], ['POST', '/api/news/image'], ['PATCH', '/api/news/abc'], ['DELETE', '/api/news/abc'],