erp_be/BACKEND_TASKS.md

23 KiB
Raw Blame History

ERP Backend — Development Tasks (Phase 1)

Reference: BACKEND_SETUP.md

Use this checklist when building or extending the backend. Follow the build order in Section 1.


1. Project Scaffold

  • Create package.json with dependencies and scripts from the spec
  • Install dependencies (npm install)
  • Add .env.example (never commit .env)
  • Configure ESLint, Prettier, Husky, lint-staged
  • Add jest.config.js with dotenv/config setup file

2. Database & Prisma

  • Define prisma/schema.prisma:
    • Auth: User, Role, Module, Permission, RolePermission, RefreshToken, PasswordResetToken
    • System: AuditLog, DocumentSeries
    • Business: Vendor (+ sub-tables), PurchaseOrder (+ items), GRN (+ items), Asset (+ transfers), all masters
  • Use PascalCase models, snake_case fields, @@map to plural table names
  • Add common columns on every business table: is_active, created_by, updated_by, created_at, updated_at, deleted_at
  • Run npx prisma migrate dev --name init
  • Run npx prisma generate
  • Implement prisma/seed.js — bootstrap Super Admin user (modules/permissions/roles from DDL)
  • Full idempotent seed (modules → permissions → roles → role_permissions) if not using DDL

Seed requirements

Step Content
Modules USERS, ROLES, MASTERS, VENDOR, PURCHASE_ORDER, GRN, ASSET, SETTINGS, AUDIT_LOGS
Permissions Each module × view, create, edit, delete, approve, export (skip where N/A)
Roles Super Admin, Admin, Purchase Manager, Store Manager, Accounts, Asset Manager
Bootstrap user Super Admin, bcrypt-hashed password, status = active

3. Core Infrastructure

  • src/config/env.js — Joi validation; app must refuse to boot on invalid/missing env
  • src/config/logger.js — Winston + daily rotate; redact sensitive keys
  • src/config/morgan.js — HTTP logs into Winston with request ID + user
  • src/config/prisma.js — singleton client with query/error logging
  • src/config/swagger.js — OpenAPI 3.0 from src/docs/completed-routes.yaml
  • src/utils/ — ApiError, ApiResponse, asyncHandler, encryption, auditLog, pagination, generateCode
  • src/middlewares/ — requestId, error, validate, rateLimiter, auth, rbac, upload
  • src/app.js — Helmet, CORS, HPP, compression, rate limit, routes, Swagger, 404, error handler
  • src/server.js — graceful shutdown, BigInt JSON serializer, unhandled rejection/exception handlers
  • Verify GET /health responds

4. Modules (HMVC Pattern)

Build in this order. Each module: *.routes.js*.controller.js*.service.js*.validation.js (+ *.repository.js for complex modules).

# Module Status Notes
8 auth [x] Done login, refresh, logout, me, profile, avatar, change/forgot/reset password
9 masters [x] Done 15 sub-masters under masters/index.js (UOM template replicated)
users [x] Done CRUD + summary/filters/export; RBAC: USERS
roles [x] Done CRUD + permission assignment + matrix; RBAC: ROLES
10 vendors [x] Done CRUD + addresses/contacts/bank-details; encrypt bank accounts
11 purchase-orders [x] Done Header + line items; submit/approve/reject/amend/cancel; PDF export
12 grn [x] Done Receipt + PO status recalc + asset auto-creation
13 assets [x] Done CRUD + transfer + AMC/service visits/insurance + expiry alerts
14 settings [x] Done Company profile + SMTP email settings; RBAC: SETTINGS

Current progress:

  • auth module (login, refresh, logout)
  • users module (screen APIs: summary, filters, export, CRUD)
  • roles module (cards, permission catalog, matrix, CRUD)
  • masters/uom template + 13 replicated sub-masters
  • Swagger docs for all completed routes (src/docs/completed-routes.yaml)
  • vendors module (CRUD, status, addresses, contacts, bank-details)
  • purchase-orders module (CRUD, workflow, PDF)
  • grn module (transactional receipt, PO status recalc, asset auto-creation)
  • assets module (CRUD, transfer, AMC, service visits, insurance, alerts)
  • GET /auth/me (current user + permissions for FE)

Layer rules

Layer Responsibility
Routes HTTP mapping + middleware chain (authenticateauthorizevalidate → controller)
Controller Parse request, call service, return ApiResponse — no business logic, no Prisma
Service Business logic, Prisma (or repository), auditLog on every mutation
Repository Multi-table prisma.$transaction only (PO, GRN, Assets)
Validation Joi schemas for body/query

5. Module API List (Phase 1)

Base path: /api/v1 · Auth: Authorization: Bearer <accessToken> (except public auth routes)

System

Status Method Endpoint RBAC Notes
[x] GET /health App health (root, not under v1)
[x] GET /healthz API v1 health
[x] GET /api-docs Swagger UI
[x] GET /api-docs.json OpenAPI spec

Auth (/auth)

Status Method Endpoint RBAC Notes
[x] POST /auth/login Public Returns accessToken, refreshToken
[x] POST /auth/refresh Public Rotating refresh token
[x] POST /auth/logout Public Revoke refresh token
[x] POST /auth/forgot-password Public Sends reset link via SMTP (email_settings)
[x] POST /auth/reset-password Public Reset password with token from email
[x] GET /auth/me Authenticated Current user + permissions (for FE)
[x] PUT /auth/profile Authenticated Update full_name / email / mobile
[x] POST /auth/profile/avatar Authenticated Upload avatar (multipart, field avatar)
[x] POST /auth/change-password Authenticated Change password (revokes refresh tokens)

DB patch: scripts/patch-users-avatar.sql — adds users.avatar_path.

Env: FRONTEND_URL (reset link base), PASSWORD_RESET_EXPIRY_MINUTES (default 60).


Users (/users) — module: USERS

Status Method Endpoint RBAC Notes
[x] GET /users/summary view Dashboard cards (total/active/inactive/locked, roles count)
[x] GET /users/filters view Role, department, status dropdowns
[x] GET /users/export export CSV export (same filters as list)
[x] GET /users view Paginated list (search, status, role_id, department_id)
[x] GET /users/:id view User detail
[x] POST /users create Create user with role_ids[] (bcrypt password, mobile encrypted)
[x] PUT /users/:id edit Update user; optional role_ids[] replaces assigned roles
[x] DELETE /users/:id delete Soft delete

Roles (/roles) — module: ROLES

Status Method Endpoint RBAC Notes
[x] GET /roles/permissions view Permission catalog (modules × actions)
[x] GET /roles/cards view Role cards (name, description, user/permission counts)
[x] GET /roles view Paginated role list
[x] GET /roles/:id view Role detail with permissions
[x] POST /roles create Create role with optional initial permissions (permission_ids[] and/or view_modules[])
[x] PUT /roles/:id edit Update role
[x] DELETE /roles/:id delete Soft delete (blocked if users assigned)
[x] PUT /roles/:id/permissions edit Assign by permission_ids[] (replaces all)
[x] GET /roles/:id/permission-matrix view Matrix UI (view/create/edit/delete/approve/export)
[x] PUT /roles/:id/permission-matrix edit Save matrix checkboxes

Masters (/masters/*) — module: MASTERS

Each sub-master supports: GET / (list), GET /:id, POST /, PUT /:id, DELETE /:id with RBAC view|create|edit|delete.

Status Sub-master Base path
[x] UOM /masters/uom
[x] Item Categories /masters/item-categories
[x] Item Subcategories /masters/item-subcategories
[x] Items /masters/items
[x] Brands /masters/brands
[x] GST Rates /masters/gst-rates
[x] HSN Codes /masters/hsn-codes
[x] Payment Terms /masters/payment-terms
[x] Delivery Terms /masters/delivery-terms
[~] Asset Categories removed — use Item Categories
[~] Asset Subcategories removed — use Item Subcategories
[x] Departments /masters/departments
[x] Designations /masters/designations
[x] Locations /masters/locations
[x] Plants /masters/plants
[x] Warehouses /masters/warehouses
[x] Document Series /masters/document-series

Masters total: 13 modules × 5 endpoints (+ plants/warehouses aliases)


Vendors (/vendors) — module: VENDOR

Status Method Endpoint RBAC Notes
[x] GET /vendors view List (search, status, vendor_type)
[x] GET /vendors/gst-treatments view GST treatment dropdown options
[x] GET /vendors/source-of-supply view Indian states/UTs dropdown options
[x] POST /vendors create Auto vendor_code via VENDOR series
[x] GET /vendors/:id view Detail + addresses, contacts, bank details, item mappings
[x] PUT /vendors/:id edit Update vendor
[x] PATCH /vendors/:id/status edit active / inactive / blacklisted
[x] DELETE /vendors/:id delete Soft delete
[x] GET /vendors/:vendorId/addresses view List addresses
[x] POST /vendors/:vendorId/addresses create Add address
[x] GET /vendors/:vendorId/addresses/:addressId view Get address
[x] PUT /vendors/:vendorId/addresses/:addressId edit Update address
[x] DELETE /vendors/:vendorId/addresses/:addressId delete Deactivate address
[x] GET /vendors/:vendorId/contacts view List contacts
[x] POST /vendors/:vendorId/contacts create Add contact
[x] GET /vendors/:vendorId/contacts/:contactId view Get contact
[x] PUT /vendors/:vendorId/contacts/:contactId edit Update contact
[x] DELETE /vendors/:vendorId/contacts/:contactId delete Deactivate contact
[x] GET /vendors/:vendorId/bank-details view List bank details (decrypted)
[x] POST /vendors/:vendorId/bank-details create Add bank detail (encrypted)
[x] GET /vendors/:vendorId/bank-details/:bankDetailId view Get bank detail
[x] PUT /vendors/:vendorId/bank-details/:bankDetailId edit Update bank detail
[x] DELETE /vendors/:vendorId/bank-details/:bankDetailId delete Deactivate bank detail
[x] GET /vendors/:vendorId/items view List vendoritem mappings
[x] POST /vendors/:vendorId/items create Map item to vendor
[x] GET /vendors/:vendorId/items/:mappingId view Get item mapping
[x] PUT /vendors/:vendorId/items/:mappingId edit Update rate / preferred flag
[x] DELETE /vendors/:vendorId/items/:mappingId delete Deactivate item mapping

Purchase Orders (/purchase-orders) — module: PURCHASE_ORDER

Status Method Endpoint RBAC Notes
[x] GET /purchase-orders view List POs
[x] GET /purchase-orders/:id view PO detail + line items
[x] POST /purchase-orders create Create PO
[x] PUT /purchase-orders/:id edit Update PO
[x] DELETE /purchase-orders/:id delete Soft delete
[x] POST /purchase-orders/:id/submit edit Submit for approval
[x] POST /purchase-orders/:id/approve approve Approve PO
[x] POST /purchase-orders/:id/reject approve Reject PO
[x] POST /purchase-orders/:id/amend edit Amend PO
[x] POST /purchase-orders/:id/cancel edit Cancel PO
[x] GET /purchase-orders/:id/pdf view PDF export
[x] GET /purchase-orders/:poId/attachments view List PO attachments
[x] POST /purchase-orders/:poId/attachments edit Upload file (multipart file)
[x] GET /purchase-orders/:poId/attachments/:attachmentId view Attachment metadata
[x] GET /purchase-orders/:poId/attachments/:attachmentId/download view Download file (authenticated)
[x] DELETE /purchase-orders/:poId/attachments/:attachmentId delete Delete attachment + file

Totals: taxable_amount = sub_total + freight + other discount; GST (tax_total / CGST+SGST / IGST) is calculated on taxable_amount (not on sub_total). Column persisted via scripts/patch-po-taxable-amount.sql.


GRN (/grn) — module: GRN

Status Method Endpoint RBAC Notes
[x] GET /grn view List GRNs
[x] GET /grn/:id view GRN detail + line items
[x] POST /grn create Create GRN (transactional)
[x] PUT /grn/:id edit Update GRN
[x] POST /grn/:id/cancel edit Cancel GRN
[x] GET /grn/:id/pdf view PDF export
[x] GET /grn/:grnId/attachments view List GRN attachments
[x] POST /grn/:grnId/attachments edit Upload file (multipart file)
[x] GET /grn/:grnId/attachments/:attachmentId view Attachment metadata
[x] GET /grn/:grnId/attachments/:attachmentId/download view Download file (authenticated)
[x] DELETE /grn/:grnId/attachments/:attachmentId delete Delete attachment + file

Assets (/assets) — module: ASSET

Status Method Endpoint RBAC Notes
[x] GET /assets view List assets
[x] GET /assets/:id view Asset detail
[x] POST /assets create Create asset
[x] PUT /assets/:id edit Update asset
[x] DELETE /assets/:id delete Soft delete
[x] POST /assets/:id/transfer edit Transfer asset
[x] GET /assets/:id/transfer-history view Transfer history
[x] GET /assets/:assetId/attachments view List asset attachments
[x] POST /assets/:assetId/attachments edit Upload file (multipart file; optional attachment_type, AMC/visit/insurance link)
[x] GET /assets/:assetId/attachments/:attachmentId view Attachment metadata
[x] GET /assets/:assetId/attachments/:attachmentId/download view Download file (authenticated)
[x] DELETE /assets/:assetId/attachments/:attachmentId delete Delete attachment + file

AMC contracts (/assets/:id/amc)

Status Method Endpoint RBAC Notes
[x] GET /assets/:id/amc view List AMC contracts
[x] POST /assets/:id/amc create Add AMC contract
[x] GET /assets/:id/amc/:contractId view AMC detail
[x] PUT /assets/:id/amc/:contractId edit Update AMC
[x] PATCH /assets/:id/amc/:contractId/renew edit Renew AMC (deactivate old, create new)

Service visits (/assets/:id/service-visits)

Status Method Endpoint RBAC Notes
[x] GET /assets/:id/service-visits view List visits
[x] POST /assets/:id/service-visits create Log visit
[x] GET /assets/:id/service-visits/:visitId view Visit detail
[x] PUT /assets/:id/service-visits/:visitId edit Update visit
[x] PATCH /assets/:id/service-visits/:visitId/status edit Update visit status

Insurance (/assets/:id/insurance)

Status Method Endpoint RBAC Notes
[x] GET /assets/:id/insurance view List policies
[x] POST /assets/:id/insurance create Add policy
[x] GET /assets/:id/insurance/:policyId view Policy detail
[x] PUT /assets/:id/insurance/:policyId edit Update policy
[x] PATCH /assets/:id/insurance/:policyId/renew edit Renew policy

Alerts (cross-asset)

Status Method Endpoint RBAC Notes
[x] GET /assets/alerts/expiry view AMC/Insurance/Warranty expiry (?days=30/60/90&type=)
[x] GET /assets/alerts/service view Overdue/upcoming service (?status=OVERDUE)

Settings (/settings) — module: SETTINGS

Status Method Endpoint RBAC Notes
[x] GET /settings/company view Company profile (org name, GSTIN, contact, address, logo/favicon URLs)
[x] PUT /settings/company edit Update company profile
[x] POST /settings/company/logo edit Upload logo (multipart/form-data, field logo)
[x] POST /settings/company/favicon edit Upload favicon (multipart/form-data, field favicon)
[x] GET /settings/email view SMTP settings (has_smtp_password flag; password never returned)
[x] PUT /settings/email edit Update SMTP settings (password encrypted at rest)

DB patch: scripts/patch-company-email-settings.sql — creates company + email_settings singleton tables and SETTINGS module permissions for Super Admin.

DB patch: scripts/patch-company-gstin.sql — adds company.gstin for PDF document headers.

DB patch: scripts/patch-company-favicon.sql — adds company.favicon_path.


Audit Logs (/audit-logs) — module: AUDIT_LOGS

Status Method Endpoint RBAC Notes
[x] GET /audit-logs/filters view Distinct table_names, actions, performers for FE dropdowns
[x] GET /audit-logs view Filtered list; empty by default until at least one filter is applied
[x] GET /audit-logs/:id view Full detail with old_value / new_value JSON
[x] GET /audit-logs/export export CSV export (filters required)

List filters: table_name, record_id, action, performed_by, request_id, date_from, date_to, search (+ page, limit).

DB patch: scripts/patch-audit-logs-module.sqlAUDIT_LOGS module with view + export for Super Admin.


DB patch: run scripts/patch-assets-amc-insurance.sql then scripts/patch-assets-views.sql on deployed DB.


API progress summary

Module Endpoints done Endpoints total Status
System 4 4 [x] Done
Auth 9 9 [x] Done
Users 8 8 [x] Done
Roles 10 10 [x] Done
Masters 70 70 [x] Done
Vendors 27 27 [x] Done
Purchase Orders 11 11 [x] Done
GRN 11 11 [x] Done
Assets 24 24 [x] Done
Settings 5 5 [x] Done
Audit Logs 4 4 [x] Done
Total 172 172 [x] Phase 1 APIs + Asset extensions

6. Security Tasks

  • JWT access tokens (15m) in Authorization: Bearer header
  • Refresh tokens: opaque, SHA-256 hashed in DB, rotated on each refresh
  • bcrypt password hashing (BCRYPT_SALT_ROUNDS=12)
  • Account lockout after MAX_LOGIN_ATTEMPTS failures
  • authenticate + authorize(module, action) on every protected route
  • AES-256-GCM field encryption + HMAC blind index for searchable PII
  • Rate limiting: global on /api, stricter on /auth/login and /auth/forgot-password
  • Helmet, CORS (no * in production), HPP, compression
  • File uploads: MIME allow-list, random filenames, RBAC-protected download (not direct web serve)
  • auditLog() on every create/update/status-change/approve/reject (completed modules)
  • X-Request-Id on every request for log correlation

RBAC permission actions

view, create, edit, delete, approve, export


7. API Conventions

  • Versioning: /api/v1/...
  • Pagination: ?page=1&limit=20 (cap limit at 100); response meta: { page, limit, total }
  • Filtering: ?status=...&search=... per module
  • Sorting: ?sort=-created_at (- = descending)
  • IDs: BigInt serialized as strings in JSON
  • Dates: ISO 8601 UTC
  • Soft delete: set deleted_at, never hard-delete transactional records
  • Response envelope: { success, message, data?, meta?, errors? }

8. Testing

  • Jest + Supertest against app.js (no live server)
  • Separate test DB via .env.test + prisma migrate deploy
  • Mirror structure: tests/modules/<module>/<module>.test.js

Minimum Phase 1 coverage

  • Auth: login, refresh, lockout
  • RBAC: allowed vs forbidden
  • Vendor: CRUD + status transitions
  • PO: status lifecycle
  • GRN: partial receipt → PO status recalculation

9. Documentation & DevOps

  • OpenAPI spec for completed routes (src/docs/completed-routes.yaml + /api-docs)
  • Add @swagger JSDoc blocks to route files (optional; YAML spec in use)
  • Dockerfile (Node 20 Alpine)
  • docker-compose.yml (API + Postgres 15)
  • Verify docker-compose up boots API + Postgres
  • Run npm audit in CI

10. Future Development Guidelines

When adding a new module or endpoint:

  1. Add Prisma model with common columns + soft delete
  2. Add module/permissions to seed (if new domain)
  3. Create the four-file HMVC module (five if multi-table transactions)
  4. Register routes in src/routes/v1/index.js
  5. Apply middleware chain: authenticateauthorize(MODULE, action)validate(schema) → controller
  6. Call auditLog() in service for all mutations
  7. Use nextDocumentNumber() for auto-generated codes
  8. Encrypt PII at service layer with blind index for search
  9. Add Swagger JSDoc + Jest tests
  10. Breaking API changes → new version (/api/v2)

Complex transaction modules

Use *.repository.js with prisma.$transaction when a single operation touches multiple tables (e.g. PO header + items, GRN + PO qty update + asset creation).

Masters replication

Copy the UOM module pattern for new masters: simple name/code fields, RBAC code MASTERS, no document numbering.