Projects Einmal noch schlafen

Einmal noch schlafen

Being rebuilt

Digital Advent calendars to give away, a photo and a few lines behind each door. Customer portal and back office, rebuilt in 2026.

A freshly opened calendar: twenty-four pale doors scattered over dark red velvet, all still closed.
Period
2024 – present
Role
Solo, concept to operations
Status
Being rebuilt, relaunch to follow
Code
Private repository
Runs under

I built my first digital Advent calendar by hand in 2024, just for me. In 2025 I wanted to turn it into something for other people, three families in the end. But every order landed on my desk, and I set up each calendar by hand.

Einmal noch schlafen is the 2026 rebuild: two running applications. One carries the marketing site, the customer portal, the back office and the API. The other serves every customer calendar, and the address says which one. Between a paid order and a link that can be sent on there is no longer a person. If one of the automatic checks fails, the operator hears about it before the customer does.

Above all, a lot got thrown out in the rebuild: no container management from inside the application, no certificate per customer, no payment service of my own, no database server. What is left is two containers, one database file and a directory of images. And there are three ways in, depending on who is arriving: whoever is given a calendar has nothing to set up at all. Whoever buys one, as little as possible. And whoever runs the shop signs in properly.

Stack
TypeScriptExpressAstroReactViteDrizzleSQLiteStripeAnsible

Decisions

ADR 0001

A new calendar is one row in the database

Every customer used to get a running instance of their own, with a proxy entry and a certificate. The back office needed nearly the rights of the server administrator for that. And every order was a chain of steps that could break in several places. Nobody needs the isolation all of that bought: all calendars run the same code, and the order data sits together anyway. Creating a calendar now means writing one row to the database.

ADR 0003

A hosted checkout instead of a payment service of my own

Payment used to run through a service I had built myself: around 3,000 lines for exactly one provider, with the API secret in the log and empty error handling. The hosted checkout charges a lower fee, brings Apple Pay and Google Pay with it and produces the invoice with the tax breakdown at the same time. For an impulse buy of just under five euros on a phone, those two wallets are what decides it. The price is a dependency on someone else’s service.

ADR 0006

No user account for the recipient

The plan had been an account per calendar in a sign-in service of my own. But the complaint from real use (“you have to log in again all the time”) was not about identity, it was the cookie lifetime. Accounts would not have fixed it, and they would have sent grandparents who only want to look at a photo through a sign-in flow. So I fixed the lifetime and left the accounts out.

ADR 0009

Design first, pay afterwards

The other way round would have been simpler: no unpaid drafts taking up space and inviting abuse. But anyone who has picked 24 photos and written a message for each has put in half an hour, and that work is the product’s strongest selling point. Behind a paywall it would be wasted. Drafts are therefore created on the server before any payment, and expire after 30 days.

This site in a different design

Same content, different look. You start on its home page, and every link stays in the chosen design.

What is this? About this site →