Belal.

Software Engineer

Open to software engineering roles and client website projects. Newark, NJ.

The same work, three other ways

Client projectLive, in pre-launch

emBabySteps

Designed and built a Next.js and Postgres publishing platform for a licensed pediatric physical therapist: a custom block editor with pre-publish checks, reader accounts, comments and saved posts, authenticator sign-in for staff, branded email and scheduled publishing.

Who it helps
Parents and caregivers of children from newborn to age five, and the physical therapist who writes for them several times a week.
What I owned
Everything: product decisions with the author, the design system, the Next.js app, the Postgres schema and migrations, authentication and security, email, tests, and deployment on Vercel and Railway.
When
October 2026
Checked
Live site and private repository checked October 21, 2026. The site is deployed and working, and kept out of search engines until launch.

Public pages captured from embabysteps.com on October 21, 2026, with the author's name replaced by her role. The editor and admin views come from a local copy with sample content and test accounts.

Tech stack

Front end
  • Next.js 16 (App Router)
  • React 19
  • TypeScript
  • Tailwind CSS 4
  • Tiptap editor
Back end
  • Next.js server actions and route handlers
  • Better Auth
  • Zod validation
  • OpenRouter (AI assistant, translation)
Data
  • PostgreSQL on Railway
  • Drizzle ORM, 21 tables, versioned migrations
  • PGlite for local development
Infrastructure
  • Vercel (functions, Blob storage, cron)
  • Resend (sending and inbound mail)
  • GitHub Actions CI
Testing
  • Vitest unit tests
  • Playwright browser tests
  • axe accessibility checks
  • Lighthouse

What's inside

  • Writing tools

    • Block editor with six PT blocks
    • Six post templates
    • Autosave and revision history
    • Content calendar and scheduling
    • AI writing assistant she approves edit by edit
    • Pre-publish checks
  • Accounts and security

    • Email, Google and magic-link sign-in
    • Authenticator app required for staff
    • Database sessions, revoked on the next request
    • Breached-password check
    • Nonce-based Content Security Policy
    • Rate limits on sign-up and sign-in
  • For readers

    • Browse by age, newborn to five
    • Translation into any language, cached
    • Comments with Helpful votes
    • Saved posts and reply emails
    • Printable home exercise sheets
    • RSS, installable web app, light and dark themes
  • Privacy

    • Separate consent to collect and to publish
    • Retention purges run by cron
    • No IP address or user agent stored with sessions
    • Google tokens discarded after sign-in
    • Account export and deletion
  • Operations

    • Admin review queues for comments and questions
    • Writer applications with license details
    • Email gallery with send-to-yourself
    • Inbound support mail through a signed webhook
    • Launch checklist read live from the app
  • Quality

    • CI: lint, type check and unit tests
    • Playwright browser tests
    • axe: no accessibility issues
    • Lighthouse 93 to 95 performance, 100 accessibility
    • Repo rules enforced on every commit

The problem

A licensed pediatric physical therapist wanted to publish practical guidance for parents of babies and young children, writing several times a week from a laptop. A generic blog couldn't hold exercises, milestone checklists and safety warnings in a form parents can follow at home, and a site that takes comments and questions about children's health has to be careful with readers' data.

My scope

I built the whole product: a design system from her sketches and the art she picked, the reader site, the writing tools, the admin console, authentication, email and deployment. Embaby Digital LLC operates the site.

Constraints

  • Staff publish health content, so writers and admins must use an authenticator app, and sensitive changes need a code from the last five minutes.
  • Readers are adults only. Comments and Ask a PT questions can mention a child's health, so collecting, publishing and deleting them each needed their own consent and retention rules.
  • She writes in her own words. The editor has to hold structured content (exercises, checklists, timers) without asking her to touch markup.
  • One Postgres database and Vercel functions, with no extra services until they earn their place.

Approach

  • Next.js 16 on Vercel with Postgres on Railway through Drizzle ORM: 21 tables, and migrations that run before every build. Local development runs on an embedded Postgres (PGlite), so nobody needs Docker.
  • A Tiptap editor with an Insert menu and custom blocks (exercise card, step by step, milestone checklist, hold timer, parent questions, myth vs fact), six post templates, autosave, revision history, a content calendar and one-tap scheduling.
  • Pre-publish checks on every post: a title, a description for every image, recorded consent for any real patient story, a reading level, and no em dashes, which the editor blocks as she types and the server refuses on save.
  • Better Auth with email and password, Google and emailed login links. Staff enroll a TOTP authenticator. Sessions live in the database with no cookie cache, so a ban or sign-out applies on the next request, and new passwords need 15 characters and pass a Have I Been Pwned check that sends only a five-character hash prefix.
  • Every page is rendered with a fresh nonce for a strict Content Security Policy, alongside HSTS preload, frame denial and a locked-down permissions policy.
  • Branded email through Resend for sign-up, login links, replies and answered questions, each previewable in an admin gallery. A Vercel cron publishes scheduled posts every five minutes and purges expired sessions, rate-limit counters and old records on a written retention schedule.
  • View counts that count each person once, skip bots, link prefetches and the author's own visits, and cap each network so clearing cookies can't inflate them.

Key decision

Render each page with a nonce instead of serving static HTML

Static pages would have been faster to serve, but a strict Content Security Policy needs a fresh nonce on every response, and this version of Next.js documents that nonces and partial prerendering don't work together. I kept pages dynamic, cached the public database queries in Next's data cache instead, and wrote the trade-off into the security notes so nobody switches static rendering back on without redesigning the policy. Production Lighthouse runs still scored 93 to 95 for performance.

Validation

  • CI runs lint, a TypeScript check and the unit tests on every push. A second workflow rejects em dashes and AI attribution in files, commits and pull requests.
  • 21 Playwright browser scripts cover staff sign-in with an authenticator, writing and publishing, comments, translation, the admin tools, accessibility and layout shift.
  • The October 20 security pass recorded 70 unit assertions, six isolated Postgres privacy checks and 49 HTTP authentication and security checks.
  • A production sweep on October 20 returned 200 on every page, no axe issues, and Lighthouse scores of 93 to 95 for performance and 100 for accessibility and best practices, with no layout shift.

Result

embabysteps.com is live on Vercel with Postgres on Railway. It stays out of search engines until launch, which waits on the author's first posts and a lawyer's review of the legal pages.

Limitations

  • Pre-launch: the only public post is a placeholder, and search engines are told not to index the site yet.
  • The weekly digest is built but stays off until the business has a postal address for the email footer.
  • The security work is engineering verification, not an independent audit or a legal compliance certification.
  • The repository is private, so the code isn't linked here.

Links