Files
psp_panel/agents.md
T
ahasani 561aca32d3 feat: add stock keeping units list component and related services
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
2026-05-12 19:58:53 +03:30

5.9 KiB

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.
  • prebuild:tis is tenant-scoped and should keep using scripts under scripts/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).
  • Do not use Angular fileReplacements for 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 manifest id, start_url, and scope match actual deployment path:
    • root deploy: /
    • subpath deploy example: /tis/
  • Keep <link rel="manifest"> path and branding config manifestPath aligned.

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:

@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:

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].

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 in list-config.model.ts):
    • pageTitle: display title for the list page
    • addNewCtaLabel: call-to-action button label
    • emptyPlaceholderTitle and emptyPlaceholderDescription: empty state messaging
    • columns: array of IColumn[] 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 breadcrumbItems as 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_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.