Trusted Infrastructure Platform
Decentralized identity platform with custom auth, iOS client, and admin dashboard
Trusted Infrastructure Platform
A decentralized authentication and trusted infrastructure platform spanning four repositories: a Node.js/TypeScript backend monorepo with shared packages and multiple service apps, a SwiftUI iOS client with OIDC authentication, a Next.js admin dashboard, and a custom OpenID Connect auth server. Uses blockchain for authentication and identity verification -- similar in concept to trusted compute frameworks for AI safety. The most architecturally complex project I've worked on.
iOS + Web + API
Platform
iOS + Full-Stack Engineer
Role
From Protocol to Platform
Backend Monorepo Architecture
Turborepo monorepo with shared packages covering auth, database, config, event bus, queue, storage, vector, and more -- plus multiple service apps. API servers import from packages, but packages never import from apps. That rule is sacred.
Blockchain Auth & OIDC Server
Custom OpenID Connect provider from scratch using Express 5 and the oidc-provider library, with blockchain-based identity verification underpinning the trust model. Authorization code flows, token exchange, refresh tokens, consent screens. Redis-backed sessions with testcontainers for integration testing. Building your own auth server with blockchain verification is unusual, but the trust and security requirements left no alternative.
iOS Client with Snapshot Testing
SwiftUI app with modular SPM packages covering API communication, authentication, utilities, AI integration, persistence, and secrets management. Snapshot testing uses CI-recorded reference images so visual consistency doesn't depend on which Xcode version a developer happens to have.
Dashboard & Worker Services
Next.js admin dashboard with shadcn/ui and TanStack Query. Backend workers process background jobs via BullMQ with Redis for scheduled tasks, async processing, and event-driven workflows.
Trust Meets Architecture
16-Package Shared Architecture
16 packages shared across 6 services. The database package owns all PostgreSQL schemas and migrations with typed repositories. A dedicated runtime package handles LLM execution with streaming and tool calling. An event bus connects services. Turborepo builds only what changed, so a package modification rebuilds only its dependents.
Blockchain-Backed OIDC Authentication
No Auth0, no Clerk. Trust and security requirements mandated a self-hosted OIDC provider with blockchain-based identity verification. Full OAuth 2.0 authorization code flow with login screens, consent prompts, token issuance, and refresh. Blockchain provides the immutable identity layer that traditional auth can't. Both the iOS app and web dashboard authenticate against the same provider. One identity, everywhere.
AI-Integrated iOS Client
Chat interface powered by the platform's AI backend. A dedicated AI package handles conversation management, streaming responses, and tool call rendering. Snapshot testing with CI-recorded reference images ensures the chat UI renders consistently regardless of device or OS version.
Under the Hood
Key Technical Decisions
Turborepo Package Boundaries
Package-based architecture means dependency management is everything. Each package declares dependencies explicitly in package.json. No implicit imports. The database package exports typed repository functions, not raw SQL. The shared package owns Zod schemas used by both API validation and client-side type generation. A new engineer can understand one package without reading the others. That was the whole point.
OIDC from Scratch
Most projects use Auth0 or Clerk for good reason. This one couldn't. The OIDC library handles protocol complexity, but the integration work was substantial: session store configuration, login views, schema-validated configuration. Containerized integration tests spin up automatically, which saved a lot of "works on my machine" debugging.
Snapshot Testing on CI
Reference images vary between local machines because of different Xcode versions and simulators. We record references exclusively on CI. Developers run tests to detect changes, CI is the source of truth for what the UI should look like. Solved the problem of snapshot tests that pass locally and fail in CI.
What I Learned
A large package count sounds like over-engineering until you see the alternative
Each package stays small and focused. A monolithic backend would have changing auth logic potentially break database migrations. Small packages with explicit interfaces are easier to reason about, full stop.
We almost used Auth0 and I'm glad we didn't
Third-party auth is faster to integrate but harder to customize. Custom consent flows, specific token claims, self-hosted infrastructure. Building the OIDC server saved time long-term. The key was using oidc-provider instead of implementing the protocol ourselves.
We considered one monorepo for everything
Backend, iOS, web, auth. Swift and Node.js toolchains don't play well together. Four repos with shared types via API contracts keeps each team's tooling simple and maintains type safety at the boundaries.
Restaurant Operations Platform
iPad restaurant system -- floor plans, payments, and receipt printing over Bluetooth