An elist management app with a form builder for making customizable user preference forms
-
Backend is implemented with Nest.js, an API framework for TypeScript
-
Data is stored in a MySQL database using Google CloudSQL for MySQL. I chose a relational database to be able to support granular analytics operations for elists.
-
MikroORM used for modeling domain entities, handling transactions and query building. I chose Mikro for it's first class TypeScript support, and since it exposes a knex like query builder for highly flexible queries.
-
Backend architecture is split into Entities, Controllers for organization
-
API is hosted as a gen 2 GCP Cloud Function
-
Front-end is build in angular, and served with firebase
-
UI library used is Angular Material. I use prime-ng most frequently and wanted to try out angular material's API.
-
Front-end architecture is layered
- HttpServices are where network interactions happen
- Stores are injectable singleton services that share global state data
- DomainServices contain all operations on domain data, and are the points of access for it for the UI
- Presenters host any complex ui logic, state and view models that may need to be shared between components
- Components are merely responsible for rendering ui and registering event handlers
- Class-transformer and class-validator are used to transform shared data contracts into model classes, and to validate them
-
Form builder is implemented with Angular Reactive Forms using the ngx-reactive-form-class-validator and with custom form controls
-
Project is organized as a monorepo with shared interfaces using Nx
I wanted to experience full-stack engieering in an isomorphic TypeScript environment, as well as work with Angular Reactive Forms. I gained deep insight into the latter, and great appreciation for much of a productivity boost shared interfaces can be. I was also hoping to build a project that would allow me to experiment with micro-frontends.
Overall, my feeling is that the isomorphic TypeScript stack gives you a great boost when you go completely backendless, and use a serverside framework to interact with the data layer directly. or perhaps if you're using a NoSQL database. If you construct an API, and use ORMs with a relational database, classes can't be shared due to normalizaton and joins. So you might as well be using a different language if performance and/or ecosystem are a concern.
- Experiment with micro-frontends to see how looper can be embedded into other peoples' websites and projects
- Make the theme and appearance of public elist pages / self-service portal more customizable
- Adding analytics for elists (new subscribes/unsubscribes, etc.)
- Adding email campaigns for elists
- Added static asset hosting with Google Cloud Storage