Build Shortcut
KINDAreplaces $10/mosaves $120/yrback to the verdict
A software project tracker where the interesting problems are keeping the board fast at ten thousand items, making workflow states mean something specific, and reporting progress in a way that does not quietly become a productivity measurement of individuals.
Before step 1
Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.
- installfree
Why Runs the server and the query layer.
Get it nodejs.org, or nvm install 22. open ↗
Verify
node --version prints v22 or higher - installfree locally
Why Ten thousand items with fast filtered queries and an append-only transition log.
Get it Docker or your package manager. open ↗
Verify
A filtered query over ten thousand rows returns within your stated time - have readyfree
Why Board performance, pagination stability and ordering all behave completely differently at the scale a team reaches within a year.
Get it Generate or import a realistic dataset with varied states, epics and a long transition history.
Verify
Ten thousand items exist with several transitions each - decidefree, and it takes a team conversation
Why Each state needs a written meaning before the first metric is computed, since a workflow assembled by accretion produces numbers nobody can interpret.
Get it Agree the states with the team, write one sentence per state, and mark which mean started and which mean done.
Verify
Every state has a written definition and explicit started and done properties - decidefree
Why The build excludes per-person reporting deliberately, and someone will ask for it, so the reasoning needs to exist before the request rather than after.
Get it Write down why per-person throughput is not offered and what you will point people at instead.
Verify
A written note exists and appears where someone would look for the feature
Data model
Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.
- stories(id, title, description, state_id, epic_id, iteration_id, estimate, created_at, archived_at) - states(id, name, kind, ordinal, is_started, is_done) · kind names what the state means rather than only its position - transitions(id, story_id, from_state_id, to_state_id, actor_id, at) · append only, the basis of every metric - epics(id, name, state_id, target_date, archived_at) and iterations(id, name, starts_on, ends_on) - links(from_story_id, to_story_id, kind) · blocks, relates or duplicates - saved_views(id, owner_id, query_json, shared) · because a query used daily should not be retyped - Metrics derive from the transition log rather than from a story's current state, so moving an item backwards produces correct history rather than a corrupted measurement.
Environment variables
These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.
| Variable | Needed | Example | Where the value comes from |
|---|---|---|---|
DATABASE_URLsecret | required | postgres://localhost:5432/tracker | Stories, transitions and team activity. |
BOARD_PAGE_SIZE | required | 100 | Pagination is required at real scale, not an optimisation. |
BOARD_LOAD_TARGET_MS | required | 500 | Measured at ten thousand items rather than at a hundred. |
PER_PERSON_METRICS | required | never | Present as a constant. It becomes a performance measure regardless of intent. |
AUTO_TRANSITION_ON_MERGE | required | never | A merge behind a flag is not a completed story. |
ARCHIVE_RETENTION_YEARS | required | 7 | Transitions are the metric history and outlive the stories. |
The build, in order
States that mean something
Every workflow state has a definition the team agreed on.
Inferring from column position breaks the first time someone reorders.
Files
src/states.tsEvery metric derives from them, so an edit would rewrite history.
Files
src/transitions.tsWorkflows accumulate states nobody remembers adding.
Files
src/workflow-health.ts
done when · tick each as it passeswatch out- A workflow with a state called in progress and another called in development, added at different times by different people, produces metrics that are meaningless because half the work skips one. Require each state to have a written definition and report states that are never used, so the workflow gets pruned rather than accumulating.
A board that stays fast
Ten thousand items load, filter and reorder without waiting.
The scale a team reaches is the scale a rewrite is most expensive.
Files
src/queries.tsItems moving while you page is the normal case on a live board.
Files
src/pagination.tsA fractional or sparse ordering rather than sequential integers.
Files
src/ordering.tssrc/ordering.test.ts
done when · tick each as it passeswatch out- Loading every story to render a board works beautifully in a demonstration and becomes unusable at the scale a real team reaches within a year, which is exactly when moving away is most expensive. Paginate and index from the start, and test against a generated ten thousand item dataset.
Hierarchy without a hierarchy problem
Epics and iterations organise work without becoming a second workflow.
An epic marked done with open children destroys trust in both.
Files
src/epics.tsMoving a story out should not erase that it was in.
Files
src/iterations.tsConflating them produces a hierarchy nobody can query.
Files
src/hierarchy.ts
done when · tick each as it passeswatch out- Tracking an epic's state separately from its stories produces an epic marked done containing three open stories, and nobody trusts either number afterwards. Derive the epic's progress from its children and let its own state express intent rather than completion.
Flow metrics, not people metrics
Reporting describes how work moves rather than how fast individuals are.
Current state cannot tell you how long anything took.
Files
src/metrics.tssrc/metrics.test.tsThe tail is where the process problems are.
Files
src/metrics.tsIt becomes a performance measure within a quarter regardless of intent.
Files
tests/no-person-metrics.test.ts
done when · tick each as it passeswatch out- Any per-person throughput chart becomes a performance measurement within a quarter regardless of how it was introduced, and the immediate effect is that people split tickets to raise their count. Do not build it, and say why in the interface where someone would look for it.
Connecting to the work itselfproduct builder
Stories link to code and archiving does not lose history.
A merge behind a flag is not a completed story.
Files
src/integration.tsTransitions are the metric history and are worth more than the story.
Files
src/archive.tsA tracker you cannot leave is a tracker to avoid.
Files
src/export.ts
done when · tick each as it passeswatch out- Automatically moving a story to done when a branch merges is right most of the time and wrong in exactly the cases that matter, such as a merge behind a flag or a partial implementation. Make the transition explicit in the commit or the merge, so closing a story is a decision someone made rather than an inference.
That is the whole plan for Shortcut. What it deliberately does not cover is below · check the gaps before you call it a replacement.
- Estimation and velocity forecasting.
- Portfolio and resource planning.
- Deep development tool integrations.
- Per-person productivity reporting.
- Git integrations, reporting, collaboration, and mature agile project semantics
- deep integrations
- enterprise permissions
- large-scale reporting
- battle-tested notifications and mobile apps
- Blocked time as a first-class measurement, which is where most cycle time actually goes
- A cumulative flow view, which the transition log already supports
- Work type classification so cycle times are compared like with like
Need the files? The project pack on the verdict page hands your agent the whole brief · more project management.