posts

PocketBudget Stream #2 Recap

I wanted to complete 4 tasks this stream, but I eneded up only doing 2 since I didn't account for any troubleshooting time.

This was the second stream of me building PocketBudget. I set out to do four things, but only ended up finishing two. Honestly, that’s fine — I learned a lot more about how PostgresNIO works, so still a win.

What happened this stream?

After last stream, I decided I want to tackle all backend needs first before moving on to the client (an iOS app in my case). So this stream, I started working on basic CRUD operations for a User, since almost all data in the app will eventually relate back to a user.

// NOTE

CRUD stands for Create, Read, Update, and Delete.

I wanted to complete full CRUD support for users, but only got Create fully working and started a stub for Read (fetching all users). Realistically, fetching all users is only useful for me during development — it doesn’t actually move the app forward much yet.

One thing I spent time on was learning how to catch a specific error from PostgresNIO. It took some digging, but I found that I needed to check the sqlState field and match it against the code 23505 to detect a unique constraint violation (basically, when trying to insert a user that already exists based on unique fields). Here’s the code I ended up with:

// Inside a do-catch block
catch let error as PSQLError {
    if let sqlState = error.serverInfo?[.sqlState] as? String, sqlState == "23505" {
        logger.error("🚨 User already exists with the same auth_provider_id and auth_provider")
        throw HTTPError(.badRequest, message: "User with this auth_provider_id and auth_provider already exists.")
    }
    logger.error("🚨 \(String(reflecting: error))")
    throw error
}
// Rest of catch

What’s next?

I’ll be continuing some work off stream — mainly converting existing tests from XCTest to Swift Testing and writing new tests for the work done so far. I also plan to finish the Delete and Update operations for users offline.

I want to set up swift-format on the project too, so the codebase stays clean and consistent as it grows.

For the next stream:

Keeping the goals small on this stream so that I can hopefully get them all done. If I end up getting them done, then I’ll head on to budgets next.

Nov 9, 2025 swiftswift testing
How to run Swift Tests Serially across files
Here's how I am running Swift Tests serially. Note, this is using Swift Testing.
Oct 16, 2025 ship-a-tonswiftcamp notes
Camp Notes's First Paywall Experiment
Starting my first paywalll experiment for Camp Notes.
Oct 13, 2025 ship-a-tonswiftcamp notes
Camp Notes Won a OneSignal Boost Award at Shipaton
Camp Notes placed 5th in the OneSignal Boost Award category at RevenueCat's Shipaton hackathon. This post covers what Shipaton is, why I entered, how I implemented OneSignal for notifications and emails, and what I learned from competing against over 800 entries.