{
  "$schema": "./app.schema.json",
  "source": "Facts imported from the public portfolio catalog at https://github.com/Afaquejaya/afaquejaya.github.io (projects/js/projects-data.js). Edit this file to add a product. Then run: node scripts/build.mjs",
  "updated": "2026-11-09",
  "apps": [
    {
      "id": "rental-saas",
      "title": "Rental Property Management SaaS",
      "tagline": "The whole rent cycle for landlords — leases, bills, payments and expenses — in one workspace.",
      "summary": "Landlords juggle spreadsheets, chats and receipts. One owner-scoped workspace covers properties, tenants, leases, billing, payments and reports — with a tenant portal and AI access over MCP.",
      "description": [
        "A multi-role SaaS for landlords in the UAE and the Gulf, with three portals: landlord, tenant and admin. It models the full rent cycle — property and unit, lease, bill (including meter readings), payment, receipt — and the costs around it.",
        "An owner can ask an AI assistant about their own portfolio, either inside the app or from an MCP-compatible AI client. Both paths are read-only and scoped to that owner’s data."
      ],
      "categories": [
        "saas",
        "web",
        "backend",
        "ai"
      ],
      "markets": [
        "saas",
        "ai"
      ],
      "status": "live",
      "visibility": "private",
      "featured": 1,
      "accent": "#e2a54a",
      "period": "Sep – Oct 2026",
      "context": "Personal product",
      "platforms": [
        "Web",
        "Mobile web"
      ],
      "technologies": [
        "JavaScript",
        "PostgreSQL",
        "REST API",
        "MCP",
        "Hatchable",
        "Razorpay",
        "Stripe"
      ],
      "problem": "Small landlords track rent in spreadsheets and chat threads. Overdue rent, expiring leases and utility readings slip, and there is no single view of what each property actually earns.",
      "solution": "A workspace per owner that ties every invoice to a lease and every payment to an invoice, so the dashboard, reminders and reports all come from the same records — and an assistant can answer questions from them.",
      "features": [
        {
          "title": "Properties, units, tenants & leases",
          "detail": "Lease lifecycle with renewals, terminations and rent history.",
          "planned": false
        },
        {
          "title": "Rent billing",
          "detail": "Batch invoice generation with proration; utility bills refuse to run without current and previous meter readings.",
          "planned": false
        },
        {
          "title": "Payments & reconciliation",
          "detail": "Manual payments, receipts, reconciliation and financial periods; invoice and receipt PDFs.",
          "planned": false
        },
        {
          "title": "Expenses",
          "detail": "One-off and recurring expenses with pause, resume and end.",
          "planned": false
        },
        {
          "title": "Financial reports",
          "detail": "Summary, monthly trend, outstanding ageing, occupancy and more, with CSV export.",
          "planned": false
        },
        {
          "title": "Configurable reminders",
          "detail": "Per-owner rules (rent due soon, overdue, lease expiring, meter reading due) with day offsets, processed hourly.",
          "planned": false
        },
        {
          "title": "Tenant portal",
          "detail": "Invoices, lease, maintenance requests with photos, documents and notifications.",
          "planned": false
        },
        {
          "title": "Maintenance & documents",
          "detail": "Requests, vendors, staff, appointments and costs; versioned documents; audit log.",
          "planned": false
        },
        {
          "title": "Property AI assistant",
          "detail": "Read-only, owner-scoped answers that name their data source.",
          "planned": false
        },
        {
          "title": "MCP tools for AI clients",
          "detail": "10 read-only tools — see the MCP integration project.",
          "planned": false
        },
        {
          "title": "Online rent payments",
          "detail": "Razorpay and Stripe adapters are written; no provider is configured or tested live yet.",
          "planned": true
        },
        {
          "title": "WhatsApp Business messaging",
          "detail": "Today reminders open a wa.me link; there is no WhatsApp API integration.",
          "planned": true
        }
      ],
      "role": [
        "Defined the product, domain model and an 18-step build plan, from data model to release checklist.",
        "Built it on the Hatchable platform, largely through its AI builder, reviewing and correcting each step.",
        "Specified the owner-isolation rules, the billing rules and the MCP integration, and documented known limitations honestly in the README."
      ],
      "architecture": {
        "summary": "Serverless API functions on Hatchable over managed PostgreSQL. Every query is scoped to the signed-in owner at the application layer.",
        "flow": [
          {
            "title": "Portals",
            "detail": "Landlord, tenant & admin — HTML/JS"
          },
          {
            "title": "Auth",
            "detail": "Email OTP / passkeys; role resolved per request"
          },
          {
            "title": "API functions",
            "detail": "/api/v1 — owner-scoped helpers"
          },
          {
            "title": "Billing & reports",
            "detail": "NUMERIC maths, proration, ageing"
          },
          {
            "title": "PostgreSQL",
            "detail": "156 migrations; cron for reminders"
          }
        ],
        "guards": [
          "Owner resolved from the session, never from the request body",
          "Tenants and suspended owners blocked from owner APIs",
          "Payment webhooks HMAC-verified"
        ],
        "caption": "Simplified. Isolation is enforced in application code (owner_id filters), not database row-level security."
      },
      "agent": null,
      "impact": [],
      "links": [],
      "notes": [
        "Most of the code was generated through Hatchable’s AI builder from my step-by-step specifications, then reviewed and corrected.",
        "Not yet done: two-account isolation (IDOR) testing, a configured payment provider, and verification of the MCP tools with a real AI client.",
        "The source repository is private."
      ],
      "related": [
        "rental-mcp",
        "ai-job-agent",
        "careersync-ai"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/rental/dashboard.webp",
        "w": 1280,
        "h": 632,
        "alt": "Landlord dashboard of the Rental SaaS: expected, collected, outstanding and overdue rent for October 2026, occupancy, vacant units, open maintenance and leases ending soon, above a pending-rent list of tenants with overdue invoices",
        "frame": "web",
        "illustrative": false,
        "caption": "Dashboard — sample data, 18 Oct 2026"
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/projects/rental/dashboard.webp",
          "w": 1280,
          "h": 632,
          "alt": "Landlord dashboard with rent, occupancy and maintenance figures and a pending-rent list",
          "frame": "web",
          "illustrative": false,
          "caption": "Dashboard — the month at a glance"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/rental/invoices.webp",
          "w": 1280,
          "h": 720,
          "alt": "Invoices screen with totals and a filterable list of rent invoices",
          "frame": "web",
          "illustrative": false,
          "caption": "Invoices and balances"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/rental/property-ai.webp",
          "w": 398,
          "h": 462,
          "alt": "Property AI panel answering “Which tenants have overdue rent?” with two tenants, amounts and days overdue, and a source line",
          "frame": "panel",
          "illustrative": false,
          "caption": "Property AI — read-only, cites its source"
        }
      ]
    },
    {
      "id": "prospectpilot",
      "title": "ProspectPilot AI",
      "tagline": "An evidence-first sales agent that finds companies who need what you sell — and shows you the proof.",
      "summary": "Small agencies waste days hunting for clients. Describe your business; the agent finds matching UAE/GCC companies, reads their websites, detects problems your services fix and drafts cited outreach in English and Arabic — a human approves everything, nothing is sent.",
      "description": [
        "An AI go-to-market agent for small B2B service businesses — agencies, consultants, software studios — selling to UAE and GCC SMEs. You describe what you sell; the agent proposes an ideal customer profile (ICP) for you to approve, then plans its own searches, discovers matching companies, researches each public website and keeps only the companies where it found a real, evidenced problem one of your services can fix.",
        "Every score is explained component by component, every fact carries its source URL and observation date, and every sentence in a draft cites its evidence. A human approves every external action; this version has no sending integration at all."
      ],
      "categories": [
        "agents",
        "ai",
        "web",
        "backend"
      ],
      "markets": [
        "agents",
        "ai",
        "tools"
      ],
      "status": "in-development",
      "visibility": "private",
      "featured": null,
      "accent": "#14806b",
      "period": "Oct 2026 —",
      "context": "Entry for the Dubai Chamber of Digital Economy AI Agents Championship (Best Business AI Agent)",
      "platforms": [
        "Web"
      ],
      "technologies": [
        "TypeScript",
        "Next.js",
        "PostgreSQL",
        "Drizzle ORM",
        "Anthropic API",
        "Auth.js",
        "Cheerio",
        "Vitest"
      ],
      "problem": "Most AI sales tools buy a firmographic list and blast templated “personalised” emails. There is no proof the company needs anything, no sources behind the claims, black-box scores, English-only copy and automatic sending.",
      "solution": "Flip it to evidence first: only a company with a concrete, checkable problem your service fixes becomes a lead, every claim links to where and when it was observed, and a person approves every message before anything leaves the app.",
      "features": [
        {
          "title": "AI-assisted ICP builder",
          "detail": "Proposes an ideal customer profile from your website and services; you edit and approve it.",
          "planned": false
        },
        {
          "title": "Step-by-step search planner",
          "detail": "Chooses one source + query at a time, validated in code (enabled tools only, no repeats, budget limits).",
          "planned": false
        },
        {
          "title": "Five discovery sources",
          "detail": "Google Places, Brave Search, public exhibitor lists, CSV upload and domain lists; non-company sites filtered out.",
          "planned": false
        },
        {
          "title": "Safe website research",
          "detail": "robots.txt respected, private networks blocked, size and time limits; page text treated as data, never instructions.",
          "planned": false
        },
        {
          "title": "Rule-based need detection",
          "detail": "Slow mobile site (PageSpeed), no HTTPS, no Arabic version, not mobile-friendly, broken contact form, outdated tech and more.",
          "planned": false
        },
        {
          "title": "Explainable scoring",
          "detail": "ICP fit 40 · need evidence 25 · evidence quality 20 · reachability 10 · freshness 5 — qualified only at 55+ with an evidenced need.",
          "planned": false
        },
        {
          "title": "Cited EN/AR drafts",
          "detail": "English email, Arabic email (RTL) and a WhatsApp-style message; every claim sentence cites its source.",
          "planned": false
        },
        {
          "title": "Approvals, pipeline, analytics, learning journal",
          "detail": "Reject reasons feed reversible scoring adjustments; analytics show their denominators.",
          "planned": false
        },
        {
          "title": "Sending integration",
          "detail": "Deliberately not built — nothing leaves the app.",
          "planned": true
        }
      ],
      "role": [
        "Sole developer: product design, agent runtime, research and scoring pipeline, UI, tests, CI and the competition documentation."
      ],
      "architecture": {
        "summary": "",
        "flow": [
          {
            "title": "Next.js app",
            "detail": "Setup, ICP, runs, leads, approvals"
          },
          {
            "title": "Postgres job queue",
            "detail": "Heartbeat, stale-lock recovery"
          },
          {
            "title": "Worker: agent runtime",
            "detail": "State machine, planner, tool registry"
          },
          {
            "title": "Research & scoring",
            "detail": "Safe fetcher, need rules, weights"
          },
          {
            "title": "Drafting",
            "detail": "EN / AR / WhatsApp with citations"
          }
        ],
        "guards": [
          "Human approval for every external action",
          "SSRF-safe fetcher",
          "Step and cost budgets",
          "Tenant isolation on every query"
        ],
        "caption": "Simplified. The learning journal feeds approved/rejected outcomes back into scoring."
      },
      "agent": {
        "objective": "Find companies that match your ideal customer profile and have an evidenced problem your services fix, then draft outreach that cites that evidence.",
        "input": "A business setup (website, services, geography) turned into an ICP you approve; a run is then queued as a background job.",
        "reasoning": "A planner proposes one step at a time (a source plus a query), sees how many new companies it produced and proposes the next — stopping at the company limit, when every industry/city pair is tried, or after 10 planning steps. The code validates every proposal.",
        "tools": [
          "places_search",
          "search_companies",
          "exhibitor list fetcher",
          "CSV / domain import",
          "safe page fetcher",
          "PageSpeed Insights",
          "tech detection",
          "fact extraction",
          "need detection",
          "scoring",
          "drafting"
        ],
        "execution": "A Postgres-backed job queue and a separate worker run a persistent state machine (plan → find → research → score → draft). Every planning decision and tool call is logged and streamed to the run page; runs can be cancelled and retried.",
        "safety": "Human approval for every external action and no sending integration. SSRF guard (private ranges, encoded IPs, redirects, DNS rebinding), prompt-injection handling, public business data only — no LinkedIn scraping, no guessed or personal emails, suppression lists and data deletion. Per-run and per-workspace-month cost caps enforced in code.",
        "models": "Provider chosen server-side. With Anthropic: claude-opus-5-5 for planning, synthesis and drafting (EN/AR), claude-haiku-5-5 for extraction and classification. A deterministic mock provider powers tests and the offline demo; Ollama is available for local development."
      },
      "impact": [
        {
          "value": "10 / 9",
          "label": "companies researched / qualified in the demo run",
          "source": "README — synthetic demo"
        },
        {
          "value": "97%",
          "label": "need signals with a source (35 / 36)",
          "source": "README — synthetic demo"
        },
        {
          "value": "100%",
          "label": "draft claim sentences cited (15 / 15)",
          "source": "README — synthetic demo"
        },
        {
          "value": "0",
          "label": "messages sent — by design",
          "source": "README"
        }
      ],
      "links": [],
      "notes": [
        "In development. The live pipeline has been run on real domains via a domain list; the Google Places and Brave adapters and a full Claude run with a real key are not yet verified.",
        "Arabic drafts have not yet had a native Gulf-Arabic review.",
        "“ProspectPilot” is a working product name. Source is private while the competition is running."
      ],
      "related": [
        "ai-job-agent",
        "rental-mcp",
        "local-agent-lab"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/prospectpilot/leads.webp",
        "w": 1280,
        "h": 800,
        "alt": "ProspectPilot Leads page in demo mode: a ranked list of synthetic companies with scores out of 100, location and industry, detected needs such as slow mobile homepage, no HTTPS and no Arabic version, evidence score, source and recommended pitch",
        "frame": "web",
        "illustrative": false,
        "caption": "Leads — synthetic demo data"
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/projects/prospectpilot/leads.webp",
          "w": 1280,
          "h": 800,
          "alt": "Leads page ranking synthetic companies by score with detected needs, evidence and recommended pitch",
          "frame": "web",
          "illustrative": false,
          "caption": "Ranked leads — each with the need it found and where"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/prospectpilot/run.webp",
          "w": 1280,
          "h": 800,
          "alt": "Discovery run page: Plan, Find, Research, Score, Draft and Your review steps, with companies found, researched, qualified, tool steps used and AI budget used",
          "frame": "web",
          "illustrative": false,
          "caption": "Live run — steps, tool budget and AI cost cap"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/prospectpilot/dossier.webp",
          "w": 1280,
          "h": 800,
          "alt": "Lead dossier for a synthetic dental clinic: score 94, why-this-lead summary, need signals with observed facts and sources, and a score breakdown by ICP fit, need evidence and evidence quality",
          "frame": "web",
          "illustrative": false,
          "caption": "Lead dossier — “Why this lead?” and the score, explained"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/prospectpilot/drafts.webp",
          "w": 1280,
          "h": 800,
          "alt": "Outreach drafts: a WhatsApp-style English message and an Arabic email, each with numbered citations to dated evidence and Approve, Edit and Reject buttons",
          "frame": "web",
          "illustrative": false,
          "caption": "English + Arabic drafts with citations — approve, edit or reject"
        }
      ]
    },
    {
      "id": "rental-mcp",
      "title": "Rental SaaS MCP Server",
      "tagline": "Lets an authorised AI client ask a landlord’s own rental data questions — read-only.",
      "summary": "Ten read-only Model Context Protocol tools expose rent, leases and expenses to MCP-compatible assistants, each answer scoped to the authenticated owner.",
      "description": [
        "An MCP endpoint on the Rental SaaS. A compatible AI client connects, authenticates, and can then call a small set of tools — the same business rules the dashboard uses, never raw SQL.",
        "Write tools (record a payment, create an invoice) are deliberately not exposed yet."
      ],
      "categories": [
        "agents",
        "backend",
        "ai"
      ],
      "markets": [
        "agents",
        "ai"
      ],
      "status": "live",
      "visibility": "private",
      "featured": null,
      "accent": "#ff7a4a",
      "period": "Oct 2026",
      "context": "Part of the Rental SaaS",
      "platforms": [],
      "technologies": [
        "MCP",
        "OAuth",
        "JavaScript",
        "PostgreSQL"
      ],
      "problem": "Owners want to ask “who hasn’t paid?” in the assistant they already use, without exporting data or handing an AI a database login.",
      "solution": "A narrow, read-only tool surface behind authentication, resolved to one owner per call.",
      "features": [
        {
          "title": "Portfolio tools",
          "detail": "get_properties, get_units, get_tenants, get_active_leases",
          "planned": false
        },
        {
          "title": "Money tools",
          "detail": "get_monthly_billing_summary, get_outstanding_rent, get_payment_history, get_outstanding_aging",
          "planned": false
        },
        {
          "title": "Cost & summary tools",
          "detail": "get_expenses, get_financial_summary",
          "planned": false
        },
        {
          "title": "Write tools",
          "detail": "Payments, invoices and reminders from an AI client.",
          "planned": true
        }
      ],
      "role": [],
      "architecture": {
        "summary": "",
        "flow": [
          {
            "title": "AI client",
            "detail": "MCP-compatible assistant"
          },
          {
            "title": "MCP auth",
            "detail": "Platform OAuth, member access"
          },
          {
            "title": "Owner resolution",
            "detail": "Identity → one owner, or fail"
          },
          {
            "title": "Read-only tools",
            "detail": "10 tools, same business rules"
          },
          {
            "title": "PostgreSQL",
            "detail": "That owner’s rows only"
          }
        ],
        "guards": [
          "Read-only tools",
          "One owner per call",
          "Fails closed on ambiguity"
        ],
        "caption": "Simplified flow of a single tool call."
      },
      "agent": {
        "objective": "Answer an owner’s questions about their portfolio from inside an MCP-compatible AI client.",
        "input": "The AI client decides to call a tool while answering the owner; the call arrives at the /mcp endpoint.",
        "reasoning": "The client’s model chooses which tool to call. The server holds no model — it only executes tools.",
        "tools": [
          "get_properties",
          "get_units",
          "get_tenants",
          "get_active_leases",
          "get_monthly_billing_summary",
          "get_outstanding_rent",
          "get_payment_history",
          "get_expenses",
          "get_financial_summary",
          "get_outstanding_aging"
        ],
        "execution": "Each tool resolves the owner from the authenticated identity, runs the same owner-scoped queries as the app, and returns structured results.",
        "safety": "Every tool is read-only and requires project-member access. If the owner can’t be resolved unambiguously, the call fails rather than guessing.",
        "models": "Model-agnostic — whichever MCP-compatible client the owner authorises."
      },
      "impact": [],
      "links": [
        {
          "type": "case",
          "url": "/apps/rental-saas/",
          "label": "Rental SaaS case study",
          "note": ""
        }
      ],
      "notes": [
        "The tools have not yet been fully verified end to end with a real MCP client — treat this as working but unproven."
      ],
      "related": [
        "rental-saas",
        "ai-job-agent",
        "careeros"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/rental-mcp/concept.webp",
        "w": 1280,
        "h": 800,
        "alt": "Illustrative concept: an AI assistant calls the get_outstanding_rent MCP tool, the MCP server lists its ten read-only tools, and results come only from the owner’s data",
        "frame": "art",
        "illustrative": true,
        "caption": ""
      },
      "screenshots": []
    },
    {
      "id": "ai-job-agent",
      "title": "AI Job Agent",
      "tagline": "A local-first agent that finds jobs, ranks them against your CV and explains every match with quotes.",
      "summary": "Job hunting means reading hundreds of listings against your own CV. The agent searches allowlisted job boards, scores each listing in code and backs every claim with a verbatim quote — it never applies or messages anyone.",
      "description": [
        "A self-hosted web app with a background worker. Upload a CV, mark which profile answers are verified, and ask the agent to find roles in India and the Middle East. It searches allowlisted public job sources, saves matches, and runs a match analysis that quotes your CV for every point.",
        "Phases 1–3 of a 12-phase roadmap are complete. Applying, tailored CVs and outreach are later phases and are not built."
      ],
      "categories": [
        "agents",
        "ai",
        "web",
        "backend"
      ],
      "markets": [
        "agents",
        "ai",
        "tools"
      ],
      "status": "in-development",
      "visibility": "public",
      "featured": 3,
      "accent": "#ff7a4a",
      "period": "Oct 2026 —",
      "context": "Personal project",
      "platforms": [
        "Web (self-hosted)"
      ],
      "technologies": [
        "TypeScript",
        "Next.js",
        "Node.js",
        "PostgreSQL",
        "Prisma",
        "Redis",
        "Ollama",
        "Anthropic API",
        "Docker",
        "Playwright"
      ],
      "problem": "Matching a CV to job listings is slow, and AI tools that “auto-apply” are a liability: they invent experience and act on your behalf without asking.",
      "solution": "Keep the agent’s power deliberately small — read, search allowlisted sources, save, analyse — and make every output checkable: quotes are verified word for word, scores are computed by code, and every step is logged.",
      "features": [
        {
          "title": "Encrypted CV upload",
          "detail": "PDF/DOCX with text extraction and suggested contact details.",
          "planned": false
        },
        {
          "title": "Verified answers",
          "detail": "Only answers you marked verified are ever reused.",
          "planned": false
        },
        {
          "title": "“Find jobs for me”",
          "detail": "Greenhouse, Lever, Ashby, Remotive and optional JSearch; deny-by-default source registry.",
          "planned": false
        },
        {
          "title": "Match analysis with quotes",
          "detail": "Every claim cites your CV; quotes are checked verbatim, the score is calculated in code.",
          "planned": false
        },
        {
          "title": "Agent chat",
          "detail": "Paste a job; the agent saves it and explains the fit, showing each step.",
          "planned": false
        },
        {
          "title": "Activity timeline",
          "detail": "Durable tasks with leases, retries, cancellation and a per-step log.",
          "planned": false
        },
        {
          "title": "Per-user isolation & health checks",
          "detail": "Better Auth sessions; Docker, database and model health page.",
          "planned": false
        },
        {
          "title": "Apply & fill forms",
          "detail": "Browser-agent interfaces only.",
          "planned": true
        },
        {
          "title": "Tailored CV, cover letters & outreach",
          "detail": "Roadmap phases 7–12.",
          "planned": true
        }
      ],
      "role": [
        "Sole developer: architecture, agent loop, tool policy, worker, UI, tests and CI."
      ],
      "architecture": {
        "summary": "",
        "flow": [
          {
            "title": "Next.js web app",
            "detail": "Chat, jobs, CVs, activity"
          },
          {
            "title": "Task queue",
            "detail": "PostgreSQL + Redis"
          },
          {
            "title": "Agent loop",
            "detail": "Tool calling, limits, budget"
          },
          {
            "title": "Tool executor",
            "detail": "Side-effect policy per tool"
          },
          {
            "title": "Model adapter",
            "detail": "Ollama (local) or Anthropic"
          }
        ],
        "guards": [
          "Side-effect-aware tool policy",
          "Deny-by-default job sources",
          "Verbatim quote verification",
          "Budget & step limits"
        ],
        "caption": "Simplified. The worker runs the same loop for background tasks."
      },
      "agent": {
        "objective": "Find relevant roles and explain, with evidence, how well your CV fits each one.",
        "input": "A chat message on the Agent page, or a background job (search, analysis, CV processing) picked up by the worker from a queue.",
        "reasoning": "A hand-written loop over native tool calling (Anthropic tool_use / Ollama tool_calls). It stops on a step limit, a deadline, an exhausted budget, a refusal or cancellation.",
        "tools": [
          "get_my_profile",
          "get_my_verified_answers",
          "get_primary_cv_text",
          "save_job_posting",
          "list_saved_jobs",
          "analyze_job_match"
        ],
        "execution": "Tasks are durable: leased, reconciled, retried and cancellable, with every step recorded and shown on the Activity page. Analysis output is validated — quotes must match the source text exactly.",
        "safety": "Each tool declares its side effect (none, internal write, external read, external write, irreversible); the executor uses that to decide when a policy check or approval is required. No AI call runs without consent, a key and budget. It never logs in, scrapes behind sign-in, or submits anything.",
        "models": "Local first: Ollama with qwen3:4b-instruct on your own machine, so the CV never leaves it. Anthropic is an opt-in paid alternative with a monthly budget cap."
      },
      "impact": [],
      "links": [
        {
          "type": "github",
          "url": "https://github.com/Afaquejaya/ai-job-agent",
          "label": "Source on GitHub",
          "note": ""
        }
      ],
      "notes": [],
      "related": [
        "local-agent-lab",
        "careersync-ai",
        "careeros"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/job-agent/jobs.webp",
        "w": 800,
        "h": 620,
        "alt": "AI Job Agent Jobs page: “Find jobs for me” form with roles and countries, a completed search that saved 13 jobs, and a list of matched roles with skills percentages",
        "frame": "web",
        "illustrative": false,
        "caption": "Jobs — sample account"
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/projects/job-agent/jobs.webp",
          "w": 800,
          "h": 620,
          "alt": "Jobs page with a completed search and matched roles",
          "frame": "web",
          "illustrative": false,
          "caption": "Find jobs → ranked by skills match"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/job-agent/agent.webp",
          "w": 800,
          "h": 460,
          "alt": "Agent page explaining what the agent can and cannot do, showing the local Ollama model in use",
          "frame": "web",
          "illustrative": false,
          "caption": "Agent chat — states its limits and the model in use"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/job-agent/activity.webp",
          "w": 800,
          "h": 380,
          "alt": "Activity page listing a running match analysis and completed job search and CV extraction tasks",
          "frame": "web",
          "illustrative": false,
          "caption": "Durable background tasks"
        }
      ]
    },
    {
      "id": "careersync-ai",
      "title": "CareerSync AI",
      "tagline": "Upload a CV once, review every extracted change, then sync it to job portals and your portfolio.",
      "summary": "Keeping LinkedIn, Naukri, Indeed and a portfolio in sync with your CV is tedious and error-prone. An LLM extraction pipeline proposes the changes; a human approves each one.",
      "description": [
        "A dashboard that parses a CV with Claude (or an offline heuristic parser), shows every extracted field as a reviewable change, and pushes approved changes to LinkedIn, Indeed, Naukri, Naukri Gulf, a portfolio repository (as a GitHub pull request) or a custom webhook.",
        "It is an extraction pipeline with a review step, not an autonomous agent: nothing is published without an explicit approval."
      ],
      "categories": [
        "ai",
        "web",
        "agents"
      ],
      "markets": [
        "agents",
        "ai",
        "tools"
      ],
      "status": "prototype",
      "visibility": "private",
      "featured": null,
      "accent": "#b493f0",
      "period": "Oct 2026",
      "context": "Personal project",
      "platforms": [],
      "technologies": [
        "Next.js",
        "React",
        "TypeScript",
        "Anthropic API",
        "Drizzle ORM",
        "PostgreSQL",
        "Chrome extension",
        "Vitest"
      ],
      "problem": "Profiles drift out of date, and an AI that rewrites them unsupervised can invent experience.",
      "solution": "Every value the model extracts is checked against the source CV before it is shown, and every change set needs approval — portfolio publishing has its own separate approval.",
      "features": [
        {
          "title": "CV parsing with Claude",
          "detail": "Offline heuristic parser as a fallback when no key is set.",
          "planned": false
        },
        {
          "title": "Anti-fabrication checks",
          "detail": "Extracted values must be traceable to the CV text.",
          "planned": false
        },
        {
          "title": "Prompt-injection defence",
          "detail": "CV text is treated as untrusted input.",
          "planned": false
        },
        {
          "title": "Review & approve",
          "detail": "Change sets per destination, approved one by one.",
          "planned": false
        },
        {
          "title": "Portfolio sync via GitHub PR",
          "detail": "Proposes changes as a pull request rather than pushing.",
          "planned": false
        },
        {
          "title": "Browser extension",
          "detail": "Fills portal forms only when you click, and never presses Save.",
          "planned": false
        },
        {
          "title": "GitHub App install flow, S3 storage, multi-instance Redis",
          "detail": "",
          "planned": true
        }
      ],
      "role": [
        "Sole developer: pipeline design, safety checks, dashboard, extension and tests."
      ],
      "architecture": {
        "summary": "",
        "flow": [
          {
            "title": "CV upload",
            "detail": "PDF / DOCX text extraction"
          },
          {
            "title": "LLM extraction",
            "detail": "Claude, or offline parser"
          },
          {
            "title": "Verification",
            "detail": "Values checked against source"
          },
          {
            "title": "Human review",
            "detail": "Approve per change set"
          },
          {
            "title": "Destinations",
            "detail": "Portals, GitHub PR, webhook"
          }
        ],
        "guards": [
          "Untrusted-input handling",
          "Approval before any publish",
          "Extension never submits"
        ],
        "caption": "Simplified pipeline."
      },
      "agent": null,
      "impact": [],
      "links": [],
      "notes": [
        "Runs locally; there is no public demo or repository."
      ],
      "related": [
        "ai-job-agent",
        "careeros",
        "rental-saas"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/careersync-ai/concept.webp",
        "w": 1280,
        "h": 800,
        "alt": "Illustrative concept: a review screen with a source CV on the left and three proposed profile changes, one blocked because it is not in the CV, above the sync destinations",
        "frame": "art",
        "illustrative": true,
        "caption": ""
      },
      "screenshots": []
    },
    {
      "id": "careeros",
      "title": "CareerOS",
      "tagline": "A local command centre that runs an open-source job-search agent’s workflows safely from the browser.",
      "summary": "The career-ops engine is driven from a terminal. CareerOS puts a web UI on top, so its modes run from buttons — with an allowlist, no shell, and no AI write access.",
      "description": [
        "A local web UI and Node server for career-ops, an open-source AI job-search engine by another author. CareerOS is my addition: it lists the engine’s actions, runs them as child processes, and streams progress to the browser.",
        "The interesting part is the safety model around running an AI coding CLI on your machine."
      ],
      "categories": [
        "agents",
        "web",
        "experiments"
      ],
      "markets": [
        "agents",
        "tools"
      ],
      "status": "prototype",
      "visibility": "private",
      "featured": null,
      "accent": "#ff7a4a",
      "period": "Oct 2026",
      "context": "Personal project built on the open-source career-ops engine (MIT)",
      "platforms": [],
      "technologies": [
        "React",
        "Vite",
        "Node.js",
        "TypeScript",
        "Zod",
        "Server-Sent Events",
        "Claude Code CLI"
      ],
      "problem": "Running agent workflows through a CLI is powerful but easy to misuse — one wrong flag and the AI can edit or delete files.",
      "solution": "The browser can only trigger allowlisted actions by id; the server never uses a shell; and when an AI mode runs, its write and shell tools are denied.",
      "features": [],
      "role": [],
      "architecture": {
        "summary": "",
        "flow": [
          {
            "title": "Browser UI",
            "detail": "React + Vite"
          },
          {
            "title": "Local server",
            "detail": "127.0.0.1 only"
          },
          {
            "title": "Action allowlist",
            "detail": "By id, validated with Zod"
          },
          {
            "title": "Child process",
            "detail": "shell: false"
          },
          {
            "title": "career-ops engine",
            "detail": "Scripts & AI modes"
          }
        ],
        "guards": [
          "Loopback only",
          "Allowlisted actions",
          "AI write/shell tools denied",
          "Dry-run before changes"
        ],
        "caption": "Simplified."
      },
      "agent": {
        "objective": "Run job-search workflows (evaluations, tracking, drafts) without touching a terminal.",
        "input": "A button in the UI sends an action id to the local server.",
        "reasoning": "The underlying engine’s modes run through the Claude Code CLI (other CLIs are detected); CareerOS orchestrates rather than reasons.",
        "tools": [
          "Allowlisted engine scripts",
          "Claude Code CLI with Write, Edit and Bash denied"
        ],
        "execution": "Child processes run with shell disabled; output streams to the browser over Server-Sent Events and is persisted by the engine’s own scripts.",
        "safety": "Server bound to 127.0.0.1. Allowlisted actions only. Destructive operations need confirmation, tracker tools offer a dry-run preview, and nothing is ever submitted or sent — drafts are for you to copy.",
        "models": "Whatever the installed CLI uses (Claude by default); the engine also ships Gemini, OpenAI and Ollama evaluators."
      },
      "impact": [],
      "links": [
        {
          "type": "github",
          "url": "https://github.com/career-ops-hq/career-ops",
          "label": "career-ops engine (not mine)",
          "note": ""
        }
      ],
      "notes": [
        "The career-ops engine is third-party open source (MIT). Only the CareerOS UI and server described here are my work, and they are not published."
      ],
      "related": [
        "ai-job-agent",
        "local-agent-lab",
        "careersync-ai"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/careeros/concept.webp",
        "w": 1280,
        "h": 800,
        "alt": "Illustrative concept: a local command centre with allowlisted actions, a streaming run log showing AI write tools denied, and a safety checklist",
        "frame": "art",
        "illustrative": true,
        "caption": ""
      },
      "screenshots": []
    },
    {
      "id": "local-agent-lab",
      "title": "Local AI Agent Lab",
      "tagline": "Learning how agents work by building one by hand — no framework, local model only.",
      "summary": "A from-scratch agent in TypeScript, planned in nine phases. Phases 1–2 are done — configuration, environment doctor, tests, an Ollama adapter and a local chat API; tools and the agent loop come next.",
      "description": [
        "A deliberately framework-free project for understanding agents: context building, decisions, tool validation, policy and approvals, written out explicitly.",
        "Status: phase 2 of 9 (19 Oct 2026). You can chat with the local model from the terminal or the local API. There is no tool use or agent loop yet — the architecture below is the plan, and the interfaces exist in code."
      ],
      "categories": [
        "agents",
        "experiments"
      ],
      "markets": [
        "agents"
      ],
      "status": "learning",
      "visibility": "public",
      "featured": null,
      "accent": "#c9a7a0",
      "period": "Oct 2026 —",
      "context": "Learning project",
      "platforms": [],
      "technologies": [
        "TypeScript",
        "Node.js",
        "SQLite",
        "Zod",
        "React",
        "Vite",
        "Vitest",
        "Ollama"
      ],
      "problem": "",
      "solution": "",
      "features": [
        {
          "title": "Config validation & `npm run doctor`",
          "detail": "Checks Node, Ollama and the model before anything runs.",
          "planned": false
        },
        {
          "title": "Local-only guard",
          "detail": "Rejects cloud models and non-loopback addresses.",
          "planned": false
        },
        {
          "title": "Ollama adapter, health check & chat API",
          "detail": "Raw HTTP adapter with per-call timeouts; /api/health and /api/chat; a terminal chat.",
          "planned": false
        },
        {
          "title": "Request limits",
          "detail": "Body size, message count and length limits; only user and assistant roles accepted.",
          "planned": false
        },
        {
          "title": "Tests",
          "detail": "Vitest, run with npm test.",
          "planned": false
        },
        {
          "title": "Tools",
          "detail": "Calculator, workspace read/search, notes — sandboxed to workspace/.",
          "planned": true
        },
        {
          "title": "Agent loop, approvals, SQLite memory, dashboard",
          "detail": "",
          "planned": true
        }
      ],
      "role": [],
      "architecture": {
        "summary": "",
        "flow": [
          {
            "title": "Context",
            "detail": "Task + history"
          },
          {
            "title": "Model decision",
            "detail": "Ollama, local"
          },
          {
            "title": "Validate",
            "detail": "Zod tool schemas"
          },
          {
            "title": "Policy",
            "detail": "Allow / approve / deny"
          },
          {
            "title": "Execute & verify",
            "detail": "Sandboxed tools"
          }
        ],
        "guards": [
          "Human approval step",
          "Workspace sandbox",
          "Local models only"
        ],
        "caption": "Planned architecture — phases 1–2 of 9 are implemented."
      },
      "agent": {
        "objective": "Understand each part of an agent by implementing it explicitly.",
        "input": "Planned: a task from a local dashboard.",
        "reasoning": "Planned loop: build context → call the model → parse its decision → validate tool arguments with Zod → policy check (allow / require approval / deny).",
        "tools": [
          "Planned: calculator",
          "Planned: workspace read & search",
          "Planned: notes"
        ],
        "execution": "Planned: execute, observe, verify, persist to SQLite.",
        "safety": "Designed in from the start: an approval manager that waits for a human decision, and file tools confined to a workspace folder.",
        "models": "Local only — Ollama with qwen3:4b; cloud models are rejected by configuration."
      },
      "impact": [],
      "links": [
        {
          "type": "github",
          "url": "https://github.com/Afaquejaya/learn-basic-ai-agent",
          "label": "Source on GitHub",
          "note": ""
        }
      ],
      "notes": [],
      "related": [
        "ai-job-agent",
        "careeros",
        "expense-tracker"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/local-agent-lab/concept.webp",
        "w": 1280,
        "h": 800,
        "alt": "Illustrative concept: the planned agent loop — context, model decision, argument validation, policy check, execution — next to a human approval prompt",
        "frame": "art",
        "illustrative": true,
        "caption": ""
      },
      "screenshots": []
    },
    {
      "id": "boring-doc",
      "title": "Boring Doc",
      "tagline": "We read the boring docs so you don’t have to — Flutter docs turned into short, evidence-backed explanations.",
      "summary": "Official docs are the source of truth but slow to use. Boring Doc keeps a synced index of the Flutter docs, release notes and API, and turns it into 30-second explanations, real version-to-version comparisons and a cited “what changed”.",
      "description": [
        "An interactive documentation platform that sits on top of the official Flutter documentation instead of copying it. Every topic opens with a one-sentence answer, then key points, an interactive visual, an analogy (with where it breaks), working code, common mistakes and the exact official sources it was checked against.",
        "An idempotent ingestion pipeline watches the official repositories and feeds, so you can compare any two real stable releases and see every indexed change — categorised, sorted by impact, with migration guides and evidence. AI explanations are optional, provider-independent and grounded in retrieved sources; everything works with AI switched off."
      ],
      "categories": [
        "ai",
        "web",
        "backend"
      ],
      "markets": [
        "ai",
        "tools"
      ],
      "status": "live",
      "visibility": "private",
      "featured": null,
      "accent": "#6d5cff",
      "period": "Oct 2026 —",
      "context": "Personal product",
      "platforms": [
        "Web",
        "Mobile web"
      ],
      "technologies": [
        "TypeScript",
        "Next.js",
        "React",
        "PostgreSQL",
        "PGlite",
        "Drizzle ORM",
        "Tailwind CSS",
        "Anthropic API",
        "Vercel"
      ],
      "problem": "Official docs are long and change every few weeks. Finding one answer means scrolling a 5,000-word page; “what changed between my version and the latest?” means reading dozens of release notes by hand; and chatbots answer with confident, made-up APIs.",
      "solution": "An intelligent layer over the docs: authored explanations verified against a specific version, a change index built automatically from the official sources, and AI that cites those sources or says “insufficient evidence”.",
      "features": [
        {
          "title": "Learn in 30 seconds",
          "detail": "Thirteen Flutter topics with the same nine sections: quick answer, key points, visual, analogy, code, when to use, mistakes, related, sources.",
          "planned": false
        },
        {
          "title": "Version Comparison Studio",
          "detail": "Any two real stable releases; changes by category and impact, migration guides, before/after diffs and an optional verified GitHub source diff.",
          "planned": false
        },
        {
          "title": "What’s new & Explore changes",
          "detail": "The latest stable series grouped by category; URL-driven filters by impact, evidence, platform and release.",
          "planned": false
        },
        {
          "title": "Search and command palette",
          "detail": "Concepts, guides, API symbols and changes in one search (Ctrl/Cmd+K), with typo tolerance.",
          "planned": false
        },
        {
          "title": "Automatic sync with provenance",
          "detail": "Webhook + daily cron ingestion; every record keeps its source commit and “last synchronized” time.",
          "planned": false
        },
        {
          "title": "Grounded AI (optional)",
          "detail": "Explain, generate an example, migration assistant — cites sources inline; works with local or hosted models.",
          "planned": false
        },
        {
          "title": "Review queue",
          "detail": "Low-confidence, high-impact items wait for a human before publishing.",
          "planned": false
        },
        {
          "title": "More ecosystems",
          "detail": "React Native, Android, Jetpack Compose, Swift, React and Next.js via adapters.",
          "planned": true
        }
      ],
      "role": [
        "Sole developer: product, ingestion pipeline, data model, UI and visual design, tests and deployment."
      ],
      "architecture": {
        "summary": "",
        "flow": [
          {
            "title": "Source adapters",
            "detail": "GitHub, release feeds, API index"
          },
          {
            "title": "Ingestion pipeline",
            "detail": "Idempotent, incremental, validated"
          },
          {
            "title": "PostgreSQL",
            "detail": "PGlite or managed; search index"
          },
          {
            "title": "Read models",
            "detail": "Comparison engine, queries"
          },
          {
            "title": "Next.js UI + grounded AI",
            "detail": "Topics, compare, what’s new"
          }
        ],
        "guards": [
          "HTTPS host allowlist for outbound requests",
          "HMAC-verified webhooks",
          "Sanitised Markdown",
          "Conservative publishing policy"
        ],
        "caption": "Simplified. Jobs are keyed by source + revision, so overlapping triggers never duplicate records."
      },
      "agent": null,
      "impact": [
        {
          "value": "3,679",
          "label": "indexed Flutter changes",
          "source": "Live site, 22 Oct 2026"
        },
        {
          "value": "180",
          "label": "stable releases tracked",
          "source": "Live site, 22 Oct 2026"
        },
        {
          "value": "4,624",
          "label": "API symbols searchable",
          "source": "Live site, 22 Oct 2026"
        },
        {
          "value": "67",
          "label": "unit tests, plus Playwright journeys",
          "source": "README"
        }
      ],
      "links": [
        {
          "type": "live",
          "url": "https://fresh-doc.vercel.app/",
          "label": "Open Boring Doc",
          "note": ""
        }
      ],
      "notes": [
        "Flutter is the only ecosystem built so far; the others are listed as planned.",
        "Boring Doc is independent and not affiliated with Google. Upstream docs stay under their own licences (flutter/website text CC BY 3.0)."
      ],
      "related": [
        "portfolio-guide",
        "ai-job-agent",
        "expense-tracker"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/boring-doc/home.webp",
        "w": 1280,
        "h": 800,
        "alt": "Boring Doc home page: “Understand faster. Compare anything. See what’s changed.” with a search box, suggested questions, a live preview of an interactive widget tree, and counters for stable releases, indexed changes, migration guides, API symbols and tracked doc pages",
        "frame": "web",
        "illustrative": false,
        "caption": "Home — live site, 22 Oct 2026"
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/projects/boring-doc/home.webp",
          "w": 1280,
          "h": 800,
          "alt": "Boring Doc home page with search, suggested questions, a rotating preview and indexed-content counters",
          "frame": "web",
          "illustrative": false,
          "caption": "Home — every number comes from the index"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/boring-doc/compare.webp",
          "w": 1280,
          "h": 800,
          "alt": "Version Comparison Studio comparing Flutter 3.41.0 to 3.47.7: 1,629 changes in range, 10 breaking or removed, 10 deprecations, all with official evidence, and a category distribution bar",
          "frame": "web",
          "illustrative": false,
          "caption": "Compare two real versions — 3.41.0 → 3.47.7"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/boring-doc/topic.webp",
          "w": 1280,
          "h": 800,
          "alt": "Topic page section “Understand visually” with an expandable widget tree, followed by a real-world analogy and a box explaining where the analogy breaks",
          "frame": "web",
          "illustrative": false,
          "caption": "Topic page — interactive widget tree and an honest analogy"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/boring-doc/whats-new.webp",
          "w": 1280,
          "h": 800,
          "alt": "What’s new in Flutter 3.47: release timeline, at-a-glance category bar and breaking-change cards with impact, version and migration-guide badges",
          "frame": "web",
          "illustrative": false,
          "caption": "What’s new — grouped, with evidence on every card"
        }
      ]
    },
    {
      "id": "glowfit-ai",
      "title": "GlowFit AI",
      "tagline": "One selfie in, a confident look out — skin analysis, virtual try-on and a score for which look suits you.",
      "summary": "Beauty shoppers guess which products and looks will suit them. GlowFit scans the skin, renders three looks on your own face and scores them — then lets you change one thing at a time.",
      "description": [
        "A hackathon build on Perfect Corp’s YouCam APIs. It turns skin analysis and virtual try-on into a decision flow: understand your skin, compare looks on your own face, adjust one variable, and leave with a look and a product list."
      ],
      "categories": [
        "ai",
        "web"
      ],
      "markets": [
        "ai",
        "tools"
      ],
      "status": "live",
      "visibility": "public",
      "featured": 5,
      "accent": "#d58f86",
      "period": "Oct 2026",
      "context": "YouCam API Skin AI & eCommerce VTO Hackathon (Perfect Corp)",
      "platforms": [
        "Web"
      ],
      "technologies": [
        "Next.js",
        "TypeScript",
        "React",
        "Tailwind CSS",
        "Zustand",
        "YouCam API",
        "MediaPipe"
      ],
      "problem": "Try-on tools show you a look, but don’t help you decide between looks — or explain why one suits your skin better.",
      "solution": "A five-step Decision Lab that combines skin metrics, face analysis and try-on renders into a comparable score, plus budget mode and single-variable previews.",
      "features": [
        {
          "title": "Skin Intelligence",
          "detail": "YouCam Skin AI score, eight metrics and a GlowMap.",
          "planned": false
        },
        {
          "title": "Decision Lab",
          "detail": "Three looks rendered on your face, each with a match score.",
          "planned": false
        },
        {
          "title": "Change one thing",
          "detail": "Swap a single product with a before/after slider.",
          "planned": false
        },
        {
          "title": "Hairstyles & budget mode",
          "detail": "AI hairstyle try-on and budget-aware product picks.",
          "planned": false
        },
        {
          "title": "Assistant",
          "detail": "Rule-based answers; an optional OpenAI-compatible model only rewrites the wording.",
          "planned": false
        }
      ],
      "role": [
        "Solo build: product flow, UI, API integration and deployment."
      ],
      "architecture": {
        "summary": "",
        "flow": [
          {
            "title": "Selfie",
            "detail": "Browser capture"
          },
          {
            "title": "Next.js API routes",
            "detail": "Keys stay server-side"
          },
          {
            "title": "YouCam APIs",
            "detail": "Skin, face, makeup, hair"
          },
          {
            "title": "Scoring",
            "detail": "Looks compared on metrics"
          },
          {
            "title": "Decision UI",
            "detail": "Zustand + IndexedDB cache"
          }
        ],
        "guards": [],
        "caption": "Simplified. No database or accounts — results are cached in the browser."
      },
      "agent": null,
      "impact": [],
      "links": [
        {
          "type": "video",
          "url": "https://www.youtube.com/watch?v=EdBg7vJooeQ",
          "label": "Demo video",
          "note": ""
        }
      ],
      "notes": [],
      "related": [
        "expense-tracker",
        "face-detection",
        "portfolio-guide"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/glowfit/screen-1.webp",
        "w": 1200,
        "h": 675,
        "alt": "GlowFit Skin Intelligence screen: skin score, eight skin metrics and an AI GlowMap on the face",
        "frame": "web",
        "illustrative": false,
        "caption": ""
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/projects/glowfit/screen-1.webp",
          "w": 1200,
          "h": 675,
          "alt": "Skin Intelligence: skin score, eight metrics and a GlowMap",
          "frame": "web",
          "illustrative": false,
          "caption": "Skin scan"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/glowfit/screen-2.webp",
          "w": 1200,
          "h": 675,
          "alt": "Decision Lab: three makeup looks rendered on the same face with match scores",
          "frame": "web",
          "illustrative": false,
          "caption": "Three looks, scored"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/glowfit/screen-3.webp",
          "w": 1200,
          "h": 675,
          "alt": "Change One Thing: lip shade options with a before and after slider",
          "frame": "web",
          "illustrative": false,
          "caption": "Change one thing"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/glowfit/screen-4.webp",
          "w": 1200,
          "h": 675,
          "alt": "Final decision screen with the chosen look and product list",
          "frame": "web",
          "illustrative": false,
          "caption": "The decision"
        }
      ]
    },
    {
      "id": "expense-tracker",
      "title": "AI Smart Expense Tracker",
      "tagline": "Type how you spent money — even in Hinglish — and get structured expense cards back.",
      "summary": "A Flutter client and FastAPI backend built around an “AI hook” — start, end and error callbacks modelled on LangChain’s callback lifecycle — that drives loading, structured JSON and error states.",
      "description": [
        "A small project for practising how an app should behave around an LLM call: show progress, accept only structured JSON, and fail gracefully.",
        "The backend currently simulates the model’s response; connecting a real LLM is the next step."
      ],
      "categories": [
        "ai",
        "mobile",
        "experiments"
      ],
      "markets": [
        "apps",
        "ai"
      ],
      "status": "learning",
      "visibility": "public",
      "featured": null,
      "accent": "#8f7ae0",
      "period": "Jun 2026",
      "context": "Learning project",
      "platforms": [
        "Flutter"
      ],
      "technologies": [
        "Flutter",
        "Dart",
        "Python",
        "FastAPI"
      ],
      "problem": "",
      "solution": "",
      "features": [
        {
          "title": "Natural-language entry",
          "detail": "One sentence can produce several expenses.",
          "planned": false
        },
        {
          "title": "AI hook lifecycle",
          "detail": "Start / end / error callbacks drive the UI states.",
          "planned": false
        },
        {
          "title": "Strict JSON contract",
          "detail": "Item, category, amount, currency.",
          "planned": false
        },
        {
          "title": "Graceful failure",
          "detail": "An error state with an offline fallback view.",
          "planned": false
        },
        {
          "title": "Real LLM parsing",
          "detail": "The backend returns a simulated response today.",
          "planned": true
        }
      ],
      "role": [],
      "architecture": null,
      "agent": null,
      "impact": [],
      "links": [
        {
          "type": "github",
          "url": "https://github.com/Afaquejaya/ai-expense-tracker",
          "label": "Source on GitHub",
          "note": ""
        },
        {
          "type": "code",
          "url": "https://gist.github.com/Afaquejaya/a4d157d4255799bd6e3521320f6d9537",
          "label": "Notes (gist)",
          "note": ""
        }
      ],
      "notes": [
        "The AI response is simulated in this version — the project demonstrates the hook pattern and UI states, not LLM accuracy."
      ],
      "related": [
        "glowfit-ai",
        "local-agent-lab",
        "pregnancy-tracker"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/expense/screen.webp",
        "w": 640,
        "h": 831,
        "alt": "App screen: a Hinglish sentence about dinner at Dubai Mall and a taxi turned into two expense cards — 120 AED food and 15 AED transport",
        "frame": "phone",
        "illustrative": false,
        "caption": ""
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/projects/expense/screen.webp",
          "w": 640,
          "h": 831,
          "alt": "Natural-language sentence turned into two expense cards",
          "frame": "phone",
          "illustrative": false,
          "caption": "Sentence in, expense cards out"
        }
      ]
    },
    {
      "id": "portfolio-guide",
      "title": "AI Portfolio Guide",
      "tagline": "A recruiter-facing chat on my portfolio that answers only from verified facts — and says so when it can’t.",
      "summary": "Chatbots on portfolios tend to invent things. This one matches questions to a knowledge base built from the CV, can only navigate to allowlisted sections, and never turns visitor text into a URL or code.",
      "description": [
        "Click the avatar on my portfolio and a chat panel opens. Questions are cleaned, safety-checked and scored against intents written from the CV. A confident match returns a stored answer with action buttons; anything else gets an honest “the portfolio doesn’t say” and the closest questions.",
        "An optional LLM fallback is designed (a serverless endpoint holding the key) but deliberately not enabled on GitHub Pages."
      ],
      "categories": [
        "ai",
        "web"
      ],
      "markets": [
        "ai",
        "tools"
      ],
      "status": "live",
      "visibility": "public",
      "featured": null,
      "accent": "#b493f0",
      "period": "Oct 2026",
      "context": "Part of afaquejaya.github.io",
      "platforms": [],
      "technologies": [
        "JavaScript",
        "HTML",
        "CSS"
      ],
      "problem": "",
      "solution": "",
      "features": [
        {
          "title": "Deterministic answers",
          "detail": "Weighted intent scoring over phrase and word keys.",
          "planned": false
        },
        {
          "title": "Allowlisted actions",
          "detail": "Buttons can only scroll to listed sections or open listed links.",
          "planned": false
        },
        {
          "title": "Input safety",
          "detail": "URLs, HTML, code and javascript: get a fixed reply; rendering uses textContent only.",
          "planned": false
        },
        {
          "title": "3D avatar",
          "detail": "Head and eyes follow the cursor; reduced-motion aware.",
          "planned": false
        },
        {
          "title": "LLM fallback",
          "detail": "Endpoint contract defined; off by default.",
          "planned": true
        }
      ],
      "role": [],
      "architecture": {
        "summary": "",
        "flow": [
          {
            "title": "Visitor question",
            "detail": "Max 300 chars, rate-limited"
          },
          {
            "title": "Safety check",
            "detail": "Links, HTML, code rejected"
          },
          {
            "title": "Intent scoring",
            "detail": "Verified knowledge base"
          },
          {
            "title": "Allowlisted action",
            "detail": "Scroll or open known link"
          },
          {
            "title": "Honest fallback",
            "detail": "No match → no guess"
          }
        ],
        "guards": [
          "No free-form generation",
          "No visitor text in URLs or selectors",
          "Nothing stored or sent"
        ],
        "caption": "How a message is handled."
      },
      "agent": null,
      "impact": [],
      "links": [
        {
          "type": "live",
          "url": "https://afaquejaya.github.io/",
          "label": "Try it on the portfolio",
          "note": ""
        },
        {
          "type": "github",
          "url": "https://github.com/Afaquejaya/afaquejaya.github.io",
          "label": "Source on GitHub",
          "note": ""
        }
      ],
      "notes": [],
      "related": [
        "portfolio-site",
        "glowfit-ai",
        "rental-mcp"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/portfolio-guide/screen.webp",
        "w": 1280,
        "h": 800,
        "alt": "The AI Portfolio Guide panel answering “How is MCP access authenticated?” and declining to guess details the portfolio doesn’t publish",
        "frame": "web",
        "illustrative": false,
        "caption": "Real capture of the live site"
      },
      "screenshots": []
    },
    {
      "id": "face-detection",
      "title": "Face Detection",
      "tagline": "Pick a photo; the app finds every face and reads age, emotion, hair, glasses and head pose.",
      "summary": "An early computer-vision project: detect faces in a photo and show per-face attributes from Microsoft’s Face API.",
      "description": [],
      "categories": [
        "ai",
        "mobile",
        "experiments"
      ],
      "markets": [
        "apps",
        "ai"
      ],
      "status": "learning",
      "visibility": "public",
      "featured": null,
      "accent": "#8fa0c9",
      "period": "Jan 2020",
      "context": "Personal project",
      "platforms": [
        "Android"
      ],
      "technologies": [
        "Java",
        "Kotlin",
        "Android",
        "Microsoft Face API"
      ],
      "problem": "",
      "solution": "",
      "features": [
        {
          "title": "Multi-face detection",
          "detail": "Landmarks drawn on each face.",
          "planned": false
        },
        {
          "title": "Attributes",
          "detail": "Age, gender, emotion, hair, glasses, make-up, head pose and image quality.",
          "planned": false
        }
      ],
      "role": [],
      "architecture": null,
      "agent": null,
      "impact": [],
      "links": [],
      "notes": [],
      "related": [
        "glowfit-ai",
        "social-app",
        "video-calling"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/face/screen-1.webp",
        "w": 480,
        "h": 976,
        "alt": "Face detection result: landmarks drawn on a face with age, gender, emotion and accessories listed",
        "frame": "phone",
        "illustrative": false,
        "caption": ""
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/projects/face/screen-1.webp",
          "w": 480,
          "h": 976,
          "alt": "Single face with landmarks and attributes",
          "frame": "phone",
          "illustrative": false,
          "caption": "Single face"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/face/screen-2.webp",
          "w": 480,
          "h": 974,
          "alt": "Two faces detected with attributes for each",
          "frame": "phone",
          "illustrative": false,
          "caption": "Multiple faces"
        }
      ]
    },
    {
      "id": "jeeb",
      "title": "Jeeb — Grocery & Logistics Platform",
      "tagline": "A 0→1 grocery e-commerce and delivery platform for Qatar, fully in Arabic.",
      "summary": "A fast-growing Qatari start-up needed a customer app, operations apps and the delivery chain behind them. A server-driven homepage and instant search made it 95% faster and lifted engagement 50%.",
      "description": [
        "Built with the founders from zero: the customer grocery app with Arabic localisation, a server-driven personalised homepage, Algolia instant search, real-time GPS tracking, route optimisation and secure payments.",
        "I also led a remote team building the Driver, Collector and Storekeeper apps that run the delivery side."
      ],
      "categories": [
        "mobile",
        "backend"
      ],
      "markets": [
        "apps"
      ],
      "status": "shipped",
      "visibility": "internal",
      "featured": 4,
      "accent": "#3f86ef",
      "period": "Sep 2022 – Sep 2024",
      "context": "Software Engineer · Jeeb E-Commerce & Logistics (start-up), Doha",
      "platforms": [
        "Android",
        "iOS",
        "Web"
      ],
      "technologies": [
        "Flutter",
        "React Native",
        "Swift",
        "Kotlin",
        "Java",
        "Python",
        "Algolia",
        "IoT"
      ],
      "problem": "An omnichannel grocery business needed to launch fast in an Arabic-first market, with a homepage merchandisers could change without app releases.",
      "solution": "A server-driven homepage rendered natively by the app, Algolia instead of in-house search, and a set of operations apps for the delivery chain.",
      "features": [
        {
          "title": "Server-driven personalised homepage",
          "detail": "Merchandising changes without an app release.",
          "planned": false
        },
        {
          "title": "Algolia instant search",
          "detail": "Typo-tolerant search replacing in-house search.",
          "planned": false
        },
        {
          "title": "Real-time GPS tracking & route optimisation",
          "detail": "",
          "planned": false
        },
        {
          "title": "Secure payments",
          "detail": "",
          "planned": false
        },
        {
          "title": "Driver, Collector & Storekeeper apps",
          "detail": "Built with a remote team I led.",
          "planned": false
        },
        {
          "title": "Arabic localisation",
          "detail": "Arabic-first UI.",
          "planned": false
        }
      ],
      "role": [
        "Built and launched the 0→1 platform working directly with the founders.",
        "Architected the server-driven personalised homepage with Algolia search.",
        "Engineered GPS tracking, route optimisation and payment integration.",
        "Led the remote team building the Driver, Collector and Storekeeper apps."
      ],
      "architecture": {
        "summary": "",
        "flow": [
          {
            "title": "Server",
            "detail": "Layout + personalised content"
          },
          {
            "title": "App renderer",
            "detail": "Layout blocks → native widgets"
          },
          {
            "title": "Algolia",
            "detail": "Instant search"
          },
          {
            "title": "Customer",
            "detail": "Personalised home, in Arabic"
          }
        ],
        "guards": [],
        "caption": "Server-driven UI, simplified — an illustration of the idea, not a production diagram."
      },
      "agent": null,
      "impact": [
        {
          "value": "95%",
          "label": "faster homepage load",
          "source": "CV"
        },
        {
          "value": "+50%",
          "label": "user engagement",
          "source": "CV"
        },
        {
          "value": "+60%",
          "label": "delivery speed (operations apps)",
          "source": "CV"
        },
        {
          "value": "+20%",
          "label": "delivery & checkout efficiency",
          "source": "CV"
        }
      ],
      "links": [],
      "notes": [
        "Employer product. The store listings are no longer public, so there are no app links or screenshots here."
      ],
      "related": [
        "pass-delivery",
        "tbay",
        "evv"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/jeeb/concept.webp",
        "w": 1280,
        "h": 800,
        "alt": "Illustrative concept: an Arabic-first grocery home screen with categories and offers, and a delivery tracking map",
        "frame": "art",
        "illustrative": true,
        "caption": ""
      },
      "screenshots": []
    },
    {
      "id": "pass-delivery",
      "title": "Pass Delivery & Operations Apps",
      "tagline": "On-demand delivery in Qatar — customer, Driver, Collector and Storekeeper apps.",
      "summary": "Couriers, collectors and storekeepers needed purpose-built tools. Real-time tracking and dedicated operations apps lifted delivery speed by 60%.",
      "description": [],
      "categories": [
        "mobile"
      ],
      "markets": [
        "apps"
      ],
      "status": "shipped",
      "visibility": "internal",
      "featured": null,
      "accent": "#1cc4cc",
      "period": "2022 – 2024",
      "context": "Jeeb E-Commerce & Logistics, Doha",
      "platforms": [
        "Android",
        "iOS"
      ],
      "technologies": [
        "Flutter",
        "Kotlin",
        "Java",
        "Python",
        "IoT"
      ],
      "problem": "",
      "solution": "",
      "features": [
        {
          "title": "Real-time GPS tracking",
          "detail": "",
          "planned": false
        },
        {
          "title": "Route optimisation",
          "detail": "",
          "planned": false
        },
        {
          "title": "Secure payments",
          "detail": "",
          "planned": false
        },
        {
          "title": "Driver, Collector & Storekeeper apps",
          "detail": "One app per role in the delivery chain.",
          "planned": false
        }
      ],
      "role": [
        "Engineered the logistics features and led the remote team building the operations apps."
      ],
      "architecture": null,
      "agent": null,
      "impact": [
        {
          "value": "+60%",
          "label": "delivery speed",
          "source": "CV"
        },
        {
          "value": "+20%",
          "label": "delivery efficiency",
          "source": "CV"
        },
        {
          "value": "3",
          "label": "operations apps",
          "source": ""
        }
      ],
      "links": [],
      "notes": [
        "The Play Store listing is no longer public."
      ],
      "related": [
        "jeeb",
        "tbay",
        "evv"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/apps/pass/screen-1.webp",
        "w": 560,
        "h": 957,
        "alt": "Pass store screenshot: live tracking with a courier’s car on the map and “Pickup in 2 min”",
        "frame": "phone",
        "illustrative": false,
        "caption": ""
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/apps/pass/screen-1.webp",
          "w": 560,
          "h": 957,
          "alt": "Live tracking with the courier on the map",
          "frame": "phone",
          "illustrative": false,
          "caption": "Live tracking"
        },
        {
          "src": "https://afaquejaya.github.io/img/apps/pass/screen-2.webp",
          "w": 560,
          "h": 957,
          "alt": "Driver orders list with pick-up and drop-off addresses in Doha and fares",
          "frame": "phone",
          "illustrative": false,
          "caption": "Driver orders"
        }
      ]
    },
    {
      "id": "tbay",
      "title": "Tbay",
      "tagline": "A gift-card marketplace for Nigeria and Ghana — escrow-protected trades, live rates, fast payouts.",
      "summary": "Selling an unused gift card for cash is slow and risky when you don’t trust the buyer. Tbay puts escrow and bonded vendors between both sides.",
      "description": [
        "A peer-to-peer marketplace where people trade gift cards for local currency. Vetted vendors compete on rates, trades are escrow-protected, and payouts go straight to a bank or mobile-money wallet.",
        "Part of the Kobet FinTech family — Tbay, VivaKard, TimuCard and BitOwi — that I helped architect and ship with a team across Dubai, China and Sri Lanka."
      ],
      "categories": [
        "mobile"
      ],
      "markets": [
        "apps"
      ],
      "status": "live",
      "visibility": "public",
      "featured": 2,
      "accent": "#2bb3a3",
      "period": "2024 – 2026",
      "context": "Senior Software Engineer · Kobet Technology DMCC, Dubai",
      "platforms": [
        "Android",
        "iOS"
      ],
      "technologies": [
        "Flutter",
        "React Native",
        "Kotlin",
        "Swift",
        "Dart",
        "CI/CD"
      ],
      "problem": "Gift-card holders want cash without the risk of trading with strangers.",
      "solution": "Escrow-protected trades with vetted vendors competing on live rates, and payouts to bank or mobile money.",
      "features": [
        {
          "title": "Escrow-protected trades",
          "detail": "",
          "planned": false
        },
        {
          "title": "Live vendor rates",
          "detail": "",
          "planned": false
        },
        {
          "title": "Bank & mobile-money payouts",
          "detail": "",
          "planned": false
        },
        {
          "title": "KYC and two-factor authentication",
          "detail": "Across the Kobet app family.",
          "planned": false
        }
      ],
      "role": [
        "Architected and delivered cross-platform FinTech apps (crypto, wallet, KYC, 2FA) with real-time data.",
        "Led a cross-country team across Dubai, China and Sri Lanka: planning, releases, documentation and CI/CD.",
        "Shipped production releases to Google Play and the App Store."
      ],
      "architecture": null,
      "agent": null,
      "impact": [
        {
          "value": "1M+",
          "label": "downloads on Google Play",
          "source": "Google Play listing, Oct 2026"
        },
        {
          "value": "4.6★",
          "label": "from 42.6K reviews",
          "source": "Google Play listing, Oct 2026"
        },
        {
          "value": "3",
          "label": "countries in the delivery team",
          "source": "CV"
        }
      ],
      "links": [
        {
          "type": "play",
          "url": "https://play.google.com/store/apps/details?id=com.gonglian.tbay",
          "label": "Google Play",
          "note": ""
        },
        {
          "type": "ios",
          "url": "https://apps.apple.com/us/app/gift-card-on-tbay/id6472409948",
          "label": "App Store",
          "note": ""
        }
      ],
      "notes": [],
      "related": [
        "vivakard",
        "timucard",
        "bitowi"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/apps/tbay/screen-1.webp",
        "w": 560,
        "h": 996,
        "alt": "Tbay app showing live gift-card rates for Razer, Steam, Vanilla, Sephora and more",
        "frame": "phone",
        "illustrative": false,
        "caption": ""
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/apps/tbay/screen-1.webp",
          "w": 560,
          "h": 996,
          "alt": "Live gift-card rates",
          "frame": "phone",
          "illustrative": false,
          "caption": "Live rates"
        },
        {
          "src": "https://afaquejaya.github.io/img/apps/tbay/screen-2.webp",
          "w": 560,
          "h": 996,
          "alt": "Store panel: the most trusted gift card trading platform",
          "frame": "phone",
          "illustrative": false,
          "caption": "Store panel"
        },
        {
          "src": "https://afaquejaya.github.io/img/apps/tbay/screen-3.webp",
          "w": 560,
          "h": 996,
          "alt": "Store panel: sell 30+ gift cards instantly at best rates",
          "frame": "phone",
          "illustrative": false,
          "caption": "Store panel"
        }
      ]
    },
    {
      "id": "vivakard",
      "title": "VivaKard",
      "tagline": "Turns gift cards into naira with transparent rates — plus referrals, check-ins and a leaderboard.",
      "summary": "Gift-card holders want a fast, fair cash-out without haggling or hidden fees. VivaKard covers 20+ brands with clear rates and engagement loops that bring users back.",
      "description": [],
      "categories": [
        "mobile"
      ],
      "markets": [
        "apps"
      ],
      "status": "live",
      "visibility": "public",
      "featured": null,
      "accent": "#a6d14a",
      "period": "2024 – 2026",
      "context": "Kobet Technology DMCC, Dubai",
      "platforms": [
        "Android",
        "iOS"
      ],
      "technologies": [
        "Flutter",
        "React Native",
        "Kotlin",
        "Swift",
        "Google Sign-In"
      ],
      "problem": "",
      "solution": "",
      "features": [
        {
          "title": "Gift cards to cash",
          "detail": "Amazon, iTunes, Steam, Google Play, Xbox and more.",
          "planned": false
        },
        {
          "title": "One-tap Google sign-in",
          "detail": "",
          "planned": false
        },
        {
          "title": "Referrals, daily check-ins & leaderboard",
          "detail": "",
          "planned": false
        }
      ],
      "role": [
        "Cross-platform delivery and production releases on both stores with the team I led."
      ],
      "architecture": null,
      "agent": null,
      "impact": [
        {
          "value": "100K+",
          "label": "downloads on Google Play",
          "source": "Google Play listing, Oct 2026"
        },
        {
          "value": "4.4★",
          "label": "from 1.1K reviews",
          "source": "Google Play listing, Oct 2026"
        }
      ],
      "links": [
        {
          "type": "play",
          "url": "https://play.google.com/store/apps/details?id=com.gift.vivakard&hl=en",
          "label": "Google Play",
          "note": ""
        },
        {
          "type": "ios",
          "url": "https://apps.apple.com/us/app/vivakard-plus/id6749223091",
          "label": "App Store",
          "note": ""
        }
      ],
      "notes": [],
      "related": [
        "tbay",
        "timucard",
        "bitowi"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/apps/vivakard/screen-1.webp",
        "w": 560,
        "h": 1212,
        "alt": "VivaKard store panel: get cash for your gift cards in minutes",
        "frame": "phone",
        "illustrative": false,
        "caption": ""
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/apps/vivakard/screen-1.webp",
          "w": 560,
          "h": 1212,
          "alt": "Get cash for your gift cards in minutes",
          "frame": "phone",
          "illustrative": false,
          "caption": "Home"
        },
        {
          "src": "https://afaquejaya.github.io/img/apps/vivakard/screen-2.webp",
          "w": 560,
          "h": 1212,
          "alt": "Trade 50+ gift cards",
          "frame": "phone",
          "illustrative": false,
          "caption": "Gift cards"
        },
        {
          "src": "https://afaquejaya.github.io/img/apps/vivakard/screen-3.webp",
          "w": 560,
          "h": 1212,
          "alt": "One-tap Google login",
          "frame": "phone",
          "illustrative": false,
          "caption": "Google sign-in"
        }
      ]
    },
    {
      "id": "timucard",
      "title": "TimuCard",
      "tagline": "Gift cards to instant payouts — then pay electricity, cable, airtime and data bills from the balance.",
      "summary": "Money stuck on unused gift cards becomes a balance people can withdraw or spend on everyday bills, with a live rate ticker and device-level fraud monitoring.",
      "description": [],
      "categories": [
        "mobile"
      ],
      "markets": [
        "apps"
      ],
      "status": "live",
      "visibility": "public",
      "featured": null,
      "accent": "#ff5a3c",
      "period": "2024 – 2026",
      "context": "Kobet Technology DMCC, Dubai",
      "platforms": [
        "Android",
        "iOS"
      ],
      "technologies": [
        "Flutter",
        "React Native",
        "Kotlin",
        "Swift",
        "Biometrics"
      ],
      "problem": "",
      "solution": "",
      "features": [
        {
          "title": "Instant payouts with live rate ticker",
          "detail": "",
          "planned": false
        },
        {
          "title": "Bill payments",
          "detail": "Electricity, cable, airtime and data.",
          "planned": false
        },
        {
          "title": "Biometric security & fraud monitoring",
          "detail": "",
          "planned": false
        },
        {
          "title": "Referral rewards",
          "detail": "",
          "planned": false
        }
      ],
      "role": [
        "Part of the FinTech app family I helped architect and ship on both stores."
      ],
      "architecture": null,
      "agent": null,
      "impact": [
        {
          "value": "50K+",
          "label": "downloads on Google Play",
          "source": "Google Play listing, Oct 2026"
        },
        {
          "value": "4.6★",
          "label": "rating",
          "source": "Google Play listing, Oct 2026"
        }
      ],
      "links": [
        {
          "type": "play",
          "url": "https://play.google.com/store/apps/details?id=com.timucard.gift&hl=en",
          "label": "Google Play",
          "note": ""
        },
        {
          "type": "ios",
          "url": "https://apps.apple.com/us/app/timucard/id6752526295",
          "label": "App Store",
          "note": ""
        }
      ],
      "notes": [],
      "related": [
        "tbay",
        "vivakard",
        "bitowi"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/apps/timucard/screen-1.webp",
        "w": 554,
        "h": 1200,
        "alt": "TimuCard store panel: highest rates, instant cashouts",
        "frame": "phone",
        "illustrative": false,
        "caption": ""
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/apps/timucard/screen-1.webp",
          "w": 554,
          "h": 1200,
          "alt": "Highest rates, instant cashouts",
          "frame": "phone",
          "illustrative": false,
          "caption": "Rates & cashouts"
        },
        {
          "src": "https://afaquejaya.github.io/img/apps/timucard/screen-2.webp",
          "w": 554,
          "h": 1200,
          "alt": "Invite friends and earn",
          "frame": "phone",
          "illustrative": false,
          "caption": "Referrals"
        },
        {
          "src": "https://afaquejaya.github.io/img/apps/timucard/screen-3.webp",
          "w": 554,
          "h": 1200,
          "alt": "Bill payments and biometrics",
          "frame": "phone",
          "illustrative": false,
          "caption": "Bills & biometrics"
        }
      ]
    },
    {
      "id": "bitowi",
      "title": "BitOwi",
      "tagline": "A crypto wallet — store, send and receive crypto with balances and history in one place.",
      "summary": "Part of the Kobet FinTech family: a crypto wallet with KYC and two-factor authentication, shipped on Google Play.",
      "description": [],
      "categories": [
        "mobile"
      ],
      "markets": [
        "apps"
      ],
      "status": "live",
      "visibility": "public",
      "featured": null,
      "accent": "#e2a54a",
      "period": "2024 – 2026",
      "context": "Kobet Technology DMCC, Dubai",
      "platforms": [
        "Android"
      ],
      "technologies": [
        "Flutter",
        "Kotlin",
        "KYC",
        "2FA"
      ],
      "problem": "",
      "solution": "",
      "features": [
        {
          "title": "Store, send & receive crypto",
          "detail": "",
          "planned": false
        },
        {
          "title": "Balances & history",
          "detail": "",
          "planned": false
        },
        {
          "title": "KYC & two-factor authentication",
          "detail": "Shared across the Kobet app family.",
          "planned": false
        }
      ],
      "role": [
        "Architected and delivered with the Kobet team; production release on Google Play."
      ],
      "architecture": null,
      "agent": null,
      "impact": [],
      "links": [
        {
          "type": "play",
          "url": "https://play.google.com/store/apps/details?id=com.bitowi.app&hl=en_US",
          "label": "Google Play",
          "note": ""
        }
      ],
      "notes": [],
      "related": [
        "tbay",
        "vivakard",
        "timucard"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/bitowi/concept.webp",
        "w": 1280,
        "h": 800,
        "alt": "Illustrative concept: a crypto wallet with total balance, send and receive, asset list, and a receive screen",
        "frame": "art",
        "illustrative": true,
        "caption": ""
      },
      "screenshots": []
    },
    {
      "id": "evv",
      "title": "eVV 2.0",
      "tagline": "Jharkhand’s school-education platform — enrolment, biometric attendance, teachers and schemes in one app.",
      "summary": "With schools closed by COVID-19, a state government needed to track students, teachers and schemes across thousands of schools. The state’s ed-tech apps passed 500K downloads with state-wide adoption.",
      "description": [
        "The Department of School Education & Literacy’s platform for running and monitoring schools across Jharkhand, used by officers, schools and teachers. I owned delivery from requirements and biometric configuration through UAT, rollout and support."
      ],
      "categories": [
        "mobile"
      ],
      "markets": [
        "apps"
      ],
      "status": "live",
      "visibility": "public",
      "featured": 6,
      "accent": "#4f8df5",
      "period": "Aug 2020 – Sep 2022",
      "context": "Software Engineer · CSM Technologies (CMMI Level 5), Ranchi",
      "platforms": [
        "Android"
      ],
      "technologies": [
        "Flutter",
        "React Native",
        "Kotlin",
        "Java",
        ".NET",
        "PHP",
        "Biometrics"
      ],
      "problem": "Keeping school management, attendance, mid-day meals and learning running state-wide when classrooms closed.",
      "solution": "Role-based mobile apps for officers, schools and teachers, with biometric attendance configured for real schools, plus training and rollout support.",
      "features": [
        {
          "title": "Biometric attendance",
          "detail": "Configured for real schools.",
          "planned": false
        },
        {
          "title": "Student & teacher enrolment and tracking",
          "detail": "",
          "planned": false
        },
        {
          "title": "Role-based logins",
          "detail": "Officer, school and teacher.",
          "planned": false
        },
        {
          "title": "Monitoring, schemes & grievances",
          "detail": "",
          "planned": false
        }
      ],
      "role": [
        "Owned delivery end to end: requirements, biometric configuration, development, UAT, rollout and post-launch support.",
        "Led client demos and user training for state-wide adoption."
      ],
      "architecture": null,
      "agent": null,
      "impact": [
        {
          "value": "500K+",
          "label": "downloads on Google Play",
          "source": "Google Play listing, Oct 2026"
        },
        {
          "value": "State-wide",
          "label": "rollout and adoption",
          "source": "CV"
        },
        {
          "value": "3",
          "label": "roles: officer, school, teacher",
          "source": ""
        }
      ],
      "links": [
        {
          "type": "play",
          "url": "https://play.google.com/store/apps/details?id=com.evidyavahini.app",
          "label": "Google Play",
          "note": ""
        }
      ],
      "notes": [],
      "related": [
        "digischool",
        "jmr",
        "ecampuslink"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/apps/evv/screen-1.webp",
        "w": 560,
        "h": 996,
        "alt": "eVV home grid: data download, student enrolment, student attendance, teacher enrolment, monitoring and more",
        "frame": "phone",
        "illustrative": false,
        "caption": ""
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/apps/evv/screen-1.webp",
          "w": 560,
          "h": 996,
          "alt": "Home grid of modules",
          "frame": "phone",
          "illustrative": false,
          "caption": "Modules"
        },
        {
          "src": "https://afaquejaya.github.io/img/apps/evv/screen-2.webp",
          "w": 560,
          "h": 996,
          "alt": "Login with Officer, School and Teacher roles",
          "frame": "phone",
          "illustrative": false,
          "caption": "Role-based login"
        },
        {
          "src": "https://afaquejaya.github.io/img/apps/evv/screen-3.webp",
          "w": 560,
          "h": 996,
          "alt": "Student enrolment form",
          "frame": "phone",
          "illustrative": false,
          "caption": "Student enrolment"
        }
      ]
    },
    {
      "id": "digischool",
      "title": "DigiSchool",
      "tagline": "E-learning for state-government schools during COVID-19.",
      "summary": "Part of the state ed-tech suite alongside eVV: e-learning so students could keep studying while schools were closed.",
      "description": [],
      "categories": [
        "mobile"
      ],
      "markets": [
        "apps"
      ],
      "status": "shipped",
      "visibility": "internal",
      "featured": null,
      "accent": "#6b9cf5",
      "period": "2020 – 2022",
      "context": "CSM Technologies, Ranchi",
      "platforms": [
        "Android"
      ],
      "technologies": [
        "Flutter",
        "React Native",
        "Kotlin",
        "Java"
      ],
      "problem": "",
      "solution": "",
      "features": [],
      "role": [
        "Built and launched as part of the state-government ed-tech apps."
      ],
      "architecture": null,
      "agent": null,
      "impact": [
        {
          "value": "500K+",
          "label": "downloads across the state’s ed-tech apps",
          "source": "CV"
        }
      ],
      "links": [],
      "notes": [
        "The store listing is no longer public."
      ],
      "related": [
        "evv",
        "jmr",
        "ecampuslink"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/digischool/concept.webp",
        "w": 1280,
        "h": 800,
        "alt": "Illustrative concept: two phone screens of an e-learning app — today’s lesson and subjects, and a video lesson with notes and a quiz",
        "frame": "art",
        "illustrative": true,
        "caption": ""
      },
      "screenshots": []
    },
    {
      "id": "jmr",
      "title": "JMR — Vendor Register App",
      "tagline": "A native app that replaced paper vendor registers at a Tata Steel company.",
      "summary": "Vendor registers were kept by hand. A native app backed by .NET APIs cut data-entry time by 70% and improved accuracy by 50%.",
      "description": [],
      "categories": [
        "mobile",
        "backend"
      ],
      "markets": [
        "apps"
      ],
      "status": "shipped",
      "visibility": "internal",
      "featured": null,
      "accent": "#2f6fb0",
      "period": "Aug 2019 – Aug 2020",
      "context": "Android App Developer · JUSCO (Tata Steel company), Jamshedpur",
      "platforms": [
        "Android"
      ],
      "technologies": [
        "Kotlin",
        "Java",
        ".NET",
        "C#",
        "SQL"
      ],
      "problem": "",
      "solution": "",
      "features": [
        {
          "title": "Digital vendor register",
          "detail": "Replaces manual paper processes.",
          "planned": false
        },
        {
          "title": "Scalable .NET backend APIs",
          "detail": "",
          "planned": false
        }
      ],
      "role": [
        "Built the native app and its .NET backend APIs; optimised API and database performance."
      ],
      "architecture": null,
      "agent": null,
      "impact": [
        {
          "value": "70%",
          "label": "less data-entry time",
          "source": "CV"
        },
        {
          "value": "+50%",
          "label": "data accuracy",
          "source": "CV"
        }
      ],
      "links": [],
      "notes": [
        "The store listing is no longer public."
      ],
      "related": [
        "ecampuslink",
        "tgs-dashboard",
        "evv"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/jmr/concept.webp",
        "w": 1280,
        "h": 800,
        "alt": "Illustrative concept: a vendor register on a tablet with entries and statuses, and a phone form for a new entry",
        "frame": "art",
        "illustrative": true,
        "caption": ""
      },
      "screenshots": []
    },
    {
      "id": "ecampuslink",
      "title": "e-CampusLink",
      "tagline": "Cross-platform web and mobile school apps built on .NET and Xamarin.",
      "summary": "School apps for web and mobile, connected to an ERP and third-party APIs.",
      "description": [],
      "categories": [
        "mobile",
        "web",
        "backend"
      ],
      "markets": [
        "apps"
      ],
      "status": "shipped",
      "visibility": "internal",
      "featured": null,
      "accent": "#6b9cf5",
      "period": "2019 – 2020",
      "context": "JUSCO (Tata Steel company) · LHS + MFK Software",
      "platforms": [
        "Android",
        "Web"
      ],
      "technologies": [
        "Xamarin",
        "C#",
        ".NET",
        "SQL",
        "ERP integration"
      ],
      "problem": "",
      "solution": "",
      "features": [],
      "role": [
        "Built the cross-platform apps and their integrations with the ERP and third-party APIs."
      ],
      "architecture": null,
      "agent": null,
      "impact": [
        {
          "value": "+40%",
          "label": "sales after API & database optimisation (role-wide)",
          "source": "CV"
        }
      ],
      "links": [],
      "notes": [
        "The store listing is no longer public."
      ],
      "related": [
        "jmr",
        "evv",
        "digischool"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/ecampuslink/concept.webp",
        "w": 1280,
        "h": 800,
        "alt": "Illustrative concept: a school portal dashboard with attendance, fees and the day’s timetable, and a phone showing school notices",
        "frame": "art",
        "illustrative": true,
        "caption": ""
      },
      "screenshots": []
    },
    {
      "id": "pregnancy-tracker",
      "title": "Pregnancy Tracker",
      "tagline": "A calm, offline week-by-week companion — with today’s week on the home screen.",
      "summary": "Progress, what’s changing, care tips, reminders and a wellness challenge — fully offline, no account, with two home-screen widgets.",
      "description": [
        "A native Android app: set a due date (or last period), then follow a 40-week timeline, nutrition and care guidance, reminders and a wellness challenge with streaks. Everything stays on the device.",
        "It started from a Google AI Studio generation that I extended into the current app."
      ],
      "categories": [
        "mobile",
        "experiments"
      ],
      "markets": [
        "apps"
      ],
      "status": "prototype",
      "visibility": "private",
      "featured": null,
      "accent": "#e58a80",
      "period": "Aug – Oct 2026",
      "context": "Personal project",
      "platforms": [
        "Android"
      ],
      "technologies": [
        "Kotlin",
        "Jetpack Compose",
        "Material 3",
        "Room",
        "AppWidget",
        "Robolectric"
      ],
      "problem": "",
      "solution": "",
      "features": [
        {
          "title": "40-week timeline",
          "detail": "Filterable by trimester.",
          "planned": false
        },
        {
          "title": "Nutrition & care",
          "detail": "",
          "planned": false
        },
        {
          "title": "Reminders that survive reboots",
          "detail": "AlarmManager + boot receiver.",
          "planned": false
        },
        {
          "title": "Wellness challenge",
          "detail": "Onboarding, streaks, achievements, progress and learn.",
          "planned": false
        },
        {
          "title": "Two home-screen widgets",
          "detail": "",
          "planned": false
        },
        {
          "title": "Light & dark themes, fully offline",
          "detail": "",
          "planned": false
        },
        {
          "title": "Play Store release",
          "detail": "",
          "planned": true
        }
      ],
      "role": [],
      "architecture": null,
      "agent": null,
      "impact": [],
      "links": [],
      "notes": [
        "Not published on Google Play; distributed as a test APK. The source repository is private."
      ],
      "related": [
        "expense-tracker",
        "social-app",
        "face-detection"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/pregnancy/dark-home.webp",
        "w": 540,
        "h": 1202,
        "alt": "Pregnancy Tracker home in dark mode: week 25, 108 days to go, progress bar, week selector and baby size this week",
        "frame": "phone",
        "illustrative": false,
        "caption": ""
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/projects/pregnancy/dark-home.webp",
          "w": 540,
          "h": 1202,
          "alt": "Home: week, days to go and baby size",
          "frame": "phone",
          "illustrative": false,
          "caption": "Home"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/pregnancy/dark-timeline.webp",
          "w": 540,
          "h": 1202,
          "alt": "40-week timeline",
          "frame": "phone",
          "illustrative": false,
          "caption": "40-week timeline"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/pregnancy/dark-widgets.webp",
          "w": 540,
          "h": 462,
          "alt": "Two home-screen widgets: pregnancy timeline and wellness progress",
          "frame": "panel",
          "illustrative": false,
          "caption": "Home-screen widgets"
        }
      ]
    },
    {
      "id": "portfolio-site",
      "title": "afaquejaya.github.io",
      "tagline": "My hand-built portfolio — no framework, no build step, no templates.",
      "summary": "An editorial portfolio with pinned horizontal-scroll sections, a 3D avatar guide and an Ask-an-AI card — all vanilla, accessible and reduced-motion aware.",
      "description": [],
      "categories": [
        "web"
      ],
      "markets": [
        "tools"
      ],
      "status": "live",
      "visibility": "public",
      "featured": null,
      "accent": "#ff5b24",
      "period": "2026",
      "context": "Personal",
      "platforms": [],
      "technologies": [
        "HTML",
        "CSS",
        "JavaScript",
        "GitHub Pages"
      ],
      "problem": "",
      "solution": "",
      "features": [
        {
          "title": "Pinned horizontal scrolling",
          "detail": "Follows native scroll, never hijacks it.",
          "planned": false
        },
        {
          "title": "3D avatar & AI Portfolio Guide",
          "detail": "",
          "planned": false
        },
        {
          "title": "Data-driven app and logo sections",
          "detail": "",
          "planned": false
        },
        {
          "title": "Accessible by default",
          "detail": "Skip link, focus states, reduced motion.",
          "planned": false
        },
        {
          "title": "This showcase",
          "detail": "A data-driven companion site for the full catalog.",
          "planned": false
        }
      ],
      "role": [],
      "architecture": null,
      "agent": null,
      "impact": [],
      "links": [
        {
          "type": "live",
          "url": "https://afaquejaya.github.io/",
          "label": "Open the portfolio",
          "note": ""
        },
        {
          "type": "github",
          "url": "https://github.com/Afaquejaya/afaquejaya.github.io",
          "label": "Source on GitHub",
          "note": ""
        }
      ],
      "notes": [],
      "related": [
        "portfolio-guide",
        "glowfit-ai",
        "rental-saas"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/portfolio-site/screen.webp",
        "w": 1280,
        "h": 800,
        "alt": "The portfolio’s hero: headline, introduction, call-to-action buttons and the ID-badge portrait",
        "frame": "web",
        "illustrative": false,
        "caption": "Real capture of the live site"
      },
      "screenshots": []
    },
    {
      "id": "tgs-dashboard",
      "title": "IoT Monitoring Dashboard",
      "tagline": "A Windows dashboard monitoring 100+ IoT devices.",
      "summary": "An internship project: one dashboard to watch 100+ IoT devices, improving operational efficiency by 30%.",
      "description": [],
      "categories": [
        "backend",
        "experiments"
      ],
      "markets": [
        "tools"
      ],
      "status": "shipped",
      "visibility": "internal",
      "featured": null,
      "accent": "#8fb36b",
      "period": "Mar – Apr 2018",
      "context": "Data Analyst intern · Tata Growth Shop, Jamshedpur",
      "platforms": [
        "Windows"
      ],
      "technologies": [
        ".NET",
        "C#",
        "SQL"
      ],
      "problem": "",
      "solution": "",
      "features": [],
      "role": [
        "Built the dashboard and its data layer."
      ],
      "architecture": null,
      "agent": null,
      "impact": [
        {
          "value": "100+",
          "label": "IoT devices monitored",
          "source": "CV"
        },
        {
          "value": "+30%",
          "label": "operational efficiency",
          "source": "CV"
        }
      ],
      "links": [],
      "notes": [],
      "related": [
        "jmr",
        "ecampuslink",
        "rental-saas"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/tgs-dashboard/concept.webp",
        "w": 1280,
        "h": 800,
        "alt": "Illustrative concept: a desktop IoT monitoring dashboard with device counts, a grid of device tiles, a throughput chart and alerts",
        "frame": "art",
        "illustrative": true,
        "caption": ""
      },
      "screenshots": []
    },
    {
      "id": "social-app",
      "title": "Social Media App",
      "tagline": "Posts, likes, comments, friends, chat and calls — a full social app on Android.",
      "summary": "A full social app with Google Sign-In, posts with photos, friend requests, one-to-one chat, voice and video calls and real-time notifications.",
      "description": [],
      "categories": [
        "experiments",
        "mobile"
      ],
      "markets": [
        "apps"
      ],
      "status": "learning",
      "visibility": "public",
      "featured": null,
      "accent": "#c9a7a0",
      "period": "Feb 2019",
      "context": "Personal project",
      "platforms": [
        "Android"
      ],
      "technologies": [
        "Java",
        "Kotlin",
        "PHP",
        "Firebase",
        "Firestore",
        "Agora"
      ],
      "problem": "",
      "solution": "",
      "features": [
        {
          "title": "Google Sign-In",
          "detail": "",
          "planned": false
        },
        {
          "title": "Posts, likes & comments",
          "detail": "",
          "planned": false
        },
        {
          "title": "Friend requests & one-to-one chat",
          "detail": "",
          "planned": false
        },
        {
          "title": "Voice & video calls",
          "detail": "",
          "planned": false
        },
        {
          "title": "Real-time notifications",
          "detail": "",
          "planned": false
        }
      ],
      "role": [],
      "architecture": null,
      "agent": null,
      "impact": [],
      "links": [],
      "notes": [],
      "related": [
        "video-calling",
        "face-detection",
        "pregnancy-tracker"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/social/feed.webp",
        "w": 480,
        "h": 973,
        "alt": "Social app feed: a post with a photo, likes and comments, and Home, Friends, Notification and Profile tabs",
        "frame": "phone",
        "illustrative": false,
        "caption": ""
      },
      "screenshots": [
        {
          "src": "https://afaquejaya.github.io/img/projects/social/feed.webp",
          "w": 480,
          "h": 973,
          "alt": "Feed with a photo post",
          "frame": "phone",
          "illustrative": false,
          "caption": "Feed"
        },
        {
          "src": "https://afaquejaya.github.io/img/projects/social/profile.webp",
          "w": 480,
          "h": 973,
          "alt": "Profile screen",
          "frame": "phone",
          "illustrative": false,
          "caption": "Profile"
        }
      ]
    },
    {
      "id": "video-calling",
      "title": "Video Calling App",
      "tagline": "One-to-one video and voice calls plus single-channel live streaming.",
      "summary": "Real-time communication on Android with Agora, and Truecaller for sign-in.",
      "description": [],
      "categories": [
        "experiments",
        "mobile"
      ],
      "markets": [
        "apps"
      ],
      "status": "learning",
      "visibility": "private",
      "featured": null,
      "accent": "#c9a7a0",
      "period": "Feb 2022",
      "context": "Personal project",
      "platforms": [
        "Android"
      ],
      "technologies": [
        "Java",
        "Agora",
        "Truecaller SDK"
      ],
      "problem": "",
      "solution": "",
      "features": [
        {
          "title": "One-to-one video & voice calls",
          "detail": "",
          "planned": false
        },
        {
          "title": "Live streaming through one channel",
          "detail": "",
          "planned": false
        },
        {
          "title": "Truecaller sign-in",
          "detail": "",
          "planned": false
        }
      ],
      "role": [],
      "architecture": null,
      "agent": null,
      "impact": [],
      "links": [],
      "notes": [],
      "related": [
        "social-app",
        "face-detection",
        "pregnancy-tracker"
      ],
      "thumbnail": {
        "src": "https://afaquejaya.github.io/img/projects/video-calling/concept.webp",
        "w": 1280,
        "h": 800,
        "alt": "Illustrative concept: a one-to-one video call screen and a live stream with viewer comments",
        "frame": "art",
        "illustrative": true,
        "caption": ""
      },
      "screenshots": []
    }
  ]
}
