A comprehensive Enterprise Resource Planning (ERP) system built with Go, designed for agricultural businesses and FPOs (Farmer Producer Organizations).
- π Official API Documentation: Scalar Registry
- Interactive Documentation:
/docsendpoint (Scalar Go-powered) - Swagger UI:
/swagger/index.htmlendpoint - OpenAPI Specification:
/api-docsendpoint
- Procurement Management: Complete vendor-to-inventory workflow
- Vendor/Supplier (Collaborator) Management
- Vendor-Product Associations (many-to-many)
- Product Variants (separate table)
- Purchase Order workflow with ALL-IN pricing
- GRN (Goods Receipt Notes) with 3 input patterns
- Auto-GRN creation with quality inspection
- Automatic inventory batch creation from GRN
- Inventory Management: Track products, batches, and stock levels with automatic batch creation from GRN and FEFO integration
- Sales Management: Handle sales orders, invoices, and customer data
- Returns Management: Process returns and refunds
- Warehouse Management: Multi-warehouse support with location tracking
- Product Management: SKU management with pricing and categorization
- Tax Management: Comprehensive tax calculation and compliance system
- Discount System: Advanced discount management with validation
- File Attachments: Generic entity-based system (S3) for logos, POs, GRNs, and documents
- Bank Payments: Track payment transactions for sales and returns
- Refund Policies: Manage return and refund policies
- Reporting: Sales analytics and inventory reports
- AAA Service Integration: Authentication, Authorization, and Accounting
- Organization-Scoped Permissions: Multi-tenant isolation with automatic organization-level access control
- Role-Based Access Control (RBAC): Granular permissions for different user roles
- JWT Token Validation: Secure token-based authentication from external AAA service with organization context
- TTL Caching: High-performance permission caching
- Audit Logging: Comprehensive activity tracking
- External User Management: User management handled by separate AAA service
- Multi-Tenant Support: Complete isolation between organizations with organization-scoped permission checks
- Backend: Go 1.21+
- Framework: Gin (HTTP framework)
- Database: PostgreSQL with GORM ORM
- Authentication: JWT with external AAA service integration
- File Storage: AWS S3
- HTTP API: RESTful API for all operations
- Documentation: Scalar Go package + Swagger UI
- Tax System: Production-ready GST compliance system
- Configuration: Environment-based configuration
- Logging: Structured logging with levels
- Validation: Comprehensive input validation and business rules
Kisanlink-erp-v1/
βββ cmd/
β βββ server/
β βββ main.go # Application entry point
βββ internal/
β βββ aaa/ # AAA service integration
β β βββ cache.go # TTL permission caching
β β βββ middleware.go # AAA authentication middleware
β β βββ types.go # AAA data structures
β β βββ audit.go # Audit logging
β β βββ README.md # AAA integration docs
β βββ api/
β β βββ handlers/ # HTTP request handlers
β β βββ middleware/ # HTTP middleware (CORS, logging, rate limiting)
β β βββ routes/ # Route definitions
β β βββ server/ # HTTP server setup
β βββ config/ # Configuration management
β βββ database/
β β βββ models/ # Database models (organized by domain)
β β β βββ attachments.go # Generic entity-based attachment models
β β β βββ bank_payments.go # Bank payment models
β β β βββ collaborator.go # Vendor/supplier models
β β β βββ collaborator_product.go # Vendor-product associations
β β β βββ product_variant.go # Product size/quantity variants
β β β βββ purchase_order.go # Purchase order models
β β β βββ grn.go # Goods receipt note models
β β β βββ inventory.go # Inventory batch and transaction models
β β β βββ price.go # Product pricing models
β β β βββ product.go # Product/SKU models
β β β βββ returns.go # Return and refund policy models
β β β βββ sales.go # Sales models
β β β βββ warehouse.go # Warehouse models
β β βββ repositories/ # Data access layer
β β βββ migrator.go # Database migrations
β βββ services/ # Business logic layer
β βββ utils/ # Utility functions
β βββ aaa/ # AAA service integration
βββ proto/ # Protocol Buffer definitions
βββ scripts/ # Build and deployment scripts
βββ docs/ # API documentation
The ERP system integrates with an external AAA (Authentication, Authorization, and Accounting) service for centralized security management. User management is handled by a separate service - this ERP service only handles business operations and uses tokens from the header for authentication.
- JWT Token Validation: Validates tokens from AAA service
- Permission-Based Access Control: Route-level permission checks
- Role-Based Access Control: Role-based route protection
- TTL Caching: Caches user permissions for performance
- Audit Logging: Optional audit event logging
The system implements organization-scoped permissions for multi-tenant isolation:
- JWT Token Contains Organization Context: AAA LoginV2 includes
organizationsarray in JWT - Automatic Extraction: Middleware extracts
organization_idfrom JWT token - Scoped Permission Checks: All routes check permissions against user's organization
- Multi-Tenant Isolation: Users can only access resources within their organization
Global Permissions (Super Admin):
ResourceType: "collaborator"
ResourceId: "*" // Access all organizations
Action: "read"
Organization-Scoped Permissions (FPO Users):
ResourceType: "collaborator"
ResourceId: "ORG_12345" // Access only ORG_12345
Action: "read"
- 16 Handler Files Updated: ~115 routes now use organization-scoped permissions
- Automatic Scoping: Middleware handles organization context extraction
- Backward Compatible: Super admin roles can still use wildcard (
*) permissions - Security Enhancement: Critical for multi-tenant security and data isolation
Documentation: See files/ORG_SCOPED_PERMISSIONS_IMPLEMENTATION.md for complete details
The system supports the following permissions based on user roles:
| Entity | Director | CEO | Auditor | Accountant | Tech_Support | Store_Manager | Store_Staff |
|---|---|---|---|---|---|---|---|
| sale_summaries | R | CRUD | R | R | R/W (temp) | R | R |
| warehouses | R | CRUD | R | β | R/W (temp) | CRUD | R |
| inventory_batches | R | CRUD | R | β | R/W (temp) | CRUD | R |
| sale_items | R | CRUD | R | R | R/W (temp) | R | CRUD |
| inventory_transactions | R | CRUD | R | β | R/W (temp) | CRUD | R |
| sales | R | CRUD | R | R | R/W (temp) | R | CRUD |
| returns | R | CRUD | R | R | R/W (temp) | R | CRUD |
| sku | R | CRUD | R | β | R/W (temp) | CRUD | R |
| return_items | R | CRUD | R | R | R/W (temp) | R | CRUD |
| return_summaries | R | CRUD | R | R | R/W (temp) | R | CRUD |
| refund_policy | R | CRUD | R | CRUD | R/W (temp) | β | β |
| bank_payments | R | CRUD | R | CRUD | R/W (temp) | β | β |
| attachments | R | CRUD | R | R | R/W (temp) | R | R |
Legend:
- R = Read access
- CRUD = Create, Read, Update, Delete access
- R/W (temp) = Read/Write access (temporary for Tech Support)
- β = No access
The system uses the following permission naming convention:
{entity}:read- Read access to entity{entity}:create- Create access to entity{entity}:update- Update access to entity{entity}:delete- Delete access to entity
Examples:
sale_summaries:read- Read sale summary datawarehouses:read- Read warehouse datasales:create- Create sales recordssku:update- Update product informationreturns:delete- Delete return recordsrefund_policy:create- Create refund policiesbank_payments:read- Read bank payment recordsattachments:read- Read attachments
The ERP system is fully multi-tenant with organization-level isolation:
- JWT Token: Contains user's organization ID(s) from AAA LoginV2
- Automatic Extraction: Middleware extracts
organization_idfrom JWT - Scoped Access: All API calls are automatically scoped to user's organization
- Data Isolation: Users cannot access resources from other organizations
# User from Organization ORG_A creates a collaborator
POST /api/v1/collaborators
Authorization: Bearer <token-with-org-A>
# Permission Check:
# - ResourceType: "collaborator"
# - ResourceId: "ORG_A" β Organization-scoped
# - Action: "create"
# Result: Collaborator created in ORG_A only# Super admin with global permissions
POST /api/v1/collaborators
Authorization: Bearer <super-admin-token>
# Permission Check:
# - ResourceType: "collaborator"
# - ResourceId: "*" β Global access
# - Action: "create"
# Result: Can create collaborators in any organizationβ Organization Isolation: Users cannot access data from other organizations β Automatic Scoping: No manual filtering needed in handlers β Audit Trail: All operations logged with organization context β Flexible Access: Supports single-org users and multi-org admins
- Middleware:
RequireOrgPermission(resourceType, action)in all handlers - Coverage: 16 handler files, ~115 routes
- Documentation: Complete guide in
files/ORG_SCOPED_PERMISSIONS_IMPLEMENTATION.md
- Go 1.21 or higher
- PostgreSQL 12 or higher
- AWS S3 bucket (for file attachments)
- AAA service (for authentication)
Create a .env file in the project root:
# Server Configuration
SERVER_HTTP_PORT=8080
SERVER_MODE=release
# Database Configuration
DB_POSTGRES_HOST=localhost
DB_POSTGRES_PORT=5432
DB_POSTGRES_USER=postgres
DB_POSTGRES_PASSWORD=your_password
DB_POSTGRES_DBNAME=erp_database
DB_POSTGRES_SSLMODE=disable
# JWT Configuration
JWT_SECRET=your-jwt-secret
JWT_EXPIRY_HOURS=24
# AWS Configuration
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_S3_BUCKET=your-s3-bucket
# CORS Configuration
CORS_ALLOWED_ORIGINS=http://localhost:3000,http://localhost:8080
CORS_ALLOWED_HEADERS=Origin,Content-Type,Accept,Authorization,X-Requested-With,X-Request-ID
# AAA Service Configuration
AAA_JWT_SECRET=your-aaa-jwt-secret
AAA_CACHE_TTL=30For testing purposes, you can generate JWT tokens using the provided script:
-
Create the token generator script:
# Create generate_token.go file with your JWT secret # Replace "REPLACE_WITH_YOUR_ACTUAL_JWT_SECRET" with your actual secret
-
Generate a token:
go run generate_token.go
-
Use the token in API requests:
curl -X GET http://localhost:8080/api/v1/warehouses \ -H "Authorization: Bearer <generated-token>" \ -H "Content-Type: application/json"
-
Clone the repository
git clone https://github.com/Kisanlink/fpo-erp.git cd Kisanlink-erp-v1 -
Install dependencies
go mod download
-
Set up pre-commit hooks (required for code quality)
# Install pre-commit (if not already installed) # macOS: brew install pre-commit # Linux: pip install pre-commit # Windows: pip install pre-commit # Install hooks make install-hooks
See PRECOMMIT_HOOKS.md for detailed setup instructions.
-
Set up the database
# Create PostgreSQL database createdb erp_database -
Run the application
go run cmd/server/main.go
The server will start on:
- HTTP API:
http://localhost:3000(default) - API Documentation:
http://localhost:3000/docs(Scalar) - Swagger UI:
http://localhost:3000/swagger/index.html - OpenAPI Spec:
http://localhost:3000/api-docs - AAA Service:
localhost:9091
All API endpoints require a valid JWT token from the AAA service in the Authorization header:
Authorization: Bearer <jwt-token>
GET /api/v1/warehouses- List all warehousesPOST /api/v1/warehouses- Create warehouseGET /api/v1/warehouses/:id- Get warehouse detailsPATCH /api/v1/warehouses/:id- Update warehouseDELETE /api/v1/warehouses/:id- Delete warehouse
GET /api/v1/products- List all productsPOST /api/v1/products- Create productGET /api/v1/products/:id- Get product detailsPATCH /api/v1/products/:id- Update productDELETE /api/v1/products/:id- Delete product
GET /api/v1/batches- List all batchesPOST /api/v1/batches- Create batch with tax configurationGET /api/v1/batches/:id- Get batch detailsGET /api/v1/batches/expiring- Get expiring batchesGET /api/v1/batches/low-stock- Get low stock batches
GET /api/v1/taxes- List all taxesPOST /api/v1/taxes- Create custom taxGET /api/v1/taxes/:id- Get tax detailsPATCH /api/v1/taxes/:id- Update taxDELETE /api/v1/taxes/:id- Delete taxPOST /api/v1/taxes/calculate- Calculate tax for items
GET /api/v1/sales- List all salesPOST /api/v1/sales- Create saleGET /api/v1/sales/:id- Get sale detailsPUT /api/v1/sales/:id- Update saleDELETE /api/v1/sales/:id- Delete sale
GET /api/v1/returns- List all returnsPOST /api/v1/returns- Create returnGET /api/v1/returns/:id- Get return detailsPUT /api/v1/returns/:id- Update returnDELETE /api/v1/returns/:id- Delete return
GET /api/v1/refund-policies- List all refund policiesPOST /api/v1/refund-policies- Create refund policyGET /api/v1/refund-policies/:id- Get refund policy detailsPUT /api/v1/refund-policies/:id- Update refund policyDELETE /api/v1/refund-policies/:id- Delete refund policy
GET /api/v1/collaborators- List all vendorsPOST /api/v1/collaborators- Create vendorGET /api/v1/collaborators/:id- Get vendor detailsGET /api/v1/collaborators/active- Get active vendorsPATCH /api/v1/collaborators/:id- Update vendorPATCH /api/v1/collaborators/:id/status- Activate/deactivate vendorDELETE /api/v1/collaborators/:id- Delete vendor
GET /api/v1/collaborator-products- List vendor-product associationsPOST /api/v1/collaborator-products- Create associationGET /api/v1/collaborator-products/:id- Get association detailsGET /api/v1/collaborator-products/collaborator/:id- Get products by vendorGET /api/v1/collaborator-products/product/:id- Get vendors by productPATCH /api/v1/collaborator-products/:id- Update associationPATCH /api/v1/collaborator-products/:id/status- Activate/deactivateDELETE /api/v1/collaborator-products/:id- Delete association
GET /api/v1/product-variants- List all variantsPOST /api/v1/product-variants- Create variantGET /api/v1/product-variants/:id- Get variant detailsGET /api/v1/product-variants/product/:id- Get variants by productPATCH /api/v1/product-variants/:id- Update variantPATCH /api/v1/product-variants/:id/status- Activate/deactivateDELETE /api/v1/product-variants/:id- Delete variant
GET /api/v1/purchase-orders- List all purchase ordersPOST /api/v1/purchase-orders- Create purchase orderGET /api/v1/purchase-orders/:id- Get PO detailsGET /api/v1/purchase-orders/pending-deliveries- Get pending deliveriesGET /api/v1/purchase-orders/status/:status- Get POs by statusPATCH /api/v1/purchase-orders/:id/status- Update status (with auto-GRN support)PATCH /api/v1/purchase-orders/:id/payment- Update payment statusGET /api/v1/collaborators/:id/purchase-orders- Get POs by vendor
GET /api/v1/grns- List all GRNsPOST /api/v1/grns- Create GRN manuallyGET /api/v1/grns/:id- Get GRN detailsGET /api/v1/grns/warehouse/:id- Get GRNs by warehouseGET /api/v1/grns/purchase-order/:id- Get GRN by purchase order
GET /api/v1/bank-payments- List all bank paymentsPOST /api/v1/bank-payments- Create bank paymentGET /api/v1/bank-payments/:id- Get bank payment detailsPUT /api/v1/bank-payments/:id- Update bank payment
GET /api/v1/attachments- List attachments (with entity filters)POST /api/v1/attachments- Upload attachment (requires entity_type & entity_id)GET /api/v1/attachments/:id- Get attachment metadataGET /api/v1/attachments/:id/download- Download attachment fileGET /api/v1/attachments/:id/url- Get presigned URL for displayGET /api/v1/attachments/:id/info- Get detailed file informationGET /api/v1/attachments/entity/:entity_type/:entity_id- Get all attachments for entityDELETE /api/v1/attachments/:id- Delete attachment
curl -X POST http://localhost:8080/api/v1/warehouses \
-H "Authorization: Bearer <your-jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Main Warehouse",
"location": "Mumbai, Maharashtra",
"capacity": 10000,
"manager_name": "John Doe",
"contact_number": "+91-9876543210"
}'curl -X POST http://localhost:3000/api/v1/batches \
-H "Authorization: Bearer <your-jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"warehouse_id": "WH1234567890",
"product_id": "PROD00000001",
"cost_price": 85.50,
"expiry_date": "2025-12-31",
"quantity": 1000,
"cgst_rate": 2.5,
"sgst_rate": 2.5,
"custom_tax_ids": ["TAX_CESS_ENV_001", "TAX_MANDI_FEE_001"],
"is_tax_exempt": false
}'curl -X POST http://localhost:3000/api/v1/taxes \
-H "Authorization: Bearer <your-jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"code": "TAX_CESS_ENV_001",
"name": "Environmental Cess",
"tax_type": "item_specific",
"calculation_type": "percentage",
"rate": 1.0,
"valid_from": "2024-01-01T00:00:00Z",
"is_active": true
}'curl -X POST http://localhost:8080/api/v1/sales \
-H "Authorization: Bearer <your-jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"warehouse_id": "WH1234567890",
"customer_id": "CUST00000001",
"batch_id": "BATCH00000001",
"selling_price": 25.00
}'curl -X POST http://localhost:8080/api/v1/refund-policies \
-H "Authorization: Bearer <your-jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"policy_name": "Standard Return Policy",
"description": "30-day return policy with 10% restocking fee",
"max_days": 30,
"restocking_fee": 10.00
}'curl -X POST http://localhost:8080/api/v1/collaborators \
-H "Authorization: Bearer <your-jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"company_name": "ABC Traders",
"contact_person": "Rajesh Kumar",
"contact_number": "+91-9876543210",
"email": "rajesh@abctraders.com",
"gst_number": "27AABCU9603R1ZM",
"bank_account_no": "123456789012",
"bank_ifsc": "SBIN0001234",
"address": {
"line1": "123 Market Street",
"city": "Mumbai",
"state": "Maharashtra",
"pincode": "400001",
"country": "India"
}
}'curl -X POST http://localhost:8080/api/v1/purchase-orders \
-H "Authorization: Bearer <your-jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"collaborator_id": "CLAB_abc12345",
"warehouse_id": "WH_xyz67890",
"expected_delivery_date": "2025-02-15",
"items": [
{
"product_id": "SKU_rice001",
"quantity": 1000,
"unit_price": 45.50
},
{
"product_id": "SKU_wheat002",
"quantity": 500,
"unit_price": 38.00
}
]
}'curl -X PATCH http://localhost:8080/api/v1/purchase-orders/PO_123/status \
-H "Authorization: Bearer <your-jwt-token>" \
-H "Content-Type: application/json" \
-d '{
"status": "delivered",
"accept_all": true,
"default_expiry_date": "2025-12-31"
}'curl -X POST http://localhost:8080/api/v1/attachments \
-H "Authorization: Bearer <your-jwt-token>" \
-F "file=@company_logo.png" \
-F "entity_type=logo" \
-F "entity_id=CLAB_abc12345"curl -X GET http://localhost:8080/api/v1/attachments/ATT_xyz789/url \
-H "Authorization: Bearer <your-jwt-token>"Run the test suite:
go test ./...Run specific test packages:
go test ./internal/aaa/...
go test ./internal/api/handlers/...
go test ./internal/services/...- Generate a test token using the token generator script
- Test different roles by modifying the permissions in the token
- Verify permission enforcement by testing endpoints with different permission sets
- Check audit logs for authentication and authorization events
- Store Manager: Test warehouse and inventory management permissions
- CEO: Test full CRUD access to all entities
- Auditor: Test read-only access to all entities
- Accountant: Test financial operations (bank payments, refund policies)
- Store Staff: Test limited CRUD operations on sales and returns
# Build the Docker image
docker build -t kisanlink-erp .
# Run the container
docker run -p 8080:8080 -p 9090:9090 \
-e DB_POSTGRES_HOST=your-db-host \
-e DB_POSTGRES_PASSWORD=your-db-password \
kisanlink-erp- Set up a PostgreSQL database
- Configure AWS S3 for file storage
- Set up the AAA service
- Configure environment variables
- Deploy using your preferred method (Docker, Kubernetes, etc.)
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
For support and questions:
- Create an issue in the GitHub repository
- Contact the development team
- Check the documentation in the
docs/directory
- Multi-Tenant Security: Complete organization-level isolation for all resources
- Automatic Organization Scoping: Middleware extracts
organization_idfrom JWT and validates permissions - 16 Handlers Updated: All major handlers (~115 routes) now use organization-scoped permission checks
- Defense in Depth: 4-layer security (JWT β Context β Org Permissions β Business Logic)
- AAA Integration: Leverages AAA service's hierarchical permission model (global/organization/instance)
- Zero Performance Impact: Organization ID already in JWT token, no additional queries needed
- Super Admin Support: Global wildcard permissions still work for cross-organization access
- Production Implementation:
RequireOrgPermission(resourceType, action)replacesRequirePermission(resourceType, "*", action)
- Vendor/Supplier Management: Full collaborator (vendor) profiles with AAA address integration
- Vendor-Product Associations: Many-to-many relationships with brand info and compliance data
- Product Variants: Separate table for size/quantity variants (500g, 1kg, 5kg, etc.)
- Purchase Order Workflow: ALL-IN pricing with status tracking (placed β confirmed β delivered β paid)
- GRN (Goods Receipt Notes): 3 flexible input patterns (Accept All, Simple Accept/Reject, Detailed Quantities)
- Auto-GRN Creation: Automatic GRN generation with quality inspection and batch tracking
- Automatic Inventory Updates: GRN accepted quantities automatically create inventory batches
- Entity-Based Architecture: Refactored from sale/return-specific to generic
entity_type+entity_idpattern - Multi-Entity Support: Works for logos, purchase orders, GRNs, and any future entity types
- Frontend-Friendly: Two-step workflow (upload β get attachment ID β create entity) with presigned URLs
- S3 Folder Structure: Organized by entity type (logos/, purchase-orders/{ID}/, grns/{ID}/, misc/)
- Database Migration: Complete migration script for existing data (
migrations/20250128_refactor_attachments_to_entity.sql)
- Automatic Batch Creation: Accepted quantities from GRN automatically create inventory batches
- FEFO Integration: New batches immediately participate in First-Expired-First-Out allocation
- Transaction Audit Trail: Complete history of inventory movements from GRN to sales
- Batch Number Tracking: Vendor batch numbers stored separately from system batch IDs
- ALL-IN Cost Pricing: PO unit price becomes inventory batch cost price
- Nested Role Support: Enhanced parsing for AAA tokens with
user_context.rolesstructure - Backward Compatibility: Conversion layer maintains compatibility with existing code
- Improved Permission Extraction: Better handling of roleIds and permissions fields
- π·οΈ Production-Ready Tax System: Complete inventory-based tax management with CGST, SGST, and custom taxes
- π Scalar Go Documentation: Interactive API documentation using Scalar Go package
- π§ Advanced Tax Calculation: Automatic tax computation during sales with GST compliance
- π― Real-world Tax Scenarios: Support for multiple tax rates and exemptions
- π Enhanced Validation: Complete input validation and business rule enforcement
- Permission Matrix Implementation: Complete role-based access control for all entities
- AAA Service Integration: Full integration with external AAA service
- JWT Token Support: Support for external JWT tokens with custom payload format
- Discount System: Comprehensive discount management and validation
- β Procurement Module: Complete vendor-to-inventory workflow (40+ endpoints)
- β Tax System: Fully implemented and tested
- β Inventory Management: Automatic updates from GRN with FEFO integration
- β API Documentation: Complete with Scalar Registry integration
- β GST Compliance: Indian tax regulations supported
- β Performance: Optimized with TTL caching and efficient queries
- Advanced reporting and analytics
- Mobile application
- Multi-tenant support (β Completed - Organization-scoped permissions implemented)
- Advanced inventory forecasting
- Integration with external systems
- Real-time notifications
- Advanced audit logging
- Performance monitoring and metrics
- Bulk operations support
- Advanced search and filtering
- Export functionality (CSV, PDF)
- Dashboard and analytics