The Module Registry — two tables, two vocabularies
Validated against the live DB on 2026-09-06.
Koovira is a multi-module platform. There are two separate registries, and they use different keys for the same real-world module. Confusing them is the single most common mistake when working across modules. Read this before touching any cross-module code.
| Table | Rows | Role |
|---|---|---|
kv_module_control | 22 | The consumer/platform on-off + visibility control plane. "Is this module live, visible, customer-accessible, in search, in the app?" |
kv_module_registry | 23 | The merchant enrollment-type catalogue. "What kinds of business can sign up?" |
kv_module_control (22 rows) — the control plane
Columns (validated): module_key, module_label, level enum(A,B,C), always_on, master_status, frontend_visibility, customer_access, merchant_enrollment, merchant_setup, existing_operations, myaccount_visibility, search_visibility, policy_visibility, app_visibility, api_access, launch_message, plus audit columns (changed_by, reason, changed_at).
Each tinyint(1) flag is an independent gate. A module can be master_status=1 (on) but frontend_visibility=0 (dark) — exactly the case for universal_entry below.
Live rows (module_key → label, level, key flags), 2026-09-06:
| module_key | label | level | always_on | master_status | frontend_vis | customer_access | merchant_enroll |
|---|---|---|---|---|---|---|---|
business_suite | Koovira Business Suite | B | Yes | Yes | Yes | Yes | Yes |
startup_passport | Startup Passport | B | Yes | Yes | Yes | Yes | Yes |
mobile_app_download_banner | Mobile App Download Banner | C | No | Yes | Yes | Yes | Yes |
real_estate | Real Estate / RealtyVerse | C | No | Yes | Yes | Yes | Yes |
classifieds | Classifieds | C | No | Yes | Yes | Yes | Yes |
cab_bike | Cab & Bike / RideMate | C | No | Yes | Yes | Yes | Yes |
ecommerce | E-commerce / CommerX | C | No | Yes | Yes | Yes | Yes |
dating | Dating | C | No | Yes | Yes | Yes | Yes |
jobs | Employer / Jobs | C | No | Yes | Yes | Yes | Yes |
business_profiles | Business Profiles | C | No | Yes | Yes | Yes | Yes |
business_directory | Business Directory | C | No | Yes | Yes | Yes | Yes |
homeassist | HomeAssist / Services | C | No | Yes | Yes | Yes | Yes |
events | Events | C | No | Yes | Yes | Yes | Yes |
hotels | Hotels & StayGo | C | No | Yes | Yes | Yes | Yes |
food | Restaurant / Food | C | No | Yes | Yes | Yes | Yes |
trip_planner | Trip Planner | C | No | Yes | Yes | Yes | Yes |
freelancer | Freelancer Marketplace | C | No | Yes | Yes | Yes | Yes |
packers_movers | Truck / Transport / Packers & Movers | C | No | Yes | Yes | Yes | Yes |
hyperlocal | Hyperlocal | C | No | Yes | Yes | Yes | Yes |
courier | Courier Delivery | C | No | Yes | Yes | Yes | Yes |
universal_entry | Universal Entry Layer | A | No | Yes | No | No | No |
investor_vc | Investor / VC | C | No | Yes | Yes | Yes | Yes |
Note universal_entry: master_status=Yes but frontend_visibility=No / customer_access=No — on, but dark. Its behavior is documented in the Universal Entry / Radar module page.
Each flag is stored as tinyint(1) in the DB (1/0); shown here as Yes/No for readability.
Levels: A = platform layer (universal entry), B = always-on suite features (business suite, startup passport), C = the switchable verticals. always_on=Yes rows cannot be turned off from the admin toggle.
kv_module_registry (23 rows) — merchant enrollment types
Columns (validated): module_key, module_name, is_active, timestamps. This is the list of business types a merchant can enroll as.
Live rows, 2026-09-06: platform (Platform Membership), customer (User/Customer), merchant (General Merchant), services (Services Provider), food (Food/Restaurant), tiffin (Tiffin Provider), realestate (Property Broker/Agent), builder (Builder/Developer), jobs (Jobs Recruiter), freelance (Freelancer/Agency), classifieds (Classifieds Seller), rides (Ride/Vehicle Partner), logistics (Logistics Partner), hotels (Hotel/Stay Partner), events (Event Organizer), campus (Campus/Institute), jobseeker (Job Seeker), founders_network (Founders Network), healthcare (Healthcare Provider), automotive (Automotive/Vehicle Service), financial (Financial Services), universal_entry (Universal Entry Layer, is_active=No), investor_vc (Investor/VC).
The key-mapping trap (critical)
The two registries do not share keys. The same module has different keys in each, and money tables (kv_order_finance_master.module_key, commission_transactions, membership plans) may use either vocabulary depending on the code path. Confirm which vocabulary a given table uses before filtering on module_key.
| Real module | kv_module_control key | kv_module_registry key(s) |
|---|---|---|
| E-commerce / CommerceX | ecommerce | merchant |
| RideMate (cab & bike) | cab_bike | rides |
| Real Estate | real_estate | realestate and builder (two enroll types) |
| HomeAssist / Services | homeassist | services |
| Food / Restaurant | food | food and tiffin |
| Freelancer | freelancer | freelance |
| Packers & Movers | packers_movers | logistics |
Registry-only enrollment types with no kv_module_control row (registered, activatable, but with no consumer control switch, hence often no nav surface): healthcare, automotive, financial, tiffin, campus, founders_network, jobseeker.
Control-only modules with no merchant enrollment counterpart: dating, trip_planner, business_directory, hyperlocal, courier, startup_passport, mobile_app_download_banner.
How to re-validate this page
php -r 'require "config/baseconfig/config.php"; global $conn;
foreach($conn->query("SELECT module_key,module_label,level,master_status,frontend_visibility FROM kv_module_control ORDER BY rowId") as $r) echo implode(" | ",$r),"\n";'
(or use _tools/kv_docs_db.php). If the row counts differ from 22 / 23, this page is stale — re-derive the tables above and update the date.