What building ROAM and The Blessing Machine taught me
Two student era applications, a venue booking service and a donation platform, read back from their repositories years later: what the data models got right, what the code got wrong, and what carried into the systems I build now.
Contents
I opened two old repositories this month to see what they would tell me, and they told me more than I expected. Both were built during my software engineering study at The Flatiron School. ROAM is a venue and band booking service, built as a group project, with a Flask API behind a React front end. The Blessing Machine is a donation platform for Christian organizations, built on the same stack, that I carried further on my own. Neither is production software. Both are honest records of what a builder knew at the time, and reading them again is a useful exercise for anyone who now builds systems for a living.
Both repositories are public on GitHub, and everything below is taken from what is in them rather than from what I remember.
What ROAM was
The README describes a platform where event organizers book venues and bands, and where venue owners and bands list their services. The user stories are specific: sign up and stay signed in, view venues and bands nearby with reviews, write and edit a review, create a listing, see venues on a map, search by distance, filter by rating. The stack was a Flask API with a SQLAlchemy model layer and Alembic migrations, and a React client using Formik for forms and React Router for navigation.
The repository is a fork of a shared team project, which is how group work at a school is organized. Reading the file tree now, the front end is organized by feature: a landing page, a login and signup flow, a dashboard, and a property list with its own components. That organization was a good instinct, and it is the one I still use.
What The Blessing Machine was
The home page component states the purpose in one sentence: a donation platform for Christian organizations, aimed at changing how they raise and manage funds. The interesting part is the model file. It defines four tables. A User with a name, an email and a password. An Organization with a name, a logo, a tagline, goals, achievements and financial needs. A Donation linking a user to an organization with an amount, a frequency and payment information. A SuccessStory belonging to an organization with a title and a description. Users and organizations are joined through an association table, so a person can follow several organizations.
That model is the best thing in either repository. It is small, it is normalized, and it names the real entities of the problem. A donation platform is people, organizations, money moving between them, and the stories that motivate the money. Four tables say exactly that.
What the code got wrong
Reading with today’s eyes, the faults are plain and they are instructive.
Passwords in the User model are stored as a plain string field, and the seed file writes literal passwords into the database. There is no hashing, no salting, and no authentication layer in the API file at all. The routes return users and donations to anyone who asks. For a platform whose whole purpose is moving money, that is the first thing I would fix and the first thing I would now design before writing any route.
The server file contains the entire application twice. Somewhere in the work the file was pasted into itself, so the app is defined, the routes are declared, and then all of it is declared again, followed by two copies of the block that starts the server. It ran, because a Python module tolerates redefinition, and nobody noticed because nothing broke. That is the purest example I have of a defect that settles into a habit instead of surfacing as a bug.
The seed file has an indentation fault: the donations are created outside the block that gives them an application context, and a list of success stories is added to the session that was never defined. The README says to install dependencies and start the server, then admits, with a date, that the debugger needs to be turned off in the package file and will be corrected soon. It was not.
What the code got right
The migrations exist. Both projects used Alembic with a versions folder, which means the database schema was versioned from the first table. Many working systems I have seen since do not have that.
The models use relationships correctly. Backrefs, lazy loading, an association table for the many to many case. The developer who wrote that understood the data before writing the routes, which is the order I still insist on.
The front end components are small and named for what they do. A Nav, a DropDown, a Home, a Dashboard, a PropertyList. There is no clever abstraction, which in a student project is a virtue and in a production system usually still is.
What a group project teaches that a solo one cannot
ROAM was built by three people and The Blessing Machine mostly by one, and the difference shows in the repositories. The group project has a README that reads like a specification: an introduction, a list of user stories, installation steps, usage steps, a technology list, and a credits section. Somebody had to write down what the system was supposed to do so that three people could build parts of it without talking every hour, and that document outlived the code. The solo project has a README of four lines, one of which is an apology. Nobody needed the specification because the one builder held it in his head, and the moment he moved on it was gone. I now write the specification first on every system, including the ones I build alone, because the person who will need it most is me in two years. The group project also shows the cost of coordination in the file tree: components duplicated between folders, two property list components in different places, a webpack configuration that one member added and the others worked around. That is what three people learning a stack together looks like, and it is not a criticism. It is the reason a shared project has a document at the top.
What carried forward
Three things from these repositories are in every system I build now.
Model first. The data model of The Blessing Machine is the reason the project is legible years later. The systems I now run for investor follow up began as a schema on paper, and the schema is the thing I defend hardest when someone wants a new feature.
Migrations from the first table. A versioned schema is the difference between a system that can change and one that has to be rebuilt.
Seed data that is honest. The seed file in The Blessing Machine wrote example users with example passwords, which was fine for a student project and would be a serious problem anywhere else. The lesson I took is that seed data is code, it ships, and it has to be treated with the same care as the tables it fills.
And one thing I learned by its absence: the boundary between what a system stores and what a system protects. Neither project drew that boundary. Every system I have built since draws it before the first route exists.
The honest limit
A repository from a course is a photograph of a moment, and the temptation is to read it as more than that, in either direction. It is not evidence of what I can build now, and it is not something to be embarrassed by. It is a record, and records are what this site is built on. I left the crypto tracker from the same period out of this article because there was nothing in it I have not already said here.