Technology
Built on AWS, end to end.
Vekuri runs on Amazon Web Services in US and EU regions, with a TypeScript codebase from database to phone: Next.js on the web, React Native on iOS and Android, one contract-first API in between. This page is the architecture an IT team asks for before saying yes: the services, the security posture, how it is operated, and the service levels it runs to.
At a glance
- Cloud
- AWS, multi-AZ, US-East primary; each organization pinned to a region.
- Web
- Next.js 16, React 19, TypeScript.
- Mobile
- React Native (Expo SDK 57, New Architecture), iOS and Android.
- API
- NestJS 11 on Fastify, Node.js 24 LTS, REST, OpenAPI 3, generated typed clients.
- Data
- Amazon Aurora PostgreSQL 18 Serverless v2, RDS Proxy, Drizzle ORM, row-level security per organization.
- Storage
- Amazon S3 with Object Lock (compliance mode).
- Identity
- Amazon Cognito for identity and sessions; WorkOS for enterprise SSO (SAML 2.0 / OIDC) and SCIM 2.0.
- Realtime
- AWS AppSync Events (WebSocket).
- AI
- Amazon Bedrock (Claude Sonnet 5) with Bedrock Guardrails; ElevenLabs Agents for voice practice.
- Service levels
- 99.9% monthly uptime SLA; RPO 5 min, RTO 30 min.
- Compliance
- SOC 2 Type II controls continuously monitored with Vanta; WCAG 2.2 AA; TLS 1.2+ in transit, AWS KMS at rest.
Architecture
Requests enter through CloudFront and AWS WAF, reach an Application Load Balancer, and land on ECS Fargate containers for the admin console, the employee web app and the API. The mobile app calls the same API. Behind the API sit Aurora PostgreSQL, ElastiCache and the services that carry the asynchronous work.
Edge
- Amazon CloudFrontCDN and signed URLs
- AWS WAF and ShieldManaged rules, Bot Control, rate limiting
- Application Load BalancerTLS termination, routing
Applications
- Admin consoleNext.js on ECS Fargate
- Employee web appNext.js on ECS Fargate
- APINestJS on ECS Fargate
- Mobile appReact Native, same API
- WorkersECS Fargate worker services (SQS, EventBridge)
Data and services
- Aurora PostgreSQL 18Multi-AZ, RDS Proxy, row-level security
- ElastiCache (Valkey 9)Cache, rate limits, realtime state
- Amazon S3Evidence, video, Object Lock
- SQS, EventBridge, EventBridge Scheduler, Step FunctionsAsynchronous work
- AppSync EventsLive roster over WebSocket
- MediaConvertHLS transcoding
- Amazon TextractOCR of sign-in sheets
- SESEmail
- AWS End User MessagingSMS
- Amazon SNSPush to APNs and FCM
- BedrockAI drafting and guardrails
- KMSOne customer-managed key per organization
- Aurora PostgreSQL 18 runs multi-AZ behind RDS Proxy for connection pooling.
- ElastiCache (Valkey 9) holds cache, rate limits and ephemeral realtime state.
- SQS, EventBridge, EventBridge Scheduler and Step Functions run the asynchronous work: issuance, expiry ladders, imports, notification fan-out and ledger anchoring.
- ECS Fargate worker services consume SQS and EventBridge and share the API's domain modules.
- AppSync Events pushes the live roster over WebSocket, with a 5-second polling fallback.
- Video is stored in S3, transcoded by MediaConvert and served through CloudFront signed URLs.
- Photographed sign-in sheets are read by Amazon Textract inside the organization's region; the recognized names are matched to the roster and confirmed by the facilitator.
- Email leaves through SES, SMS through AWS End User Messaging on a 10DLC-registered number, and push through Amazon SNS to APNs and FCM.
- AWS KMS holds one customer-managed key per organization.
Application stack
One TypeScript monorepo from database to phone. The API's contract is generated from its code, and the clients are generated from the contract, so drift between them is a build error.
Monorepo
pnpm 11 and Turborepo 2, with strict TypeScript everywhere.
- strict and noUncheckedIndexedAccess are on in every package.
- A shared design system package: tokens, HeroUI 3 over React Aria, Tailwind CSS 4.
- Shared domain schemas in zod 4, used by web, mobile and API.
- Typed API clients generated by orval from the OpenAPI document.
Web
Next.js 16 App Router on React 19.
- TanStack Query 5 for server state; react-hook-form with zod for forms.
- The employee web app installs as a PWA, with a service worker caching the app shell.
Mobile
React Native 0.86 through Expo SDK 57 on the New Architecture, with expo-router.
- EAS Build and Submit for store releases; EAS Update for over-the-air JavaScript fixes.
- Secure token storage, biometric unlock and camera QR scanning.
- Push through Amazon SNS to APNs and FCM.
- A SQLite offline cache of lessons and records, synced on reconnect.
- Universal links open the right screen from a notification and from an email.
- Certificate pinning and jailbreak and root detection.
- MDM distribution through Apple Business Manager and Android Enterprise.
API
A NestJS 11 modular monolith on the Fastify adapter, one module per domain.
- Modules: tenancy, courses, classes, attendance, certifications, evidence, assessment, notifications, dashboards.
- OpenAPI 3 is generated from the code, and typed clients are generated for web and mobile; contract drift is a build error.
- Drizzle ORM, with SET LOCAL organization context per transaction.
- Offset pagination is the list convention.
- Background workers share the domain modules and run as ECS Fargate services consuming SQS and EventBridge.
- The API and workers run on Node.js 24 LTS.
Data and tenancy
A single Aurora PostgreSQL cluster with a shared schema and an organization identifier on every tenant row, isolated by four layers that each hold on their own.
- Layer one, identity: the session establishes the organization.
- Layer two, API guards: role and organization are checked on every request.
- Layer three, Postgres row-level security: defense in depth, so a defective query cannot cross tenants.
- Layer four, audited platform-admin access: the one path across organizations, and it audits itself.
- A standing cross-tenant test suite runs in CI on every change.
- S3 keys live in per-organization namespaces, and presigned URLs are issued only after authorization.
- Aged evidence moves through S3 Intelligent-Tiering to Glacier under the retention policy.
- Ledger anchors and certificate PDFs are held under Object Lock in compliance mode.
- Backups are continuous (point-in-time recovery) and stored in an AWS Backup vault with vault lock (immutable).
- Each organization has its own AWS KMS customer-managed key (envelope encryption), which makes cryptographic deletion on offboarding a key-destruction operation.
- Data export and deletion APIs serve access and erasure requests (GDPR/CCPA).
- An organization is pinned to a region, US or EU, including AI inference; US and EU regions are served.
Identity and access
Amazon Cognito holds every account and session. Organizations with an identity provider federate through WorkOS; employees without one sign in on the local lane. The authentication lane is explicit per account and never inferred.
- Amazon Cognito runs the local lane: passwordless sign-in by email code, and admin-provisioned username and password for employees without an email address.
- WorkOS runs enterprise SSO over SAML 2.0 and OIDC with Okta, Microsoft Entra ID and Google Workspace.
- WorkOS runs SCIM 2.0 provisioning and deprovisioning from the identity provider.
- MFA uses TOTP and passkeys.
- Each account has an explicit auth lane; nothing is inferred from an email domain.
- Deactivation is enforced on every request, not only at sign-in.
- Tokens are short-lived; refresh tokens live in secure storage on mobile.
- The admin console itself sits behind SSO.
- Roles: Platform admin, Organization admin, Content manager, Supervisor, Employee; Facilitator is a per-session designation.
Security
Private networking, least privilege, continuous monitoring, and vendors held to the same posture.
- Compute and data sit in private subnets inside a VPC, reached through VPC endpoints; the database has no public address.
- AWS WAF managed rules and rate limiting at the edge, with AWS Shield; AWS WAF Bot Control guards the sign-in and roster endpoints.
- AWS PrivateLink connects organizations that require private connectivity.
- Least-privilege IAM per service; secrets in Secrets Manager with rotation.
- GuardDuty, Security Hub and Amazon Inspector (container and dependency scanning) run continuously.
- A CloudTrail organization trail feeds CloudTrail Lake; AWS Config tracks configuration; Macie watches the document buckets.
- TLS 1.2 or later everywhere; encryption at rest by default.
- Every file is served through a signed URL.
- Attendance tokens carry a TTL, are single-use and session-bound; rejected redemptions are logged without retaining unknown values.
- An SBOM is generated per build with SLSA provenance attestations.
- An independent penetration test runs annually.
- SOC 2 Type II controls are continuously monitored with Vanta; audit reports are available under NDA.
- AWS's own infrastructure reports (SOC 1, 2 and 3, ISO 27001) come through AWS Artifact.
- A data processing agreement and a published sub-processor list cover every vendor below.
- Amazon Bedrock does not train on customer data, per its published trust documentation.
- ElevenLabs holds SOC 2 Type II and ISO 27001 per its published trust documentation, and Vekuri runs it in zero-retention mode.
- SMS is sent only with recorded consent (TCPA) from a 10DLC-registered number.
Audit ledger
Certificate and attendance history is an append-only event log with a hash chain, anchored daily to write-once storage, so any retroactive edit is detectable by anyone holding an export.
- Every event carries a sequence number, the hash of the previous event and its own hash over the event's content.
- Events are append-only at the database layer; there is no update path and no delete path for them.
- Each day the chain heads are written to S3 under Object Lock in compliance mode, which not even the operator can rewrite within the retention window.
- A verification walk recomputes the chain from any point and compares it against the anchored heads.
- Exports carry the proofs, so an auditor verifies them without access to the platform.
- Every event is attributed to a human, a system or an assistant actor.
Reliability and operations
Multi-AZ by default, cross-region recovery, and observability that watches the journeys that matter.
- Fargate services and Aurora run multi-AZ with auto-scaling.
- Recovery point objective is 5 minutes; recovery time objective is 30 minutes; uptime is 99.9% monthly under SLA.
- AWS Backup policies cover the data stores.
- Cross-region disaster recovery runs on Aurora Global Database.
- Deployments are blue/green.
- Feature flags run on AWS AppConfig with automatic rollback.
- CloudWatch logs, metrics and alarms, with Application Signals for SLOs.
- Distributed tracing with X-Ray through OpenTelemetry (ADOT).
- CloudWatch Synthetics canaries run against sign-in, course load, check-in and certificate download.
- CloudWatch RUM measures Core Web Vitals on real sessions; Sentry collects web and mobile errors.
- A public status page runs on Better Stack, and an on-call rotation answers every alert.
Delivery and quality
Every environment is reproducible from code, every deploy passes the same gates, and the tests cover what the product promises: isolation, accessibility and the check-in burst.
- Infrastructure as code with AWS CDK v2; every environment is reproducible.
- GitHub Actions authenticates to AWS with OIDC; there are no long-lived keys.
- Separate AWS accounts for dev, staging and prod under AWS Organizations, with Control Tower guardrails.
- Ephemeral preview environments per pull request.
- Database migrations are versioned with Drizzle Kit and gated before traffic cutover.
- Dependabot, ECR image scanning and Amazon Inspector keep dependencies and images current.
- An SBOM with SLSA provenance is produced for every build.
- Unit and component tests with Vitest 4 and Testing Library; end-to-end tests with Playwright, including responsive runs at 320, 390, 768 and 1024 pixels.
- axe accessibility checks in CI, plus a manual screen-reader pass per release with VoiceOver, TalkBack and NVDA.
- The cross-tenant isolation suite and a load test of the check-in burst run in CI.
- Release cadence: weekly on the web; mobile store releases with over-the-air fixes in between.
- The API and workers run on Node.js 24 LTS.
Integration surface
Everything the console does is reachable through the API, and the systems around Vekuri connect through standard protocols.
- A versioned public REST API (OpenAPI 3) with API keys, rate limits and quotas.
- HMAC-signed webhooks (course completed, certificate issued, attendance recorded, and more) with retries and a dead-letter view.
- SAML/OIDC single sign-on and SCIM provisioning through WorkOS.
- Lattice and other HRIS systems sync read-only on a schedule.
- A CSV bulk import pipeline that validates, dedupes and provisions.
- SCORM 1.2, SCORM 2004 and xAPI import through the Rustici SCORM Cloud runtime, and an xAPI statement endpoint.
- Zoom webhooks for join and leave reconciliation.
- Incumbent LMS history import (Docebo).
- Email in and out through SES.
- Calendar export as ICS.
Performance and accessibility
Targets are measured on real sessions through CloudWatch RUM and on mid-range phones over degraded connections, not on a lab machine.
- Core Web Vitals targets: LCP under 2.5 seconds, INP under 200 milliseconds, CLS under 0.1, measured on real sessions.
- Adaptive HLS video with captions, drafted by Amazon Transcribe and reviewed by a person.
- WCAG 2.2 AA across both surfaces.
- Touch targets of at least 44 pixels, and a check-in that works one-handed.
Service levels
The numbers Vekuri operates to.
- Uptime
- 99.9% monthly SLA.
- RPO / RTO
- 5 minutes / 30 minutes.
- Data location
- The organization's region (US or EU), never moved.
- Encryption
- TLS 1.2+ in transit; AWS KMS per-organization keys at rest.
- Isolation
- Row-level security, audited cross-tenant access, and a CI isolation suite.
- Audit
- Hash-chained, anchored to write-once storage, exportable.
- Security
- SOC 2 Type II controls monitored with Vanta, annual penetration test, WAF with Bot Control.
- Support
- 24x7 incident response with a named escalation path.