A game is no longer just an invite link
The last 24 hours in Nima Project left a fairly clear signal.
There was heavy activity in three repositories:
world-cup-porraworld-cup-apinima-system
And while there are many commits, they all tell the same story:
Ultimate Porra can no longer treat a game as a secondary consequence of voting. It has to treat it as a complete product object: visible, editable, reusable, shareable and administrable.
The product pressure was already there: one source of truth and a more honest entry point
The June 16 chat left two very concrete requirements:
Solo debe haber una fuente de puntuacionla pagina de inicio debe ser la pagina principal al entrar en una partida
That context matters because this day does not start from zero.
The previous day had already opened the app around Inicio, but in this 24-hour window the emphasis shifts:
it is no longer enough to explain the live match;
now the product has to explain which game you are in, which ones you belong to, which one you can create, which one you can edit and which one is worth reusing work from.
The frontend stops assuming a single implicit game
The big frontend commit, Add entry hub for public games and vote copy UI, makes a serious move:
- an entry hub for public games appears;
- the app starts listing games you have already joined;
- and it introduces an explicit vote-copy tool.
That changes the product semantics.
Before, the game could feel like the silent container inside which you voted.
Now the app has to answer much more operational questions:
- which game do I want to join;
- which one do I want to reuse votes from;
- which one is my favorite;
- and which competition or season am I actually configuring.
That is why several later commits matter more than they first seem:
Show joined public games in entryImprove setup page pool actionsAdd favorite pools to setupMake entry pool cards clickableStabilize public game join flowKeep copy votes tool available
These are not isolated touch-ups.
They are proof that once an app stops living inside a single linear flow, the entry surface stops being a form and becomes a control desk.
Copying votes stops being an internal trick and becomes a product tool
One decision in this batch is especially revealing: vote copying gets its own interface, its own contract and its own tests.
This is not just a helper landing in the codebase.
We get:
actions-copy-predictions.js;- dedicated API support;
- client state persistence;
- and a commit explicitly protecting the contract:
Cover prediction copy flow contract.
That says a lot about the current stage of the product.
Copying votes is not a cute shortcut.
It is an admission of reality:
if the pool app is going to live with multiple games, multiple competitions and multiple phases, the user cannot keep rebuilding similar work manually over and over.
The app starts assuming something more mature:
reusing a previous prediction is also a primary action, not a buried convenience.
The last commit in the window, Keep copy votes tool available, reinforces exactly that lesson.
It is not enough to implement the tool.
The product also has to defend its presence while layouts, states and entry paths keep moving.
Game setup can no longer merge competition and season as if they were the same thing
Another important change is Split competition and season selectors.
It looks like a form detail, but it actually fixes a domain confusion.
While the product was small, competition and season could travel almost as one value.
Once you start opening up:
- public games,
- admin views,
- future leagues beyond the World Cup,
- and configurable phase rules,
that fusion stops holding.
Splitting selectors is not only a UX improvement.
It is an acknowledgement that the app needs a more faithful model to answer questions like:
- which competition am I creating;
- which concrete edition am I using;
- and under which public phase should this game be exposed.
The commits Prioritize active competition lifecycle in setup, Rename competition display labels and Respect configurable preview phase point in exactly that direction.
The product stops smoothing over states.
It starts naming them.
The API stops being only about scoring and results: now it carries game lifecycle
The same story appears in world-cup-api.
In less than a day it receives:
Add public games and prediction copy APIAllow admin public game owners by auth subjectMake preview phase configurableAdd admin public game editing endpointsAdd admin private games listing
That matters because it shifts the center of gravity of the backend.
Until very recently, the pool API was strongly associated with:
- matches,
- results,
- bonuses,
- scoring,
- and external synchronization.
Now it also has to support something much closer to a game management system.
It no longer only calculates.
It also:
- creates;
- lists;
- edits;
- decides ownership;
- and governs public versus private visibility.
That change in responsibility is exactly what often separates a functional demo from an operable product.
Admin stops being an abstract boundary and starts managing concrete surfaces
The third leg of the change sits in nima-system.
The admin console commits are very direct:
Add Porra public game admin creationAdd public games admin viewAdd private games admin viewAdd competitions admin viewPin public game form in admin sidebar
A few days ago, the thesis was that admin should not live embedded inside the public app.
These 24 hours turn that thesis into real furniture.
This is no longer just about architectural separation.
It is about:
- dedicated screens for public games;
- dedicated screens for private games;
- competition views;
- sidebar-pinned forms that let operators work without losing context.
That matters because it completes the triangle:
- the player enters and joins through the public app;
- the API carries the rules and mutations;
- the operator manages the catalog and lifecycle from the console.
The boundary is no longer theoretical.
It becomes choreography across surfaces.
Even the small UI details confirm the stage change
Two smaller signals stand out to me:
- game cards become clickable;
- and
favorite poolsappears inside setup.
Both may look minor.
They are not.
They are symptoms that a game is no longer just a record.
It has become a recurring unit of work.
When something can be favorited, reopened quickly or promoted into the main entry path, that thing is no longer accessory.
It has gained durable mental weight inside the product.
What actually changed in these 24 hours
The easy description would be:
- more views,
- more endpoints,
- more admin.
But that undersells what happened.
What really changed was this:
Ultimate Porra started treating the game as the object that organizes the whole experience.
The game is no longer just where you end up after voting.
It is where you:
- land;
- choose context;
- see your options;
- copy previous work;
- distinguish public from private;
- and separate player operations from admin operations.
What I take from this stretch
Iniciono longer only explains live play; it prepares a more honest entry into the universe of games.- Vote copying rises from useful hack to official product capability.
- Splitting competition and season fixes a modeling debt, not just a form.
- The API starts carrying game ownership, visibility and editing, not only scoring.
- The admin console stops being a boundary promise and starts managing public games, private games and competitions through dedicated views.
- Favorites, clickable cards and stable join flows are signals that the game has become a recurring unit of use.
These 24 hours were not just a batch of new screens.
They were the moment when the pool app started understanding that a game is not the link that gets you in, but the main object the product has to know how to create, read, reuse and govern.
Part of my product and platform notes. Follow the blog or contact me.