Cosmetra bundles appointment management, customers, staff, booking, and finances for beauty and service studios in a single platform. The core promise: studios see their appointments right where they already work — in Apple Calendar, in Thunderbird, in DAVx⁵ — without a separate sync tool.
To make that possible, Cosmetra runs its own CalDAV server instead of a ready-made library like sabre/dav: lean, scoped to the feature set it actually needs, and integrated directly into its own workspace/token model.
Gallery
Case Study
Situation
Beauty and service studios often manage appointments across several disconnected systems. Cosmetra set out as a two-person venture (Felix Schattenberg as technical lead, a co-founder for product and go-to-market) to solve that with real calendar synchronization, instead of pushing studios onto yet another island tool.
Challenge
The CalDAV server is no trivial appendage at roughly 450 lines of custom controller code: Basic Auth over custom tokens, PROPFIND/REPORT/GET/PUT/DELETE handling, and manual iCal parsing and serialization (line unfolding, property/parameter parsing, TZID handling, escaping). The PUT method was originally a stub that ignored every incoming iCal payload — external calendar clients couldn’t create or change appointments through it. The fix needed a real VEVENT parser that extracts DTSTART/DTEND/SUMMARY/DESCRIPTION/STATUS and maps them onto appointments via updateOrCreate — and made customer_id nullable on the appointments table, because CalDAV clients can create appointments without a known customer.
Approach
Laravel 13 with PHP 8.5, Vue 3.5 and TypeScript via Inertia.js, shadcn/ui (reka-ui) on Tailwind CSS 4, Pest for tests. Multi-tenancy as shared-schema: every core entity carries a workspace_id instead of running a separate database per customer. Shipped via GitHub Actions and Deployer with an atomic symlink swap, queue workers under systemd.
Decisions
A lean feature set scoped to workspaces and staff, rather than a full DAV/ACL library, integrated directly into the existing token model.
A CaldavToken model with workspace or staff scope, individually restrictable per staff member.
Deliberately kept auth and deployment complexity low for a two-founder MVP, rather than running backend and frontend as separate deployments.
Avoids later table rewrites; every core entity carries a workspace_id instead of schema-per-tenant.
Rules out rounding errors on amounts; time is kept consistently in UTC internally and only converted to the workspace time zone for display.
My contribution
Full technical implementation: data model, CalDAV server, Vue/TypeScript frontend, booking and finance logic, deployment. A second co-founder is registered as super admin and responsible for the product side — this was primarily, though not exclusively, solo work.
Results