I built shipping-bill, a React and TypeScript app for creating and managing Indian export Shipping Bills. It is on my GitHub profile, github profile, and is built on the shared fe-zen-arch architecture included as a Git submodule. The app captures exporters, consignees, invoices, goods, containers, packing ranges, supporting documents and licences in a three-tab form; its dashboard searches saved bills and downloads an ICEGATE-style .sb flat file for each bill. The project metadata gives a start and last-updated date of 2026-10.
There is no backend in this assignment. Components load and save through Promise-based mock services with simulated latency, backed for bills and parties by demo-store.ts and browser local storage; static code lists and options live in src/data/ and are accessed through the reference-data service. The service boundary is intended to make a future backend replaceable without component changes: toShippingBillPayload in model.ts defines the shape for a future POST /api/shipping-bills.
I manage form state with React Hook Form through the fe-zen-arch core/form wrapper and use useFieldArray for nested invoices, items, containers, packing ranges, documents and licences. All tabs stay mounted so submit validates the whole bill. Cross-field and format rules are centralized in validation.ts, with leaf-field schema in the form module; field messages, a summary error and automatic navigation to the tab containing the first problem help surface validation issues. The save path guards against duplicate submissions, disables controls while saving and leaves input untouched after a failed save. A successful save confirms the reference (SB-<id>) and offers links to the list and a new bill.
- A bill has one exporter and one consignee, each with a branch/address, and ships from an Indian port of loading to a foreign final destination port; countries are derived from port codes when building the payload.
shippingBillServiceexposeslist(),getById(id),getInitialValues(id),save(values, id?)anddownloadFlatFile(id, bill?).
localStorage.setItem('export-software-simulate-service-failure', '1')
To clone the repository, initialize the fe-zen-arch submodule. If Git cannot use its SSH URL, configure the HTTPS rewrite before initializing it. ZIP recipients already have the submodule contents. I need Node.js 20 or later and pnpm 10; no API keys or manual credentials are required. Corepack can activate pnpm 10.15.0. The development server uses port 5173 at http://localhost:5173/.
corepack enable
corepack prepare pnpm@10.15.0 --activate
git config url."https://github.com/".insteadOf "git@github.com:"
git submodule update --init
pnpm install
pnpm dev
pnpm devstarts Vite on port 5173; openhttp://localhost:5173/.
The repository is organized around src/dashboard/list-dashboard.tsx for the bill list, search and flat-file download; src/shipping-bills/shipping-bill-form.tsx for the form; model.ts for form types, defaults, totals and payload mapping; and validation.ts for cross-field and format rules. Bill, party and reference-data services are in shipping-bill-service.ts, party-mock-service.ts and reference-data-service.ts; demo-store.ts holds demo data. The remaining notable areas are src/data/ for static reference data, src/shared/ for layout, interceptors and routes, party-dialogs.tsx for quick-add dialogs, workflow.ts for form workflow steps, and fe-zen-arch/ for the shared core, UI and icons packages.
My verification record dated 20 October 2026 says installation, production build and TypeScript checks passed with Node 20.20.2 and pnpm 10.15.0. Browser checks covered bill creation and editing, validation, successful and failed saves, and mobile display. I fixed two form type errors and a native-validation issue; ESLint errors fell from 162 to 5, all pre-existing helper errors. I did not add a test framework. Data is local-only, and small screens retain the framework’s “Desktop Only” warning. The source reports no production deployment results.
I verified the project on 20 October 2026 in a Linux sandbox with Node 20.20.2 and pnpm 10.15.0. pnpm install and pnpm build succeeded, and tsc --incremental false passed with no errors. I fixed two pre-existing shipping-bill-form type errors: a clsx call and an InputError generic. The root postcss.config.js now keeps only the Tailwind PostCSS plugin: the starter’s fe-zen-arch re-export loaded production-only cssnano and postcss-variable-compress plugins that failed with the pinned dependencies because trustedFunctions.difference is not a function.
I ran ESLint over src/; errors fell from 162 in the starter to 5. All five remaining errors are pre-existing errors in the unrelated model.ts and demo-store.ts helpers, and most other remaining output is cspell warnings for domain vocabulary in static data files. The starter had no test framework, and I added neither a test framework nor dependencies because the assignment forbids new dependencies. I used pnpm lint-check for the read-only lint check; pnpm lint also runs Prettier across the repository, including the submodule.
- I used Playwright/Chromium against the production build to check asynchronous dashboard loading and the seeded bill; invalid Details-tab progression and field errors; bill creation and editing; successful saves and simulated failures; and the mobile viewport. A complete bill could be created with exporter, branch, consignee, branch, ports, invoice, and item. With the simulated-failure flag set, saving displayed an error banner and preserved the input.
I used an AI coding agent in Arena.ai Agent Mode with file, shell, and browser tools for repository inspection, design and implementation, README drafting, and validation. I reviewed every change against the original source before keeping it, and I do not claim results for checks I did not execute.
- Browser testing exposed a native-validation bug: decimal weights or prices could block saving when number inputs in hidden tabs failed step validation and could not be focused. I set
noValidateon the form and rely on the schema andvalidation.tsrules instead. - I left the framework’s
SmallScreenWarningunchanged. Small screens show “Desktop Only — Continue Anyway,” although the responsive grids were checked at desktop and mobile widths. - Data persists only in browser local storage under
export-software-shipping-bills-v2; clearing storage resets it to seed data. Mock services support a single simulated failure via a local-storage flag, but there is no offline or retry queue. Auth and the HTTP request layer are present and wired but unused because the assignment has no backend. pnpm buildcreates the production build indist/;pnpm previewserves that build.pnpm lintruns thefe-zen-archPrettier, TypeScript and ESLint pipeline with auto-fix;pnpm lint-checkruns it without auto-fix.partyMockServiceprovides search and lookup for exporters, consignees, branches and ports, plusgetMarksAndNumbersOptions.referenceDataService.getReferenceData()returns dropdown and code lists;searchDocumentCodesandsearchFileTypessupport document pickers.- To replace the mock layer, replace each service function body with an HTTP call through the
fe-zen-archcore/requestclient, wired with interceptors insrc/index.tsx, while retaining function signatures and return types. - To simulate a one-time service failure, run the following in the browser console, then save a bill or refresh the dashboard. The next service call fails once with a readable error and writes no data.
- Each bill has one or more invoices, each with one or more goods items. An invoice buyer defaults to the consignee; if “buyer same as consignee” is unchecked, a buyer and branch are required. Third-party involvement is optional per invoice and per item.
- Assignment validation assumptions include 8-digit RITC codes, net weight no greater than gross weight, invoice date no later than job date, unique invoice numbers within a bill, container numbers matching the common 4-letters-plus-7-digits pattern when entered, charge rates from 0 to 100%, licence export quantity no greater than licence quantity, and document expiry no earlier than issue.
- These checks are product assumptions, not exhaustive Indian customs rules; the project makes no claim of legal completeness.