# AGENT.md ## Purpose - This file defines repository-specific instructions for coding agents. - Scope is the full repo unless a deeper `AGENT.md` overrides it. ## Stack Context - Frontend: Angular 20 standalone app. - Package manager: `pnpm`. - Deployment: Docker / Docker Compose with tenant-specific services. - Current service mapping expectation: - `app_default` on host port `8090` - `app_tis` on host port `8091` ## Tenant Build Rules - `default` tenant currently builds via `ng build` and outputs to `dist/production`. - `tis` tenant builds via `ng build --configuration tis` and outputs to `dist/tis`. - Keep Docker `DIST_DIR` aligned with actual Angular output path. - Do not assume `default` Angular configuration is usable unless verified (it may reference missing replacements). ## Input Component Rules - File: `src/app/shared/components/input/input.component.ts` - For `type === 'number'` or `type === 'price'`: - Normalize Persian/Arabic digits to English digits. - Allow only digits and `.`. - Support `fixed` precision formatting when provided. - Keep behavior for identifier fields (`mobile`, `phone`, `postalCode`, `nationalId`) string-safe. ## Change Policy - Keep changes minimal and scoped to user request. - Prefer root-cause fixes over temporary workarounds. - Avoid unrelated refactors. - Reuse existing patterns and naming conventions. ## Do / Don't - Do follow existing field wrapper style in `src/app/shared/components/fields/*.component.ts`. - Do reuse `app-input` and set only required props (`type`, `label`, `name`, constraints). - Do register every new field in: - `src/app/shared/components/fields/index.ts` - `src/app/shared/constants/fields/index.ts` - Do keep control keys consistent across form group, field component `name`, and `fieldControl` key. - Don't add one-off field patterns when an existing field component can be reused. - Don't use invalid Angular file replacements for directories or empty paths. - Don't change tenant output directories without updating Docker `DIST_DIR`. ## How To Create Form Fields - Create a wrapper component in `src/app/shared/components/fields`. - Use the same pattern as existing files like: - `src/app/shared/components/fields/name.component.ts` - `src/app/shared/components/fields/unit_price.component.ts` - Minimal wrapper shape: - `selector`: `field-` - template: `` - inputs: `control` (required), optional `name`, optional `label` Example pattern: ```ts @Component({ selector: 'field-example', template: ``, imports: [ReactiveFormsModule, InputComponent], }) export class ExampleComponent { @Input({ required: true }) control = new FormControl(''); @Input() name = 'example'; @Input() label = 'Example'; } ``` ## Register New Fields - Export the component from: - `src/app/shared/components/fields/index.ts` - Add its form control factory in: - `src/app/shared/constants/fields/index.ts` - `fieldControl` entry shape: - key must match form control name - return tuple: `[defaultValue, validators]` Example: ```ts example: (value = '', isRequired = true): ControlConfig => [ value, isRequired ? [Validators.required] : [], ], ``` ## Using Fields In Forms - In form group builders, use `fieldControl.(initialValue, isRequired)` for consistency. - In templates, render matching wrapper component and pass the matching control: - `` - For numeric/price behavior, use `app-input` `type="number"` or `type="price"` and optional `[fixed]`. ## Validation Checklist - For TypeScript-only changes, run: - `pnpm -s exec tsc -p tsconfig.app.json --noEmit` - For Docker/build changes, verify with: - `docker compose build app_default` - `docker compose build app_tis` - Start with targeted validation, then broader checks only if needed. ## Communication Expectations - Report exactly which files changed and why. - Call out any assumptions or discovered config mismatches. - If validation is blocked (permissions, missing dependencies), state it clearly and provide next command.