Welcome Guest to Defaut site!

Documentation System
Last Updated: 2025-09-27 | Version: 2.1 | Author: Shanta | Status: Active
Overview

The Comserv documentation system provides a structured way to organize and access documentation for different sites, roles, and modules. This document explains how the documentation system works, including visibility rules and organization principles.

Documentation Types

The system supports several types of documentation:

  • General Application Documentation
    • Common features like login, profile customization, etc.
    • Visible to all sites and users
    • Located in the main Documentation directory
  • Site-Specific Documentation
    • Documentation specific to a particular site (e.g., MCOOP, CSC)
    • Only visible to users of that specific site
    • Located in the Documentation/sites/{site_name} directory
  • Role-Specific Documentation
    • Documentation targeted at specific user roles (admin, developer, etc.)
    • Only visible to users with the appropriate role
    • Located in the Documentation/roles/{role_name} directory
  • Module Documentation
    • Documentation for specific system modules
    • Visibility depends on module access permissions
    • Located in the main Documentation directory or module-specific directories
  • Controller Documentation
    • Documentation for system controllers
    • Located in the Documentation/controllers directory
    • Primarily for developers and administrators
  • Changelog Documentation
    • Documentation of system changes and updates
    • Located in the Documentation/changelog directory
    • Helps track system evolution and recent updates
⚠️ Visibility Rules

The documentation system applies the following visibility rules:

  • CSC Site Administrators
    • Can see ALL documentation across all sites and roles
    • This is the only user group with complete documentation access
  • Site-Specific Visibility
    • Users can only see documentation for their current site
    • General documentation (site = 'all') is visible to all sites
  • Role-Based Visibility
    • Users can only see documentation appropriate for their role
    • Higher roles can see documentation for lower roles (e.g., admins can see normal user docs)
  • Module-Specific Visibility
    • Module documentation visibility follows the same site and role rules
    • Additional module-specific permissions may apply
Documentation Organization

Documentation is organized into the following categories:

  • User Guides
    • Basic documentation for end users
    • Includes getting started guides and FAQs
    • Visible to all user roles
  • Administrator Guides
    • Documentation for system administrators
    • Includes installation and configuration guides
    • Only visible to users with admin role
  • Developer Documentation
    • Technical documentation for developers
    • Includes API references and coding standards
    • Only visible to users with developer role
  • Tutorials
    • Step-by-step guides for common tasks
    • Visibility depends on the complexity of the task
  • Site-Specific Documentation
    • Documentation specific to the current site
    • Only visible to users of that site
  • Module Documentation
    • Documentation for specific system modules
    • Visibility depends on module access permissions
  • Controllers Documentation
    • Documentation for system controllers
    • Only visible to developers and administrators
  • Models Documentation
    • Documentation for system models
    • Only visible to developers and administrators
  • Changelog
    • System changes and updates
    • Only visible to developers and administrators
  • Proxmox Documentation
    • Documentation for Proxmox virtualization environment
    • Only visible to administrators
File Formats

The documentation system supports multiple file formats:

  • Markdown (.md)
    • Used primarily as working copies for AI assistants
    • Serve as staging area for edits and reviews
    • Changes are reviewed then copied to .tt files for publication
  • Template Toolkit (.tt)
    • Official, browser-friendly documentation format
    • Used for documentation that requires dynamic content
    • Can include variables, conditionals, and other TT features
    • All published documentation should be in .tt files
  • Other Formats
    • JSON, HTML, CSS, and other formats are supported
    • Served with appropriate content types
Configuration

The documentation system uses a JSON configuration file to manage documentation categories and file paths:

  • documentation_config2.json
    • Located in the Documentation directory
    • Defines documentation categories and their properties
    • Maps documentation keys to file paths
    • Allows for centralized management of documentation structure
  • Configuration Structure
    • Categories section defines all documentation categories
    • Default paths section maps documentation keys to file paths
    • This structure allows for easy reorganization of documentation
  • Updating Configuration
    • When adding new documentation, update the configuration file
    • When moving files, update the paths in the configuration
    • Ensure all paths are correct and point to existing files
Best Practices

When creating documentation, follow these best practices:

  • Proper Placement
    • Place documentation in the appropriate directory based on its type
    • Use the site-specific directory for site-specific documentation
    • Use the role-specific directory for role-specific documentation
  • Clear Metadata
    • Include Template Toolkit headers with clear metadata
    • Specify title, last updated date, version, and author
    • Include status (Active, Draft, Deprecated) and purpose
  • Structured Content
    • Use proper HTML structure with semantic tags
    • Include navigation with table of contents
    • Use appropriate CSS classes (info-box, warning-box, etc.)
    • Use code blocks with proper markup for code examples
  • Comprehensive Coverage
    • Cover all aspects of the feature or module
    • Include examples and use cases
    • Address common questions and issues
  • Regular Updates
    • Keep documentation up-to-date with system changes
    • Use Template Toolkit date functions for dynamic dates
    • Archive or clearly mark deprecated documentation
  • Configuration Management
    • Update the documentation_config2.json file when adding or moving documentation
    • Ensure all paths in the configuration file are correct
    • Test documentation visibility after configuration changes
Adding New Documentation

To add new documentation to the system:

  1. Determine the Type
    • Is it general, site-specific, role-specific, or module-specific?
  2. Choose the Location
    • Place the file in the appropriate directory
    • Use a descriptive filename with .tt extension
  3. Include Template Toolkit Headers
    • Add Template Toolkit headers with metadata
    • Include title, author, date, version, and status
  4. Write the Content
    • Follow the structured HTML format with proper CSS classes
    • Include all necessary sections and information
  5. Update Configuration
    • Add the document to the documentation_config2.json file
    • Specify the correct path and category
  6. Test Visibility
    • Verify that the document is visible to the intended audience
    • Check that it appears in the appropriate category
Accessing Documentation

Users can access documentation through:

  • Documentation Index
    • Available at /documentation
    • Shows all documentation visible to the current user
  • Direct URLs
    • Access specific documents via /documentation/page_name
    • File extensions are optional (e.g., /documentation/user_guide or /documentation/user_guide.md)
  • Category Pages
    • Access category-specific documentation via /documentation/category/category_name
    • Shows all documents in that category visible to the current user
  • Search
    • Use the documentation search feature to find specific content
    • Searches only within documentation visible to the current user
Technical Implementation

The documentation system is implemented in the Documentation.pm controller with these key components:

  • Scanning Mechanism
    • Scans documentation directories on application startup
    • Builds metadata for each documentation file
    • Uses the documentation_config2.json file for configuration
  • Filtering Logic
    • Filters documentation based on user role and site
    • Special case for CSC site admins who can see everything
  • Rendering System
    • Renders Markdown files as working copies
    • Processes Template Toolkit files with the TT view for publication
    • Supports dynamic content with TT features
  • Access Control
    • Enforces visibility rules based on site and role
    • Provides appropriate error messages for unauthorized access
  • Modular Template Structure
    • The main index.tt file has been refactored to improve maintainability
    • Each documentation category now has its own separate template file
    • This modular approach makes it easier to update specific sections without affecting others
    • Template includes are used to assemble the complete documentation interface
Template Structure

The documentation system's template structure has been refactored to improve maintainability and organization:

  • Main Index Template
    • The main index.tt file now serves as a container for the documentation interface
    • It includes modular template components for different sections
    • This approach reduces complexity and makes the code more maintainable
  • Category Templates
    • Each documentation category has its own dedicated template file
    • Examples:
      • user_guides.tt - Template for user documentation
      • admin_guides.tt - Template for administrator documentation
      • developer_guides.tt - Template for developer documentation
      • tutorials.tt - Template for tutorials
      • site_specific.tt - Template for site-specific documentation
  • Shared Components
    • Common UI elements are extracted into reusable components
    • This includes navigation, search, and filtering controls
    • These components can be included in multiple templates
  • Benefits of Modular Structure
    • Easier maintenance: Changes to one category don't affect others
    • Better organization: Code is logically grouped by functionality
    • Improved readability: Smaller, focused template files
    • Easier collaboration: Multiple developers can work on different sections
Debugging

The documentation system includes debugging features to help troubleshoot issues:

  • Debug Mode
    • Enable debug mode to see detailed information about documentation loading
    • Debug messages are pushed to the stash and displayed in the template
  • Logging
    • The system logs documentation scanning and categorization
    • Check the application log for errors and warnings
  • Configuration Validation
    • The system validates the documentation_config2.json file
    • Errors in the configuration are logged
Future Enhancements

Planned enhancements for the documentation system include:

  • Improved Search
    • Full-text search across all documentation
    • Advanced filtering options
  • Version Control
    • Track changes to documentation over time
    • View previous versions of documents
  • User Feedback
    • Allow users to rate and comment on documentation
    • Collect suggestions for improvements
  • Interactive Examples
    • Add interactive code examples and demos
    • Include video tutorials for complex topics
  • Documentation Analytics
    • Track which documentation is most frequently accessed
    • Identify gaps in documentation coverage
  • Further Template Improvements
    • Additional modularization of template components
    • Dynamic loading of documentation sections
    • Improved mobile responsiveness
ENCY System

ENCY Module

The goal of ency is to provide a comprehensive database of herbs and their uses. We will be starting with plants that have medicinal properties, but the database can be expanded to include other types of plants as well. They will be categorized by their botanical names, common names, and uses. The database will also include references to scientific studies and other sources of information about the plants. Here is a preliminary view of the database structure: 1. Core Tables This is just a start. The database structure will evolve as we add more features and functionality. Plants This will be the main table where each plant entry is stored. plant_id (Primary Key) botanical_name common_names key_name description image_url Should a table with a list of images be created? distribution comments history username_of_poster group_of_poster date_time_posted TherapeuticActions Stores different therapeutic actions associated with plants. action_id (Primary Key) name description PlantTherapeuticActions A many-to-many relationship table linking plants to their therapeutic actions. plant_id (Foreign Key to Plants) action_id (Foreign Key to TherapeuticActions) Constituents Stores information about the chemical components of plants. constituent_id (Primary Key) name formula description PlantConstituents A many-to-many relationship table linking plants to their chemical constituents. plant_id (Foreign Key to Plants) constituent_id (Foreign Key to Constituents) Cultivation Details methods and information about the cultivation of plants. cultivation_id (Primary Key) plant_id (Foreign Key to Plants) method soil_type sun_exposure watering 2. Specialized Tables Pollinators we want to know what part of the plant the pollinators are attracted to. pollinator_id (Primary Key) name type (insect, animal, etc.) Tracks the pollinators associated with each plant. pollinator_id (Primary Key) name type (insect, animal, etc.) PlantPollinators Links plants to their pollinators. plant_id (Foreign Key to Plants) pollinator_id (Foreign Key to Pollinators) PartsUsed Stores different parts of the plant that are used. part_id (Primary Key) name description PlantPartsUsed Links plants to the parts used. plant_id (Foreign Key to Plants) part_id (Foreign Key to PartsUsed) 3. Relational Integrity Formulas Details various formulas that include plants. formula_id (Primary Key) name description therapeutic action PlantFormulas Links plants to the formulas they are part of. plant_id (Foreign Key to Plants) formula_id (Foreign Key to Formulas) 4. User Roles and Access Users Tracks users in the system with roles. user_id (Primary Key) username role (admin, researcher, etc.) group UserAccess Controls access based on roles. user_id (Foreign Key to Users) access_level The ency module is divided into two parts: the controller and the model. References This table will store references to scientific studies and other sources of information about the plants. if a reference is made to a plant, component therapeutic action, etc. we provide connection to that date her.. reference_id (Primary Key) title author publication_date url description plant_id (Foreign Key to Plants) References are rated as well. rating_id (Primary Key) reference_id (Foreign Key to References) user_id (Foreign Key to Users) rating date_time_rated comments diseases table will store diseases that plants, animals, fungi, etc.can treat. id (Primary Key) reference_id (Foreign Key to References) user_id (Foreign Key to Users) date_time_dissed comments Animals id (Primary Key) reference_id (Foreign Key to References) user_id (Foreign Key to Users) date_time_dissed comments Fungi id (Primary Key) reference_id (Foreign Key to References) user_id (Foreign Key to Users) date_time_dissed comments insects id (Primary Key) reference_id (Foreign Key to References) user_id (Foreign Key to Users) date_time_dissed comments We will need link tables to connect the diseases, animals, fungi, and insects to the plants that can treat them. or vice versa. plant_id (Foreign Key to Plants) disease_id (Foreign Key to Diseases) animal_id (Foreign Key to Animals) fungi_id (Foreign Key to Fungi) insect_id (Foreign Key to Insects) disease_id (Foreign Key to Diseases) plant_id (Foreign Key to Plants) animal_id (Foreign Key to Animals) fungi_id (Foreign Key to Fungi) insect_id (Foreign Key to Insects) animal_id (Foreign Key to Animals) plant_id (Foreign Key to Plants) disease_id (Foreign Key to Diseases) fungi_id (Foreign Key to Fungi) insect_id (Foreign Key to Insects) fungi_id (Foreign Key to Fungi) plant_id (Foreign Key to Plants) disease_id (Foreign Key to Diseases) animal_id (Foreign Key to Animals) insect_id (Foreign Key to Insects) insect_id (Foreign Key to Insects) plant_id (Foreign Key to Plants) disease_id (Foreign Key to Diseases) animal_id (Foreign Key to Animals) fungi_id (Foreign Key to Fungi) The controller is responsible for handling requests related to the ency model, while the model is responsible for handling data related to the ency controller. The controller is responsible for handling requests related to the ency model, while the model is responsible for handling data related to the ency controller.

ENCY ControllerENCY Controller

The ENCY controller is responsible for handling requests related to the ENCY model. It includes several subroutines, each of which performs a specific task.

Return to top

index

The index subroutine handles requests to the root of the ENCY controller's URL. It sets the template to 'ENCY/index.tt', which is used to render the response.


sub index :Path('/ENCY') :Args(0) {
    my ( $self, $c ) = @_;
    # The index action will display the 'index.tt' template
    $c->stash(template => 'ENCY/index.tt');
}

Return to top

botanical_name_view

The botanical_name_view subroutine handles requests to display the Botanical Name View page. It fetches herbal data from the 'DBForager' model and passes this data to the template.


sub index :Path('/ENCY') :Args(0) {
    my ( $self, $c ) = @_;
    # The index action will display the 'index.tt' template
    $c->stash(template => 'ENCY/index.tt');
}

Return to top

botanical_name_view

The botanical_name_view subroutine handles requests to display the Botanical Name View page. It fetches herbal data from the 'DBForager' model and passes this data to the template.


sub botanical_name_view :Path('/ENCY/BotanicalNameView') :Args(0) {
    my ( $self, $c ) = @_;

    # Fetch the herbal data
    my $forager_data = $c->model('DBForager')->get_herbal_data();

    # Pass the data to the template
    my $herbal_data = $forager_data;
    $c->stash(herbal_data => $herbal_data, template => 'ENCY/BotanicalNameView.tt');
}

Return to top

herb_detail

The herb_detail subroutine handles requests to display detailed information about a specific herb. It takes an id as an argument, fetches the corresponding herb from the 'DBForager' model, and sets the herb and the template 'ENCY/HerbDetailView.tt' in the stash.


sub herb_detail :Path('/ENCY/herb_detail') :Args(1) {
    my ( $self, $c, $id ) = @_;
    my $herb = $c->model('DBForager')->get_herb_by_id($id);
    $c->stash(herb => $herb, template => 'ENCY/HerbDetailView.tt');
}

Return to top

add_herb

The add_herb subroutine handles requests to add a new herb. It processes the form submission and saves the new herb to the database.

get_reference_by_id

The get_reference_by_id subroutine handles requests to get a reference by its id. It takes an id as an argument, fetches the corresponding reference from the 'ENCY' model, and sets the reference and the template 'ency/get_reference_form.tt' in the stash.


sub get_reference_by_id :Local {
    my ( $self, $c, $id ) = @_;
    my $reference = $c->model('ENCY')->get_reference_by_id($id);
    $c->stash(reference => $reference, template => 'ency/get_reference_form.tt');
}

Return to top

create_reference

The create_reference subroutine handles requests to display the form for creating a new reference. It sets the template 'ency/create_reference_form.tt' in the stash.


sub add_herb :Path('/ENCY/add_herb') :Args(0) {
    my ( $self, $c ) = @_;

    if ($c->request->method eq 'POST') {
        # Handle form submission
        my $form_data = $c->request->body_parameters;

        my $new_herb = {
            therapeutic_action => $form_data->{therapeutic_action},
            botanical_name => $form_data->{botanical_name},
            common_names => $form_data->{common_names},
            parts_used => $form_data->{parts_used},
            comments => $form_data->{comments},
            medical_uses => $form_data->{medical_uses},
            homiopathic => $form_data->{homiopathic},
            ident_character => $form_data->{ident_character},
            image => $form_data->{image},
            stem => $form_data->{stem},
            nectar => $form_data->{nectar},
            pollinator => $form_data->{pollinator},
            pollen => $form_data->{pollen},
            leaves => $form_data->{leaves},
            flowers => $form_data->{flowers},
            fruit => $form_data->{fruit},
            taste => $form_data->{taste},
            odour => $form_data->{odour},
            distribution => $form_data->{distribution},
            url => $form_data->{url},
            root => $form_data->{root},
            constituents => $form_data->{constituents},
            solvents => $form_data->{solvents},
            chinese => $form_data->{chinese},
            culinary => $form_data->{culinary},
            contra_indications => $form_data->{contra_indications},
            dosage => $form_data->{dosage},
            administration => $form_data->{administration},
            formulas => $form_data->{formulas},
            vetrinary => $form_data->{vetrinary},
            cultivation => $form_data->{cultivation},
            sister_plants => $form_data->{sister_plants},
            harvest => $form_data->{harvest},
            non_med => $form_data->{non_med},
            history => $form_data->{history},
            reference => $form_data->{reference},
            username_of_poster => $c->session->{username},
            group_of_poster => $c->session->{group},
            date_time_posted => \'NOW()',  # Assuming you want to set this to the current timestamp
            share => $form_data->{share} // 0,
            should_display => $form_data->{should_display} // 0,
            preperation => $form_data->{preperation},
            pollennotes => $form_data->{pollennotes},
            nectarnotes => $form_data->{nectarnotes},
            apis => $form_data->{apis},
        };

        # Save the new herb using the ENCYModel
        $c->model('ENCYModel')->add_herb($new_herb);

        # Redirect or display a success message
        $c->flash->{success_message} = 'Herb added successfully';
        $c->res->redirect($c->uri_for($self->action_for('index')));
    } else {
        # Display the form
        $c->stash(
            template => 'ENCY/add_herb_form.tt',
            user_role => $c->session->{roles}  # Pass user role to the template
        );
    }
    $c->stash(template => 'ency/create_reference_form.tt');
}

Return to top

get_category_by_id

The get_category_by_id subroutine handles requests to get a category by its id. It takes an id as an argument, fetches the corresponding category from the 'ENCY' model, and sets the category and the template 'ency/get_category_form.tt' in the stash.


sub get_category_by_id :Local {
    my ( $self, $c, $id ) = @_;
    my $category = $c->model('ENCY')->get_category_by_id($id);
    $c->stash(category => $category, template => 'ency/get_category_form.tt');
}

Return to top

For more information on how AI can enhance the functionalities of the ENCY module, refer to the AI Integration Plan.

create_category

The create_category subroutine handles requests to display the form for creating a new category. It sets the template 'ency/create_category_form.tt' in the stash.


sub create_category :Local {
    my ( $self, $c ) = @_;
    $c->stash(template => 'ency/create_category_form.tt');
}

Return to top

edit_herb

The edit_herb subroutine handles requests to edit an existing herb. It processes the form submission and updates the herb in the database.


sub edit_herb :Path('/ENCY/edit_herb') :Args(0) {
    my ( $self, $c ) = @_;
    my $form_data = $c->request->params;

    # Ensure all required fields are captured and logged
    $self->logging->log_with_details('info', "Form data: " . join(", ", map { "$_: $form_data->{$_}" } keys %$form_data));

    if ($c->request->method eq 'POST') {
        my $id = $c->session->{record_id};  # Retrieve the record_id from the session

        # Add all specified fields to the updated_herb hash
        my $updated_herb = {
            botanical_name => $form_data->{botanical_name} // '',
            common_names => $form_data->{common_names} // '',
            parts_used => $form_data->{parts_used} // '',
            comments => $form_data->{comments} // '',
            contra_indications => $form_data->{contra_indications} // '',
            preparation => $form_data->{preparation} // '',
            chinese => $form_data->{chinese} // '',
            vetrinary => $form_data->{vetrinary} // '',
            homiopathic => $form_data->{homiopathic} // '',
            key_name => $form_data->{key_name} // '',  # Added key_name
            url => $form_data->{url} // '',            # Added url
            apis => $form_data->{apis} // 0,  # Ensure apis is an integer
            pollinator => $form_data->{pollinator} // '',
            pollen => $form_data->{pollen} // 0,  # Ensure pollen is an integer
            pollennotes => $form_data->{pollennotes} // '',
            parts_used => $form_data->{parts_used} // '',  # Added parts_used
        };

        # Log the updated herb data
        $self->logging->log_with_details('info', "Updated herb data: " . join(", ", map { "$_: $updated_herb->{$_}" } keys %$updated_herb));

        my ($success, $message) = $c->model('ENCYModel')->update_herb($id, $updated_herb);
        if (!$success) {
            $self->logging->log_with_details('error', "Failed to update herb: $message");
            $c->stash(
                error_message => $message,
                mode => 'edit',
                herb => $form_data,
                template => 'ENCY/HerbView.tt'
            );
        } else {
            $c->flash->{success_message} = $message;
            $c->res->redirect($c->uri_for($self->action_for('herb_detail'), [$id]));
        }
    } else {
        my $id = $c->request->params->{id};  # Retrieve the id from the request parameters
        my $herb = $c->model('DBForager')->get_herb_by_id($id);
        $c->session->{record_id} = $id;  # Store the id in the session
        $c->stash(
            mode => 'edit',
            herb => $herb,
            template => 'ENCY/HerbView.tt'
        );
    }
}

Return to top

add_herb

The add_herb subroutine handles requests to add a new herb. It processes the form submission and saves the new herb to the database.


sub add_herb :Path('/ENCY/add_herb') :Args(0) {
    my ( $self, $c ) = @_;

    if ($c->request->method eq 'POST') {
        # Handle form submission
        my $form_data = $c->request->body_parameters;

        my $new_herb = {
            therapeutic_action => $form_data->{therapeutic_action},
            botanical_name => $form_data->{botanical_name},
            common_names => $form_data->{common_names},
            parts_used => $form_data->{parts_used},
            comments => $form_data->{comments},
            medical_uses => $form_data->{medical_uses},
            homiopathic => $form_data->{homiopathic},
            ident_character => $form_data->{ident_character},
            image => $form_data->{image},
            stem => $form_data->{stem},
            nectar => $form_data->{nectar},
            pollinator => $form_data->{pollinator},
            pollen => $form_data->{pollen},
            leaves => $form_data->{leaves},
            flowers => $form_data->{flowers},
            fruit => $form_data->{fruit},
            taste => $form_data->{taste},
            odour => $form_data->{odour},
            distribution => $form_data->{distribution},
            url => $form_data->{url},
            root => $form_data->{root},
            constituents => $form_data->{constituents},
            solvents => $form_data->{solvents},
            chinese => $form_data->{chinese},
            culinary => $form_data->{culinary},
            contra_indications => $form_data->{contra_indications},
            dosage => $form_data->{dosage},
            administration => $form_data->{administration},
            formulas => $form_data->{formulas},
            vetrinary => $form_data->{vetrinary},
            cultivation => $form_data->{cultivation},
            sister_plants => $form_data->{sister_plants},
            harvest => $form_data->{harvest},
            non_med => $form_data->{non_med},
            history => $form_data->{history},
            reference => $form_data->{reference},
            username_of_poster => $c->session->{username},
            group_of_poster => $c->session->{group},
            date_time_posted => \'NOW()',  # Assuming you want to set this to the current timestamp
            share => $form_data->{share} // 0,
            should_display => $form_data->{should_display} // 0,
            preperation => $form_data->{preperation},
            pollennotes => $form_data->{pollennotes},
            nectarnotes => $form_data->{nectarnotes},
            apis => $form_data->{apis},
        };

        # Save the new herb using the ENCYModel
        $c->model('ENCYModel')->add_herb($new_herb);

        # Redirect or display a success message
        $c->flash->{success_message} = 'Herb added successfully';
        $c->res->redirect($c->uri_for($self->action_for('index')));
    } else {
        # Display the form
        $c->stash(
            template => 'ENCY/add_herb_form.tt',
            user_role => $c->session->{roles}  # Pass user role to the template
        );
    }
}

Return to top

The search subroutine handles requests to search for herbs. It processes the search string and fetches the results from the 'DBForager' model.


sub search :Path('/ENCY/search') :Args(0) {
    my ($self, $c) = @_;

    my $search_string = $c->request->parameters->{search_string};

    # Call the searchHerbs method in the DBForager model
    my $results = $c->model('DBForager')->searchHerbs($c, $search_string);

    # Stash the results for the view
    $c->stash(herbal_data => $results);  # Changed from 'results' to 'herbal_data'

    # Get the referer from the request headers
    my $referer = $c->req->headers->referer;

    # Extract the template name from the referer
    $c->stash(template => 'ENCY/BotanicalNameView.tt');
}

Return to top

Problem Description

There was an issue with the `HerbView.tt` form where the values were not being saved into the database. The form data was not being correctly passed to the `edit_herb` subroutine, and the existing functionality was inadvertently removed during debugging attempts. The goal was to ensure that the form data is correctly passed and saved without removing any existing functionality.

Return to top

Each of these subroutines relies on the ENCY model to perform its tasks. The ENCY model is loaded in the ENCY controller with the use Comserv::Model::ENCY; statement. The ENCY model is defined in the 'Comserv::Model::ENCY' package, which is located in the 'lib/Comserv/Model' directory.

Return to top

Future Development

To evolve the ENCY application, consider the following enhancements:

  • Improved Data Validation: Implement stricter data validation and error handling in all subroutines to ensure data integrity and provide better user feedback.
  • Enhanced User Interface: Develop more interactive and user-friendly templates, possibly integrating JavaScript frameworks for a better user experience.
  • API Integration: Create RESTful API endpoints to allow external applications to interact with the ENCY data, enabling wider access and integration.
  • Search and Filtering: Add advanced search and filtering capabilities to allow users to find specific information more efficiently.
  • Automated Data Updates: Implement automation for data updates from trusted sources to keep the information current and accurate.
  • User Contributions: Develop features that allow users to contribute data and corrections, with moderation workflows to ensure quality.

ENCY Model

ENCY Model

The ENCY model is responsible for handling data related to the ENCY controller. It includes several methods, each of which performs a specific task.

Return to top

get_reference_by_id

The 'get_reference_by_id' method is responsible for fetching a reference by its id. It takes an id as an argument, fetches the corresponding reference from the database, and returns the reference.

Return to top

create_reference

The 'create_reference' method is responsible for creating a new reference. It takes the necessary data as arguments, creates a new reference in the database, and returns the new reference.

Return to top

get_category_by_id

The 'get_category_by_id' method is responsible for fetching a category by its id. It takes an id as an argument, fetches the corresponding category from the database, and returns the category.

Return to top

create_category

The 'create_category' method is responsible for creating a new category. It takes the necessary data as arguments, creates a new category in the database, and returns the new category.

Return to top

Each of these methods is used by the ENCY controller to perform its tasks. The ENCY model is defined in the 'Comserv::Model::ENCY' package, which is located in the 'lib/Comserv/Model' directory.

Return to top


package Comserv::Model::Schema::Forager::Result::Herb;

use strict;
use warnings;
use base 'DBIx::Class::Core';

__PACKAGE__->load_components('InflateColumn::DateTime', 'TimeStamp', 'EncodedColumn');
__PACKAGE__->table('ency_herb_tb');
__PACKAGE__->add_columns(
    'therapeutic_action',
    'record_id',
    'apis',
    'botanical_name',
    'common_names',
    'key_name',
    'parts_used',
    'comments',
    'medical_uses',
    'homiopathic',
    'ident_character',
    'image',
    'stem',
    'nectar',
    'pollinator',
    'pollen',
    'leaves',
    'flowers',
    'fruit',
    'taste',
    'odour',
    'distribution',
    'url',
    'root',
    'constituents',
    'solvents',
    'chinese',
    'culinary',
    'contra_indications',
    'dosage',
    'administration',
    'formulas',
    'vetrinary',
    'cultivation',
    'sister_plants',
    'harvest',
    'non_med',
    'history',
    'reference',
    'username_of_poster',
    'group_of_poster',
    'date_time_posted',
    'share' => { data_type => 'integer', default_value => 0, is_nullable => 0 },
    'should_display' => { data_type => 'integer', default_value => 0, is_nullable => 0 },
    'preperation' => { data_type => 'varchar', size => 150, is_nullable => 0 },
    'pollennotes' => { data_type => 'text', is_nullable => 0 },
    'nectarnotes' => { data_type => 'text', is_nullable => 0 },
    'apis' => { data_type => 'varchar', size => 100, is_nullable => 0 },
);

__PACKAGE__->set_primary_key('record_id');

1;

Return to top

Controller

The goal of ENCY is to provide a comprehensive database of herbs and their uses. We will be starting with plants that have medicinal properties, but the database can be expanded to include other types of plants as well. They will be categorized by their botanical names, common names, and uses. The database will also include references to scientific studies and other sources of information about the plants.

Plan for Creating the ENCY Module

  1. Database Design: Define the database schema and create the necessary tables and relationships.
  2. CREATE TABLE Plants ( plant_id INT PRIMARY KEY AUTO_INCREMENT, botanical_name VARCHAR(255), common_names TEXT, key_name VARCHAR(255), description TEXT, image_url VARCHAR(255), distribution TEXT, comments TEXT, history TEXT, username_of_poster VARCHAR(255), group_of_poster VARCHAR(255), date_time_posted DATETIME ); CREATE TABLE TherapeuticActions ( action_id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), description TEXT ); CREATE TABLE PlantTherapeuticActions ( plant_id INT, action_id INT, FOREIGN KEY (plant_id) REFERENCES Plants(plant_id), FOREIGN KEY (action_id) REFERENCES TherapeuticActions(action_id) ); CREATE TABLE Constituents ( constituent_id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), formula VARCHAR(255), description TEXT ); CREATE TABLE PlantConstituents ( plant_id INT, constituent_id INT, FOREIGN KEY (plant_id) REFERENCES Plants(plant_id), FOREIGN KEY (constituent_id) REFERENCES Constituents(constituent_id) ); CREATE TABLE Cultivation ( cultivation_id INT PRIMARY KEY AUTO_INCREMENT, plant_id INT, method TEXT, soil_type VARCHAR(255), sun_exposure VARCHAR(255), watering VARCHAR(255), FOREIGN KEY (plant_id) REFERENCES Plants(plant_id) ); CREATE TABLE Pollinators ( pollinator_id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), type VARCHAR(255) ); CREATE TABLE PlantPollinators ( plant_id INT, pollinator_id INT, FOREIGN KEY (plant_id) REFERENCES Plants(plant_id), FOREIGN KEY (pollinator_id) REFERENCES Pollinators(pollinator_id) ); CREATE TABLE PartsUsed ( part_id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), description TEXT ); CREATE TABLE PlantPartsUsed ( plant_id INT, part_id INT, FOREIGN KEY (plant_id) REFERENCES Plants(plant_id), FOREIGN KEY (part_id) REFERENCES PartsUsed(part_id) ); CREATE TABLE Formulas ( formula_id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), description TEXT, therapeutic_action TEXT ); CREATE TABLE PlantFormulas ( plant_id INT, formula_id INT, FOREIGN KEY (plant_id) REFERENCES Plants(plant_id), FOREIGN KEY (formula_id) REFERENCES Formulas(formula_id) ); CREATE TABLE Users ( user_id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(255), role VARCHAR(255), group_name VARCHAR(255) ); CREATE TABLE UserAccess ( user_id INT, access_level VARCHAR(255), FOREIGN KEY (user_id) REFERENCES Users(user_id) ); CREATE TABLE References ( reference_id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(255), author VARCHAR(255), publication_date DATE, url VARCHAR(255), description TEXT, plant_id INT, FOREIGN KEY (plant_id) REFERENCES Plants(plant_id) ); CREATE TABLE Ratings ( rating_id INT PRIMARY KEY AUTO_INCREMENT, reference_id INT, user_id INT, rating INT, date_time_rated DATETIME, comments TEXT, FOREIGN KEY (reference_id) REFERENCES References(reference_id), FOREIGN KEY (user_id) REFERENCES Users(user_id) ); CREATE TABLE Diseases ( disease_id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), description TEXT ); CREATE TABLE Animals ( animal_id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), description TEXT ); CREATE TABLE Fungi ( fungi_id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), description TEXT ); CREATE TABLE Insects ( insect_id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), description TEXT ); CREATE TABLE PlantDiseases ( plant_id INT, disease_id INT, FOREIGN KEY (plant_id) REFERENCES Plants(plant_id), FOREIGN KEY (disease_id) REFERENCES Diseases(disease_id) ); CREATE TABLE PlantAnimals ( plant_id INT, animal_id INT, FOREIGN KEY (plant_id) REFERENCES Plants(plant_id), FOREIGN KEY (animal_id) REFERENCES Animals(animal_id) ); CREATE TABLE PlantFungi ( plant_id INT, fungi_id INT, FOREIGN KEY (plant_id) REFERENCES Plants(plant_id), FOREIGN KEY (fungi_id) REFERENCES Fungi(fungi_id) ); CREATE TABLE PlantInsects ( plant_id INT, insect_id INT, FOREIGN KEY (plant_id) REFERENCES Plants(plant_id), FOREIGN KEY (insect_id) REFERENCES Insects(insect_id) );
  3. Database Configuration: Load the database configuration from a JSON file.
  4. Model Development: Create the ENCY model and implement methods for data retrieval and manipulation.
  5. Controller Development: Create the ENCY controller and implement methods for handling web requests and responses.
  6. Debugging and Logging: Add debugging output and logging mechanisms.
  7. Security: Implement security measures such as password hashing.
  8. Catalyst Integration: Integrate the ENCY module with the Catalyst framework.

Pros and Cons of MySQL and PostgreSQL for Data Storage

MySQL

  • Pros: Widely used, high performance for read-heavy operations, easy to set up, strong community support.
  • Cons: Limited support for advanced SQL features, less efficient for write-heavy operations, less flexible in terms of data types and indexing.

PostgreSQL

  • Pros: Advanced SQL features, better performance for write-heavy operations, highly extensible, strong support for complex queries and indexing.
  • Cons: More complex to set up, can be slower for simple read-heavy operations, smaller community compared to MySQL.