← Cloud Compute
Open source · Remote management

Remote Apartment Automation

Fully automated short-term rental for a private apartment managed remotely: reservations, smart-lock access, identity verification, invoicing, statutory guest reporting and guest messaging run end-to-end without on-site presence — an event-driven serverless stack on AWS: 8 Lambda functions, 3 DynamoDB tables and EventBridge schedules, running for well under $1/month.

Python 3.12 AWS SAM / Lambda DynamoDB EventBridge Scheduler Secrets Manager Smoobu API Nuki API SOAP + mTLS (eTurizem)
⚡
Built with agentic AI. Development on this project runs through multi-agent Claude Code workflows — developer → independent-reviewer cycles with evidence gates, batched into unattended runs that execute overnight and resume from committed ledgers. How the agent system works →

How a stay runs itself

A booking arrives as a Smoobu (channel manager) webhook and upserts reservation state into DynamoDB. From there everything is autonomous: two days before arrival the stack creates and fiscalises the invoice (Cebelca), creates a time-bound Nuki smart-lock PIN and publishes it into the guest's welcome message; on arrival day it arms the building intercom and polls for the guest's first keypad entry; guest ID scans are filed to the Slovenian eTurizem registry over mTLS SOAP, and the monthly statutory return files itself. Every schedule runs in a real timezone (Europe/Berlin), so DST is AWS's problem.

Reservations & smart lock

  • Webhooks upsert reservation state; an hourly sync reconciles drift and cancellations.
  • 6-digit Nuki PINs created for the arrival window, deleted after departure, and written into Smoobu placeholders so guests see them in confirmations.
  • Nuki lock logs detect the first keypad entry and trigger check-in and cleaning flows — including a WhatsApp/email alert to the cleaning boss if no cleaner has entered by a set time before check-in.

Identity, billing & compliance

  • Identity-scan polling with guest de-duplication in DynamoDB and Smoobu sync.
  • Statutory reporting: check-in data is built into the required knjigaGostov XML and submitted to eTurizem via the official client-cert SOAP API.
  • Invoicing via the Cebelca API; PDFs archived to S3; all tokens and the mTLS certificate live in Secrets Manager; structured logging in CloudWatch.

Engineering highlights

The interesting parts came from real incidents — each fix is now a permanent property of the system.

Trust-nothing device control

Nuki's API returns "accepted", not "applied" — and one dropped command locked a guest out for hours. The check-in monitor now reads state back from the device and re-asserts it every 5 minutes until the guest is detected. A second, independent check-in signal (the keypad code's usage counter) covers the cloud log silently dropping entries the lock itself recorded.

Atomic claims, not read-then-write

Every "send this once" decision — reminders, forecasts, the monthly statutory report, guest de-dup — is a DynamoDB conditional write, so a concurrent webhook and a scheduled run can never double-send or double-file. The statutory sequence number is an atomic counter.

Alert latches & reconciliation

Alerts are one-shot latches re-armed on recovery, with an all-clear sent on self-heal — a flapping device can't email every 5 minutes. And after a cancellation webhook silently stopped matching for weeks, the hourly sync now reconciles cancellations too — hardened so a failed fetch can never masquerade as "everything was cancelled".

Structural secret containment

The repo's early history contains an mTLS private key, so publication is guarded twice: a pre-push hook rejects any ref whose history ever touched key files, and a mirror-publisher script credential-sweeps the tree and pushes a single parentless squashed commit. The leak is impossible, not remembered.

Source code

The whole stack is public: one SAM template, eight Lambda handlers and one module per vendor integration. GitHub shows a single squashed snapshot rather than the commit history, because the early history carried an mTLS key. That is the publication guard described above doing its job.

Fougl/apartment

Serverless short-term rental automation on AWS SAM: Lambda, DynamoDB, S3, EventBridge and Secrets Manager. A booking webhook drives invoicing, smart-lock PINs, guest registration, cleaning checks, laundry forecasts and the monthly statutory report.

Start with aws-serverless/template.yaml (the whole infrastructure), src/handlers/checkin_monitor.py (arrival detection and lock control) and src/common/store.py (the DynamoDB state layer).

Open on GitHub ↗

How to read it

Handlers stay about the workflow; each vendor’s API quirks live in one module under src/common/ (Smoobu, Nuki, Cebelca, eTurizem, CheckinScan). Every schedule is declared in a real timezone in the template, and every “send this once” decision is a conditional write, so the code reads the way the incidents above are described.