🚗 Hantoor · Project Management
Mission control for the Hantoor platform
No product code — just the map of every repo, the initiatives we’re driving, and the tickets we’re tracking across them.
NOTE
Hantoor is a car-rental platform connecting providers (rental agencies and individual car owners) with renters. The product is split across several repositories — this one coordinates them.
🧭 At a glance
| 🗂️ Registry | config/projects.yml — every repo’s URL, local path & metadata |
| 🎯 Initiatives | initiatives/ — cross-cutting goals, one folder each |
| 🎫 Ticket boards | tracking/tickets/ — status of each repo’s tickets |
| 📊 Portfolio view | tracking/initiatives.md — all initiatives at once |
| 🗂️ Repo state | tracking/repos.md — latest commit + date per repo, and when it was last synced |
| 🤖 Agent skills | .claude/skills/ — 7 slash commands (see below) |
| 📖 How Claude works here | CLAUDE.md |
🌐 The ecosystem
flowchart TD L["🖥️ landing<br/><i>marketing site</i>"] M["📱 mobile · hantoor-kmp<br/><i>Android / iOS</i>"] D["🧑💼 dashboard<br/><i>admin + provider web</i>"] W["🌐 web · hantoor-web<br/><i>renter marketplace</i>"] X["🏷️ white-label · hantoor-web-white-label<br/><i>provider storefronts (single-tenant trial → multi-tenant)</i>"] B[("⚙️ backend<br/><i>GraphQL API + PostgreSQL</i>")] M -->|GraphQL| B D -->|GraphQL| B W -->|GraphQL| B X -->|GraphQL| B
| Key | Repo | Role | Status |
|---|---|---|---|
backend | hantoor-backend | Kotlin / Spring Boot GraphQL API | 🟢 active |
mobile | hantoor-kmp | KMP + Compose MP app (Android/iOS) | 🟢 active |
dashboard | hantoor-dashboard | Admin / provider web dashboard | 🟢 active |
landing | hantoor-landing | Marketing landing page | 🟢 active |
web | hantoor-web | Renter web marketplace (host TBD — see the initiative) | 🟢 active |
white-label | hantoor-web-white-label | White-label provider booking storefronts (single-tenant Najeb trial; being evolved into the multi-tenant template, decided 2026-10-06) | 🟢 active |
TIP
Other repos (
hantoor-demos,hantoor-androidlegacy,hantoor-creative-content,hantoor-vehicle-image-catalog) live indocs/ecosystem.mdand can be registered when we want to track them.
🎯 Initiatives & 🎫 tickets — how work is tracked
Two altitudes, both file-based in git:
- Initiative — a goal spanning one or more repos (a launch, a feature program,
an ops rescue). One folder under
initiatives/: a charter (initiative.md), a livingtracker.md(milestones, linked tickets, log), and optionaldocs/. Lifecycle:proposed → active → blocked → done(+parked,cancelled). - Ticket — an implementation-level spec that lives in each repo’s own
docs/tickets/(ticket-<n>-<slug>.md). The coordinator never duplicates it — it mirrors only the status on ticket boards, keyed by<project-key>#<number>(e.g.backend#19).
flowchart LR A["📝 create-ticket<br/><i>author into a repo</i>"] --> B["🔄 sync-tickets<br/><i>reconcile boards</i>"] B --> C["🎯 track-initiative<br/><i>link across repos</i>"] C --> D["⛴️ sync-initiatives<br/><i>infer progress from main</i>"] D --> E["📊 program-status<br/><i>one-glance snapshot</i>"] E -.-> A
🤖 Agent skills
Run from Claude Code inside this repo as /name:
| Skill | What it does |
|---|---|
/create-ticket | Draft a ticket and write it into a linked project’s docs/tickets/ (following that repo’s convention), then register it on the board |
/sync-tickets | Reconcile the boards against each repo’s docs/tickets/ — add new, flag removed, never clobber a set status |
/track-initiative | Scaffold / update an initiative folder and link tickets across repos |
/sync-initiatives | Review what merged to main in each linked repo and propose milestone / ticket / initiative status updates |
/program-status | One-shot snapshot: git state + ticket counts + active initiatives |
/skills-catalog | Show a catalog of available skills — this repo’s, or all to include every linked project’s |
/refresh-docs | Reconcile the README, docs/ecosystem.md, badges & indexes with the sources of truth (run after adding a project/skill/initiative) |
🗂️ What lives here
hantoor-project-management/
├── config/
│ ├── projects.yml # THE registry: repo URL + local path + metadata
│ └── taxonomy.yml # initiative type + tag vocabularies
├── initiatives/ # cross-cutting efforts, one FOLDER each
│ ├── README.md # lifecycle + index
│ ├── TEMPLATE/ # copy to start a new initiative
│ └── <slug>/ # initiative.md (charter) + tracker.md + docs/
├── tracking/
│ ├── initiatives.md # portfolio roll-up across all initiatives
│ ├── repos.md # GENERATED: last-known git state per repo
│ └── tickets/ # per-project status boards
├── docs/ecosystem.md # deeper map of how the repos fit together
├── scripts/
│ ├── status.sh # live git status across all local repos
│ ├── repo-state.sh # regenerate tracking/repos.md
│ └── build-site.sh # build the browsable docs site (Quartz)
├── site/ # docs-site config + staging script
├── .claude/skills/ # the 7 agent skills above
├── CLAUDE.md # how Claude Code operates as program manager here
└── README.md # you are here
⚡ Quick start
See the state of everything at once — branch, dirty files, ticket count & last commit for every registered repo on this machine:
./scripts/status.shRecord it — refresh tracking/repos.md, the committed
snapshot of each project’s latest commit, its date, and when the coordinator
last synced that repo:
./scripts/repo-state.sh --fetchBrowse it as a website — the same Markdown, rendered with search, a folder
sidebar, backlinks and a link graph (built by Quartz;
deployed to Cloudflare Pages on every push to main). Local preview on
http://localhost:8080:
./scripts/build-site.sh --serveDrive it from Claude Code — open this repo and use the skills above. Claude
reads config/projects.yml to resolve where each project lives, and prefers
subagents for work that spans multiple repos.
📐 Conventions
- This repo tracks and coordinates; it never contains product source.
config/projects.ymlis the only place local paths are defined.local_diris relative toworkspace_root— editworkspace_rootwhen you change machines, nothing else.- One initiative = one folder. Keep it short; link out to the real work.
- Status is set by humans/Claude. The sync skills propose from git, they never flip a status silently.