DDay Sync
Log in

Technical overview

Next.js 16React 19TypeScriptPrisma 7PostgresLangChain / LangGraphOpenAI gpt-4oGoogle Calendar APITailwind CSS 4ZodJWT + bcrypt

What's actually running under Day Sync's chat interface — architecture, agent design, security, and data model.

Architecture & streaming

1
Next.js 16 App Router, server-first

The root route checks auth server-side (getUserId()) and redirects before any client JS ships. Only the interactive surfaces — login, chat, demo — are client components; everything else stays on the server.

2
Token-level SSE streaming

/api/chat streams the LangGraph agent's streamEvents output over Server-Sent Events. The client reads the stream and calls flushSync per token so React paints immediately instead of batching — the UI reads as truly live, not a delayed dump.

AI agent design

3
LangGraph tool-calling state machine

gpt-4o is bound to four Zod-validated tools via DynamicStructuredTool. A StateGraph conditionally routes between the model node and a tool-execution node based on whether the last message carries tool_calls, looping until the model responds with plain text.

4
Per-request, per-user tool scoping

Tools are built fresh per request (buildTools(userId, clientIp)), closing over the current user's id — there's no global calendar client, so one request can never leak another user's calendar access.

5
Confirm-before-destructive by design

The delete-event tool's own description instructs the model to confirm with the user before calling it, and the UI enforces a second click ("Cancel it" / "Keep") — the destructive path requires agreement at both the prompt and UI layer.

Security & auth

6
Self-healing OAuth token lifecycle

Google access tokens auto-refresh via googleapis's OAuth2Client using the stored refresh_token — no manual expiry checks. An on('tokens', ...) listener transparently persists rotated tokens back to Postgres on every refresh.

7
Configurable JWT session TTL

Sessions are signed HS256 JWTs in an httpOnly, sameSite=lax cookie. Expiry is one SESSION_MINUTES env var shared by login, signup, and demo-login through a single setSessionCookie() helper, so the three paths can never drift out of sync.

8
Per-IP sliding-window rate limiting

The public demo account is capped via an in-memory sliding-window counter keyed by client IP (trusted from x-forwarded-for on Vercel's edge) — one misbehaving visitor can't exhaust the quota for everyone else sharing the same demo login.

9
Credential-free public demo

/api/auth/demo-login reads the demo account's credentials server-side from environment variables and issues a session directly — the browser never receives or displays a password.

Data model

10
Minimal, tightly-scoped data model

GoogleToken is @unique on userId with onDelete: Cascade — a strict one-to-one with User, so calendar credentials are deleted automatically the moment an account is, with no orphaned tokens to manage.