i’m the vice president of the computer science society at tcu, and i originally built pulse labs because i got tired of switching between spreadsheets, google forms, and paper sign-in sheets every time we ran an event. i wanted one place where we could manage members, organize events, and track attendance. after i deployed the first version, people started asking for more features, and the project slowly grew into a platform for student organizations.
it’s built with react (tanstack start), typescript, postgresql, and supabase. i decided not to build a separate backend service. instead, most of the authorization lives in the database through row level security and postgres functions. every organization has its own workspace, and access is enforced in the database instead of relying on frontend checks.
supporting multiple organizations ended up changing a lot of the project. once every club had its own members, officers, events, and invitations, i had to redesign a good part of the database. permissions became much more complicated than they were in the first version, and moving them into postgres made the rest of the application much simpler.
one bug i found pretty late was in my row level security policies. some of the earliest policies were written before the app supported multiple organizations, and they still allowed public reads. the interface never exposed another organization’s data, but someone could still query it directly with the public api key. i rewrote those policies and moved the public check-in flow into a small set of postgres functions that only expose the data needed for that page.
qr check-ins changed a lot too. the first version used a static qr code, which meant anyone with a screenshot could keep using it. now every qr code rotates every five minutes using an hmac based on the event and the current time window. resetting a session immediately invalidates every previous qr code without affecting attendance records.
there isn’t an analytics table either. attendance, retention, active members, and engagement metrics are all calculated directly from check-in data whenever someone opens the dashboard. i originally tried storing some of those values, but they eventually became inconsistent, so i removed them and calculated everything from the source data instead.
the computer science society was the first organization to use pulse labs. after it was deployed, most of the work shifted from adding new features to improving the ones that already existed. i still use it whenever we run events, so every semester i end up finding something else to improve.