The Impulse: A Law Student’s “Improper Side Quest”
As a corporate lawyer, I spend much of my day dealing with statutes, regulations, and relatives or friends who come to me with legal questions. One of the topics people ask about most often is employment law. Local leave policies in particular—how many days of marriage leave, how long maternity leave lasts, and so on—are questions almost everyone eventually runs into.
A while ago, a friend moved to a company in Shenzhen and asked me, “How many days of paternity leave does Shenzhen actually give? Everything online is a mess.” I looked around and found that he was right. There is one set of national rules, and then every province has its own local supplements. The information is scattered across human resources department websites, government gazettes, and local regulations. There was no single place where you could compare everything at a glance.
At the time I thought: it would be useful to have a website where you choose a province and immediately see all leave policies, with national rules and local special rules displayed side by side, each rule linked to its legal source.
Then another thought appeared: why don’t I build it myself?
In the past, I would have pushed that thought back down within three seconds. I did not know front-end development, could not draw a map, and had no idea how to deploy a website. But over the past year, things have changed.
When Law Meets Vibe Coding
First, a word about vibe coding. The term was proposed by Andrej Karpathy in early 2025. The basic idea is that you no longer need to write every line of code by hand. You describe what you want in natural language, and AI writes the code. What you do is less “programming” and more “directing.” You are responsible for the idea and taste; AI is responsible for execution.
When I first encountered vibe coding, I also went through a period of confusion. I watched other people use Cursor or Claude Code to spin up projects in no time. Then I tried it myself and found that it was not that simple. AI can write code, but the code often has problems: components fail to render, types break, styles go wrong, routes do not work.
Later I slowly figured something out: vibe coding does not mean “stop thinking.” It means “think in a different way.” You cannot really let go completely. You have to review the code, give precise revision instructions, and point the AI in the right direction when it gets stuck. In a sense, it is not so different from reviewing a law paper. You may not write every word from beginning to end, but you must know where the problem is and how it should be fixed.
My legal background ended up playing an unexpected role in this project.
How Legal Thinking Reshaped My Development Process
What is the core training of legal education? If I had to name one thing, it would be systematic classification and subsumption. When facing a case, the first step is not to jump to a conclusion. It is to break the facts into legal elements, examine them one by one, and then reach a conclusion.
That way of thinking mapped naturally onto the data structure for this leave policy site.
Leave policy is, at its core, a multi-layered rule system:
- First layer: the national statutory baseline. For example, 98 days of maternity leave and 3 days of marriage leave are found in national rules such as the Special Provisions on Labor Protection for Female Employees and the Population and Family Planning Law, and apply nationwide.
- Second layer: provincial supplements. Shanghai adds 30 days of maternity leave on top of the 98-day baseline, Guangdong gives 15 days of paternity leave, and some autonomous minority areas have special policies.
- Third layer: fallback rules. If there is no special local rule, the national standard applies by default.
I understood this three-layer structure through the legal relationship between general law and special law: special law prevails over general law, and where special law is silent, general law applies. That is exactly the core logic of the mergePolicy() function in the code: load the national baseline first, then merge in provincial override fields. Local values override the national baseline; missing local values fall back to the national rule.
So when the AI asked how I wanted to design the data structure, I almost immediately sketched out this YAML schema:
婚姻假:
天数: 3
适用条件: 依法办理结婚登记的夫妻
工资待遇: 正常发放
法律依据:
- 名称: 国家劳动总局、财政部关于国营企业职工请婚丧假和路程假问题的通知
条款: 第一条
Then each province file only records what differs from the national baseline. For example, Jiangsu:
婚姻假:
天数: 13
法律依据:
- 名称: 江苏省人口与计划生育条例
条款: 第二十七条
Anyone in the legal world can immediately recognize this as the logic of “special law prevails over general law.” But if you had asked me a year ago to write the merge logic from scratch, I absolutely could not have done it. Now I describe the idea to AI, and within half a minute the code appears, with type checks passing.
Zod data validation follows the same pattern. Law cares about formal requirements: a contract missing an essential clause may be invalid. In this project, the equivalent is strict schema validation for data files. central.yaml must contain all seven leave categories; every leave item in a province file must include a “days” field; legal sources cannot be empty. I described these constraints to the AI in natural language, and it generated a Zod schema plus a validation script that runs before build. If the YAML format for any province is wrong, the entire CI pipeline fails.
It is a little funny to imagine what my supervisor would think if they knew I was using legal methodology to “train” AI to write code. But honestly, this kind of cross-disciplinary transfer is one of the most interesting parts of the vibe coding era. You do not have to be a formally trained software engineer, but you do need a systematic way of thinking, whether it comes from law, medicine, architecture, or music.
From Idea to Product: A Weekend Build Log
Once the idea and methodology were clear, the next step was to build.
For the tech stack, I followed one principle: choose the most mainstream tools, the ones AI knows best. This was not the time to show off. I am happy to be pragmatic here. Next.js + Tailwind CSS + shadcn/ui is a stack that appears heavily in AI training data, which means the AI is less likely to make mistakes.
Data Layer: Compiling Leave Policies for 31 Provinces
This was actually the most time-consuming part. Code can be generated with AI; content cannot.
I spent almost two full weekends checking the websites of health commissions, human resources departments, and local people’s congresses across 31 provincial-level regions, along with amendments to local population and family planning regulations. For every rule, I recorded the source document, article number, and official link. Some rules were buried very deep. A paternity leave rule in one autonomous region, for example, was hidden in a 2016 decision amending the local population and family planning regulation. To reconstruct the full rule, I had to follow the amendment back to the original text.
AI cannot really help with that, at least not yet. It may fabricate legal provisions that look plausible, but on this kind of issue a legal professional still has a bottom line: the data must be traceable.
All the cleaned data is stored under data/provinces/ using the XX-pinyin.yaml naming convention: 31 province files, plus a central.yaml file as the baseline.
Front End: Three Days of Pain with an SVG Map of China
The most painful part of the project was the map of China.
At first I thought it would be simple: find an existing ECharts map library and render the map. Then I discovered that the China map in ECharts uses GeoJSON, which is not only large but also annoying to adapt for dark mode. AI suggested using native SVG, but most China SVG maps I found online were poor quality: rough borders, and in some cases incomplete province paths.
In the end, I used a compromise. I asked AI to help generate precise SVG path data and store it as a JSON file. Each province has one path, with a viewBox, path coordinates, and the latitude and longitude of the province center. Then I wrote a React component for interaction.
One detail is worth mentioning: click areas for small provinces and municipalities. Beijing, Tianjin, and Shanghai are so small on the map that the mouse can hardly hit them. I went back and forth with the AI for several rounds before coming up with a solution: wrap an invisible circular click hotspot around the path, enlarge the radius threefold, and cover the nearby blank area. The AI did not suggest this on its own, but once I described it, it implemented the idea quickly.
The heat map colors also took a long time to tune. I defined a “leave heat score” by adding together the days of marriage leave, maternity leave, and paternity leave, then dividing the result into four bands:
- Green (≥200): provinces with relatively generous leave benefits
- Yellow (190-199): above average
- Red (180-189): somewhat below average
- Dark red (<180): places with fewer total leave days
To be honest, this “heat score” is fairly rough. I mainly wanted to give users an immediate visual impression: at a glance, they can roughly see which color regions offer more leave. If I have time later, I plan to add more weighted factors, such as childcare leave and home leave.
Province Detail Pages: Seven Leave Categories as Cards
The province detail page was inspired by the dashboard in the health app on my phone. Each leave category is an independent card. The top shows the number of days, the middle shows eligibility and wage treatment, and the bottom folds away detailed explanations on qualification and notes.
The most valuable design is the source label system. Each rule has a small label on the right:
- “National Rule” (gray): this rule comes from national-level law or regulation.
- “Local Special Rule” (blue): this is an additional policy made by the province on top of the national baseline.
Displayed side by side, the labels let users immediately tell which benefits come from the state and which are local supplements.
Deployment: GitHub Actions + GitHub Pages, Online at Zero Cost
Deployment turned out to be the easiest part of the whole project.
Next.js has a feature called Static Export. In simple terms, it pre-renders the entire site into static HTML, CSS, and JavaScript files, so no server is needed. I only had to add output: "export" in next.config.mjs, then configure GitHub Actions so that every push to the main branch automatically runs npm run build and publishes the output to GitHub Pages.
The CI pipeline is also clean:
- Check out the code.
- Run
npm cito install dependencies. - Run
npm run validate-datato validate all YAML data files. - Run
npm run typecheckfor TypeScript type checking. - Run
npm run buildto build the static site. - Deploy to GitHub Pages.
From pushing code to seeing the site updated, everything is automatic and takes less than two minutes.
Live site: masonblog.github.io/HolidayGO-CN
Closing Thoughts: In the AI Era, Ideas Are the Scarce Resource
After finishing this project, my strongest feeling was not “AI is amazing.” It was this: in the AI era, people with ideas are scarce, and people who can actually ship those ideas are even scarcer.
Think about it. Every year in China, countless law students, lawyers, and HR workers look up leave policies. After checking the answer, they move on. How many people think, “Why don’t I build a lookup tool?” And among those who do, how many actually open a computer and start building?
AI has flattened the technical implementation gap, but it has not flattened the gap between wanting to do something and being able to persist until it is done.
I am not a programming expert. Before starting this project, I did not even know how routing works in Next.js. But now a usable product is here: data for all 31 provincial-level regions, dark mode, an interactive map, traceable sources, and fully automated CI/CD deployment. Two years ago, as someone trained in the humanities, I would not have dared to imagine this. In 2026, with spare time and AI, I did it.
So what I want to say is this: if there is a thought in your head that keeps saying, “It would be nice if something like this existed,” do not hesitate. Start now. You do not need to wait until you have “learned programming” before beginning. That era is over. You need only:
- a clear idea (your most distinctive asset, and one AI cannot take away);
- a systematic framework for thinking (from any discipline);
- the patience to polish details (AI can help write code, but only you can polish the product).
Leave the rest to AI and time.
All code for this project is open source on GitHub: masonblog/HolidayGO-CN . If you have additions or corrections to the leave policy data, PRs are welcome.
If you also come from a non-technical background and have built something of your own with AI as a “wild developer,” feel free to share your story in the comments. I would love to hear it.
