Chapter 8 - Prod / Dev Design and Operations
Every form worth maintaining needs somewhere to change it safely before users see the change. This chapter describes two ways to organise a development (or UAT) copy next to production, and the operating routine that goes with each. Both assume the template uses the Dynamic Data Connections XTP from Chapter 7; without it, every promotion means editing connection URLs by hand.
8.1 What has to differ between Prod and Dev
| Concern | Prod | Dev / UAT |
|---|---|---|
| Where submitted forms land | Production form library | A library only testers see |
| Lists the form reads (lookups, choices) | Production data | Same data, or a test copy |
| Who can open the form | End users | Designers and testers |
| Template version | Published, stable | Draft or newer version under test |
The template itself should be identical in both places. Anything that differs has to come from the environment (the site the form runs on, or the template name), never from a hand edit made during promotion.
8.2 Approach 1 - separate sites, identical names
Prod and Dev are two sites (or a site and a subsite). Each has the same libraries and lists with exactly the same names: the form library the template submits to, every list it queries, and any library it reads.
How it works: Dynamic DCs re-points every enabled connection to the site the form is opened from (SPHostUrl). Because the names match, the re-pointed URLs resolve on both sites without any per-site configuration.
Setting it up:
- Create the Dev site (or subsite). Create the libraries and lists with names identical to Prod. Match internal column names too if the form promotes properties or maps list fields.
- Deploy FormsViewer on the Dev site and upload the template there.
- In the template, enable Dynamic DCs for every connection type in use and set the submit library name once (Chapter 7, section 7.4).
- Switch off Query during form load on the re-pointed connections and query after Run Dynamic DCs (Chapter 7, section 7.5).
Operating routine:
- Design and test on Dev. Use Open (Ctrl+O) for quick checks; publish on Dev for tester UAT.
- When UAT passes, Download the template from Dev and upload the same file to Prod's FormsViewer (Manage Templates > upload as a new version of the existing template), then publish. No edits in between.
- Keep the version number visible (the sample form shows "Solution Version" in the footer) so support can tell which build a user is on.
- Keep the previously promoted template file (Download it before uploading the new one). To roll back, upload that file again as the next version and publish it. Version History lists earlier versions but does not offer a one-click restore.
Strengths: complete separation of data and permissions; testers cannot pollute production libraries; identical templates by construction. Cost: two sites to keep in step. Lists and libraries must match not only by name but by schema: a missing column, a renamed internal name, or a different column type on Prod breaks queries and submits that worked on Dev. When a list or column is added on Dev it must be added on Prod, identically, before promotion; put that on the promotion checklist.
8.3 Approach 2 - one site, submit target chosen by template name
Prod and Dev live on the same site. The read-only lookups are shared, and only the submit target differs: the development copy of the template (for example ExpenseReport-DEV) submits to a test library, the production template (ExpenseReport) submits to the production library.
How it works: at start-up the form asks FormsViewer which template it was opened as, with the qRules command GetInputParameter /key=templateName, and sets the submit library accordingly before Dynamic DCs runs ChangeSubmitUrl. The same XSN is uploaded twice, once as ExpenseReport and once as ExpenseReport DEV; nothing inside the file changes between the two.
Setting it up:
- Create the test form library next to the production one (for example
DEV Expense ReportsbesideExpense Reports). - Upload the template twice with different names, one carrying a marker such as
DEV. - Add a hidden text field in the main data source, for example
TemplateName. - In the finishedLoading rule list, above Run Dynamic DCs, add a rule Set Template Name with two actions:
Run a qRules Command:"GetInputParameter /key=templateName"Set a field value:TemplateName= QdabraRules > Result- Directly below it add two rules that write the library name into XtpLogic_DynamicDCs > XtpLogic > Actions > Connections > submitLibraries (the
@libraryNamevalue of the "SharePoint Library Submit [edit]" slot): - Use DEV library: condition TemplateName contains
DEV; actionSet a field value@libraryName ="DEV Expense Reports". - Use production library: condition TemplateName does not contain
DEV; actionSet a field value@libraryName ="Expense Reports". - Leave Run Dynamic DCs below these rules so
ChangeSubmitUrlpicks up the chosen library. - Everything else stays shared. If the form also reads a lookup that must differ per environment, switch it the same way with
queryListsorqueryLibrariesinstead of hard-coding two connections.
Operating routine:
- Edit and publish only the
-DEVtemplate while testing. Production users keep using the unmarked template. - To promote, download the
-DEVtemplate and upload it as the new version of the production template. Because the switch keys off the template name, the same file behaves as production once it is uploaded under the production name. - Roll back by re-uploading the previous file as in 8.2.
Strengths: one site to maintain, shared lookups stay in sync automatically, quick to set up. Limits: testers work against production lookup lists (fine for read-only lookups, not for lists the form writes to); permissions are shared; the template name convention must be respected by everyone who uploads. If the form also submits to lists (SubmitToSharePointList) or several libraries, extend the switch to each target, or move to Approach 1.
8.4 Choosing
| If ... | Use |
|---|---|
| The form writes to more than one list or library | Approach 1 |
| Testers must not see production data | Approach 1 |
| The form is mostly read-only lookups plus one submit | Approach 2 |
| You have no rights to create sites | Approach 2 |
| Several forms share the environment | Approach 1 (one Dev site serves all of them) |
Both approaches can coexist: a Dev site for heavy changes and a -DEV template on Prod for quick fixes that need production data to reproduce.
8.5 Promotion checklist
Use this for every promotion, whichever approach:
- Draft tested with Open (Ctrl+O); published on Dev (or as
-DEV) and signed off by a tester. - Rule Inspector shows no warnings (Chapter 10).
- New lists, columns, or libraries created on Prod with identical names, internal names, and column types (Approach 1), or the submit switch verified (Approach 2).
- Query connections checked against list Titles and submit connections against library URL names on Prod (Chapter 7, section 7.4).
- User profile properties the form relies on exist on the Prod tenant; custom profile properties are tenant-specific and do not travel with the template.
- Previous Prod template file downloaded and kept for rollback.
- Template downloaded from Dev, uploaded to Prod unchanged, version number noted.
- Published on Prod; one real submission checked in the production library; Debug Slider log confirms
ChangeSubmitUrlpoints at the production library.
8.6 Summary
- The template must be identical across environments; let the environment decide the targets.
- Approach 1: separate sites with identical list and library names, Dynamic DCs does the rest.
- Approach 2: one site, a
-DEVtemplate name switches only the submit library, set before Run Dynamic DCs. - Promote by uploading the same file, never by editing connections on Prod.
Next: Chapter 9 - Recipes.