⚡ System Integration Blueprint + Claude Code Plan — v2.0

Musharakah Integration Engine
Banks, APPNA & Institutional Gateways

Complete process architecture + software plan connecting a single person through Musharakah pools to 40+ Pakistani banks, APPNA diaspora, ZTBL agricultural finance, pension funds, and HomeFranchise.Biz — one unified journey, all backend orchestrated, ready for Claude Code.
40+
Banks Connected
55K+
APPNA Physicians
PKR 35T
Banking Assets
890K
ZTBL Farmers
01 — System Overview
One Person, One Journey — Every Backend Connected

A franchise applicant in Thar or a physician in Houston experiences a single process. The backend orchestrates Musharakah pool formation, Shariah compliance, bank provisioning, APPNA diaspora investment, ZTBL credit, pension fund participation, and franchise deployment through unified API gateways.

5
Islamic Banks
PKR 6.5T assets
5
Govt Banks
PKR 7.8T assets
15
Private Banks
PKR 18T assets
11
Microfinance
PKR 1.2T assets
90M+
Mobile Wallets
JazzCash/Easypaisa

🟢 LOCAL COMMUNITY PATH

Farmer, shopkeeper, women's group → CNIC registration → Pool with neighbors → JazzCash/Easypaisa contribution → Musharakah pool → Franchise funded → Monthly profit via mobile money

Banks: Meezan, BankIslami, ZTBL, NBP, microfinance

🔵 APPNA DIASPORA PATH

Pakistani physician in US → APPNA portal → Select hometown Musharakah pool → Stripe/ACH $500+ → Co-invest with local community → Quarterly returns + social impact report

Payments: Stripe, Wire, ACH → OFAC/KYC-US compliance

🟡 INSTITUTIONAL PATH

IsDB, Gulf SWF, pension fund → Due diligence package → Shariah board review → Large-scale Musharakah ($100K-$50M) → Fund 100-10,000 franchise units → Diminishing Musharakah exit

Partners: EOBI, NIT, Akhuwat, NRSP, Gulf funds
02 — Single User Journey
12 Steps — From Registration to Franchise Ownership

Every user type enters the same funnel. The orchestration engine detects their profile and routes them through the correct backend processes — banking, compliance, pooling, deployment.

📱 Registration & Intent Declaration

User registers via web/mobile/Postal Code Center. Selects: Community Investor Operator APPNA Diaspora Institutional. System captures CNIC (local) or Passport+SSN (diaspora).

Backend: POST /api/v1/auth/register → Firebase Auth → Role routing → KYC flow assignment

🔍 KYC/AML Verification (Auto-Routed)

Local: CNIC → NADRA e-Sahulat API → Document AI scan → SBP AML check
APPNA: US Passport + SSN → Stripe Identity → OFAC screening → FinCEN compliance
Gulf: Emirates ID → GCC KYC → UAE Central Bank clearance
Institutional: Company registration → LEI verification → Enhanced due diligence

Backend: POST /api/v1/kyc/verify → Router selects: nadra_service | stripe_identity | gcc_kyc | edd_service

🏦 Bank Account Provisioning

System auto-provisions or links appropriate bank account:
• Islamic bank account (Meezan/BankIslami) for Musharakah pooling
• JazzCash/Easypaisa wallet for micro-investors (PKR 10K-50K)
• Stripe Connect account for APPNA/international
• ZTBL account link for agricultural franchise operators

Backend: POST /api/v1/banking/provision → bank_gateway_service selects: islamic_bank_api | mobile_money_api | stripe_connect | ztbl_api

🔎 AI-Powered Matching

Investors: Vertex AI matches to pools based on location, risk profile, investment size, preferred sector (cooking, solar, AI kiosk)
Operators: Skills + location + capital → Top 3 franchise type recommendations
APPNA: Hometown zip code → Active pools in home village/city → Social impact score

Backend: POST /api/v1/ai/match → Vertex AI prediction endpoint → Ranked results with confidence scores

💰 Pool Selection & Capital Commitment

User selects Musharakah pool. Reviews: target capital, current fill %, profit ratio, franchise type, Shariah certificate, operator profile. Commits capital amount. System validates against pool rules (min/max, geographic restrictions).

Backend: POST /api/v1/pools/{id}/commit → validate_investment → reserve_units → generate_contract_draft

📜 Contract Generation & Shariah Review

Auto-generates trilingual contract (EN/UR/AR) from template. Includes: profit ratios, loss rules, diminishing schedule, Halal clause, dispute resolution. Submitted to Shariah Advisory Board queue. AI pre-screens for compliance (Gemini-powered).

Backend: POST /api/v1/contracts/generate → template_engine + ai_shariah_checker → shariah_review_queue

💳 Payment Processing

Capital contribution routed through appropriate gateway:
JazzCash/Easypaisa: USSD or app → PKR 10K-500K → Instant
Islamic Bank Transfer: IBFT/RTGS → PKR 50K-50M → Same day
Stripe (APPNA): Card/ACH → $500-$500K → FX conversion at market rate
Wire (Institutional): SWIFT → $100K-$50M → T+1 settlement

Backend: POST /api/v1/payments/contribute → payment_router → jazzcash_api | bank_ibft | stripe_charges | swift_gateway → ledger_entry

✍️ E-Signature & Contract Execution

All parties sign digitally. CNIC-verified digital signature for locals. DocuSign/Stripe-verified for international. Shariah advisor counter-signs. Executed contract stored in Cloud Storage. All parties receive PDF copy via SMS/email/WhatsApp.

Backend: POST /api/v1/contracts/{id}/sign → signature_hash (SHA-256) → verify_all_parties → mark_executed → store_pdf → notify_all

🏗️ Franchise Deployment (HomeFranchise.Biz)

Pool capital released → Equipment procurement from approved vendors → Operator completes training modules (4-6 weeks) → Equipment installation → Quality inspection → Launch. All tracked in real-time dashboard.

Backend: POST /api/v1/franchises/{id}/deploy → procurement_workflow → training_tracker → inspection_checklist → status: OPERATING

📊 Monthly Operations & Reporting

Operator submits monthly report: revenue, expenses, units sold. System auto-calculates net profit. Dashboard shows all investors real-time performance. AI flags anomalies. ZTBL-linked units also report agricultural output.

Backend: POST /api/v1/franchises/{id}/reports → profit_calculator → BigQuery analytics → investor_dashboard_update → anomaly_detection

💵 Profit Distribution & Diminishing Buyout

Quarterly: System calculates distributable profit → Allocates per Musharakah ratio → Deducts Zakat if elected → Routes payment to each partner (JazzCash/bank/Stripe). Diminishing Musharakah: operator's equity unit purchase processed, ownership % updated.

Backend: Cloud Scheduler (1st of quarter) → /api/v1/finance/distribute → per-partner calculation → multi-gateway payout → diminishing_engine.update_equity

🏆 Full Ownership Achievement

After 3-5 years, operator has purchased all equity units. System: marks pool as COMPLETED, transfers franchise registration to operator, generates ownership certificate (trilingual), notifies all partners of successful exit with final ROI summary.

Backend: diminishing_engine.check_completion → transfer_ownership → generate_certificate → close_pool → final_report → celebrate 🎉
03 — Bank Gateway Integration
40+ Banks — Islamic, Government, Private, Microfinance

Every Pakistani bank is a potential Musharakah channel. Islamic banks are primary (Shariah-native), government banks provide infrastructure reach, private banks offer scale, and microfinance enables the lowest income tiers.

☪️ Islamic Banks — Primary Musharakah Partners (5 banks, 4,200+ branches)

BankBranchesAssets 2024 (PKR B)Islamic WindowAPI IntegrationMusharakah Role
Meezan Bank 🥇1,000+2,800+Full Islamic✅ REST APIPrimary pool custodian, Musharakah accounts
BankIslami380+650+Full Islamic✅ REST APIRural franchise accounts, micro-Musharakah
Dubai Islamic Bank250+580+Full Islamic⚙️ In progressGulf investor bridge, AED/PKR settlement
Al-Baraka Bank200+420+Full Islamic⚙️ In progressBahrain/ME investor gateway
MCB Islamic / Faysal850+1,200+Islamic Division🔜 PlannedMass-market Islamic window Musharakah

🏛️ Government Banks + ZTBL (5 banks, 2,100+ branches, PKR 7.8T assets)

BankBranchesAssets 2015→2024GrowthMusharakah Role
National Bank (NBP)2,1504,800→16,500 B+123%Govt scheme disbursement, rural reach
Bank of Punjab8501,850→8,200 B+118%Punjab franchise deployment channel
Sindh Bank320680→4,100 B+113%Sindh/Thar franchise operations
Bank of Khyber180420→2,800 B+133%KPK/tribal areas deployment
ZTBL (Zarai Taraqiati)500+195B annual890K farmersAgricultural franchise bridge

🏦 Private Banks (15 banks, 8,500+ branches)

HBL (PKR 5.2T) • UBL (3.2T) • MCB (2.8T) • Allied (2.2T) • Bank Alfalah (1.85T) • Standard Chartered • Habib Metro • JS Bank • Askari • Soneri • Summit • Silk • Bank Al-Habib • Samba • KASB

Integration: Open Banking API (SBP RAAST) for IBFT transfers. Private banks serve as secondary investment channels — their Islamic windows route to Musharakah accounts at partner Islamic banks. HBL/UBL provide remittance corridors for APPNA members.

📱 Microfinance + Mobile Money (11 banks, 90M+ wallets)

Khushhali Bank • JazzCash (50M users) • Telenor/Easypaisa (40M) • FINCA • U Microfinance • NRSP MFB • Apna • Advans • SadaPay • NayaPay

Integration: JazzCash/Easypaisa APIs for instant investment (PKR 10K min). USSD channel for non-smartphone users. Microfinance banks provide Tier 1-3 household credit bridge — operator can start franchise while Musharakah pool forms.

Bank Gateway Service — Software Architecture

services/banking-gateway/routers/banks.py
# ═══════════════════════════════════════════════════════
# BANK GATEWAY ROUTER — Routes to appropriate bank API
# ═══════════════════════════════════════════════════════

from fastapi import APIRouter, Depends
from enum import Enum

class BankChannel(str, Enum):
    ISLAMIC     = "islamic"       # Meezan, BankIslami, Dubai Islamic
    GOVERNMENT  = "government"    # NBP, BoP, Sindh, BoK
    ZTBL        = "ztbl"          # Agricultural loans
    PRIVATE     = "private"       # HBL, UBL, MCB via RAAST
    MOBILE      = "mobile_money"  # JazzCash, Easypaisa
    STRIPE      = "stripe"        # International (APPNA, Gulf)
    WIRE        = "wire"          # Institutional SWIFT

router = APIRouter(prefix="/api/v1/banking", tags=["Banking"])

@router.post("/provision")
async def provision_bank_account(user_id: str, user_type: str, location: dict):
    """Auto-provision appropriate bank channel based on user profile."""
    
    if user_type == "community_investor":
        if location["province"] in ["Punjab", "Sindh", "KPK", "Balochistan"]:
            # Check if user has Islamic bank account
            existing = await check_existing_accounts(user_id)
            if not existing:
                # Create Meezan Musharakah Pool Account
                return await islamic_bank_api.create_musharakah_account(
                    bank="meezan", user_cnic=user_id, account_type="musharakah_pool"
                )
            return existing
        # Fallback: mobile money for unbanked
        return await mobile_money_api.create_wallet(user_id, provider="jazzcash")

    elif user_type == "franchise_operator":
        # Operators need both: Islamic account + ZTBL link (if agricultural)
        islamic = await islamic_bank_api.create_musharakah_account(
            bank="bankislami", user_cnic=user_id, account_type="operator"
        )
        if is_agricultural_franchise(location):
            ztbl = await ztbl_api.link_farmer_account(user_id, location)
            return {"islamic_account": islamic, "ztbl_account": ztbl}
        return {"islamic_account": islamic}

    elif user_type == "appna_diaspora":
        # Stripe Connect for US-based, with PKR settlement
        return await stripe_service.create_connect_account(
            user_id=user_id, country="US", currency="usd",
            settlement_currency="pkr", kyc_type="appna"
        )

    elif user_type == "institutional":
        # SWIFT/Wire for large transfers
        return await wire_gateway.create_institutional_account(
            user_id=user_id, expected_volume="high",
            currencies=["USD", "SAR", "AED", "PKR"]
        )

@router.post("/transfer")
async def process_investment_transfer(
    user_id: str, pool_id: str, amount: float, 
    currency: str = "PKR", channel: BankChannel = None
):
    """Route payment through appropriate bank channel."""
    
    if channel is None:
        channel = await auto_detect_channel(user_id, amount, currency)
    
    CHANNEL_MAP = {
        BankChannel.ISLAMIC:    islamic_bank_api.ibft_transfer,
        BankChannel.GOVERNMENT: raast_api.instant_transfer,
        BankChannel.ZTBL:       ztbl_api.agri_credit_transfer,
        BankChannel.MOBILE:     mobile_money_api.p2p_transfer,
        BankChannel.STRIPE:     stripe_service.charge_and_convert,
        BankChannel.WIRE:       swift_gateway.initiate_transfer,
    }
    
    handler = CHANNEL_MAP[channel]
    result = await handler(
        from_account=user_id, to_pool=pool_id,
        amount=amount, currency=currency
    )
    
    # Record in double-entry ledger
    await ledger_service.record(
        debit="1000_cash_" + channel.value,
        credit="2000_partner_capital",
        amount=amount, pool_id=pool_id, user_id=user_id,
        description=f"Capital contribution via {channel.value}"
    )
    
    return result
04 — APPNA Diaspora Channel
55,000+ Pakistani-American Physicians — Hometown Investment

APPNA (Association of Physicians of Pakistani Descent of North America) represents 55,000+ physicians earning $250K-$1M+ annually. They send $2B+ in remittances yearly. Our platform channels this into structured Musharakah investments in their home communities — not charity, but profitable Shariah-compliant partnerships.

55K+
APPNA Members
$250K+
Avg Annual Income
$2B+
Annual Remittances
$500
Min Investment

APPNA Integration Process

1 APPNA member logs in via APPNA SSO or registers directly
2 US KYC: SSN + Driver License → Stripe Identity → OFAC screening
3 Enters hometown (Lahore, Peshawar, Multan etc.) or ancestral village
4 System shows active Musharakah pools in/near hometown
5 Selects pool → Reviews Shariah certificate + franchise details
6 Invests $500-$500K via Stripe (card/ACH/wire)
7 FX conversion at market rate (USD→PKR) — no hidden spreads
8 Contract generated in English + Urdu, e-signed via DocuSign
9 Quarterly: profit distributed back via Stripe (PKR→USD at market)
10 Annual: Social impact report + franchise photos/videos from hometown

APPNA-Specific Software Components

APPNA SSO Integration: OAuth 2.0 with APPNA member directory. Verify active membership. Auto-populate physician profile (specialty, hospital, state).
Hometown Matching Engine: Maps APPNA member's ancestral district/tehsil to active pools. Shows distance from family village. Prioritizes pools with existing family connections.
US Tax Compliance: Auto-generates K-1 equivalent for Musharakah income. FATCA reporting. IRS-compatible profit/loss statements. 1099-INT not applicable (this is equity income, not interest).
Impact Dashboard: Real-time franchise performance visible from Houston. Photos of franchise unit. Number of families served. CO₂ saved. Women employed. Children in school.
APPNA Chapter Events: Integration with APPNA chapter meetings. Pool formation at annual convention. Chapter-level aggregate investment tracking.
services/appna-gateway/service.py
class APPNAGatewayService:
    """Handles all APPNA diaspora investment flows."""
    
    async def register_appna_member(self, appna_id: str, ssn: str, passport: str):
        # 1. Verify APPNA membership
        member = await appna_sso.verify_membership(appna_id)
        if not member.active: raise HTTPException(403, "Inactive APPNA membership")
        
        # 2. US KYC via Stripe Identity
        kyc = await stripe_identity.verify(ssn=ssn, passport=passport)
        
        # 3. OFAC/SDN screening (required for US persons)
        ofac = await ofac_screening.check(name=member.full_name, dob=member.dob)
        if ofac.match: raise HTTPException(403, "OFAC screening flag — manual review")
        
        # 4. Create Stripe Connect account for payouts
        stripe_acct = await stripe.create_connect_account(
            country="US", type="express",
            capabilities={"transfers": {"requested": True}},
            metadata={"appna_id": appna_id, "hometown": member.hometown_district}
        )
        
        return {"user_id": member.id, "kyc": "verified", "stripe": stripe_acct.id}
    
    async def match_hometown_pools(self, user_id: str):
        """Find Musharakah pools near member's ancestral village."""
        member = await get_user(user_id)
        hometown = member.profile.hometown_district  # e.g., "Rawalpindi"
        
        pools = await pool_service.search(
            province=member.profile.hometown_province,
            district=hometown,
            status="fundraising",
            sort_by="proximity_to_hometown"
        )
        
        # Enrich with social impact data
        for pool in pools:
            pool.impact = await impact_service.calculate(pool.id)
            pool.family_connections = await find_family_in_pool(user_id, pool.id)
        
        return pools
    
    async def invest_from_us(self, user_id: str, pool_id: str, amount_usd: float):
        """Process USD investment with FX conversion."""
        # 1. Charge via Stripe
        charge = await stripe.create_charge(
            amount=int(amount_usd * 100), currency="usd",
            customer=user_id, metadata={"pool_id": pool_id}
        )
        
        # 2. FX conversion at SBP market rate
        rate = await fx_service.get_rate("USD", "PKR")  # e.g., 278.50
        amount_pkr = amount_usd * rate.mid
        
        # 3. Transfer PKR to pool's Islamic bank account
        transfer = await islamic_bank_api.ibft_transfer(
            to_account=pool.bank_account, amount=amount_pkr,
            reference=f"APPNA-{user_id}-{pool_id}"
        )
        
        # 4. Record in ledger
        await ledger_service.record_multi_currency(
            debit="1003_cash_stripe_usd", credit="2001_partner_capital_external",
            amount_original=amount_usd, currency_original="USD",
            amount_pkr=amount_pkr, fx_rate=rate.mid
        )
        
        return {"charge_id": charge.id, "pkr_amount": amount_pkr, "fx_rate": rate.mid}
05 — ZTBL Agricultural Bridge
890,000 Farmers — PKR 195 Billion Annual Portfolio

ZTBL (Zarai Taraqiati Bank Limited) serves 890,000 farmers with PKR 195B in annual agricultural loans. Our integration creates a bridge: ZTBL agricultural credit + Musharakah equity = farmer becomes franchise operator (food drying, dairy processing, solar) without pure debt.

ZTBL Loan TypePortfolio %RateTermMax AmountMusharakah Bridge
Production (فصلی)45%12-15%1 yearRs. 15 LakhConvert to Musharakah → Food drying franchise
Development (ترقیاتی)25%10-14%5-7 yrsRs. 50 LakhSolar induction cooking franchise setup
Livestock (مویشی)15%11-13%3-5 yrsRs. 25 LakhDairy processing franchise
Tractor/Machinery10%9-12%5-7 yrsRs. 30 LakhSolar installation franchise tools
Kissan Card5%14-16%RevolvingRs. 5 LakhMicro-franchise starter capital

The ZTBL → Musharakah Conversion Process

Instead of pure interest-based ZTBL loans, we structure a hybrid: ZTBL provides equipment credit (Murabaha — cost-plus sale, Shariah-compliant). Community Musharakah pool provides working capital + training. Farmer operates franchise. ZTBL Murabaha is paid from franchise revenue. Community receives profit share. Farmer owns everything in 3-5 years.

Software: ZTBL API integration reads farmer's credit history, crop data, land records. Auto-qualifies for franchise types matching their agricultural expertise. ZTBL repayment schedule synced with Musharakah distribution calendar.

06 — Pension Fund & Institutional Investment
PKR 1,766+ Billion — Institutional Capital for Musharakah

Pakistan's pension and investment funds hold PKR 1.77 trillion in assets. Currently invested in government bonds (low return) and stocks (volatile). Musharakah in real productive franchises offers a new asset class: asset-backed, Shariah-compliant, direct economic impact.

InstitutionAUM (PKR B)Annual AllocationCurrent PortfolioMusharakah Allocation Target
EOBI (Pension)465Rs. 50BBonds 85%, Stocks 10%5% → PKR 23B for franchise Musharakah
NIT (Nat'l Investment)210Rs. 25BStocks 70%, Bonds 25%10% → PKR 21B for tech Musharakah
GPF (Govt Provident)280Rs. 30BGovt bonds 100%3% → PKR 8.4B pilot allocation
Military Funds400Rs. 50BReal estate, industry2% → PKR 8B franchise + datacenter
Benevolent Funds131Rs. 15BBonds, deposits5% → PKR 6.5B social impact
Akhuwat Foundation280Rs. 35BInterest-free loansNatural partner — 0% interest aligned
NRSP / Rural SupportRs. 15BCommunity lendingField operations partner
TOTAL TARGET1,766+PKR 67B addressable in Year 1-3
07 — Household Income Tier Integration
7 Income Tiers × Musharakah = 50 Million Households

Each of Pakistan's 50M households maps to an income tier. Each tier has a different Musharakah entry point, franchise type, and bank channel. The software auto-routes based on declared income and investment capacity.

TierMonthly IncomeInvestmentFranchise TypeBank ChannelMusharakah ModelHouseholds
🔴 Tier 1PKR 30,000PKR 20,000Food drying (micro)JazzCash/EasypaisaCommunity pool (mosque)15M
🟠 Tier 2PKR 50,000PKR 40,000Induction cookingMicrofinance + mobileWomen's group pool12M
🟡 Tier 3PKR 75,000PKR 80,000Solar installationBankIslamiVillage development pool10M
🟢 Tier 4PKR 100,000PKR 125,000Dairy processingMeezan + ZTBLBazaar merchant pool7M
🔵 Tier 5PKR 150,000PKR 250,000AI kiosk + digitalMeezan/Private IslamicUniversity innovation pool4M
🟣 Tier 6PKR 200,000PKR 500,000Multi-unit franchiseHBL/UBL Islamic windowDistrict-level pool1.5M
💎 Tier 7PKR 300,000PKR 1,000,000NoCodeAI platformPrivate bank + StripeProvincial/diaspora pool500K

Auto-Tier Detection in Software

When user registers and declares income, the system automatically: (1) assigns income tier, (2) calculates max investment capacity, (3) filters franchise types within budget, (4) selects appropriate bank channel, (5) recommends matching Musharakah pools, (6) generates tier-appropriate contract with scaled profit ratios. Tier 1-2 users get Urdu-first UI with voice guidance. Tier 5-7 get English dashboard with advanced analytics.

08 — Process Engine Details
Core Backend Processes — The Orchestration Layer

These are the 8 core processes that make the single-journey possible. Each runs as an independent microservice on Cloud Run, communicating via Pub/Sub events.

P1: Registration & KYC Router

Accepts registration from web, mobile, USSD, or postal code center. Detects user type. Routes to appropriate KYC flow. Stores verified profile in Firestore. Triggers bank provisioning.

Trigger: POST /auth/register
Events emitted: user.registered → kyc.started → kyc.verified → bank.provision.requested
Services: Firebase Auth, NADRA API, Stripe Identity, Document AI, OFAC

P2: Bank Gateway Router

Provisions bank accounts. Routes investment transfers. Handles multi-channel payments (Islamic IBFT, mobile money, Stripe, SWIFT). Manages FX conversion. Settlement reconciliation.

Trigger: bank.provision.requested | payment.initiated
Events emitted: bank.provisioned → payment.processed → ledger.entry.created
Integrations: 40+ bank APIs, JazzCash, Easypaisa, Stripe, RAAST (SBP)

P3: Pool Formation Engine

Creates Musharakah pools. Validates parameters (min/max capital, profit ratios, geographic restrictions). Tracks capital commitments. Manages pool lifecycle (fundraising → active → distributing → completed). Handles multi-source capital aggregation.

Trigger: pool.created | investment.committed
Events emitted: pool.target.reached → pool.activated → distribution.scheduled
Data: Firestore /pools collection with real-time listeners

P4: Shariah Compliance Engine

AI pre-screening of contracts (Gemini). Human review queue for Shariah board. Rule-based validation (profit/loss ratios, Halal activities, transparency). Certificate generation. Ongoing transaction monitoring.

Trigger: contract.generated | pool.created | transaction.flagged
AI: Gemini 2.5 Pro Shariah prompt + AAOIFI Standard 12 rules engine
Output: COMPLIANT | NEEDS_REVIEW | NON_COMPLIANT

P5: Contract Generator

Generates trilingual contracts (EN/UR/AR) from templates. Injects pool-specific terms, partner details, financial schedules. PDF rendering via WeasyPrint. E-signature workflow. Version control for amendments.

Templates: 8 contract types × 3 languages = 24 template variants
Trigger: investment.committed → contract.generate → shariah.review → sign → execute

P6: Franchise Deployment Engine

Manages franchise lifecycle from funded → training → procurement → installation → launch → operating. Tracks equipment, vendor payments, training completion, quality inspections. Links to ZTBL for agricultural franchises.

Franchise types: 12+ types with YAML config each (equipment BOM, training modules, revenue projections)
ZTBL link: Agricultural franchise auto-links farmer's ZTBL account for Murabaha equipment financing

P7: Profit Distribution Engine

Quarterly automated calculation. Multi-gateway payout (JazzCash for local, Stripe for APPNA, IBFT for bank-linked). Diminishing Musharakah equity updates. Zakat deduction. Tax reporting for US investors. BigQuery analytics.

Schedule: Cloud Scheduler runs 1st of Jan/Apr/Jul/Oct
Algorithm: Revenue - Expenses = Net → Profit × agreed ratio per partner → Multi-channel payout
Loss rule: Strictly proportional to capital (Shariah R3)

P8: APPNA & Diaspora Gateway

APPNA SSO integration. US/UK/Gulf KYC. OFAC/FinCEN compliance. Stripe Connect for payouts. Hometown matching algorithm. Social impact dashboard. Tax document generation (K-1 equivalent). Annual convention integration.

Compliance: OFAC SDN list, FinCEN BSA, FATCA reporting, IRS equity income rules
FX: Real-time SBP rate, no hidden spread, full transparency
09 — GCP Software Architecture
Complete Cloud Architecture — Ready for Claude Code
infrastructure/terraform/main.tf — GCP Services
# ═══════════════════════════════════════════
# GCP PROJECT: musharakah-franchise-platform
# REGION: asia-south1 (Mumbai — closest to PK)
# ═══════════════════════════════════════════

# Cloud Run Services (9 microservices)
# ──────────────────────────────────────
# 1. auth-service          → Firebase Auth + RBAC + KYC routing
# 2. banking-gateway       → 40+ bank API integrations
# 3. musharakah-engine     → Pool CRUD, partner mgmt, capital tracking
# 4. franchise-engine      → Unit lifecycle, operator mgmt, training
# 5. contract-engine       → Template rendering, PDF gen, e-signatures
# 6. financial-engine      → Ledger, profit calc, distributions, Zakat
# 7. ai-engine             → Vertex AI matching, Gemini compliance
# 8. appna-gateway         → APPNA SSO, US compliance, Stripe Connect
# 9. notification-engine   → SMS (Twilio), Email, WhatsApp, FCM push

# Data Layer
# ──────────────────────────────────────
# Firestore         → Primary DB (users, pools, franchises, contracts, ledger)
# BigQuery          → Analytics, financial reporting, ML training data
# Cloud Storage     → Contract PDFs, KYC docs, franchise photos, manuals
# Secret Manager    → API keys (40+ banks, Stripe, Twilio, NADRA)

# AI/ML Layer
# ──────────────────────────────────────
# Vertex AI         → Franchise matching model, risk scoring
# Gemini 2.5 Pro    → Shariah compliance checker, contract Q&A
# Claude API        → Document analysis, multilingual generation
# Document AI       → CNIC scanning, contract parsing

# Integration Layer
# ──────────────────────────────────────
# Cloud Pub/Sub     → Event bus (9 services communicate via events)
# Cloud Tasks       → Async job queue (payment processing, PDF gen)
# Cloud Scheduler   → Cron: quarterly distributions, daily reconciliation
# API Gateway       → Rate limiting, API key auth, request routing

# Estimated Monthly Cost
# ──────────────────────────────────────
# Cloud Run (9 services)  : $80-250
# Firestore               : $30-100
# BigQuery                : $20-50
# Cloud Storage            : $5-15
# Vertex AI + Gemini      : $50-200
# Pub/Sub + Tasks         : $10-20
# Firebase Auth            : Free (up to 50K MAU)
# Monitoring + Logging    : $10-20
# TOTAL                   : $205-655/month
Project File Structure — For Claude Code
musharakah-franchise-platform/
├── services/
│   ├── auth-service/
│   │   ├── main.py                    # FastAPI entry
│   │   ├── routers/auth.py            # Register, login, CNIC verify
│   │   ├── routers/kyc.py             # KYC routing (NADRA/Stripe/GCC)
│   │   ├── services/nadra_api.py      # NADRA CNIC verification
│   │   ├── services/stripe_identity.py # US/international KYC
│   │   ├── services/ofac_screening.py # OFAC/SDN list check
│   │   ├── services/rbac.py           # Role-based access control
│   │   ├── Dockerfile
│   │   └── requirements.txt
│   │
│   ├── banking-gateway/
│   │   ├── main.py
│   │   ├── routers/banks.py           # Bank provisioning + transfers
│   │   ├── routers/payments.py        # Multi-channel payment routing
│   │   ├── services/islamic_bank_api.py    # Meezan, BankIslami, Dubai Islamic
│   │   ├── services/govt_bank_api.py       # NBP, BoP, Sindh, BoK
│   │   ├── services/ztbl_api.py            # ZTBL agricultural credit
│   │   ├── services/raast_api.py           # SBP RAAST instant payment
│   │   ├── services/mobile_money_api.py    # JazzCash, Easypaisa
│   │   ├── services/stripe_service.py      # Stripe (APPNA/international)
│   │   ├── services/swift_gateway.py       # Institutional wire transfers
│   │   ├── services/fx_service.py          # Currency conversion (SBP rates)
│   │   ├── config/banks.yaml               # All 40+ bank configurations
│   │   ├── Dockerfile
│   │   └── requirements.txt
│   │
│   ├── musharakah-engine/
│   │   ├── main.py
│   │   ├── routers/pools.py           # Pool CRUD, lifecycle
│   │   ├── routers/partners.py        # Partner join/exit
│   │   ├── routers/investments.py     # Capital contribution flows
│   │   ├── routers/diminishing.py     # Diminishing Musharakah buyout
│   │   ├── services/pool_service.py
│   │   ├── services/profit_calculator.py   # Shariah-compliant P&L
│   │   ├── services/diminishing_engine.py  # Equity buyout schedule
│   │   ├── services/tier_router.py         # Income tier → pool matching
│   │   └── ...
│   │
│   ├── franchise-engine/
│   │   ├── main.py
│   │   ├── routers/units.py           # Franchise unit CRUD
│   │   ├── routers/operators.py
│   │   ├── routers/training.py
│   │   ├── services/matching_service.py    # AI franchise matching
│   │   ├── services/setup_wizard.py
│   │   ├── services/ztbl_bridge.py         # ZTBL↔franchise integration
│   │   ├── franchise_types/                # 12+ YAML configs
│   │   │   ├── induction_cooking.yaml
│   │   │   ├── food_drying.yaml
│   │   │   ├── solar_installation.yaml
│   │   │   ├── dairy_processing.yaml
│   │   │   ├── ai_services_kiosk.yaml
│   │   │   ├── inventor_workshop.yaml
│   │   │   ├── water_harvesting.yaml
│   │   │   ├── textile_production.yaml
│   │   │   └── digital_services.yaml
│   │   └── ...
│   │
│   ├── contract-engine/
│   │   ├── main.py
│   │   ├── routers/generate.py
│   │   ├── routers/signatures.py
│   │   ├── templates/                      # Trilingual contract templates
│   │   │   ├── musharakah_master.html
│   │   │   ├── franchise_musharakah.html
│   │   │   ├── diminishing_schedule.html
│   │   │   ├── appna_investment.html       # US-specific disclosures
│   │   │   ├── ztbl_murabaha_bridge.html   # ZTBL hybrid contract
│   │   │   ├── institutional_musharakah.html
│   │   │   ├── shariah_certificate.html
│   │   │   └── partner_exit.html
│   │   ├── generators/pdf_generator.py     # WeasyPrint HTML→PDF
│   │   └── ...
│   │
│   ├── financial-engine/
│   │   ├── main.py
│   │   ├── routers/ledger.py
│   │   ├── routers/distributions.py
│   │   ├── routers/reports.py
│   │   ├── services/ledger_service.py      # Double-entry accounting
│   │   ├── services/distribution_engine.py # Quarterly profit calc
│   │   ├── services/zakat_service.py       # 2.5% Zakat calculation
│   │   ├── services/tax_service.py         # US K-1 for APPNA, PK tax
│   │   ├── services/reconciliation.py      # Daily bank reconciliation
│   │   └── ...
│   │
│   ├── ai-engine/
│   │   ├── main.py
│   │   ├── routers/matching.py             # Franchise ↔ operator matching
│   │   ├── routers/compliance.py           # Shariah AI checker
│   │   ├── routers/projections.py          # Financial projections
│   │   ├── prompts/shariah_compliance.txt
│   │   ├── prompts/franchise_advisor.txt
│   │   ├── services/vertex_service.py
│   │   ├── services/gemini_service.py
│   │   └── ...
│   │
│   ├── appna-gateway/
│   │   ├── main.py
│   │   ├── routers/appna.py                # APPNA member registration
│   │   ├── routers/hometown.py             # Hometown pool matching
│   │   ├── routers/impact.py               # Social impact dashboard
│   │   ├── services/appna_sso.py           # APPNA OAuth2 integration
│   │   ├── services/us_compliance.py       # OFAC, FinCEN, FATCA
│   │   ├── services/impact_service.py      # Impact metrics calculation
│   │   ├── services/tax_docs.py            # K-1 generation for IRS
│   │   └── ...
│   │
│   └── notification-engine/
│       ├── main.py
│       ├── services/sms.py                 # Twilio (Urdu + English)
│       ├── services/whatsapp.py            # WhatsApp Business API
│       ├── services/email.py               # SendGrid
│       ├── services/push.py                # Firebase Cloud Messaging
│       └── templates/                      # Notification templates
│
├── frontend/
│   └── web-app/                            # Next.js 14 + Tailwind
│       ├── src/app/
│       │   ├── (auth)/login|register|kyc/
│       │   ├── (dashboard)/pools|franchises|contracts|portfolio/
│       │   ├── (appna)/invest|impact|hometown/    # APPNA portal
│       │   ├── (operator)/my-unit|reports|training/
│       │   ├── (shariah)/review|rulings/
│       │   └── (admin)/dashboard|kyc|pools/
│       └── ...
│
├── infrastructure/
│   ├── terraform/main.tf                   # All GCP resources
│   ├── docker/base.Dockerfile
│   └── cloudbuild.yaml                     # CI/CD pipeline
│
├── contracts/templates/                    # 8 contract templates × 3 langs
├── data/franchise_types/                   # 12+ YAML franchise configs
├── data/banks/config.yaml                  # 40+ bank API configurations
└── docs/api/openapi.yaml                   # Full API specification
10 — Complete API Specification
All Endpoints for Claude Code Implementation
API Endpoints — Full Specification
# ═══════════════════════════════════════════
# MUSHARAKAH INTEGRATION ENGINE — API v1
# Base URL: https://api.musharakah.kaamyabpakistan.org/v1
# ═══════════════════════════════════════════

# ── AUTH & KYC ──
POST   /auth/register                    # Register (all user types)
POST   /auth/login                       # Firebase token login
POST   /auth/kyc/verify-cnic             # NADRA CNIC verification
POST   /auth/kyc/verify-us              # US KYC (APPNA) via Stripe
POST   /auth/kyc/verify-gulf            # Gulf KYC (Emirates ID)
POST   /auth/kyc/verify-institutional   # Enhanced due diligence
GET    /auth/kyc/status/{uid}           # KYC status check
POST   /auth/appna/sso                  # APPNA SSO login

# ── BANKING GATEWAY ──
POST   /banking/provision                # Auto-provision bank account
POST   /banking/transfer                 # Route payment to bank
GET    /banking/accounts/{uid}           # User's linked accounts
POST   /banking/jazzcash/pay            # JazzCash payment
POST   /banking/easypaisa/pay           # Easypaisa payment
POST   /banking/ibft                    # Islamic bank IBFT
POST   /banking/raast                   # SBP RAAST instant
POST   /banking/stripe/charge           # Stripe (APPNA/intl)
POST   /banking/swift                   # Institutional wire
GET    /banking/fx/rate/{from}/{to}     # FX rate (SBP market)
POST   /banking/reconcile               # Daily reconciliation

# ── MUSHARAKAH POOLS ──
GET    /pools                            # List (filter: platform, region, status)
POST   /pools                            # Create pool
GET    /pools/{id}                       # Pool details
PUT    /pools/{id}                       # Update pool
POST   /pools/{id}/commit                # Commit capital
POST   /pools/{id}/activate              # Activate (after target met)
GET    /pools/{id}/partners              # List partners
POST   /pools/{id}/exit/{uid}           # Partner exit with valuation
GET    /pools/match/{uid}               # AI-matched pools for user
GET    /pools/hometown/{district}       # Pools by hometown (APPNA)
GET    /pools/tier/{tier_number}        # Pools by income tier

# ── FRANCHISE UNITS ──
GET    /franchises                       # List units
POST   /franchises                       # Create unit
GET    /franchises/{id}                  # Unit details
GET    /franchises/types                 # Available franchise types
POST   /franchises/{id}/deploy          # Begin deployment
POST   /franchises/{id}/train/complete  # Mark training done
POST   /franchises/{id}/inspect         # Quality inspection
POST   /franchises/{id}/launch          # Launch operations
POST   /franchises/{id}/reports         # Submit monthly report
GET    /franchises/{id}/performance     # Performance dashboard
GET    /franchises/match/{uid}          # AI franchise matching

# ── CONTRACTS ──
POST   /contracts/generate               # Generate from template
GET    /contracts/{id}                   # Get contract
GET    /contracts/{id}/pdf              # Download PDF
POST   /contracts/{id}/sign             # E-sign (with hash)
POST   /contracts/{id}/shariah-review   # Submit for review
POST   /contracts/{id}/approve          # Shariah board approve
GET    /contracts/templates             # Available templates
GET    /contracts/my/{uid}              # User's contracts

# ── FINANCIAL ──
GET    /finance/ledger/{poolId}          # Pool ledger entries
POST   /finance/distribute/calculate    # Calculate quarterly dist
POST   /finance/distribute/approve      # Approve distribution
POST   /finance/distribute/execute      # Execute multi-gateway payout
GET    /finance/diminishing/{poolId}    # Diminishing schedule
POST   /finance/zakat/calculate         # Zakat calculation
GET    /finance/reports/{poolId}        # Financial reports
GET    /finance/tax/k1/{uid}/{year}    # US K-1 for APPNA
POST   /finance/reconcile/daily        # Daily bank reconciliation

# ── AI SERVICES ──
POST   /ai/match-franchise              # AI franchise matching
POST   /ai/match-pool                   # AI pool matching
POST   /ai/risk-score                   # Investment risk assessment
POST   /ai/shariah-check                # Auto Shariah compliance
POST   /ai/financial-projection         # Revenue projection
POST   /ai/translate                    # EN ↔ UR ↔ AR translation
POST   /ai/contract-qa                  # Contract Q&A chatbot

# ── APPNA SPECIFIC ──
POST   /appna/register                   # APPNA member registration
GET    /appna/hometown-pools/{uid}      # Hometown matching
POST   /appna/invest                    # USD investment flow
GET    /appna/impact/{uid}              # Social impact dashboard
GET    /appna/tax-docs/{uid}/{year}    # US tax documents
GET    /appna/chapter/{chapter_id}     # Chapter aggregate stats

# ── ZTBL BRIDGE ──
POST   /ztbl/link-farmer                # Link ZTBL farmer account
GET    /ztbl/credit-history/{cnic}     # Farmer credit history
POST   /ztbl/murabaha-bridge           # Create Murabaha+Musharakah hybrid
GET    /ztbl/eligible-franchises/{uid} # Franchises matching farm profile

# ── PENSION/INSTITUTIONAL ──
POST   /institutional/register          # Institutional registration
POST   /institutional/due-diligence    # Submit DD package
POST   /institutional/allocate         # Allocate fund capital
GET    /institutional/portfolio/{id}   # Fund portfolio view
GET    /institutional/reports/{id}     # Institutional reports

# ── NOTIFICATIONS ──
GET    /notifications/{uid}              # User notifications
PUT    /notifications/{id}/read         # Mark read
POST   /notifications/broadcast/{poolId} # Broadcast to pool members

# ── ADMIN ──
GET    /admin/dashboard                  # System-wide metrics
GET    /admin/pools/pending             # Pools awaiting review
GET    /admin/kyc/queue                 # KYC review queue
POST   /admin/kyc/{uid}/approve        # Approve KYC
GET    /admin/banks/health             # Bank API health check
GET    /admin/distributions/pending    # Pending distributions
10B — Complete Technical Specifications for Claude Code
Pydantic Schemas, Firestore Rules, Indexes, Tests, Dependencies & Algorithms

These are the 8 critical specifications Claude Code needs to build every service correctly — data validation, security, queries, monitoring, testing, and the core financial algorithms.

① Pydantic Request/Response Schemas (all services)

services/shared/schemas.py — Core Pydantic Models
# ═══════════════════════════════════════════════════════
# SHARED PYDANTIC SCHEMAS — Used across all services
# ═══════════════════════════════════════════════════════

from pydantic import BaseModel, Field, validator
from typing import Optional, List, Literal
from datetime import datetime
from enum import Enum

# ── Enums ──
class UserRole(str, Enum):
    COMMUNITY_INVESTOR = "community_investor"
    EXTERNAL_FINANCIER = "external_financier"
    FRANCHISE_OPERATOR = "franchise_operator"
    MANAGING_PARTNER   = "managing_partner"
    SHARIAH_ADVISOR    = "shariah_advisor"
    PLATFORM_ADMIN     = "platform_admin"

class Platform(str, Enum):
    KAAMYABPAKISTAN = "kaamyabpakistan"
    YOUINVENT       = "youinvent"
    HOMEFRANCHISE   = "homefranchise"
    NOCODEAI        = "nocodeai"

class PoolType(str, Enum):
    SHIRKAT_AMWAL       = "shirkat_amwal"       # Capital partnership
    SHIRKAT_AMAL        = "shirkat_amal"        # Services partnership
    SHIRKAT_WUJUH       = "shirkat_wujuh"       # Goodwill partnership
    MUSHARAKAH_MUTANAQISAH = "musharakah_mutanaqisah"  # Diminishing

class PoolStatus(str, Enum):
    DRAFT           = "draft"
    SHARIAH_REVIEW  = "shariah_review"
    FUNDRAISING     = "fundraising"
    ACTIVE          = "active"
    DISTRIBUTING    = "distributing"
    COMPLETED       = "completed"

class FranchiseType(str, Enum):
    INDUCTION_COOKING   = "induction_cooking"
    FOOD_DRYING         = "food_drying"
    WATER_HARVESTING    = "water_harvesting"
    SOLAR_INSTALLATION  = "solar_installation"
    AI_SERVICES_KIOSK   = "ai_services_kiosk"
    INVENTOR_WORKSHOP   = "inventor_workshop"
    DAIRY_PROCESSING    = "dairy_processing"
    TEXTILE_PRODUCTION  = "textile_production"
    HERBAL_PROCESSING   = "herbal_processing"
    DIGITAL_SERVICES    = "digital_services"
    SAFFRON_AQUAPONIC   = "saffron_aquaponic"
    FISH_POND_CHINESE   = "fish_pond_chinese"

class BankChannel(str, Enum):
    ISLAMIC    = "islamic"
    GOVERNMENT = "government"
    ZTBL       = "ztbl"
    PRIVATE    = "private"
    MOBILE     = "mobile_money"
    STRIPE     = "stripe"
    WIRE       = "wire"

class PaymentMethod(str, Enum):
    JAZZCASH    = "jazzcash"
    EASYPAISA   = "easypaisa"
    BANK_IBFT   = "bank_ibft"
    STRIPE_CARD = "stripe_card"
    STRIPE_WIRE = "stripe_wire"

# ── User Schemas ──
class UserRegisterRequest(BaseModel):
    email: str
    phone: str = Field(..., regex=r"^\+92[0-9]{10}$")  # Pakistan format
    full_name_en: str
    full_name_ur: Optional[str] = None
    cnic: Optional[str] = Field(None, regex=r"^[0-9]{5}-[0-9]{7}-[0-9]$")
    passport: Optional[str] = None  # For diaspora
    role: UserRole
    platform_affiliation: List[Platform]
    province: Optional[str] = None
    district: Optional[str] = None
    postal_code: Optional[str] = None

class UserProfileResponse(BaseModel):
    uid: str
    email: str
    phone: str
    full_name: dict  # {"en": "...", "ur": "..."}
    role: UserRole
    kyc_status: Literal["pending", "submitted", "verified", "rejected"]
    bank_accounts: List[dict]
    income_tier: Optional[int] = None  # 1-7
    created_at: datetime

# ── Musharakah Pool Schemas ──
class PoolCreateRequest(BaseModel):
    pool_name: dict  # {"en": "...", "ur": "..."}
    platform: Platform
    pool_type: PoolType
    target_capital_pkr: float = Field(..., gt=0)
    minimum_investment_pkr: float = Field(10000, ge=10000)
    maximum_investment_pkr: Optional[float] = None
    profit_sharing: dict  # {"community_pct": 40, "financier_pct": 35, ...}
    loss_sharing: str = "proportional_to_capital"  # ALWAYS this per Shariah
    diminishing_enabled: bool = False
    buyout_period_months: Optional[int] = None
    franchise_type: Optional[FranchiseType] = None
    target_region: dict  # {"province": "...", "district": "..."}
    description: dict  # {"en": "...", "ur": "..."}

    @validator("profit_sharing")
    def validate_profit_shares(cls, v):
        total = sum(v.values())
        if abs(total - 100) > 0.01:
            raise ValueError(f"Profit shares must sum to 100%, got {total}%")
        return v

class PoolResponse(BaseModel):
    pool_id: str  # MKP-2026-XXXXX
    pool_name: dict
    platform: Platform
    pool_type: PoolType
    status: PoolStatus
    target_capital: float
    raised_capital: float
    partner_count: int
    profit_sharing: dict
    franchise_type: Optional[FranchiseType]
    shariah_approved: bool
    created_at: datetime
    updated_at: datetime

class InvestRequest(BaseModel):
    pool_id: str
    amount_pkr: float = Field(..., ge=10000)
    payment_method: PaymentMethod
    payment_account_id: Optional[str] = None

class InvestResponse(BaseModel):
    investment_id: str
    pool_id: str
    amount_pkr: float
    equity_percentage: float
    payment_status: Literal["pending", "completed", "failed"]
    contract_id: str
    transaction_ref: str

# ── Franchise Schemas ──
class FranchiseApplyRequest(BaseModel):
    franchise_type: FranchiseType
    pool_id: str
    location: dict  # {"province", "district", "tehsil", "postal_code", "lat", "lng"}
    operator_cnic: str
    skills_assessment: dict  # From AI matching quiz
    education_level: str
    experience_years: int

class FranchiseUnitResponse(BaseModel):
    franchise_id: str  # HF-2026-XXXXX
    franchise_type: FranchiseType
    operator_id: str
    pool_id: str
    status: Literal["setup", "training", "operating", "paused", "closed"]
    setup_cost_pkr: float
    monthly_revenue_target: float
    monthly_revenue_actual: float
    operator_ownership_pct: float  # Increases with diminishing Musharakah
    training_progress: dict
    equipment_status: dict

# ── Financial Schemas ──
class ProfitDistributionRequest(BaseModel):
    pool_id: str
    period: str  # "2026-Q1" or "2026-03"

class ProfitDistributionResponse(BaseModel):
    distribution_id: str
    pool_id: str
    period: str
    total_revenue: float
    total_expenses: float
    net_profit: float  # Can be negative (loss)
    distributions: List[dict]  # Per-partner breakdown
    zakat_total: float
    status: Literal["calculating", "review", "approved", "distributed"]

# ── Contract Schemas ──
class ContractGenerateRequest(BaseModel):
    template_id: str  # "musharakah_master", "franchise_musharakah", etc.
    pool_id: str
    parties: List[dict]  # [{"user_id", "role", "name"}]
    language: Literal["en", "ur", "bilingual", "trilingual"]
    custom_clauses: Optional[List[str]] = None

class ContractSignRequest(BaseModel):
    contract_id: str
    signature_data: str  # Base64 canvas signature
    signer_uid: str

# ── Banking Schemas ──
class BankProvisionRequest(BaseModel):
    user_id: str
    user_type: UserRole
    preferred_channel: Optional[BankChannel] = None
    location: dict

class BankProvisionResponse(BaseModel):
    account_id: str
    bank_name: str
    channel: BankChannel
    account_number: str
    iban: Optional[str] = None
    wallet_id: Optional[str] = None

# ── APPNA Schemas ──
class APPNAInvestRequest(BaseModel):
    appna_member_id: str
    amount_usd: float = Field(..., ge=100)
    hometown_postal_code: str  # Pakistan postal code
    preferred_platform: Optional[Platform] = None
    preferred_franchise_type: Optional[FranchiseType] = None
    payment_method: Literal["stripe_card", "stripe_ach", "wire"]

class APPNAMatchResponse(BaseModel):
    member_id: str
    hometown: dict
    matching_pools: List[dict]  # Ranked by relevance
    social_impact_score: float
    projected_roi_annual: float
    fx_rate_usd_pkr: float

② Firestore Security Rules

firestore.rules — Complete security rules
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    // ── Helper functions ──
    function isAuthenticated() {
      return request.auth != null;
    }
    function isOwner(userId) {
      return request.auth.uid == userId;
    }
    function hasRole(role) {
      return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == role;
    }
    function isAdmin() {
      return hasRole('platform_admin');
    }
    function isShariahAdvisor() {
      return hasRole('shariah_advisor');
    }
    function isManagingPartner() {
      return hasRole('managing_partner');
    }
    function isPartnerInPool(poolId) {
      return request.auth.uid in get(/databases/$(database)/documents/pools/$(poolId)).data.partner_uids;
    }

    // ── Users collection ──
    match /users/{userId} {
      allow read: if isAuthenticated() && (isOwner(userId) || isAdmin() || isManagingPartner());
      allow create: if isAuthenticated() && isOwner(userId);
      allow update: if isAuthenticated() && (isOwner(userId) || isAdmin());
      allow delete: if isAdmin();

      // KYC subcollection
      match /kyc_documents/{docId} {
        allow read: if isAuthenticated() && (isOwner(userId) || isAdmin());
        allow create: if isAuthenticated() && isOwner(userId);
        allow update: if isAdmin();
      }
    }

    // ── Musharakah Pools ──
    match /pools/{poolId} {
      allow read: if isAuthenticated();  // All authenticated users can browse
      allow create: if isAuthenticated() && (isManagingPartner() || isAdmin());
      allow update: if isAuthenticated() &&
        (isManagingPartner() || isAdmin() ||
         (isShariahAdvisor() && request.resource.data.diff(resource.data).affectedKeys()
           .hasOnly(['shariah_approved','shariah_reviewer_id','shariah_notes','shariah_approved_at','status'])));
      allow delete: if isAdmin() && resource.data.status == 'draft';

      // Partners subcollection
      match /partners/{partnerId} {
        allow read: if isAuthenticated() && (isPartnerInPool(poolId) || isManagingPartner() || isAdmin());
        allow create: if isAuthenticated();  // Anyone can join (invest)
        allow update: if isAuthenticated() && (isManagingPartner() || isAdmin());
      }
    }

    // ── Franchise Units ──
    match /franchises/{franchiseId} {
      allow read: if isAuthenticated();
      allow create: if isAuthenticated() && (isManagingPartner() || isAdmin());
      allow update: if isAuthenticated() &&
        (resource.data.operator_id == request.auth.uid ||
         isManagingPartner() || isAdmin());

      // Monthly reports
      match /reports/{reportId} {
        allow read: if isAuthenticated() && (isPartnerInPool(resource.data.pool_id) || isAdmin());
        allow create: if isAuthenticated() && resource.data.operator_id == request.auth.uid;
        allow update: if isManagingPartner() || isAdmin();
      }
    }

    // ── Contracts ──
    match /contracts/{contractId} {
      allow read: if isAuthenticated() &&
        (request.auth.uid in resource.data.party_uids || isShariahAdvisor() || isAdmin());
      allow create: if isAuthenticated() && (isManagingPartner() || isAdmin());
      allow update: if isAuthenticated() &&
        (request.auth.uid in resource.data.party_uids ||
         isShariahAdvisor() || isAdmin());
    }

    // ── Ledger (financial records) — Read-only for partners ──
    match /ledger/{entryId} {
      allow read: if isAuthenticated() &&
        (isPartnerInPool(resource.data.pool_id) || isManagingPartner() || isAdmin());
      allow create: if isAuthenticated() && (isManagingPartner() || isAdmin());
      allow update: if false;  // Ledger entries are immutable
      allow delete: if false;  // Never delete financial records
    }

    // ── Profit Distributions ──
    match /distributions/{distId} {
      allow read: if isAuthenticated() &&
        (isPartnerInPool(resource.data.pool_id) || isAdmin());
      allow create: if isManagingPartner() || isAdmin();
      allow update: if isManagingPartner() || isAdmin() || isShariahAdvisor();
    }

    // ── Platform Projects ──
    match /projects/{projectId} {
      allow read: if isAuthenticated();
      allow write: if isManagingPartner() || isAdmin();
    }
  }
}

③ Firestore Composite Indexes

firestore.indexes.json — Required composite indexes
{
  "indexes": [
    {
      "collectionGroup": "pools",
      "queryScope": "COLLECTION",
      "fields": [
        {"fieldPath": "platform", "order": "ASCENDING"},
        {"fieldPath": "status", "order": "ASCENDING"},
        {"fieldPath": "created_at", "order": "DESCENDING"}
      ]
    },
    {
      "collectionGroup": "pools",
      "queryScope": "COLLECTION",
      "fields": [
        {"fieldPath": "target_region.province", "order": "ASCENDING"},
        {"fieldPath": "pool_type", "order": "ASCENDING"},
        {"fieldPath": "status", "order": "ASCENDING"}
      ]
    },
    {
      "collectionGroup": "pools",
      "queryScope": "COLLECTION",
      "fields": [
        {"fieldPath": "franchise_type", "order": "ASCENDING"},
        {"fieldPath": "status", "order": "ASCENDING"},
        {"fieldPath": "raised_capital", "order": "DESCENDING"}
      ]
    },
    {
      "collectionGroup": "ledger",
      "queryScope": "COLLECTION",
      "fields": [
        {"fieldPath": "pool_id", "order": "ASCENDING"},
        {"fieldPath": "entry_type", "order": "ASCENDING"},
        {"fieldPath": "created_at", "order": "DESCENDING"}
      ]
    },
    {
      "collectionGroup": "franchises",
      "queryScope": "COLLECTION",
      "fields": [
        {"fieldPath": "franchise_type", "order": "ASCENDING"},
        {"fieldPath": "location.province", "order": "ASCENDING"},
        {"fieldPath": "status", "order": "ASCENDING"}
      ]
    },
    {
      "collectionGroup": "contracts",
      "queryScope": "COLLECTION",
      "fields": [
        {"fieldPath": "pool_id", "order": "ASCENDING"},
        {"fieldPath": "status", "order": "ASCENDING"},
        {"fieldPath": "created_at", "order": "DESCENDING"}
      ]
    },
    {
      "collectionGroup": "distributions",
      "queryScope": "COLLECTION",
      "fields": [
        {"fieldPath": "pool_id", "order": "ASCENDING"},
        {"fieldPath": "period", "order": "DESCENDING"}
      ]
    },
    {
      "collectionGroup": "users",
      "queryScope": "COLLECTION",
      "fields": [
        {"fieldPath": "role", "order": "ASCENDING"},
        {"fieldPath": "location.province", "order": "ASCENDING"},
        {"fieldPath": "kyc_status", "order": "ASCENDING"}
      ]
    }
  ],
  "fieldOverrides": []
}

④ Profit Distribution & Diminishing Musharakah Algorithms

services/financial-engine/algorithms/profit_distribution.py
# ═══════════════════════════════════════════════════════
# SHARIAH-COMPLIANT PROFIT DISTRIBUTION ENGINE
# Key rule: Profit per AGREED ratio, Loss per CAPITAL ratio
# ═══════════════════════════════════════════════════════

from dataclasses import dataclass
from typing import List, Optional
from decimal import Decimal, ROUND_HALF_UP
import logging

logger = logging.getLogger("financial_engine.profit_distribution")

@dataclass
class PartnerShare:
    user_id: str
    partner_type: str        # community_investor | external_financier | operator | managing_partner
    capital_contributed: Decimal
    capital_percentage: Decimal   # For LOSS allocation (Shariah: proportional to capital)
    profit_ratio: Decimal         # For PROFIT allocation (can differ from capital %)
    zakat_opt_in: bool = False

@dataclass
class DistributionResult:
    user_id: str
    partner_type: str
    gross_amount: Decimal
    zakat_deducted: Decimal
    platform_fee: Decimal
    net_amount: Decimal
    is_profit: bool    # True = profit distribution, False = loss allocation

def calculate_distribution(
    pool_id: str,
    period: str,
    total_revenue: Decimal,
    total_expenses: Decimal,
    partners: List[PartnerShare],
    platform_fee_pct: Decimal = Decimal("5.0"),
    zakat_rate: Decimal = Decimal("2.5"),
    zakat_annual_prorate: bool = True,  # Prorate 2.5% annually to period
    period_months: int = 3,  # Quarterly = 3
) -> List[DistributionResult]:
    """
    Core Shariah-compliant profit/loss distribution.
    
    PROFIT: distributed per agreed profit_ratio (may reward active management)
    LOSS:   distributed per capital_percentage ONLY (Shariah requirement)
    """
    net_profit = total_revenue - total_expenses
    results = []

    logger.info(f"Pool {pool_id} | Period {period} | Revenue: {total_revenue} | "
                f"Expenses: {total_expenses} | Net: {net_profit}")

    if net_profit > 0:
        # ── PROFIT SCENARIO ──
        # Step 1: Deduct platform fee
        platform_fee_total = (net_profit * platform_fee_pct / 100).quantize(Decimal("0.01"))
        distributable = net_profit - platform_fee_total

        # Step 2: Distribute per AGREED PROFIT RATIO
        for partner in partners:
            gross = (distributable * partner.profit_ratio / 100).quantize(
                Decimal("0.01"), rounding=ROUND_HALF_UP
            )

            # Step 3: Optional Zakat deduction
            zakat = Decimal("0")
            if partner.zakat_opt_in:
                if zakat_annual_prorate:
                    # Prorate 2.5% annual to this period
                    zakat = (gross * zakat_rate / 100 * period_months / 12).quantize(Decimal("0.01"))
                else:
                    zakat = (gross * zakat_rate / 100).quantize(Decimal("0.01"))

            # Per-partner platform fee (proportional)
            partner_platform_fee = (platform_fee_total * partner.profit_ratio / 100).quantize(Decimal("0.01"))

            results.append(DistributionResult(
                user_id=partner.user_id,
                partner_type=partner.partner_type,
                gross_amount=gross,
                zakat_deducted=zakat,
                platform_fee=partner_platform_fee,
                net_amount=gross - zakat,
                is_profit=True,
            ))

        logger.info(f"PROFIT distributed to {len(partners)} partners. Platform fee: {platform_fee_total}")

    elif net_profit < 0:
        # ── LOSS SCENARIO ──
        # Shariah requirement: Loss MUST be proportional to CAPITAL only
        # profit_ratio is IGNORED for losses
        loss = abs(net_profit)

        for partner in partners:
            loss_share = (loss * partner.capital_percentage / 100).quantize(
                Decimal("0.01"), rounding=ROUND_HALF_UP
            )
            results.append(DistributionResult(
                user_id=partner.user_id,
                partner_type=partner.partner_type,
                gross_amount=-loss_share,  # Negative = loss
                zakat_deducted=Decimal("0"),
                platform_fee=Decimal("0"),  # No fee on losses
                net_amount=-loss_share,
                is_profit=False,
            ))

        logger.warning(f"LOSS of {loss} allocated to {len(partners)} partners by capital ratio")

    else:
        # Break-even: no distribution
        logger.info(f"Break-even for pool {pool_id} period {period}")

    return results


# ═══════════════════════════════════════════════════════
# DIMINISHING MUSHARAKAH SCHEDULE ENGINE
# Operator buys out financier equity units over time
# ═══════════════════════════════════════════════════════

@dataclass
class BuyoutScheduleEntry:
    period: int           # Month number
    units_purchased: int
    unit_price: Decimal
    payment_amount: Decimal
    operator_units_after: int
    financier_units_after: int
    operator_ownership_pct: Decimal
    cumulative_paid: Decimal

def generate_diminishing_schedule(
    total_units: int,
    buyout_period_months: int,
    unit_price_method: str,  # "book_value" or "fair_market"
    initial_unit_price: Decimal,
    appreciation_rate_annual: Decimal = Decimal("0"),  # For fair_market
    buyout_frequency_months: int = 1,  # Monthly buyout
) -> List[BuyoutScheduleEntry]:
    """
    Generate complete diminishing Musharakah buyout schedule.
    Operator purchases equity units each period until 100% ownership.
    """
    units_per_period = total_units // (buyout_period_months // buyout_frequency_months)
    remainder = total_units % (buyout_period_months // buyout_frequency_months)

    schedule = []
    operator_units = 0
    cumulative = Decimal("0")
    monthly_appreciation = (1 + appreciation_rate_annual / 100) ** (Decimal("1") / 12)

    for period in range(buyout_frequency_months, buyout_period_months + 1, buyout_frequency_months):
        # Calculate unit price for this period
        if unit_price_method == "book_value":
            price = initial_unit_price  # Fixed
        else:  # fair_market — appreciates
            months_elapsed = period
            price = (initial_unit_price * monthly_appreciation ** months_elapsed).quantize(Decimal("0.01"))

        # Last period gets remainder units
        units_this = units_per_period + (remainder if period >= buyout_period_months else 0)
        payment = (price * units_this).quantize(Decimal("0.01"))

        operator_units += units_this
        cumulative += payment
        financier_units = total_units - operator_units
        ownership_pct = (Decimal(operator_units) / total_units * 100).quantize(Decimal("0.01"))

        schedule.append(BuyoutScheduleEntry(
            period=period,
            units_purchased=units_this,
            unit_price=price,
            payment_amount=payment,
            operator_units_after=operator_units,
            financier_units_after=financier_units,
            operator_ownership_pct=ownership_pct,
            cumulative_paid=cumulative,
        ))

    return schedule

⑤ Dependencies — requirements.txt per service

services/shared/requirements-base.txt
# ── Base dependencies (all services) ──
fastapi==0.109.0
uvicorn[standard]==0.27.0
pydantic==2.5.3
python-dotenv==1.0.0
httpx==0.26.0
google-cloud-firestore==2.14.0
google-cloud-storage==2.14.0
google-cloud-secret-manager==2.18.0
firebase-admin==6.4.0
python-jose[cryptography]==3.3.0  # JWT
passlib[bcrypt]==1.7.4
python-multipart==0.0.6
structlog==24.1.0  # Structured logging
tenacity==8.2.3    # Retry logic
services/financial-engine/requirements.txt
-r ../shared/requirements-base.txt
# ── Financial engine specific ──
google-cloud-bigquery==3.17.0
google-cloud-scheduler==2.13.0
pandas==2.1.4
numpy==1.26.3
forex-python==1.8    # FX rates
services/contract-engine/requirements.txt
-r ../shared/requirements-base.txt
# ── Contract engine specific ──
weasyprint==60.2     # HTML → PDF
jinja2==3.1.3        # Template rendering
google-cloud-documentai==2.24.0
services/ai-engine/requirements.txt
-r ../shared/requirements-base.txt
# ── AI engine specific ──
google-cloud-aiplatform==1.40.0  # Vertex AI
anthropic==0.18.0   # Claude API
google-generativeai==0.4.0  # Gemini
scikit-learn==1.4.0  # Matching algo
services/banking-gateway/requirements.txt
-r ../shared/requirements-base.txt
# ── Banking gateway specific ──
stripe==8.4.0
requests==2.31.0    # JazzCash/Easypaisa REST
cryptography==42.0.0  # HMAC for payment signatures
services/appna-gateway/requirements.txt
-r ../shared/requirements-base.txt
# ── APPNA gateway specific ──
stripe==8.4.0
stripe-identity==0.1.0  # Stripe Identity (KYC)
ofac-screening==1.2.0   # OFAC/SDN check
us-tax-forms==0.3.0     # K-1 generation
services/notification-engine/requirements.txt
-r ../shared/requirements-base.txt
# ── Notification specific ──
twilio==8.12.0       # SMS
sendgrid==6.11.0     # Email
firebase-admin>=6.4.0  # Push (FCM)
frontend/web-app/package.json (dependencies)
{
  "dependencies": {
    "next": "14.1.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "tailwindcss": "3.4.1",
    "firebase": "10.8.0",
    "@stripe/stripe-js": "2.4.0",
    "recharts": "2.10.3",
    "react-hook-form": "7.49.3",
    "zod": "3.22.4",
    "next-intl": "3.5.4",
    "signature_pad": "4.1.7",
    "date-fns": "3.3.1",
    "lucide-react": "0.312.0",
    "@radix-ui/react-dialog": "1.0.5",
    "@radix-ui/react-dropdown-menu": "2.0.6"
  }
}

⑥ Cloud Logging, Monitoring & Alerting

infrastructure/monitoring/logging_config.py — Structured logging
# ═══════════════════════════════════════════════════════
# STRUCTURED LOGGING — All services use this
# Sends to Google Cloud Logging automatically on Cloud Run
# ═══════════════════════════════════════════════════════

import structlog
import google.cloud.logging
from google.cloud.logging_v2.handlers import CloudLoggingHandler

def setup_logging(service_name: str):
    """Initialize structured logging for a service."""
    client = google.cloud.logging.Client()
    handler = CloudLoggingHandler(client, name=service_name)

    structlog.configure(
        processors=[
            structlog.processors.TimeStamper(fmt="iso"),
            structlog.processors.add_log_level,
            structlog.processors.StackInfoRenderer(),
            structlog.processors.format_exc_info,
            structlog.processors.JSONRenderer(),
        ],
        wrapper_class=structlog.BoundLogger,
        context_class=dict,
        logger_factory=structlog.PrintLoggerFactory(),
    )
    return structlog.get_logger(service=service_name)

# Usage in any service:
# logger = setup_logging("musharakah-engine")
# logger.info("pool_created", pool_id="MKP-2026-00001", capital=500000)
# logger.warning("shariah_review_pending", pool_id="MKP-2026-00001")
# logger.error("payment_failed", user_id="...", amount=10000, provider="jazzcash")
infrastructure/terraform/monitoring.tf — Alerts & Dashboards
# ═══════════════════════════════════════════════════════
# CLOUD MONITORING — Alerts for critical operations
# ═══════════════════════════════════════════════════════

resource "google_monitoring_alert_policy" "payment_failures" {
  display_name = "Payment Failure Rate > 5%"
  combiner     = "OR"
  conditions {
    display_name = "High payment failure rate"
    condition_threshold {
      filter          = "resource.type=\"cloud_run_revision\" AND metric.type=\"logging.googleapis.com/user/payment_failed\""
      comparison      = "COMPARISON_GT"
      threshold_value = 5
      duration        = "300s"
      aggregations {
        alignment_period   = "60s"
        per_series_aligner = "ALIGN_RATE"
      }
    }
  }
  notification_channels = [google_monitoring_notification_channel.ops_email.name]
}

resource "google_monitoring_alert_policy" "shariah_queue" {
  display_name = "Shariah Review Queue > 50 pending"
  combiner     = "OR"
  conditions {
    display_name = "Shariah review backlog"
    condition_threshold {
      filter          = "resource.type=\"cloud_run_revision\" AND metric.type=\"logging.googleapis.com/user/shariah_review_pending\""
      comparison      = "COMPARISON_GT"
      threshold_value = 50
      duration        = "600s"
    }
  }
  notification_channels = [google_monitoring_notification_channel.ops_email.name]
}

resource "google_monitoring_alert_policy" "pool_funding_complete" {
  display_name = "Pool Fully Funded"
  combiner     = "OR"
  conditions {
    display_name = "Pool reached target capital"
    condition_threshold {
      filter     = "metric.type=\"logging.googleapis.com/user/pool_fully_funded\""
      comparison = "COMPARISON_GT"
      threshold_value = 0
      duration   = "0s"
    }
  }
  notification_channels = [google_monitoring_notification_channel.ops_email.name]
}

resource "google_monitoring_notification_channel" "ops_email" {
  display_name = "Operations Team"
  type         = "email"
  labels       = { email_address = "ops@kaamyabpakistan.org" }
}

# Custom metrics for dashboard
resource "google_monitoring_dashboard" "musharakah_dashboard" {
  dashboard_json = jsonencode({
    displayName = "Musharakah Platform Dashboard"
    gridLayout = { columns = 3, widgets = [
      { title = "Active Pools",        scorecard = { timeSeriesQuery = { timeSeriesFilter = { filter = "metric.type=\"logging.googleapis.com/user/active_pools\"" }}}},
      { title = "Total Invested (PKR)", scorecard = { timeSeriesQuery = { timeSeriesFilter = { filter = "metric.type=\"logging.googleapis.com/user/total_invested\"" }}}},
      { title = "Franchise Units Live", scorecard = { timeSeriesQuery = { timeSeriesFilter = { filter = "metric.type=\"logging.googleapis.com/user/franchise_units_active\"" }}}},
      { title = "Payment Success Rate", scorecard = { timeSeriesQuery = { timeSeriesFilter = { filter = "metric.type=\"logging.googleapis.com/user/payment_success_rate\"" }}}},
      { title = "APPNA Investments",    scorecard = { timeSeriesQuery = { timeSeriesFilter = { filter = "metric.type=\"logging.googleapis.com/user/appna_investments\"" }}}},
      { title = "Shariah Queue",        scorecard = { timeSeriesQuery = { timeSeriesFilter = { filter = "metric.type=\"logging.googleapis.com/user/shariah_review_pending\"" }}}},
    ]}
  })
}

⑦ Seed Data Script

scripts/seed_data.py — Development seed data
# ═══════════════════════════════════════════════════════
# SEED DATA — Run once to populate dev/staging Firestore
# python scripts/seed_data.py --env=dev
# ═══════════════════════════════════════════════════════

import firebase_admin
from firebase_admin import credentials, firestore
import json, sys, os

def seed_franchise_types(db):
    """Seed 12 franchise type configurations."""
    types = [
        {"id": "induction_cooking",  "name_en": "48V DC Solar Induction Cooking", "name_ur": "سولر انڈکشن کوکنگ",
         "setup_cost_min": 72000, "setup_cost_max": 113000, "setup_cost_typical": 85000,
         "monthly_revenue_target": 65000, "monthly_operating_cost": 8000, "break_even_months": 2,
         "equipment": [
           {"item": "4x 400W Solar Panels", "cost": 17500},
           {"item": "MPPT Controller 48V/60A", "cost": 10000},
           {"item": "LiFePO4 Battery 48V 100Ah", "cost": 45000},
           {"item": "DC Induction Cooker (local)", "cost": 8000},
           {"item": "Wiring + Installation", "cost": 4500}
         ],
         "training_modules": ["Solar Installation 8hr", "Cooker Operation 6hr", "Food Dehydration 4hr", "Business Mgmt 6hr"],
         "target_regions": ["Thar", "Cholistan", "Southern Punjab", "Balochistan"]},
        {"id": "food_drying",  "name_en": "Solar Food Drying Unit", "name_ur": "سولر فوڈ ڈرائنگ",
         "setup_cost_typical": 95000, "monthly_revenue_target": 80000, "break_even_months": 2,
         "target_regions": ["Sindh", "Punjab", "Balochistan"]},
        {"id": "water_harvesting", "name_en": "Desiccant Water Harvesting", "name_ur": "پانی کی کٹائی",
         "setup_cost_typical": 120000, "monthly_revenue_target": 45000, "break_even_months": 4,
         "target_regions": ["Thar", "Cholistan", "Thal Desert"]},
        {"id": "solar_installation", "name_en": "Solar System Installation", "name_ur": "سولر سسٹم انسٹالیشن",
         "setup_cost_typical": 150000, "monthly_revenue_target": 100000, "break_even_months": 2},
        {"id": "ai_services_kiosk", "name_en": "NoCodeAI Service Kiosk", "name_ur": "AI سروس کیوسک",
         "setup_cost_typical": 200000, "monthly_revenue_target": 120000, "break_even_months": 3},
        {"id": "dairy_processing", "name_en": "Dairy Processing Unit", "name_ur": "ڈیری پروسیسنگ",
         "setup_cost_typical": 250000, "monthly_revenue_target": 150000, "break_even_months": 3},
        {"id": "textile_production", "name_en": "Home Textile Production", "name_ur": "ٹیکسٹائل پروڈکشن",
         "setup_cost_typical": 180000, "monthly_revenue_target": 90000, "break_even_months": 3},
        {"id": "saffron_aquaponic", "name_en": "Saffron Indoor Aquaponic Farm", "name_ur": "زعفران ایکواپونک",
         "setup_cost_typical": 500000, "monthly_revenue_target": 300000, "break_even_months": 4},
        {"id": "fish_pond_chinese", "name_en": "Chinese Integrated Pond System", "name_ur": "چینی مچھلی تالاب",
         "setup_cost_typical": 350000, "monthly_revenue_target": 200000, "break_even_months": 3},
    ]
    for ft in types:
        db.collection("franchise_types").document(ft["id"]).set(ft)
    print(f"  ✅ Seeded {len(types)} franchise types")

def seed_sample_pool(db):
    """Create a sample Musharakah pool for testing."""
    pool = {
        "pool_id": "MKP-2026-00001",
        "pool_name": {"en": "Thar Solar Cooking Musharakah", "ur": "تھر سولر کوکنگ مشارکہ"},
        "platform": "homefranchise", "pool_type": "musharakah_mutanaqisah",
        "status": "fundraising", "target_capital": 500000, "raised_capital": 0,
        "minimum_investment": 10000, "maximum_investment": 100000,
        "profit_sharing": {"community_pct": 40, "financier_pct": 30, "managing_pct": 15, "operator_pct": 10, "platform_pct": 5},
        "loss_sharing": "proportional_to_capital",
        "diminishing_enabled": True, "buyout_period_months": 36,
        "franchise_type": "induction_cooking",
        "target_region": {"province": "Sindh", "district": "Tharparkar"},
        "partners": [], "partner_uids": [],
        "shariah_approved": False, "created_at": firestore.SERVER_TIMESTAMP,
    }
    db.collection("pools").document(pool["pool_id"]).set(pool)
    print(f"  ✅ Seeded sample pool: {pool['pool_id']}")

def seed_test_users(db):
    """Create test users for each role."""
    users = [
        {"uid": "test-admin-001", "email": "admin@kaamyabpakistan.org", "role": "platform_admin", "full_name": {"en": "Admin User"}},
        {"uid": "test-investor-001", "email": "investor@test.pk", "role": "community_investor", "cnic": "41303-1234567-1", "income_tier": 3},
        {"uid": "test-operator-001", "email": "operator@test.pk", "role": "franchise_operator", "cnic": "41303-7654321-2"},
        {"uid": "test-shariah-001", "email": "shariah@test.pk", "role": "shariah_advisor"},
        {"uid": "test-appna-001", "email": "doctor@appna.org", "role": "external_financier", "appna_member_id": "APPNA-12345"},
    ]
    for u in users:
        db.collection("users").document(u["uid"]).set({**u, "kyc_status": "verified", "created_at": firestore.SERVER_TIMESTAMP})
    print(f"  ✅ Seeded {len(users)} test users")

if __name__ == "__main__":
    env = sys.argv[1].replace("--env=", "") if len(sys.argv) > 1 else "dev"
    cred = credentials.ApplicationDefault()
    firebase_admin.initialize_app(cred, {"projectId": f"musharakah-franchise-{env}"})
    db = firestore.client()
    print(f"Seeding {env} environment...")
    seed_franchise_types(db)
    seed_sample_pool(db)
    seed_test_users(db)
    print("✅ Seed complete!")

⑧ Testing Specifications — pytest

services/financial-engine/tests/test_profit_distribution.py
# ═══════════════════════════════════════════════════════
# TESTS — Profit Distribution Algorithm
# Run: pytest services/financial-engine/tests/ -v
# ═══════════════════════════════════════════════════════

import pytest
from decimal import Decimal
from algorithms.profit_distribution import (
    calculate_distribution, generate_diminishing_schedule, PartnerShare
)

@pytest.fixture
def sample_partners():
    return [
        PartnerShare(user_id="community-1", partner_type="community_investor",
                     capital_contributed=Decimal("200000"), capital_percentage=Decimal("40"),
                     profit_ratio=Decimal("40"), zakat_opt_in=True),
        PartnerShare(user_id="financier-1", partner_type="external_financier",
                     capital_contributed=Decimal("200000"), capital_percentage=Decimal("40"),
                     profit_ratio=Decimal("30")),
        PartnerShare(user_id="operator-1", partner_type="franchise_operator",
                     capital_contributed=Decimal("50000"), capital_percentage=Decimal("10"),
                     profit_ratio=Decimal("20")),  # Higher profit ratio rewards active management
        PartnerShare(user_id="manager-1", partner_type="managing_partner",
                     capital_contributed=Decimal("50000"), capital_percentage=Decimal("10"),
                     profit_ratio=Decimal("10")),
    ]

class TestProfitDistribution:

    def test_profit_shares_sum_correctly(self, sample_partners):
        """All profit distributions + platform fee = net profit."""
        results = calculate_distribution(
            pool_id="TEST-001", period="2026-Q1",
            total_revenue=Decimal("200000"), total_expenses=Decimal("50000"),
            partners=sample_partners, platform_fee_pct=Decimal("5"),
        )
        total_distributed = sum(r.gross_amount for r in results)
        net = Decimal("150000") * Decimal("0.95")  # After 5% fee
        assert abs(total_distributed - net) < Decimal("1")  # Rounding tolerance

    def test_loss_uses_capital_ratio_not_profit_ratio(self, sample_partners):
        """Shariah rule: Loss MUST be proportional to capital, never profit ratio."""
        results = calculate_distribution(
            pool_id="TEST-001", period="2026-Q1",
            total_revenue=Decimal("50000"), total_expenses=Decimal("80000"),
            partners=sample_partners,
        )
        # Loss = 30000. Community has 40% capital → should bear 12000
        community = next(r for r in results if r.user_id == "community-1")
        assert community.net_amount == Decimal("-12000.00")
        assert community.is_profit == False

        # Operator has 10% capital → bears 3000 (NOT 20% which is profit ratio)
        operator = next(r for r in results if r.user_id == "operator-1")
        assert operator.net_amount == Decimal("-3000.00")

    def test_no_platform_fee_on_loss(self, sample_partners):
        """Platform should not charge fees when partnership is losing money."""
        results = calculate_distribution(
            pool_id="TEST-001", period="2026-Q1",
            total_revenue=Decimal("10000"), total_expenses=Decimal("30000"),
            partners=sample_partners,
        )
        assert all(r.platform_fee == Decimal("0") for r in results)

    def test_zakat_deduction_prorated(self, sample_partners):
        """Zakat 2.5% annual should be prorated to quarterly (÷4)."""
        results = calculate_distribution(
            pool_id="TEST-001", period="2026-Q1",
            total_revenue=Decimal("200000"), total_expenses=Decimal("50000"),
            partners=sample_partners, period_months=3,
        )
        community = next(r for r in results if r.user_id == "community-1")
        assert community.zakat_deducted > 0
        # Quarterly zakat = gross * 2.5% * 3/12 = gross * 0.625%
        expected_zakat = (community.gross_amount * Decimal("0.00625")).quantize(Decimal("0.01"))
        assert community.zakat_deducted == expected_zakat

    def test_zakat_not_deducted_if_not_opted_in(self, sample_partners):
        """Only partners who opt in should have Zakat deducted."""
        results = calculate_distribution(
            pool_id="TEST-001", period="2026-Q1",
            total_revenue=Decimal("200000"), total_expenses=Decimal("50000"),
            partners=sample_partners,
        )
        financier = next(r for r in results if r.user_id == "financier-1")
        assert financier.zakat_deducted == Decimal("0")

    def test_break_even_returns_empty(self, sample_partners):
        """Zero net profit/loss = no distributions."""
        results = calculate_distribution(
            pool_id="TEST-001", period="2026-Q1",
            total_revenue=Decimal("100000"), total_expenses=Decimal("100000"),
            partners=sample_partners,
        )
        assert len(results) == 0


class TestDiminishingMusharakah:

    def test_full_buyout_reaches_100_percent(self):
        """After all periods, operator should own 100%."""
        schedule = generate_diminishing_schedule(
            total_units=100, buyout_period_months=36,
            unit_price_method="book_value", initial_unit_price=Decimal("1000"),
        )
        last = schedule[-1]
        assert last.operator_ownership_pct == Decimal("100.00")
        assert last.financier_units_after == 0

    def test_cumulative_payment_correct(self):
        """Total paid should equal units × price for book value method."""
        schedule = generate_diminishing_schedule(
            total_units=100, buyout_period_months=36,
            unit_price_method="book_value", initial_unit_price=Decimal("1000"),
        )
        last = schedule[-1]
        assert last.cumulative_paid == Decimal("100000.00")  # 100 units × 1000

    def test_fair_market_appreciates(self):
        """Fair market method should have increasing unit prices."""
        schedule = generate_diminishing_schedule(
            total_units=100, buyout_period_months=36,
            unit_price_method="fair_market", initial_unit_price=Decimal("1000"),
            appreciation_rate_annual=Decimal("10"),
        )
        assert schedule[-1].unit_price > schedule[0].unit_price

    def test_ownership_monotonically_increases(self):
        """Operator ownership should only increase, never decrease."""
        schedule = generate_diminishing_schedule(
            total_units=100, buyout_period_months=36,
            unit_price_method="book_value", initial_unit_price=Decimal("1000"),
        )
        for i in range(1, len(schedule)):
            assert schedule[i].operator_ownership_pct >= schedule[i-1].operator_ownership_pct
services/musharakah-engine/tests/test_pool_crud.py
# ═══════════════════════════════════════════════════════
# TESTS — Pool CRUD Operations
# ═══════════════════════════════════════════════════════

import pytest
from httpx import AsyncClient
from main import app

@pytest.fixture
def test_app():
    return AsyncClient(app=app, base_url="http://test")

class TestPoolCreation:

    @pytest.mark.asyncio
    async def test_create_pool_valid(self, test_app):
        resp = await test_app.post("/api/v1/pools", json={
            "pool_name": {"en": "Test Pool", "ur": "ٹیسٹ پول"},
            "platform": "homefranchise",
            "pool_type": "musharakah_mutanaqisah",
            "target_capital_pkr": 500000,
            "minimum_investment_pkr": 10000,
            "profit_sharing": {"community_pct": 40, "financier_pct": 30, "managing_pct": 15, "operator_pct": 10, "platform_pct": 5},
            "franchise_type": "induction_cooking",
            "target_region": {"province": "Sindh", "district": "Tharparkar"},
            "description": {"en": "Test", "ur": "ٹیسٹ"},
        })
        assert resp.status_code == 201
        data = resp.json()
        assert data["pool_id"].startswith("MKP-2026-")
        assert data["status"] == "draft"

    @pytest.mark.asyncio
    async def test_reject_profit_shares_not_100(self, test_app):
        resp = await test_app.post("/api/v1/pools", json={
            "pool_name": {"en": "Bad Pool"}, "platform": "homefranchise",
            "pool_type": "shirkat_amwal", "target_capital_pkr": 100000,
            "profit_sharing": {"community_pct": 40, "financier_pct": 30},  # Only 70%
            "target_region": {"province": "Punjab"}, "description": {"en": "Test"},
        })
        assert resp.status_code == 422  # Validation error

    @pytest.mark.asyncio
    async def test_invest_below_minimum_rejected(self, test_app):
        resp = await test_app.post("/api/v1/investments/contribute", json={
            "pool_id": "MKP-2026-00001", "amount_pkr": 5000,  # Below 10K minimum
            "payment_method": "jazzcash",
        })
        assert resp.status_code == 400

    @pytest.mark.asyncio
    async def test_shariah_advisor_can_approve(self, test_app):
        # With shariah_advisor auth header
        resp = await test_app.post(
            "/api/v1/pools/MKP-2026-00001/approve-shariah",
            json={"approved": True, "notes": "Compliant with AAOIFI Std 12"},
            headers={"Authorization": "Bearer shariah_advisor_token"}
        )
        assert resp.status_code == 200
11 — Claude Code Implementation Plan
6-Phase Build Plan — Hand This to Claude Code

Phase 1: Foundation (Weeks 1-4)

□ GCP project setup (Terraform)
□ Firebase Auth with phone + email + CNIC
□ Firestore schema (all collections)
□ auth-service: register, login, RBAC
□ banking-gateway: JazzCash + Easypaisa stubs
□ Next.js frontend: login, register, KYC flow
□ Deploy to Cloud Run + Firebase Hosting
□ CI/CD with Cloud Build
Deliverable: Users register, KYC, link bank

Phase 2: Musharakah Core (Weeks 5-8)

□ musharakah-engine: Pool CRUD, partners
□ financial-engine: Ledger, basic accounting
□ contract-engine: Master Musharakah template
□ Banking: Islamic bank IBFT integration
□ Banking: JazzCash/Easypaisa live APIs
□ Frontend: Pool browsing, invest flow, contracts
□ Income tier auto-detection + routing
□ Shariah review queue (manual approval)
Deliverable: Invest in pools via JazzCash, sign contracts

Phase 3: Franchise Engine (Weeks 9-12)

□ franchise-engine: Unit CRUD, operator mgmt
□ 12 franchise type YAML configs
□ Franchise-Musharakah combined contract
□ Training module tracker
□ Monthly reporting system
□ ZTBL bridge: farmer→franchise integration
□ Frontend: Franchise catalog, operator dashboard
□ Equipment procurement workflow
Deliverable: Operators launch franchise units, submit reports

Phase 4: APPNA + International (Weeks 13-16)

□ appna-gateway: SSO, US KYC, OFAC
□ Stripe Connect: USD investment + PKR payout
□ Hometown matching algorithm
□ FX conversion engine (SBP rates)
□ US tax compliance (K-1 generation)
□ Social impact dashboard
□ SWIFT gateway for institutional investors
□ Pension fund API (EOBI, NIT)
Deliverable: APPNA physicians invest from US, Gulf investors onboard

Phase 5: Financial Ops + AI (Weeks 17-20)

□ Automated quarterly profit distribution
□ Diminishing Musharakah equity engine
□ Multi-gateway payout (JazzCash+bank+Stripe)
□ Zakat auto-deduction module
□ AI franchise matching (Vertex AI)
□ AI Shariah compliance checker (Gemini)
□ Contract Q&A chatbot (Claude API)
□ BigQuery analytics dashboards
Deliverable: Automated distributions, AI matching live

Phase 6: Scale + Launch (Weeks 21-24)

□ All 8 contract templates (trilingual)
□ All 40+ bank API integrations tested
□ ZTBL full integration live
□ WhatsApp notification channel
□ Urdu-first UI for Tier 1-2 users
□ Admin panel for managing partners
□ Load testing + security audit
□ Beta: 10 pilot pools, 50 franchise units
Deliverable: Production launch with all channels live
Claude Code — Initial Setup Commands
# ═══════════════════════════════════════════
# STEP 1: GCP Project Setup
# ═══════════════════════════════════════════
gcloud projects create musharakah-franchise-platform
gcloud config set project musharakah-franchise-platform
gcloud services enable \
  run.googleapis.com firestore.googleapis.com \
  cloudbuild.googleapis.com secretmanager.googleapis.com \
  aiplatform.googleapis.com documentai.googleapis.com \
  pubsub.googleapis.com cloudscheduler.googleapis.com \
  cloudtasks.googleapis.com

# ═══════════════════════════════════════════
# STEP 2: Create Pub/Sub Topics (Event Bus)
# ═══════════════════════════════════════════
for topic in user-registered kyc-verified bank-provisioned \
  pool-created investment-committed contract-generated \
  contract-signed pool-activated franchise-deployed \
  report-submitted distribution-calculated distribution-executed \
  ownership-transferred; do
  gcloud pubsub topics create $topic
done

# ═══════════════════════════════════════════
# STEP 3: Build & Deploy Services
# ═══════════════════════════════════════════
SERVICES="auth-service banking-gateway musharakah-engine \
  franchise-engine contract-engine financial-engine \
  ai-engine appna-gateway notification-engine"

for svc in $SERVICES; do
  cd services/$svc
  gcloud builds submit --tag gcr.io/musharakah-franchise-platform/$svc
  gcloud run deploy $svc \
    --image gcr.io/musharakah-franchise-platform/$svc \
    --region asia-south1 --platform managed \
    --set-env-vars GCP_PROJECT=musharakah-franchise-platform
  cd ../..
done

# ═══════════════════════════════════════════
# STEP 4: Cloud Scheduler (Quarterly Distribution)
# ═══════════════════════════════════════════
gcloud scheduler jobs create http quarterly-distribution \
  --schedule="0 2 1 1,4,7,10 *" \
  --uri="https://financial-engine-xxx.run.app/api/v1/finance/distribute/calculate-all" \
  --http-method=POST \
  --time-zone="Asia/Karachi"

# Daily bank reconciliation
gcloud scheduler jobs create http daily-reconciliation \
  --schedule="0 3 * * *" \
  --uri="https://banking-gateway-xxx.run.app/api/v1/banking/reconcile" \
  --http-method=POST

# ═══════════════════════════════════════════
# STEP 5: Frontend Deploy
# ═══════════════════════════════════════════
cd frontend/web-app
npm run build
firebase deploy --only hosting
.env — Environment Variables (Secret Manager in production)
# GCP
GCP_PROJECT_ID=musharakah-franchise-platform
GCP_REGION=asia-south1

# Firebase
FIREBASE_API_KEY=xxx
FIREBASE_AUTH_DOMAIN=musharakah-franchise-platform.firebaseapp.com

# AI
VERTEX_AI_LOCATION=asia-south1
GEMINI_MODEL=gemini-2.5-pro
ANTHROPIC_API_KEY=xxx
CLAUDE_MODEL=claude-sonnet-4-5-20250929

# Banking — Islamic
MEEZAN_API_URL=https://api.meezanbank.com/v1
MEEZAN_API_KEY=xxx
BANKISLAMI_API_URL=https://api.bankislami.com.pk/v1
BANKISLAMI_API_KEY=xxx

# Banking — Government
NBP_API_URL=https://api.nbp.com.pk/corporate/v1
RAAST_API_URL=https://api.raast.sbp.org.pk/v1
ZTBL_API_URL=https://api.ztbl.com.pk/agri/v1

# Mobile Money
JAZZCASH_MERCHANT_ID=xxx
JAZZCASH_PASSWORD=xxx
JAZZCASH_SALT=xxx
EASYPAISA_STORE_ID=xxx
EASYPAISA_TOKEN=xxx

# International
STRIPE_SECRET_KEY=xxx
STRIPE_WEBHOOK_SECRET=xxx

# APPNA
APPNA_SSO_CLIENT_ID=xxx
APPNA_SSO_SECRET=xxx
OFAC_API_KEY=xxx

# Notifications
TWILIO_ACCOUNT_SID=xxx
TWILIO_AUTH_TOKEN=xxx
SENDGRID_API_KEY=xxx
WHATSAPP_BUSINESS_TOKEN=xxx

# NADRA
NADRA_API_URL=https://api.nadra.gov.pk/e-sahulat/v1
NADRA_API_KEY=xxx
12 — Benefits & Impact
Why This Integration Changes Everything

For Local Communities

• PKR 10,000 minimum entry — accessible to Tier 1 households
• No interest (Riba-free) — purely Halal returns
• Mobile money integration — JazzCash from any corner shop
• Franchise in own village — no migration needed
• 3-5 year path to full franchise ownership
• Women's groups earn independent income
• 50M households addressable across 7 tiers

For APPNA Diaspora

• Invest in hometown from Houston/Chicago/NYC
• $500 minimum — physician-friendly amounts
• US-compliant: OFAC, FATCA, IRS reporting built-in
• Real-time impact dashboard — see franchise working
• Not charity — real Shariah-compliant ROI (15-40%)
• Connect with hometown community digitally
• 55,000 physicians × $10K avg = $550M potential

For Institutional Investors

• New asset class: asset-backed, Shariah-compliant
• PKR 67B addressable from pension/investment funds
• Diversification away from govt bonds + stocks
• Real economic impact — verifiable at unit level
• AAOIFI Standard 12 compliant structures
• Diminishing Musharakah provides clean exit path
• Carbon credit potential (solar franchises)

For ZTBL Farmers

• Convert interest-based loans to Musharakah
• Add franchise revenue to agricultural income
• 890,000 existing farmers as pipeline
• Food drying creates 8-15× value from harvest waste
• Solar reduces energy costs to zero after payback
• ZTBL Murabaha bridge = Shariah-compliant equipment
• Existing ZTBL relationship lowers onboarding friction

For the Platform Ecosystem

• KaamyabPakistan: Innovation hubs funded via Social Impact Musharakah
• YouInvent: Patent + prototype funding via Innovation Musharakah
• HomeFranchise: Franchise units funded via Franchise Musharakah
• NoCodeAI: AI platform development via Technology Musharakah
• All 4 platforms connected, single user identity
• PKR 500-5,000/month SaaS feeds recurring revenue
• Co-located datacenters next to power plants

For Pakistan's Economy

• 50M households × 7 tiers = PKR 42.6T annual GDP impact
• 100,000+ franchise units by 2030
• $2B+ diaspora remittances channeled productively
• 890K farmers diversify beyond agriculture
• Women workforce participation increase
• Indoor air pollution deaths reduced (induction cooking)
• Carbon credits from solar + clean cooking

50M
Households
Addressable
$550M
APPNA Investment
Potential
PKR 67B
Institutional
Year 1-3
100K+
Franchise Units
by 2030
0%
Interest
100% Halal