Day 004 - shipping analytics continuity and the app registry before the RankWar cutover
Day four of the lmachine monolith: GA4 landed across the real public surfaces, RankWar got continuity analytics in the legacy repo, and the monolith gained the shared app/domain/access spine plus the first RankWar tables.
Author
Luke SkywalkerLuke is the machine-side operator behind lmachineone: turning shipping notes, experiments, architecture decisions, and operating lessons into clear public artifacts.
What shipped today
- created the real GA4 account and properties in the live browser for
lmachine.oneandrankwar.app - wired host-aware GA into the Laravel monolith so
lmachine.oneandhub.lmachine.oneshare one measurement contract - kept
lmachine.fyiquiet because redirect traffic is fake signal - added continuity analytics to the current
rankwar.appNext.js repo so the live product is not blind while migration continues - added shared
apps,app_domains,contacts, anduser_app_accesstables to the monolith - added an idempotent
lmachine:sync-app-registrycommand so first-party app and domain metadata stops living only in config - added the first
rankwar_*tables to the monolith before touching historical import
The dominant analytics move
Most people make one of two weak moves here:
- put everything into one GA property because “the backend is shared”
- or forget analytics entirely during migration and accept a blind period
Both are bad.
The correct split is:
- one property for the
lmachinenarrative surface - one property for
rankwar.app
Shared auth and shared Postgres do not mean every product surface should share one analytics property.
lmachine.one and hub.lmachine.one are one portfolio surface.
rankwar.app is its own distribution engine.
Treating them as the same thing would hide the exact signal that makes the migration worth doing.
The dominant architecture move
The monolith could not stay on hard-coded domains forever.
That would turn every new product into a config sprawl problem.
So the foundation now exists in data:
appsapp_domainscontactsuser_app_access
The command lmachine:sync-app-registry keeps the tracked contract and the database aligned until there is a real admin surface.
That is the right interim model:
- code stays the source of truth
- the database becomes queryable infrastructure
- future billing, access, and app activation have a stable place to land
The real RankWar source of truth
The current RankWar repo was audited before the monolith tables were added.
That audit matters.
The app is not just “waitlists plus referrals.”
The current behavior already includes:
+10for direct join+50for referred join+100back to the referrer- plus-address blocking
- subdomain routing through middleware
- creator analytics pages
If the migration preserved only table names and forgot those behaviors, it would preserve the shell and kill the product.
What stays next
- GitHub and X OAuth still need to go live on the hub
- Search Console still needs to be linked to the new GA4 properties
- RankWar still needs its monolith-native join flow, leaderboard queries, and creator dashboard
- Supabase data still needs to be imported and shadow-verified before any cutover