Map App Harness is a multi-tenant business-operations platform built around one idea:
- tenants should get a fast, beautiful, useful workspace now
- the platform should keep getting more self-serve, reusable, and configurable with each tenant
Externally, this product is sold as opinionated vertical workspaces. Internally, it is being architected as a harness that composes tenant workspaces from canonical data, reusable primitives, packages, and portable workspace definitions.
PICC is the first tenant. FraterniTees is the second. Neither tenant is the product.
The repo now separates tenant-specific setup from tenant type defaults:
- FraterniTees has tenant type
Screenprinting - PICC has tenant type
Cannabis Wholesale - tenant type docs define universal industry defaults
- tenant docs define one tenant's decisions, credentials, exceptions, rollout notes, and acceptance checks
The next durable version of this repo is not "a CRM with tenant forks." It is:
- a canonical runtime for accounts, contacts, orders, activities, locations, and documents
- a map/list/detail shell that can serve multiple verticals
- tenant-installed adapters and packages
- tenant workspace definitions that stay portable and text-native
- a change system that can translate tenant requests into safe config/package changes
The governing test for new platform work is simple:
Does this make tenant #10 more likely to onboard and keep moving without founder involvement?
If the answer is no, it is probably the wrong abstraction or the wrong slice.
The repo already contains working product surfaces, not just scaffolding:
- shared login and tenant routing
- self-serve onboarding for tenant-type workspace definitions
- self-serve domain handoff for bootstrap-created workspaces
- runtime-backed territory map and accounts surfaces
- shared account detail page
- workspace-driven navigation and integration surfaces
- in-app screen-comment change capture with annotated screenshots and queue visibility
- PICC-specific PPP savings and mock-order proposal workflows
- FraterniTees-specific Printavo onboarding, sync, verified daily auto-sync, lead scoring, tabbed accounts workspace, top-customer spend analysis, and mobile-ready map/account experiences
- first-class workspace/package manifests under
tenants/andpackages/ - first-class tenant type manifests under
tenant-types/ - first primitive components for scorecards, filter bars, and trend panels
- tenant-scoped integration state and plugin toggles
- runtime APIs for territory, accounts, sync jobs, geocoding, and tenant integrations
The repo is also mid-transition:
- most shared auth/session and route-scoping now run through generic tenant session cookies and workspace manifests
- tenant differences still exist in some shared code paths, but the remaining work is now concentrated in reusable primitive/read-model extraction rather than tenant-specific login/session hacks
- the primitive catalog is only partially extracted into reusable runtime components
- workspace/package manifests exist but not every tenant behavior is driven by them yet
- the change-request system exists, but preview/policy automation is still next
- onboarding exists, but connector depth is still uneven across tenant types and workspaces
- onboarding is email-domain based today, not verified-domain based
That is the main architectural work now.
Supabase Postgresis the operational source of truth for runtime readsClerkremains the auth layer- user-facing surfaces read local runtime data, not live provider payloads
- provider credentials are organization-scoped and encrypted
- tenant-facing provider resolution must never fall back to shared/global paid API keys
- change requests are a core tenant capability and are normalized on for every compiled workspace, not a per-workspace optional feature
- shared multi-tenant is the default topology today
- tenant-specific behavior should move toward workspace config, packages, and read-model compilation rather than shared-code branching
- tenant type behavior should be documented and configured above individual tenants so a competitor in the same industry can inherit the same default operating model without a fork
The target platform shape has seven major layers:
- canonical data layer
- primitive layer
- package layer
- tenant type definition layer
- tenant workspace definition layer
- compiled read-model/runtime layer
- tenant change-request system
- control plane for installs, policies, releases, and auditability
See the docs below for the detailed plan.
- docs/HANDOFF.md
- docs/GLOSSARY.md
- docs/STATUS.md
- docs/AUTONOMOUS_PRODUCT_BUILD.md
- docs/WORK_REGISTRY.md
- docs/WORK_REGISTRY.json
- docs/DEFINITION_OF_DONE.md
- docs/ARCHITECTURE_RUNWAY.md
- docs/DATA_MODEL.md
- docs/API_CONTRACTS.md
- docs/ACCEPTANCE_AND_FIXTURES.md
- docs/ENVIRONMENT_AND_DEPLOYMENT_POLICY.md
- docs/MIGRATION_SAFETY.md
- docs/tenant-types/SCHEMA.md
- docs/AGENT_CONCURRENCY.md
- docs/AGENT_PROMPT_TEMPLATE.md
- docs/STRATEGY.md
- docs/PLATFORM_SPEC.md
- docs/ARCHITECTURE.md
- docs/WORKSPACE_MODEL.md
- docs/tenant-types/README.md
- docs/PRIMITIVE_CATALOG.md
- docs/ONBOARDING.md
- docs/CHANGE_SYSTEM.md
- docs/IMPLEMENTATION_PLAN.md
- docs/ROADMAP.md
- docs/TODO.md
- docs/VERIFICATION_STRATEGY.md
- docs/AUTONOMOUS_EXECUTION.md
- docs/SETUP.md
- docs/OPERATING_ENVIRONMENT.md
Tenant type material lives under docs/tenant-types/<type>/. Tenant-specific migration and requirements material lives under docs/tenants/<org>/.
- Install dependencies
npm install- Copy the environment template
cp .env.example .env.local-
Fill in
.env.localusing docs/SETUP.md -
Run the app
npm run devBaseline repo verification:
npm run check:work-registry
npm run verifyIf you have a local server running and want runtime smoke checks too:
SMOKE_BASE_URL=http://localhost:3000 npm run verifyIf you want browser-level verification too against a deployed URL, use:
SMOKE_BASE_URL=http://localhost:3000 PLAYWRIGHT_VERIFY=1 npm run verifyIf you want browser-level verification against a local production server, do not rebuild while that server is already running. Use:
npm run build
npm run start -- --port 3000
SMOKE_BASE_URL=http://127.0.0.1:3000 npm run smoke:runtime
SMOKE_BASE_URL=http://127.0.0.1:3000 PLAYWRIGHT_VERIFY=1 npm run verify:browsernpm run mapapp -- health check <org-slug> # tenant migration preflight, not generic repo verification
npm run mapapp -- migration dry-run <org-slug>
npm run mapapp -- migration validate <org-slug>
npm run seed:runtime