Build Log #
I spent the morning polishing and shipping a tiny demo app that shows off Mosaic’s public API, now live here. The goal was to give users a frictionless playground, so I scaffolded a FastAPI backend, wired in the SDK, and dropped a minimal React front layer that fetches clips on button press. Three days after our last docs push, half the endpoints had evolved, so I rewrote the quickstart, the auth section, and every curl snippet to match the new payload shapes. While combing through those examples I discovered a stray string-encoded JSON object that would have broken anyone using --data '{}'
, which was a near miss. The deployments for the API are from the public-facing backend, which we're soon migrating to Railway because holy shit everything we've hosted there just works without complaint, which still feels like sorcery given how often I used to fight Docker builds. Railway.toml is incredibly goated.
me when json :(
Right after that push, I went into architecture mode for a new service I've been internally calling ChronoRail. The service will own every time-pegged workflow Mosaic users might want: scheduled social posts, weekly summary emails, automatic archiving, and anything else that needs a clock. I drew the first system diagram in Excalidraw and then rewrote it twice because arrows began resembling spaghetti faster than I could label them ;-; . The high-level idea is simple: FastAPI entry, Prefect orchestration, HTTPX calls to third-party services, and Loki for task logs. The trick is making sure no job gets dropped during deploys, which led me down a zero-downtime rolling restart rabbit hole most of the afternoon.
The stack choices feel solid so far. Prefect’s worker model pairs nicely with Railway’s hot-swap containers because a SIGTERM tells the old worker to stop accepting new tasks while finishing its queue. UV handles Python environments, so dependency issues stay local to the virtualenv and never reach production. Ayrshare will give us social media access (twitter, instagram, linkedin, etc.), Resend will fire user notifications, and Structlog keeps logs human readable. I am writing this all down because I know Future Shresht will thank Present Shresht when debugging the strangest two-week-long cron job bugs to ever plague human civilization.
doesn't structlog look so nice?
By the time I got home around 11:45 pm, my brain was fried, so I opened the Amazon boxes that arrived. I got a push-up board, an exercise mat, and some new skincare bits which I've wanted for years but never bought because it wasn't my own money until now.
Media Diet #
Media intake was short but sweet today. The highlight was ITZY’s brand-new music video Girls Will Be Girls which I watched three times back to back.
I listened to a lot of RIIZE and Young Posse today while coding. Also watched an episode of Dr. Stone!
Small Wins & Face-plants #
-
Wins:
- Mosaic API demo shipped and visible to the world.
- Docs updated before >1 angry tickets appeared.
- First draft of ChronoRail architecture sketched and critiqued.
- Pressframe and yoga mat delivered intact.
-
Fails:
- None cause I'm so freaking awesome hahahahahahahahahahahaha
railway.com my goat
- Surprises:
- Railway waow!!! I love public transport!!!!
Stack Draft of the Day #
ChronoRail’s stack decisions are locked for the first iteration. FastAPI plus Pydantic will remain the entry layer because the team is fluent and type hints prevent half my typos. UV manages the environment, giving every dev an identical Python world in like five seconds flat. Prefect sits at the core, orchestrating tasks and retrying failures while exposing a dashboard we can embed in our internal admin panel. Each worker will run as a lightweight container on Railway, and we will lean on the platform’s rolling deploys to keep tasks alive during image swaps.
Ayrshare handles the messy OAuth stuff for social networks, saving me from dealing with the Meta and X developer dashboard nightmare. Loki aggregates logs with labels for flow ID, which means one Grafana query shows the life story of any job. Structlog formats everything into rich dictionaries before shipping to Loki, making tracebacks readable. Resend fires email notifications once flows succeed or fail, and we get bounce analytics for free. HTTPX stays as the default client since async plus connection pooling beats requests in every benchmark I care about.
Zero downtime remains the north star. The sequence will go like this: Railway sends SIGTERM, the Prefect worker flips accepting_tasks
to false, it finishes in-flight tasks, and then exits. A fresh container spawns, registers itself, and immediately begins picking up new work. If Loki shows tasks stuck longer than five minutes, we page the on-call. I plan to write chaos tests that kill a container mid-run to prove the pipeline survives. Nothing teaches faster than breaking your own toys.
The next big decision involves how we store user-defined schedules. Native Prefect blocks could work, but they feel heavy for simple cron expressions. I might stash schedules in Supabase and let a small scheduler service enqueue tasks via the Prefect client. That keeps the database as the single source of truth and avoids race conditions when users rapidly toggle jobs. We will prototype both and pick whichever looks less cursed.
I am weirdly excited to build this because it combines my love of tidy diagrams with the thrill of catching edge cases. Plus it unlocks features like “auto post my highlight reel to Instagram every Friday at 5” which users are practically salivating for, not to mention it automates our own content game. If nothing else, shipping this will squash the weekly Slack thread that starts with “can we schedule tweets yet?” and ends with me sending three ";-;"s in a row. That is worth a weekend of container spelunking.
Ending Meows #
meow meow MEOW meow mrow mrow nyaa~ meow meow MEOOOOW meow mew mew meow meow purrrr meow meow meow mrow nyaa meow meow meow MEOW MEOW meow mrow mrow meow meow meow nyaaaaa meow meow meow mrow purr purr meow meow MEOOOOOOOW meow meow meow mrow mrow meow meow meow nyaa~ meow meow meow MEOW meow mrow mrow meow meow meow purrrrrr meow meow meow mrow nyaa meow meow meow MEOW MEOW MEOW meow mrow mrow meow meow meow nyaaaaaaaa meow meow meow mrow purr purr meow meow MEOOOOOOOOOOOW