Skip to content

Case study

A guide for everyday life in Switzerland

Zusammen brings information on rights, work, documents, health and education into one app — multilingual and offline-ready.

Challenge

Anyone arriving in Switzerland faces a distributed system: 26 cantons, three official languages, and different authorities for residence, work, health and education. Information sits across dozens of portals — cantonal, communal, sector-specific — and is rarely available in the same language and level of detail.

Language is the first barrier. Many official guides exist only in German, French or Italian. People who speak Farsi, Arabic, Ukrainian or Kyrgyz have to rely on translation or on community knowledge — and often miss the formal deadlines and nuances that matter.

The second barrier is permit status. Rights and obligations differ fundamentally between B, C, F, N, L, S and EU/EFTA holders — but standard portals abstract that away. People end up reading advice that does not apply to them and make decisions on the wrong basis.

The third barrier is digital fragmentation. Job search, document checklists, appointments, community questions and service maps would each need their own app. Zusammen starts from a different premise: one app instead of ten portals.

Approach

Five principles shaped the architecture and feature set:

  • Multilingual from day one — 11 languages ship in the code (ar, de, en, fa, fr, it, ky, pt, ru, tr, uk). Every content entity is translatable by design, not localised as an afterthought.
  • Offline-capable — guide articles and checklists work without a network connection. Important for people on tight data plans or in accommodation with unreliable Wi-Fi.
  • Permit-aware — content, jobs and recommendations take permit status into account instead of serving one-size-fits-all answers.
  • One ecosystem rather than many apps — guide, job search, service map, documents, community forum and AI assistant live behind a single sign-in.
  • Editorially maintainable — a dedicated back office lets subject-matter editors publish without a developer deploy.

What we built

Guide

Structured articles covering rights, work, housing, health, education and everyday life. The data model separates Article from ArticleTranslation: editors write once per language and the app reads in the user’s preferred language. Categorisation is handled by ContentCategory, which is translated in the same way.

A jobs module built around Job, JobApplication and JobTemplate. Employers manage postings via their own accounts (Employer), candidates store CVs through the cv/ module and apply directly from the app. Templates help editors and employer partners with recurring roles.

Service map

ServicePoint catalogues migration offices, counselling centres, primary healthcare, language schools and other services with geo data. The geo/ module handles location and radius queries; ServicePointTranslation provides localised names and descriptions.

Document checklists and reminders

DocumentChecklist describes the paperwork required for a given situation. The Reminder model ties deadlines — permit renewals, registrations, course starts — to push notifications so people are nudged in time.

Community forum

A full forum with ForumCategory, ForumTopic, ForumPost and ForumLike, plus moderation via ForumReport. Users share concrete experiences without leaving the app.

AI assistant

AiConversation and AiMessage store conversations server-side so the assistant retains context. It answers guide-style questions in the user’s language and points back to editorially maintained articles rather than arbitrary web sources.

Push notifications

DeviceToken manages FCM and APNs tokens; Notification records what has been sent. Deadline reminders, forum replies and job matches are all delivered reliably through the same pipeline.

Editorial back office

A separate React + Vite application (admin/) lets the editorial team maintain categories, articles, jobs, services and checklists across all languages, with preview, review workflow and roles.

Architecture

Zusammen is a three-tier system: Flutter clients (iOS, Android, web PWA) talk to a NestJS REST API backed by PostgreSQL. The mobile codebase is a monorepo; the web PWA reuses the same Flutter code as the native clients and is served through nginx.

The data schema is deliberately translation-first: 35 Prisma models are grouped into 10 domains (Auth, Content, Jobs, Services, Documents, Forum, AI, Notifications, Analytics, Audit). Every content entity has a paired *Translation table, which cleanly separates the editorial workflow (approve per language) from the delivery logic (read per user in the requested language).

The backend is sliced into 25+ NestJS modules by domain: auth, content, jobs, employers, services (via geo), forum, ai, bookmarks, messages, notifications, reminders, search, subscriptions, sync, admin, analytics, audit, mailer, media, integrations, i18n, cv, users, common. Each module owns its data model, DTOs, controller and service, which keeps the code legible as the domain grows.

Deployment runs on Docker Compose on a single VPS: backend, admin front end, web PWA and the landing site each run as their own containers behind nginx. A built-in analytics and audit pipeline (AnalyticsEvent, AnalyticsDailyStat, AuditLog) records usage and editorial actions without relying on third-party trackers.

Numbers & facts

MetricValue
Languages shipped11 (ar · de · en · fa · fr · it · ky · pt · ru · tr · uk)
Backend modules (NestJS)25+ (Auth, Content, Jobs, Services, Forum, AI, Analytics …)
Prisma data models35 across 10 domains
Client platformsiOS · Android · web PWA
Translatable content types5 (guide, jobs, services, checklists, forum)
AI assistantintegrated, conversation history stored server-side

What we learned

A permission-driven content model — tailoring content to permit status — takes real time up front, but repays that effort every week in support load and in how useful the guide actually is. Without that separation the AI assistant would inevitably have been vague or wrong.

Editorial UX matters more than any front-end animation. If the person maintaining articles in eleven languages cannot move quickly in the admin, content stalls and the rest of the app loses value. Investing early in the back office was the single most productive decision in the project.

Offline-first forces a clean data contract. Once the client caches content locally, the backend has to handle versioning, fallback languages and sync conflicts explicitly. That discipline sharpened the API boundaries and reduced side effects across the whole system.

Next steps

  • More languages, prioritised by real community demand and the first languages of current arrival groups.
  • Deeper integration with cantonal data sources (service directories, official information sheets) so guide content stays current automatically.
  • Finer permit matching: assembling recommendations and checklists dynamically from permit type, canton and family situation.

Collaboration

Have similar work in mind?

Let’s have a short chat — no sales pitch.