7 Days of Bootstraps: Day 4
Tags: startup, business, bootstrapping
Published: 2021-08-13 12:11:31

On Monday, August 9th I started a challenge for myself to bootstrap a business from the group up during my 7 day vacation. This post documents what I learned and the challenges that I faced on day 4. The start of my journey with the Remarkable Sidekick is here.

## Lesson of The Day

Move on quickly, when you hit a roadblock.

I ran into an issue when trying to pass images from the front-end to the back-end components of the Remarkable Sidekick. Unfortunately, the IPC interaction works great in an asynchronous mode, but gets a little bit clunky when expecting a response back in a synchronous fashion.

I ended up spending a few hours trying a few different approaches, but ultimately moved on. After returning later, I ended up with a satisfactory approach by centralizing the error handling. Such that no individual request will handle their own errors, rather error notifications will be emitted by the IPCConsumer process.

Moving onto other problems, and returning later a bit sooner likely would have saved me some time in the long run.

## Early Morning

I spent most of the morning working on implementing the ability to add images locally. This involved base64 encoding the images, passing them to the Electron back-end via IPC and then persisting them to a local directory. In addition to that, I implemented a simple scan of that images directory so that the Remarkable Sidekick is able to populate a 4x4 image grid showcasing the available images that can be set as the lockscreen image.

I still have an open item to define the image height and widths based on the 4:3 aspect ratio of the Remarkable. I played around with this a little, but I think I'm going to have to resize the images to a fixed size, as setting the width and height dynamically isn't providing to best UX.

## Afternoon

The afternoon was focused on implementing the first serverless function to handle uploading images to a centralized GCS bucket. In addition to that, I started exploring GCP's API gateway as it offers a few amazing capabilities out of the box. Specifically, it provides authentication, rate limiting, routing and the ability to natively integrate with GCP Cloud functions.

As someone who has worked built out at least two reverse-proxy API gateways, these features can not only be tedious to build, but also challenging to get right. I've been wanting to try out one of the managed API Gateways, so this has turned out to be a perfect chance.

I have not seen this Open API format before, but its a pretty interesting way to define the relative API paths and metadata. Standards can be nice, especially for providing cross platform compatibility, and it does look like AWS and Azure support the same configuration approach based on Open API.

```
swagger: '2.0'
info:
  title: API_ID optional-string
  description: Remarkable API with Cloud Functions backend
  version: 0.0.1
schemes:
  - https
produces:
  - application/json
paths:
  /image/upload:
    post:
      summary: Allows a user to upload a lockscreen image
      operationId: hello
      x-google-backend:
        address: https://us-east1-remarkable-sidekick.cloudfunctions.net/upload-image
      responses:
        '200':
          description: A successful response
          schema:
            type: string
```

## Progress
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2vxvzsuj4e7qc7ljoffc.png)

## Conclusion

We're starting to get into the home stretch and I'll admit that I still have a decent amount of work to do. That being said, I'm almost finish with the initial set of offline features. This should allow me to start identifying the process for submitting this application to both the Mac App Store and the Windows App Store.

I also still have a decent amount of work to do on the API side of things, namely around creating accounts and handling payment information via Stripe.

[Remarkable Sidekick](https://remarkablesidekick.com) | [Twitter](https://twitter.com/peytoncasper)