b2a1eb8e5b
- Added StockKeepingUnitFormComponent for creating and editing stock keeping units. - Introduced StockKeepingUnitsComponent for listing stock keeping units with pagination. - Integrated form fields for code, name, VAT, and SKU type in the stock keeping unit form. - Created API routes for stock keeping units with CRUD operations. - Updated input components to handle numeric and price types with Persian/Arabic digit normalization. - Enhanced key-value component to support tag display instead of badge. - Adjusted layout styles for sidebar menu. - Added AGENT.md for repository-specific coding guidelines and practices. - Implemented good management form with file upload and category selection.
118 lines
4.1 KiB
Markdown
118 lines
4.1 KiB
Markdown
# 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-<field-name>`
|
|
- template: `<app-input ... />`
|
|
- inputs: `control` (required), optional `name`, optional `label`
|
|
|
|
Example pattern:
|
|
|
|
```ts
|
|
@Component({
|
|
selector: 'field-example',
|
|
template: `<app-input [label]="label" [control]="control" [name]="name" type="simple" />`,
|
|
imports: [ReactiveFormsModule, InputComponent],
|
|
})
|
|
export class ExampleComponent {
|
|
@Input({ required: true }) control = new FormControl<string>('');
|
|
@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.<key>(initialValue, isRequired)` for consistency.
|
|
- In templates, render matching wrapper component and pass the matching control:
|
|
- `<field-example [control]="form.controls.example" />`
|
|
- 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.
|