From 2f1d3964c8003ca21342736a86037ba82c032f27 Mon Sep 17 00:00:00 2001 From: Md Afiq Iskandar Date: Tue, 15 Jul 2025 10:17:10 +0800 Subject: [PATCH] Add Documentation for Process Builder and CLAUDE Guidance - Introduced CLAUDE.md to provide comprehensive guidance for developers working with the codebase, including common development commands, architecture overview, and security considerations. - Added Process Builder Pages Analysis document detailing the implementation, features, and improvement opportunities for the process-builder section, including in-depth analysis of index.vue, manage.vue, and analytics pages. - Updated README.md to reflect the new documentation structure and enhance clarity on system capabilities and usage guidelines. - Removed outdated JSON files related to process definitions and variables to streamline the documentation and ensure relevance. - Enhanced overall documentation organization for better accessibility and understanding of the Corrad ProcessMaker platform. --- CLAUDE.md | 214 ++ docs/README.md | 348 ++- .../process-builder/currentDefiniton.json | 2195 ----------------- .../process-builder/fullProcessSettings.json | 1462 ----------- .../process-builder/processDefinition.json | 1686 +++++++++---- .../process-builder/processVariables.json | 341 ++- docs/process-builder-analysis.md | 338 +++ 7 files changed, 2144 insertions(+), 4440 deletions(-) create mode 100644 CLAUDE.md delete mode 100644 docs/json/process-builder/currentDefiniton.json delete mode 100644 docs/json/process-builder/fullProcessSettings.json create mode 100644 docs/process-builder-analysis.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..13c89d0 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,214 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Common Development Commands + +### Development Server +```bash +yarn dev # Start development server +yarn build # Build for production +yarn build:new # Build with pre/post-build scripts +yarn preview # Preview production build +yarn generate # Generate static site +``` + +### Database Operations +```bash +yarn prisma # Pull DB schema, generate client, and start dev server +npx prisma generate # Generate Prisma client only +npx prisma db pull # Pull database schema +npx prisma studio # Open Prisma Studio for database management +``` + +### Code Quality +```bash +npx eslint . # Run ESLint +npx prettier --write . # Format code with Prettier +``` + +## Architecture Overview + +### Technology Stack +- **Framework**: Nuxt 3 with Vue 3 Composition API +- **Database**: MySQL with Prisma ORM +- **State Management**: Pinia stores +- **UI Framework**: Tailwind CSS + Custom Rose UI components +- **Forms**: FormKit with custom extensions +- **Process Visualization**: Vue Flow for BPMN diagrams +- **Authentication**: JWT-based with custom middleware + +### Core System Components + +This is a **Business Process Management (BPM) platform** with two primary modules: + +#### 1. Process Builder (`/process-builder/`) +Visual BPMN workflow designer with three main pages: +- **index.vue**: Main process designer (drag-and-drop BPMN editor, ~40k tokens) +- **manage.vue**: Process management dashboard with metrics and CRUD operations +- **analytics/[id].vue**: Process analytics and journey visualization + +#### 2. Form Builder (`/form-builder/`) +Dynamic form creator with conditional logic, validation, and JavaScript API integration + +### State Management Architecture + +**Primary Stores:** +- `processBuilder.js`: Process design, node management, auto-save, history tracking +- `formBuilder.js`: Form components, validation, custom scripts, preview data +- `variableStore.js`: Global process variables and data flow management +- `user.js`: Authentication and user session management + +**Store Patterns:** +- All stores use Pinia with persistence +- Reactive state updates trigger UI changes automatically +- Centralized error handling and loading states +- Auto-save functionality prevents data loss + +### Database Schema (Prisma) + +**Core Entities:** +- `process`: BPMN process definitions with JSON schema, versioning, and templates +- `form`: Dynamic form configurations with custom scripts and validation +- `caseInstance`: Process execution instances with status tracking +- `task`: User tasks within process cases +- `user/role/userrole`: Authentication and RBAC system + +**Key Relationships:** +- Forms can be embedded in process tasks +- Process variables flow between forms and process nodes +- Complete audit trail through `processHistory` and `formHistory` +- Case timeline tracking for process execution monitoring + +### Component Architecture + +**Process Flow Components (`/components/process-flow/`):** +- `ProcessFlowCanvas.vue`: Main BPMN editor using Vue Flow +- `ProcessBuilderComponents.vue`: Draggable component palette +- Node Configuration Modals: Specialized modals for each BPMN node type +- `VariableManager.vue`: Process variable management interface + +**Form Components (`/components/formkit/`):** +- Custom FormKit inputs with enhanced functionality +- Conditional logic engine for dynamic field visibility +- JavaScript API integration for real-time calculations + +**Rose UI Components (`/components/rs-*/`):** +- Custom design system components (buttons, modals, cards, etc.) +- Consistent styling and behavior across the application + +### API Architecture (`/server/api/`) + +**RESTful Structure:** +- `/api/forms/`: CRUD operations for forms with history tracking +- `/api/process/`: Process management, publishing, execution +- `/api/tasks/`: Task assignment and completion +- `/api/devtool/`: Development utilities (ORM, code editor, etc.) + +**Special Endpoints:** +- Form field extraction: `/api/forms/[formId]/fields.get.js` +- Process analytics: `/api/process/dashboard/summary.get.js` +- Version management: `/api/forms/[id]/history.get.js` + +### Configuration Files (`/docs/json/`) + +**Critical System Configurations:** +- `formComponents.json`: Complete form structure for Malaysian Asnaf registration system +- `processDefinition.json`: BPMN process flow definitions with nodes and edges +- `processVariables.json`: 100+ process variables for data management +- `customScript.js`: Form conditional logic and field visibility rules + +These JSON files define a production Malaysian welfare application system with complex business rules. + +### Development Patterns + +**Vue 3 Composition API Usage:** +- Use `ref()` for primitive reactive data +- Use `shallowRef()` for large objects (like Vue Flow nodes) to avoid deep reactivity +- Implement proper cleanup in `onUnmounted()` for timers and event listeners +- Use `watch()` for complex reactive logic, `computed()` for derived state + +**State Management Patterns:** +- Store actions handle all business logic and API calls +- Components focus on presentation and user interaction +- Use store getters for computed values across components +- Implement optimistic updates with error rollback + +**Form Builder Patterns:** +- FormKit schema generation from component configurations +- Conditional logic engine evaluates field visibility in real-time +- JavaScript API provides hooks for custom calculations and validations +- Custom script execution sandbox for security + +**Process Builder Patterns:** +- Vue Flow integration for professional BPMN rendering +- Node configuration through specialized modal components +- Auto-save with debouncing to prevent data loss +- History tracking for undo/redo functionality + +### Security Considerations + +**Authentication:** +- JWT tokens with refresh mechanism +- Role-based access control (RBAC) through `user/role/userrole` models +- Route-level middleware protection + +**Data Security:** +- XSS protection disabled for specific API routes (devtool, forms) +- Rate limiting: 200 requests per minute +- Input validation through FormKit and Prisma +- SQL injection protection through Prisma ORM + +**Script Execution:** +- Form custom scripts run in 'safe' mode by default +- Script execution sandbox prevents direct DOM access +- Advanced mode available for power users with additional permissions + +### Key Implementation Details + +**Auto-save System:** +- Debounced saves every 2 seconds after changes +- Unsaved changes protection with navigation guards +- Visual indicators for save status + +**Process Execution:** +- BPMN-compliant process engine +- Task assignment and routing based on process definition +- Variable management throughout process lifecycle +- Integration points for external APIs and services + +**Form System:** +- Dynamic component rendering from JSON schema +- Real-time validation and conditional logic +- Preview mode for form testing +- Import/export functionality for form templates + +**Performance Optimizations:** +- Lazy loading for heavy components (modals, editors) +- Virtual scrolling for large lists +- Optimized API calls with loading states +- Bundle splitting for reduced initial load times + +### Development Tips + +**Working with Large Files:** +- `pages/process-builder/index.vue` is ~40k tokens - consider code splitting +- Use component lazy loading for modal components +- Implement proper loading states for better UX + +**Database Changes:** +- Always run `npx prisma generate` after schema changes +- Use migrations for production database updates +- Test with realistic data volumes + +**Testing Process Flows:** +- Use the process management dashboard for testing +- Create test cases in `/execution/` interface +- Monitor variables through the Variable Manager + +**Custom Scripts:** +- Test in 'safe' mode first before enabling 'advanced' mode +- Use the JavaScript API documentation for available functions +- Implement proper error handling for custom scripts + +This codebase represents a sophisticated, production-ready BPM platform with comprehensive process design, form building, and execution capabilities. \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 85a7db2..1bb55eb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,95 +1,295 @@ # Corrad ProcessMaker Documentation -Welcome to the Corrad ProcessMaker documentation. This repository contains comprehensive guides and technical documentation for developers and users of the Corrad ProcessMaker platform. +This documentation provides a comprehensive overview of the Corrad ProcessMaker system, its features, architecture, and usage guidelines. -## Documentation Structure +## System Overview -The documentation is organized into the following sections: +Corrad ProcessMaker is a sophisticated business process management (BPM) platform built with modern web technologies. It enables organizations to design, automate, and manage complex business workflows with an intuitive drag-and-drop interface. The system follows BPMN (Business Process Model and Notation) standards to create executable business processes. -### Overview -- [Project Overview](./overview/PROJECT_OVERVIEW.md) - Introduction to the system and its capabilities -- [Architecture](./overview/ARCHITECTURE.md) - Technical architecture of the system -- [Development Guide](./overview/DEVELOPMENT_GUIDE.md) - Guide for new developers +### Core Purpose -### Process Builder -- [User Guide](./process-builder/USER_GUIDE.md) - How to use the Process Builder -- [Technical Guide](./process-builder/TECHNICAL_GUIDE.md) - Technical details of the Process Builder implementation -- [Roadmap](./process-builder/ROADMAP.md) - Planned improvements for the Process Builder +The platform serves as a complete solution for: +- **Process Automation**: Streamline business workflows with visual process design +- **Form Management**: Create dynamic, interactive forms with conditional logic +- **Data Collection**: Gather and process structured data through forms and APIs +- **Workflow Execution**: Run automated processes with user tasks and decision points +- **Documentation Management**: Handle document uploads, verification, and processing -### Form Builder -- [User Guide](./form-builder/USER_GUIDE.md) - How to use the Form Builder -- [Technical Guide](./form-builder/TECHNICAL_GUIDE.md) - Technical details of the Form Builder implementation -- [JavaScript API Reference](./form-builder/JAVASCRIPT_API.md) - Complete JavaScript API for dynamic forms and calculations -- [Grid System Guide](./form-builder/grid-system.md) - Visual grid system and layout documentation -- [Roadmap](./form-builder/ROADMAP.md) - Development roadmap and missing essential features checklist +## Key Features -### Process Execution -- [User Guide](./process-execution/USER_GUIDE.md) - How to use the Process Execution interface -- [Technical Guide](./process-execution/TECHNICAL_GUIDE.md) - Technical details of the Process Execution implementation +### 1. Visual Process Builder +- **Drag-and-Drop Interface**: Intuitive process design with BPMN-compliant elements +- **Node Types**: Start/End events, User Tasks, Service Tasks, Gateways, and Sub-processes +- **Flow Control**: Conditional branching, parallel execution, and loop handling +- **Integration Points**: API calls, script execution, and external service connections -## Getting Started +### 2. Dynamic Form Builder +- **Component Library**: Comprehensive set of form components (text, select, radio, checkbox, date, file upload) +- **Conditional Logic**: Show/hide fields based on user input with visual condition builder +- **Validation Rules**: Built-in and custom validation with real-time feedback +- **Multi-step Forms**: Wizard-style forms with progress tracking +- **Responsive Design**: Mobile-friendly forms that adapt to different screen sizes -New to the project? We recommend reading the documentation in this order: +### 3. Process Execution Engine +- **Task Management**: Assign and track user tasks with role-based access +- **Variable Management**: Handle data flow throughout the process lifecycle +- **API Integration**: Connect with external services and databases +- **Notification System**: Automated alerts and status updates +- **Audit Trail**: Complete logging of process execution and user actions -1. [Project Overview](./overview/PROJECT_OVERVIEW.md) - Understand what the system does -2. [Development Guide](./overview/DEVELOPMENT_GUIDE.md) - Learn how to set up your development environment -3. [Architecture](./overview/ARCHITECTURE.md) - Understand the technical architecture -4. User guides for components you'll be working with -5. Technical guides for deeper implementation details +### 4. Advanced Capabilities +- **JavaScript API**: Custom scripting for calculations and business logic +- **File Handling**: Secure document upload, storage, and verification +- **Role-based Security**: Granular permissions and access control +- **Process Templates**: Reusable process definitions and form templates +- **Analytics**: Process performance monitoring and reporting -## Contributing to Documentation +## Architecture -When contributing to this documentation: +### Technology Stack +- **Frontend**: Nuxt 3, Vue 3, TypeScript +- **Backend**: Node.js with Nitro server +- **Database**: MySQL/MariaDB with Prisma ORM +- **UI Framework**: Tailwind CSS with custom Rose UI components +- **Form Engine**: FormKit with custom extensions +- **Process Visualization**: Vue Flow for BPMN diagram rendering +- **State Management**: Pinia for reactive state handling -1. Keep the structure organized and logical -2. Update cross-references when moving or renaming files -3. Ensure code examples are up-to-date -4. Include diagrams where helpful -5. Keep the language clear and concise +### System Components -## Contact +#### Frontend Architecture +``` +├── components/ # Reusable Vue components +│ ├── process-flow/ # Process builder components +│ ├── formkit/ # Custom form components +│ └── rs-*/ # Rose UI component library +├── pages/ # Application routes and views +│ ├── process-builder/ # Process design interface +│ ├── form-builder/ # Form design interface +│ └── execution/ # Process execution views +├── stores/ # Pinia state management +├── composables/ # Reusable composition functions +└── plugins/ # Vue/Nuxt plugins +``` -If you have questions about this documentation or need help with the system, please contact the development team. +#### Backend Architecture +``` +├── server/ # API endpoints and server logic +│ ├── api/ # REST API routes +│ ├── middleware/ # Server middleware +│ └── utils/ # Utility functions +├── prisma/ # Database schema and migrations +└── docs/ # Configuration and documentation +``` -Last updated: December 2024 +## Configuration Files in docs/ Folder -## Recent Updates +The `docs/` folder contains critical configuration files that define the system's behavior: -### December 2024 - Major Process Builder Enhancements -- **Enhanced Form Node Configuration**: Complete redesign of form task configuration with step-by-step workflow -- **Input/Output Mappings**: Bidirectional data flow between process variables and form fields -- **Field Conditions**: Dynamic field behavior based on process variables (readonly, hidden, required states) -- **4-Point Connection System**: All nodes now have 4 connection points (top, bottom, left, right) to prevent edge overlaps -- **Improved Visual Design**: Better handle styling with hover effects and connection state feedback -- **Auto-Save Mechanism**: Reliable data persistence for form configurations and mappings -- **Variable Integration**: Seamless integration with process variables for form pre-filling and data capture -- **Conditional Logic**: Support for complex field conditions with multiple operators and actions -- **Process Settings Management**: Comprehensive process configuration with 5 organized tabs: - - **Process Info**: Name, description, priority, category, ownership management - - **Execution Settings**: Process type, timeouts, parallel execution, error recovery - - **Variables & Data**: Data persistence policies, logging, encryption, retention controls - - **Permissions**: Role-based access control, execution permissions, approval workflows - - **JSON Export**: Complete configuration export with metadata for API integration -- **Advanced Configuration Options**: Professional-grade settings comparable to enterprise BPM platforms -- **Enhanced State Management**: Improved process store with settings persistence and history tracking +### Form Configuration (`docs/json/form/`) -### December 2024 - Process Builder Critical Fixes & Database Integration -- **Database Integration**: Complete API system with REST endpoints for all process operations -- **URL Parameter Support**: Direct process linking via `/process-builder?id={uuid}` pattern -- **Save Functionality**: Enhanced with success/error messages and proper state management -- **Navigation Improvements**: Fixed unsaved changes detection and automatic URL synchronization -- **Connection Dragging Fix**: Resolved Vue Flow interference preventing connector dragging -- **Backward Compatibility**: Legacy process definitions with embedded nodes automatically upgraded -- **Toast Notifications**: Comprehensive user feedback system for all operations -- **Performance Optimizations**: Reduced re-renders and improved memory management -- **Error Handling**: Robust validation and graceful error recovery throughout system -- **UI Consistency**: Updated form builder management to match process builder design patterns +#### formComponents.json +Contains the complete form structure definition for the Malaysian Asnaf (welfare recipient) registration system. This configuration includes: -### December 2024 - Major Form Builder Enhancements -- **JavaScript Execution Engine**: Added FormScriptEngine component for real-time calculations -- **Dynamic Field Updates**: Implemented onFieldChange and onLoad event handlers -- **Real-time Calculations**: Forms now support live mathematical calculations and field dependencies -- **Enhanced Debugging**: Comprehensive logging and error handling for JavaScript execution -- **API Documentation**: Complete JavaScript API reference with practical examples -- **Performance Optimizations**: Improved change detection and memory management -- **Security Enhancements**: Sandboxed JavaScript execution with input validation \ No newline at end of file +- **Section A**: Personal information collection (name, ID type, citizenship, gender, race, education) +- **Section B**: Dependent information and family details +- **Banking Information**: Account details for payment processing +- **Educational Background**: School and institution information +- **Conditional Logic**: Field visibility rules based on user selections + +Key features demonstrated: +- Multi-language support (Bahasa Malaysia) +- Complex conditional field display logic +- Validation rules for required fields +- Grid-based responsive layout +- Structured data collection for government processes + +#### customScript.js +JavaScript code that implements dynamic form behavior: +- Field visibility control based on user selections +- Real-time conditional logic execution +- Form validation and data manipulation +- Integration with the FormKit JavaScript API + +### Process Configuration (`docs/json/process-builder/`) + +#### processDefinition.json +Defines the complete business process workflow structure including: +- **Process Nodes**: Forms, API calls, scripts, decision points +- **Edge Connections**: Flow between process steps +- **Data Mapping**: Variable assignments between steps +- **Conditional Routing**: Business rules for process flow + +#### processVariables.json +Comprehensive variable definitions used throughout the process: +- **Form Data Variables**: User input from forms +- **API Response Variables**: Data from external service calls +- **Calculation Variables**: Computed values (e.g., Had Kifayah calculations) +- **Status Variables**: Process state and flow control +- **Configuration Variables**: System settings and constants + +Key variable categories: +- Applicant personal information +- Financial data and calculations +- Document verification status +- Process flow control variables +- Error handling and notifications + +## How to Use the System + +### For Process Designers + +1. **Creating a New Process** + - Navigate to Process Builder + - Drag nodes from the component palette + - Connect nodes with flow arrows + - Configure each node's properties + - Set up variables and data mapping + +2. **Designing Forms** + - Access Form Builder interface + - Drag form components onto the canvas + - Configure field properties and validation + - Set up conditional logic rules + - Preview and test the form + +3. **Process Deployment** + - Test process flows in development mode + - Validate all connections and configurations + - Deploy to production environment + - Monitor process execution + +### For End Users + +1. **Starting a Process** + - Access the process from the execution interface + - Complete required forms step by step + - Upload necessary documents + - Submit for processing + +2. **Task Management** + - View assigned tasks in inbox + - Complete user tasks as they become available + - Track process progress + - Receive notifications on status changes + +### For Administrators + +1. **System Configuration** + - Manage user roles and permissions + - Configure API endpoints and integrations + - Set up notification templates + - Monitor system performance + +2. **Process Management** + - Monitor active process instances + - Handle exceptions and errors + - Generate reports and analytics + - Maintain process templates + +## Use Cases + +### Malaysian Asnaf Registration System +The current configuration demonstrates a comprehensive welfare application system: + +- **Multi-step Application Process**: Guided user journey through application stages +- **Family Information Collection**: Detailed dependent and household member data +- **Financial Assessment**: Had Kifayah (poverty line) calculations +- **Document Verification**: Upload and validation of supporting documents +- **Decision Processing**: Automated eligibility determination +- **Approval Workflow**: Multi-level review and approval process + +### General Business Processes +The platform supports various business scenarios: + +- **Employee Onboarding**: HR processes with document collection and approvals +- **Purchase Requests**: Procurement workflows with budget approvals +- **Customer Service**: Ticket management and resolution processes +- **Compliance Reporting**: Regulatory submission and review processes +- **Project Management**: Task assignment and milestone tracking + +## Integration Capabilities + +### API Integration +- REST API endpoints for external system integration +- Real-time data synchronization +- Webhook support for event-driven processes +- Custom authentication and authorization + +### Database Connectivity +- Multiple database support through Prisma ORM +- Data migration and schema management +- Query optimization and caching +- Backup and recovery procedures + +### Third-party Services +- Email and SMS notification services +- Document storage and management systems +- Payment gateway integration +- Identity verification services + +## Security Features + +### Authentication & Authorization +- Multi-factor authentication support +- Role-based access control (RBAC) +- Session management and timeout +- API key management + +### Data Protection +- Encryption at rest and in transit +- PII (Personally Identifiable Information) protection +- Audit logging and compliance +- GDPR and data privacy compliance + +### Process Security +- Secure document handling +- Input validation and sanitization +- XSS and injection attack prevention +- Secure API communications + +## Development Guidelines + +### Code Structure +- Follow Vue 3 Composition API patterns +- Use TypeScript for type safety +- Implement component-based architecture +- Maintain clear separation of concerns + +### Best Practices +- Write comprehensive tests for business logic +- Document API endpoints and data models +- Follow consistent naming conventions +- Implement proper error handling + +### Configuration Management +- Use environment variables for sensitive data +- Maintain separate configurations for different environments +- Version control all configuration changes +- Document configuration dependencies + +## Support and Maintenance + +### System Monitoring +- Real-time performance monitoring +- Error tracking and alerting +- Process execution analytics +- User activity monitoring + +### Backup and Recovery +- Automated database backups +- Process definition versioning +- Configuration backup procedures +- Disaster recovery planning + +### Updates and Upgrades +- Regular security updates +- Feature enhancement releases +- Database migration procedures +- Backward compatibility maintenance + +## Conclusion + +Corrad ProcessMaker provides a comprehensive solution for business process automation with its powerful visual design tools, dynamic form capabilities, and robust execution engine. The system's modular architecture and extensive configuration options make it suitable for a wide range of business applications, from simple approval workflows to complex multi-stage processes like the Malaysian Asnaf registration system demonstrated in this documentation. + +The platform's strength lies in its ability to handle complex business logic while maintaining an intuitive user interface for both process designers and end users. With proper configuration and customization, it can adapt to virtually any business process automation requirement. \ No newline at end of file diff --git a/docs/json/process-builder/currentDefiniton.json b/docs/json/process-builder/currentDefiniton.json deleted file mode 100644 index 1d1562d..0000000 --- a/docs/json/process-builder/currentDefiniton.json +++ /dev/null @@ -1,2195 +0,0 @@ -{ - "edges": [ - { - "id": "start-1751870920411-form-1752471000000-1752110219601", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "start-1751870920411", - "target": "form-1752471000000", - "animated": true, - "sourceHandle": "start-1751870920411-right", - "targetHandle": "form-1752471000000-left" - }, - { - "id": "form-1752471000000-api-1752471000010-1752110221444", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "form-1752471000000", - "target": "api-1752471000010", - "animated": true, - "sourceHandle": "form-1752471000000-bottom", - "targetHandle": "api-1752471000010-top" - }, - { - "id": "api-1752471000010-script-1752471000020-1752110222889", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "api-1752471000010", - "target": "script-1752471000020", - "animated": true, - "sourceHandle": "api-1752471000010-right", - "targetHandle": "script-1752471000020-left" - }, - { - "id": "script-1752471000020-form-1751870928350-1752110513125", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "script-1752471000020", - "target": "form-1751870928350", - "animated": true, - "sourceHandle": "script-1752471000020-right", - "targetHandle": "form-1751870928350-left" - }, - { - "id": "form-1751870928350-api-1751871528249-1752110547688", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "form-1751870928350", - "target": "api-1751871528249", - "animated": true, - "sourceHandle": "form-1751870928350-bottom", - "targetHandle": "api-1751871528249-top" - }, - { - "id": "api-1751871528249-script-1751871635000-1752110661170", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "api-1751871528249", - "target": "script-1751871635000", - "animated": true, - "sourceHandle": "api-1751871528249-right", - "targetHandle": "script-1751871635000-left" - }, - { - "id": "start-1751870920411-form-1753000000000-1752115210580", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "start-1751870920411", - "target": "form-1753000000000", - "animated": true, - "sourceHandle": "start-1751870920411-right", - "targetHandle": "form-1753000000000-left" - }, - { - "id": "form-1753000000000-api-1753000000001-1752115217959", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "form-1753000000000", - "target": "api-1753000000001", - "animated": true, - "sourceHandle": "form-1753000000000-bottom", - "targetHandle": "api-1753000000001-top" - }, - { - "id": "api-1753000000001-script-1753000000002-1752115222952", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "api-1753000000001", - "target": "script-1753000000002", - "animated": true, - "sourceHandle": "api-1753000000001-right", - "targetHandle": "script-1753000000002-left" - }, - { - "id": "script-1753000000002-gateway-1753100000000-1752202680793", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "script-1753000000002", - "target": "gateway-1753100000000", - "animated": true, - "sourceHandle": "script-1753000000002-right", - "targetHandle": "gateway-1753100000000-left" - }, - { - "id": "gateway-1753100000000-form-1751870928350-1752202820616", - "data": {}, - "type": "smoothstep", - "label": "Tidak", - "source": "gateway-1753100000000", - "target": "form-1751870928350", - "animated": true, - "sourceHandle": "gateway-1753100000000-right", - "targetHandle": "form-1751870928350-left" - }, - { - "id": "form-1753100000001-gateway-1753100000002-1752202841767", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "form-1753100000001", - "target": "gateway-1753100000002", - "animated": true, - "sourceHandle": "form-1753100000001-right", - "targetHandle": "gateway-1753100000002-left" - }, - { - "id": "gateway-1753100000002-subprocess-1753100000003-1752202973206", - "data": {}, - "type": "smoothstep", - "label": "Ya", - "source": "gateway-1753100000002", - "target": "subprocess-1753100000003", - "animated": true, - "sourceHandle": "gateway-1753100000002-right", - "targetHandle": "subprocess-1753100000003-left" - }, - { - "id": "gateway-1753100000000-form-1753100000001-1752203198190", - "data": {}, - "type": "smoothstep", - "label": "Ya", - "source": "gateway-1753100000000", - "target": "form-1753100000001", - "animated": true, - "sourceHandle": "gateway-1753100000000-right", - "targetHandle": "form-1753100000001-top" - }, - { - "id": "script-1751871635000-form-family-tree-choice-1752204006162", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "script-1751871635000", - "target": "form-family-tree-choice", - "animated": true, - "sourceHandle": "script-1751871635000-right", - "targetHandle": "form-family-tree-choice-left" - }, - { - "id": "form-family-tree-choice-gateway-family-tree-choice-1752204014461", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "form-family-tree-choice", - "target": "gateway-family-tree-choice", - "animated": true, - "sourceHandle": "form-family-tree-choice-bottom", - "targetHandle": "gateway-family-tree-choice-left" - }, - { - "id": "gateway-family-tree-choice-api-1752114771983-1752204050925", - "data": {}, - "type": "smoothstep", - "label": "Ya", - "source": "gateway-family-tree-choice", - "target": "api-1752114771983", - "animated": true, - "sourceHandle": "gateway-family-tree-choice-right", - "targetHandle": "api-1752114771983-left" - }, - { - "id": "api-1752114771983-html-1752109761532-1752204167660", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "api-1752114771983", - "target": "html-1752109761532", - "animated": true, - "sourceHandle": "api-1752114771983-bottom", - "targetHandle": "html-1752109761532-left" - }, - { - "id": "gateway-family-tree-choice-form-kategori-asnaf-1752204312974", - "data": {}, - "type": "smoothstep", - "label": "Tidak", - "source": "gateway-family-tree-choice", - "target": "form-kategori-asnaf", - "animated": true, - "sourceHandle": "gateway-family-tree-choice-right", - "targetHandle": "form-kategori-asnaf-top" - }, - { - "id": "form-kategori-asnaf-gateway-fakir-miskin-choice-1752204332412", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "form-kategori-asnaf", - "target": "gateway-fakir-miskin-choice", - "animated": true, - "sourceHandle": "form-kategori-asnaf-bottom", - "targetHandle": "gateway-fakir-miskin-choice-left" - }, - { - "id": "gateway-1753100000002-subprocess-1752202751327-1752204374213", - "data": {}, - "type": "smoothstep", - "label": "Tidak", - "source": "gateway-1753100000002", - "target": "subprocess-1752202751327", - "animated": true, - "sourceHandle": "gateway-1753100000002-right", - "targetHandle": "subprocess-1752202751327-left" - }, - { - "id": "gateway-fakir-miskin-choice-business-rule-1751871900000-1752204422657", - "data": {}, - "type": "smoothstep", - "label": "Ya", - "source": "gateway-fakir-miskin-choice", - "target": "business-rule-1751871900000", - "animated": true, - "sourceHandle": "gateway-fakir-miskin-choice-right", - "targetHandle": "business-rule-1751871900000-left" - }, - { - "id": "business-rule-1751871900000-business-rule-1751871901000-1752206876221", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "business-rule-1751871900000", - "target": "business-rule-1751871901000", - "animated": true, - "sourceHandle": "business-rule-1751871900000-bottom", - "targetHandle": "business-rule-1751871901000-top" - }, - { - "id": "business-rule-1751871901000-notification-1753200000002-1752207615091", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "business-rule-1751871901000", - "target": "notification-1753200000002", - "animated": true, - "sourceHandle": "business-rule-1751871901000-right", - "targetHandle": "notification-1753200000002-top" - }, - { - "id": "business-rule-1751871901000-form-pengesahan-1752207621840", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "business-rule-1751871901000", - "target": "form-pengesahan", - "animated": true, - "sourceHandle": "business-rule-1751871901000-bottom", - "targetHandle": "form-pengesahan-top" - }, - { - "id": "api-pengesahan-submit-form-pengesahan-1752208003574", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "api-pengesahan-submit", - "target": "form-pengesahan", - "animated": true, - "sourceHandle": "api-pengesahan-submit-right", - "targetHandle": "form-pengesahan-left" - }, - { - "id": "script-process-pengesahan-api-pengesahan-submit-1752208004921", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "script-process-pengesahan", - "target": "api-pengesahan-submit", - "animated": true, - "sourceHandle": "script-process-pengesahan-bottom", - "targetHandle": "api-pengesahan-submit-top" - }, - { - "id": "gateway-status-check-subprocess-1752202751327-berjaya-fm", - "data": {}, - "type": "smoothstep", - "label": "Berjaya FM", - "source": "gateway-status-check", - "target": "subprocess-1752202751327", - "animated": true, - "sourceHandle": "gateway-status-check-right", - "targetHandle": "subprocess-1752202751327-left" - }, - { - "id": "gateway-status-check-notification-1753200000002-berjaya-miskin", - "data": {}, - "type": "smoothstep", - "label": "Berjaya Miskin", - "source": "gateway-status-check", - "target": "notification-1753200000002", - "animated": true, - "sourceHandle": "gateway-status-check-bottom", - "targetHandle": "notification-1753200000002-left" - }, - { - "id": "gateway-status-check-notification-1753200000002-berjaya-non-fm", - "data": {}, - "type": "smoothstep", - "label": "Berjaya Non-FM", - "source": "gateway-status-check", - "target": "notification-1753200000002", - "animated": true, - "sourceHandle": "gateway-status-check-top", - "targetHandle": "notification-1753200000002-left" - }, - { - "id": "gateway-status-check-notification-1753200000002-gagal", - "data": {}, - "type": "smoothstep", - "label": "Gagal", - "source": "gateway-status-check", - "target": "notification-1753200000002", - "animated": true, - "sourceHandle": "gateway-status-check-left", - "targetHandle": "notification-1753200000002-left" - }, - { - "id": "script-process-pengesahan-gateway-status-check-1752208100000", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "script-process-pengesahan", - "target": "gateway-status-check", - "animated": true, - "sourceHandle": "script-process-pengesahan-right", - "targetHandle": "gateway-status-check-left" - } - ], - "nodes": [ - { - "id": "gateway-family-tree-choice", - "data": { - "label": "Lihat Family Tree?", - "shape": "diamond", - "textColor": "#374151", - "conditions": [ - { - "id": "condition-group-ya-path", - "output": "Ya", - "conditions": [ - { - "id": "condition-1", - "value": "ya", - "operator": "eq", - "variable": "lihatFamilyTree", - "valueType": "string", - "logicalOperator": "and" - } - ] - }, - { - "id": "condition-group-tidak-path", - "output": "Tidak", - "conditions": [ - { - "id": "condition-2", - "value": "tidak", - "operator": "eq", - "variable": "lihatFamilyTree", - "valueType": "string", - "logicalOperator": "and" - } - ] - } - ], - "borderColor": "#6b7280", - "defaultPath": "gateway-fakir-miskin-choice", - "description": "Choose whether to view family tree", - "gatewayType": "exclusive", - "backgroundColor": "#f9fafb" - }, - "type": "gateway", - "label": "Lihat Family Tree?", - "position": { "x": 2070, "y": -345 } - }, - { - "id": "form-family-tree-choice", - "data": { - "label": "Pilihan Family Tree", - "formId": 6, - "formName": "Pilihan Family Tree", - "formUuid": "6e07fc8f-a160-478a-85fd-fa3364401547", - "description": "Form untuk memilih sama ada mahu lihat family tree atau tidak", - "assignedRoles": [], - "assignedUsers": [], - "inputMappings": [ - { "formField": "nama_pemohon", "processVariable": "applicantName" } - ], - "assignmentType": "public", - "outputMappings": [ - { - "formField": "lihat_family_tree", - "processVariable": "lihatFamilyTree" - } - ], - "fieldConditions": [] - }, - "type": "form", - "label": "Pilihan Family Tree", - "position": { "x": 2040, "y": -540 } - }, - { - "id": "gateway-fakir-miskin-choice", - "data": { - "label": "Fakir Miskin?", - "shape": "diamond", - "textColor": "#333333", - "conditions": [ - { - "id": "condition-group-ya-path", - "output": "Ya", - "conditions": [ - { - "id": "condition-1", - "value": "fakir_miskin", - "operator": "eq", - "variable": "kategoriAsnaf", - "valueType": "string", - "logicalOperator": "and" - } - ] - }, - { - "id": "condition-group-tidak-path", - "output": "Tidak", - "conditions": [ - { - "id": "condition-2", - "value": "bukan_fakir_miskin", - "operator": "eq", - "variable": "kategoriAsnaf", - "valueType": "string", - "logicalOperator": "and" - } - ] - } - ], - "borderColor": "#6b7280", - "defaultPath": "business-rule-1751871900000", - "description": "Determine if applicant is Fakir Miskin", - "gatewayType": "exclusive", - "backgroundColor": "#f9fafb" - }, - "type": "gateway", - "label": "Fakir Miskin?", - "position": { "x": 2085, "y": 210 } - }, - { - "id": "form-kategori-asnaf", - "data": { - "label": "Pilihan Kategori Asnaf", - "formId": 7, - "formName": "Pilihan Kategori Asnaf", - "formUuid": "7e07fc8f-a160-478a-85fd-fa3364401548", - "description": "Form untuk memilih kategori asnaf", - "assignedRoles": [], - "assignedUsers": [], - "inputMappings": [ - { "formField": "nama_pemohon", "processVariable": "applicantName" } - ], - "assignmentType": "public", - "outputMappings": [ - { "formField": "kategori_asnaf", "processVariable": "kategoriAsnaf" } - ], - "fieldConditions": [] - }, - "type": "form", - "label": "Pilihan Kategori Asnaf", - "position": { "x": 2055, "y": -30 } - }, - { - "id": "start-1751870920411", - "data": { "label": "Start", "description": "Process start point" }, - "type": "start", - "label": "Start", - "position": { "x": -75, "y": -510 } - }, - { - "id": "form-1752471000000", - "data": { - "label": "Penilaian Awal", - "formId": 3, - "formName": "Penilaian Awal", - "formUuid": "8e07fc8f-a160-478a-85fd-fa3364401544", - "description": "Form: Penilaian Awal untuk permohonan bantuan", - "assignedRoles": [], - "assignedUsers": [], - "inputMappings": [], - "assignmentType": "public", - "outputMappings": [ - { - "formField": "komitmen_pembiayaan", - "processVariable": "komitmenKosTinggi" - }, - { - "formField": "keperluan_mendesak", - "processVariable": "keperluanMendesak" - }, - { - "formField": "keperluan_lain_nyatakan", - "processVariable": "keperluanLainNyatakan" - }, - { - "formField": "dokumen_berkaitan", - "processVariable": "dokumenBerkaitan" - }, - { - "formField": "catatan_tambahan", - "processVariable": "catatanTambahan" - } - ], - "fieldConditions": [], - "assignmentVariable": "", - "assignmentVariableType": "user_id" - }, - "type": "form", - "label": "Penilaian Awal", - "position": { "x": 435, "y": -540 } - }, - { - "id": "api-1752471000010", - "data": { - "label": "Submit Penilaian Awal API", - "apiUrl": "https://jsonplaceholder.typicode.com/posts", - "headers": "{ \"Content-Type\": \"application/json\" }", - "apiMethod": "POST", - "description": "Submit penilaian awal data to external system", - "requestBody": "{\n \"komitmenKosTinggi\": \"{komitmenKosTinggi}\",\n \"keperluanMendesak\": \"{keperluanMendesak}\",\n \"keperluanLainNyatakan\": \"{keperluanLainNyatakan}\",\n \"dokumenBerkaitan\": \"{dokumenBerkaitan}\",\n \"catatanTambahan\": \"{catatanTambahan}\"\n}", - "errorVariable": "penilaianAwalApiError", - "outputVariable": "penilaianAwalApiResponse", - "continueOnError": false - }, - "type": "api", - "label": "Submit Penilaian Awal API", - "position": { "x": 435, "y": -345 } - }, - { - "id": "script-1752471000020", - "data": { - "label": "Process Penilaian Awal Response", - "scriptCode": "// Extract important data from Penilaian Awal API response\nconst apiData = processVariables.penilaianAwalApiResponse;\n\nif (apiData && apiData.data) {\n // Generate a reference number for the assessment\n processVariables.penilaianAwalId = apiData.data.id || 'PA-' + Date.now();\n \n // Process the high cost commitment answer\n processVariables.hasHighCostCommitment = processVariables.komitmenKosTinggi === 'ya';\n \n // Process urgent needs\n if (Array.isArray(processVariables.keperluanMendesak)) {\n // Set flags for specific urgent needs\n processVariables.hasUrgentMedicalNeed = processVariables.keperluanMendesak.includes('perubatan_kritikal');\n processVariables.hasDisasterNeed = processVariables.keperluanMendesak.includes('bencana');\n processVariables.hasDeathRelatedNeed = processVariables.keperluanMendesak.includes('kematian');\n processVariables.hasFamilyConflict = processVariables.keperluanMendesak.includes('konflik_keluarga');\n processVariables.hasHomelessness = processVariables.keperluanMendesak.includes('tiada_tempat_tinggal');\n processVariables.hasUtilityArrears = processVariables.keperluanMendesak.includes('tunggakan_utiliti');\n processVariables.hasOtherNeeds = processVariables.keperluanMendesak.includes('lain_lain');\n processVariables.hasNoUrgentNeeds = processVariables.keperluanMendesak.includes('tidak_mendesak');\n \n // Calculate urgency score based on selected needs\n let urgencyScore = 0;\n if (processVariables.hasUrgentMedicalNeed) urgencyScore += 5;\n if (processVariables.hasDisasterNeed) urgencyScore += 5;\n if (processVariables.hasDeathRelatedNeed) urgencyScore += 4;\n if (processVariables.hasFamilyConflict) urgencyScore += 3;\n if (processVariables.hasHomelessness) urgencyScore += 5;\n if (processVariables.hasUtilityArrears) urgencyScore += 2;\n if (processVariables.hasOtherNeeds) urgencyScore += 1;\n if (processVariables.hasNoUrgentNeeds) urgencyScore = 0;\n \n processVariables.urgencyScore = urgencyScore;\n processVariables.urgencyLevel = urgencyScore >= 5 ? 'high' : (urgencyScore >= 3 ? 'medium' : 'low');\n }\n \n // Check if documents were uploaded\n processVariables.hasUploadedDocuments = processVariables.dokumenBerkaitan && \n Array.isArray(processVariables.dokumenBerkaitan) && \n processVariables.dokumenBerkaitan.length > 0;\n \n // Set status for next step\n processVariables.penilaianAwalStatus = 'completed';\n processVariables.readyForPersonalInfo = true;\n \n console.log('Penilaian Awal processed successfully:', {\n penilaianAwalId: processVariables.penilaianAwalId,\n urgencyLevel: processVariables.urgencyLevel,\n urgencyScore: processVariables.urgencyScore,\n hasHighCostCommitment: processVariables.hasHighCostCommitment,\n hasUploadedDocuments: processVariables.hasUploadedDocuments\n });\n} else {\n // Handle API error case\n processVariables.penilaianAwalStatus = 'failed';\n processVariables.readyForPersonalInfo = false;\n processVariables.penilaianAwalError = 'Failed to submit penilaian awal';\n}", - "description": "Process the penilaian awal form data and API response", - "errorVariable": "penilaianAwalScriptError", - "inputVariables": [ - "penilaianAwalApiResponse", - "komitmenKosTinggi", - "keperluanMendesak", - "keperluanLainNyatakan", - "dokumenBerkaitan", - "catatanTambahan" - ], - "scriptLanguage": "javascript", - "continueOnError": false, - "outputVariables": [ - { - "name": "penilaianAwalId", - "type": "string", - "description": "Generated ID for the initial assessment" - }, - { - "name": "hasHighCostCommitment", - "type": "boolean", - "description": "Whether applicant has high cost commitments" - }, - { - "name": "urgencyScore", - "type": "number", - "description": "Calculated urgency score based on needs" - }, - { - "name": "urgencyLevel", - "type": "string", - "description": "Urgency level (high/medium/low)" - }, - { - "name": "hasUrgentMedicalNeed", - "type": "boolean", - "description": "Whether applicant has urgent medical needs" - }, - { - "name": "hasDisasterNeed", - "type": "boolean", - "description": "Whether applicant has disaster-related needs" - }, - { - "name": "hasDeathRelatedNeed", - "type": "boolean", - "description": "Whether applicant has death-related needs" - }, - { - "name": "hasFamilyConflict", - "type": "boolean", - "description": "Whether applicant has family conflict" - }, - { - "name": "hasHomelessness", - "type": "boolean", - "description": "Whether applicant is homeless" - }, - { - "name": "hasUtilityArrears", - "type": "boolean", - "description": "Whether applicant has utility arrears" - }, - { - "name": "hasOtherNeeds", - "type": "boolean", - "description": "Whether applicant has other needs" - }, - { - "name": "hasNoUrgentNeeds", - "type": "boolean", - "description": "Whether applicant has no urgent needs" - }, - { - "name": "hasUploadedDocuments", - "type": "boolean", - "description": "Whether documents were uploaded" - }, - { - "name": "penilaianAwalStatus", - "type": "string", - "description": "Status of initial assessment submission" - }, - { - "name": "readyForPersonalInfo", - "type": "boolean", - "description": "Whether ready for personal info form" - } - ] - }, - "type": "script", - "label": "Process Penilaian Awal Response", - "position": { "x": 780, "y": -345 } - }, - { - "id": "form-1751870928350", - "data": { - "label": "Borang Maklumat Peribadi", - "formId": 1, - "formName": "Borang Maklumat Peribadi", - "formUuid": "9f08fc8f-b170-478a-85fd-fa3364401533", - "description": "Form: Borang Maklumat Peribadi", - "assignedRoles": [], - "assignedUsers": [], - "inputMappings": [], - "assignmentType": "public", - "outputMappings": [ - { "formField": "text_3", "processVariable": "text3" }, - { "formField": "select_1", "processVariable": "select1" }, - { "formField": "form_jeniskp_1", "processVariable": "formJeniskp1" }, - { "formField": "form_jeniskp_2", "processVariable": "formJeniskp2" }, - { "formField": "form_jeniskp_3", "processVariable": "formJeniskp3" }, - { - "formField": "text_warganegara", - "processVariable": "textWarganegara" - }, - { "formField": "radio_jantina", "processVariable": "radioJantina" }, - { "formField": "radio_bangsa", "processVariable": "radioBangsa" }, - { "formField": "nyatakan_lain2", "processVariable": "nyatakanLain2" }, - { "formField": "radio_9_copy", "processVariable": "radio9Copy" }, - { - "formField": "radio_pendidikan", - "processVariable": "radioPendidikan" - }, - { "formField": "text_14", "processVariable": "text14" }, - { - "formField": "date_masukislam", - "processVariable": "dateMasukislam" - }, - { - "formField": "date_masukislam_copy", - "processVariable": "dateMasukislamCopy" - }, - { - "formField": "select_statusperkahwinan", - "processVariable": "selectStatusperkahwinan" - }, - { - "formField": "hubungan_keluarga", - "processVariable": "hubunganKeluarga" - }, - { - "formField": "hubungan_lain_nyatakan", - "processVariable": "hubunganLainNyatakan" - }, - { - "formField": "nama_tanggungan", - "processVariable": "namaTanggungan" - }, - { - "formField": "jenis_kad_tanggungan", - "processVariable": "jenisKadTanggungan" - }, - { - "formField": "no_pengenalan_tanggungan", - "processVariable": "noPengenalanTanggungan" - }, - { - "formField": "jantina_tanggungan", - "processVariable": "jantinaTanggungan" - }, - { - "formField": "tarikh_lahir_tanggungan", - "processVariable": "tarikhLahirTanggungan" - }, - { - "formField": "tempat_lahir_tanggungan", - "processVariable": "tempatLahirTanggungan" - }, - { - "formField": "bangsa_tanggungan", - "processVariable": "bangsaTanggungan" - }, - { - "formField": "bangsa_lain_tanggungan", - "processVariable": "bangsaLainTanggungan" - }, - { - "formField": "status_kahwin_tanggungan", - "processVariable": "statusKahwinTanggungan" - }, - { - "formField": "tarikh_masuk_islam_tanggungan", - "processVariable": "tarikhMasukIslamTanggungan" - }, - { - "formField": "tarikh_mula_kfam_tanggungan", - "processVariable": "tarikhMulaKfamTanggungan" - }, - { - "formField": "warganegara_tanggungan", - "processVariable": "warganegaraTanggungan" - }, - { - "formField": "tempat_menetap_tanggungan", - "processVariable": "tempatMenetapTanggungan" - }, - { - "formField": "no_telefon_tanggungan", - "processVariable": "noTelefonTanggungan" - }, - { - "formField": "nama_pemegang_akaun", - "processVariable": "namaPemegangAkaun" - }, - { "formField": "nama_bank", "processVariable": "namaBank" }, - { "formField": "no_akaun_bank", "processVariable": "noAkaunBank" }, - { - "formField": "cara_pembayaran", - "processVariable": "caraPembayaran" - }, - { "formField": "sebab_tunai", "processVariable": "sebabTunai" }, - { - "formField": "bersekolah_tanggungan", - "processVariable": "bersekolahTanggungan" - }, - { - "formField": "pendidikan_tertinggi_tanggungan", - "processVariable": "pendidikanTertinggiTanggungan" - }, - { - "formField": "pendidikan_lain_tanggungan", - "processVariable": "pendidikanLainTanggungan" - }, - { "formField": "nama_sekolah", "processVariable": "namaSekolah" }, - { "formField": "alamat_sekolah", "processVariable": "alamatSekolah" }, - { "formField": "daerah_sekolah", "processVariable": "daerahSekolah" }, - { "formField": "negeri_sekolah", "processVariable": "negeriSekolah" }, - { "formField": "poskod_sekolah", "processVariable": "poskodSekolah" }, - { - "formField": "tinggal_bersama_keluarga", - "processVariable": "tinggalBersamaKeluarga" - } - ], - "fieldConditions": [], - "assignmentVariable": "", - "assignmentVariableType": "user_id" - }, - "type": "form", - "label": "Borang Maklumat Peribadi", - "position": { "x": 1260, "y": -540 } - }, - { - "id": "api-1751871528249", - "data": { - "label": "Submit Profile API", - "apiUrl": "https://jsonplaceholder.typicode.com/posts", - "headers": "{ \"Content-Type\": \"application/json\" }", - "apiMethod": "POST", - "description": "Submit user profile to external system", - "requestBody": "{\n \"applicantName\": \"{text3}\",\n \"idType\": \"{select1}\",\n \"mykadNumber\": \"{formJeniskp1}\",\n \"passportNumber\": \"{formJeniskp2}\",\n \"birthCertNumber\": \"{formJeniskp3}\",\n \"nationality\": \"{textWarganegara}\",\n \"gender\": \"{radioJantina}\",\n \"race\": \"{radioBangsa}\",\n \"otherRace\": \"{nyatakanLain2}\",\n \"isStudying\": \"{radio9Copy}\",\n \"education\": \"{radioPendidikan}\",\n \"otherEducation\": \"{text14}\",\n \"islamConversionDate\": \"{dateMasukislam}\",\n \"kfamStartDate\": \"{dateMasukislamCopy}\",\n \"maritalStatus\": \"{selectStatusperkahwinan}\",\n \"dependentInfo\": {\n \"relationship\": \"{hubunganKeluarga}\",\n \"otherRelationship\": \"{hubunganLainNyatakan}\",\n \"name\": \"{namaTanggungan}\",\n \"idType\": \"{jenisKadTanggungan}\",\n \"idNumber\": \"{noPengenalanTanggungan}\",\n \"gender\": \"{jantinaTanggungan}\",\n \"birthDate\": \"{tarikhLahirTanggungan}\",\n \"birthPlace\": \"{tempatLahirTanggungan}\",\n \"race\": \"{bangsaTanggungan}\",\n \"otherRace\": \"{bangsaLainTanggungan}\",\n \"maritalStatus\": \"{statusKahwinTanggungan}\",\n \"islamConversionDate\": \"{tarikhMasukIslamTanggungan}\",\n \"kfamStartDate\": \"{tarikhMulaKfamTanggungan}\",\n \"nationality\": \"{warganegaraTanggungan}\",\n \"residenceDuration\": \"{tempatMenetapTanggungan}\",\n \"phoneNumber\": \"{noTelefonTanggungan}\",\n \"isStudying\": \"{bersekolahTanggungan}\",\n \"education\": \"{pendidikanTertinggiTanggungan}\",\n \"otherEducation\": \"{pendidikanLainTanggungan}\",\n \"schoolName\": \"{namaSekolah}\",\n \"schoolAddress\": \"{alamatSekolah}\",\n \"schoolDistrict\": \"{daerahSekolah}\",\n \"schoolState\": \"{negeriSekolah}\",\n \"schoolPostcode\": \"{poskodSekolah}\",\n \"liveWithFamily\": \"{tinggalBersamaKeluarga}\"\n },\n \"bankingInfo\": {\n \"accountHolderName\": \"{namaPemegangAkaun}\",\n \"bankName\": \"{namaBank}\",\n \"accountNumber\": \"{noAkaunBank}\",\n \"paymentMethod\": \"{caraPembayaran}\",\n \"cashReason\": \"{sebabTunai}\"\n }\n}", - "errorVariable": "apiError", - "outputVariable": "apiResponse", - "continueOnError": false - }, - "type": "api", - "label": "Submit Profile API", - "position": { "x": 1260, "y": -345 } - }, - { - "id": "script-1751871635000", - "data": { - "label": "Process API Response", - "scriptCode": "// Extract important data from API response\nconst apiData = processVariables.apiResponse;\n\nif (apiData && apiData.data) {\n // Extract application ID\n processVariables.applicationId = apiData.data.id || 'APP-' + Date.now();\n \n // Determine if documents are required based on profile\n processVariables.documentsRequired = true;\n \n // Set verification level based on education and other factors\n if (processVariables.radioPendidikan === 'ijazah' || processVariables.radioPendidikan === 'diploma') {\n processVariables.verificationLevel = 'enhanced';\n processVariables.documentsRequired = true;\n } else {\n processVariables.verificationLevel = 'standard';\n }\n \n // Extract applicant name for verification form\n processVariables.applicantName = processVariables.text3;\n \n // Process dependent information if available\n if (processVariables.namaTanggungan) {\n processVariables.hasDependents = true;\n processVariables.dependentCount = 1;\n processVariables.dependentName = processVariables.namaTanggungan;\n } else {\n processVariables.hasDependents = false;\n processVariables.dependentCount = 0;\n }\n \n // Process banking information\n if (processVariables.namaBank && processVariables.noAkaunBank) {\n processVariables.hasBankingInfo = true;\n processVariables.paymentReady = true;\n } else {\n processVariables.hasBankingInfo = false;\n processVariables.paymentReady = false;\n }\n \n // Set status for next step\n processVariables.profileSubmissionStatus = 'success';\n processVariables.nextStepReady = true;\n \n console.log('Profile processed successfully:', {\n applicationId: processVariables.applicationId,\n verificationLevel: processVariables.verificationLevel,\n documentsRequired: processVariables.documentsRequired,\n hasDependents: processVariables.hasDependents,\n hasBankingInfo: processVariables.hasBankingInfo\n });\n} else {\n // Handle API error case\n processVariables.profileSubmissionStatus = 'failed';\n processVariables.nextStepReady = false;\n processVariables.errorMessage = 'Failed to submit profile';\n}", - "description": "Transform API response for document verification step", - "errorVariable": "scriptError", - "inputVariables": [ - "apiResponse", - "text3", - "radioPendidikan", - "namaTanggungan", - "namaBank", - "noAkaunBank" - ], - "scriptLanguage": "javascript", - "continueOnError": false, - "outputVariables": [ - { - "name": "applicationId", - "type": "string", - "description": "Generated application ID" - }, - { - "name": "documentsRequired", - "type": "boolean", - "description": "Whether documents verification is required" - }, - { - "name": "verificationLevel", - "type": "string", - "description": "Level of verification required" - }, - { - "name": "applicantName", - "type": "string", - "description": "Applicant name for verification" - }, - { - "name": "hasDependents", - "type": "boolean", - "description": "Whether applicant has dependents" - }, - { - "name": "dependentCount", - "type": "number", - "description": "Number of dependents" - }, - { - "name": "dependentName", - "type": "string", - "description": "Name of dependent" - }, - { - "name": "hasBankingInfo", - "type": "boolean", - "description": "Whether banking information is provided" - }, - { - "name": "paymentReady", - "type": "boolean", - "description": "Whether payment processing is ready" - }, - { - "name": "profileSubmissionStatus", - "type": "string", - "description": "Status of profile submission" - }, - { - "name": "nextStepReady", - "type": "boolean", - "description": "Whether ready for next step" - } - ] - }, - "type": "script", - "label": "Process API Response", - "position": { "x": 1590, "y": -345 } - }, - { - "id": "business-rule-1751871900000", - "data": { - "label": "BF-NAS-PRF-AS-QS-03 Analisa Data (Had Kifayah)", - "shape": "rectangle", - "textColor": "#1e40af", - "ruleGroups": [ - { - "id": "group-1", - "name": "Ketua Keluarga Base Amount", - "actions": [ - { - "id": "action-1-1", - "type": "set_variable", - "value": 1215, - "variable": "baseKifayahKetuaKeluarga" - }, - { - "id": "action-1-2", - "type": "set_variable", - "value": "ketua_keluarga", - "variable": "categoryKetuaKeluarga" - } - ], - "operator": "AND", - "conditions": [ - { - "id": "condition-1-1", - "value": "", - "operator": "neq", - "variable": "noKadPengenalan", - "valueType": "string" - } - ] - }, - { - "id": "group-2", - "name": "Dewasa Bekerja (18 Tahun Ke Atas)", - "actions": [ - { - "id": "action-2-1", - "type": "set_variable", - "value": 412, - "variable": "hadKifayahDewasaBekerja" - }, - { - "id": "action-2-2", - "type": "calculation", - "formula": "hadKifayahDewasaBekerja * bilanganDewasaBekerja", - "variable": "totalHadKifayahDewasaBekerja" - } - ], - "operator": "AND", - "conditions": [ - { - "id": "condition-2-1", - "value": 0, - "operator": "gt", - "variable": "bilanganDewasaBekerja" - } - ] - }, - { - "id": "group-3", - "name": "Dewasa Tidak Bekerja (18 Tahun Ke Atas)", - "actions": [ - { - "id": "action-3-1", - "type": "set_variable", - "value": 167, - "variable": "hadKifayahDewasaTidakBekerja" - }, - { - "id": "action-3-2", - "type": "calculation", - "formula": "hadKifayahDewasaTidakBekerja * bilanganDewasaTidakBekerja", - "variable": "totalHadKifayahDewasaTidakBekerja" - } - ], - "operator": "AND", - "conditions": [ - { - "id": "condition-3-1", - "value": 0, - "operator": "gt", - "variable": "bilanganDewasaTidakBekerja" - } - ] - }, - { - "id": "group-4", - "name": "Tanggungan Belajar IPT", - "actions": [ - { - "id": "action-4-1", - "type": "set_variable", - "value": 613, - "variable": "hadKifayahTanggunganIPT" - }, - { - "id": "action-4-2", - "type": "calculation", - "formula": "hadKifayahTanggunganIPT * bilanganTanggunganIPT", - "variable": "totalHadKifayahTanggunganIPT" - } - ], - "operator": "AND", - "conditions": [ - { - "id": "condition-4-1", - "value": 0, - "operator": "gt", - "variable": "bilanganTanggunganIPT" - } - ] - }, - { - "id": "group-5", - "name": "Tanggungan Berumur 7-17 tahun", - "actions": [ - { - "id": "action-5-1", - "type": "set_variable", - "value": 408, - "variable": "hadKifayahTanggungan7to17" - }, - { - "id": "action-5-2", - "type": "calculation", - "formula": "hadKifayahTanggungan7to17 * bilanganTanggungan7to17", - "variable": "totalHadKifayahTanggungan7to17" - } - ], - "operator": "AND", - "conditions": [ - { - "id": "condition-5-1", - "value": 0, - "operator": "gt", - "variable": "bilanganTanggungan7to17" - } - ] - }, - { - "id": "group-6", - "name": "Tanggungan 6 Tahun Ke Bawah", - "actions": [ - { - "id": "action-6-1", - "type": "set_variable", - "value": 175, - "variable": "hadKifayahTanggungan6KeBawah" - }, - { - "id": "action-6-2", - "type": "calculation", - "formula": "hadKifayahTanggungan6KeBawah * bilanganTanggungan6KeBawah", - "variable": "totalHadKifayahTanggungan6KeBawah" - } - ], - "operator": "AND", - "conditions": [ - { - "id": "condition-6-1", - "value": 0, - "operator": "gt", - "variable": "bilanganTanggungan6KeBawah" - } - ] - }, - { - "id": "group-7", - "name": "Calculate Total Had Kifayah", - "actions": [ - { - "id": "action-7-1", - "type": "calculation", - "formula": "baseKifayahKetuaKeluarga + (totalHadKifayahDewasaBekerja || 0) + (totalHadKifayahDewasaTidakBekerja || 0) + (totalHadKifayahTanggunganIPT || 0) + (totalHadKifayahTanggungan7to17 || 0) + (totalHadKifayahTanggungan6KeBawah || 0)", - "variable": "totalJumlahHadKifayah" - }, - { - "id": "action-7-2", - "type": "calculation", - "formula": "((pendapatanBersih || 0) / totalJumlahHadKifayah) * 100", - "variable": "peratusHadKifayah" - }, - { - "id": "action-7-3", - "type": "set_variable", - "value": "completed", - "variable": "kifayahCalculationStatus" - } - ], - "operator": "AND", - "conditions": [ - { - "id": "condition-7-1", - "value": "", - "operator": "neq", - "variable": "noKadPengenalan" - } - ] - } - ], - "borderColor": "#3b82f6", - "description": "BF-NAS-PRF-AS-QS-03: Proses pengiraan had kifayah asnaf menggunakan maklumat konfigurasi had kifayah dan maklumat yang telah diisi oleh pemohon/pendaftar", - "errorVariable": "kifayahCalculationError", - "outputVariable": "kifayahCalculationResult", - "backgroundColor": "#eff6ff" - }, - "type": "business-rule", - "label": "BF-NAS-PRF-AS-QS-03 Analisa Data (Had Kifayah)", - "position": { "x": 2505, "y": -60 } - }, - { - "id": "business-rule-1751871901000", - "data": { - "label": "BF-NAS-PRF-AS-QS-04 Syor Status Keluarga Asnaf", - "shape": "rectangle", - "textColor": "#1e40af", - "ruleGroups": [ - { - "id": "group-status-1", - "name": "Kategorikan Fakir (0%-49.9%)", - "actions": [ - { - "id": "action-status-1-1", - "type": "set_variable", - "value": "Fakir", - "variable": "kategoriKeluargaAsna" - }, - { - "id": "action-status-1-2", - "type": "set_variable", - "value": "Fakir", - "variable": "kategoriAsnafSyor" - }, - { - "id": "action-status-1-3", - "type": "set_variable", - "value": "Fakir", - "variable": "statusKeluarga" - } - ], - "operator": "AND", - "conditions": [ - { - "id": "condition-status-1-1", - "value": 0, - "operator": "gte", - "variable": "peratusHadKifayah" - }, - { - "id": "condition-status-1-2", - "value": 49.9, - "operator": "lte", - "variable": "peratusHadKifayah" - } - ] - }, - { - "id": "group-status-2", - "name": "Kategorikan Miskin (50%-100%)", - "actions": [ - { - "id": "action-status-2-1", - "type": "set_variable", - "value": "Miskin", - "variable": "kategoriKeluargaAsnaf" - }, - { - "id": "action-status-2-2", - "type": "set_variable", - "value": "Miskin", - "variable": "kategoriAsnafSyor" - }, - { - "id": "action-status-2-3", - "type": "set_variable", - "value": "Miskin", - "variable": "statusKeluarga" - } - ], - "operator": "AND", - "conditions": [ - { - "id": "condition-status-2-1", - "value": 50, - "operator": "gte", - "variable": "peratusHadKifayah" - }, - { - "id": "condition-status-2-2", - "value": 100, - "operator": "lte", - "variable": "peratusHadKifayah" - } - ] - }, - { - "id": "group-status-3", - "name": "Kategorikan Non-FM (>100%)", - "actions": [ - { - "id": "action-status-3-1", - "type": "set_variable", - "value": "Non-FM", - "variable": "kategoriKeluargaAsnaf" - }, - { - "id": "action-status-3-2", - "type": "set_variable", - "value": "Non-FM", - "variable": "kategoriAsnafSyor" - }, - { - "id": "action-status-3-3", - "type": "set_variable", - "value": "Non-FM", - "variable": "statusKeluarga" - } - ], - "operator": "AND", - "conditions": [ - { - "id": "condition-status-3-1", - "value": 100, - "operator": "gt", - "variable": "peratusHadKifayah" - } - ] - }, - { - "id": "group-status-4", - "name": "Check Muallaf Status", - "actions": [ - { - "id": "action-status-4-1", - "type": "set_variable", - "value": "Muallaf", - "variable": "kategoriAsnafSyor" - }, - { - "id": "action-status-4-2", - "type": "set_variable", - "value": "Muallaf", - "variable": "statusIndividu" - } - ], - "operator": "AND", - "conditions": [ - { - "id": "condition-status-4-1", - "value": "", - "operator": "neq", - "variable": "dateMasukislam" - }, - { - "id": "condition-status-4-2", - "value": 5, - "operator": "lt", - "variable": "tempohMasukIslam" - } - ] - }, - { - "id": "group-status-5", - "name": "Generate AI Recommendation", - "actions": [ - { - "id": "action-status-5-1", - "type": "set_variable", - "value": "Generated", - "variable": "syorPengesahanStatus" - }, - { - "id": "action-status-5-2", - "type": "set_variable", - "value": "${new Date().toISOString()}", - "variable": "tarikhPengesyoran" - }, - { - "id": "action-status-5-3", - "type": "set_variable", - "value": "Berdasarkan analisis had kifayah, pemohon dikategorikan sebagai ${kategoriAsnafSyor} dengan peratus had kifayah ${peratusHadKifayah.toFixed(2)}%. Jumlah had kifayah keluarga: RM ${totalJumlahHadKifayah.toFixed(2)}.", - "variable": "syorPengesahan" - } - ], - "operator": "AND", - "conditions": [ - { - "id": "condition-status-5-1", - "value": "completed", - "operator": "eq", - "variable": "kifayahCalculationStatus" - } - ] - } - ], - "borderColor": "#3b82f6", - "description": "BF-NAS-PRF-AS-QS-04: Sistem akan mengesyorkan status keluarga asnaf hasil dari pengiraan had kifayah", - "errorVariable": "statusRecommendationError", - "outputVariable": "statusRecommendationResult", - "backgroundColor": "#eff6ff" - }, - "type": "business-rule", - "label": "BF-NAS-PRF-AS-QS-04 Syor Status Keluarga Asnaf", - "position": { "x": 2505, "y": 195 } - }, - { - "id": "html-1752109761532", - "data": { - "label": "Family Tree", - "shape": "rectangle", - "jsCode": "", - "cssCode": "", - "htmlCode": "\n
\n

Custom HTML Content

\n

This is a custom HTML node that can display rich content.

\n
", - "textColor": "#333333", - "autoRefresh": false, - "borderColor": "#dddddd", - "description": "Family Tree for Borang", - "inputVariables": [], - "backgroundColor": "#ffffff", - "outputVariables": [], - "allowVariableAccess": true - }, - "type": "html", - "label": "Family Tree", - "position": { "x": 2535, "y": -435 } - }, - { - "id": "rectangle-shape-1752110224921", - "data": { - "label": "", - "shape": "rectangle", - "width": 650, - "height": 400, - "isShape": true, - "shapeType": "rectangle", - "textColor": "#374151", - "borderColor": "#16a34a", - "description": "", - "backgroundColor": "#e8f5e9" - }, - "type": "rectangle-shape", - "label": "", - "position": { "x": 375, "y": -570 } - }, - { - "id": "text-annotation-1752110279700", - "data": { - "label": "NF-NAS-PRF-AS-PA", - "shape": "rectangle", - "width": 200, - "height": 80, - "isShape": true, - "shapeType": "text-annotation", - "textColor": "#92400e", - "borderColor": "#fbbf24", - "description": "Pernilaian Awal", - "backgroundColor": "#fffbeb" - }, - "type": "text-annotation", - "label": "BF-NAS-PRF-AS-PA", - "position": { "x": 810, "y": -555 } - }, - { - "id": "rectangle-shape-1752110492897", - "data": { - "label": "", - "shape": "rectangle", - "width": 650, - "height": 400, - "isShape": true, - "shapeType": "rectangle", - "textColor": "#374151", - "borderColor": "#16a34a", - "description": "", - "backgroundColor": "#e8f5e9" - }, - "type": "rectangle-shape", - "label": "", - "position": { "x": 1185, "y": -570 } - }, - { - "id": "text-annotation-1752110562983", - "data": { - "label": "BF-NAS-PRF-AS-QS-02", - "shape": "rectangle", - "width": 200, - "height": 80, - "isShape": true, - "shapeType": "text-annotation", - "textColor": "#92400e", - "borderColor": "#fbbf24", - "description": "Isi Borang Permohonan Online", - "backgroundColor": "#fffbeb" - }, - "type": "text-annotation", - "label": "BF-NAS-PRF-AS-QS-02", - "position": { "x": 1620, "y": -555 } - }, - { - "id": "rectangle-shape-1752114739551", - "data": { - "label": "", - "shape": "rectangle", - "width": 750, - "height": 400, - "isShape": true, - "shapeType": "rectangle", - "textColor": "#374151", - "borderColor": "#16a34a", - "description": "", - "backgroundColor": "#e8f5e9" - }, - "type": "rectangle-shape", - "label": "", - "position": { "x": 1995, "y": -570 } - }, - { - "id": "api-1752114771983", - "data": { - "label": "API Call", - "shape": "rectangle", - "apiUrl": "", - "headers": "{ \"Content-Type\": \"application/json\" }", - "apiMethod": "GET", - "textColor": "#1e40af", - "borderColor": "#3b82f6", - "description": "External API call", - "requestBody": "", - "errorVariable": "apiError", - "outputVariable": "apiResponse", - "backgroundColor": "#eff6ff", - "continueOnError": false - }, - "type": "api", - "label": "Called Family Tree", - "position": { "x": 2295, "y": -525 } - }, - { - "id": "text-annotation-1752114833800", - "data": { - "label": "", - "shape": "rectangle", - "width": 200, - "height": 80, - "isShape": true, - "shapeType": "text-annotation", - "textColor": "#92400e", - "borderColor": "#fbbf24", - "description": "Family Tree", - "backgroundColor": "#fffbeb" - }, - "type": "text-annotation", - "label": "BF-NAS-PRF-AS-FM", - "position": { "x": 2520, "y": -555 } - }, - { - "id": "form-1753000000000", - "data": { - "label": "Carian Profil", - "formId": 4, - "formName": "Carian Profil", - "formUuid": "4e07fc8f-a160-478a-85fd-fa3364401545", - "description": "Skrin carian asnaf atau login", - "assignedRoles": [], - "assignedUsers": [], - "inputMappings": [], - "assignmentType": "public", - "outputMappings": [ - { "formField": "search_type", "processVariable": "carianSearchType" }, - { "formField": "search_id", "processVariable": "carianSearchId" }, - { "formField": "login_id", "processVariable": "carianLoginId" }, - { - "formField": "login_password", - "processVariable": "carianLoginPassword" - } - ], - "fieldConditions": [], - "assignmentVariable": "", - "assignmentVariableType": "user_id" - }, - "type": "form", - "label": "Carian Profil", - "position": { "x": 450, "y": -15 } - }, - { - "id": "api-1753000000001", - "data": { - "label": "Submit Carian Profil API", - "apiUrl": "https://api.example.com/profiles/search", - "headers": "{ \"Content-Type\": \"application/json\" }", - "apiMethod": "POST", - "description": "Submit profile search or login credentials", - "requestBody": "{\n \"searchType\": \"{carianSearchType}\",\n \"searchId\": \"{carianSearchId}\",\n \"loginId\": \"{carianLoginId}\",\n \"password\": \"{carianLoginPassword}\"\n}", - "errorVariable": "carianProfilApiError", - "outputVariable": "carianProfilApiResponse", - "continueOnError": false - }, - "type": "api", - "label": "Submit Carian Profil API", - "position": { "x": 450, "y": 180 } - }, - { - "id": "script-1753000000002", - "data": { - "label": "Process Carian Profil Response", - "scriptCode": "// Process API response from profile search/login\nconst response = processVariables.carianProfilApiResponse;\n\nif (response && response.data) {\n if (response.data.loginSuccess) {\n processVariables.loginSuccess = true;\n processVariables.profileData = response.data.profile;\n processVariables.carianProfilStatus = 'login_successful';\n } else if (response.data.profileFound) {\n processVariables.profileFound = true;\n processVariables.profileData = response.data.profile;\n processVariables.carianProfilStatus = 'profile_found';\n } else {\n processVariables.profileFound = false;\n processVariables.loginSuccess = false;\n processVariables.carianProfilStatus = 'not_found';\n }\n} else {\n processVariables.carianProfilStatus = 'error';\n processVariables.carianProfilScriptError = 'Invalid or empty API response';\n}", - "description": "Process the response from the Carian Profil API", - "errorVariable": "carianProfilScriptError", - "inputVariables": ["carianProfilApiResponse"], - "scriptLanguage": "javascript", - "continueOnError": false, - "outputVariables": [ - { - "name": "profileFound", - "type": "boolean", - "description": "Indicates if a profile was found via search" - }, - { - "name": "loginSuccess", - "type": "boolean", - "description": "Indicates if the asnaf login was successful" - }, - { - "name": "profileData", - "type": "object", - "description": "The retrieved profile data" - }, - { - "name": "carianProfilStatus", - "type": "string", - "description": "The status of the profile search/login action" - } - ] - }, - "type": "script", - "label": "Process Carian Profil Response", - "position": { "x": 780, "y": 180 } - }, - { - "id": "rectangle-shape-1752115136908", - "data": { - "label": "", - "shape": "rectangle", - "width": 650, - "height": 400, - "isShape": true, - "shapeType": "rectangle", - "textColor": "#374151", - "borderColor": "#16a34a", - "description": "", - "backgroundColor": "#e8f5e9" - }, - "type": "rectangle-shape", - "label": "", - "position": { "x": 375, "y": -45 } - }, - { - "id": "text-annotation-1752115184991", - "data": { - "label": "", - "shape": "rectangle", - "width": 200, - "height": 80, - "isShape": true, - "shapeType": "text-annotation", - "textColor": "#92400e", - "borderColor": "#fbbf24", - "description": "Carian Profil", - "backgroundColor": "#fffbeb" - }, - "type": "text-annotation", - "label": "BF-NAS-PRF-AS-QS-01", - "position": { "x": 810, "y": -30 } - }, - { - "id": "gateway-1753100000000", - "data": { - "label": "Profil Wujud?", - "shape": "diamond", - "textColor": "#374151", - "conditions": [ - { - "id": "condition-group-ya-path", - "output": "Ya", - "conditions": [ - { - "id": "condition-1", - "value": true, - "operator": "eq", - "variable": "profileFound", - "valueType": "boolean", - "logicalOperator": "and" - } - ] - }, - { - "id": "condition-group-tidak-path", - "output": "Tidak", - "conditions": [ - { - "id": "condition-2", - "value": false, - "operator": "eq", - "variable": "profileFound", - "valueType": "boolean", - "logicalOperator": "and" - } - ] - } - ], - "borderColor": "#6b7280", - "defaultPath": "form-1752471000000", - "description": "Check if profile exists in system", - "gatewayType": "exclusive", - "backgroundColor": "#f9fafb" - }, - "type": "gateway", - "label": "Profil Wujud?", - "position": { "x": 1230, "y": 0 } - }, - { - "id": "form-1753100000001", - "data": { - "label": "Pengesahan Kemaskini Profil", - "formId": 5, - "formName": "Pengesahan Kemaskini Profil", - "formUuid": "5e07fc8f-a160-478a-85fd-fa3364401546", - "description": "Borang pengesahan untuk kemaskini profil sedia ada", - "assignedRoles": [], - "assignedUsers": [], - "inputMappings": [ - { - "formField": "nama_pemohon", - "processVariable": "profileData.nama" - }, - { - "formField": "no_kad_pengenalan", - "processVariable": "profileData.noKadPengenalan" - }, - { - "formField": "tarikh_lahir", - "processVariable": "profileData.tarikhLahir" - }, - { "formField": "alamat", "processVariable": "profileData.alamat" } - ], - "assignmentType": "public", - "outputMappings": [ - { - "formField": "kemaskini_profil", - "processVariable": "kemaskiniProfil" - }, - { - "formField": "sebab_kemaskini", - "processVariable": "sebabKemaskini" - } - ], - "fieldConditions": [], - "assignmentVariable": "", - "assignmentVariableType": "user_id" - }, - "type": "form", - "label": "Pengesahan Kemaskini Profil", - "position": { "x": 1200, "y": 195 } - }, - { - "id": "gateway-1753100000002", - "data": { - "label": "Perubahan Profil?", - "shape": "diamond", - "textColor": "#374151", - "conditions": [ - { - "id": "condition-group-ya-path", - "output": "Ya", - "conditions": [ - { - "id": "condition-1", - "value": "ya", - "operator": "eq", - "variable": "kemaskiniProfil", - "valueType": "string", - "logicalOperator": "and" - } - ] - }, - { - "id": "condition-group-tidak-path", - "output": "Tidak", - "conditions": [ - { - "id": "condition-2", - "value": "tidak", - "operator": "eq", - "variable": "kemaskiniProfil", - "valueType": "string", - "logicalOperator": "and" - } - ] - } - ], - "borderColor": "#6b7280", - "defaultPath": "form-1752471000000", - "description": "Check if user wants to update profile", - "gatewayType": "exclusive", - "backgroundColor": "#f9fafb" - }, - "type": "gateway", - "label": "Perubahan Profil?", - "position": { "x": 1440, "y": 60 } - }, - { - "id": "subprocess-1753100000003", - "data": { - "label": "BF-NAS-PRF-AS-UP-02", - "shape": "rectangle", - "processId": "kemaskini-profil-process", - "textColor": "#134e4a", - "borderColor": "#14b8a6", - "description": "Sub Process: Kemaskini Profil", - "subprocessId": 3, - "inputMappings": [ - { - "processVariable": "profileData", - "subprocessVariable": "profileData" - }, - { - "processVariable": "sebabKemaskini", - "subprocessVariable": "sebabKemaskini" - } - ], - "outputMappings": [ - { - "processVariable": "updatedProfileData", - "subprocessVariable": "profileData" - }, - { - "processVariable": "profileUpdateStatus", - "subprocessVariable": "updateStatus" - } - ], - "subprocessName": "BF-NAS-PRF-AS-UP-02", - "backgroundColor": "#f0fdfa" - }, - "type": "subprocess", - "label": "BF-NAS-PRF-AS-UP-02", - "position": { "x": 1635, "y": -30 } - }, - { - "id": "subprocess-1752202751327", - "data": { - "label": "BF-NAS-BTN-PB", - "shape": "rectangle", - "textColor": "#134e4a", - "borderColor": "#14b8a6", - "description": "Sub Process: Bantuan", - "subprocessId": 4, - "subprocessName": "BF-NAS-BTN-PB", - "backgroundColor": "#f0fdfa" - }, - "type": "subprocess", - "label": "BF-NAS-BTN-PB", - "position": { "x": 1635, "y": 180 } - }, - { - "id": "notification-1753200000001", - "data": { - "label": "Terima Notifikasi", - "message": "Assalamualaikum {applicantName},\n\nPermohonan bantuan anda telah diterima dan sedang dalam proses semakan.\n\nNo Rujukan: {applicationId}\nTarikh Permohonan: {submissionDate}\nStatus: Dalam Proses\n\nAnda akan menerima notifikasi lanjut apabila terdapat kemaskini status permohonan.\n\nTerima kasih.", - "subject": "Permohonan Bantuan Diterima - {applicationId}", - "priority": "normal", - "template": "application_received", - "variables": [ - "applicantName", - "applicationId", - "submissionDate", - "applicantEmail" - ], - "recipients": [ - { "type": "variable", "value": "applicantEmail" }, - { "type": "role", "value": "admin" } - ], - "attachments": [], - "description": "Send notification when application is received", - "sendImmediately": true, - "notificationType": "email" - }, - "type": "notification", - "label": "Terima Notifikasi", - "position": { "x": 3180, "y": -435 } - }, - { - "id": "gateway-status-check", - "data": { - "label": "Status", - "shape": "diamond", - "textColor": "#374151", - "conditions": [ - { - "id": "condition-group-berjaya-fm-path", - "output": "Berjaya FM", - "conditions": [ - { - "id": "condition-1", - "value": "approved", - "operator": "eq", - "variable": "applicationStatus", - "valueType": "string", - "logicalOperator": "and" - }, - { - "id": "condition-2", - "value": "Fakir", - "operator": "eq", - "variable": "kategoriAsnafSyor", - "valueType": "string", - "logicalOperator": "and" - } - ] - }, - { - "id": "condition-group-berjaya-miskin-path", - "output": "Berjaya Miskin", - "conditions": [ - { - "id": "condition-3", - "value": "approved", - "operator": "eq", - "variable": "applicationStatus", - "valueType": "string", - "logicalOperator": "and" - }, - { - "id": "condition-4", - "value": "Miskin", - "operator": "eq", - "variable": "kategoriAsnafSyor", - "valueType": "string", - "logicalOperator": "and" - } - ] - }, - { - "id": "condition-group-berjaya-non-fm-path", - "output": "Berjaya Non-FM", - "conditions": [ - { - "id": "condition-5", - "value": "approved", - "operator": "eq", - "variable": "applicationStatus", - "valueType": "string", - "logicalOperator": "and" - }, - { - "id": "condition-6", - "value": "Non-FM", - "operator": "eq", - "variable": "kategoriAsnafSyor", - "valueType": "string", - "logicalOperator": "and" - } - ] - }, - { - "id": "condition-group-gagal-path", - "output": "Gagal", - "conditions": [ - { - "id": "condition-7", - "value": "rejected", - "operator": "eq", - "variable": "applicationStatus", - "valueType": "string", - "logicalOperator": "and" - } - ] - } - ], - "borderColor": "#6b7280", - "defaultPath": "notification-1753200000002", - "description": "Check application status and asnaf category for routing", - "gatewayType": "exclusive", - "backgroundColor": "#f9fafb" - }, - "type": "gateway", - "label": "Status", - "position": { "x": 1470, "y": 615 } - }, - { - "id": "form-pengesahan", - "data": { - "label": "BF-NAS-PRF-AS-QS-05 Pengesahan", - "formId": 8, - "formName": "Borang Pengesahan", - "formUuid": "8e07fc8f-a160-478a-85fd-fa3364401549", - "description": "Form untuk pengesahan dokumen dan maklumat pemohon", - "assignedRoles": ["verifier", "admin"], - "assignedUsers": [], - "inputMappings": [ - { "formField": "nama_pemohon", "processVariable": "applicantName" }, - { "formField": "no_rujukan", "processVariable": "applicationId" }, - { "formField": "kategori_asnaf", "processVariable": "kategoriAsnaf" }, - { - "formField": "dokumen_berkaitan", - "processVariable": "dokumenBerkaitan" - }, - { "formField": "urgency_level", "processVariable": "urgencyLevel" } - ], - "assignmentType": "role", - "outputMappings": [ - { - "formField": "status_pengesahan", - "processVariable": "pengesahanStatus" - }, - { - "formField": "catatan_pengesahan", - "processVariable": "catatanPengesahan" - }, - { - "formField": "dokumen_tambahan_diperlukan", - "processVariable": "dokumenTambahanDiperlukan" - }, - { - "formField": "jumlah_bantuan_dicadangkan", - "processVariable": "jumlahBantuanDicadangkan" - }, - { "formField": "jenis_bantuan", "processVariable": "jenisBantuan" }, - { "formField": "verified_by", "processVariable": "verifiedBy" }, - { - "formField": "verification_date", - "processVariable": "verificationDate" - } - ], - "fieldConditions": [], - "assignmentVariable": "", - "assignmentVariableType": "user_id" - }, - "type": "form", - "label": "BF-NAS-PRF-AS-QS-05 Pengesahan", - "position": { "x": 2505, "y": 705 } - }, - { - "id": "api-pengesahan-submit", - "data": { - "label": "Submit Pengesahan API", - "apiUrl": "https://api.bantuan.gov.my/v1/verification/submit", - "headers": "{ \"Content-Type\": \"application/json\", \"Authorization\": \"Bearer {apiToken}\" }", - "apiMethod": "POST", - "description": "Submit verification results to central system", - "requestBody": "{\n \"applicationId\": \"{applicationId}\",\n \"verificationStatus\": \"{pengesahanStatus}\",\n \"verificationNotes\": \"{catatanPengesahan}\",\n \"additionalDocumentsRequired\": \"{dokumenTambahanDiperlukan}\",\n \"recommendedAmount\": \"{jumlahBantuanDicadangkan}\",\n \"assistanceType\": \"{jenisBantuan}\",\n \"verifiedBy\": \"{verifiedBy}\",\n \"verificationDate\": \"{verificationDate}\",\n \"applicantCategory\": \"{kategoriAsnaf}\",\n \"urgencyLevel\": \"{urgencyLevel}\"\n}", - "errorVariable": "pengesahanApiError", - "outputVariable": "pengesahanApiResponse", - "continueOnError": false - }, - "type": "api", - "label": "Submit Pengesahan API", - "position": { "x": 2175, "y": 720 } - }, - { - "id": "script-process-pengesahan", - "data": { - "label": "Process Pengesahan Response", - "scriptCode": "// Process the pengesahan (verification) response\nconst apiData = processVariables.pengesahanApiResponse;\n\nif (apiData && apiData.status === 'success') {\n // Update application status based on verification\n switch (processVariables.pengesahanStatus) {\n case 'lulus':\n processVariables.applicationStatus = 'approved';\n processVariables.statusMessage = 'Permohonan telah diluluskan';\n processVariables.nextAction = 'payment_processing';\n break;\n case 'ditolak':\n processVariables.applicationStatus = 'rejected';\n processVariables.statusMessage = 'Permohonan ditolak: ' + processVariables.catatanPengesahan;\n processVariables.nextAction = 'send_rejection_notice';\n break;\n case 'dokumen_tambahan':\n processVariables.applicationStatus = 'pending_documents';\n processVariables.statusMessage = 'Dokumen tambahan diperlukan';\n processVariables.nextAction = 'request_additional_documents';\n break;\n case 'semakan_lanjut':\n processVariables.applicationStatus = 'under_review';\n processVariables.statusMessage = 'Permohonan dalam semakan lanjut';\n processVariables.nextAction = 'further_review';\n break;\n default:\n processVariables.applicationStatus = 'pending';\n processVariables.statusMessage = 'Status tidak diketahui';\n processVariables.nextAction = 'manual_review';\n }\n \n // Set verification completion flag\n processVariables.verificationCompleted = true;\n processVariables.verificationTimestamp = new Date().toISOString();\n \n // Calculate processing time\n if (processVariables.submissionDate) {\n const submitTime = new Date(processVariables.submissionDate);\n const verifyTime = new Date();\n const processingHours = Math.round((verifyTime - submitTime) / (1000 * 60 * 60));\n processVariables.processingTimeHours = processingHours;\n }\n \n // Set notification flags based on status\n processVariables.sendApprovalNotification = processVariables.applicationStatus === 'approved';\n processVariables.sendRejectionNotification = processVariables.applicationStatus === 'rejected';\n processVariables.sendPendingNotification = processVariables.applicationStatus.includes('pending');\n \n // Set payment processing flag for approved applications\n if (processVariables.applicationStatus === 'approved') {\n processVariables.paymentReady = true;\n processVariables.paymentAmount = processVariables.jumlahBantuanDicadangkan || 0;\n processVariables.paymentMethod = processVariables.sebabTunai === 'ya' ? 'cash' : 'bank_transfer';\n }\n \n console.log('Pengesahan processed successfully:', {\n applicationStatus: processVariables.applicationStatus,\n statusMessage: processVariables.statusMessage,\n nextAction: processVariables.nextAction,\n verificationCompleted: processVariables.verificationCompleted,\n paymentReady: processVariables.paymentReady\n });\n} else {\n // Handle API error\n processVariables.applicationStatus = 'verification_failed';\n processVariables.statusMessage = 'Ralat semasa pengesahan';\n processVariables.verificationCompleted = false;\n processVariables.pengesahanError = apiData ? apiData.message : 'Unknown API error';\n \n console.error('Pengesahan API failed:', processVariables.pengesahanError);\n}", - "description": "Process verification results and determine next steps", - "errorVariable": "pengesahanScriptError", - "inputVariables": [ - "pengesahanApiResponse", - "pengesahanStatus", - "catatanPengesahan", - "dokumenTambahanDiperlukan", - "jumlahBantuanDicadangkan", - "jenisBantuan", - "verifiedBy", - "verificationDate", - "submissionDate", - "sebabTunai" - ], - "scriptLanguage": "javascript", - "continueOnError": false, - "outputVariables": [ - { - "name": "applicationStatus", - "type": "string", - "description": "Final application status after verification" - }, - { - "name": "statusMessage", - "type": "string", - "description": "Human-readable status message" - }, - { - "name": "nextAction", - "type": "string", - "description": "Next action to be taken" - }, - { - "name": "verificationCompleted", - "type": "boolean", - "description": "Whether verification process is completed" - }, - { - "name": "verificationTimestamp", - "type": "string", - "description": "Timestamp when verification was completed" - }, - { - "name": "processingTimeHours", - "type": "number", - "description": "Total processing time in hours" - }, - { - "name": "sendApprovalNotification", - "type": "boolean", - "description": "Whether to send approval notification" - }, - { - "name": "sendRejectionNotification", - "type": "boolean", - "description": "Whether to send rejection notification" - }, - { - "name": "sendPendingNotification", - "type": "boolean", - "description": "Whether to send pending status notification" - }, - { - "name": "paymentReady", - "type": "boolean", - "description": "Whether payment processing is ready" - }, - { - "name": "paymentAmount", - "type": "number", - "description": "Amount approved for payment" - }, - { - "name": "paymentMethod", - "type": "string", - "description": "Payment method (cash/bank_transfer)" - } - ] - }, - "type": "script", - "label": "Process Pengesahan Response", - "position": { "x": 2175, "y": 540 } - }, - { - "id": "notification-1753200000002", - "data": { - "label": "BF-NAS-PRF-AS-QS-06 Terima Notifikasi", - "shape": "rectangle", - "message": "Assalamualaikum {applicantName},\n\nStatus permohonan bantuan anda telah dikemaskini.\n\nNo Rujukan: {applicationId}\nStatus Terkini: {statusMessage}\nTarikh Kemaskini: {verificationTimestamp}\nDiluluskan oleh: {verifiedBy}\n\n{conditionalMessage}\n\nUntuk maklumat lanjut, sila hubungi pejabat kami.\n\nTerima kasih.", - "subject": "Kemaskini Status Permohonan - {applicationId}", - "priority": "high", - "template": "status_update", - "textColor": "#0284c7", - "variables": [ - "applicantName", - "applicationId", - "statusMessage", - "verificationTimestamp", - "verifiedBy", - "conditionalMessage" - ], - "recipients": [{ "type": "variable", "value": "applicantEmail" }], - "attachments": [], - "borderColor": "#0ea5e9", - "description": "Send status update notification to applicant", - "backgroundColor": "#f0f9ff", - "sendImmediately": true, - "notificationType": "email", - "conditionalSending": { - "conditions": [ - { - "value": true, - "operator": "eq", - "variable": "verificationCompleted", - "valueType": "boolean" - } - ] - } - }, - "type": "notification", - "label": "Terima Notifikasi", - "position": { "x": 3195, "y": 615 } - }, - { - "id": "swimlane-horizontal-1752207659712", - "data": { - "label": "", - "shape": "rectangle", - "width": 650, - "height": 400, - "isShape": true, - "shapeType": "swimlane-horizontal", - "textColor": "#374151", - "borderColor": "#16a34a", - "description": "", - "backgroundColor": "#e8f5e9" - }, - "type": "swimlane-horizontal", - "label": "", - "position": { "x": 2940, "y": -570 } - }, - { - "id": "text-annotation-1752207727571", - "data": { - "label": "", - "shape": "rectangle", - "width": 200, - "height": 80, - "isShape": true, - "shapeType": "text-annotation", - "textColor": "#92400e", - "borderColor": "#fbbf24", - "description": "Terima Notifikasi", - "backgroundColor": "#fffbeb" - }, - "type": "text-annotation", - "label": "BF-NAS-PRF-AS-QS-06", - "position": { "x": 3360, "y": -540 } - }, - { - "id": "text-annotation-1752207881502", - "data": { - "label": "BF-NAS-PRF-AS-QS-06", - "shape": "rectangle", - "width": 200, - "height": 80, - "zIndex": 1, - "isShape": true, - "shapeType": "text-annotation", - "textColor": "#92400e", - "borderColor": "#fbbf24", - "description": "Terima Notifikasi", - "backgroundColor": "#fffbeb" - }, - "type": "text-annotation", - "label": "BF-NAS-PRF-AS-QS-06", - "position": { "x": 3375, "y": 525 } - }, - { - "id": "swimlane-horizontal-1752207945135", - "data": { - "label": "", - "shape": "rectangle", - "width": 650, - "height": 400, - "zIndex": 0, - "isShape": true, - "shapeType": "swimlane-horizontal", - "textColor": "#374151", - "borderColor": "#16a34a", - "description": "", - "backgroundColor": "#e8f5e9" - }, - "type": "swimlane-horizontal", - "label": "", - "position": { "x": 2100, "y": 495 } - }, - { - "id": "swimlane-horizontal-1752208028711", - "data": { - "label": "", - "shape": "rectangle", - "width": 650, - "height": 400, - "isShape": true, - "shapeType": "swimlane-horizontal", - "textColor": "#475569", - "borderColor": "#16a34a", - "description": "", - "backgroundColor": "#e8f5e9" - }, - "type": "swimlane-horizontal", - "label": "", - "position": { "x": 2955, "y": 495 } - } - ], - "viewport": { - "x": -424.4299384069254, - "y": 160.3515779089071, - "zoom": 0.5618446897868647 - } -} diff --git a/docs/json/process-builder/fullProcessSettings.json b/docs/json/process-builder/fullProcessSettings.json deleted file mode 100644 index ae1baaa..0000000 --- a/docs/json/process-builder/fullProcessSettings.json +++ /dev/null @@ -1,1462 +0,0 @@ -{ - "processInfo": { - "id": "51979028-2779-490c-a237-bf552a2e6376", - "name": "Pendaftaran Profil", - "description": "", - "priority": "normal", - "category": "HR", - "owner": "" - }, - "settings": { - "processType": "standard", - "maxExecutionTime": 60, - "autoTimeout": 24, - "allowParallel": false, - "enableErrorRecovery": true, - "sendNotifications": true - }, - "dataSettings": { - "dataPersistence": "short_term", - "logVariableChanges": true, - "encryptSensitiveData": false, - "dataRetentionPolicy": "" - }, - "permissions": { - "executionPermission": "authenticated", - "allowedRoles": "", - "modificationPermission": "managers", - "requireApproval": false, - "enableAuditTrail": true - }, - "workflow": { - "nodes": [], - "edges": [ - { - "id": "business-rule-1751871901000-notification-1753200000002-1752207615091", - "source": "business-rule-1751871901000", - "target": "notification-1753200000002", - "label": "", - "type": "smoothstep", - "animated": true, - "data": {} - }, - { - "id": "business-rule-1751871901000-form-pengesahan-1752207621840", - "source": "business-rule-1751871901000", - "target": "form-pengesahan", - "label": "", - "type": "smoothstep", - "animated": true, - "data": {} - }, - { - "id": "api-pengesahan-submit-form-pengesahan-1752208003574", - "source": "api-pengesahan-submit", - "target": "form-pengesahan", - "label": "", - "type": "smoothstep", - "animated": true, - "data": {} - }, - { - "id": "script-process-pengesahan-api-pengesahan-submit-1752208004921", - "source": "script-process-pengesahan", - "target": "api-pengesahan-submit", - "label": "", - "type": "smoothstep", - "animated": true, - "data": {} - } - ] - }, - "variables": [ - { - "name": "text3", - "type": "string", - "scope": "global", - "value": null, - "description": "Text field 3 from Section A" - }, - { - "name": "text14", - "type": "string", - "scope": "global", - "value": null, - "description": "Text field 14" - }, - { - "name": "select1", - "type": "string", - "scope": "global", - "value": null, - "description": "Select field 1 from Section A" - }, - { - "name": "apiError", - "type": "object", - "scope": "global", - "value": null, - "description": "API error from Submit Profile API" - }, - { - "name": "apiToken", - "type": "string", - "scope": "global", - "value": "your-api-token-here", - "description": "API authentication token for external services" - }, - { - "name": "namaBank", - "type": "string", - "scope": "global", - "value": null, - "description": "Nama bank from Section B" - }, - { - "name": "nextAction", - "type": "string", - "scope": "global", - "value": null, - "description": "Next action to be taken in the process" - }, - { - "name": "radio9Copy", - "type": "string", - "scope": "global", - "value": null, - "description": "Radio field 9 copy" - }, - { - "name": "sebabTunai", - "type": "string", - "scope": "global", - "value": null, - "description": "Sebab tunai from Section B" - }, - { - "name": "verifiedBy", - "type": "string", - "scope": "global", - "value": null, - "description": "User ID or name of person who verified documents" - }, - { - "name": "apiResponse", - "type": "object", - "scope": "global", - "value": { - "data": { - "id": "APP-2024-001234", - "score": 85, - "status": "pending_verification", - "profileId": "PROF-567890", - "riskLevel": "low", - "documentCount": 3, - "submissionDate": "2024-01-15T10:30:00Z" - }, - "status": "success", - "message": "Profile submitted successfully" - }, - "description": "API response from Submit Profile API" - }, - { - "name": "namaSekolah", - "type": "string", - "scope": "global", - "value": null, - "description": "Nama sekolah from Section B" - }, - { - "name": "noAkaunBank", - "type": "string", - "scope": "global", - "value": null, - "description": "No akaun bank from Section B" - }, - { - "name": "profileData", - "type": "object", - "scope": "global", - "value": { - "nama": "Ahmad Bin Ali", - "alamat": "No 123, Jalan Merdeka, 50000 Kuala Lumpur", - "tarikhLahir": "1985-01-01", - "noKadPengenalan": "850101-01-1234" - }, - "description": "The retrieved profile data" - }, - { - "name": "radioBangsa", - "type": "string", - "scope": "global", - "value": null, - "description": "Radio field for bangsa" - }, - { - "name": "scriptError", - "type": "object", - "scope": "global", - "value": null, - "description": "Error information from script execution" - }, - { - "name": "errorMessage", - "type": "string", - "scope": "global", - "value": null, - "description": "Error message from failed operations" - }, - { - "name": "formJeniskp1", - "type": "string", - "scope": "global", - "value": null, - "description": "Form field for jenis KP 1" - }, - { - "name": "formJeniskp2", - "type": "string", - "scope": "global", - "value": null, - "description": "Form field for jenis KP 2" - }, - { - "name": "formJeniskp3", - "type": "string", - "scope": "global", - "value": null, - "description": "Form field for jenis KP 3" - }, - { - "name": "jenisBantuan", - "type": "string", - "scope": "global", - "value": null, - "description": "Type of assistance (tunai/barangan/perkhidmatan)" - }, - { - "name": "loginSuccess", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Indicates if the asnaf login was successful" - }, - { - "name": "okuAllowance", - "type": "number", - "scope": "global", - "value": null, - "description": "OKU (disabled person) allowance (RM 247.00)" - }, - { - "name": "paymentReady", - "type": "boolean", - "scope": "global", - "value": true, - "description": "Whether payment processing is ready" - }, - { - "name": "profileFound", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Indicates if a profile was found via search" - }, - { - "name": "profileScore", - "type": "number", - "scope": "global", - "value": 85, - "description": "Profile score from initial API response" - }, - { - "name": "radioJantina", - "type": "string", - "scope": "global", - "value": null, - "description": "Radio field for jantina" - }, - { - "name": "urgencyLevel", - "type": "string", - "scope": "global", - "value": null, - "description": "Urgency level (high/medium/low)" - }, - { - "name": "urgencyScore", - "type": "number", - "scope": "global", - "value": 0, - "description": "Calculated urgency score based on needs" - }, - { - "name": "alamatSekolah", - "type": "string", - "scope": "global", - "value": null, - "description": "Alamat sekolah from Section B" - }, - { - "name": "applicantName", - "type": "string", - "scope": "global", - "value": null, - "description": "Applicant's full name" - }, - { - "name": "applicationId", - "type": "string", - "scope": "global", - "value": null, - "description": "Unique application reference number" - }, - { - "name": "carianLoginId", - "type": "string", - "scope": "global", - "value": null, - "description": "Asnaf ID for login" - }, - { - "name": "daerahSekolah", - "type": "string", - "scope": "global", - "value": null, - "description": "Daerah sekolah from Section B" - }, - { - "name": "dependentName", - "type": "string", - "scope": "global", - "value": "Siti Aminah Binti Ahmad", - "description": "Name of dependent" - }, - { - "name": "dependentType", - "type": "string", - "scope": "global", - "value": null, - "description": "Type of dependent (school_age_7_17, below_6, etc.)" - }, - { - "name": "hasDependents", - "type": "boolean", - "scope": "global", - "value": true, - "description": "Whether applicant has dependents" - }, - { - "name": "hasOtherNeeds", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether applicant has other needs" - }, - { - "name": "householdType", - "type": "string", - "scope": "global", - "value": null, - "description": "Type of household (married_with_dependents, single_with_dependents, etc.)" - }, - { - "name": "kategoriAsnaf", - "type": "string", - "scope": "global", - "value": null, - "description": "Category of asnaf (fakir_miskin/bukan_fakir_miskin)" - }, - { - "name": "kifayahStatus", - "type": "string", - "scope": "global", - "value": null, - "description": "Status of Had Kifayah calculation (calculated, pending, error)" - }, - { - "name": "negeriSekolah", - "type": "string", - "scope": "global", - "value": null, - "description": "Negeri sekolah from Section B" - }, - { - "name": "nextStepReady", - "type": "boolean", - "scope": "global", - "value": true, - "description": "Whether ready for next step in process" - }, - { - "name": "nyatakanLain2", - "type": "string", - "scope": "global", - "value": null, - "description": "Text field for nyatakan lain-lain" - }, - { - "name": "paymentAmount", - "type": "number", - "scope": "global", - "value": null, - "description": "Amount approved for payment (RM)" - }, - { - "name": "paymentMethod", - "type": "string", - "scope": "global", - "value": null, - "description": "Payment method (cash/bank_transfer)" - }, - { - "name": "poskodSekolah", - "type": "string", - "scope": "global", - "value": null, - "description": "Poskod sekolah from Section B" - }, - { - "name": "statusMessage", - "type": "string", - "scope": "global", - "value": null, - "description": "Human-readable status message" - }, - { - "name": "applicantEmail", - "type": "string", - "scope": "global", - "value": null, - "description": "Applicant's email address for notifications" - }, - { - "name": "caraPembayaran", - "type": "string", - "scope": "global", - "value": null, - "description": "Cara pembayaran from Section B" - }, - { - "name": "carianSearchId", - "type": "string", - "scope": "global", - "value": null, - "description": "IC or Foreign ID used for profile search" - }, - { - "name": "dateMasukislam", - "type": "string", - "scope": "global", - "value": null, - "description": "Date field for masuk Islam" - }, - { - "name": "dependentCount", - "type": "number", - "scope": "global", - "value": 1, - "description": "Number of dependents" - }, - { - "name": "hasBankingInfo", - "type": "boolean", - "scope": "global", - "value": true, - "description": "Whether banking information is provided" - }, - { - "name": "namaTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Nama tanggungan from Section B" - }, - { - "name": "riskAssessment", - "type": "string", - "scope": "global", - "value": null, - "description": "Risk assessment result from verification" - }, - { - "name": "sebabKemaskini", - "type": "string", - "scope": "global", - "value": null, - "description": "Reason for updating profile" - }, - { - "name": "statusIndividu", - "type": "string", - "scope": "global", - "value": null, - "description": "Individual status (e.g., Muallaf)" - }, - { - "name": "statusKeluarga", - "type": "string", - "scope": "global", - "value": null, - "description": "Family status based on had kifayah calculation" - }, - { - "name": "submissionDate", - "type": "string", - "scope": "global", - "value": null, - "description": "Date when application was submitted" - }, - { - "name": "syorPengesahan", - "type": "string", - "scope": "global", - "value": null, - "description": "AI-generated recommendation summary" - }, - { - "name": "catatanTambahan", - "type": "string", - "scope": "global", - "value": null, - "description": "Catatan tambahan berkaitan permohonan" - }, - { - "name": "hasDisasterNeed", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether applicant has disaster-related needs" - }, - { - "name": "hasHomelessness", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether applicant is homeless" - }, - { - "name": "kemaskiniProfil", - "type": "string", - "scope": "global", - "value": null, - "description": "User's decision on whether to update profile (ya/tidak)" - }, - { - "name": "lihatFamilyTree", - "type": "string", - "scope": "global", - "value": null, - "description": "User's choice whether to view family tree (ya/tidak)" - }, - { - "name": "noKadPengenalan", - "type": "string", - "scope": "global", - "value": "850101-01-1234", - "description": "No Kad Pengenalan" - }, - { - "name": "pengesahanError", - "type": "string", - "scope": "global", - "value": null, - "description": "General error message from pengesahan process" - }, - { - "name": "penilaianAwalId", - "type": "string", - "scope": "global", - "value": null, - "description": "Generated ID for the initial assessment" - }, - { - "name": "radioPendidikan", - "type": "string", - "scope": "global", - "value": null, - "description": "Radio field for pendidikan" - }, - { - "name": "rejectionReason", - "type": "string", - "scope": "global", - "value": null, - "description": "Reason for rejection if documents incomplete" - }, - { - "name": "textWarganegara", - "type": "string", - "scope": "global", - "value": null, - "description": "Text field for warganegara" - }, - { - "name": "totalHadKifayah", - "type": "number", - "scope": "global", - "value": null, - "description": "Total calculated Had Kifayah amount" - }, - { - "name": "bangsaTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Bangsa tanggungan from Section B" - }, - { - "name": "carianSearchType", - "type": "string", - "scope": "global", - "value": null, - "description": "Type of search for Carian Profil (e.g., 'ic_search', 'login')" - }, - { - "name": "dokumenBerkaitan", - "type": "array", - "scope": "global", - "value": null, - "description": "Upload dokumen yang berkaitan" - }, - { - "name": "eligibilityScore", - "type": "number", - "scope": "global", - "value": null, - "description": "Eligibility score from verification API" - }, - { - "name": "hasNoUrgentNeeds", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether applicant has no urgent needs" - }, - { - "name": "hubunganKeluarga", - "type": "string", - "scope": "global", - "value": null, - "description": "Hubungan keluarga from Section B" - }, - { - "name": "pendapatanBersih", - "type": "number", - "scope": "global", - "value": 1000, - "description": "Net family income" - }, - { - "name": "pengesahanStatus", - "type": "string", - "scope": "global", - "value": null, - "description": "Verification status (lulus/ditolak/dokumen_tambahan/semakan_lanjut)" - }, - { - "name": "readyForDecision", - "type": "boolean", - "scope": "global", - "value": null, - "description": "Whether ready for decision gateway" - }, - { - "name": "tempohMasukIslam", - "type": "number", - "scope": "global", - "value": null, - "description": "Duration since converting to Islam (in years)" - }, - { - "name": "verificationDate", - "type": "string", - "scope": "global", - "value": null, - "description": "Date when verification was completed" - }, - { - "name": "applicationStatus", - "type": "string", - "scope": "global", - "value": "pending", - "description": "Current application status (pending/approved/rejected/under_review)" - }, - { - "name": "baseKifayahAmount", - "type": "decimal", - "scope": "global", - "value": null, - "description": "Base Had Kifayah amount for head of household (RM 1,215.00)" - }, - { - "name": "catatanPengesahan", - "type": "string", - "scope": "global", - "value": null, - "description": "Verification notes from officer" - }, - { - "name": "documentsComplete", - "type": "boolean", - "scope": "global", - "value": null, - "description": "Whether all documents are complete" - }, - { - "name": "documentsRequired", - "type": "boolean", - "scope": "global", - "value": true, - "description": "Whether documents verification is required" - }, - { - "name": "hasFamilyConflict", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether applicant has family conflict" - }, - { - "name": "hasUtilityArrears", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether applicant has utility arrears" - }, - { - "name": "jantinaTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Jantina tanggungan from Section B" - }, - { - "name": "kategoriAsnafSyor", - "type": "string", - "scope": "global", - "value": null, - "description": "Recommended asnaf category" - }, - { - "name": "keperluanMendesak", - "type": "array", - "scope": "global", - "value": null, - "description": "Apakah keperluan tuan/puan mendesak sekarang ini?" - }, - { - "name": "komitmenKosTinggi", - "type": "string", - "scope": "global", - "value": null, - "description": "Adakah tuan/puan mempunyai komitmen dan pembiayaan melibatkan kos yang tinggi?" - }, - { - "name": "namaPemegangAkaun", - "type": "string", - "scope": "global", - "value": null, - "description": "Nama pemegang akaun from Section B" - }, - { - "name": "notificationError", - "type": "object", - "scope": "global", - "value": null, - "description": "Error from notification sending process" - }, - { - "name": "peratusHadKifayah", - "type": "number", - "scope": "global", - "value": 0, - "description": "Percentage of had kifayah (income/total had kifayah * 100)" - }, - { - "name": "tarikhPengesyoran", - "type": "string", - "scope": "global", - "value": null, - "description": "Date of recommendation generation" - }, - { - "name": "verificationError", - "type": "string", - "scope": "global", - "value": null, - "description": "Error message from verification processing" - }, - { - "name": "verificationLevel", - "type": "string", - "scope": "global", - "value": "enhanced", - "description": "Level of verification required (standard/enhanced)" - }, - { - "name": "verificationNotes", - "type": "string", - "scope": "global", - "value": null, - "description": "Notes from document verification process" - }, - { - "name": "carianProfilStatus", - "type": "string", - "scope": "global", - "value": null, - "description": "The status of the profile search/login action" - }, - { - "name": "childcareAllowance", - "type": "number", - "scope": "global", - "value": null, - "description": "Childcare allowance for 12 years and below (RM 330.00)" - }, - { - "name": "conditionalMessage", - "type": "string", - "scope": "global", - "value": null, - "description": "Conditional message based on application status" - }, - { - "name": "dateMasukislamCopy", - "type": "string", - "scope": "global", - "value": null, - "description": "Date field for masuk Islam copy" - }, - { - "name": "dependentAllowance", - "type": "decimal", - "scope": "global", - "value": null, - "description": "Allowance per dependent (RM 408.00 for school age 7-17)" - }, - { - "name": "jenisKadTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Jenis kad tanggungan from Section B" - }, - { - "name": "pengesahanApiError", - "type": "object", - "scope": "global", - "value": null, - "description": "API error from verification submission" - }, - { - "name": "penilaianAwalError", - "type": "string", - "scope": "global", - "value": null, - "description": "Error message from penilaian awal processing" - }, - { - "name": "updatedProfileData", - "type": "object", - "scope": "global", - "value": null, - "description": "Updated profile data after changes" - }, - { - "name": "verificationStatus", - "type": "string", - "scope": "global", - "value": null, - "description": "Status of document verification process" - }, - { - "name": "canProceedToKifayah", - "type": "boolean", - "scope": "global", - "value": null, - "description": "Whether process can proceed to kifayah analysis" - }, - { - "name": "carianLoginPassword", - "type": "string", - "scope": "global", - "value": null, - "description": "Password for Asnaf login" - }, - { - "name": "hasDeathRelatedNeed", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether applicant has death-related needs" - }, - { - "name": "noTelefonTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "No telefon tanggungan from Section B" - }, - { - "name": "penilaianAwalStatus", - "type": "string", - "scope": "global", - "value": null, - "description": "Status of initial assessment submission" - }, - { - "name": "processingTimeHours", - "type": "number", - "scope": "global", - "value": null, - "description": "Total processing time in hours" - }, - { - "name": "profileUpdateStatus", - "type": "string", - "scope": "global", - "value": null, - "description": "Status of profile update process" - }, - { - "name": "spouseKifayahAmount", - "type": "decimal", - "scope": "global", - "value": null, - "description": "Had Kifayah amount for spouse (RM 780.00)" - }, - { - "name": "bangsaLainTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Bangsa lain tanggungan from Section B" - }, - { - "name": "bersekolahTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Bersekolah tanggungan from Section B" - }, - { - "name": "carianProfilApiError", - "type": "string", - "scope": "global", - "value": null, - "description": "Error from Carian Profil API" - }, - { - "name": "hasUploadedDocuments", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether documents were uploaded" - }, - { - "name": "hasUrgentMedicalNeed", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether applicant has urgent medical needs" - }, - { - "name": "hubunganLainNyatakan", - "type": "string", - "scope": "global", - "value": null, - "description": "Hubungan lain nyatakan from Section B" - }, - { - "name": "kifayahAnalysisError", - "type": "object", - "scope": "global", - "value": null, - "description": "Error from kifayah analysis API call" - }, - { - "name": "readyForPersonalInfo", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether ready for personal info form" - }, - { - "name": "syorPengesahanStatus", - "type": "string", - "scope": "global", - "value": "pending", - "description": "Status of AI recommendation generation" - }, - { - "name": "verificationApiError", - "type": "object", - "scope": "global", - "value": null, - "description": "Error from document verification API call" - }, - { - "name": "bilanganDewasaBekerja", - "type": "number", - "scope": "global", - "value": 1, - "description": "Number of working adults (18 years and above)" - }, - { - "name": "bilanganTanggunganIPT", - "type": "number", - "scope": "global", - "value": 0, - "description": "Number of dependents studying in higher education institutions" - }, - { - "name": "categoryKetuaKeluarga", - "type": "string", - "scope": "global", - "value": "ketua_keluarga", - "description": "Category for head of family" - }, - { - "name": "hasHighCostCommitment", - "type": "boolean", - "scope": "global", - "value": null, - "description": "Whether applicant has high cost commitments" - }, - { - "name": "kategoriKeluargaAsnaf", - "type": "string", - "scope": "global", - "value": null, - "description": "Family asnaf category (Fakir/Miskin/Non-FM)" - }, - { - "name": "keperluanLainNyatakan", - "type": "string", - "scope": "global", - "value": null, - "description": "Keperluan lain yang dinyatakan oleh pemohon" - }, - { - "name": "kifayahAnalysisResult", - "type": "object", - "scope": "global", - "value": null, - "description": "Result from kifayah eligibility analysis API" - }, - { - "name": "pengesahanApiResponse", - "type": "object", - "scope": "global", - "value": null, - "description": "API response from verification submission" - }, - { - "name": "pengesahanScriptError", - "type": "object", - "scope": "global", - "value": null, - "description": "Script error from pengesahan processing" - }, - { - "name": "penilaianAwalApiError", - "type": "string", - "scope": "global", - "value": null, - "description": "Error from the Penilaian Awal API" - }, - { - "name": "tarikhLahirTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Tarikh lahir tanggungan from Section B" - }, - { - "name": "tempatLahirTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Tempat lahir tanggungan from Section B" - }, - { - "name": "totalJumlahHadKifayah", - "type": "number", - "scope": "global", - "value": 0, - "description": "Total family had kifayah amount" - }, - { - "name": "verificationCompleted", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether verification process is completed" - }, - { - "name": "verificationProcessed", - "type": "boolean", - "scope": "global", - "value": null, - "description": "Whether verification processing is complete" - }, - { - "name": "verificationTimestamp", - "type": "string", - "scope": "global", - "value": null, - "description": "Timestamp when verification was completed" - }, - { - "name": "warganegaraTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Warganegara tanggungan from Section B" - }, - { - "name": "kifayahCalculationDate", - "type": "string", - "scope": "global", - "value": null, - "description": "Date and time when Had Kifayah was calculated" - }, - { - "name": "noPengenalanTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "No pengenalan tanggungan from Section B" - }, - { - "name": "statusKahwinTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Status kahwin tanggungan from Section B" - }, - { - "name": "tinggalBersamaKeluarga", - "type": "string", - "scope": "global", - "value": null, - "description": "Tinggal bersama keluarga from Section B" - }, - { - "name": "bilanganTanggungan7to17", - "type": "number", - "scope": "global", - "value": 2, - "description": "Number of dependents aged 7-17 years" - }, - { - "name": "carianProfilApiResponse", - "type": "object", - "scope": "global", - "value": null, - "description": "Response from Carian Profil API" - }, - { - "name": "carianProfilScriptError", - "type": "object", - "scope": "global", - "value": null, - "description": "Error from Carian Profil script execution" - }, - { - "name": "chronicIllnessAllowance", - "type": "number", - "scope": "global", - "value": null, - "description": "Chronic illness allowance (RM 243.00)" - }, - { - "name": "dependentEducationLevel", - "type": "array", - "scope": "global", - "value": ["smk"], - "description": "Dependent highest education from Section B" - }, - { - "name": "hadKifayahDewasaBekerja", - "type": "number", - "scope": "global", - "value": 412, - "description": "Had kifayah amount per working adult (RM 412.00)" - }, - { - "name": "hadKifayahTanggunganIPT", - "type": "number", - "scope": "global", - "value": 613, - "description": "Had kifayah amount per dependent in higher education (RM 613.00)" - }, - { - "name": "kifayahCalculationError", - "type": "object", - "scope": "global", - "value": null, - "description": "Error from Had Kifayah calculation" - }, - { - "name": "profileSubmissionStatus", - "type": "string", - "scope": "global", - "value": "success", - "description": "Status of profile submission" - }, - { - "name": "selectStatusperkahwinan", - "type": "string", - "scope": "global", - "value": null, - "description": "Select field for status perkahwinan" - }, - { - "name": "sendPendingNotification", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether to send pending status notification" - }, - { - "name": "tempatMenetapTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Tempat menetap tanggungan from Section B" - }, - { - "name": "verificationApiResponse", - "type": "object", - "scope": "global", - "value": null, - "description": "Response from document verification API" - }, - { - "name": "verificationCompletedAt", - "type": "string", - "scope": "global", - "value": null, - "description": "Timestamp when verification was completed" - }, - { - "name": "verificationScriptError", - "type": "object", - "scope": "global", - "value": null, - "description": "Error from verification response processing script" - }, - { - "name": "baseKifayahKetuaKeluarga", - "type": "number", - "scope": "global", - "value": 1215, - "description": "Base had kifayah amount for head of family (RM 1,215.00)" - }, - { - "name": "jumlahBantuanDicadangkan", - "type": "number", - "scope": "global", - "value": null, - "description": "Recommended assistance amount (RM)" - }, - { - "name": "kifayahCalculationResult", - "type": "object", - "scope": "global", - "value": null, - "description": "Result from Had Kifayah business rule calculation" - }, - { - "name": "kifayahCalculationStatus", - "type": "string", - "scope": "global", - "value": "pending", - "description": "Status of had kifayah calculation" - }, - { - "name": "kifayahNotificationError", - "type": "object", - "scope": "global", - "value": null, - "description": "Error from sending Had Kifayah notification" - }, - { - "name": "pendidikanLainTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Pendidikan lain tanggungan from Section B" - }, - { - "name": "penilaianAwalApiResponse", - "type": "object", - "scope": "global", - "value": null, - "description": "Response from the Penilaian Awal API" - }, - { - "name": "penilaianAwalScriptError", - "type": "object", - "scope": "global", - "value": null, - "description": "Error from Penilaian Awal script execution" - }, - { - "name": "sendApprovalNotification", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether to send approval notification" - }, - { - "name": "tarikhMulaKfamTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Tarikh mula KFAM tanggungan from Section B" - }, - { - "name": "dokumenTambahanDiperlukan", - "type": "array", - "scope": "global", - "value": null, - "description": "List of additional documents required" - }, - { - "name": "hadKifayahTanggungan7to17", - "type": "number", - "scope": "global", - "value": 408, - "description": "Had kifayah amount per dependent aged 7-17 years (RM 408.00)" - }, - { - "name": "sendRejectionNotification", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether to send rejection notification" - }, - { - "name": "statusRecommendationError", - "type": "object", - "scope": "global", - "value": null, - "description": "Error information from status recommendation" - }, - { - "name": "bilanganDewasaTidakBekerja", - "type": "number", - "scope": "global", - "value": 1, - "description": "Number of non-working adults (18 years and above)" - }, - { - "name": "bilanganTanggungan6KeBawah", - "type": "number", - "scope": "global", - "value": 1, - "description": "Number of dependents aged 6 years and below" - }, - { - "name": "dependentDocumentsComplete", - "type": "boolean", - "scope": "global", - "value": null, - "description": "Whether dependent documents are complete" - }, - { - "name": "documentVerificationResult", - "type": "string", - "scope": "global", - "value": null, - "description": "Result from document verification form (lengkap/tidak_lengkap)" - }, - { - "name": "statusRecommendationResult", - "type": "object", - "scope": "global", - "value": null, - "description": "Result of status recommendation process" - }, - { - "name": "tarikhMasukIslamTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Tarikh masuk Islam tanggungan from Section B" - }, - { - "name": "dependentVerificationStatus", - "type": "string", - "scope": "global", - "value": null, - "description": "Dependent verification status" - }, - { - "name": "hadKifayahDewasaTidakBekerja", - "type": "number", - "scope": "global", - "value": 167, - "description": "Had kifayah amount per non-working adult (RM 167.00)" - }, - { - "name": "hadKifayahTanggungan6KeBawah", - "type": "number", - "scope": "global", - "value": 175, - "description": "Had kifayah amount per dependent aged 6 years and below (RM 175.00)" - }, - { - "name": "totalHadKifayahDewasaBekerja", - "type": "number", - "scope": "global", - "value": 0, - "description": "Total had kifayah for working adults" - }, - { - "name": "totalHadKifayahTanggunganIPT", - "type": "number", - "scope": "global", - "value": 0, - "description": "Total had kifayah for dependents in higher education" - }, - { - "name": "pendidikanTertinggiTanggungan", - "type": "string", - "scope": "global", - "value": null, - "description": "Pendidikan tertinggi tanggungan from Section B" - }, - { - "name": "totalHadKifayahTanggungan7to17", - "type": "number", - "scope": "global", - "value": 0, - "description": "Total had kifayah for dependents aged 7-17 years" - }, - { - "name": "totalHadKifayahDewasaTidakBekerja", - "type": "number", - "scope": "global", - "value": 0, - "description": "Total had kifayah for non-working adults" - }, - { - "name": "totalHadKifayahTanggungan6KeBawah", - "type": "number", - "scope": "global", - "value": 0, - "description": "Total had kifayah for dependents aged 6 years and below" - } - ], - "metadata": { - "nodeCount": 0, - "edgeCount": 4, - "variableCount": 195, - "exportedAt": "2025-07-11T04:28:56.583Z" - } -} diff --git a/docs/json/process-builder/processDefinition.json b/docs/json/process-builder/processDefinition.json index f755507..086f63c 100644 --- a/docs/json/process-builder/processDefinition.json +++ b/docs/json/process-builder/processDefinition.json @@ -1,9 +1,9 @@ { "edges": [ { - "id": "start-1751870920411-form-1752471000000-1752110219601", + "id": "start-1751870920411-form-1752471000000-1752213918971", "data": {}, - "type": "smoothstep", + "type": "custom", "label": "", "source": "start-1751870920411", "target": "form-1752471000000", @@ -12,9 +12,9 @@ "targetHandle": "form-1752471000000-left" }, { - "id": "form-1752471000000-api-1752471000010-1752110221444", + "id": "form-1752471000000-api-1752471000010-1752213921952", "data": {}, - "type": "smoothstep", + "type": "custom", "label": "", "source": "form-1752471000000", "target": "api-1752471000010", @@ -23,9 +23,9 @@ "targetHandle": "api-1752471000010-top" }, { - "id": "api-1752471000010-script-1752471000020-1752110222889", + "id": "api-1752471000010-script-1752471000020-1752213928277", "data": {}, - "type": "smoothstep", + "type": "custom", "label": "", "source": "api-1752471000010", "target": "script-1752471000020", @@ -34,9 +34,9 @@ "targetHandle": "script-1752471000020-left" }, { - "id": "script-1752471000020-form-1751870928350-1752110513125", + "id": "script-1752471000020-form-1751870928350-1752213932854", "data": {}, - "type": "smoothstep", + "type": "custom", "label": "", "source": "script-1752471000020", "target": "form-1751870928350", @@ -45,9 +45,9 @@ "targetHandle": "form-1751870928350-left" }, { - "id": "form-1751870928350-api-1751871528249-1752110547688", + "id": "form-1751870928350-api-1751871528249-1752213937166", "data": {}, - "type": "smoothstep", + "type": "custom", "label": "", "source": "form-1751870928350", "target": "api-1751871528249", @@ -56,9 +56,9 @@ "targetHandle": "api-1751871528249-top" }, { - "id": "api-1751871528249-script-1751871635000-1752110661170", + "id": "api-1751871528249-script-1751871635000-1752213939472", "data": {}, - "type": "smoothstep", + "type": "custom", "label": "", "source": "api-1751871528249", "target": "script-1751871635000", @@ -67,141 +67,9 @@ "targetHandle": "script-1751871635000-left" }, { - "id": "start-1751870920411-form-1753000000000-1752115210580", + "id": "gateway-family-tree-choice-form-kategori-asnaf-1752213977562", "data": {}, - "type": "smoothstep", - "label": "", - "source": "start-1751870920411", - "target": "form-1753000000000", - "animated": true, - "sourceHandle": "start-1751870920411-right", - "targetHandle": "form-1753000000000-left" - }, - { - "id": "form-1753000000000-api-1753000000001-1752115217959", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "form-1753000000000", - "target": "api-1753000000001", - "animated": true, - "sourceHandle": "form-1753000000000-bottom", - "targetHandle": "api-1753000000001-top" - }, - { - "id": "api-1753000000001-script-1753000000002-1752115222952", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "api-1753000000001", - "target": "script-1753000000002", - "animated": true, - "sourceHandle": "api-1753000000001-right", - "targetHandle": "script-1753000000002-left" - }, - { - "id": "script-1753000000002-gateway-1753100000000-1752202680793", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "script-1753000000002", - "target": "gateway-1753100000000", - "animated": true, - "sourceHandle": "script-1753000000002-right", - "targetHandle": "gateway-1753100000000-left" - }, - { - "id": "gateway-1753100000000-form-1751870928350-1752202820616", - "data": {}, - "type": "smoothstep", - "label": "Tidak", - "source": "gateway-1753100000000", - "target": "form-1751870928350", - "animated": true, - "sourceHandle": "gateway-1753100000000-right", - "targetHandle": "form-1751870928350-left" - }, - { - "id": "form-1753100000001-gateway-1753100000002-1752202841767", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "form-1753100000001", - "target": "gateway-1753100000002", - "animated": true, - "sourceHandle": "form-1753100000001-right", - "targetHandle": "gateway-1753100000002-left" - }, - { - "id": "gateway-1753100000002-subprocess-1753100000003-1752202973206", - "data": {}, - "type": "smoothstep", - "label": "Ya", - "source": "gateway-1753100000002", - "target": "subprocess-1753100000003", - "animated": true, - "sourceHandle": "gateway-1753100000002-right", - "targetHandle": "subprocess-1753100000003-left" - }, - { - "id": "gateway-1753100000000-form-1753100000001-1752203198190", - "data": {}, - "type": "smoothstep", - "label": "Ya", - "source": "gateway-1753100000000", - "target": "form-1753100000001", - "animated": true, - "sourceHandle": "gateway-1753100000000-right", - "targetHandle": "form-1753100000001-top" - }, - { - "id": "script-1751871635000-form-family-tree-choice-1752204006162", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "script-1751871635000", - "target": "form-family-tree-choice", - "animated": true, - "sourceHandle": "script-1751871635000-right", - "targetHandle": "form-family-tree-choice-left" - }, - { - "id": "form-family-tree-choice-gateway-family-tree-choice-1752204014461", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "form-family-tree-choice", - "target": "gateway-family-tree-choice", - "animated": true, - "sourceHandle": "form-family-tree-choice-bottom", - "targetHandle": "gateway-family-tree-choice-left" - }, - { - "id": "gateway-family-tree-choice-api-1752114771983-1752204050925", - "data": {}, - "type": "smoothstep", - "label": "Ya", - "source": "gateway-family-tree-choice", - "target": "api-1752114771983", - "animated": true, - "sourceHandle": "gateway-family-tree-choice-right", - "targetHandle": "api-1752114771983-left" - }, - { - "id": "api-1752114771983-html-1752109761532-1752204167660", - "data": {}, - "type": "smoothstep", - "label": "", - "source": "api-1752114771983", - "target": "html-1752109761532", - "animated": true, - "sourceHandle": "api-1752114771983-bottom", - "targetHandle": "html-1752109761532-left" - }, - { - "id": "gateway-family-tree-choice-form-kategori-asnaf-1752204312974", - "data": {}, - "type": "smoothstep", + "type": "custom", "label": "Tidak", "source": "gateway-family-tree-choice", "target": "form-kategori-asnaf", @@ -210,20 +78,130 @@ "targetHandle": "form-kategori-asnaf-top" }, { - "id": "form-kategori-asnaf-gateway-fakir-miskin-choice-1752204332412", + "id": "form-pengesahan-api-pengesahan-submit-1752214069039", "data": {}, - "type": "smoothstep", + "type": "custom", "label": "", - "source": "form-kategori-asnaf", - "target": "gateway-fakir-miskin-choice", + "source": "form-pengesahan", + "target": "api-pengesahan-submit", "animated": true, - "sourceHandle": "form-kategori-asnaf-bottom", - "targetHandle": "gateway-fakir-miskin-choice-left" + "sourceHandle": "form-pengesahan-bottom", + "targetHandle": "api-pengesahan-submit-left" }, { - "id": "gateway-1753100000002-subprocess-1752202751327-1752204374213", + "id": "api-pengesahan-submit-script-process-pengesahan-1752214088487", "data": {}, - "type": "smoothstep", + "type": "custom", + "label": "", + "source": "api-pengesahan-submit", + "target": "script-process-pengesahan", + "animated": true, + "sourceHandle": "api-pengesahan-submit-right", + "targetHandle": "script-process-pengesahan-left" + }, + { + "id": "script-process-pengesahan-gateway-status-check-1752214096335", + "data": {}, + "type": "custom", + "label": "", + "source": "script-process-pengesahan", + "target": "gateway-status-check", + "animated": true, + "sourceHandle": "script-process-pengesahan-bottom", + "targetHandle": "gateway-status-check-left" + }, + { + "id": "start-1751870920411-form-1753000000000-1752214106743", + "data": {}, + "type": "custom", + "label": "", + "source": "start-1751870920411", + "target": "form-1753000000000", + "animated": true, + "sourceHandle": "start-1751870920411-right", + "targetHandle": "form-1753000000000-left" + }, + { + "id": "form-1753000000000-api-1753000000001-1752214111161", + "data": {}, + "type": "custom", + "label": "", + "source": "form-1753000000000", + "target": "api-1753000000001", + "animated": true, + "sourceHandle": "form-1753000000000-bottom", + "targetHandle": "api-1753000000001-top" + }, + { + "id": "api-1753000000001-script-1753000000002-1752214115516", + "data": {}, + "type": "custom", + "label": "", + "source": "api-1753000000001", + "target": "script-1753000000002", + "animated": true, + "sourceHandle": "api-1753000000001-right", + "targetHandle": "script-1753000000002-left" + }, + { + "id": "script-1753000000002-gateway-1753100000000-1752214119151", + "data": {}, + "type": "custom", + "label": "", + "source": "script-1753000000002", + "target": "gateway-1753100000000", + "animated": true, + "sourceHandle": "script-1753000000002-right", + "targetHandle": "gateway-1753100000000-left" + }, + { + "id": "gateway-1753100000000-form-1753100000001-1752214129187", + "data": {}, + "type": "custom", + "label": "Ya", + "source": "gateway-1753100000000", + "target": "form-1753100000001", + "animated": true, + "sourceHandle": "gateway-1753100000000-right", + "targetHandle": "form-1753100000001-top" + }, + { + "id": "gateway-1753100000000-form-1751870928350-1752214132173", + "data": {}, + "type": "custom", + "label": "Tidak", + "source": "gateway-1753100000000", + "target": "form-1751870928350", + "animated": true, + "sourceHandle": "gateway-1753100000000-right", + "targetHandle": "form-1751870928350-left" + }, + { + "id": "form-1753100000001-gateway-1753100000002-1752214140594", + "data": {}, + "type": "custom", + "label": "", + "source": "form-1753100000001", + "target": "gateway-1753100000002", + "animated": true, + "sourceHandle": "form-1753100000001-right", + "targetHandle": "gateway-1753100000002-left" + }, + { + "id": "gateway-1753100000002-subprocess-1753100000003-1752214144896", + "data": {}, + "type": "custom", + "label": "Ya", + "source": "gateway-1753100000002", + "target": "subprocess-1753100000003", + "animated": true, + "sourceHandle": "gateway-1753100000002-right", + "targetHandle": "subprocess-1753100000003-left" + }, + { + "id": "gateway-1753100000002-subprocess-1752202751327-1752214146974", + "data": {}, + "type": "custom", "label": "Tidak", "source": "gateway-1753100000002", "target": "subprocess-1752202751327", @@ -232,22 +210,132 @@ "targetHandle": "subprocess-1752202751327-left" }, { - "id": "gateway-fakir-miskin-choice-business-rule-1751871900000-1752204422657", + "id": "gateway-status-check-subprocess-1752202751327-1752214182325", "data": {}, - "type": "smoothstep", + "type": "custom", + "label": "Berjaya FM", + "source": "gateway-status-check", + "target": "subprocess-1752202751327", + "animated": true, + "sourceHandle": "gateway-status-check-right", + "targetHandle": "subprocess-1752202751327-left" + }, + { + "id": "gateway-status-check-subprocess-1752208906615-1752214184716", + "data": {}, + "type": "custom", + "label": "Berjaya Non-FM", + "source": "gateway-status-check", + "target": "subprocess-1752208906615", + "animated": true, + "sourceHandle": "gateway-status-check-right", + "targetHandle": "subprocess-1752208906615-left" + }, + { + "id": "gateway-status-check-notification-1753200000001-1752214194993", + "data": {}, + "type": "custom", + "label": "Berjaya Fakir Miskin & Non-FM", + "source": "gateway-status-check", + "target": "notification-1753200000001", + "animated": true, + "sourceHandle": "gateway-status-check-right", + "targetHandle": "notification-1753200000001-left" + }, + { + "id": "gateway-status-check-notification-1753200000001-1752214200770", + "data": {}, + "type": "custom", + "label": "Gagal", + "source": "gateway-status-check", + "target": "notification-1753200000001", + "animated": true, + "sourceHandle": "gateway-status-check-right", + "targetHandle": "notification-1753200000001-left" + }, + { + "id": "script-1751871635000-api-1752114771983-1752224956615", + "data": {}, + "type": "custom", + "label": "", + "source": "script-1751871635000", + "target": "api-1752114771983", + "animated": true, + "sourceHandle": "script-1751871635000-right", + "targetHandle": "api-1752114771983-left" + }, + { + "id": "api-1752114771983-gateway-family-tree-choice-1752224958790", + "data": {}, + "type": "custom", + "label": "", + "source": "api-1752114771983", + "target": "gateway-family-tree-choice", + "animated": true, + "sourceHandle": "api-1752114771983-bottom", + "targetHandle": "gateway-family-tree-choice-left" + }, + { + "id": "gateway-family-tree-choice-html-1752109761532-1752224992397", + "data": {}, + "type": "custom", "label": "Ya", - "source": "gateway-fakir-miskin-choice", + "source": "gateway-family-tree-choice", + "target": "html-1752109761532", + "animated": true, + "sourceHandle": "gateway-family-tree-choice-right", + "targetHandle": "html-1752109761532-left" + }, + { + "id": "form-kategori-asnaf-business-rule-1751871900000-1752225961535", + "data": {}, + "type": "custom", + "label": "", + "source": "form-kategori-asnaf", "target": "business-rule-1751871900000", "animated": true, - "sourceHandle": "gateway-fakir-miskin-choice-right", + "sourceHandle": "form-kategori-asnaf-right", "targetHandle": "business-rule-1751871900000-left" + }, + { + "id": "business-rule-1751871900000-business-rule-1751871901000-1752225963292", + "data": {}, + "type": "custom", + "label": "", + "source": "business-rule-1751871900000", + "target": "business-rule-1751871901000", + "animated": true, + "sourceHandle": "business-rule-1751871900000-right", + "targetHandle": "business-rule-1751871901000-left" + }, + { + "id": "business-rule-1751871901000-form-pengesahan-1752226611009", + "data": {}, + "type": "custom", + "label": "", + "source": "business-rule-1751871901000", + "target": "form-pengesahan", + "animated": true, + "sourceHandle": "business-rule-1751871901000-right", + "targetHandle": "form-pengesahan-top" + }, + { + "id": "business-rule-1751871901000-notification-1753200000002-1752226620873", + "data": {}, + "type": "custom", + "label": "", + "source": "business-rule-1751871901000", + "target": "notification-1753200000002", + "animated": true, + "sourceHandle": "business-rule-1751871901000-right", + "targetHandle": "notification-1753200000002-top" } ], "nodes": [ { "id": "gateway-family-tree-choice", "data": { - "label": "Lihat Family Tree?", + "label": "Lihat Tanggungan", "shape": "diamond", "textColor": "#374151", "conditions": [ @@ -282,94 +370,25 @@ ], "borderColor": "#6b7280", "defaultPath": "gateway-fakir-miskin-choice", - "description": "Choose whether to view family tree", + "description": "Check if have dependency", "gatewayType": "exclusive", "backgroundColor": "#f9fafb" }, "type": "gateway", - "label": "Lihat Family Tree?", + "label": "Lihat Tanggungan", "position": { "x": 2070, "y": -345 } }, - { - "id": "form-family-tree-choice", - "data": { - "label": "Pilihan Family Tree", - "formId": 6, - "formName": "Pilihan Family Tree", - "formUuid": "6e07fc8f-a160-478a-85fd-fa3364401547", - "description": "Form untuk memilih sama ada mahu lihat family tree atau tidak", - "assignedRoles": [], - "assignedUsers": [], - "inputMappings": [ - { "formField": "nama_pemohon", "processVariable": "applicantName" } - ], - "assignmentType": "public", - "outputMappings": [ - { - "formField": "lihat_family_tree", - "processVariable": "lihatFamilyTree" - } - ], - "fieldConditions": [] - }, - "type": "form", - "label": "Pilihan Family Tree", - "position": { "x": 2040, "y": -540 } - }, - { - "id": "gateway-fakir-miskin-choice", - "data": { - "label": "Fakir Miskin?", - "shape": "diamond", - "textColor": "#333333", - "conditions": [ - { - "id": "condition-group-ya-path", - "output": "Ya", - "conditions": [ - { - "id": "condition-1", - "value": "fakir_miskin", - "operator": "eq", - "variable": "kategoriAsnaf", - "valueType": "string", - "logicalOperator": "and" - } - ] - }, - { - "id": "condition-group-tidak-path", - "output": "Tidak", - "conditions": [ - { - "id": "condition-2", - "value": "bukan_fakir_miskin", - "operator": "eq", - "variable": "kategoriAsnaf", - "valueType": "string", - "logicalOperator": "and" - } - ] - } - ], - "borderColor": "#6b7280", - "defaultPath": "business-rule-1751871900000", - "description": "Determine if applicant is Fakir Miskin", - "gatewayType": "exclusive", - "backgroundColor": "#f9fafb" - }, - "type": "gateway", - "label": "Fakir Miskin?", - "position": { "x": 2085, "y": 210 } - }, { "id": "form-kategori-asnaf", "data": { "label": "Pilihan Kategori Asnaf", + "shape": "rectangle", "formId": 7, "formName": "Pilihan Kategori Asnaf", "formUuid": "7e07fc8f-a160-478a-85fd-fa3364401548", - "description": "Form untuk memilih kategori asnaf", + "textColor": "#6b21a8", + "borderColor": "#9333ea", + "description": "Form untuk papar syor bantuan", "assignedRoles": [], "assignedUsers": [], "inputMappings": [ @@ -379,18 +398,19 @@ "outputMappings": [ { "formField": "kategori_asnaf", "processVariable": "kategoriAsnaf" } ], + "backgroundColor": "#faf5ff", "fieldConditions": [] }, "type": "form", - "label": "Pilihan Kategori Asnaf", - "position": { "x": 2055, "y": -30 } + "label": "Papar Syor Bantuan", + "position": { "x": 1995, "y": -30 } }, { "id": "start-1751870920411", "data": { "label": "Start", "description": "Process start point" }, "type": "start", "label": "Start", - "position": { "x": -75, "y": -510 } + "position": { "x": 75, "y": -510 } }, { "id": "form-1752471000000", @@ -438,13 +458,17 @@ "id": "api-1752471000010", "data": { "label": "Submit Penilaian Awal API", + "shape": "rectangle", "apiUrl": "https://jsonplaceholder.typicode.com/posts", "headers": "{ \"Content-Type\": \"application/json\" }", "apiMethod": "POST", + "textColor": "#c2410c", + "borderColor": "#f97316", "description": "Submit penilaian awal data to external system", "requestBody": "{\n \"komitmenKosTinggi\": \"{komitmenKosTinggi}\",\n \"keperluanMendesak\": \"{keperluanMendesak}\",\n \"keperluanLainNyatakan\": \"{keperluanLainNyatakan}\",\n \"dokumenBerkaitan\": \"{dokumenBerkaitan}\",\n \"catatanTambahan\": \"{catatanTambahan}\"\n}", "errorVariable": "penilaianAwalApiError", "outputVariable": "penilaianAwalApiResponse", + "backgroundColor": "#fff7ed", "continueOnError": false }, "type": "api", @@ -702,13 +726,17 @@ "id": "api-1751871528249", "data": { "label": "Submit Profile API", + "shape": "rectangle", "apiUrl": "https://jsonplaceholder.typicode.com/posts", "headers": "{ \"Content-Type\": \"application/json\" }", "apiMethod": "POST", + "textColor": "#c2410c", + "borderColor": "#f97316", "description": "Submit user profile to external system", "requestBody": "{\n \"applicantName\": \"{text3}\",\n \"idType\": \"{select1}\",\n \"mykadNumber\": \"{formJeniskp1}\",\n \"passportNumber\": \"{formJeniskp2}\",\n \"birthCertNumber\": \"{formJeniskp3}\",\n \"nationality\": \"{textWarganegara}\",\n \"gender\": \"{radioJantina}\",\n \"race\": \"{radioBangsa}\",\n \"otherRace\": \"{nyatakanLain2}\",\n \"isStudying\": \"{radio9Copy}\",\n \"education\": \"{radioPendidikan}\",\n \"otherEducation\": \"{text14}\",\n \"islamConversionDate\": \"{dateMasukislam}\",\n \"kfamStartDate\": \"{dateMasukislamCopy}\",\n \"maritalStatus\": \"{selectStatusperkahwinan}\",\n \"dependentInfo\": {\n \"relationship\": \"{hubunganKeluarga}\",\n \"otherRelationship\": \"{hubunganLainNyatakan}\",\n \"name\": \"{namaTanggungan}\",\n \"idType\": \"{jenisKadTanggungan}\",\n \"idNumber\": \"{noPengenalanTanggungan}\",\n \"gender\": \"{jantinaTanggungan}\",\n \"birthDate\": \"{tarikhLahirTanggungan}\",\n \"birthPlace\": \"{tempatLahirTanggungan}\",\n \"race\": \"{bangsaTanggungan}\",\n \"otherRace\": \"{bangsaLainTanggungan}\",\n \"maritalStatus\": \"{statusKahwinTanggungan}\",\n \"islamConversionDate\": \"{tarikhMasukIslamTanggungan}\",\n \"kfamStartDate\": \"{tarikhMulaKfamTanggungan}\",\n \"nationality\": \"{warganegaraTanggungan}\",\n \"residenceDuration\": \"{tempatMenetapTanggungan}\",\n \"phoneNumber\": \"{noTelefonTanggungan}\",\n \"isStudying\": \"{bersekolahTanggungan}\",\n \"education\": \"{pendidikanTertinggiTanggungan}\",\n \"otherEducation\": \"{pendidikanLainTanggungan}\",\n \"schoolName\": \"{namaSekolah}\",\n \"schoolAddress\": \"{alamatSekolah}\",\n \"schoolDistrict\": \"{daerahSekolah}\",\n \"schoolState\": \"{negeriSekolah}\",\n \"schoolPostcode\": \"{poskodSekolah}\",\n \"liveWithFamily\": \"{tinggalBersamaKeluarga}\"\n },\n \"bankingInfo\": {\n \"accountHolderName\": \"{namaPemegangAkaun}\",\n \"bankName\": \"{namaBank}\",\n \"accountNumber\": \"{noAkaunBank}\",\n \"paymentMethod\": \"{caraPembayaran}\",\n \"cashReason\": \"{sebabTunai}\"\n }\n}", "errorVariable": "apiError", "outputVariable": "apiResponse", + "backgroundColor": "#fff7ed", "continueOnError": false }, "type": "api", @@ -794,361 +822,380 @@ "label": "Process API Response", "position": { "x": 1590, "y": -345 } }, - { - "id": "form-1751871700000", - "data": { - "label": "Borang Semak Dokumen", - "formId": 2, - "formName": "Borang Semak Dokumen", - "formUuid": "2a15fc8f-c270-478a-95fd-fa4364401644", - "description": "Document verification form", - "assignedRoles": ["verifier"], - "assignedUsers": [], - "inputMappings": [ - { - "formField": "reference_number", - "processVariable": "applicationId" - }, - { "formField": "applicant_name", "processVariable": "applicantName" }, - { "formField": "dependent_name", "processVariable": "dependentName" }, - { "formField": "has_dependents", "processVariable": "hasDependents" }, - { - "formField": "verification_level", - "processVariable": "verificationLevel" - } - ], - "assignmentType": "role", - "outputMappings": [ - { - "formField": "verification_result", - "processVariable": "documentVerificationResult" - }, - { - "formField": "verification_notes", - "processVariable": "verificationNotes" - } - ], - "fieldConditions": [], - "assignmentVariable": "", - "assignmentVariableType": "user_id" - }, - "type": "form", - "label": "Borang Semak Dokumen", - "position": { "x": 825, "y": 945 } - }, - { - "id": "api-1751871750000", - "data": { - "label": "Submit Document Verification API", - "apiUrl": "https://api.example.com/documents/verify", - "headers": "{ \"Content-Type\": \"application/json\", \"Authorization\": \"Bearer {apiToken}\" }", - "apiMethod": "POST", - "description": "Submit document verification results to external system", - "requestBody": "{\n \"applicationId\": \"{applicationId}\",\n \"applicantName\": \"{applicantName}\",\n \"verificationResult\": \"{documentVerificationResult}\",\n \"verificationNotes\": \"{verificationNotes}\",\n \"verificationLevel\": \"{verificationLevel}\",\n \"verifiedBy\": \"{verifiedBy}\",\n \"verificationDate\": \"{verificationDate}\",\n \"documentStatus\": {\n \"applicantId\": \"{formJeniskp1}\",\n \"dependentInfo\": {\n \"hasDependents\": {hasDependents},\n \"dependentName\": \"{dependentName}\",\n \"dependentId\": \"{noPengenalanTanggungan}\"\n },\n \"bankingVerified\": {hasBankingInfo},\n \"profileScore\": {profileScore}\n }\n}", - "errorVariable": "verificationApiError", - "outputVariable": "verificationApiResponse", - "continueOnError": false - }, - "type": "api", - "label": "Submit Document Verification API", - "position": { "x": 1170, "y": 810 } - }, - { - "id": "script-1751871770000", - "data": { - "label": "Process Verification Response", - "scriptCode": "// Process document verification API response\nconst verificationData = processVariables.verificationApiResponse;\n\nif (verificationData && verificationData.data) {\n // Extract verification status\n processVariables.verificationStatus = verificationData.data.status || 'pending';\n \n // Set document completeness based on verification result\n if (processVariables.documentVerificationResult === 'lengkap') {\n processVariables.documentsComplete = true;\n processVariables.canProceedToKifayah = true;\n \n // Extract additional data from verification response\n if (verificationData.data.eligibilityScore) {\n processVariables.eligibilityScore = verificationData.data.eligibilityScore;\n }\n \n if (verificationData.data.riskAssessment) {\n processVariables.riskAssessment = verificationData.data.riskAssessment;\n }\n \n // Set verification completion timestamp\n processVariables.verificationCompletedAt = new Date().toISOString();\n \n } else {\n processVariables.documentsComplete = false;\n processVariables.canProceedToKifayah = false;\n processVariables.rejectionReason = processVariables.verificationNotes || 'Dokumen tidak lengkap';\n }\n \n // Process dependent verification if applicable\n if (processVariables.hasDependents && verificationData.data.dependentVerification) {\n processVariables.dependentVerificationStatus = verificationData.data.dependentVerification.status;\n processVariables.dependentDocumentsComplete = verificationData.data.dependentVerification.documentsComplete;\n }\n \n // Set next step readiness\n processVariables.verificationProcessed = true;\n processVariables.readyForDecision = true;\n \n console.log('Verification processed successfully:', {\n verificationStatus: processVariables.verificationStatus,\n documentsComplete: processVariables.documentsComplete,\n canProceedToKifayah: processVariables.canProceedToKifayah,\n eligibilityScore: processVariables.eligibilityScore\n });\n \n} else {\n // Handle verification API error\n processVariables.verificationStatus = 'failed';\n processVariables.documentsComplete = false;\n processVariables.canProceedToKifayah = false;\n processVariables.verificationError = 'Failed to process verification';\n processVariables.readyForDecision = false;\n}", - "description": "Process document verification API response and set decision variables", - "errorVariable": "verificationScriptError", - "inputVariables": [ - "verificationApiResponse", - "documentVerificationResult", - "verificationNotes", - "hasDependents", - "dependentName" - ], - "scriptLanguage": "javascript", - "continueOnError": false, - "outputVariables": [ - { - "name": "verificationStatus", - "type": "string", - "description": "Status of document verification process" - }, - { - "name": "documentsComplete", - "type": "boolean", - "description": "Whether all documents are complete" - }, - { - "name": "canProceedToKifayah", - "type": "boolean", - "description": "Whether process can proceed to kifayah analysis" - }, - { - "name": "eligibilityScore", - "type": "number", - "description": "Eligibility score from verification" - }, - { - "name": "riskAssessment", - "type": "string", - "description": "Risk assessment result" - }, - { - "name": "verificationCompletedAt", - "type": "string", - "description": "Timestamp when verification was completed" - }, - { - "name": "rejectionReason", - "type": "string", - "description": "Reason for rejection if documents incomplete" - }, - { - "name": "dependentVerificationStatus", - "type": "string", - "description": "Dependent verification status" - }, - { - "name": "dependentDocumentsComplete", - "type": "boolean", - "description": "Whether dependent documents are complete" - }, - { - "name": "verificationProcessed", - "type": "boolean", - "description": "Whether verification processing is complete" - }, - { - "name": "readyForDecision", - "type": "boolean", - "description": "Whether ready for decision gateway" - } - ] - }, - "type": "script", - "label": "Process Verification Response", - "position": { "x": 540, "y": 780 } - }, - { - "id": "gateway-1751871800000", - "data": { - "label": "Lengkap?", - "shape": "diamond", - "textColor": "#333333", - "conditions": [ - { - "id": "condition-group-ya-path", - "output": "Ya", - "conditions": [ - { - "id": "condition-1", - "value": "lengkap", - "operator": "eq", - "variable": "documentVerificationResult", - "valueType": "string", - "logicalOperator": "and" - } - ] - }, - { - "id": "condition-group-tidak-path", - "output": "Tidak", - "conditions": [ - { - "id": "condition-2", - "value": "tidak_lengkap", - "operator": "eq", - "variable": "documentVerificationResult", - "valueType": "string", - "logicalOperator": "and" - } - ] - } - ], - "borderColor": "#6b7280", - "defaultPath": "notification-1751872000000", - "description": "Check if documents are complete", - "gatewayType": "exclusive", - "backgroundColor": "#f9fafb" - }, - "type": "gateway", - "label": "Lengkap?", - "position": { "x": 1935, "y": 510 } - }, { "id": "business-rule-1751871900000", "data": { - "label": "Analisis Had Kifayah", + "label": "BF-NAS-PRF-AS-QS-03", "shape": "rectangle", + "priority": "medium", "textColor": "#1e40af", "ruleGroups": [ { "id": "group-1", - "name": "Married with Dependents", + "name": "Ketua Keluarga Base Amount", "actions": [ { "id": "action-1-1", "type": "set_variable", - "value": "married_with_dependents", - "variable": "householdType" + "value": 1215, + "variable": "baseKifayahKetuaKeluarga" }, { "id": "action-1-2", "type": "set_variable", - "value": 1215, - "variable": "baseKifayahAmount" - }, - { - "id": "action-1-3", - "type": "set_variable", - "value": 780, - "variable": "spouseKifayahAmount" + "value": "ketua_keluarga", + "variable": "categoryKetuaKeluarga" } ], "operator": "AND", "conditions": [ { "id": "condition-1-1", - "value": "berkahwin", - "operator": "eq", - "variable": "selectStatusperkahwinan" - }, - { - "id": "condition-1-2", - "value": true, - "operator": "eq", - "variable": "hasDependents" + "value": "", + "operator": "neq", + "variable": "noKadPengenalan", + "valueType": "string" } ] }, { "id": "group-2", - "name": "Single with Dependents", + "name": "Dewasa Bekerja (18 Tahun Ke Atas)", "actions": [ { "id": "action-2-1", "type": "set_variable", - "value": "single_with_dependents", - "variable": "householdType" + "value": 412, + "variable": "hadKifayahDewasaBekerja" }, { "id": "action-2-2", - "type": "set_variable", - "value": 1215, - "variable": "baseKifayahAmount" - }, - { - "id": "action-2-3", - "type": "set_variable", - "value": 0, - "variable": "spouseKifayahAmount" + "type": "increment", + "formula": "hadKifayahDewasaBekerja * bilanganDewasaBekerja", + "variable": "totalHadKifayahDewasaBekerja" } ], "operator": "AND", "conditions": [ { "id": "condition-2-1", - "value": "berkahwin", - "operator": "neq", - "variable": "selectStatusperkahwinan" - }, - { - "id": "condition-2-2", - "value": true, - "operator": "eq", - "variable": "hasDependents" + "value": 0, + "operator": "gt", + "variable": "bilanganDewasaBekerja" } ] }, { "id": "group-3", - "name": "Calculate Dependent Allowance", + "name": "Dewasa Tidak Bekerja (18 Tahun Ke Atas)", "actions": [ { "id": "action-3-1", "type": "set_variable", - "value": 408, - "variable": "dependentAllowance" + "value": 167, + "variable": "hadKifayahDewasaTidakBekerja" }, { "id": "action-3-2", - "type": "set_variable", - "value": "school_age_7_17", - "variable": "dependentType" + "type": "increment", + "formula": "hadKifayahDewasaTidakBekerja * bilanganDewasaTidakBekerja", + "variable": "totalHadKifayahDewasaTidakBekerja" } ], "operator": "AND", "conditions": [ { "id": "condition-3-1", - "value": true, - "operator": "eq", - "variable": "hasDependents" + "value": 0, + "operator": "gt", + "variable": "bilanganDewasaTidakBekerja" + } + ] + }, + { + "id": "group-4", + "name": "Tanggungan Belajar IPT", + "actions": [ + { + "id": "action-4-1", + "type": "set_variable", + "value": 613, + "variable": "hadKifayahTanggunganIPT" }, { - "id": "condition-3-2", - "value": "ya", - "operator": "eq", - "variable": "bersekolahTanggungan" + "id": "action-4-2", + "type": "increment", + "formula": "hadKifayahTanggunganIPT * bilanganTanggunganIPT", + "variable": "totalHadKifayahTanggunganIPT" + } + ], + "operator": "AND", + "conditions": [ + { + "id": "condition-4-1", + "value": 0, + "operator": "gt", + "variable": "bilanganTanggunganIPT" + } + ] + }, + { + "id": "group-5", + "name": "Tanggungan Berumur 7-17 tahun", + "actions": [ + { + "id": "action-5-1", + "type": "set_variable", + "value": 408, + "variable": "hadKifayahTanggungan7to17" + }, + { + "id": "action-5-2", + "type": "increment", + "formula": "hadKifayahTanggungan7to17 * bilanganTanggungan7to17", + "variable": "totalHadKifayahTanggungan7to17" + } + ], + "operator": "AND", + "conditions": [ + { + "id": "condition-5-1", + "value": 0, + "operator": "gt", + "variable": "bilanganTanggungan7to17" + } + ] + }, + { + "id": "group-6", + "name": "Tanggungan 6 Tahun Ke Bawah", + "actions": [ + { + "id": "action-6-1", + "type": "set_variable", + "value": 175, + "variable": "hadKifayahTanggungan6KeBawah" + }, + { + "id": "action-6-2", + "type": "increment", + "formula": "hadKifayahTanggungan6KeBawah * bilanganTanggungan6KeBawah", + "variable": "totalHadKifayahTanggungan6KeBawah" + } + ], + "operator": "AND", + "conditions": [ + { + "id": "condition-6-1", + "value": 0, + "operator": "gt", + "variable": "bilanganTanggungan6KeBawah" + } + ] + }, + { + "id": "group-7", + "name": "Calculate Total Had Kifayah", + "actions": [ + { + "id": "action-7-1", + "type": "calculation", + "formula": "baseKifayahKetuaKeluarga + (totalHadKifayahDewasaBekerja || 0) + (totalHadKifayahDewasaTidakBekerja || 0) + (totalHadKifayahTanggunganIPT || 0) + (totalHadKifayahTanggungan7to17 || 0) + (totalHadKifayahTanggungan6KeBawah || 0)", + "variable": "totalJumlahHadKifayah" + }, + { + "id": "action-7-2", + "type": "calculation", + "formula": "((pendapatanBersih || 0) / totalJumlahHadKifayah) * 100", + "variable": "peratusHadKifayah" + }, + { + "id": "action-7-3", + "type": "set_variable", + "value": "completed", + "variable": "kifayahCalculationStatus" + } + ], + "operator": "AND", + "conditions": [ + { + "id": "condition-7-1", + "value": "", + "operator": "neq", + "variable": "noKadPengenalan" } ] } ], "borderColor": "#3b82f6", - "description": "Calculate Had Kifayah based on household composition and income", + "description": " Analisa Data (Had Kifayah)", "errorVariable": "kifayahCalculationError", "outputVariable": "kifayahCalculationResult", "backgroundColor": "#eff6ff" }, "type": "business-rule", - "label": "Analisis Had Kifayah", - "position": { "x": 2445, "y": -45 } + "label": "BF-NAS-PRF-AS-QS-03", + "position": { "x": 2250, "y": -30 } }, { - "id": "notification-1751871950000", + "id": "business-rule-1751871901000", "data": { - "label": "Hantar Keputusan Had Kifayah", - "message": "Assalamualaikum {applicantName},\n\nAnalisis Had Kifayah untuk permohonan anda dengan rujukan {applicationId} telah selesai.\n\n=== BUTIRAN ANALISIS HAD KIFAYAH ===\n\nJenis Isi Rumah: {householdType}\nJumlah Had Kifayah: RM {totalHadKifayah}\n\nPecahan:\n- Ketua Keluarga: RM {baseKifayahAmount}\n- Pasangan: RM {spouseKifayahAmount}\n- Tanggungan ({dependentCount} orang): RM {dependentAllowance}\n\nTarikh Analisis: {kifayahCalculationDate}\nStatus: {kifayahStatus}\n\nSila tunggu maklumat lanjut mengenai keputusan permohonan anda.\n\nTerima kasih.", - "subject": "Keputusan Analisis Had Kifayah - Permohonan {applicationId}", - "template": "kifayah-calculation-template", - "description": "Send Had Kifayah calculation results to applicant", - "errorVariable": "kifayahNotificationError", - "recipientType": "variable", - "recipientValue": "applicantEmail", - "notificationType": "email" + "label": "BF-NAS-PRF-AS-QS-04", + "shape": "rectangle", + "priority": "medium", + "textColor": "#1e40af", + "ruleGroups": [ + { + "name": "Rule 1", + "actions": [ + { + "type": "set_variable", + "value": "Fakir", + "variable": "kategoriKeluargaAsnaf" + }, + { + "type": "set_variable", + "value": "Fakir", + "variable": "kategoriAsnafSyor" + }, + { + "type": "set_variable", + "value": "Fakir", + "variable": "statusKeluarga" + } + ], + "conditions": [ + { + "value": "0", + "operator": "gte", + "variable": "peratusHadKifayah" + }, + { + "value": "49.9", + "operator": "lte", + "variable": "peratusHadKifayah" + } + ], + "conditionType": "all" + }, + { + "name": "Rule 2", + "actions": [ + { + "type": "set_variable", + "value": "Miskin", + "variable": "kategoriKeluargaAsnaf" + }, + { + "type": "set_variable", + "value": "Miskin", + "variable": "kategoriAsnafSyor" + }, + { + "type": "set_variable", + "value": "Miskin", + "variable": "statusKeluarga" + } + ], + "conditions": [ + { + "value": "50", + "operator": "gte", + "variable": "peratusHadKifayah" + }, + { + "value": "100", + "operator": "lte", + "variable": "peratusHadKifayah" + } + ], + "conditionType": "all" + }, + { + "name": "Rule 3", + "actions": [ + { + "type": "set_variable", + "value": "Non-FM", + "variable": "kategoriKeluargaAsnaf" + }, + { + "type": "set_variable", + "value": "Non-FM", + "variable": "kategoriAsnafSyor" + }, + { + "type": "set_variable", + "value": "Non-FM", + "variable": "statusKeluarga" + } + ], + "conditions": [ + { + "value": "100", + "operator": "gt", + "variable": "peratusHadKifayah" + } + ], + "conditionType": "all" + }, + { + "name": "Rule 4", + "actions": [ + { + "type": "set_variable", + "value": "Muallaf", + "variable": "kategoriAsnafSyor" + }, + { + "type": "set_variable", + "value": "Muallaf", + "variable": "statusIndividu" + } + ], + "conditions": [ + { "value": "5", "operator": "lt", "variable": "tempohMasukIslam" } + ], + "conditionType": "all" + }, + { + "name": "Rule 5", + "actions": [ + { + "type": "set_variable", + "value": "Generated", + "variable": "syorPengesahanStatus" + }, + { + "type": "set_variable", + "value": "${new Date().toISOString()}", + "variable": "tarikhPengesyoran" + }, + { + "type": "set_variable", + "value": "Berdasarkan analisis had kifayah, pemohon dikategorikan sebagai ${kategoriAsnafSyor} dengan peratus had kifayah ${peratusHadKifayah.toFixed(2)}%. Jumlah had kifayah keluarga: RM ${totalJumlahHadKifayah.toFixed(2)}.", + "variable": "syorPengesahan" + } + ], + "conditions": [ + { + "value": "completed", + "operator": "eq", + "variable": "kifayahCalculationStatus" + } + ], + "conditionType": "all" + } + ], + "borderColor": "#3b82f6", + "description": " Syor Status Keluarga Asnaf", + "errorVariable": "statusRecommendationError", + "outputVariable": "statusRecommendationResult", + "backgroundColor": "#eff6ff" }, - "type": "notification", - "label": "Hantar Keputusan Had Kifayah", - "position": { "x": 2730, "y": 690 } - }, - { - "id": "notification-1751872000000", - "data": { - "label": "Terima Notifikasi", - "message": "Assalamualaikum {applicantName},\n\nPermohonan anda dengan rujukan {applicationId} tidak dapat diproses kerana dokumen yang dikemukakan tidak lengkap.\n\nSila lengkapkan dokumen yang diperlukan dan kemukakan semula permohonan anda.\n\nCatatan daripada pegawai pengesah:\n{verificationNotes}\n\nTerima kasih.", - "subject": "Dokumen Tidak Lengkap - Permohonan {applicationId}", - "template": "incomplete-documents-template", - "description": "Send notification for incomplete documents", - "errorVariable": "notificationError", - "recipientType": "variable", - "recipientValue": "applicantEmail", - "notificationType": "email" - }, - "type": "notification", - "label": "Terima Notifikasi", - "position": { "x": 1455, "y": 915 } - }, - { - "id": "end-1751872100000", - "data": { - "label": "End", - "description": "Process completion - documents incomplete" - }, - "type": "end", - "label": "End", - "position": { "x": 1710, "y": 930 } + "type": "business-rule", + "label": "BF-NAS-PRF-AS-QS-04", + "position": { "x": 2550, "y": -30 } }, { "id": "html-1752109761532", @@ -1169,7 +1216,7 @@ }, "type": "html", "label": "Family Tree", - "position": { "x": 2535, "y": -435 } + "position": { "x": 2535, "y": -345 } }, { "id": "rectangle-shape-1752110224921", @@ -1178,6 +1225,7 @@ "shape": "rectangle", "width": 650, "height": 400, + "zIndex": 1, "isShape": true, "shapeType": "rectangle", "textColor": "#374151", @@ -1214,6 +1262,7 @@ "shape": "rectangle", "width": 650, "height": 400, + "zIndex": 1, "isShape": true, "shapeType": "rectangle", "textColor": "#374151", @@ -1250,6 +1299,7 @@ "shape": "rectangle", "width": 750, "height": 400, + "zIndex": 1, "isShape": true, "shapeType": "rectangle", "textColor": "#374151", @@ -1264,23 +1314,23 @@ { "id": "api-1752114771983", "data": { - "label": "API Call", + "label": "Called Family Tree", "shape": "rectangle", "apiUrl": "", "headers": "{ \"Content-Type\": \"application/json\" }", "apiMethod": "GET", - "textColor": "#1e40af", - "borderColor": "#3b82f6", + "textColor": "#c2410c", + "borderColor": "#f97316", "description": "External API call", "requestBody": "", "errorVariable": "apiError", "outputVariable": "apiResponse", - "backgroundColor": "#eff6ff", + "backgroundColor": "#fff7ed", "continueOnError": false }, "type": "api", "label": "Called Family Tree", - "position": { "x": 2295, "y": -525 } + "position": { "x": 2040, "y": -540 } }, { "id": "text-annotation-1752114833800", @@ -1333,13 +1383,17 @@ "id": "api-1753000000001", "data": { "label": "Submit Carian Profil API", + "shape": "rectangle", "apiUrl": "https://api.example.com/profiles/search", "headers": "{ \"Content-Type\": \"application/json\" }", "apiMethod": "POST", + "textColor": "#c2410c", + "borderColor": "#f97316", "description": "Submit profile search or login credentials", "requestBody": "{\n \"searchType\": \"{carianSearchType}\",\n \"searchId\": \"{carianSearchId}\",\n \"loginId\": \"{carianLoginId}\",\n \"password\": \"{carianLoginPassword}\"\n}", "errorVariable": "carianProfilApiError", "outputVariable": "carianProfilApiResponse", + "backgroundColor": "#fff7ed", "continueOnError": false }, "type": "api", @@ -1553,7 +1607,7 @@ }, "type": "gateway", "label": "Perubahan Profil?", - "position": { "x": 1440, "y": 60 } + "position": { "x": 1425, "y": 60 } }, { "id": "subprocess-1753100000003", @@ -1607,11 +1661,587 @@ "type": "subprocess", "label": "BF-NAS-BTN-PB", "position": { "x": 1635, "y": 180 } + }, + { + "id": "notification-1753200000001", + "data": { + "label": "Terima Notifikasi", + "message": "Assalamualaikum {applicantName},\n\nPermohonan bantuan anda telah diterima dan sedang dalam proses semakan.\n\nNo Rujukan: {applicationId}\nTarikh Permohonan: {submissionDate}\nStatus: Dalam Proses\n\nAnda akan menerima notifikasi lanjut apabila terdapat kemaskini status permohonan.\n\nTerima kasih.", + "subject": "Permohonan Bantuan Diterima - {applicationId}", + "priority": "normal", + "template": "application_received", + "variables": [ + "applicantName", + "applicationId", + "submissionDate", + "applicantEmail" + ], + "recipients": [ + { "type": "variable", "value": "applicantEmail" }, + { "type": "role", "value": "admin" } + ], + "attachments": [], + "description": "Send notification when application is received", + "sendImmediately": true, + "notificationType": "email" + }, + "type": "notification", + "label": "Terima Notifikasi", + "position": { "x": 3180, "y": -435 } + }, + { + "id": "gateway-status-check", + "data": { + "label": "Status", + "shape": "diamond", + "textColor": "#374151", + "conditions": [ + { + "id": "condition-group-berjaya-fm-path", + "output": "Berjaya FM", + "conditions": [ + { + "id": "condition-1", + "value": "approved", + "operator": "eq", + "variable": "applicationStatus", + "valueType": "string", + "logicalOperator": "and" + }, + { + "id": "condition-2", + "value": "Fakir", + "operator": "eq", + "variable": "kategoriAsnafSyor", + "valueType": "string", + "logicalOperator": "and" + } + ] + }, + { + "id": "condition-group-berjaya-miskin-path", + "output": "Berjaya Non-FM", + "conditions": [ + { + "id": "condition-3", + "value": "Non-Fakir", + "operator": "eq", + "variable": "applicationStatus", + "valueType": "string", + "logicalOperator": "and" + }, + { + "id": "condition-4", + "value": "Miskin", + "operator": "eq", + "variable": "kategoriAsnafSyor", + "valueType": "string", + "logicalOperator": "and" + } + ] + }, + { + "id": "condition-group-berjaya-non-fm-path", + "output": "Berjaya Fakir Miskin & Non-FM", + "conditions": [ + { + "id": "condition-5", + "value": "approved", + "operator": "eq", + "variable": "applicationStatus", + "valueType": "string", + "logicalOperator": "and" + }, + { + "id": "condition-6", + "value": "Fakir", + "operator": "eq", + "variable": "kategoriAsnafSyor", + "valueType": "string", + "logicalOperator": "and" + }, + { + "id": "condition-1752209204119", + "value": "Non-Fakir", + "maxValue": "", + "minValue": "", + "operator": "eq", + "variable": "kategoriAsnaf", + "valueType": "string", + "logicalOperator": "or" + } + ] + }, + { + "id": "condition-group-gagal-path", + "output": "Gagal", + "conditions": [ + { + "id": "condition-7", + "value": "rejected", + "operator": "eq", + "variable": "applicationStatus", + "valueType": "string", + "logicalOperator": "and" + } + ] + } + ], + "borderColor": "#6b7280", + "defaultPath": "notification-1753200000002", + "description": "Check application status and asnaf category for routing", + "gatewayType": "exclusive", + "backgroundColor": "#f9fafb" + }, + "type": "gateway", + "label": "Status", + "position": { "x": 1635, "y": 765 } + }, + { + "id": "form-pengesahan", + "data": { + "label": "Pengesahan", + "shape": "rectangle", + "formId": 8, + "formName": "Borang Pengesahan", + "formUuid": "8e07fc8f-a160-478a-85fd-fa3364401549", + "textColor": "#6b21a8", + "borderColor": "#9333ea", + "description": "Form untuk pengesahan dokumen dan maklumat pemohon", + "assignedRoles": ["verifier", "admin"], + "assignedUsers": [], + "inputMappings": [ + { "formField": "nama_pemohon", "processVariable": "applicantName" }, + { "formField": "no_rujukan", "processVariable": "applicationId" }, + { "formField": "kategori_asnaf", "processVariable": "kategoriAsnaf" }, + { + "formField": "dokumen_berkaitan", + "processVariable": "dokumenBerkaitan" + }, + { "formField": "urgency_level", "processVariable": "urgencyLevel" } + ], + "assignmentType": "role", + "outputMappings": [ + { + "formField": "status_pengesahan", + "processVariable": "pengesahanStatus" + }, + { + "formField": "catatan_pengesahan", + "processVariable": "catatanPengesahan" + }, + { + "formField": "dokumen_tambahan_diperlukan", + "processVariable": "dokumenTambahanDiperlukan" + }, + { + "formField": "jumlah_bantuan_dicadangkan", + "processVariable": "jumlahBantuanDicadangkan" + }, + { "formField": "jenis_bantuan", "processVariable": "jenisBantuan" }, + { "formField": "verified_by", "processVariable": "verifiedBy" }, + { + "formField": "verification_date", + "processVariable": "verificationDate" + } + ], + "backgroundColor": "#faf5ff", + "fieldConditions": [], + "assignmentVariable": "", + "assignmentVariableType": "user_id" + }, + "type": "form", + "label": "Borang Pengesahan", + "position": { "x": 2505, "y": 705 } + }, + { + "id": "api-pengesahan-submit", + "data": { + "label": "Submit Pengesahan API", + "shape": "rectangle", + "apiUrl": "https://api.bantuan.gov.my/v1/verification/submit", + "headers": "{ \"Content-Type\": \"application/json\", \"Authorization\": \"Bearer {apiToken}\" }", + "apiMethod": "POST", + "textColor": "#c2410c", + "borderColor": "#f97316", + "description": "Submit verification results to central system", + "requestBody": "{\n \"applicationId\": \"{applicationId}\",\n \"verificationStatus\": \"{pengesahanStatus}\",\n \"verificationNotes\": \"{catatanPengesahan}\",\n \"additionalDocumentsRequired\": \"{dokumenTambahanDiperlukan}\",\n \"recommendedAmount\": \"{jumlahBantuanDicadangkan}\",\n \"assistanceType\": \"{jenisBantuan}\",\n \"verifiedBy\": \"{verifiedBy}\",\n \"verificationDate\": \"{verificationDate}\",\n \"applicantCategory\": \"{kategoriAsnaf}\",\n \"urgencyLevel\": \"{urgencyLevel}\"\n}", + "errorVariable": "pengesahanApiError", + "outputVariable": "pengesahanApiResponse", + "backgroundColor": "#fff7ed", + "continueOnError": false + }, + "type": "api", + "label": "Submit Pengesahan API", + "position": { "x": 2175, "y": 720 } + }, + { + "id": "script-process-pengesahan", + "data": { + "label": "Process Pengesahan Response", + "scriptCode": "// Process the pengesahan (verification) response\nconst apiData = processVariables.pengesahanApiResponse;\n\nif (apiData && apiData.status === 'success') {\n // Update application status based on verification\n switch (processVariables.pengesahanStatus) {\n case 'lulus':\n processVariables.applicationStatus = 'approved';\n processVariables.statusMessage = 'Permohonan telah diluluskan';\n processVariables.nextAction = 'payment_processing';\n break;\n case 'ditolak':\n processVariables.applicationStatus = 'rejected';\n processVariables.statusMessage = 'Permohonan ditolak: ' + processVariables.catatanPengesahan;\n processVariables.nextAction = 'send_rejection_notice';\n break;\n case 'dokumen_tambahan':\n processVariables.applicationStatus = 'pending_documents';\n processVariables.statusMessage = 'Dokumen tambahan diperlukan';\n processVariables.nextAction = 'request_additional_documents';\n break;\n case 'semakan_lanjut':\n processVariables.applicationStatus = 'under_review';\n processVariables.statusMessage = 'Permohonan dalam semakan lanjut';\n processVariables.nextAction = 'further_review';\n break;\n default:\n processVariables.applicationStatus = 'pending';\n processVariables.statusMessage = 'Status tidak diketahui';\n processVariables.nextAction = 'manual_review';\n }\n \n // Set verification completion flag\n processVariables.verificationCompleted = true;\n processVariables.verificationTimestamp = new Date().toISOString();\n \n // Calculate processing time\n if (processVariables.submissionDate) {\n const submitTime = new Date(processVariables.submissionDate);\n const verifyTime = new Date();\n const processingHours = Math.round((verifyTime - submitTime) / (1000 * 60 * 60));\n processVariables.processingTimeHours = processingHours;\n }\n \n // Set notification flags based on status\n processVariables.sendApprovalNotification = processVariables.applicationStatus === 'approved';\n processVariables.sendRejectionNotification = processVariables.applicationStatus === 'rejected';\n processVariables.sendPendingNotification = processVariables.applicationStatus.includes('pending');\n \n // Set payment processing flag for approved applications\n if (processVariables.applicationStatus === 'approved') {\n processVariables.paymentReady = true;\n processVariables.paymentAmount = processVariables.jumlahBantuanDicadangkan || 0;\n processVariables.paymentMethod = processVariables.sebabTunai === 'ya' ? 'cash' : 'bank_transfer';\n }\n \n console.log('Pengesahan processed successfully:', {\n applicationStatus: processVariables.applicationStatus,\n statusMessage: processVariables.statusMessage,\n nextAction: processVariables.nextAction,\n verificationCompleted: processVariables.verificationCompleted,\n paymentReady: processVariables.paymentReady\n });\n} else {\n // Handle API error\n processVariables.applicationStatus = 'verification_failed';\n processVariables.statusMessage = 'Ralat semasa pengesahan';\n processVariables.verificationCompleted = false;\n processVariables.pengesahanError = apiData ? apiData.message : 'Unknown API error';\n \n console.error('Pengesahan API failed:', processVariables.pengesahanError);\n}", + "description": "Process verification results and determine next steps", + "errorVariable": "pengesahanScriptError", + "inputVariables": [ + "pengesahanApiResponse", + "pengesahanStatus", + "catatanPengesahan", + "dokumenTambahanDiperlukan", + "jumlahBantuanDicadangkan", + "jenisBantuan", + "verifiedBy", + "verificationDate", + "submissionDate", + "sebabTunai" + ], + "scriptLanguage": "javascript", + "continueOnError": false, + "outputVariables": [ + { + "name": "applicationStatus", + "type": "string", + "description": "Final application status after verification" + }, + { + "name": "statusMessage", + "type": "string", + "description": "Human-readable status message" + }, + { + "name": "nextAction", + "type": "string", + "description": "Next action to be taken" + }, + { + "name": "verificationCompleted", + "type": "boolean", + "description": "Whether verification process is completed" + }, + { + "name": "verificationTimestamp", + "type": "string", + "description": "Timestamp when verification was completed" + }, + { + "name": "processingTimeHours", + "type": "number", + "description": "Total processing time in hours" + }, + { + "name": "sendApprovalNotification", + "type": "boolean", + "description": "Whether to send approval notification" + }, + { + "name": "sendRejectionNotification", + "type": "boolean", + "description": "Whether to send rejection notification" + }, + { + "name": "sendPendingNotification", + "type": "boolean", + "description": "Whether to send pending status notification" + }, + { + "name": "paymentReady", + "type": "boolean", + "description": "Whether payment processing is ready" + }, + { + "name": "paymentAmount", + "type": "number", + "description": "Amount approved for payment" + }, + { + "name": "paymentMethod", + "type": "string", + "description": "Payment method (cash/bank_transfer)" + } + ] + }, + "type": "script", + "label": "Process Pengesahan Response", + "position": { "x": 2175, "y": 510 } + }, + { + "id": "notification-1753200000002", + "data": { + "label": "BF-NAS-PRF-AS-QS-06 Terima Notifikasi", + "shape": "rectangle", + "message": "Assalamualaikum {applicantName},\n\nStatus permohonan bantuan anda telah dikemaskini.\n\nNo Rujukan: {applicationId}\nStatus Terkini: {statusMessage}\nTarikh Kemaskini: {verificationTimestamp}\nDiluluskan oleh: {verifiedBy}\n\n{conditionalMessage}\n\nUntuk maklumat lanjut, sila hubungi pejabat kami.\n\nTerima kasih.", + "subject": "Kemaskini Status Permohonan - {applicationId}", + "priority": "high", + "template": "status_update", + "textColor": "#0284c7", + "variables": [ + "applicantName", + "applicationId", + "statusMessage", + "verificationTimestamp", + "verifiedBy", + "conditionalMessage" + ], + "recipients": [{ "type": "variable", "value": "applicantEmail" }], + "attachments": [], + "borderColor": "#0ea5e9", + "description": "Send status update notification to applicant", + "backgroundColor": "#f0f9ff", + "sendImmediately": true, + "notificationType": "email", + "conditionalSending": { + "conditions": [ + { + "value": true, + "operator": "eq", + "variable": "verificationCompleted", + "valueType": "boolean" + } + ] + } + }, + "type": "notification", + "label": "Terima Notifikasi", + "position": { "x": 3165, "y": 630 } + }, + { + "id": "swimlane-horizontal-1752207659712", + "data": { + "label": "", + "shape": "rectangle", + "width": 650, + "height": 400, + "zIndex": 1, + "isShape": true, + "shapeType": "swimlane-horizontal", + "textColor": "#374151", + "borderColor": "#16a34a", + "description": "", + "backgroundColor": "#e8f5e9" + }, + "type": "swimlane-horizontal", + "label": "", + "position": { "x": 2940, "y": -570 } + }, + { + "id": "text-annotation-1752207727571", + "data": { + "label": "", + "shape": "rectangle", + "width": 200, + "height": 80, + "isShape": true, + "shapeType": "text-annotation", + "textColor": "#92400e", + "borderColor": "#fbbf24", + "description": "Terima Notifikasi", + "backgroundColor": "#fffbeb" + }, + "type": "text-annotation", + "label": "BF-NAS-PRF-AS-QS-06", + "position": { "x": 3360, "y": -540 } + }, + { + "id": "swimlane-horizontal-1752207945135", + "data": { + "label": "", + "shape": "rectangle", + "width": 650, + "height": 400, + "zIndex": 0, + "isShape": true, + "shapeType": "swimlane-horizontal", + "textColor": "#374151", + "borderColor": "#16a34a", + "description": "", + "backgroundColor": "#e8f5e9" + }, + "type": "swimlane-horizontal", + "label": "", + "position": { "x": 2100, "y": 495 } + }, + { + "id": "swimlane-horizontal-1752208028711", + "data": { + "label": "", + "shape": "rectangle", + "width": 650, + "height": 400, + "isShape": true, + "shapeType": "swimlane-horizontal", + "textColor": "#475569", + "borderColor": "#16a34a", + "description": "", + "backgroundColor": "#e8f5e9" + }, + "type": "swimlane-horizontal", + "label": "", + "position": { "x": 2925, "y": 495 } + }, + { + "id": "subprocess-1752208906615", + "data": { + "label": "Bantuan Selain Fakir, Miskin", + "shape": "rectangle", + "textColor": "#134e4a", + "borderColor": "#14b8a6", + "description": "Sub-process: Bantuan Selain Fakir, Miskin", + "subprocessId": 5, + "subprocessName": "Bantuan Selain Fakir, Miskin", + "backgroundColor": "#f0fdfa" + }, + "type": "subprocess", + "label": "Bantuan Selain Fakir, Miskin", + "position": { "x": 2010, "y": 225 } + }, + { + "id": "text-annotation-1752214226967", + "data": { + "label": "BF-NAS-PRF-AS-QS-06", + "shape": "rectangle", + "width": 200, + "height": 80, + "isShape": true, + "shapeType": "text-annotation", + "textColor": "#92400e", + "borderColor": "#fbbf24", + "description": "Terima Notifikasi", + "backgroundColor": "#fffbeb" + }, + "type": "text-annotation", + "label": "BF-NAS-PRF-AS-QS-06", + "position": { "x": 3360, "y": 510 } + }, + { + "id": "text-annotation-1752214239218", + "data": { + "label": "", + "shape": "rectangle", + "width": 200, + "height": 80, + "isShape": true, + "shapeType": "text-annotation", + "textColor": "#92400e", + "borderColor": "#fbbf24", + "description": "Pengesahan", + "backgroundColor": "#fffbeb" + }, + "type": "text-annotation", + "label": "BF-NAS-PRF-AS-QS-05", + "position": { "x": 2535, "y": 510 } + }, + { + "id": "swimlane-horizontal-1752459527902", + "data": { + "label": "", + "shape": "rectangle", + "width": 3800, + "height": 600, + "zIndex": 0, + "isShape": true, + "shapeType": "swimlane-horizontal", + "textColor": "#475569", + "borderColor": "#cedced", + "description": "", + "backgroundColor": "#edf0f3" + }, + "type": "swimlane-horizontal", + "label": "", + "position": { "x": -165, "y": -690 } + }, + { + "id": "swimlane-horizontal-1752459624822", + "data": { + "label": "", + "shape": "rectangle", + "width": 3800, + "height": 600, + "isShape": true, + "shapeType": "swimlane-horizontal", + "textColor": "#475569", + "borderColor": "#cedced", + "description": "", + "backgroundColor": "#edf0f3" + }, + "type": "swimlane-horizontal", + "label": "", + "position": { "x": -165, "y": -90 } + }, + { + "id": "swimlane-horizontal-1752459677022", + "data": { + "label": "", + "shape": "rectangle", + "width": 3800, + "height": 600, + "isShape": true, + "shapeType": "swimlane-horizontal", + "textColor": "#475569", + "borderColor": "#cedced", + "description": "", + "backgroundColor": "#edf0f3" + }, + "type": "swimlane-horizontal", + "label": "", + "position": { "x": -165, "y": 390 } + }, + { + "id": "text-annotation-1752459743051", + "data": { + "label": "", + "shape": "rectangle", + "width": 200, + "height": 80, + "isShape": true, + "shapeType": "text-annotation", + "textColor": "#92400e", + "borderColor": "#fbbf24", + "description": "", + "backgroundColor": "#fffbeb" + }, + "type": "text-annotation", + "label": "Pendaftar/Pemohon", + "position": { "x": -135, "y": -660 } + }, + { + "id": "text-annotation-1752459783975", + "data": { + "label": "", + "shape": "rectangle", + "width": 200, + "height": 80, + "isShape": true, + "shapeType": "text-annotation", + "textColor": "#92400e", + "borderColor": "#fbbf24", + "description": "", + "backgroundColor": "#fffbeb" + }, + "type": "text-annotation", + "label": "NAS", + "position": { "x": -135, "y": -60 } + }, + { + "id": "text-annotation-1752459793219", + "data": { + "label": "", + "shape": "rectangle", + "width": 200, + "height": 80, + "isShape": true, + "shapeType": "text-annotation", + "textColor": "#92400e", + "borderColor": "#fbbf24", + "description": "", + "backgroundColor": "#fffbeb" + }, + "type": "text-annotation", + "label": "EOAD", + "position": { "x": -120, "y": 435 } } ], "viewport": { - "x": -818.4067095426772, - "y": 210.4283305655609, - "zoom": 0.5930425475009586 + "x": 380.3737299152659, + "y": 485.7223789581114, + "zoom": 0.3414482349217966 } } diff --git a/docs/json/process-builder/processVariables.json b/docs/json/process-builder/processVariables.json index e398400..0458f8f 100644 --- a/docs/json/process-builder/processVariables.json +++ b/docs/json/process-builder/processVariables.json @@ -41,6 +41,13 @@ "value": null, "description": "Nama bank from Section B" }, + "nextAction": { + "name": "nextAction", + "type": "string", + "scope": "global", + "value": null, + "description": "Next action to be taken in the process" + }, "radio9Copy": { "name": "radio9Copy", "type": "string", @@ -149,6 +156,13 @@ "value": null, "description": "Form field for jenis KP 3" }, + "jenisBantuan": { + "name": "jenisBantuan", + "type": "string", + "scope": "global", + "value": null, + "description": "Type of assistance (tunai/barangan/perkhidmatan)" + }, "loginSuccess": { "name": "loginSuccess", "type": "boolean", @@ -216,15 +230,15 @@ "name": "applicantName", "type": "string", "scope": "global", - "value": "Ahmad Bin Ali", - "description": "Applicant name for verification form" + "value": null, + "description": "Applicant's full name" }, "applicationId": { "name": "applicationId", "type": "string", "scope": "global", - "value": "APP-1751871528249", - "description": "Generated application ID from script processing" + "value": null, + "description": "Unique application reference number" }, "carianLoginId": { "name": "carianLoginId", @@ -310,6 +324,20 @@ "value": null, "description": "Text field for nyatakan lain-lain" }, + "paymentAmount": { + "name": "paymentAmount", + "type": "number", + "scope": "global", + "value": null, + "description": "Amount approved for payment (RM)" + }, + "paymentMethod": { + "name": "paymentMethod", + "type": "string", + "scope": "global", + "value": null, + "description": "Payment method (cash/bank_transfer)" + }, "poskodSekolah": { "name": "poskodSekolah", "type": "string", @@ -317,12 +345,19 @@ "value": null, "description": "Poskod sekolah from Section B" }, + "statusMessage": { + "name": "statusMessage", + "type": "string", + "scope": "global", + "value": null, + "description": "Human-readable status message" + }, "applicantEmail": { "name": "applicantEmail", "type": "string", "scope": "global", - "value": "ahmad.ali@example.com", - "description": "Applicant email address for notifications" + "value": null, + "description": "Applicant's email address for notifications" }, "caraPembayaran": { "name": "caraPembayaran", @@ -394,6 +429,13 @@ "value": null, "description": "Family status based on had kifayah calculation" }, + "submissionDate": { + "name": "submissionDate", + "type": "string", + "scope": "global", + "value": null, + "description": "Date when application was submitted" + }, "syorPengesahan": { "name": "syorPengesahan", "type": "string", @@ -443,6 +485,13 @@ "value": "850101-01-1234", "description": "No Kad Pengenalan" }, + "pengesahanError": { + "name": "pengesahanError", + "type": "string", + "scope": "global", + "value": null, + "description": "General error message from pengesahan process" + }, "penilaianAwalId": { "name": "penilaianAwalId", "type": "string", @@ -527,6 +576,13 @@ "value": 1000, "description": "Net family income" }, + "pengesahanStatus": { + "name": "pengesahanStatus", + "type": "string", + "scope": "global", + "value": null, + "description": "Verification status (lulus/ditolak/dokumen_tambahan/semakan_lanjut)" + }, "readyForDecision": { "name": "readyForDecision", "type": "boolean", @@ -548,6 +604,13 @@ "value": null, "description": "Date when verification was completed" }, + "applicationStatus": { + "name": "applicationStatus", + "type": "string", + "scope": "global", + "value": "pending", + "description": "Current application status (pending/approved/rejected/under_review)" + }, "baseKifayahAmount": { "name": "baseKifayahAmount", "type": "decimal", @@ -555,6 +618,13 @@ "value": null, "description": "Base Had Kifayah amount for head of household (RM 1,215.00)" }, + "catatanPengesahan": { + "name": "catatanPengesahan", + "type": "string", + "scope": "global", + "value": null, + "description": "Verification notes from officer" + }, "documentsComplete": { "name": "documentsComplete", "type": "boolean", @@ -674,6 +744,13 @@ "value": null, "description": "Childcare allowance for 12 years and below (RM 330.00)" }, + "conditionalMessage": { + "name": "conditionalMessage", + "type": "string", + "scope": "global", + "value": null, + "description": "Conditional message based on application status" + }, "dateMasukislamCopy": { "name": "dateMasukislamCopy", "type": "string", @@ -695,6 +772,13 @@ "value": null, "description": "Jenis kad tanggungan from Section B" }, + "pengesahanApiError": { + "name": "pengesahanApiError", + "type": "object", + "scope": "global", + "value": null, + "description": "API error from verification submission" + }, "penilaianAwalError": { "name": "penilaianAwalError", "type": "string", @@ -751,6 +835,13 @@ "value": null, "description": "Status of initial assessment submission" }, + "processingTimeHours": { + "name": "processingTimeHours", + "type": "number", + "scope": "global", + "value": null, + "description": "Total processing time in hours" + }, "profileUpdateStatus": { "name": "profileUpdateStatus", "type": "string", @@ -884,6 +975,20 @@ "value": null, "description": "Result from kifayah eligibility analysis API" }, + "pengesahanApiResponse": { + "name": "pengesahanApiResponse", + "type": "object", + "scope": "global", + "value": null, + "description": "API response from verification submission" + }, + "pengesahanScriptError": { + "name": "pengesahanScriptError", + "type": "object", + "scope": "global", + "value": null, + "description": "Script error from pengesahan processing" + }, "penilaianAwalApiError": { "name": "penilaianAwalApiError", "type": "string", @@ -912,6 +1017,13 @@ "value": 0, "description": "Total family had kifayah amount" }, + "verificationCompleted": { + "name": "verificationCompleted", + "type": "boolean", + "scope": "global", + "value": false, + "description": "Whether verification process is completed" + }, "verificationProcessed": { "name": "verificationProcessed", "type": "boolean", @@ -919,6 +1031,13 @@ "value": null, "description": "Whether verification processing is complete" }, + "verificationTimestamp": { + "name": "verificationTimestamp", + "type": "string", + "scope": "global", + "value": null, + "description": "Timestamp when verification was completed" + }, "warganegaraTanggungan": { "name": "warganegaraTanggungan", "type": "string", @@ -1024,6 +1143,13 @@ "value": null, "description": "Select field for status perkahwinan" }, + "sendPendingNotification": { + "name": "sendPendingNotification", + "type": "boolean", + "scope": "global", + "value": false, + "description": "Whether to send pending status notification" + }, "tempatMenetapTanggungan": { "name": "tempatMenetapTanggungan", "type": "string", @@ -1059,6 +1185,13 @@ "value": 1215, "description": "Base had kifayah amount for head of family (RM 1,215.00)" }, + "jumlahBantuanDicadangkan": { + "name": "jumlahBantuanDicadangkan", + "type": "number", + "scope": "global", + "value": null, + "description": "Recommended assistance amount (RM)" + }, "kifayahCalculationResult": { "name": "kifayahCalculationResult", "type": "object", @@ -1101,6 +1234,13 @@ "value": null, "description": "Error from Penilaian Awal script execution" }, + "sendApprovalNotification": { + "name": "sendApprovalNotification", + "type": "boolean", + "scope": "global", + "value": false, + "description": "Whether to send approval notification" + }, "tarikhMulaKfamTanggungan": { "name": "tarikhMulaKfamTanggungan", "type": "string", @@ -1108,6 +1248,13 @@ "value": null, "description": "Tarikh mula KFAM tanggungan from Section B" }, + "dokumenTambahanDiperlukan": { + "name": "dokumenTambahanDiperlukan", + "type": "array", + "scope": "global", + "value": null, + "description": "List of additional documents required" + }, "hadKifayahTanggungan7to17": { "name": "hadKifayahTanggungan7to17", "type": "number", @@ -1115,6 +1262,13 @@ "value": 408, "description": "Had kifayah amount per dependent aged 7-17 years (RM 408.00)" }, + "sendRejectionNotification": { + "name": "sendRejectionNotification", + "type": "boolean", + "scope": "global", + "value": false, + "description": "Whether to send rejection notification" + }, "statusRecommendationError": { "name": "statusRecommendationError", "type": "object", @@ -1226,180 +1380,5 @@ "scope": "global", "value": 0, "description": "Total had kifayah for dependents aged 6 years and below" - }, - "pengesahanStatus": { - "name": "pengesahanStatus", - "type": "string", - "scope": "global", - "value": null, - "description": "Verification status (lulus/ditolak/dokumen_tambahan/semakan_lanjut)" - }, - "catatanPengesahan": { - "name": "catatanPengesahan", - "type": "string", - "scope": "global", - "value": null, - "description": "Verification notes from officer" - }, - "dokumenTambahanDiperlukan": { - "name": "dokumenTambahanDiperlukan", - "type": "array", - "scope": "global", - "value": null, - "description": "List of additional documents required" - }, - "jumlahBantuanDicadangkan": { - "name": "jumlahBantuanDicadangkan", - "type": "number", - "scope": "global", - "value": null, - "description": "Recommended assistance amount (RM)" - }, - "jenisBantuan": { - "name": "jenisBantuan", - "type": "string", - "scope": "global", - "value": null, - "description": "Type of assistance (tunai/barangan/perkhidmatan)" - }, - "applicationStatus": { - "name": "applicationStatus", - "type": "string", - "scope": "global", - "value": "pending", - "description": "Current application status (pending/approved/rejected/under_review)" - }, - "statusMessage": { - "name": "statusMessage", - "type": "string", - "scope": "global", - "value": null, - "description": "Human-readable status message" - }, - "nextAction": { - "name": "nextAction", - "type": "string", - "scope": "global", - "value": null, - "description": "Next action to be taken in the process" - }, - "verificationCompleted": { - "name": "verificationCompleted", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether verification process is completed" - }, - "verificationTimestamp": { - "name": "verificationTimestamp", - "type": "string", - "scope": "global", - "value": null, - "description": "Timestamp when verification was completed" - }, - "processingTimeHours": { - "name": "processingTimeHours", - "type": "number", - "scope": "global", - "value": null, - "description": "Total processing time in hours" - }, - "sendApprovalNotification": { - "name": "sendApprovalNotification", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether to send approval notification" - }, - "sendRejectionNotification": { - "name": "sendRejectionNotification", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether to send rejection notification" - }, - "sendPendingNotification": { - "name": "sendPendingNotification", - "type": "boolean", - "scope": "global", - "value": false, - "description": "Whether to send pending status notification" - }, - "paymentAmount": { - "name": "paymentAmount", - "type": "number", - "scope": "global", - "value": null, - "description": "Amount approved for payment (RM)" - }, - "paymentMethod": { - "name": "paymentMethod", - "type": "string", - "scope": "global", - "value": null, - "description": "Payment method (cash/bank_transfer)" - }, - "applicantEmail": { - "name": "applicantEmail", - "type": "string", - "scope": "global", - "value": null, - "description": "Applicant's email address for notifications" - }, - "applicantName": { - "name": "applicantName", - "type": "string", - "scope": "global", - "value": null, - "description": "Applicant's full name" - }, - "applicationId": { - "name": "applicationId", - "type": "string", - "scope": "global", - "value": null, - "description": "Unique application reference number" - }, - "submissionDate": { - "name": "submissionDate", - "type": "string", - "scope": "global", - "value": null, - "description": "Date when application was submitted" - }, - "conditionalMessage": { - "name": "conditionalMessage", - "type": "string", - "scope": "global", - "value": null, - "description": "Conditional message based on application status" - }, - "pengesahanApiResponse": { - "name": "pengesahanApiResponse", - "type": "object", - "scope": "global", - "value": null, - "description": "API response from verification submission" - }, - "pengesahanApiError": { - "name": "pengesahanApiError", - "type": "object", - "scope": "global", - "value": null, - "description": "API error from verification submission" - }, - "pengesahanScriptError": { - "name": "pengesahanScriptError", - "type": "object", - "scope": "global", - "value": null, - "description": "Script error from pengesahan processing" - }, - "pengesahanError": { - "name": "pengesahanError", - "type": "string", - "scope": "global", - "value": null, - "description": "General error message from pengesahan process" } } diff --git a/docs/process-builder-analysis.md b/docs/process-builder-analysis.md new file mode 100644 index 0000000..41eb27b --- /dev/null +++ b/docs/process-builder-analysis.md @@ -0,0 +1,338 @@ +# Process Builder Pages Analysis + +This document provides a comprehensive analysis of the process-builder pages in the Corrad ProcessMaker system, including their current implementation, features, and improvement opportunities. + +## Overview + +The process-builder section consists of three main pages: +1. **index.vue** - Main process builder/designer interface +2. **manage.vue** - Process management dashboard +3. **analytics/[id].vue** - Process analytics and monitoring + +## Page-by-Page Analysis + +### 1. Process Builder (index.vue) + +**Purpose**: Main visual process design interface where users create and edit business processes using a drag-and-drop BPMN editor. + +#### Key Features +- **Visual Process Designer**: Full-featured BPMN editor with Vue Flow integration +- **Component Palette**: Drag-and-drop components (Start/End, Forms, APIs, Scripts, Gateways, etc.) +- **Node Configuration**: Dedicated modals for configuring each node type +- **Variable Management**: Built-in variable manager for process data +- **Auto-save**: Automatic saving with unsaved changes protection +- **Process Templates**: Template system for reusable process definitions +- **Process History**: Version control and history tracking +- **Responsive Design**: Mobile-friendly interface with collapsible panels + +#### Technical Implementation +```javascript +// Core Dependencies +- Vue 3 Composition API +- Vue Flow for BPMN rendering +- Pinia store for state management +- Process Builder Store for centralized logic +- Multiple specialized modals for node configuration + +// Key Components Used +- ProcessFlowCanvas (main canvas) +- ProcessBuilderComponents (component palette) +- FormSelector, VariableManager +- Various node configuration modals +- ProcessTemplatesModal, ProcessSettingsModal +``` + +#### File Structure Insights +- **Large file** (~40k tokens) indicating complex functionality +- **Comprehensive imports** showing integration with 15+ specialized components +- **State management** using refs and reactive variables +- **Modal system** for node configuration with dedicated modals per node type +- **Navigation handling** with unsaved changes protection + +#### Current State +- ✅ **Feature Complete**: Full BPMN editing capabilities +- ✅ **Node Types**: Supports all major BPMN elements +- ✅ **Integration Ready**: API and form integration built-in +- ✅ **User Experience**: Auto-save, templates, history +- ⚠️ **Performance**: Large file size may impact load times +- ⚠️ **Maintainability**: Complex component structure + +### 2. Process Management Dashboard (manage.vue) + +**Purpose**: Central hub for managing processes with dashboard view, process listing, and administrative functions. + +#### Key Features + +##### Dashboard View +- **Real-time Metrics**: Process counts, case statistics, completion rates +- **Visual Analytics**: Process distribution charts, case status visualization +- **Recent Activity**: Activity feed with user actions and timestamps +- **Quick Actions**: Fast access to common operations + +##### List View +- **Advanced Filtering**: Search, status, and category filters +- **Process Management**: Edit, publish, duplicate, delete operations +- **Bulk Operations**: Multi-select for batch actions +- **Status Management**: Draft, published, archived, deleted states + +##### Process Operations +- **CRUD Operations**: Full create, read, update, delete functionality +- **Publishing Workflow**: Draft → Published state management +- **Process Duplication**: Clone existing processes +- **Soft Delete**: Move to trash with restore capability + +#### Technical Implementation +```javascript +// State Management +- Process store integration +- Real-time data fetching +- Filter and search state +- Loading states and error handling + +// API Integration +- Dashboard summary endpoint +- Process CRUD operations +- Bulk operations support +- Analytics data fetching + +// UI Components +- Custom Rose UI components +- FormKit for forms and inputs +- Icon system with Material Symbols +- Responsive grid layouts +``` + +#### User Experience Features +- **Dual View Mode**: Dashboard and list views with seamless switching +- **Real-time Updates**: Live data refresh and status updates +- **Responsive Design**: Mobile-optimized interface +- **Progressive Loading**: Skeleton states and loading indicators +- **Error Handling**: Graceful error states with fallbacks + +#### Current State +- ✅ **Comprehensive**: Full process lifecycle management +- ✅ **User-Friendly**: Intuitive interface with clear actions +- ✅ **Performance**: Optimized API calls and loading states +- ✅ **Responsive**: Works well on all device sizes +- ⚠️ **Charts**: Placeholder chart implementations (not fully functional) +- ⚠️ **Analytics**: Basic metrics, could be enhanced + +### 3. Process Analytics ([id].vue) + +**Purpose**: Detailed analytics and monitoring for individual processes with journey visualization. + +#### Key Features + +##### Overview Tab +- **Key Performance Metrics**: Total cases, completion rates, success rates +- **Time Analytics**: Average completion times and efficiency metrics +- **User Analytics**: Top users and department statistics +- **Visual Indicators**: Color-coded status indicators and progress bars + +##### Journey Tab +- **Process Flow Visualization**: Step-by-step journey mapping +- **Completion Tracking**: Success rates per step +- **Performance Analysis**: Time spent at each step +- **Issue Identification**: Bottlenecks and problem areas highlighted +- **Visual Timeline**: Connected flow showing process progression + +#### Technical Implementation +```javascript +// Data Structure +- Mock analytics data (ready for API integration) +- Journey step definitions with metrics +- User performance tracking +- Time-based analytics + +// Visualization +- Custom timeline component +- Progress bars and completion indicators +- Icon-based node type identification +- Responsive table layouts + +// Navigation +- Tab-based interface +- Back navigation to management +- Edit process integration +``` + +#### Analytics Metrics +- **Process Execution**: Cases started, completed, abandoned +- **Performance**: Average completion times, bottlenecks +- **User Behavior**: Most active users, department usage +- **Quality**: Success rates, error rates, retry counts +- **Journey Analysis**: Step-by-step conversion funnel + +#### Current State +- ✅ **Well-Structured**: Clear analytics framework +- ✅ **Visual Design**: Excellent journey visualization +- ✅ **User Experience**: Intuitive tab navigation +- ⚠️ **Mock Data**: Uses placeholder data (API integration needed) +- ⚠️ **Chart Integration**: Could benefit from chart libraries +- ⚠️ **Real-time**: Static data, needs live updates + +## Architecture Analysis + +### Strengths + +1. **Comprehensive Functionality** + - Complete BPMN process design capabilities + - Full process lifecycle management + - Detailed analytics and monitoring + +2. **Modern Technology Stack** + - Vue 3 Composition API for optimal performance + - Pinia for reactive state management + - Vue Flow for professional diagram rendering + - FormKit for consistent form handling + +3. **User Experience** + - Intuitive drag-and-drop interface + - Responsive design across all pages + - Auto-save and unsaved changes protection + - Comprehensive error handling + +4. **Modular Architecture** + - Separated concerns across pages + - Reusable component library + - Centralized store management + - Clean navigation structure + +### Areas for Improvement + +1. **Performance Optimization** + - Large file sizes (index.vue ~40k tokens) + - Potential bundle splitting opportunities + - Lazy loading for modal components + - Canvas rendering optimization + +2. **Data Integration** + - Analytics page uses mock data + - Chart implementation placeholders + - Real-time data updates needed + - API error handling enhancement + +3. **Code Organization** + - Complex component structure in index.vue + - Potential for refactoring into smaller components + - Shared utilities extraction + - Type safety improvements + +4. **Feature Enhancements** + - Advanced analytics charts + - Real-time collaboration + - Process versioning UI + - Export/import functionality + - Advanced filtering options + +## Component Dependencies + +### Process Builder (index.vue) +``` +├── ProcessFlowCanvas (main editor) +├── ProcessBuilderComponents (palette) +├── Node Configuration Modals: +│ ├── FormNodeConfigurationModal +│ ├── ApiNodeConfigurationModal +│ ├── BusinessRuleNodeConfigurationModal +│ ├── NotificationNodeConfigurationModal +│ ├── ScriptNodeConfigurationModal +│ ├── HtmlNodeConfigurationModal +│ └── SubprocessNodeConfigurationModal +├── Supporting Components: +│ ├── FormSelector +│ ├── VariableManager +│ ├── GatewayConditionManager +│ ├── ProcessTemplatesModal +│ ├── ProcessSettingsModal +│ └── ProcessHistoryModal +``` + +### Management Dashboard (manage.vue) +``` +├── Rose UI Components: +│ ├── RsButton, RsBadge, RsModal +│ └── FormKit components +├── Dashboard Charts (placeholder) +├── Process List Components +└── Filter and Search Components +``` + +### Analytics ([id].vue) +``` +├── Tab Navigation System +├── Metrics Display Components +├── Journey Timeline Component +├── User Analytics Table +└── Visual Progress Indicators +``` + +## State Management + +### Process Builder Store Integration +- **Centralized Logic**: All process operations through store +- **Reactive Updates**: Real-time UI updates on data changes +- **Persistence**: Auto-save and local storage integration +- **Error Handling**: Consistent error states across pages + +### Key Store Methods Used +```javascript +// Process Management +- fetchProcesses() +- createProcess() +- updateProcess() +- deleteProcess() +- publishProcess() +- duplicateProcess() + +// Process Building +- loadProcess() +- saveProcess() +- addNode() +- updateNode() +- addEdge() + +// Analytics +- getProcessAnalytics() +- getProcessJourney() +``` + +## Recommended Improvements + +### 1. Performance Optimization +- **Code Splitting**: Break index.vue into smaller, lazy-loaded components +- **Virtual Scrolling**: For large process lists in manage.vue +- **Canvas Optimization**: Implement viewport-based rendering for large processes +- **Bundle Analysis**: Identify and optimize heavy dependencies + +### 2. Real-time Features +- **Live Analytics**: WebSocket integration for real-time metrics +- **Collaboration**: Multi-user editing with conflict resolution +- **Auto-refresh**: Periodic data updates for dashboard +- **Push Notifications**: Process completion alerts + +### 3. Enhanced Analytics +- **Chart Integration**: Implement Chart.js or similar for visual analytics +- **Advanced Metrics**: More detailed performance analytics +- **Custom Reports**: User-configurable analytics dashboards +- **Export Features**: PDF/Excel export for analytics data + +### 4. User Experience +- **Keyboard Shortcuts**: Power user features for faster editing +- **Advanced Search**: Full-text search across process content +- **Bulk Operations**: Multi-select operations in management view +- **Process Comparison**: Side-by-side process comparison tools + +### 5. Developer Experience +- **TypeScript**: Add type safety across all components +- **Testing**: Unit and integration test coverage +- **Documentation**: Component and API documentation +- **Storybook**: Component library documentation + +## Conclusion + +The process-builder pages represent a sophisticated and well-architected business process management system. The implementation demonstrates strong technical competency with modern Vue.js patterns, comprehensive functionality, and excellent user experience design. + +The system is production-ready with room for performance optimizations and feature enhancements. The modular architecture provides a solid foundation for future development and scaling. + +Key strengths include the complete BPMN implementation, intuitive user interfaces, and comprehensive process management capabilities. The main opportunities lie in performance optimization, real-time features, and enhanced analytics visualization. \ No newline at end of file