Full-stack Product · 2025–2026
Ovanta
A cross-region self-service platform for visas, immigration, and overseas identity.
A self-service application platform for Chinese and international users. One codebase powers both regional sites with structured policy content, regional login and payments, and membership entitlements. Live at ovanta.cn.
Problem & responsibility
Business problem: organizing scattered, professional, and ever-changing official policies into auditable, composable structured guides — then completing commercial delivery through subscriptions, payments, and entitlements. I led content modeling, regionalization, and payment idempotency.
System flow
- Policy content
- Structured modeling
- Eligibility check
- Subscription & payment
- Entitlements
- Consulting
- Operations loop
Engineering focus
- Content System
- 16 content models and typed components power multiple products and 200+ pages through one editing and publishing flow.
- Payment Hook Chain
- Payment callbacks pass a blocking hook chain — signature, amount, state machine, and idempotency checks — blocking on write, degrading on read.
- Regional Architecture
- Both regions share the core business code with build-time regional config and channel adapters, sharply reducing duplicated work.
Evidence
- Content Models
- 16 models · 25 components · 200+ pages
- Entitlements
- 99.9%+ reconciliation · zero duplicate grants across 1k+ replays
- Events API
- P95 < 100ms · duplicate rate < 0.1%
- E2E
- Given-When-Then pass rate ≥ 98%
React · Vite · Django · DRF · Strapi · MySQL · PostgreSQL · Redis · Celery · Docker Compose · Cloudflare
Design tradeoffs
-
Model policy as structured content instead of long-form rich text
- Why
- In a rich-text article it is hard to tell which requirement has gone stale, which version an assessment was based on, and there is no reliable way to gate chapters by membership.
- Cost
- A cross-system boundary forms between Strapi/PostgreSQL and Django/MySQL, and every content-model extension has to change both sides.
-
Domestic and international sites share core business code, with differences pushed into build-time config
- Why
- Two codebases diverge immediately, and orders, payments, and entitlements are exactly the parts that most need to stay consistent — once split, they never converge again.
- Cost
- Regional differences get compressed into config and adapters, so runtime branching increases; region-specific product asks have to be assessed before they reach the trunk.
-
Payment callbacks pass a blocking hook chain: signature, amount, state machine, idempotency
- Why
- Payment callbacks durably duplicate, arrive out of order, and arrive late — any missing check turns directly into granted entitlements that should not exist, or missing ones that should.
- Cost
- The callback path gets longer and failure modes need their own degradation and manual-intervention design; reconciliation becomes a permanent independent capability.
-
Server-side checks are the authority for permissions; frontend display state is never the basis
- Why
- Hiding an entry point in the frontend does not mean the user lacks access — treating display as authorization hands the permission boundary to the browser.
- Cost
- Every feature with a display state re-checks permissions on the server, increasing endpoint count and round-trips.
What this system does not do
Deliberate non-goals. A boundary that is written down is a boundary that can be held.
- Does not accept or approve applications on behalf of government agencies
- Does not guarantee visa, immigration, permanent-residency, or account-opening outcomes
- Does not make professional legal judgments automatically without a factual basis
- Does not replace consultants for work that requires human judgment and sign-off
- Does not auto-generate and publish policy content from non-authoritative sources
- Does not let AI directly modify content, eligibility rules, prices, plans, or entitlements
- Does not read correlation in operations data as established causation
- Does not let frontend display state stand in for real server-side permission checks
- Does not clear payments itself — funds still settle through compliant payment channels
Open questions
What I do not have an answer for yet. Happy to be asked about any of these.
- Content-model coverage depends on how finely editors decompose a policy, and there is no settled “minimal common model” for cross-region reuse
- Payment callbacks are down to zero duplicate grants across 1k+ replays by idempotency key, but late-arriving channel reconciliation files still need manual cover
- How to raise content-production efficiency without crossing the line that policy conclusions require human confirmation — today AI only aggregates on the operations side, which is not automation
- The regionalization adapter folds differences into config, but each new region still needs its payment channels and compliance requirements assessed individually