Tech stack
Languages, frameworks, infrastructure, and third-party services used by Intry.
Intry is a TypeScript-first system: the Core API and most tools share Node.js runtimes, with mobile on Expo and several UIs on Next.js.
| Layer | Technology |
|---|
| Runtime | Node.js |
| HTTP | Express 5 |
| ORM | Prisma |
| Database | PostgreSQL |
| Background jobs | pg-boss (PostgreSQL-backed; no Redis required for workers) |
| Core deploy | Railway (typical) |
| Error tracking | Sentry |
| Use case | Mechanism |
|---|
| Admin dashboard API | WorkOS SSO (legacy) and/or Clerk Organizations (migration); Unkey API keys for automation |
| Property managers / B2B | Clerk org membership (clerkUserId on User; org:role in session) |
| Residents (portal) | Clerk → JWT exchange via /api/v1/auth/clerk-session |
| Residents (mobile) | Clerk or legacy email/password → JWT Bearer |
| Internal ops | Tailscale identity + intry-ops permissions |
See Auth for current vs target (ADR-004) state.
| Capability | Provider |
|---|
| Voice / buzzer | TelephonyProvider abstraction — Twilio or Telnyx via TELEPHONY_PROVIDER |
| Voice webhooks | /twilio/* or /telnyx/* (mirrored routes) |
| SMS / WhatsApp | Twilio or Telnyx through TelephonyProvider |
| OTP verification | Twilio Verify (src/services/verify.ts) |
| Push (mobile) | Knock workflows → FCM (Android) and APNs (iOS) |
| SMS fallbacks | Carrier SMS via TelephonyProvider when user flags enable fallbacks |
| Area | Services |
|---|
| Subscriptions | Stripe direct (ADR-005; no Clerk Billing) |
| Plan tier cache | Clerk org publicMetadata.plan_tier (target); Tenant DB fallback |
| Product analytics | Mixpanel, PostHog |
| APM / logs | New Relic (Core start script) |
| Tool | Purpose |
|---|
| EAS Observe | Production startup/render perf (SDK 55, expo-observe in intry-app) |
| Sentry | Mobile crash and error tracking |
| Vexo / PostHog | In-app product analytics |
See EAS Observe for Intry integration notes.
| Area | Services |
|---|
| Resident/PM chat | Chatwoot (widgets in portal/app; AI bot in Core webhooks) |
| Omnichannel notifications | Knock |
| Surface | Base path | Consumers |
|---|
| Admin | /api/admin/* | Admin SPA, MCP, internal tools |
| Resident v1 | /api/v1/* | Portal, mobile app |
| Voice gateway | /twilio/*, /telnyx/* | Carrier callbacks |
| Legacy mobile | /access/*, /devices/*, /registration/* | Older app builds |
| Webhooks | /stripe, /webhooks/clerk, /webhooks/10dlc/events | Stripe, Clerk, Telnyx 10DLC |
| App | Stack | Hosting (typical) |
|---|
| Admin | Express proxy + static templates + Clerk gateway | Fly.io (intry-admin) |
| Admin 2.0 (target) | Next.js App Router + shadcn/ui (IN-103) | Fly.io |
| Portal | Next.js + Clerk + i18n | Fly.io / Vercel |
| Mobile | Expo / React Native + Clerk + EAS Observe (prod perf) | EAS builds |
| Prop1 | Vite + React + Express | Fly.io (separate DB) |
- Multi-environment admin: proxy sends
X-Admin-Env: DEV, TEST, STAGING, or PROD to route to the correct Core base URL.
- Telephony provider:
TELEPHONY_PROVIDER=twilio or telnyx (per-number VirtualNumber.telephonyProvider is canonical for voice).
- Secrets: Never commit
.env; use platform secrets (Railway, Fly, Vercel) per environment.
Last verified: 2026-06-21 (commit 293c4a7)