561aca32d3
feat: implement checkbox component with label and hint support feat: create sale invoice full response model for invoice details feat: add single view component for displaying sale invoice details feat: define various list configurations for account, business activity, and consumer management feat: establish list configurations for managing devices, goods, and licenses feat: create list configurations for managing partners and their accounts feat: implement user management list configuration
5.9 KiB
5.9 KiB
AGENT.md
Purpose
- This file defines repository-specific instructions for coding agents.
- Scope is the full repo unless a deeper
AGENT.mdoverrides it.
Stack Context
- Frontend: Angular 20 standalone app.
- Package manager:
pnpm. - Deployment: Docker / Docker Compose with tenant-specific services.
- Current service mapping expectation:
app_defaulton host port8090app_tison host port8091
Tenant Build Rules
defaulttenant currently builds viang buildand outputs todist/production.tistenant builds viang build --configuration tisand outputs todist/tis.prebuild:tisis tenant-scoped and should keep using scripts underscripts/tis/*.- Keep Docker
DIST_DIRaligned with actual Angular output path. - Do not assume
defaultAngular configuration is usable unless verified (it may reference missing replacements). - Do not use Angular
fileReplacementsfor static assets (.png,.jpg, etc.); use tenant public assets or prebuild copy scripts.
Tenant PWA Rules
- Keep tenant manifest files under tenant public assets (e.g.
public-tis/favicon/site.webmanifest). - Ensure
manifestid,start_url, andscopematch actual deployment path:- root deploy:
/ - subpath deploy example:
/tis/
- root deploy:
- Keep
<link rel="manifest">path and branding configmanifestPathaligned.
Input Component Rules
- File:
src/app/shared/components/input/input.component.ts - For
type === 'number'ortype === 'price':- Normalize Persian/Arabic digits to English digits.
- Allow only digits and
.. - Support
fixedprecision 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-inputand set only required props (type,label,name, constraints). - Do register every new field in:
src/app/shared/components/fields/index.tssrc/app/shared/constants/fields/index.ts
- Do keep control keys consistent across form group, field component
name, andfieldControlkey. - 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.tssrc/app/shared/components/fields/unit_price.component.ts
- Minimal wrapper shape:
selector:field-<field-name>- template:
<app-input ... /> - inputs:
control(required), optionalname, optionallabel
Example pattern:
@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
fieldControlentry shape:- key must match form control name
- return tuple:
[defaultValue, validators]
Example:
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-inputtype="number"ortype="price"and optional[fixed].
List Component Configs
- Centralized list metadata is stored in
src/app/shared/constants/list-configs/— never in domain modules. - Structure by data type, not domain (e.g.
good-list.const.ts,sku-list.const.ts,category-list.const.ts). - Each config implements
IListConfig(defined inlist-config.model.ts):pageTitle: display title for the list pageaddNewCtaLabel: call-to-action button labelemptyPlaceholderTitleandemptyPlaceholderDescription: empty state messagingcolumns: array ofIColumn[]definitions
- Usage in list components:
@Input() header: IColumn[] = goodListConfig.columns; listConfig = goodListConfig; - Any domain needing a list config imports from
@/shared/constants/list-configs— no cross-domain dependencies. - Do not define configs inside domains or duplicate them across modules.
Breadcrumb Usage in Stores & Views
- Entity stores expose
breadcrumbItemsas a computed signal. - Call
store.breadcrumbItems()in view components and extend with current page:setBreadcrumb() { this.breadcrumbService.setItems([ ...this.store.breadcrumbItems(), { title: 'Current Page' }, ]); } - Root page breadcrumbs are set in the store's
getData()method once entity is loaded.
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_defaultdocker 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.