Repos & branches

How Lucent Axis builds and ships SCOPE. Hover or tap Like this.Each one explains the term in plain English. for any term

One codebase. Each client gets their own database and their own installation. Work happens on branches, merges into main, and reaches the demo and clients only as a named release.

One core, many clients

Every waste client runs the same code. Their differences are settings in a folder, and their data sits in a database of its own.

Not this

A copy per client

No client repos, no client branches. Copies drift apart, so every fix is made and tested three times.

Novvia is the exception: a different industry, so its own repo.

Do this
One repo · lucent-axis on GitHub

SCOPE

The whole product, add-ons included. A fix is made once and reaches every client at their next release.

tenants/one folder per client Config folder = how one client differsInside the one repo, a folder per client: branding, which add-ons are on, and later their own words. Also called a tenant folder. Never their data, never passwords.
  client-a/logo · LMS on · Spotter on
  client-b/logo · LMS off · Spotter off
  client-c/logo · LMS on · Spotter off
same release
same release
same release
Installation Installation = the running websiteA Vercel project built from the one repo, with its own address and its own settings: which database, which config folder. Each client has two sites in it: staging, where a release is checked on safe data, and live. The code is identical; the settings differ.

Client A

LMS on
Spotter on
A's own database Physically separateEach client's data lives in its own Supabase project, hosted by Lucent Axis. One client can never see another's, even if a security rule has a bug, and a client's data can be handed over or deleted whole. This is multi-tenancy of the isolated kind.
Installation

Client B

LMS off
Spotter off
B's own database
Installation

Client C

LMS on
Spotter off
C's own database
Built

Branding

Logo, colours, font, product and client name, footer.

Now

Add-ons on/off

Spotter (Ask) and the LMS, each switched per client. A feature for one client is built as an add-on too.

With the first client

Words

Their names for things: VP → Director, GM → General Manager. Ready to build when their specs arrive.

When asked

Choices

Which metrics show, thresholds, workflow steps. Added one at a time, each with a default.

Dev, demo, clients

Dev, the demo, and for every client a staging site and a live one, all from the one repo. Only a release reaches the demo and the clients.

Branch its own preview site Pull request tests run, then merge main always releasable Dev site dev database, safe to break automatic release when approved Albany automatic Deploy release when you choose Demo on Albany Client A staging, then live: Albany Client B still on Addison
When you…Dev siteDemoClients
Merge a branch into mainUpdates by itselfNo changeNo change
Release AlbanyNo changeUpdatesNo change
Deploy Albany to Client A, stagingNo changeNo changeClient A's staging updates
Deploy Albany to Client A, liveNo changeNo changeClient A updates, once a second person approves

Every site is deployed by GitHub Actions, which applies the database changes first and then builds; Vercel builds only the branch previews, on the dev site. Each environment has its own database: dev holds sample data, the demo its storyline, each client's staging safe sample data shaped like theirs, and each client's live site their own. A new Lucent Axis dev site and demo are built beside today's; Paul's demo site stays exactly as it is until Paul switches over.

Branches

Every piece of work starts from main and goes back to main. Two people means two branches side by side, never one inside the other.

feature/…new work you expect to keep fix/…a bug fix try/…an experiment, maybe thrown away tidy/…a session of small fixes Don't know yet? Fine.Start a tidy/ branch for the session, or make the changes first and name the branch afterwards. Claude can read what changed and name it. A poke that grows big moves to its own branch.
main feature/lms-addon · Dan fix/dvir-date · Kyle try/new-dashboard · deleted update from main Addison Albany 1 2 3 4 5
1Branch from main Branch = your own laneA private line of work inside the repo. Commit and push as often as you like; nobody else sees it in main until it merges. Vercel builds each branch its own preview site.
One branch per piece of work. Days, not weeks.
2First done merges first Pull request = ask to mergeA page on GitHub that shows what the branch changes, runs the tests, and has a Merge button. Its description is the record of what happened.
Kyle's fix opens a pull request, the tests pass, it merges. The dev site updates.
3Update from main Merge conflictTwo people changed the same lines. Git can't guess, so whoever merges second picks what stays. Claude can resolve most of these.
Dan brings Kyle's fix into his branch (one button on the pull request) before merging.
4Merge
Unfinished work can merge switched off, so main stays releasable.
5Release
When main is worth shipping, it gets the next town name.

An experiment that doesn't work out is deleted and leaves no trace. Branch from someone else's branch only when your work truly needs theirs, and merge after them.

Release once, deploy to whoever

A release is a permanent name on one exact version of main. Deploying puts that version on a site. Two verbs, two moments.

Addison Albany Alburgh Andover Arlington … 247 Vermont towns and cities, A to Z, Rutland County included … Worcester Tag = a version's nameEvery commit is a version with a code like f397899. A tag sticks a name on one of them, permanently: main keeps moving, the tag never does. A release is the tag plus its page of notes.
gh release create addison --generate-notes
Once · on GitHub

Release

Name what's on main. GitHub → Releases → Draft a new release → type addison → Generate release notes → Publish. The demo updates itself, database first.

"Release Addison"
Per site · any time

Deploy

Put a release on a client. Actions → Deploy release → pick the release, the client and staging → Run. It applies the database changes, builds with that client's settings, and lands on their staging site. Once it checks out, run it again for live; someone else approves.

"Deploy Addison to Client A"
When something's wrong

Roll back or hotfix

Roll back: deploy the previous release; the database stays as it is, because it still works with it. Hotfix: branch from the release, fix only that, release it as albany-2; the fix also goes into main.

"Roll Client A back to Addison"
Say it like this
What does a client have?"Client A is on Albany"
What's waiting to go out?"What's on main since Albany?"
Never"Add a tag to Client A"

Rules: never move or delete a release; a mistake is fixed by a new one. Database changes run on dev, then the demo, then clients, and each must still work with the previous release so a rollback is never blocked.

Claude asks, you click

Nobody has to remember the rules. Claude raises each step at the right moment, as buttons, and a typed answer always works too.

Work starts on main
What kind of work is this?
FeatureFixExperimentSmall fixes
Or type your own answer…
Something worth showing
Release Albany? 6 changes since Addison. Notes drafted.
ReleaseEdit notesNot yet
Or type your own answer…
Release published
Albany is on the demo. Put it on a client's staging?
Choose clientsAll clientsNot yet
Or type your own answer…

Built into the repo so every developer's Claude does the same: project instructions say when to ask, a session-start check shows the branch and open pull requests, and two commands, /start-work and /release, walk the steps on purpose. Being tried in test-repo first.

Getting there

One new habit at a time. Nothing here needs to happen all at once.

Now

Start naming releases

  • Publish Addison when something is worth showing
  • Committing straight to main is still fine
  • Try the whole flow in test-repo
  • LMS and Spotter become on/off add-ons
Second developer, or before the first client

Branches and pull requests

  • All work on branches, merged by pull request
  • GitHub refuses direct pushes to main
  • A dev site follows main; the demo runs releases
First client live

Clients deploy from releases

  • Their installation, with a staging site and a live one
  • Two databases: staging on safe data, live on theirs
  • Deploy release: staging first, live approved by a second person
  • Their words in their config folder
Moving home

lucent-axis, as soon as the accounts exist

Nothing is moved: new sites and databases are built in Lucent Axis's own Vercel and Supabase accounts, beside the personal ones. First the dev site and the demo, then each client; Novvia gets its own site built from its own repo. Paul's demo stays untouched until Paul switches to the new one; then the personal copies are paused, and nothing is pushed to two places any more.