P Palmyra ERP Docs

Developer guide

Code structure, patterns, and testing for the Palmyra ERP application. Designed to be manageable by a single developer.

Code structure

Single solution: Palmyra ERP.Web (MVC + API + Vue) and Palmyra ERP.Tests. Controllers under Api/ and Pages/; business logic in Services/; data access in Data/ (DbService, CrudService) with raw SQL in Schema/. No ORM; data flows as Dictionary<string, object?>.

Key patterns

  • CrudService — Auto-adds WHERE tenant_id = @tenant_id to every query.
  • DbService — Npgsql wrapper: QueryAsync, ExecuteAsync, ScalarAsync, QueryPagedAsync.
  • Generic base controller — Handles GET/POST/PUT/DELETE, pagination, 304, tenant isolation, permission check.
  • Configuration over code — Business rules, workflows, features in DB (TenantConfig, WorkflowConfigs); not in code.

Testing

C# tests use seeded database (schema + seed SQL). Tests hit APIs directly; validate CRUD, workflow stages, permissions, and integration (e.g. GRN posting to inventory). See API Testing module for test harness and output log.

Schema migrations

Numbered SQL files in Schema/ (e.g. 001_tenants.sql). SchemaRunner runs them on startup and records applied migrations in _schema_migrations. No separate migration framework.