This is a submission for the Gemma 4 Challenge: Build with Gemma 4
Most refusals for Cameroonian Express Entry applicants come from the same handful of patterns. I built a Gemma 4–powered second-reviewer that flags them before submission.
What I Built
The Canada Immigration Assistant is a second-reviewer tool for African applicants navigating Canadian immigration. It addresses three of the most common refusal patterns IRCC cites, all in one place.
The reference letter generator takes a user's NOC code, their actual day-to-day duties, and employer details — then rewrites the duties in the applicant's own voice (so IRCC doesn't see verbatim NOC text), produces a 7-to-10-point reference-letter checklist, and assembles a full copy-paste-ready letter outline.
The proof of funds + employment legitimacy analyzer checks the applicant's funds against the official IRCC table for their family size, flags fund-source issues (microfinance, mobile money, gifts without donor documentation), and validates employment legitimacy across Cameroon's public, private, mission, and vacataire sectors. It also surfaces CEC and job-offer exemptions up front, so applicants who don't need POF know it immediately.
The visitor visa home ties analyzer rates an applicant's ties to home, builds a category-by-category inventory across employment, family, property, financial, and travel history, and flags dual-intent risks specific to the applicant's situation.
What makes it different from generic AI immigration tools: it knows that a Cameroonian government teacher is documented by l'acte d'intégration, not CNPS — and many other locally-specific rules that a globally-trained model gets confidently wrong by default. All three features are powered by Gemma 4.
Try it: gemma-canada-assistant.vercel.app
The deeper story: I wrote about the prompt-engineering lessons here.
Demo
Live app: gemma-canada-assistant.vercel.app
The reference letter feature, with all twelve supported NOC codes and three-way navigation:
A real Gemma 4 response from the proof of funds analyzer, flagging microfinance and missing CNPS for a private-sector applicant:
Code
github.com/t-yanick/gemma-canada-assistant
The README walks through architecture (Next.js 16 App Router, Tailwind v4, three API routes, a shared Gemma client, three system prompts, twelve IRCC-verified NOC entries), setup, and local development.
How I Used Gemma 4
I used google/gemma-4-31b-it:free via OpenRouter throughout the project, with a Google AI Studio API key plugged in as BYOK. Total cost to build, test, and deploy: $0.
Three things mattered for the project, and Gemma 4 handled all three well.
Structured JSON output. Every API endpoint in the app expects a typed response from Gemma — RewriteApiResponse, PofApiResponse, VisitorVisaApiResponse. I used Gemma's JSON mode (response_format: { type: 'json_object' }) and defined the exact schema inside each system prompt. The model returned valid, parseable JSON on the first attempt, the overwhelming majority of the time. For the rare exceptions, the shared client falls back to a defensive parser that strips markdown fences before parsing.
Long, rule-dense system prompts. Each prompt is roughly 100-150 lines of dense domain knowledge: which Cameroonian institutions are microfinance vs commercial banks, how l'acte d'intégration differs from CNPS for public-sector workers, which fund sources require seasoning, when an applicant qualifies for exemption. Gemma 4 held all of it across the conversation without drifting.
Retry-on-5xx for reliability. The free Google AI Studio tier occasionally returns transient 500 errors. The shared callGemma client retries once on 5xx with a 1.5-second delay, which made the difference between a flaky demo and a reliable product.
A real Gemma 4 response, lightly trimmed, from the POF analyzer for an applicant with funds at Express Union microfinance and cash-paid employment:
{
"exemption_status": "not_exempt",
"pof_status": "borderline",
"pof_amount_check": "The applicant has 25,000 CAD, which exceeds the required 23,360 CAD. However, this is a slim margin; a buffer of 2,000-3,000 CAD is recommended to account for exchange rate fluctuations.",
"fund_source_flags": [
"IRCC does not accept funds held in microfinance institutions like Express Union because they are not considered liquid commercial bank accounts. These funds must be transferred to a commercial bank (e.g., Afriland First Bank, BICEC, Ecobank) to be valid."
],
"employment_legitimacy_flags": [
"Cash payment without CNPS registration is a strong red flag for a private sector worker. IRCC may view this as undocumented or informal employment, which can lead to a rejection of the work experience claim."
],
"required_documents": [
"Bank letter from a commercial bank on official letterhead, dated within 1 month, stating account number, opening date, current balance, 6-month average balance, and outstanding debts.",
"6 months of stamped bank statements from a commercial bank showing salary deposits.",
"CNPS attestation to prove legal employment status in the private sector."
],
"recommended_next_steps": [
"Immediately open a commercial bank account and transfer the funds from Express Union to begin establishing a 6-month average balance.",
"Request your employer to provide a formal letter of employment and start registering with CNPS to legitimize your work history.",
"Begin depositing your cash salary into your new commercial bank account every month to create a paper trail of income."
],
"regional_context_note": "In Cameroon, microfinance and cash-based salaries are common and legitimate ways of managing finances. However, IRCC requires strict adherence to commercial banking standards and social security registration to verify the legitimacy of funds and employment."
}
That single response identified two refusal-pattern risks, listed the documents the applicant needs, sequenced four concrete next steps, and acknowledged the local context without moralizing about it. The same model, with a generic prompt, would have given generic advice that didn't apply to Cameroon at all. The difference is entirely in the system prompt.
Lessons Learned
Three things I'd tell another developer building with Gemma 4:
Constrain the output, narrow the decision space. Gemma 4 is reliable when you use JSON mode with an explicit schema, and unreliable when you let it improvise. Define the shape you want, define the values it can produce, and the model will stay inside the box.
It's a general-purpose model — domain context goes in the prompt. Don't expect Gemma to know your context. Teach it, explicitly. For me, that meant four rounds of iteration: ship a prompt, test with real applicant data, find what the model got wrong by local standards, refine. The fourth round held up against two real anonymized IRCC refusal letters.
Deploy it as a second reviewer, not an oracle. This tool isn't replacing immigration lawyers — it's catching the kinds of mistakes a human would, if a human had the time and patience to review every applicant's file before submission. Framing it that way changed both the product and how I wrote about it.




Top comments (0)