---
title: private-ops Phase 1 — In Progress
type: project
tags: [private-ops, phase-1, milestone]
date: 2026-05-14
status: aktiv
related: [[CONTEXT]], [[features-map]], [[phase-0-complete]]
description: Phase 1 Foundation Update 2026-05-14 23:35 CEST. 3 PRs in main (Wiring + Magic-Link + TOTP). Magic-Link end-to-end verifiziert. TOTP-Test pending wegen SMTP-rate-limit.
---

# private-ops — Phase 1 In Progress (2026-05-14 23:35 CEST)

## Was steht (Phase 1 PRs gemerged)

| PR | Title | Commit |
|---|---|---|
| #11 | fix(vercel): typedRoutes top-level + vercel.json --prod=false install | `bcd0c87` |
| #12 | feat(phase-1): Supabase SSR + Sentry + structured logging + env validator | `2b06a4d` |
| #13 | feat(auth): magic-link login + session helpers + authed layout | `652df0e` |
| #14 | feat(auth): TOTP-2FA — Supabase native MFA enroll + step-up flow | `c1517a3` |

72 vitest passed. 9 CI-Jobs grün auf jedem PR.

## Code-Layout

```
apps/web/src/
├── lib/
│   ├── env.ts                          Zod-validated env loader
│   ├── logger.ts                       JSON-to-stdout structured logger
│   ├── auth/
│   │   ├── get-user.ts                 getCurrentUser + requireUser
│   │   ├── get-user.test.ts            4 assertions
│   │   ├── mfa.ts                      getUserMfaState + getCurrentAal + requireAal2
│   │   └── mfa.test.ts                 6 assertions
│   └── supabase/
│       ├── client.ts                   browser (anon-key)
│       └── server.ts                   SSR (anon-key + cookies)
├── app/
│   ├── page.tsx                        Public landing
│   ├── (auth)/
│   │   ├── layout.tsx                  Centered single-column
│   │   ├── login/
│   │   │   ├── page.tsx
│   │   │   ├── login-form.tsx          Client form, useTransition
│   │   │   ├── actions.ts              Magic-link send
│   │   │   └── actions.test.ts         4 assertions
│   │   ├── login/verify-mfa/
│   │   │   ├── page.tsx                Step-up if AAL1
│   │   │   ├── verify-form.tsx
│   │   │   └── actions.ts              verifyMfaChallenge
│   │   └── logout/route.ts             POST-only (CSRF-resistant)
│   ├── (authed)/
│   │   ├── layout.tsx                  requireUser + Settings/Logout header
│   │   ├── home/page.tsx               "Du bist eingeloggt"
│   │   └── settings/
│   │       ├── page.tsx                Settings landing
│   │       └── security/
│   │           ├── page.tsx            MFA enroll + remove
│   │           ├── security-form.tsx   3-state (none/enrolling/enrolled)
│   │           ├── actions.ts          enroll + verify + unenroll
│   │           └── actions.test.ts     8 assertions
│   ├── auth/callback/route.ts          OAuth-style code → session
│   └── api/health/route.ts             Readiness probe
├── middleware.ts                       Edge-runtime safe session refresh
├── instrumentation.ts                  Sentry server/edge
└── instrumentation-client.ts           Sentry browser
```

## Production verifiziert

- Vercel deploy READY auf `https://private-ops-web.vercel.app`
- `/api/health` returns `{"status":"ok","supabase":"ok"}`
- Magic-Link send → email arrives → callback → session → `/home`
- Logout works

## NICHT verifiziert (pending)

- TOTP enroll + step-up flow (SMTP rate-limit erreicht)

## Pre-Reqs für PR #7+

| Pre-Req | Status |
|---|---|
| Supabase EU project | ✓ provisioniert + Auth-URL-Config |
| Vercel project | ✓ + 8 env-vars (Production + Preview, kein Dev für Sensitive) |
| Anthropic Org-Key | ✓ key + ZDR-Sales-Antrag (Antwort: ZDR Enterprise-only) |
| Sentry EU | ✓ DSN configured |
| Better Stack | ✓ token (auto-injected) |
| User in Supabase | ✓ aseckzai@gmail.com |

## Open todos

- TOTP end-to-end-Test (nach Rate-Limit-Reset oder Custom-SMTP)
- Custom SMTP Setup (Resend / Postmark / SendGrid mit DKIM)
- `headers()` Hotfix für NEXT_PUBLIC_APP_URL (statt Env-Var-Default)
- Vercel Env-Var Cleanup nicht 100% (Sensitive-Vars Production + Preview)

## Phase 1 PR-Plan (verbleibend)

| PR | Inhalt | Plan-Mode |
|---|---|---|
| #15 (planned) | WebAuthn / Passkey via @simplewebauthn/* | Ja |
| #16 (planned) | audit_log table + SECURITY DEFINER writer + packages/admin/ scaffold | Ja |
| #17 (planned) | spaces + space_members + persons-RLS-Update | Ja |
| #18 (planned) | pgsodium / Field-Encryption Tier-4 | Ja |
| #19 (planned) | Capability-Tokens scaffolding | Ja |

## Brain-Notes verwandt

- [[CONTEXT]] — Vision + Boundaries + Phasen-Map
- [[features-map]] — 8 Cluster
- [[infrastructure-decisions]] — Stack + Encryption + Cost
- [[phase-0-complete]] — Phase 0 Milestone
