PSA/eslint-plugin-custom-rules
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00
..

Custom ESLint Rules

This directory contains custom ESLint rules specific to the Alga PSA project.

Available Rules

migration-filename

Enforces proper naming conventions for database migration files.

Purpose: Ensures all database migrations follow the yyyymmddhhmm_description.cjs naming pattern and prevents future-dated migrations.

Documentation: See migration-filename.md for detailed information.

Example violations:

# Wrong format (14 digits instead of 12)
server/migrations/20241002132600_add_tax_rates_tables.cjs
# Error: Migration file must be named with yyyymmddhhmm prefix

# Future timestamp
server/migrations/202511011001_create_extension_storage_tables.cjs
# Error: Migration file has a timestamp in the future (2025-11-01 14:01)

map-return-type

Validates return type annotations for map functions.

check-required-props

Ensures required props are defined in React components.

no-legacy-ext-imports

Prevents imports from legacy extension system paths, enforcing use of v2 APIs.

Testing

Each rule has an accompanying test file (.test.js) that validates its behavior:

node eslint-plugin-custom-rules/migration-filename.test.js

Adding New Rules

  1. Create a new .js file in this directory with your rule implementation
  2. Export an object with meta and create properties
  3. Add the rule to index.js:
    import myNewRule from "./my-new-rule.js";
    
    export default {
      rules: {
        // ... existing rules
        "my-new-rule": myNewRule,
      },
    };
    
  4. Configure the rule in the main eslint.config.js
  5. Create a test file to validate the rule's behavior
  6. Document the rule in a markdown file

Rule Structure

Each rule should follow this structure:

export default {
  meta: {
    type: "problem", // or "suggestion" or "layout"
    docs: {
      description: "Brief description of what the rule does",
      recommended: true,
    },
    schema: [], // JSON schema for rule options
    messages: {
      messageId: "Error message template with {{placeholders}}",
    },
  },

  create(context) {
    return {
      // AST node visitors
      NodeType(node) {
        // Rule logic
        if (violation) {
          context.report({
            node,
            messageId: "messageId",
            data: {
              placeholder: "value",
            },
          });
        }
      },
    };
  },
};

Resources