A Vue 3 + Pinia application for creating and editing carrier integrations, designed with modularity, testability, and Clean Code principles in mind.
The application includes two main routes for handling carrier integration forms:
| Path | Name | Purpose |
|---|---|---|
/carrier/create |
CarrierCreate |
Creates a new carrier form |
/carrier/:id |
CarrierEdit |
Edits an existing carrier by ID |
It is assumed that the Carrier Status Panel (which displays ONBOARDING, ORDERING, and MANIFESTING statuses) is considered an integral part of the form.
- Each status field has a
statusvalue and anisEditableflag. - When
isEditable: true, the status can be changed via aSelectButton. - When
isEditable: false, the current status is displayed as a staticTag.- If the
statusis an empty string (""), a placeholder?is shown.
- If the
- Example:
onboarding.status = ""onboarding.isEditable = false- → The panel renders a
Tagwith value?
This logic was not explicitly defined in the task, but implemented based on the assumption that:
The status panel reflects part of the persisted and editable form data (read-only or not), and changes in editable statuses should be submitted like any other form field.
- Navigating to
/carrier/createwill open an empty form pre-filled with default values. - Navigating to
/carrier/2(example) will load form data for the carrier with ID2.
-
🔌 API Injection via Store
Uses a.init(service)pattern in the store to inject services → promotes testability and SOLID. -
🧪 Deep Diff on Submit
Submits only changed fields by comparingformDatavsoriginalFormDatausing lodash. -
📦 Clean State Management
Reset, load, and submit are clearly separated in store actions. -
📐 Reusable Components
Each logical unit of the form (e.g.,PricingOptions,CarrierInfoSection) is encapsulated. -
🔁 Async Wrapper
AsyncStateHandler.vuewraps loading, error, and fallback states for any async section. -
✅ Scoped Validation
LightweightuseFormInputValidatorcomposable for checking required fields.
This project uses Prettier for code formatting.
To format the codebase:
- Vue 3 + Composition API
- Pinia (Store)
- Vite
- PrimeVue + PrimeFlex
- Lodash (deep comparison)
- SCSS
-
Install dependencies
npm install npm run dev ## ⚠️ Node Version Requirement
This project has been tested Node.js version
^20.19.0or>=22.12.0
This project uses GitHub Actions with a Git Flow branching strategy.
- develop → Integration branch (receives merges from feature branches)
- staging → QA branch (triggers preview deployment)
- main → Production branch (triggers production deployment)
Trigger: Pull Requests to develop, staging, or main
What it does:
- Installs dependencies and verifies the project builds successfully
- (Optional) Runs lint checks and unit tests
Purpose: Prevents broken code from entering key branches.
Trigger: Push to the staging branch or any Pull Request.
What it does:
- Builds the app with:
VITE_BASE=./→ ensures assets load correctly from subpathsVITE_FORCE_HASH=1→ enables Vue Router hash mode to avoid 404s
- Generates
404.html(SPA fallback) - Deploys to GitHub Pages under the
github-pagesenvironment - Prints a Preview URL in the workflow logs
Where to find the Preview URL:
- Actions tab → open the run →
deployjob → “Print preview URL” - Settings → Environments → github-pages → Recent deployments → View deployment
Trigger: Push to the main branch
What it does:
- Builds the app with:
VITE_BASE=/carrier-integration-form/→ correct subpath for the production siteVITE_FORCE_HASH=0→ enables history mode (clean URLs)
- Generates
404.html(SPA fallback) - Deploys to the live GitHub Pages site
Production URL:
- Feature development:
- Create a
feature/my-featurebranch - Open a PR →
develop→ CI checks run
- Create a
- QA:
- Open PR
develop→staging - After merge → preview deployment is available for testing
- Open PR
- Release:
- Open PR
staging→main - After merge → production deployment & GitHub Release (via
release-please)
- Open PR
This project uses release-please for automated:
- Semantic version bump
- Git tag (e.g.
v1.0.0) - GitHub Release with generated changelog