DTDucas™
Sign inSign in
DTDucas
  • Projects
  • About
  • Capabilities
  • Blog
  • Contact
  • Sign in
  • LinkedIn
  • GitHub
  • X
contact@dtducas.com
|
P05 · 2026

This site — a portfolio that is itself a small distributed system

All projects
Overview

Bilingual marketing site with real backend features: an encrypted auth handshake, a self-hosted admin CMS with scheduled publishing and email campaigns, polyglot persistence, realtime comments, and a full Docker + CI/CD pipeline. The public surface is the product.

Role

Designer & engineer

Stack
  • Next.js
  • NestJS
  • Prisma
  • Postgres
  • MongoDB
  • Redis
  • Socket.IO
  • Docker
  • Turborepo
View repositoryView repository
Highlights
  • 01Encrypted handshake: ECDH P-256 → HKDF → AES-256-GCM, forward secrecy + replay protection
  • 02One CQRS-shaped API contract: typed response envelope + a full error-code catalog
  • 03Self-hosted admin CMS: scheduled publishing, bulk email, ratings, analytics drill-down
  • 04Polyglot persistence (Postgres · MongoDB · Redis) + realtime Socket.IO comments
  • 05Monorepo, multi-stage Docker, GitHub Actions gates, Lighthouse ≥ 95
Behind the build

Auth payloads are encrypted end to end

Signup and login go through an application-layer envelope on top of TLS: ephemeral ECDH P-256 → HKDF-SHA256 → AES-256-GCM, with timestamp + nonce replay protection bound into the GCM AAD. The crypto SDK lives in a shared package, so client and server never drift.

  • 01Client generates an ephemeral ECDH P-256 key pair
  • 02ECDH(client_eph, server_pub) → HKDF-SHA256 → AES-256-GCM key
  • 03Encrypt payload; bind ts + nonce into the GCM AAD
  • 04Server checks ts window + unused nonce (Redis), derives the same key, decrypts
  • 05Server encrypts the response under the same key — forward secrecy per request
  • 06Shared crypto SDK in packages/, imported by both web and api — no client/server drift

Sessions are hardened, not just issued

Beyond the handshake, the auth core does refresh-token rotation with family reuse detection and optional TOTP MFA — the kind of hardening usually skipped on a portfolio site.

  • 01Refresh tokens rotate on every use; each belongs to a session family
  • 02Reuse of a retired token kills the whole family in one transaction (theft response)
  • 03Optional TOTP MFA (authenticator app) with audit-logged enable/disable
  • 04Every public endpoint is rate-limited; auth + subscribe carry Cloudflare Turnstile
  • 05No token, key, nonce, or password hash ever reaches logs or the client bundle

One API contract, CQRS-shaped

Every endpoint speaks one envelope, enforced by a global interceptor + exception filter — not hand-written per controller. Reads return data; writes return success + message; lists carry pagination; errors carry a stable code from a single catalog.

  • 01Query → { data } · Mutation → { success, message, data }
  • 02Paginated → { success, data, pagination: { page, pageSize, totalItems, totalPages } }
  • 03Error → { success: false, message, error: { code } } from one ErrorCode catalog
  • 04Validation → { success: false, errors: [{ field, message }] }
  • 05The encrypted route nests its own interceptor so the global envelope wraps the sealed blob
  • 06Prisma P2025/P2002 mapped to 404/409; /health passes through untouched (Terminus format)

The site runs its own admin CMS

An allow-listed admin app manages users, posts, and subscribers as searchable paginated tables, schedules posts to publish by the minute, and sends bulk email campaigns — backed by the same hardened API.

  • 01Users · Posts · Subscribers tables: offset pagination + search, behind an AdminGuard
  • 02Scheduled publishing: @nestjs/schedule cron + atomic claim (multi-instance safe)
  • 03Bulk campaigns: background send via Resend, fire-and-forget, bootstrap reconciliation
  • 04Stateless unsubscribe: HMAC token id.HMAC("unsub:"+id) — no per-send DB write
  • 05Blog ratings (1–5, one per user) + per-user activity (comments, reads, ratings)

The right store for each job

PostgreSQL holds the transactional core; MongoDB holds append-heavy and document data; Redis holds nonces and rate-limit counters. One writer per concern — no entity is dual-written.

  • 01Postgres (Prisma): users · refresh tokens (family + rotation) · posts · subscribers · ratings
  • 02MongoDB (Mongoose): analytics_events · contact_messages
  • 03Redis (ioredis): handshake nonces + per-endpoint rate-limit windows
  • 04Free-tier discipline: pooled connections, lean documents, indexes on hot paths

Realtime comments and honest read counts

Comments stream over Socket.IO so threads update without a refresh. Read counts respect ISR: instead of incrementing on a cached server render, a client beacon counts one read per session.

  • 01Socket.IO gateway broadcasts new comments to everyone viewing a post
  • 02Comment list is keyset-paginated; the realtime feed merges without duplicates
  • 03ISR (revalidate 300s) makes server-side counting wrong → client read-beacon instead
  • 04sessionStorage dedupe = one read per visitor per post; the POST /view route is throttled

Built and shipped like production

Clean/hexagonal NestJS, structured logging, health probes, and a full container + CI/CD pipeline — documented in ADRs, not improvised.

  • 01Architecture: NestJS clean/hexagonal · SOLID · DI · shared types in packages/
  • 02Observability: nestjs-pino structured logs · @nestjs/terminus health (Postgres + Mongo)
  • 03Delivery: multi-stage Docker per app · GitHub Actions CI gates
  • 04Quality: Lighthouse ≥ 95 · typed end to end · EN/VI metadata, hreflang, JSON-LD
Outcomes

≥95

Lighthouse target

3

data stores, one writer each

0

plaintext credentials on the wire
Next project

CHM Converter

Tell me about your project and I'll advise on the fit, scope, and approach — architecture, APIs, data pipelines, cloud, and CI/CD — and the right level of automation for your goals, technical constraints, and timeline.

Let's build something reliable, end to end

ContactContact
BLCK. 01
  • Projects
  • About
  • Capabilities
  • Blog
  • Contact
BLCK. 02
  • Privacy Policy
  • Terms
  • Cookie Policy
  • FAQ
BLCK. 03
  • LinkedIn
  • GitHub
  • X
  • |
DTDucas™
© 2026 DTDucas. All rights reserved.contact@dtducas.com