The notification guard checks clerkId not email because a client record can exist before the person behind it
Every admin action in portal/admin/actions.ts that triggers a notification wraps the call in if project client clerkId. The client record always has an email — the createClient form requires it. But the notification only fires when clerkId is not null, meaning the client has actually signed up through Clerk. A client created in the admin panel with email sarah@example.com gets a database record immediately, but her clerkId stays null until she follows the portal link and creates her Clerk account. Sending a session notes notification to sarah@example.com before she has signed up would be confusing — she would receive an email with a portal link she cannot access yet because she has no Clerk credentials. The guard makes the notification system aware of the onboarding gap. I can create a client, add projects, set milestones, write session notes, post comments, add deliverables, and assign action items — all silently. The moment Sarah signs up through Clerk, the webhook at api/webhooks/clerk/route.ts matches her email to the existing record and sets her clerkId. From that point forward, every admin write that would interest a client triggers an email. Five notification functions in lib/portal/notifications.ts — notifySessionNotes, notifyMilestoneUpdate, notifyNewComment, notifyNewDeliverable, notifyNewActionItem — all fire through the same gate. The guard checks relationship status, not record existence, and the entire notification backlog is zero because there is no queue. Anything that happened before signup simply does not notify.
Comments coming soon
Sign in with TikTok to leave a comment. Coming soon.