Skip to main content
Skip table of contents

Projects with merging - Best Practices

The following best practices are intended to improve application maintenance and upgrades.  Initially we will discuss the setup of project files and dependencies and then development best practices, such as for component naming. 

Beyond just the project and metadata structure, developers should strive to use consistent design patterns. For example, when creating a new Filter and Grid form, it should be consistent with existing Filter and Grid implementations. If it was implemented differently, even though it is functionally the same as other implementations, it has a higher risk of not being supported in future upgrades because Framework would not be aware of that specific usage. When designing a feature, a developer should:

  • Search the current application UI to find a similar functionality or paradigm. The vast majority of project work will be similar to an existing feature. It is critical to maintain this level of consistency in both technical implementation and functionality. Please raise to the Business Analyst when there are functional inconsistencies.

  • Document new design patterns when a feature does not match an existing pattern. The new design should be documented and reviewed by the NexJ Architecture group.

Project structure

The best practice for a new project is to set its base to Finance and mix in any required additional mixins.  If you are creating a functional module, either do the work right in your project and use namespace folders, or create a new project, set its module property to an appropriate namespace, and mix it in to your main project.

Guidelines for development

The amount of customization on a project directly influences the amount of effort need to upgrade the project to a new Service Pack, Hotfix or Platform. While we cannot avoid customization completely, developers can follow certain guidelines to avoid common issues that occur during merging.

The overall strategy is to build on top of existing code as opposed to in line. Less touching core code directly results in less conflicts and easier merges.

  • Limit the amount of customization. New functions should be added to new library files as opposed to customizing an existing one.

  • Avoid “high-traffic” areas in Components. For example, adding new attributes to the top of the XML collection.

Use a Project Namespace

A new project namespace should be used for new Components on the project level to isolate custom files. This will avoid colliding with any new Components in an upgrade. This is can be done by either of the following methods:

  • When creating a component using NexJ Studio, append namespaceName: to the component name.

  • Create a namespace folder in each component folder, for example, meta/class/namespaceName.

Parallel Files

For Library files, creating a parallel version of file is a good way to avoid conflicts. A commonly customized library is client.scm. Instead of adding a new function to that file, create an enbd:client.scm file to will avoid conflicts. This works best for net new functions.

Presentation Layer Components

Forms

  • Use the same form for Create and Edit popups.

UIEvents

  • New events should be placed in a new file in the project namespace, for example, .meta/uievents/PROJECT/newFile.

Business Model Components

Classes

  • New Attributes and new Events should be added to the top of the collection in the Project. Product will continue to add to the bottom of the collection to avoid conflict.

  • Add a description to the Class, Attribute or Event. Ensure to prefix the description, for example projPrefix:newAttribute.

  • Append project prefix before the name of new actions of an Event.

  • If a required attribute is implemented, update the resulting helper function in unittesthelper.scm to ensure unrelated test cases still pass. For example, if new attribute companySize is mandatory on the Company class, then update the unittest-create-company function so that it populates to a default value.

  • If a new Class is created, create a related create function in ns:unittesthelper.scm. For example, if a new object AddressGroup is added, then create a function named unittest-create-addressGroup that will retrieve an existing instance or return a new committed instance. Also create a Test Case in the UnitTestHelper.utest for the new function.

  • In general, do not add new columns to core database tables as we want to encapsulate the core behavior to minimize conflicts. New attributes to a class should be put together in one extension table.

Enumerations

  • The typeCode value should include the project prefix. For example, SNSNewEnum.

UnitTests

  • Core Unit Tests should be resilient to any project-level configuration and should not need updating to overcome failures. If it is necessary to customize a Unit Test to correct a failure, please ensure that the issue is logged with the NexJ Product team. 

  • New Test Cases are not to be added to Core Unit Tests. New Unit Test files are to be created based on functional or technical areas. For example, ns:Entity, ns:DirectQuery.

  • Direct creation of objects should be avoided and instead use helper functions found in unittesthelper.scm. This would make the test less volatile for future model changes. For example, don't use Entity'new to create a contact for your test case, instead use unittest-create-contact.

Facets

  • For new classes/attributes that are user facing (i.e. appear in the UI or in a Report), always specify a Facet.

Persistence Components

Upgrades

  • UICompononetSeeder is an XML document that lists all components visible to the UI, as indicated by the f_ui_component_field facet. The purpose of the file is to provide a centralized location to indicate the new and modified attributes that Product has introduced in an Upgrade.

Resource Components

Strings

  • New strings should be placed in a new file in the project namespace. For example, meta/strings/PROJECT/newFile.

Libraries

  • New functions should be placed in a new library file in the project namespace. For example, meta/libraries/PROJECT/newFile.

  • All new functions will still need to be namespaced. Therefore, the function name should start with enbd:.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.