# agents.md - NC Backend Development Guide

This document provides essential information for AI agents working in the NC backend codebase (/Volumes/nc/nc-backend). This is a multi-repository project with specific conventions and patterns.

## Repository Structure

### Multi-Repository Layout

- **Main repositories**: `/Volumes/nc/nc-server` (backend), `/Volumes/nc/nc-backend` (forms/preferences), `/Volumes/nc/nc-plugin` (plugins), `/Volumes/nc/nc-frontend` (Vue.js frontend)
- **Working directory**: Typically `/Volumes/nc/nc-backend` for form editing
- **Critical**: All paths must start with `/Volumes/nc/` - never use relative paths like `nc/nc/`

### Web Forms Architecture

Web pages are organized as folders under `/Volumes/nc/nc-backend/preference/form/nc/`:

```bash
nc-admin/
├── init.json          # Page definition and file manifest
├── rec.json           # Default values for single records
├── hdr.json           # Header translations (fi, en, etc.)
├── arr.json           # Arrays (dropdowns, tabs, options)
├── grid.json          # Grid definitions
├── nc-admin.json      # Layout (Vue component structure)
├── nc-admin.js        # JavaScript logic
├── nc-admin.css       # Styling (optional)
└── query/             # Database queries and column definitions
```

### Critical Rule: Only Edit Listed Files

**Never edit files not listed in `init.json`**. When working on a page:

1. First read `init.json` to see the authorized files
2. Only edit files explicitly listed in the manifest
3. If you need other files, add them to `init.json` first
4. Do not read or edit files outside the authorized list

## File Types and Conventions

### init.json Structure

```json
{
  "name": "form/nc/page-name/init.json",
  "rec": "form/nc/page-name/rec.json",           // Record defaults
  "hdr": "form/nc/page-name/hdr.json",           // Translations
  "arr": "form/nc/page-name/arr.json",           // Arrays/dropdowns
  "grid": "form/nc/page-name/grid.json",         // Grid definitions
  "layout": "form/nc/page-name/page-name.json",  // Vue layout
  "javascript": "form/nc/page-name/page-name.js", // JS logic
  "css": "form/nc/page-name/page-name.css",      // Styling (optional)
  "lua": ["backend-script.lua"],                 // Backend scripts
  "include": {                                   // Dependencies
    "javascript": [{"path": "util.js", "js": "path/to/util.js"}],
    "constant": ["/path/to/constants.json"]
  }
}
```

### JSON Configuration Files

- **rec.json**: Default values for state variables (must match arr.json keys)
- **arr.json**: Array data for dropdowns, tabs, options
- **hdr.json**: Translation strings (keys must match rec/arr keys)
- **grid.json**: Grid column definitions and configurations
- **query/*.json**: Database query definitions and column mappings

### JavaScript Files

- **Vue.js components**: Layout JSON compiles to Vue components
- **State management**: Uses reactive state from rec.json and arr.json
- **Global helpers**: Access via `nc.*` namespace (nc.callServer, nc.recData, etc.)

### Lua Backend Files

- **Server-side logic**: Event handlers, data processing
- **Utility libraries**: Use standard libs (util, fs, dconn, dqry, etc.)
- **Module pattern**: Local modules with `return module`

## Development Commands

### JavaScript Linting

```bash
# From /Volumes/nc/nc-backend
npm run lint      # Check code style
npm run lintf     # Auto-fix issues
npm run lintall   # Lint all files
npm run lintd     # Debug mode
npm run lintp     # Prettier check
```

### Lua Linting

```bash
# Use luacheck with full paths
luacheck /Volumes/nc/nc-backend/plugin/db-sync/db-sync.lua
luacheck /Volumes/nc/nc-backend/preference/form/nc/erp-sync/erp-sync.lua
```

### Markdown Linting

```bash
# For documentation files
bunx markdownlint /Volumes/nc/nc-backend/preference/form/nc/nc-work-center/documentation/file.md
```

## Coding Standards

### Naming Conventions (STRICT)

- **Files**: `lowercase-with-dashes` (always)
- **Variables/Functions**: `camelCase` (always)
- **JSON keys**: `snake_case` (preserve existing)
- **Singular names**: Use singular for files, folders, variables, functions
- **Arrays**: Add `Array` suffix if same name used as normal variable (`productIdArray`)
- **Index tables**: Use `Idx` suffix (`productIdIdx[productId]`)
- **No generic names**: Avoid "handler", "factory" - use descriptive names

### JavaScript Patterns

```javascript
// Null/undefined checks
if (x == null) {}  // Correct way to check null/undefined
if (!x) {}         // Check for '', null, undefined

// No Set/Map - use plain objects/arrays only
const data = {}  // Not: new Map()
const items = [] // Not: new Set()

// Declare variables outside loops
let temp
for (let i = 0; i < arr.length; i++) {
  temp = arr[i] // Not: let temp = arr[i] inside loop
}

// Trust state - no fallbacks
const value = state.rec.someValue // Not: state.rec.someValue || 'default'
```

### Lua Patterns

```lua
-- Table operations
tbl[#tbl + 1] = val  -- Preferred over table.insert for appending

-- Nil vs false handling
if x == nil then     -- Use when x might be false
if x ~= nil then     -- Use when x might be false

-- No trailing nil parameters
myFunc(a, b)         -- Not: myFunc(a, b, nil)

-- Declare variables once, at first use
local util = require "util"  -- Declare once, reuse
```

### Critical: No Fallbacks or Defaults

- **NEVER** add fallbacks like `|| 'default'` or `or 'default'`
- **TRUST** that state is always initialized properly
- **FAIL FAST** - let errors surface immediately rather than hiding them
- **Exception**: Only user input and REST parameters need validation

## File Organization

### Query Structure

```bash
page-name/
├── query/
│   ├── entity-name.json        # Main query
│   ├── entity-name-local.json  # Local data query
│   └── column/
│       └── entity-name.json    # Column definitions
├── save/
│   └── entity-name.json        # Save configurations
└── convert/
    └── entity-name.json        # Data conversion rules
```

### ERP Integration Patterns

Each ERP integration (woocommerce, odoo, netvisor, etc.) follows:

- `arr-tab.json` - Tab definitions
- `grid.json` - Grid configurations
- `query/` - Data retrieval queries
- `query-local/` - Local database queries
- `save/` - Data save configurations
- `column/` - Column mappings

## Icon Management

- **Font Awesome**: Use icon names without prefixes (`user`, `clock`, `check`)
- **Icon library**: `/Volumes/nc/nc-frontend/src/lib/font-awesome/nc-regular-icon.json`
- **Add icons**: `cd /Volumes/nc/nc-frontend && add-icon icon1 icon2`

## Testing

- **Test location**: `/Volumes/nc/nc-backend/test/` (minimal test infrastructure)
- **Lua tests**: Use `utest` framework, follow existing patterns in `plugin/db-sync/`
- **Create tests**: Only when explicitly requested

## State Management

### Vue Component State

```javascript
// State comes from rec.json (singles) and arr.json (arrays)
const state = reactive({
  rec: recData,  // From rec.json defaults
  arr: arrData   // From arr.json options
})

// Access in layout JSON
"v-model": "rec.tab"           // Binds to rec.json key
"v-for": "option in arr.tab"   // Loops over arr.json array
```

### Translation System

- **hdr.json** contains translations matching rec/arr keys
- **Multi-language**: Add `hdr_fi.json`, `hdr_en.json` etc.
- **Required**: Every key in rec/arr must have matching translation

## Development Workflow

### When Editing a Form Page

1. **Read init.json first** - understand authorized files
2. **Check existing patterns** - look at similar working pages
3. **Maintain consistency** - follow naming and structure conventions
4. **Update all related files** - rec, arr, hdr must stay in sync
5. **Test with linting** - run `npm run lint` for JS, `luacheck` for Lua

### Path Management

- **Always use absolute paths**: `/Volumes/nc/nc-backend/preference/form/nc/...`
- **End paths with '/'** for directories
- **JSON paths in init.json**: Use relative paths from form directory
- **External dependencies**: Use absolute paths in include sections

## Error Handling

- **Fail fast**: Don't hide errors with fallbacks
- **Clear error messages**: Print descriptive errors in Lua
- **Input validation**: Only for user input and API parameters
- **Trust internal state**: Assume rec/arr state is correctly initialized

## Important Gotchas

### Common Mistakes to Avoid

1. **Reading files not in init.json** - check manifest first
2. **Adding fallbacks** - let errors surface instead
3. **Using wrong path formats** - always start with `/Volumes/nc/`
4. **Mixing naming conventions** - stick to camelCase/kebab-case
5. **Creating temp variables in loops** - declare outside
6. **Using Set/Map** - use plain objects/arrays only

### Memory Management

- Declare variables outside loops in both JS and Lua
- Use `tbl[#tbl + 1] = val` instead of `table.insert` in Lua
- Avoid unnecessary allocations in hot paths

### Date Handling

- Use `dt.isZeroDate()` for date checks in both JavaScript and Lua
- Consistent date utilities across frontend and backend

This guide reflects the actual observed patterns in the codebase. Follow these conventions strictly to maintain consistency with existing code.

Read AGENTS.md and REMEMBER all it's guidelines and instructions.

⁠ **Important**

Read /Volumes/nc/nc-devops/conf/vscode/AGENTS.md and REMEMBER all it's guidelines and instructions.
