Technical Philosophy
How we build product workflows
Velyn Dental relies on a few engineering basics: clear triggers, fast responses, useful records, and fallbacks when a dependency fails.
What we are building: Product workflows that answer calls, save the record, and prepare follow-up without hiding what happened from the practice.
Core Principles
Background Work With Clear Triggers
Some work should happen without anyone babysitting the screen: answering calls, saving transcripts, and preparing follow-up.
→ Event-driven architecture with scheduled checks, explicit thresholds, and traceable actions.
Models Are Only Part of the Product
The hard parts are reliability, latency, fallbacks, and the rules around when to alert or hand off.
→ Streaming pipelines, fallback chains, and state machines that handle edge cases gracefully.
Latency Changes Trust
A voice workflow that waits too long feels broken. A callback task that shows up hours late is not useful.
→ Parallel processing, warm connections, predictive caching, and aggressive optimization.
Designed for Early Scale
Serverless-first architecture keeps small launch traffic simple and gives busy periods room to grow.
→ Vercel Functions + edge compute, connection pooling, and usage-based pricing that scales linearly.
Fail Gracefully, Always
APIs time out. Networks drop. Models can fail. The product needs a clear fallback instead of a silent dead end.
→ Circuit breakers, fallback responses, retry logic with exponential backoff, and monitoring at every layer.
Ship Fast, Learn Faster
Real use teaches what demos cannot. We optimize for small releases, visible monitoring, and fast correction.
→ Feature flags, canary deployments, real-time monitoring, and weekly release cycles.
Architecture Patterns
These patterns recur throughout Velyn Dental. They keep call handling, handoffs, and follow-up work understandable under stress.
Event-Driven Monitoring
How do you know when to take action without constantly asking?
Scheduled background jobs (cron) that check state and act when conditions are met.
Velyn Dental runs a scheduled job every 30 minutes. When it is 7 a.m. in a practice's time zone, it emails the team a digest of the calls and callback tasks that came in after hours. A per-practice, per-day claim keeps the email from going out twice.
// Vercel cron runs every 30 minutes
export async function GET(req: Request) {
const practices = await getDigestTargets();
const due = practices.filter((p) => isSevenAmLocal(p.timezone, new Date()));
for (const practice of due) {
// One claim per practice per day, so a retried run can't double-send
const claimed = await claimDigest(practice.id, localDateKey(practice.timezone));
if (!claimed) continue;
const digest = await buildAfterHoursDigest(practice.id);
await emailTeam(practice.recipients, digest);
}
return Response.json({ practices: due.length });
}Streaming Pipelines
Voice AI needs <2s latency. Sequential processing takes 5-10s.
Stream every layer: transcription → LLM → synthesis. Start speaking before the LLM finishes thinking.
Velyn Dental streams Google speech-to-text into Claude (via AWS Bedrock), which streams to voice synthesis — targeting sub-2-second latency.
// Stream LLM response to voice synthesis
const stream = anthropic.messages.stream({
model: "claude-haiku-4-5-20251001",
messages: conversationHistory,
max_tokens: 300,
});
for await (const event of stream) {
if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
// Synthesize and play immediately
await synthesizeAndStream(event.delta.text);
}
}Checked Decisions
How do you keep a model from acting on a bad guess?
Every model decision is checked before it is used. A failed check means fall back, not guess.
Before Velyn Dental uses Claude's routing decision on a live call, policy and grounding checks run against the practice's published facts. A failed check is logged and the call goes to a safe default route.
interface Decision {
shouldAct: boolean;
confidence: number; // 0-100
reasoning: string;
}
function makeDecision(context: Context): Decision {
const signals = analyzeSignals(context);
const confidence = calculateConfidence(signals);
// Only act if confidence > 80%
return {
shouldAct: confidence > 80,
confidence,
reasoning: explainDecision(signals),
};
}State Persistence
What did the product already tell the user, caller, or team?
Important interactions persist to the database. Decision engines check history before acting.
Velyn Dental can use previous call records from the same number so staff do not start from scratch.
// Pull recent calls from the same number before the team calls back
const priorCalls = await db.callLog.findMany({
where: {
practiceId: practice.id,
from: call.from,
createdAt: { gte: subDays(new Date(), 30) },
},
orderBy: { createdAt: "desc" },
take: 3,
});
// Staff see what the caller already asked about, not a blank slate
return { ...task, priorCalls };Key Technical Decisions
Every choice is a trade-off. Here's what we chose and why.
Serverless over containers
AI workloads are spiky. Serverless scales to zero during off-hours and handles 100x spikes instantly. No DevOps overhead.
PostgreSQL over NoSQL
Relational data (practices, calls, tasks) with strong consistency requirements. Prisma provides type-safe queries.
Monorepo over microservices
Small team, shared types/utilities. Microservices add coordination overhead we don't need at this scale.
Telnyx over custom WebRTC
Telephony is complex. Telnyx handles PSTN connectivity, HIPAA-eligible transport under a signed BAA, and reliability. We focus on AI logic.
Managed model APIs over self-hosted models
Inference cost ($0.03/min) is negligible vs engineering time. Self-hosting adds operational complexity without ROI.
Monitoring > Testing
Unit tests catch syntax errors. Production monitoring catches real user problems. We invest heavily in Datadog + Sentry.
What we do differently
The product keeps working between visits
Customers should not have to keep checking the same screen. The product watches the narrow workflow it was built for, then shows a clear record when something needs attention.
- •Keep answering calls and tracking tasks in the background
- •Open with the details that explain why a call needs attention
- •Prepare the follow-up: answer the call, save the transcript, create the task
- •Keep the history attached for whoever touches it next
Example: A front desk should not have to wonder whether a patient called after hours. Velyn answers the call, saves the transcript, and creates the callback task before anyone opens the office.
That requires telephony, speech recognition, state management, handoff rules, and task delivery. That is the product work we build.
What's next
Right now Velyn catches what matters and shows the record. The next step is handling more of the follow-through, such as appointment booking, while keeping the practice in control.
We ship what works today and add more automation only where trust is earned.
Want to see this approach in action?