PROJ: GitHub Integration Plan
Executive Summary
Section titled “Executive Summary”╔══════════════════════════════════════════════════════════════════════╗║ ║║ ██████╗ ██╗████████╗██╗ ██╗██╗ ██╗██████╗ ║║ ██╔════╝ ██║╚══██╔══╝██║ ██║██║ ██║██╔══██╗ ║║ ██║ ███╗██║ ██║ ███████║██║ ██║██████╔╝ ║║ ██║ ██║██║ ██║ ██╔══██║██║ ██║██╔══██╗ ║║ ╚██████╔╝██║ ██║ ██║ ██║╚██████╔╝██████╔╝ ║║ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ║║ ║║ I N T E G R A T I O N P L A N ║║ ║║ Magic e-VERSE ──► GitHub Repositories ║║ Multi-Tenant Version Control & Code Distribution ║║ ║╚══════════════════════════════════════════════════════════════════════╝The Magic e-VERSE platform currently manages 9 commerce tenants, a PIM system, a Portal, and multiple supporting services. Code is distributed manually by copying files from magic_development to all tenants using rsync and cp commands.
This plan migrates the entire ecosystem to GitHub-hosted repositories with proper version control, branching, commit history, and a structured code distribution workflow — eliminating manual file copying and introducing traceability, rollback capability, and team collaboration.
What is Git & GitHub? — High-Level Overview
Section titled “What is Git & GitHub? — High-Level Overview”Git — The Version Control System
Section titled “Git — The Version Control System”Git is a distributed version control system that tracks every change ever made to your codebase. Think of it as an unlimited “undo history” for your entire project, where every save point (called a commit) records exactly what changed, when, and by whom.
Your Code Over Time ═══════════════════
Commit 1 Commit 2 Commit 3 Commit 4 ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Initial │─────►│ Add cart │─────►│ Fix bug │─────►│ New CMS │ │ project │ │ feature │ │ in login │ │ module │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ Jan 15 Jan 22 Jan 25 Feb 3 by Michiel by Michiel by Claude by Michiel
◄──── You can go back to ANY of these points at any time ────►Key Git concepts:
| Concept | What it means | Analogy |
|---|---|---|
| Repository (repo) | A project folder tracked by Git | A project folder with infinite undo |
| Commit | A saved snapshot of changes | A save point in a video game |
| Branch | A parallel version of your code | A copy you can experiment on safely |
| Merge | Combining changes from one branch into another | Bringing your experiment back into the main project |
| Pull | Download changes from GitHub to your server | Syncing your local copy with the team |
| Push | Upload changes from your server to GitHub | Publishing your work for the team |
| Clone | Create a full copy of a repository | Downloading the project for the first time |
GitHub — The Hosting Platform
Section titled “GitHub — The Hosting Platform”GitHub is a cloud platform that hosts Git repositories and adds collaboration features on top:
- Central source of truth — One place where the “official” code lives
- Pull Requests (PRs) — Propose changes, review them, discuss, then merge
- History & blame — See who changed what line and when
- Issues — Track bugs and feature requests
- Releases — Tag and distribute specific versions
- Access control — Control who can read/write to each repository
- Backup — Your code is safely stored in the cloud, not just on one server
Branches — The Key to Safe Development
Section titled “Branches — The Key to Safe Development”Branches are what make Git powerful for a multi-tenant setup like Magic e-VERSE:
main (stable, production-ready) ────●────●────●────●────●────●────●────●────●────► \ \ / \ \ / ◄── merge back when done \ \ / ●────●────● ●───● feature/ fix/cart- new-cms calculation
● = commit (saved change)mainbranch always contains stable, tested code- New features and fixes are developed on separate branches
- Changes are merged back into
mainonly after review and testing - If something goes wrong on a branch,
mainis never affected
Why Git for Magic e-VERSE? — Benefits for Multi-Tenant
Section titled “Why Git for Magic e-VERSE? — Benefits for Multi-Tenant”Current Pain Points
Section titled “Current Pain Points”┌──────────────────────────────────────────────────────────────────────┐│ CURRENT WORKFLOW (Manual Copy) │├──────────────────────────────────────────────────────────────────────┤│ ││ 1. Developer changes files in magic_development ││ 2. Manually copy changed files to 8 other tenants (cp / rsync) ││ 3. Rebuild Docker containers for each tenant ││ 4. Hope nothing was missed ││ ││ PROBLEMS: ││ ✗ No history — "What changed last week?" → Unknown ││ ✗ No rollback — "Something broke, go back" → Impossible (no ││ snapshots unless manual backup was made) ││ ✗ No traceability — "Who changed this file?" → Unknown ││ ✗ No safety net — Accidentally copy tenant-specific config → ││ Tenant breaks ││ ✗ No collaboration — Two people working = conflicts and chaos ││ ✗ No code review — Changes go live without any review process ││ ✗ Drift — Tenants slowly diverge from each other over time ││ │└──────────────────────────────────────────────────────────────────────┘How Git Solves Each Problem
Section titled “How Git Solves Each Problem”┌──────────────────────────────────────────────────────────────────────┐│ FUTURE WORKFLOW (Git + GitHub) │├──────────────────────────────────────────────────────────────────────┤│ ││ 1. Developer creates a branch for their change ││ 2. Makes changes, commits with descriptive message ││ 3. Opens a Pull Request → visible diff, review, discussion ││ 4. After approval, merge into main ││ 5. Pull on server → all tenants get the update automatically ││ ││ BENEFITS: ││ ✓ Full history — Every change recorded with timestamp & author ││ ✓ Instant rollback — "git revert" undoes any change safely ││ ✓ Full traceability — "git blame" shows who changed each line ││ ✓ Safety — Tenant-specific files in .gitignore, can't be ││ accidentally overwritten ││ ✓ Collaboration — Branches isolate work, merges combine it ││ ✓ Code review — Pull Requests enforce review before deploy ││ ✓ Consistency — All tenants pull from the same source branch ││ │└──────────────────────────────────────────────────────────────────────┘Multi-Tenant Specific Benefits
Section titled “Multi-Tenant Specific Benefits”In a multi-tenant architecture like Magic e-VERSE, Git is particularly valuable:
- Single source of truth — Shared code lives in one repository. No more 9 copies drifting apart.
- Tenant-specific configuration safely separated —
docker-compose.yml,.env, andmedusa-config.tsare in.gitignore(or in a separate config directory), so they are never accidentally overwritten during sync. - Feature branches per tenant — If Brinxx needs a custom feature, it can live on a dedicated branch without affecting other tenants.
- Deployment visibility — Commit history shows exactly which features have been deployed to which tenants and when.
- Disaster recovery — If the server dies, the full codebase (with history) is safely on GitHub. Clone and you’re back.
Current State Analysis
Section titled “Current State Analysis”What Exists Today
Section titled “What Exists Today”| Component | Git Status | Remote | Notes |
|---|---|---|---|
magic_omniverse/ | Local git repo | Local bare repo only | 8,524 tracked files, master branch |
magic_pim/ | Local git repo | No remote | Isolated, 8,478 tracked files |
magic_brinxx/ | Local git repo | Local bare repo | 8,524 tracked files |
magic_development/ | Local git repo | Local bare repo | Source/basis for all tenants |
magic_commerce.git | Bare repository | N/A | Central local repo for commerce tenants |
| Other tenants | Mixed | Local bare repo | Some empty (no commits) |
Key Issues
Section titled “Key Issues”| Issue | Impact | Priority |
|---|---|---|
No .gitignore files | Sensitive files (.env, credentials) could be tracked | Critical |
| No GitHub remote | Single point of failure — code only on this server | Critical |
| No branch strategy | Everything on master, no feature isolation | High |
| No PR workflow | Changes go live without review | High |
| Tenant configs in source | Risk of overwriting tenant-specific files during sync | High |
| PIM has no remote | Complete isolation, no backup | High |
safe.directory = * | Bypasses Git’s security protections | Medium |
Repository Architecture — Two Options
Section titled “Repository Architecture — Two Options”Option A: Monorepo (Recommended for teams < 10)
Section titled “Option A: Monorepo (Recommended for teams < 10)”One single repository contains all shared code. Tenant-specific configuration lives in a dedicated config/tenants/ directory within the same repo.
GitHub Organization: magiceverse ═══════════════════════════════
┌────────────────────────────────────────────────────────────────┐ │ Repository: magiceverse/magic-commerce │ │ │ │ main branch │ │ ├── backend/ │ │ │ ├── src/ ◄── Shared code (all tenants) │ │ │ │ ├── api/admin/aplt/ │ │ │ │ ├── admin/routes/ │ │ │ │ ├── modules/ │ │ │ │ └── ... │ │ │ ├── Dockerfile │ │ │ └── package.json │ │ ├── storefront/ │ │ │ ├── src/ ◄── Shared code (all tenants) │ │ │ │ ├── themes/ │ │ │ │ │ ├── base/ ◄── Shared base theme │ │ │ │ │ ├── brinxx/ ◄── Tenant-specific theme │ │ │ │ │ ├── default/ ◄── Tenant-specific theme │ │ │ │ │ └── .../ │ │ │ ├── Dockerfile │ │ │ └── package.json │ │ ├── config/ │ │ │ └── tenants/ ◄── Tenant configs (tracked!) │ │ │ ├── magic_development/ │ │ │ │ ├── docker-compose.yml │ │ │ │ ├── medusa-config.ts │ │ │ │ └── .env.example ◄── Template only, no secrets │ │ │ ├── magic_brinxx/ │ │ │ │ ├── docker-compose.yml │ │ │ │ ├── medusa-config.ts │ │ │ │ └── .env.example │ │ │ └── .../ │ │ ├── scripts/ │ │ │ ├── deploy-tenant.sh ◄── Automated deployment │ │ │ ├── deploy-all.sh ◄── Deploy to all tenants │ │ │ └── new-tenant.sh ◄── Create new tenant setup │ │ ├── .gitignore │ │ └── README.md │ │ │ └────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐ │ Repository: magiceverse/magic-pim │ │ (Separate repo — different codebase, different lifecycle) │ └────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐ │ Repository: magiceverse/magic-portal │ │ (Separate repo — React/Vite app, independent deployment) │ └────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐ │ Repository: magiceverse/magic-docs │ │ (Separate repo — Starlight documentation site) │ └────────────────────────────────────────────────────────────────┘Pros:
- Simple — one repo to manage, one place to search code
- Atomic commits — a change that affects backend + storefront is one commit
- Easy code review — one Pull Request for all related changes
- No dependency management between repos
- Tenant themes are versioned alongside the code that uses them
Cons:
- Larger repository size (but Git handles this well)
- All developers see all tenant configs (mitigated by GitHub access controls)
Option B: Core + Tenant Config Repos (Better for teams > 10)
Section titled “Option B: Core + Tenant Config Repos (Better for teams > 10)”Shared code lives in a core repository. Each tenant has a tiny config-only repository.
GitHub Organization: magiceverse ═══════════════════════════════
┌────────────────────────────────────────────────────────────────┐ │ Repository: magiceverse/magic-commerce-core │ │ │ │ Contains ONLY shared code: │ │ ├── backend/src/ ◄── All API routes, modules │ │ ├── storefront/src/ ◄── All storefront code │ │ ├── backend/Dockerfile │ │ ├── storefront/Dockerfile │ │ ├── backend/package.json │ │ ├── storefront/package.json │ │ └── storefront/src/themes/ ◄── All tenant themes │ └────────────────────────────────────────────────────────────────┘
┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ │ magic-tenant- │ │ magic-tenant- │ │ magic-tenant- │ │ development │ │ brinxx │ │ default │ │ │ │ │ │ │ │ docker-compose │ │ docker-compose │ │ docker-compose │ │ medusa-config │ │ medusa-config │ │ medusa-config │ │ .env.example │ │ .env.example │ │ .env.example │ └───────────────────┘ └───────────────────┘ └───────────────────┘ ...and 6 more tenant config reposPros:
- Clean separation of concerns
- Tenant-specific access control (client could see only their config)
- Smaller repos, faster clones
Cons:
- More repositories to manage (10+ repos instead of 1)
- Changes spanning core + config require coordinated commits
- More complex deployment orchestration
- Harder to keep everything in sync
Recommendation
Section titled “Recommendation”| Factor | Option A (Monorepo) | Option B (Multi-Repo) |
|---|---|---|
| Setup complexity | Low | High |
| Ongoing maintenance | Low | Medium |
| Team size fit | 1-10 developers | 10+ developers |
| Code review workflow | Simple (1 PR) | Complex (multiple PRs) |
| Deployment automation | Simple | Requires orchestration |
| Tenant isolation | Medium | High |
| Current team size | Best fit | Overkill for now |
Migration Plan
Section titled “Migration Plan”The migration is divided into 6 phases, designed to be executed safely with minimal downtime. Each phase is independent — if something goes wrong, you can pause and resume later.
Overview
Section titled “Overview” ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ PHASE 1 │───►│ PHASE 2 │───►│ PHASE 3 │───►│ PHASE 4 │ │ GitHub │ │ Clean & │ │ Push to │ │ Branch │ │ Setup │ │ Prepare │ │ GitHub │ │ Strategy │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ ┌──────────┐ ┌──────────┐ │ │ PHASE 6 │◄───│ PHASE 5 │◄────────────────────────┘ │ New Code │ │ Tenant │ │ Workflow │ │ Deploy │ └──────────┘ └──────────┘
┌──────────────────────────────────────────────────────────────┐ │ FUTURE: Phase 7 — CI/CD with GitHub Actions │ │ (Automated testing, building, and deployment on merge) │ └──────────────────────────────────────────────────────────────┘Phase 1 — GitHub Organization & Repository Setup
Section titled “Phase 1 — GitHub Organization & Repository Setup”Goal: Create the GitHub organization and empty repositories.
Time estimate: 30 minutes
-
Create GitHub Organization
Go to github.com/organizations/new and create:
- Organization name:
magiceverse(ormagic-everse) - Plan: Free (sufficient for private repos with small team)
- Owner email:
admin@magiceverse.nl
- Organization name:
-
Create Repositories
Create the following repositories (all private):
Repository Description Visibility magic-commerceMulti-tenant B2B e-commerce platform (Medusa 2.x) Private magic-pimProduct Information Management system Private magic-portalCentral dashboard & tenant manager (React/Vite) Private magic-docsDeveloper documentation (Starlight/Astro) Private Terminal window # Using GitHub CLI (install first if needed: apt install gh)gh auth login# Create organizationgh api orgs -X POST -f login=magiceverse -f billing_email=admin@magiceverse.nl# Create repositoriesgh repo create magiceverse/magic-commerce --private --description "Multi-tenant B2B e-commerce (Medusa 2.x)"gh repo create magiceverse/magic-pim --private --description "Product Information Management"gh repo create magiceverse/magic-portal --private --description "Central dashboard & tenant manager"gh repo create magiceverse/magic-docs --private --description "Developer documentation (Starlight)" -
Set up SSH access on the server
Terminal window # Generate SSH key for the serverssh-keygen -t ed25519 -C "server@magiceverse.online" -f ~/.ssh/github_magiceverse# Add to SSH configcat >> ~/.ssh/config << 'EOF'Host github.comIdentityFile ~/.ssh/github_magiceverseIdentitiesOnly yesEOF# Copy public key and add to GitHub organizationcat ~/.ssh/github_magiceverse.pub# → Add this key at: github.com/organizations/magiceverse/settings/keys -
Install GitHub CLI on the server
Terminal window # Install gh CLIcurl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | \sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpgecho "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | \sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/nullsudo apt update && sudo apt install ghgh auth login
Phase 2 — Clean & Prepare Repositories
Section titled “Phase 2 — Clean & Prepare Repositories”Goal: Add .gitignore files, clean up tracked files, ensure no secrets are committed.
Time estimate: 1-2 hours
-
Create comprehensive
.gitignorefor magic-commerceTerminal window cat > /mnt/data/magic_omniverse/magic_commerce/magic_development/.gitignore << 'GITIGNORE'# ══════════════════════════════════════════════════════# Magic e-VERSE Commerce — .gitignore# ══════════════════════════════════════════════════════# ── Dependencies ──────────────────────────────────────node_modules/.pnp/.pnp.js# ── Build Output ──────────────────────────────────────dist/build/.next/.medusa/.cache/# ── Environment & Secrets ─────────────────────────────.env.env.local.env.*.localbackend/.envstorefront/.env# ── Tenant-Specific Configuration ─────────────────────# These files MUST differ per tenant and should never# be synced. They live in config/tenants/ instead.docker-compose.ymldocker-compose.override.ymlbackend/medusa-config.ts# ── Database & Data Dumps ─────────────────────────────*.sql*.dump*.bak*_export.*# ── Runtime & Logs ────────────────────────────────────*.loglogs/tmp/uploads/backend/public/uploads/# ── OS & IDE ──────────────────────────────────────────.DS_Store._.DS_StoreThumbs.db.vscode/.idea/*.swp*.swo# ── Backups ───────────────────────────────────────────*.bak-*src.bak-*/backups/# ── Package Lock (optional — uncomment to track) ─────# package-lock.jsonGITIGNORE -
Create
.gitignorefor magic-pimTerminal window cat > /mnt/data/magic_pim/.gitignore << 'GITIGNORE'# Magic PIM — .gitignorenode_modules/dist/build/.next/.medusa/.cache/.env.env.local.env.*.localbackend/.envstorefront/.envdocker-compose.ymldocker-compose.override.yml*.sql*.dump*.loguploads/.DS_Store._.DS_Store.vscode/.idea/GITIGNORE -
Audit for secrets currently tracked in git
Terminal window # Check if any .env files are trackedcd /mnt/data/magic_omniversegit ls-files | grep -E '\.env|password|secret|credential|docker-compose\.yml'# If files with secrets are tracked, remove them from tracking# (this removes from git but keeps the file on disk)git rm --cached path/to/secret-file -
Clean up untracked files
Terminal window # Review what's untracked (DO NOT auto-delete)cd /mnt/data/magic_omniversegit status# Move backups to a safe location outside the repomv backups/ /mnt/data/backups_archive/ -
Create the
config/tenants/directory structureTerminal window BASE="/mnt/data/magic_omniverse/magic_commerce/magic_development"mkdir -p "$BASE/config/tenants"TENANTS="magic_development magic_brinxx magic_default magic_demo magic_jodasign magic_logohorloge magic_bovisales magic_desluis magic_spranz"for tenant in $TENANTS; domkdir -p "$BASE/config/tenants/$tenant"TENANT_DIR="/mnt/data/magic_omniverse/magic_commerce/$tenant"# Copy tenant-specific files to config directory[ -f "$TENANT_DIR/docker-compose.yml" ] && \cp "$TENANT_DIR/docker-compose.yml" "$BASE/config/tenants/$tenant/"[ -f "$TENANT_DIR/backend/medusa-config.ts" ] && \cp "$TENANT_DIR/backend/medusa-config.ts" "$BASE/config/tenants/$tenant/"# Create .env.example (stripped of actual secrets)if [ -f "$TENANT_DIR/backend/.env" ]; thensed 's/=.*/=CHANGE_ME/' "$TENANT_DIR/backend/.env" \> "$BASE/config/tenants/$tenant/.env.example"fiecho " Prepared config for $tenant"done -
Commit the clean state
Terminal window cd /mnt/data/magic_omniversegit add .gitignore config/git commit -m "chore: add .gitignore and tenant config structure- Add comprehensive .gitignore to exclude secrets, build artifacts,and tenant-specific runtime files- Create config/tenants/ directory with per-tenant configuration- Prepare for GitHub migration"
Phase 3 — Push to GitHub
Section titled “Phase 3 — Push to GitHub”Goal: Push the existing repositories (with full commit history) to GitHub.
Time estimate: 30-60 minutes (depends on upload speed)
-
Connect magic_development to GitHub
Terminal window cd /mnt/data/magic_omniverse/magic_commerce/magic_development# Rename local remote for claritygit remote rename origin local-bare# Add GitHub as the new origingit remote add origin git@github.com:magiceverse/magic-commerce.git# Verify remotesgit remote -v# Should show:# local-bare /mnt/data/magic_omniverse/magic_commerce.git (fetch)# local-bare /mnt/data/magic_omniverse/magic_commerce.git (push)# origin git@github.com:magiceverse/magic-commerce.git (fetch)# origin git@github.com:magiceverse/magic-commerce.git (push) -
Rename master to main (GitHub standard)
Terminal window git branch -m master main -
Push to GitHub
Terminal window # Push main branch with full historygit push -u origin main# Push all existing feature/fix branchesgit push origin --all -
Repeat for Magic PIM
Terminal window cd /mnt/data/magic_pimgit remote add origin git@github.com:magiceverse/magic-pim.gitgit branch -m master main # or main alreadygit push -u origin main -
Repeat for Magic Portal
Terminal window cd /mnt/data/magic_omniverse/magic_portalgit remote add origin git@github.com:magiceverse/magic-portal.gitgit branch -m master maingit push -u origin main -
Repeat for Magic Docs
Terminal window cd /mnt/data/magic_omniverse/magic_docs/starlightgit remote add origin git@github.com:magiceverse/magic-docs.gitgit branch -m master maingit push -u origin main -
Verify on GitHub
Visit
github.com/magiceverseand confirm:- All 4 repositories are visible
- Commit history is intact
- No
.envor secret files are visible .gitignoreis present
Phase 4 — Branching Strategy
Section titled “Phase 4 — Branching Strategy”Goal: Establish a clear branching model for development and releases.
BRANCHING MODEL ═══════════════
main ─────●─────●─────●─────●─────●─────●─────●─────► │ ↑ │ ↑ │ │ merge │ │merge│ │ │ │ │ │ │ feature/ └───●───●───┘ │ │ └───●───●── ... PROJ-0025 add test │ │ new invoice it │ │ feature │ │ fix/ ──────────────────────└──●──┘ FIX-0003 quick fix
hotfix/ (for urgent production fixes — branch from main, merge back immediately)Branch naming conventions:
| Branch Pattern | Purpose | Example |
|---|---|---|
main | Stable, production-ready code | Always deployable |
feature/PROJ-XXXX-description | New features | feature/PROJ-0025-invoice-module |
fix/FIXNNNN-description | Bug fixes | fix/FIX0003-cart-calculation |
hotfix/description | Urgent production fixes | hotfix/login-crash |
tenant/name | Tenant-specific customizations (if needed) | tenant/brinxx-custom-pricing |
Rules:
- Never commit directly to
main— always use a branch + Pull Request - Delete branches after merge — keeps the repo clean
- Write meaningful commit messages — explain why, not just what
- Use the existing
PROJ-XXXXnumbering from the Dev Projects system
-
Protect the main branch on GitHub
Terminal window # Using GitHub CLIgh api repos/magiceverse/magic-commerce/branches/main/protection \-X PUT \-f required_pull_request_reviews='{"required_approving_review_count":1}' \-F enforce_admins=false \-f required_status_checks='null' \-f restrictions='null'Or in GitHub web UI:
- Go to
Settings → Branches → Add branch protection rule - Branch name pattern:
main - Enable: “Require a pull request before merging”
- Enable: “Require approvals” (at least 1)
- Go to
-
Set up commit message template
Terminal window # Create commit message templatecat > /mnt/data/magic_omniverse/magic_commerce/magic_development/.gitmessage << 'EOF'# Format: type(scope): description## Types: feat, fix, refactor, docs, chore, style, test# Scope: backend, storefront, admin, api, config, theme## Examples:# feat(admin): add invoice PDF export# fix(api): correct cart total calculation# refactor(backend): simplify order processing module# chore(config): update Docker ports for spranz tenantEOFgit config commit.template .gitmessage
Phase 5 — Tenant Deployment from Git
Section titled “Phase 5 — Tenant Deployment from Git”Goal: Replace the manual cp/rsync workflow with a Git-based deployment to all tenants.
Time estimate: 2-3 hours
This is the most impactful phase — it replaces the current manual copy workflow with a clean, repeatable, Git-based approach.
New Deployment Architecture
Section titled “New Deployment Architecture” GitHub (magiceverse/magic-commerce) ┌──────────────────────────────────┐ │ main branch │ │ (shared backend + storefront) │ └───────────────┬──────────────────┘ │ │ git pull origin main │ ▼ Server: /mnt/data/magic_commerce_shared/ ┌──────────────────────────────────┐ │ Single checkout of shared code │ │ ├── backend/src/ │ │ ├── storefront/src/ │ │ └── config/tenants/ │ └───────────────┬──────────────────┘ │ │ deploy-tenant.sh (symlinks or rsync) │ ┌────────────┼────────────┬────────────┐ │ │ │ │ ▼ ▼ ▼ ▼ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ dev │ │ brinxx │ │default │ │ ... │ │tenant │ │ tenant │ │ tenant │ │tenants │ │(Docker)│ │(Docker)│ │(Docker)│ │(Docker)│ └────────┘ └────────┘ └────────┘ └────────┘-
Create the shared code directory
Terminal window # Clone from GitHub into a new shared locationcd /mnt/datagit clone git@github.com:magiceverse/magic-commerce.git magic_commerce_shared# This becomes the SINGLE SOURCE for all tenant deployments -
Create the deployment script
cat > /mnt/data/magic_commerce_shared/scripts/deploy-tenant.sh << 'SCRIPT'#!/bin/bash# ══════════════════════════════════════════════════════# Magic e-VERSE — Deploy shared code to a tenant# ══════════════════════════════════════════════════════set -eSHARED="/mnt/data/magic_commerce_shared"COMMERCE="/mnt/data/magic_omniverse/magic_commerce"TENANT="${1:?Usage: deploy-tenant.sh <tenant_name>}"TENANT_DIR="$COMMERCE/$TENANT"DATE=$(date +%Y%m%d-%H%M)if [ ! -d "$TENANT_DIR" ]; thenecho "ERROR: Tenant directory not found: $TENANT_DIR"exit 1fiecho "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"echo " Deploying to: $TENANT"echo " Source: $SHARED ($(cd $SHARED && git log --oneline -1))"echo " Date: $DATE"echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"# Step 1: Sync backend source codeecho "[1/5] Syncing backend source code..."rsync -av --delete \--exclude='node_modules' \--exclude='.medusa' \--exclude='dist' \"$SHARED/backend/src/" "$TENANT_DIR/backend/src/"# Step 2: Sync storefront source codeecho "[2/5] Syncing storefront source code..."rsync -av --delete \--exclude='node_modules' \--exclude='.next' \--exclude='dist' \"$SHARED/storefront/src/" "$TENANT_DIR/storefront/src/"# Step 3: Sync package files (if changed)echo "[3/5] Syncing package files..."cp "$SHARED/backend/package.json" "$TENANT_DIR/backend/package.json"cp "$SHARED/storefront/package.json" "$TENANT_DIR/storefront/package.json"cp "$SHARED/backend/Dockerfile" "$TENANT_DIR/backend/Dockerfile"cp "$SHARED/storefront/Dockerfile" "$TENANT_DIR/storefront/Dockerfile"# Step 4: Apply tenant-specific config (if exists in config/tenants/)TENANT_CONFIG="$SHARED/config/tenants/$TENANT"if [ -d "$TENANT_CONFIG" ]; thenecho "[4/5] Applying tenant config from config/tenants/$TENANT..."[ -f "$TENANT_CONFIG/docker-compose.yml" ] && \cp "$TENANT_CONFIG/docker-compose.yml" "$TENANT_DIR/docker-compose.yml"[ -f "$TENANT_CONFIG/medusa-config.ts" ] && \cp "$TENANT_CONFIG/medusa-config.ts" "$TENANT_DIR/backend/medusa-config.ts"elseecho "[4/5] No tenant config found, skipping..."fi# Step 5: Rebuild Docker containersecho "[5/5] Rebuilding Docker containers..."cd "$TENANT_DIR"docker compose build backend storefrontdocker compose up -d backend storefrontecho ""echo " ✓ $TENANT deployed successfully"echo " Commit: $(cd $SHARED && git log --oneline -1)"echo ""SCRIPTchmod +x /mnt/data/magic_commerce_shared/scripts/deploy-tenant.sh -
Create the deploy-all script
cat > /mnt/data/magic_commerce_shared/scripts/deploy-all.sh << 'SCRIPT'#!/bin/bash# ══════════════════════════════════════════════════════# Magic e-VERSE — Deploy to ALL tenants# ══════════════════════════════════════════════════════set -eSHARED="/mnt/data/magic_commerce_shared"SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"# Pull latest from GitHub firstecho "╔══════════════════════════════════════════╗"echo "║ Magic e-VERSE — Full Deployment ║"echo "╚══════════════════════════════════════════╝"echo ""echo "Pulling latest from GitHub..."cd "$SHARED"git pull origin mainecho "Current commit: $(git log --oneline -1)"echo ""TENANTS="magic_development magic_brinxx magic_default magic_demo magic_jodasign magic_logohorloge magic_bovisales magic_desluis magic_spranz"FAILED=""for tenant in $TENANTS; doecho ""echo "┌─── Deploying: $tenant ─────────────────────"if "$SCRIPT_DIR/deploy-tenant.sh" "$tenant"; thenecho "└─── ✓ $tenant complete ────────────────────"elseecho "└─── ✗ $tenant FAILED ──────────────────────"FAILED="$FAILED $tenant"fidoneecho ""echo "╔══════════════════════════════════════════╗"if [ -z "$FAILED" ]; thenecho "║ ✓ ALL TENANTS DEPLOYED SUCCESSFULLY ║"elseecho "║ ⚠ SOME TENANTS FAILED: ║"echo "║ $FAILED"fiecho "║ ║"echo "║ Commit: $(git log --oneline -1) ║"echo "╚══════════════════════════════════════════╝"SCRIPTchmod +x /mnt/data/magic_commerce_shared/scripts/deploy-all.sh -
Create the git-pull-and-deploy workflow
cat > /mnt/data/magic_commerce_shared/scripts/update.sh << 'SCRIPT'#!/bin/bash# Quick update: pull latest code and deploy to specified tenants# Usage: ./update.sh [tenant1 tenant2 ...] or ./update.sh --allSHARED="/mnt/data/magic_commerce_shared"SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"cd "$SHARED"echo "Pulling latest from GitHub..."git pull origin mainecho "Latest commit: $(git log --oneline -1)"echo ""if [ "$1" = "--all" ]; then"$SCRIPT_DIR/deploy-all.sh"elif [ $# -gt 0 ]; thenfor tenant in "$@"; do"$SCRIPT_DIR/deploy-tenant.sh" "$tenant"doneelseecho "Usage:"echo " ./update.sh --all Deploy to all tenants"echo " ./update.sh magic_brinxx Deploy to specific tenant(s)"echo " ./update.sh magic_brinxx magic_demo"fiSCRIPTchmod +x /mnt/data/magic_commerce_shared/scripts/update.sh
Phase 6 — New Development Workflow
Section titled “Phase 6 — New Development Workflow”Goal: Establish the day-to-day workflow for making changes using Git.
Daily Workflow
Section titled “Daily Workflow” NEW DEVELOPMENT WORKFLOW ═══════════════════════
Developer (on server or local machine) ──────────────────────────────────────
1. git pull origin main ◄── Get latest code 2. git checkout -b feature/PROJ-XXXX ◄── Create feature branch 3. ... make changes ... ◄── Write code 4. git add -p ◄── Stage changes (review each) 5. git commit -m "feat(admin): ..." ◄── Commit with clear message 6. git push origin feature/PROJ-XXXX ◄── Push branch to GitHub 7. Open Pull Request on GitHub ◄── Request review 8. Review & approve ◄── Team reviews the diff 9. Merge into main ◄── PR merged 10. Deploy to tenants ◄── Run update.sh
┌─────────────────────────────────────────────────────────────┐ │ KEY RULE: All changes flow through Pull Requests. │ │ No direct pushes to main. No more manual file copying. │ └─────────────────────────────────────────────────────────────┘-
Starting new work
Terminal window cd /mnt/data/magic_commerce_shared# Make sure you're up to dategit checkout maingit pull origin main# Create a new branch for your workgit checkout -b feature/PROJ-0030-credit-notes -
Making changes and committing
Terminal window # After making changes...git status # See what changedgit diff # Review the actual changesgit add backend/src/api/admin/aplt/credit-notes/ # Stage specific filesgit commit -m "feat(admin): add credit note generation- Add POST /admin/aplt/credit-notes endpoint- Add credit note PDF template- Add admin UI route for credit note management" -
Push and create Pull Request
Terminal window git push origin feature/PROJ-0030-credit-notes# Create PR using GitHub CLIgh pr create \--title "feat: Add credit note generation (PROJ-0030)" \--body "## Changes- New credit note API endpoint- PDF generation with template- Admin UI for management## Testing- [ ] Create credit note from order- [ ] Generate PDF- [ ] View in admin panel" -
After PR is merged — deploy to tenants
Terminal window # Pull the merged changescd /mnt/data/magic_commerce_sharedgit checkout maingit pull origin main# Deploy to specific tenant for testing first./scripts/deploy-tenant.sh magic_development# Test on development tenant...# If everything works, deploy to all./scripts/deploy-all.sh
Phase 7 (Future) — CI/CD with GitHub Actions
Section titled “Phase 7 (Future) — CI/CD with GitHub Actions”Goal: Automate testing and deployment using GitHub Actions.
Planned Pipeline
Section titled “Planned Pipeline” CI/CD PIPELINE (Future) ═══════════════════════
Push to branch Open Pull Request Merge to main ───────────── ────────────────── ───────────── │ │ │ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Lint & │ │ Build │ │ Deploy │ │ Type │ │ Check │ │ to all │ │ Check │ │ (Docker) │ │ tenants │ └──────────┘ └──────────┘ └──────────┘ │ │ │ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Unit │ │ Preview │ │ Health │ │ Tests │ │ Comment │ │ Check │ │ (if any) │ │ on PR │ │ (curl) │ └──────────┘ └──────────┘ └──────────┘Example GitHub Actions Workflow (for reference)
Section titled “Example GitHub Actions Workflow (for reference)”name: Deploy to Tenants
on: push: branches: [main]
jobs: deploy: runs-on: self-hosted # Runs on your server steps: - name: Pull latest code run: | cd /mnt/data/magic_commerce_shared git pull origin main
- name: Deploy to development (canary) run: | /mnt/data/magic_commerce_shared/scripts/deploy-tenant.sh magic_development
- name: Health check development run: | sleep 10 curl -f https://admin-development.magiceverse.online/health || exit 1
- name: Deploy to all tenants run: | /mnt/data/magic_commerce_shared/scripts/deploy-all.sh
- name: Notify on success run: echo "Deployment complete for commit ${{ github.sha }}"Self-Hosted Runner Setup (Future)
Section titled “Self-Hosted Runner Setup (Future)”# Install GitHub Actions runner on your servermkdir /opt/actions-runner && cd /opt/actions-runnercurl -o actions-runner-linux-x64.tar.gz -L \ https://github.com/actions/runner/releases/download/v2.XXX/actions-runner-linux-x64-2.XXX.tar.gztar xzf actions-runner-linux-x64.tar.gz./config.sh --url https://github.com/magiceverse --token YOUR_TOKENsudo ./svc.sh installsudo ./svc.sh startComplete Migration Checklist
Section titled “Complete Migration Checklist”Pre-Migration Checklist
Section titled “Pre-Migration Checklist”┌────────────────────────────────────────────────────────────────────┐│ PRE-MIGRATION CHECKLIST │├────────────────────────────────────────────────────────────────────┤│ ││ PREPARATION ││ [ ] Full server backup completed (all /mnt/data/) ││ [ ] Database backups completed for all tenant databases ││ [ ] Disk space verified (df -h — need ~5GB free) ││ [ ] No active development in progress ││ [ ] All tenants are currently stable and running ││ [ ] Team has been informed of the migration ││ ││ ACCOUNTS & ACCESS ││ [ ] GitHub account created / available ││ [ ] Credit card on file (if using paid features) ││ [ ] SSH key generated for server ││ [ ] GitHub CLI installed on server ││ ││ CODE AUDIT ││ [ ] No .env files or secrets in git history ││ [ ] .gitignore created and tested ││ [ ] docker-compose.yml files are NOT tracked ││ [ ] medusa-config.ts tenant-specific values identified ││ [ ] All tenant configurations backed up to config/tenants/ ││ │└────────────────────────────────────────────────────────────────────┘Post-Migration Checklist
Section titled “Post-Migration Checklist”┌────────────────────────────────────────────────────────────────────┐│ POST-MIGRATION CHECKLIST │├────────────────────────────────────────────────────────────────────┤│ ││ GITHUB VERIFICATION ││ [ ] All 4 repositories visible on github.com/magiceverse ││ [ ] Commit history is complete and intact ││ [ ] No secrets visible in any repository ││ [ ] Branch protection rules enabled on main branches ││ [ ] SSH access from server to GitHub works (ssh -T git@github.com)││ ││ REPOSITORY VERIFICATION ││ [ ] magic-commerce: all backend/src files present ││ [ ] magic-commerce: all storefront/src files present ││ [ ] magic-commerce: config/tenants/ contains all 9 tenant configs ││ [ ] magic-pim: all files present ││ [ ] magic-portal: all files present ││ [ ] magic-docs: documentation site builds correctly ││ ││ DEPLOYMENT VERIFICATION ││ [ ] deploy-tenant.sh works for magic_development ││ [ ] deploy-tenant.sh works for magic_brinxx ││ [ ] deploy-all.sh completes without errors ││ [ ] All 9 tenant admin UIs are accessible ││ [ ] All 9 tenant storefronts are accessible ││ [ ] PIM system is unaffected and running ││ [ ] beta.brinxx.nl is accessible and functional ││ ││ WORKFLOW VERIFICATION ││ [ ] Can create branch, commit, push, and open PR ││ [ ] Can merge PR and pull changes on server ││ [ ] Deploy scripts correctly sync code after pull ││ [ ] Old local bare repo preserved as backup (do not delete yet) ││ │└────────────────────────────────────────────────────────────────────┘Rollback Plan
Section titled “Rollback Plan”If the migration causes issues, every phase is individually reversible:
Phase 1-3 Rollback (GitHub push failed or secrets exposed)
Section titled “Phase 1-3 Rollback (GitHub push failed or secrets exposed)”# If secrets were accidentally pushed — delete the repo and recreategh repo delete magiceverse/magic-commerce --yes# Then fix the issue and re-push
# Local repos are untouched — GitHub is just a copy# Remove the GitHub remote if needed:git remote remove origin# Re-add the original local bare repo:git remote add origin /mnt/data/magic_omniverse/magic_commerce.gitPhase 5 Rollback (Deployment script broke a tenant)
Section titled “Phase 5 Rollback (Deployment script broke a tenant)”# The original tenant directories still exist with their code# The deploy script only overwrites src/ directories
# Option 1: Restore from git historycd /mnt/data/magic_omniverse/magic_commerce/magic_brinxxgit checkout HEAD -- backend/src/ storefront/src/docker compose build backend storefrontdocker compose up -d backend storefront
# Option 2: Restore from the local bare repocd /mnt/data/magic_omniverse/magic_commerce/magic_brinxxgit fetch local-baregit checkout local-bare/master -- backend/src/docker compose build backend && docker compose up -d backendFull Rollback (Abandon migration)
Section titled “Full Rollback (Abandon migration)”# The old workflow still works — nothing was deleted# Simply stop using GitHub and go back to manual copy workflow# Remove GitHub remotes from all repos:for dir in magic_development magic_brinxx magic_pim; do cd "/mnt/data/magic_omniverse/magic_commerce/$dir" 2>/dev/null || \ cd "/mnt/data/$dir" 2>/dev/null git remote remove origin 2>/dev/null git remote rename local-bare origin 2>/dev/null echo "Restored: $dir"doneQuick Reference — Common Git Commands
Section titled “Quick Reference — Common Git Commands”For daily use after migration:
# ── Status & Information ──────────────────────git status # What files changed?git log --oneline -10 # Last 10 commitsgit diff # See unstaged changesgit diff --staged # See staged changes
# ── Branching ─────────────────────────────────git checkout main # Switch to main branchgit pull origin main # Get latest from GitHubgit checkout -b feature/name # Create new branchgit branch -d feature/name # Delete merged branch
# ── Committing ────────────────────────────────git add path/to/file # Stage specific filegit add -p # Stage interactively (review each change)git commit -m "type: message" # Commit staged changesgit push origin branch-name # Push branch to GitHub
# ── Pull Requests (via GitHub CLI) ────────────gh pr create --title "..." # Create PR from current branchgh pr list # List open PRsgh pr merge 42 # Merge PR #42gh pr view 42 --web # Open PR in browser
# ── Deployment ────────────────────────────────./scripts/update.sh --all # Pull + deploy all./scripts/update.sh magic_brinxx # Pull + deploy one./scripts/deploy-tenant.sh magic_brinxx # Deploy without pull
# ── Emergency ─────────────────────────────────git revert HEAD # Undo last commit (creates new commit)git stash # Temporarily shelve changesgit stash pop # Restore shelved changesTimeline & Effort Summary
Section titled “Timeline & Effort Summary”| Phase | Description | Effort | Risk | Dependencies |
|---|---|---|---|---|
| Phase 1 | GitHub org & repos | 30 min | Low | GitHub account |
| Phase 2 | Clean & .gitignore | 1-2 hours | Medium | Phase 1 |
| Phase 3 | Push to GitHub | 30-60 min | Medium | Phase 2 |
| Phase 4 | Branch strategy | 30 min | Low | Phase 3 |
| Phase 5 | Deployment scripts | 2-3 hours | Medium | Phase 3 |
| Phase 6 | New workflow | Ongoing | Low | Phase 4+5 |
| Phase 7 | CI/CD (future) | 4-8 hours | Low | Phase 6 stable |
Total initial effort: ~5-7 hours (Phases 1-6)
Related Documentation
Section titled “Related Documentation”- Tenant Architecture — How multi-tenancy works
- Code Distribution — Current distribution workflow (being replaced)
- Docker Setup — Container infrastructure
- Development Workflow — Development process
- Deployment — Container rebuild procedures
- Brinxx Code Sync — Example of current sync process (being replaced)