Changelog — ChargeGrid
[2026-05-30] — "Funders" are now "Investors" — tappable detail + a profit calculator
- Funders are now called Investors everywhere — it's the word people actually relate to. Nothing about how it works changed, just the name.
- See the story behind every number. In the Investor app, tap any earning, any power bank, or any item in your live rental feed to open a clean detail card — what happened, which unit, how much, and when.
- A built-in profit calculator. On the Invest screen, as you choose how many power banks to buy, you instantly see what you pay, what you earn back, your profit, and the % return — no maths required.
- A plain-English help section. New "How it works" page explains, in simple words: how you own power banks, how every rental pays you, when you get paid, and what happens if a unit is lost — with a worked profit example and one-tap WhatsApp/Call support.
Internal
- Display-only rename Funder→Investor across admin nav/list/dashboard/settings/devices/swap-split labels, marketplace + help copy, the investor portal views and signup. Internal role
funder, routes /funder, columns, cg_funder_ functions and /api/funders endpoints are unchanged.
funder-earnings rows reuse the shared activity-detail endpoint (already funder-scoped); the portfolio live feed + funder-devices cards open client-side CGP.detail; funder-invest gained a live profit/ROI breakdown; new public/funder-help.php + funder-help public route + Help entry points on the portfolio home and Invest page.
[2026-05-30] — Referrals are a free swap, not cash · support contact saves
- Referrals now reward a free swap, not money. When you invite a friend and they make their first swap, you both get a free swap — the fee is simply waived on your next one, exactly like a loyalty reward. It's a perk, not wallet cash, so there's nothing to withdraw. (This replaces the earlier money-credit bonus from the 2026-05-30 "honest referral bonuses" note — crediting cash could be cashed out and abused. Free swaps cost the platform nothing and mint no money; agents/funders agree to the occasional waived fee as a term of joining.)
- Support contact now actually saves. The support phone, WhatsApp and hours you set in Settings now save correctly and show up under Account → Help for members. (They were previously dropped on save.)
Internal
cg_qualify_referral grants free_swaps_available += referral_reward_swaps (default 1) to both referrer and referred, marks the referral rewarded with reward_kobo=0 — no cg_wallet_record, no platform debit. New referral_reward_swaps setting replaces referral_reward_kobo in helpers defaults, both seeds, the admin Settings field (now a swap count, not ₦), and api/settings.php whitelist.
- Added
support_phone / support_whatsapp / support_hours to CG_WRITABLE_SETTINGS — the save endpoint silently skips any key not in that whitelist, which is why they never persisted.
[2026-05-30] — Member lookup, clearer deposits & loyalty, "log in as"
- Agents can look up a member by phone. Walk-up with a dead phone? Agents now have a "Look up a member" screen — type the number and see a clean profile: deposit status, plan, wallet, the unit they're carrying and their loyalty standing. (Read-only — no swap.)
- Your deposit, front and centre. Your Account now shows a bold "Refundable deposit ₦X — held & protected" card with a checkmark, so you can see at a glance what you've paid without digging into your plan.
- Agents see the deposit is good. When an agent pulls you up for a swap, a green "Deposit verified" mark confirms you're ready to swap — and if you've earned a free swap, a clear "this swap is FREE — loyalty reward" banner tells the agent so. (Free swaps cost nobody — the fee is simply waived.)
- Clearer loyalty wording. The rewards screen now reads plainly: "Pay for 2 more swaps and the one after is free."
- Edit your own details. Update your name, phone and email yourself from Account.
- Bolder wallet top-up. The card / transfer top-up area is redesigned — bigger amount buttons and a clearer, secure "Top up" button.
- Friendlier plan-switch message. Moving to a smaller plan while holding a power bank now says, simply, "It looks like you still have a power bank out from your current plan. Please return it to any agent first."
- Plan-switch confirmation stays put. After switching, the confirmation now waits for you to tap "Got it" instead of flashing by.
- Staff "log in as". Admins can log in as any app user (and see their login PIN for support); managers can log in as their own agents and members. A banner shows when you're viewing as someone else, with one tap to exit.
- Fixed a payment error ("invalid email") when paying without an email on file.
Internal
- Impersonation helpers in
lib/auth.php (cg_start/stop_impersonation, cg_do_impersonate) modelled on ServicePro; impersonate actions in api/agents|members|funders.php, stop-impersonate portal action (CSRF-exempt), banner in _shell.php, PIN shown in admin drawers.
- New
member-lookup portal action + public/agent-member.php view + agent-member route + agent-home entry.
update-member-profile portal action; member profile card with inline edit in account.php.
cg_paystack_email returns a real @mypancho.com synthetic address (Paystack rejects placeholder TLDs).
- Agent swap card gained a
Deposit verified badge + free-swap banner; account gained a held-deposit hero; change-plan return_first copy softened on both the unit-count and solvency guards.
[2026-05-30] — Self-serve deposits, account closure & honest referral bonuses
- Pay & top up your deposit yourself. Your deposit can now be paid (or topped back up after a charge) right from the Wallet with card / transfer — paying cash or transfer to an agent is just an option, not the only way. Your Account now shows exactly how much deposit you hold.
- Close your account & get refunded. From Account, request to close — give your bank, and your wallet + deposit are refunded together. For safety, money is never sent automatically: a manager reviews the request (new Closures screen) and runs the transfer.
- Referral bonuses are honest now. When you and a friend both earn a referral bonus, that free money is funded by the platform (out of its own cut) and shown clearly in everyone's activity — no agent/funder/manager is silently charged, and no money is invented from nowhere. (Also fixed a bug where first-swap referral rewards silently failed.)
Internal
cg_qualify_referral rewards both sides, books a matching platform debit (referral_reward), and is transaction-safe (joins the swap's transaction instead of nesting — the previous nested beginTransaction silently rolled back).
deposit-init/-callback + agent-collect-deposit are now shortfall-based (plan deposit − held) so the same flow pays the first deposit and tops up a partial one.
account_closures table + member request-closure/cancel-closure (snapshots wallet+deposit, captures bank, flags status='closing'); manager api/closures.php (list / process / reject) + views/closures.php queue; closure releases the deposit into the wallet then pays the lot out via cg_request_payout. cg_authenticate permits closing login; resolve-bank permits members.
- Wallet/Account deposit cards are shortfall-aware; self-serve card/transfer is the primary CTA.
[2026-05-30] — Tappable activity, return-without-swap & flexible downgrades
- Tap any activity for the full story. Every row in your Wallet activity, your swap History, and an agent's Earnings now opens a clean detail card — date, who/where, the units involved, the method, and the receipt number — so every transaction is accountable.
- Return a power bank without swapping. Agents can now take a unit back on its own: on the swap screen, look up the returning unit and tap "Just take it back — no new unit." No fee — the member is then holding nothing and can collect their deposit or change plan.
- Smarter plan downgrades. You can move to a smaller plan as long as its deposit still covers the power bank you're holding — you only have to return a unit if it genuinely wouldn't.
Internal
CGP.detail bottom-sheet in the portal shell; activity-detail endpoint resolves a wallet-ledger row + its linked swap; wallet / history / agent-earnings rows wired to it.
- New
return-unit agent endpoint (unit → depleted at agent, holder cleared, open extension charge closed, no fee) + a "Return only" flow on the agent swap screen.
change-plan downgrade guard relaxed back to the solvency rule only (held unit cost ≤ new deposit); the over-strict "can't downgrade while holding" block was removed.
[2026-05-30] — Agent app: an Account home, saved bank & a bolder swap
- New "Account" tab for agents (replaces "Earnings"), with sections:
- Earnings — your wallet balance, a one-tap Withdraw, and recent commissions.
- Bank — save your payout bank once; withdrawals reuse it (no re-typing).
- Profile — update your owner name, business name, and address.
- Help — call / WhatsApp your manager and ChargeGrid support, plus quick links to load a member or report a damaged unit.
- Withdraw, simplified. Big, bold screen that shows your balance and the saved bank it's going to — just tap Withdraw. (Set the bank under Account → Bank first.)
- Process-a-swap, bolder. Bigger code boxes, a clearer heading, a prominent "New member?" card for first swaps, and a roomier phone field.
Internal
- New
public/agent-account.php (tabbed) + agent-account route; agent bottom-nav "Earnings"→"Account" across agent screens; agent-payout.php rebuilt to use the saved bank only.
- New
update-agent-profile portal action; manager contact resolved via manager_areas for the agent's area.
[2026-05-30] — Agent confirmations, friendlier popups & a cleaner app
- Agent swap, rebuilt for trust. When an agent enters a power-bank code, the member's card now shows a clear green/red verdict — deposit on file? wallet covers the fee? — and won't let the swap proceed if not, with exactly what to fix. After a swap, a big, bold confirmation shows the member their handed-out unit, the fee, and their new wallet balance — so they can see it's done even though their phone is dead. Same for agent cash top-ups.
- Beautiful pop-ups everywhere. Replaced the plain browser "OK/Cancel" boxes (like switching plans) with clean in-app cards — for confirmations, prompts, and errors, across the member and manager apps.
- "Agents" tab. The map tab is now Agents, and you pick your area from a searchable list (works whether you have 5 areas or 500). Each station shows how many power banks it has in stock; tap in to see the sizes it carries. (We no longer claim how many are "charged" — that can't be verified.)
- Tidier wallet. "Prefer to pay with cash or transfer?" with the safety tip tucked behind a tap; removed the duplicate "agents near you" list (use the Agents tab).
- Nicer plan cards in Account → Plan — clear deposit, swap fee, and limits at a glance.
- Support number is a setting. Set your call / WhatsApp line under admin Settings → Support contact; it shows to members in Account → Help.
- Damage charges take the deposit first (then the wallet only if the deposit somehow can't cover it).
Internal
cg_swap_customer_payload() adds fee/deposit/wallet validity to the swap lookup; agent-swap gates on it + big confirmation; swap result returns customer name + new wallet balance.
cg_charge_member() flipped to deposit-first → wallet-fallback.
- Portal
CGP.confirm/alert/prompt + admin CG.confirm/alert/prompt styled modals; all native confirm/prompt in live views replaced.
- Map: searchable area sheet +
units (on-hand) counts; agent-detail groups by capacity_mah without status claims; "Map"→"Agents" nav across member screens.
support_phone/support_whatsapp/support_hours editable in admin Settings.
[2026-05-30] — Self-serve plans, a deposit safety rule & damage charges
- Redesigned Account page. Cleaner icon tabs that fit any phone, and each section (Account · Plan · Users · Refer · Help) now shows on its own — no more scrolling past everything at once.
- Change your plan yourself. In the Plan tab, tap "Switch to …" to upgrade or downgrade instantly. If the new plan's deposit is higher, the difference comes from your wallet; if it's lower, it's refunded to your wallet. (You're stopped if you'd be holding a power bank your new deposit can't cover.)
- A deposit can never be "underwater." New platform-wide rule: a member can never hold power banks that cost more than their deposit — enforced at the moment of every swap, so the business is always covered even if a limit was set wrong.
- Power-bank sizes & cost are now managed. Units default to 10,000 mAh; an admin or manager can set each unit's size (10k/20k/30k) and cost from the Devices screen.
- Damage & loss charges. A manager can charge a member for a lost or spoiled unit — taken from their wallet first, then their deposit — and release the unit, all in one action.
Internal
account.php: class-based panel switching (fixes the inline-display vs hidden bug that showed all sections), compact icon segmented tabs, click delegation.
change-plan portal action: wallet-reconciled deposit delta with unit-count, sub-account, and solvency guards. Verified an upgrade/downgrade round-trip balances exactly.
- Solvency invariant
Σ(held unit_cost) ≤ held deposit enforced in cg_process_swap (step 3b) and change-plan.
power_banks.capacity_mah default → 10000; devices add/update + admin drawer expose size + cost.
cg_charge_member() (wallet-first → deposit) in the deposit engine + devices/charge_loss action + drawer button.
[2026-05-30] — Loyalty, agent discovery, power-bank sizes & editable users
- Loyalty rewards page. Tap the Loyalty card on your home screen to see exactly how many more swaps until your next free one, your progress, and your totals. It's fully automatic — when you hit the target, your next swap's fee is waived at the agent. (Also fixed a glitch where a brand-new member saw "free swap ready" before earning one.)
- Power banks now come in sizes. Every unit is tagged 10,000 / 20,000 / 30,000 mAh, so you can find the capacity you want (bigger = more charges).
- "Find an agent" is now useful. Pick your area, search by name or street, and each station shows how many power banks it has on hand and which sizes are available (10k/20k/30k chips). Tap an agent to see their full stock — each unit's ID, size, and status.
- Honest stock counts. Replaced the old "X charged" claim (which couldn't be verified) with real "on hand" and "ready" counts.
- Edit additional users. You can now edit a family/staff member's name, phone, or PIN — not just remove them.
- Sign-up screens (rent / agent / funder) now match the new login look.
Internal
power_banks.capacity_mah column (10000/20000/30000) — additive, the lazy migrator adds it; demo seeds a 3/3/4 spread.
- New
public/loyalty.php and public/agent-detail.php routes; home loyalty card + nearby-agent cards now link out; map.php gains an area filter, name search, capacity chips, and devices-on-hand counts.
- New
edit-subaccount portal action (owner-scoped) + edit UI in Account → Additional users.
_authskin.php re-tints the cg-* system to the login's Manrope / Space Grotesk warm palette for the three signup forms (per-page role accent preserved).
[2026-05-30] — Member app: new look, Account hub & safer top-ups
- A beautiful new sign-in. Brand-new login screen — warm, clean, and native-feeling, with phone + PIN, a "Forgot PIN?" helper, and a "Create account" toggle. The sign-up role chooser now matches it exactly.
- New Account area. Tap Account in the bottom bar for a tidy, tabbed home for everything about you:
- Account — your name, plan, deposit status, wallet balance, and quick links.
- Plan — see your membership and compare every plan (deposit, swap fee, units, extra users).
- Additional users — add family or staff who swap on your wallet (renamed from "Family" — it's for anyone, not just family). Limited by your plan.
- Refer & earn — your referral code, a one-tap share link, and how much you both earn.
- Help — call or WhatsApp support, common questions, and "report a problem" if an agent didn't load your wallet.
- Safer top-ups (important). You can no longer "top up" without actually paying. Top-ups now happen by card/transfer or by paying cash to an agent who loads your wallet on the spot — with a clear reminder to check your new balance before you leave.
- Clearer wallet. The wallet card is easier to read (solid "Top up wallet" button, a "per swap" badge), and a "No card? Top up with cash" card lists agents near you.
Internal
- Money-minting fix: removed the manual free-credit path on
wallet-topup-init/callback. Wallet credit now requires a verified Paystack payment or the balanced agent cash-transfer; in manual mode the API returns no_online and the UI routes to an agent.
- New
public/account.php (tabbed hub) + account route; bottom-nav "Family" tab replaced by "Account" across member screens. Sub-account gating reads plans.max_sub_accounts (not the old family tier check).
- Added
support_phone / support_whatsapp / support_hours settings (seeded), surfaced in Account → Help.
- Login brand renders as "ChargeGrid" (not all-caps); subtitle trimmed.
[2026-05-30] — Smoother signup, login fix & nationwide branding
- Fixed login. Signing in no longer fails with a "session/CSRF" error — the login screen now talks to the right place. (You can sign in again.)
- Beautiful new sign-in & join screens. Signing in now opens on a striking Earth-at-night backdrop — a world lit up with power — with the phone + PIN fields (each with its own icon) floating in a clean, centered glass form, no boxed-in white card. The "join the grid" page keeps its full emerald hero. A proper native-app feel instead of a blank page.
- Now just "ChargeGrid". Dropped the "Lagos" tag everywhere — ChargeGrid runs nationwide.
- Joining is quicker. Customers now simply create a PIN when signing up (the step that used to be missing), and we no longer ask for your NIN/BVN up front — your refundable deposit covers it. Staff can still add a NIN/BVN later from the admin if ever needed.
- Clearer "pay" choices. Instead of a payment brand name, you pick "Card or bank transfer" or "Pay cash to an agent" (with a reminder to make sure your deposit shows before you leave).
- Friendlier wording. Agents sign up a "business" (not a "shop") — stalls and roadside spots welcome. Every signup screen now has a back button and an "Already have an account? Log in" link.
- Two new membership plans. Added Starter (₦7,000 deposit · ₦1,000/swap) for the easiest way in, and Business (₦100,000 deposit · ₦1,200/swap) for teams holding up to 5 units. Existing Standard, Family, and Professional plans are unchanged.
- Agent cash-loading, done right. An agent now tops up their own wallet once, then instantly transfers wallet credit or a deposit to a member who pays them cash — so the books always balance. Family/Professional/Business members can be given sub-accounts based on their plan.
Internal
- Root cause of the login failure: the
/p/{uuid}/{appId}/login route rendered without $basePath, so the client posted to the platform API path and tripped the platform CSRF gate. Fixed in [core/index.php](../../core/index.php) by passing $basePath (and mirroring $GLOBALS['basePath']) to the login view, matching every other public route.
agent-topup is now a balanced wallet→wallet transfer (debit agent, credit member, in one transaction) instead of a one-sided credit that minted money; added agent-collect-deposit. Sub-account gating reads plans.max_sub_accounts instead of a hardcoded family tier.
- Shared auth-hero styles (
.cg-auth*) added to the portal shell; nin_bvn wired into the agent/funder edit drawers + APIs.
- Belt-and-suspenders for the login fix: the portal shell JS now self-heals an empty
cg-base by deriving /p/{uuid}/{appId} from the URL, so login posts to the app API even if a server still serves the un-updated login route (works from the app folder alone, without the core change).
[2026-05-29] — Full production rebuild
ChargeGrid was rebuilt from the ground up into a complete, production-ready three-sided network app — customer, agent, and funder mobile portals, plus an owner/manager operations dashboard.
- Customer app — sign up with NIN/BVN + photo and pay your refundable deposit online, see a live map of agents with charged stock, top up your wallet, view swap history, and add family members on the Family plan.
- Agent app — process a swap in seconds (type the returning unit's 6-digit code, confirm the customer's photo, type the outgoing unit's code — the fee auto-deducts), track inventory and earnings, withdraw to your bank, report damaged units, and load a customer's wallet for cash.
- Funder app — fund units via Paystack, then watch each one earn toward its payoff live, with weekly auto-payouts to your bank.
- Manager (renamed from "Director") runs the day-to-day for their assigned areas; the owner oversees everything with full control.
- Phone + PIN login for everyone; the customer portal installs as a phone app (PWA).
This builds on the foundations below:
- Three-sided marketplace economics. Configurable ₦1,200 swap fee and ₦20,000 refundable deposit, with every swap split between the platform, the hosting agent, and the unit's funder. A funder's unit earns a boosted share on each swap until it hits its promised return (e.g. invest ₦20,000 → earn ₦30,000), then it's "Paid Up" and the split reverts to platform + agent — tracked per device.
- Day-to-day is run by Managers. The old "Director" role is now Manager — the person who handles agents, devices, deposits, and payouts on the ground for their area(s). The account owner oversees everything with full control.
- Solid wallet + deposit engine. Every member, agent, and funder has a wallet; swaps deduct automatically. Refundable member deposits and configurable agent security deposits (with a per-agent waiver a manager can grant) protect units in the field. Lost units draw against the deposit after a configurable grace + weekly extension-fee window.
- Loyalty & referrals. Every 10th swap is free, and referring a friend earns credit once they complete their first swap.
- Online deposits, wallet top-ups, and automatic payouts to agents/funders are wired for Paystack (card + bank transfer + USSD in, bank-account transfers out).
Internal
- Schema rebuilt for the per-user model: a single
app_users table for all roles + family sub-accounts (no shared members registry), all money stored in kobo, and a wallet_ledger. Fixes the broken install where the old schema referenced a members table it no longer created.
- New engine libraries under
lib/ (swap, deposits, extensions, funder payoff, payouts) verified by an integration test covering split math, the payoff cap, and unit rotation.
[2026-05-14]
- Added a Watch/Read tab on the tutorial page — every lesson now has a written version alongside the video for users who prefer to read.
[2026-04-20]
- Fixed demo data not loading on install — the seed file was referencing an outdated column name, so new customers never saw the sample agents, funders, and transactions.
Internal
seeds/demo.sql now writes to members.pancho_user_id (schema has been on UUIDs for a while); every foreign-key to a member row is a matching UUID placeholder instead of the old 100-series integers.
[2026-04-18] — Renamed
- Renamed from Charge Pro to ChargeGrid (slug
chargepro → chargegrid).
- Every display string, marketing copy, schema reference, code-comment, folder path, DB filename, and
subscriptions.app_id value now uses the new slug. Platform had not gone live yet, so old URLs are not preserved.
All notable changes to this app are recorded here. Newest entries on top.
[2026-04-17] — Funder rename, 30% agent share, payoff mechanic
- Renamed the "investor" role to "funder" across every screen, API route, setting, and URL — less regulatory baggage, clearer to Nigerian users.
- Agents now earn a fixed 30% of every swap (was 33%). Changed is visible on the new "How you earn" page in the agent dashboard — no more splitting hairs over platform math.
- Funded units now have a payoff target. When you fund a unit, the platform records the purchase price × (1 + interest %) as your payoff goal (default 20% interest). Every swap on that unit credits you the non-agent share until your earnings reach the target, at which point the split reverts to the platform.
- Director settings page simplified: just set the agent % and the default interest rate — the rest is derived automatically.
- Funder portfolio page shows a per-unit payoff progress bar.
- New in-app event
chargegrid_unit_paid_off fires when a unit crosses its payoff target (useful for future notification hooks).
Internal
- Full rename of
investor_* → funder_* across schema (investor_devices → funder_devices, investor_id, investor_share), API routes (/investors/ → /funders/), app.json permissions, role values, and setting keys.
- New columns on
funder_devices: interest_rate, payoff_target, paid_off_at. Guarded ALTERs for existing installs.
[0.3.0] — 2026-04-17
- Role-aware home dashboard: customers see wallet/device status and quick actions, agents see inventory counts and today's earnings, funders see portfolio summary, directors see area overview
- 3-step swap wizard for agents: verify customer identity (photo + name), scan returned and outgoing device IDs, confirm and process with automatic wallet debit and three-way revenue split
- Customer swap view showing active device info and how-to-swap instructions
- Wallet page with balance card, top-up flow, withdrawal requests (agents/funders), and full transaction history
- Customer swap history with chronological transaction list
- Family sub-accounts page for managing household members under one membership
- Agent inventory view with filter tabs (charged/charging/damaged) and device grid
- Earnings view shared by agents, funders, and directors — shows relevant commission data per role
- Funder portfolio showing all owned devices with ROI calculation, rental counts, and lifecycle status
- Director area management: view/create geographic zones with agent/device/swap counts
- Director agent management with enriched stats per agent (devices, swaps, earnings)
- Director member management with search, role filtering, detail sheet with freeze/unfreeze actions
- Director device fleet view with table layout, status filters, and create-new-device form
- Director settings page for configuring swap fee, deposit, revenue split percentages, late fees, and payout thresholds
- Self-service public signup portal at /p/{userId}/chargegrid/signup — multi-step form with photo capture, NIN/BVN collection, tier selection, and deposit payment flow
[0.2.0] — 2026-04-17
- Full database schema: members with NIN/BVN and photo verification, sub-accounts, geographic areas, power banks with 6-digit device IDs, transactions with three-way revenue split, wallets, funder devices, agent profiles, deposits, damage reports, late returns, corporate sponsors, director area assignments, and payouts
- Four first-class roles: customer, agent, funder, director — each with role-specific navigation and permissions
- Role-aware dashboard API returning tailored stats per role
- Swap processing API with wallet debits, three-way revenue split (platform/agent/funder), and device status tracking
- Wallet API: balance check, top-up recording, transaction history, payout requests
- Devices API: fleet CRUD with filtering by status/area, device creation with funder linking
- Members API: list, update, freeze/unfreeze, account closure request and approval flow
- Agents API: list with enriched stats, profile updates, approve/suspend
- Funders API: portfolio view, device purchase flow
- Deposits API: payment recording, refund processing with wallet integration
- Geographic areas API: CRUD with director assignment
- Demo seed with Lagos zones, sample agents, funders, customers, power banks, and transactions
- Fresh seed with default settings (1,200 NGN swap fee, 20,000 NGN deposit, configurable revenue split)
[0.1.0] — 2026-04-16
- Initial shell scaffold with customer / agent / admin roles.
- Concept page outlining PIN-based swap confirmation and deposit flow.
- Added funder role as a stretch idea — outside funders fund individual power banks and earn a cut of every rental their unit generates, tracked live in-app.