惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
有赞技术团队
有赞技术团队
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
美团技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
人人都是产品经理
人人都是产品经理
酷 壳 – CoolShell
酷 壳 – CoolShell
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Check Point Blog
博客园 - 【当耐特】
The GitHub Blog
The GitHub Blog
Recent Announcements
Recent Announcements
The Cloudflare Blog
Microsoft Azure Blog
Microsoft Azure Blog
腾讯CDC
Vercel News
Vercel News
IT之家
IT之家
MyScale Blog
MyScale Blog
博客园_首页
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
罗磊的独立博客

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Why we built EU-native time tracking (and what Schrems II...
Cadensa · 2026-06-26 · via DEV Community

In 2020, the Court of Justice of the European Union invalidated the EU–US Privacy Shield. The ruling — known as Schrems II — declared that US surveillance law makes it impossible for US companies to guarantee the privacy of EU citizens' data, even if that data is stored "in Europe."

Most SaaS founders in the US probably shrugged. Most EU agency owners probably didn't notice at all. But the implications were significant: transferring personal data to a US-based processor became legally risky, even if those processors had EU data centers.

I built Cadensa because I kept running into this exact problem while advising small EU agencies on their software stack.


The problem hiding in plain sight

Let's say you run a 12-person digital agency in Amsterdam. You use a popular US time tracking tool — one that has a "Frankfurt data center" checkbox. You tick the box, feel good about it, and move on.

Here's what you might not know:

  • The vendor is a US company subject to FISA Section 702 and CLOUD Act requests
  • Even if your data sits on EU servers, US authorities can compel access
  • Your DPA is using standard contractual clauses that post-Schrems II case law increasingly views as insufficient
  • Your enterprise clients — especially in finance, healthcare, or public sector — are starting to ask for a data processing agreement that names the actual sub-processors

None of this is FUD. It's just the current legal reality.

And the truly ironic part: time tracking data is surprisingly sensitive. It contains project names, client names, employee working hours, task descriptions, and billing rates. It's exactly the kind of data that triggers GDPR Article 5(1)(f) — integrity and confidentiality.


What we built instead

Cadensa runs entirely on Hetzner Cloud, Frankfurt. Not "Frankfurt as a region on AWS." Hetzner is a German company, incorporated in Germany, subject to German law and the GDPR — not the CLOUD Act.

GDPR compliance isn't a toggle you flip on the Enterprise plan. It's on every plan, including Free:

  • Data stored in the EU (Germany)
  • Right to erasure: full account deletion with 7-day reversible grace period
  • Right to portability: JSON export of all your data, on demand
  • Data processing agreement available at signup, not behind a sales call

Multi-tenancy is database-level, not row-level. Each organizational unit gets its own isolated MongoDB database. A breach in one tenant can't cascade to another. This is more expensive to operate, but the security and compliance story is clean.


The technical part (for the devs reading this)

The stack: Express.js + TypeScript on the backend, React 18 + Vite on the frontend, MongoDB (multi-database architecture), Socket.io for real-time presence and live updates.

The thing that surprised me most architecturally: implementing GDPR rights as first-class API citizens is genuinely hard. "Delete my account" sounds simple. In practice, it means:

  1. Soft-delete with a 7-day grace period (user can reverse)
  2. Hard-delete: cascade across multiple databases (global user record + all tenant databases)
  3. Anonymize data that legally must be retained (financial records, audit logs) rather than delete it
  4. Export: traverse the entire data graph and serialize it to a portable format

We have a gdprRights.service.ts that handles this. It's one of the more complex parts of the codebase, and it's not optional — it's a legal requirement.

Email hashing was another non-obvious decision: user emails in the global database are stored as SHA-256 hashes. We never store plaintext emails globally. This limits some email-based lookups, but it means a global DB dump leaks no PII.


What I'd tell other EU founders

If you're building a SaaS for European SMBs or agencies, EU data residency is becoming a selling point, not just a checkbox. We've had prospects come to us specifically because their enterprise clients required it.

You don't need to be perfect on day one. But you do need:

  1. A clear answer to "where is my data?"
  2. A DPA you can actually show to a client's legal team
  3. No hand-waving about "we're GDPR compliant" without specifics

The 12-person agency in Amsterdam doesn't have a dedicated compliance officer. They need a tool that makes the right answer easy to give.

That's what we're building with Cadensa.


Cadensa is EU-native time tracking for agencies — free plan, no credit card required. If you're building something similar or have thoughts on GDPR + SaaS, I'd love to hear from you in the comments.

cadensa.io — building in public, one sprint at a time.