08

Building a Project Management System Around the Way Work Actually Happens.

Designing an evolving project management platform around clearer planning, flexible workflows, and fewer assumptions about how teams should work.

Company
BetaVault Creative
Project Management System
Role
Founder / Senior Full-Stack Developer
Product Architecture & Engineering
Technology / Skills
Angular, NestJS, PrimeNG, NgRx
TypeScript, APIs, AWS

Project Management System

I’ve used a lot of project management software over the years, and I’ve often found myself adapting the way I work to the tool rather than the other way around. The more capable these systems become, the easier it is for managing the system itself to become part of the job.

This project started as an opportunity to explore that problem for myself.

I’m building a project management system around a simple idea: software should help people understand what needs their attention without requiring them to constantly organize, categorize, and maintain the information that tells them so.

That means I’m not trying to reproduce every feature found in established project management platforms. I’m starting with the problems I actually want to solve—organizing work, understanding priorities, planning time, and seeing what is coming—and allowing the product to grow from there.

It is also intentionally a long-term engineering project. I’m using it to explore architectural ideas, evaluate newer approaches in Angular and Node.js development, and build something substantial enough that today’s decisions have consequences I’ll have to live with tomorrow.

I don’t want to build software that simply stores information about work. I want to build software that helps make sense of the work and help forecast the outcome.

Product Philosophy

Project management systems naturally accumulate options. Every team works a little differently, so adding another setting, field, status, or workflow can always be justified. Taken far enough, however, flexibility can transfer the responsibility for designing the system from the software back to the user.

I’m interested in finding the boundary between the two.

The application should provide enough structure that someone can begin using it without first designing their own project management methodology. At the same time, the underlying architecture needs to accommodate different kinds of projects, priorities, schedules, and workflows.

This has made product design inseparable from architecture. Before adding something, I try to ask not only how I can build it, but whether the application should require the user to think about it at all.

Frontend Architecture

The frontend is built with Angular, with PrimeNG providing many of the foundational interface components and Tailwind CSS handling much of the surrounding layout and presentation.

I’ve worked with Angular since the early releases of Angular 2, so this project gives me an opportunity to build an application using the framework as I would choose to use it today rather than inheriting an established architecture.

I’m organizing the frontend around clearly separated application concerns and reusable components rather than individual pages. Features should be able to evolve without requiring unrelated parts of the application to understand their implementation.

I’m also making extensive use of Angular’s modern reactive capabilities. Signals have become particularly useful for keeping component state close to the features that own it while still allowing larger application concerns to be handled through a more structured state architecture.

The goal isn’t to demonstrate how many Angular features I can fit into one project. It’s the opposite: I want the architecture to remain understandable as the application becomes more complicated.

State Management

For persistent and application-wide state, I’m using NgRx as the primary state-management layer.

Temporary interface state—whether something is expanded, what a component is currently displaying, transient editing behavior, and similar concerns—can often remain closer to the component or feature that owns it using Angular Signals and NgRx SignalStore.

My general rule is that state should become global because multiple parts of the application genuinely need to understand it, not simply because a state-management library exists.

That gives me a layered approach:

NgRx for durable application state. Signals and NgRx SignalStore for local and transient state. Components for behavior that doesn’t need to escape the component at all.

As the application grows, I’m continuing to refine those boundaries based on actual use rather than trying to predict every state-management requirement up front.

API / Backend Architecture

The backend is being developed with NestJS, giving the application a TypeScript-based architecture from the browser through the API.

I’m particularly interested in keeping the API contract centered around the needs of the product rather than simply exposing database structures to the frontend. I’ve seen how much unnecessary complexity can accumulate in a frontend when it becomes responsible for repeatedly reshaping backend data into something the interface can actually use. Here, I’m able to design both sides together.

Shared types, validation, predictable response structures, and clear service boundaries are being treated as part of the architecture from the beginning.

I’m also developing a Time Off system as part of the broader scheduling model. That’s useful because it forces the application to deal with something project-management software often simplifies too aggressively: people aren’t infinitely available resources. Scheduling eventually has to understand when people can actually work.

That will become increasingly important as I develop the forecasting side of the application.

Development Infrastructure

This is intentionally not the primary focus yet.

I don’t want to spend weeks perfecting a production environment for a product whose core behavior is still changing rapidly.

Instead, I’m putting enough infrastructure in place to keep development productive while postponing decisions that don’t need to be made yet.

I’ve built development tooling and mock data infrastructure that allow me to work on frontend features without requiring every backend capability to be finished first. This makes it much faster to experiment with interactions and change data structures while the product is still taking shape.

For deployment, I’m building toward AWS, including ECS, but I’m deliberately allowing the product architecture to stabilize before making production infrastructure a major focus.

For me, that’s part of engineering too:

Not every problem needs to be solved at the earliest possible moment.

Designing for Change

The architecture isn’t being designed around the assumption that I can predict the final shape of the product. Instead, I’m trying to create boundaries that make changing my mind relatively inexpensive.

Iterating Frequently

That means keeping domain logic separated from presentation, maintaining clear API contracts, avoiding unnecessary coupling between features, and being cautious about abstractions that exist only because I might need them someday.

In that sense, the application isn’t only a project management product. It’s an ongoing test of the way I currently believe software should be built.

Currently on the Boards

  • Update Dependencies
  • Basic Structuring
  • Time Off System
Where my attention is.

My current focus is primarily on the frontend experience and the underlying application model. I’m using mock services where appropriate so I can rapidly test workflows and refine the data they need before committing those decisions to the backend.

This is a bit of a pivot from my original approach. I started by developing the frontend and backend together, but I’ve found that working through the interface first gives me a clearer picture of what the API actually needs to provide. As those behaviors and data structures stabilize, I’ll move them behind the NestJS API and toward the production architecture.

Update Dependencies
Starting fresh with the latest tech.

I’m taking this opportunity to bring the application forward with the latest versions of the tools and frameworks I’m using while selectively porting work from the previous version. It’s also a chance to revisit older decisions, clean up code that has evolved over time, and take advantage of newer Angular patterns rather than simply recreating the application exactly as it was.

Basic Structuring
Organizations, projects, and the relationships between them.

Much of the foundation for organizations and projects already exists in the previous version, but I’m reconsidering how those concepts are represented and managed in the new application. While building the Time Off system, I developed cleaner patterns for handling forms, controls, and shared behaviors. I’m now bringing those lessons back into these foundational features so they establish patterns the rest of the application can build upon.

Time Off System
The lonely kicker that became a system of its own.

What started as a relatively isolated feature has coincidentally become one of the largest and more interesting parts of the application. Scheduling time off sounds simple until you account for partial days, date ranges, recurring schedules, different policies, validation, availability, and all the ways those rules can interact. Fortunately, I’ve already worked through many of those problems in the previous version. Now I’m refining the model and using what I’ve learned to make the implementation cleaner and easier to extend.

Recent Development

  • June 2026
  • April 2026
  • March 2026
June 2026
Starting Fresh with New Tools
Angular, PrimeNG, NgRx

I started a new version of the project using the latest versions of the core technologies behind it. The first milestone was rebuilding the frontend authentication experience while establishing the Angular architecture and patterns I’ll use throughout the rest of the application.

April 2026
Development Takes a Back Seat

I accepted a four-month software development contract, so work on the project slowed while my attention shifted to client work. One advantage of a long-term personal project is that it can wait for me—and often benefits from the perspective I bring back to it.

March 2026
Building the Time Off System
Angular, NestJS, RRule

I completed the first major version of the Time Off system across both the frontend and backend. What initially looked like a relatively isolated feature grew into a much deeper exploration of recurring schedules, date ranges, validation, and the many exceptions involved in representing when people are actually available to work.

Things I’ve Learned So Far

Architecture needs evidence.

It’s easy to design for imaginary future requirements. Building the product has continually reminded me to let real problems earn their abstractions.

Not all state deserves the same solution.

Using NgRx alongside NgRx SignalStore has reinforced the value of choosing state management based on scope and lifetime rather than applying one pattern everywhere.

Frontend and backend design are one conversation.

When I control both sides of the API, I can design contracts around how the product actually behaves instead of making either side compensate for the other.

Product development changes engineering priorities.

When I’m responsible for deciding what gets built as well as how it gets built, technical elegance has to compete with usefulness. That’s a healthy constraint.

Other Case Studies

Different problems, different constraints, and different kinds of solutions. Here’s another project from the collection.

Have a Complicated Problem of Your Own?

I’m actively developing this project, so some of the most interesting decisions are still being made. If you’re working through similar product or architecture problems—or simply want to compare notes—I’d be happy to hear from you. Send me a message below or reach me directly at mitchell@betavc.com