# 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

### Linting

```bash
# Use lnt with full paths
lnt /Volumes/nc/nc-backend/plugin/db-sync/db-sync.lua
lnt /Volumes/nc/nc-backend/plugin/db-sync/db-sync.js
lnt /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'`, `|| 0`, `|| {}`
- **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
```

## 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 `lnt` for all file types

### Path Management

- **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**: ALL rec/arr state is correctly initialized

## Important Gotchas

### Common Mistakes to Avoid

- **Reading files not in init.json** - check manifest first
- **Adding fallbacks** - let errors surface instead
- **Mixing naming conventions** - stick to camelCase/kebab-case
- **Creating temp variables in loops** - declare outside
- **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

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