Tiny full‑stack URL shortener used for the technical test.
- Client: React + Vite + Tailwind (
client/) - API: Express (
api/) - DB: PGlite (in‑memory, PostgreSQL compatible)
sdk/types.ts– shared TypeScript types (client + API)
api/index.ts– API entrypointapp.ts– Express app factoryroutes.ts– route wiringconfig/database.ts– PGlite client + initdatabase/migration.sql– schema forurlsdatabase/seeds.sql– initial datasrc/controllers/url.controller.ts– HTTP handlerssrc/services/url.service.ts– core logicsrc/repositories/url.repository.ts– DB access
client/routes/- App pagescomponents/– UI componentshooks/– app hooks/providersutils.ts– helpers (e.g.,getShortUrl)
- Import shared contracts from
sdk/typesin both API and client, e.g.:
import type { UrlRow, ShortenRequest, ShortenResponse } from "sdk/types";GET /api/health– health check. AcceptsfrontendOriginquery to compute base URL.POST /api/shorten– create a short URL. Body:{ url: string, frontendOrigin?: string }GET /api/urls– list recent URLs. Query:?limit=10GET /:shortCode– redirects to the original URL and increments click counter.
- Run the local environment (both API and client) by running
npm run dev
- You can use the Debug menu in the lower right corner of the homepage to dump the database content or copy the API url.
- Code is split by responsibility (controllers/services/repositories) to clarify where to add logic.
- Keep types in
sdk/to avoid drift between client and server. - Database schema and seed are plain SQL for readability.