dignuz

Webtools

One private place to build, ship and translate a product.

A private web app for a team that ships a desktop product. It gives them one place to rebuild the product, download its installers, and translate its interface into two languages. Each person sees only what their role allows.

Private, in use

Private, behind a login. There is no public link.

01

How it's built

  • TypeScript
  • SvelteKit 2
  • Svelte
  • Supabase
  • Postgres
  • row-level security
  • Tailwind
  • shadcn-svelte
  • Bits UI
  • Lucide
  • Zod
  • sveltekit-superforms
  • GitHub REST API
  • Azure Blob Storage
  • Azure Translator
  • Resend
  • GitHub Actions
  • Vercel
  • ESLint
  • Prettier

SvelteKit 2 and TypeScript, deployed to Vercel.

  • Architecture: the server code is layered into domain, application and infrastructure. The application layer is organised by feature (builds, installers, translations, users), and each feature is split into commands and queries (CQRS) that pass data as DTOs. Handlers reach the outside world only through interfaces: repositories for the database, and service clients for GitHub, Azure and email.
  • Database and sign-in: Supabase. Postgres with email and password sign-in, and sessions kept in cookies through @supabase/ssr. Row-level security on every table, every schema change a Supabase CLI migration, and the TypeScript types generated from the schema.
  • Forms: sveltekit-superforms, with Zod schemas shared by the browser and the server.
  • The interface: Svelte and Tailwind, with shadcn-svelte on Bits UI, Lucide icons, a command palette, toast notifications and a dark mode.
  • Integrations: the GitHub REST API for builds and commits, the Azure Blob Storage SDK for the installers, Azure Translator for the first drafts of translations, and Resend for email.
  • Shipping: GitHub Actions starts a local Supabase, pushes the migrations to production, then deploys a prebuilt app to Vercel. Dependencies are pinned to exact versions, the lockfile is frozen in CI, and the code is checked with ESLint, Prettier and svelte-check.

02

What was hard

Access that holds on the server. There are three roles: admin, contributor and translator. The sidebar hides what a role cannot use, but that is only tidiness. Every route checks the role on the server, and the database has row-level security on every table behind it. Installers are handed out as download links that expire after two minutes.

Translations that go back where they came from. Translators edit one grid of every text in English and both languages, with a machine translation from Azure as an editable first draft. When they are done, only the rows that changed are merged into the product's resource file, and the result is committed to the product's GitHub repository on the branch they chose. No file is emailed around.

03

The trade-off

It is built on four outside services: GitHub, Azure, Supabase and Vercel. Each does one job it already does well, so the app itself stays small and does only what is specific to the team. When one of their APIs changes, the change stays in the one repository or service client that talks to it.

Want something like this, built around how your business works?