Eventee: my own event app for Mac and iPad

A native Mac app for the work before and after a B2B event, and an iPad app for the show floor. Enrichment, scoring and messaging in my voice run by themselves. Built with Claude Code.

Eventee is my own app for the B2B events where I sell. A Mac app covers the work before and after the event. An iPad app covers the show floor. The data lives on my Mac, not in someone else's cloud.

The name follows the -ee family of my other tools (Notee: my own Markdown editor for macOS, Dictee: my own local dictation app). Why I build my own apps at all: The era of personal software is here.

Eventee on the Mac in pre-event mode: the People list with tier pills, scores and filters, a legend bar at the bottom, and a selected lead with outreach texts behind English, German and French flag pills. Names and companies are blurred.

Why I built it

Until now, each event ran on a mix of tools: spreadsheets, a task dashboard I built for the last show and my inbox. It worked, but nothing connected. The person I met on the floor, the message I sent them before the show, what we talked about and the follow-up email lived in different places.

What I wanted: 1 record per person that follows them through the whole event, on the device that fits the moment.

3 phases, 2 devices

A 3-way toggle at the top of the Mac app switches between the phases. During lives on the iPad only. Before and after live on the Mac only, where I have a keyboard and a big screen.

Before the show (Mac)

  • People: the attendee data, with a tier and a score per person. My own accounts show in green, and a legend bar explains every mark.
  • Outreach: drafts in English, French and German. Flag pills switch the language, and 1 click copies the text.
  • Logistics: meetings, agenda, booths and side events in 1 place.
  • Filters on every field where it makes sense: tier, owner, persona, company, contacted, speakers.
  • Media: the demo videos and HTML slide decks the iPad will need on the floor.

During the show (iPad)

  • Scan a badge or a QR code, and see who the person is and what I already sent them.
  • Rate the conversation (hot, warm, cold, no fit) and star the person.
  • Record a voice note right after the conversation: who, what they need, what I promised. The iPad transcribes it on the device with Apple's speech model, and files it under the person. No audio leaves the iPad until it syncs with my Mac.
  • Demos offline: my demo videos and my master deck play from the iPad, so the venue wifi doesn't matter.
  • Sync back to the Mac when a connection is there.

After the show (Mac)

  • Voice notes transcribed a second time on the Mac with whisper, for a cleaner text.
  • Every follow-up is generated automatically, on LinkedIn and by email, from the lead's context and my voice note. Each email comes with a personalised PDF one-pager for that person and their use case.
  • The send list in 3 coloured groups: internal follow-ups first, then hot and warm leads, then cold and no fit.
  • I review, copy and paste. Eventee doesn't send the emails itself. The address, the subject line and the text each have a copy button, and I paste them into my email client. Then I tick the follow-up as sent, so I always know who got what. With SMTP access to my corporate mailbox, Eventee could send them directly.
  • The overview shows where the event stands: "Over · follow up now", with the number of follow-ups still to send.

Eventee on the Mac in post-event mode: the World Summit AI 2026 header with its logo, dates, the Dutch flag and an amber status saying the event is over and it is time to follow up, then the post-event task list. Numbers and task details are blurred.

What runs without me

The screens are the visible part. The work behind them runs by itself.

Enrichment: a name and a company are enough

I add a person with a name and a company. Eventee finds the rest through a waterfall: my own databases first, then Apollo, then FullEnrich for the gaps, which checks many data providers in turn. Each step runs only for what the previous one didn't find. A detail that was found is never overwritten.

The rules are configurable. Apollo runs without asking. FullEnrich costs credits, so it shows the cost and waits for my OK.

Scoring and priorities on my ICP

Every attendee gets a score and a tier from 1 to 4, measured against my ideal customer profile. An LLM answers 5 typed questions per person: the buyer role their title describes, the kind of organisation, their buying power, how close their job is to the problems I solve, and whether their company is a competitor. My own signals go on top: priority accounts, existing clients, accounts in my book, people I'm already connected with. The tier decides the effort: a personal message for tier 1, a meeting request for tier 2, a hello on the floor for tier 3.

Account context

For each company, Eventee shows which of my colleagues owns the account, and whether the company is already a client. I know before I write if the conversation belongs to someone else, and when a follow-up should go to a colleague first.

Messaging in my voice

Every message, before, during and after the event, is generated with context about the lead: their role, their company, what they said, what we discussed. My own model writes it in my voice: NicAI, a local LLM fine-tuned from Qwen 3.8 (27B) on my own writing. The story of that model is in Fine-tuning my own model (LLM): NicAI. It runs on my Mac, so lead data never goes to an outside model to be written up.

Messages that stay current

The unsent messages on LinkedIn, in the event's own app and by email are regenerated every day, so they never sound stale:

  • Before the event: they mention the event to come.
  • On day 2: they mention something from day 1.
  • After the event: "yesterday" becomes "last week" when it should.

Small things I care about:

  • A copy icon on every field. Name, company, email address, subject line: 1 click each.
  • Each event has its own look. Its logo, its colour in the top bar, the country flag in the header.
  • Text size for the whole app with ⌘+ and ⌘-, and a light and dark mode.

For business people

Eventee is software for 1 user. It does what I need at an event and nothing else.

The value is the single record per person, and the work I no longer do by hand. Before the show, the list is enriched, scored and written in my voice. On the floor, I scan a badge and see it all. After the show, every conversation turns into a follow-up with its own one-pager, and I can see at a glance what's still open.

The other value: it changes when I want it to. When something bothers me, I tell Claude Code, and the change is built, tested and installed in minutes. The copy icons and the coloured follow-up groups both came from 1 morning of real use.

The trade-offs:

  • I maintain it, and there's no support team behind it.
  • It runs on Apple devices only. An iPhone version is planned, not built.
  • The iPad side hasn't seen a real show yet. Its first test is my next event.

For technical people

Architecture

Part Choice Why
Hub Python standard-library daemon on the Mac, LaunchAgent, SQLite No dependencies, 1 database file
Apps SwiftUI on macOS 26 and iPadOS 26 Native, with camera and microphone on the iPad
Shared code Swift package EventeeCore: SQLite, ops, queries, sync, theme The same logic on both apps, and the iPhone later
Sync Append-only op log, hybrid logical clock, last writer per field Works offline, merges without a conflict dialog
Network Tailscale The iPad reaches the Mac from any venue, no open port
Files Stored by SHA-256 A file is copied once and never changes
Speech SpeechAnalyzer on the iPad, whisper.cpp on the Mac On-device first, a stronger pass later on the Mac
Badges VisionKit DataScannerViewController Text and QR codes from the live camera
Decks HTML bundles with absolute paths rewritten, in WKWebView A deck with 383 files plays offline

Local-first sync

Each device keeps its own SQLite database and a log of every change it makes: the record, the field, the value and a clock. The clock is a hybrid logical clock, the wall time plus a counter plus the device name, so 2 changes never tie.

Applying a change is 1 SQL upsert that wins only when its clock is newer. Python on the hub and Swift on the devices run the same statement. Applying the same change twice does nothing, so a retried sync is always safe.

Data safety

  • No row is ever deleted. People are dismissed, media archived.
  • A sent text never changes. A SQLite trigger refuses any update to a locked message or follow-up.
  • Backups go to Dropbox: the database every 10 minutes while changes arrive, before every install of a new version, and on demand. Voice notes and photos are copied once. Old backups thin out to 1 per day after 48 hours. A restore command backs up the current database first.
  • Tests never touch live data. Every test runs in a scratch folder with a test hub on another port, and email tests use a dry run.
  • Eventee sends no email to leads. Follow-ups leave from my own email client, after I copy and paste them.
  • The iPad holds no API keys. It talks only to the hub on my Mac.

Gotchas I hit

  • Swift tools version. A package that targets macOS 26 needs swift-tools-version: 6.2; 6.0 rejects .v26.
  • Event colours. A logo colour is often too light for white text. Eventee darkens it until the contrast reaches 5.5:1.
  • A blue focus ring sat around the phase toggle in the top bar. .focusEffectDisabled() removed it.
  • Audio recording in the iPad simulator hung the app when it started on the main thread. It now starts on a background thread with a timeout.
  • launchctl bootout returns before the old process is gone, so an immediate bootstrap fails with error 5. The install now waits for the old hub to stop.
  • Snapshots for the iPad failed on foreign keys while copying tables in order. The copy now turns them off while it runs.

The code: about 10,700 lines of Swift, 2,400 lines of Python, Python and Swift tests, and an end-to-end QA script that runs both apps against a test hub.

The Eventee app icon: a white event badge with a red edelweiss on a lanyard, on a red background, with the name Eventee under it

How I got there: 10 prompts

I built Eventee in 1 session with Claude Code, from 10th to 12th October 2026. I wrote 10 prompts about the app.

Eventee worked end to end after the 1st build prompt: the hub, the sync, the Mac app with its before and after modes, the iPad app and the media library, tested against my last event's data. The 6 prompts after it only made a working app better.

Phase Prompts What happened
Brief and spec 3 Claude read the handover from my last event and asked 45 questions. I answered them
Build 1 "Go ahead and build now this event app", with the 3 phases and the media on the iPad
Improvements 6 Event look, filters, status, copy buttons, text size, icon, follow-up groups, backups

What worked well:

  • Spec before code. The first prompt said "don't build anything". The 45 questions surfaced decisions I hadn't made: how the devices sync, who sends the email, whether anything can be deleted (no).
  • Real data, frozen. Claude made a read-only copy of my last event's data as the test set. The app was tested on real volumes from the first build, and the live files were never touched.
  • Hard rules in the project file. No deletion, no email sent by a test, no test against live data. Every later change respected them without a reminder.

Further reading

NicAI
Written by NicAI, Nic's AI assistant, for his personal knowledge base. Researched and drafted by the model, not hand-written by Nic. Verify anything you plan to act on.