Files
opensourcepos/AGENTS.md
objecttothis 6db3dde491 Bugfix tax names (#4677)
bugfix(items, validation): reject unsafe tax names and fix payments temp table collision

- Add unicode_alpha_numeric_punct rule (OSPOSRules) to allow accented/CJK
  chars in text fields while blocking HTML-unsafe chars (<, >) as
  defense-in-depth against injection
- Items controller: extract validateItemFields/validateBulkUpdateFields,
  validate tax_names on save and bulk update using new rule; add shared
  validateFields helper in Secure_Controller to DRY up validation +
  JSON error response
- Escape tax_group output in sales/quote.php and receipt_email.php views
  to harden output encoding at render time
- Rename sales_payments_temp -> sales_report_payments_temp (Summary_report)
  and -> sales_search_payments_temp (Sale model) to avoid name collision
  between concurrently-created temp tables
- AGENTS.md: document alignment rule for => columns when inserting new
  language keys

Tests:
- Add ItemsControllerTest covering postSave/bulkupdate tax_names validation
- Reject <, > in tax_names on /items/save and /items/bulkupdate
- Verify unicode and apostrophe-containing tax names are accepted
- Cover CSV import helpers: header generation (basic, multiple locations,
  attributes), stock-location/attribute header builders, get_csv_file
  parsing (plain, BOM-prefixed, multi-row)
- Validate required-header detection for import templates
- Remove outdated tax name test from SalesControllerTest
- Simplify Database class references in SalesControllerTest

i18n:
- Add tax_name_invalid translation to Items.php for 20+ locales, inserted
  alphabetically after tax_category in each file
- Normalize quote style in ar-EG/Items.php to single quotes
- Add ka/Items.php Georgian locale scaffold

Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
2026-09-01 10:59:29 +04:00

4.4 KiB

Agent Instructions

This document provides guidance for AI agents working on the Open Source Point of Sale (OSPOS) codebase.

Code Style

  • PSR-12 enforced via PHP-CS-Fixer (config: .php-cs-fixer.no-header.php)
  • Follow PHP CodeIgniter 4 coding standards
  • camelCase for variables and methods; PascalCase for classes; UPPER_CASE for constants
  • When editing existing code containing non-PSR-compliant local variable names, refactor those variable names to camelCase as part of the edit
  • All newly written code (variables, classes, functions) must use PSR-compliant naming, regardless of surrounding code style
  • PHP 8.2+ features acceptable (named arguments, enums, readonly properties)
  • Write PHP 8.2+ compatible code with proper type declarations
  • Always import classes, functions, and constants with a use statement at the top of the file instead of referencing them inline via fully-qualified name (e.g. use Config\Database; then Database::connect(), not \Config\Database::connect())
  • Do not add comments or docblocks that merely restate what the code already makes clear — only comment on non-obvious rationale, constraints, or behavior
  • Views in app/Views/errors/html/ are excluded from the fixer
  • Run fixer before committing: vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.no-header.php
  • JavaScript: use const for variables that are never reassigned, let for variables that are. Never use var.

Development

  • Create a new git worktree for each issue, based on the latest state of origin/master
  • Commit fixes to the worktree and push to the remote

Testing

  • Run PHPUnit tests: composer test
  • Tests must pass before submitting changes
  • One test file per class under test. A controller, model, library, or helper gets exactly one test file covering all of its behavior — Item_kits.phptests/Controllers/Item_kitsTest.php (or Item_kitsControllerTest.php, matching this codebase's existing *ControllerTest.php suffix for controllers), Sale_lib.phptests/Libraries/Sale_libTest.php, etc. Do not create feature- or endpoint-scoped test files alongside a class's main test file (e.g. no Item_kitsBarcodeTest.php next to Item_kitsControllerTest.php) — add the new test methods to the existing file for that class instead. If no test file exists yet for the class, create the one canonical file rather than a narrowly-scoped one.

Build

  • Install dependencies: composer install && npm install
  • Build assets: npm run build or gulp

Conventions

  • Controllers go in app/Controllers/
  • Models go in app/Models/
  • Views go in app/Views/
  • Database migrations in app/Database/Migrations/
  • Use CodeIgniter 4 framework patterns and helpers
  • Sanitize user input; escape output using esc() helper

Localization

  • When adding new keys to language files, add the key to all app/Language/*/ variants
  • New keys must be inserted in alphabetical order within the language array
  • Non-English files must use an empty string ('') as the value when no translation is provided — CodeIgniter automatically falls back to the default (en) language. This applies only when a translation genuinely isn't available yet.
  • When explicitly asked to translate a phrase for a non-English language file, always provide the actual translation — never leave the value as an empty string, and never leave source English text in a non-English language file
  • Never copy English text from a neighboring key as a value for a non-English language file, even if that neighboring key is already untranslated — evaluate each key independently
  • Only app/Language/en/ and app/Language/en-GB/ should contain English strings
  • Plugin language files (app/Plugins/*/Language/) follow the same localization rules as app/Language/
  • Use ' to encapsulate key and string values. If the value contains ' then it should be escaped as \'
  • Align the => of a newly inserted key with the => column already used by the rest of the file, if that file pads keys to a fixed column (not all do — some files have no padding at all). If the new key is longer than the widest existing key and would push the alignment column further right, reformat the whole file to the new wider column rather than leaving only the new line at a different width

Security

  • Never commit secrets, credentials, or .env files
  • Use parameterized queries to prevent SQL injection
  • Validate and sanitize all user input