Contributing

This guide covers development workflow, code conventions, and contribution guidelines for FT Configs UI.

Getting Started

  1. Clone the repository and install dependencies (see Local Development).

  2. Verify the project builds: npm run lint && npm run typecheck && npm run test.

  3. Read the Architecture page to understand the codebase structure.

Development Workflow

  1. Create a feature branch from main.

  2. Install dependencies: npm install.

  3. Run the dev server: npm run dev (Vite, http://localhost:9002).

  4. Make your changes following the conventions below.

  5. Run quality gates before pushing:

    npm run lint
    npm run typecheck
    npm run test
    npm run build    # verifies the production Vite build (outputs to dist/)
  6. Raise a Pull Request with a clear description.

  7. For UI changes, include manual QA notes and screenshots.

Code Conventions

General

  • TypeScript only, functional React components.

  • Two-space indentation, single quotes, trailing commas.

  • @/ path alias for all imports (maps to ./src/*).

  • Tailwind CSS + shadcn/ui primitives for styling.

  • No any types — use proper type annotations.

File Organization

  • Routes (src/routes/**) — TanStack Router file-based routes. Route files are thin bridges — they call createFileRoute(…​) and render a feature component, passing isReadOnly and other props.

  • Feature components (src/components/<feature>/) — All UI logic for a feature.

  • API layer (src/api/<feature>/) — Typed API service functions grouped by module (e.g. src/api/acs/, src/api/angular/, src/api/provision-portal/, src/api/settings/).

  • Shared libs (src/lib/) — axios.ts, api-url.ts, runtime-config.ts, validation.ts, permissions.ts, error-utils.ts, etc.

  • Tests — Colocated as .test.ts / .test.tsx alongside the code they test.

Import Order

Group imports in this order:

  1. React and framework packages (react, @tanstack/react-router, @tanstack/react-query)

  2. Third-party libraries

  3. Internal @/ imports (components, hooks, lib, api)

  4. Relative imports

  5. Type-only imports (import type { …​ })

Naming

  • Components: PascalCase (e.g., FccEntryCard)

  • Hooks: useCamelCase (e.g., useErrorHandler)

  • Files: kebab-case (e.g., fcc-entry-card.tsx)

  • API functions: camelCase (e.g., getSnapshot)

i18n

All user-visible text must come from locale dictionaries, never hardcoded.

  • Dictionaries: locales/en.json and locales/ru.json

  • Access via useI18n() hook: t('key.path')

  • Always add keys to both locale files when creating UI text

  • Follow existing key naming conventions (e.g., moduleName.section.label)

Feature Module Pattern

When adding a new configuration module, split the code across three locations:

src/routes/_protected/<feature>.tsx       # Route file: createFileRoute(), renders <FeatureView isReadOnly={...} />
src/api/<feature>/
├── api.ts                                # Typed API service functions (use apiService from @/lib/axios)
└── api.test.ts                           # Unit tests for the API layer
src/components/<feature>/
└── FeatureView.tsx                       # Main feature component with all UI logic
  1. Define the API functions in src/api/<feature>/api.ts using apiService from @/lib/axios.

  2. Implement the feature component in src/components/<feature>/.

  3. Create the route in src/routes/_protected/<feature>.tsx — keep it thin: createFileRoute(…​) + render the feature component, passing isReadOnly from useAuth().

  4. Add locale keys for all UI text to both locales/en.json and locales/ru.json.

  5. If the module supports import/export, reuse GenericImportExport from src/components/common/ and configure it via a *-import-export-config.tsx file — do not reinvent the dry-run → apply flow.

Read CLAUDE.md and Architecture for the full module anatomy and the provider hierarchy.

Validation

  • Use React Hook Form + Zod for all forms.

  • Schema factories accept t() for localized messages: createMySchema(t).

  • Access via useLocalizedSchema() hook.

  • Field validators support isEditing mode for conditional uniqueness.

Error Handling

  • Use useErrorHandler().handleError(error, options) for all API error handling.

  • Never swallow errors silently — always show user feedback via toast.

  • Use extractUnifiedError(error, t) for consistent error classification.

Testing

  • Run tests with npm run test (Vitest).

  • Colocate test files as *.test.ts next to source files.

  • Test utility functions, validation schemas, and hooks.

  • See Testing Strategy for patterns and examples.

Pull Request Guidelines

  • Keep PRs focused — one feature or fix per PR.

  • Include a clear description of what changed and why.

  • For UI changes, add screenshots or screen recordings.

  • Ensure all quality gates pass (lint, typecheck, test).

  • Update locale files if any user-facing text was added or changed.

  • Update documentation if behaviour or architecture changed.