Meridian handbook
ReferenceConfiguration

Portal files

Every key of config/portal/portal.yaml (the member portal's install defaults, member report rules and invitation timings), config/sites/<key>/portal.yaml (a site's portal, screens and actions) and config/portal/roles.yaml (partner roles), all engine-dmo.

engine-dmo

This feature is part of the DMO bundle (engine-dmo).

The member portal is where the people behind partner businesses sign in to update their listings, see their report and manage their membership. Three files configure it. Partners and the portal and Portal screens and actions explain the portal; this page lists every key.

portal/portal.yaml

The install’s portal. A portal: block in engine.yaml is still read, with a warning that it belongs here.

portal:
  mode: both
  invitations:
    expiry: 30d
    reminder_after: 7d
  report:
    peer_comparison: true
    peer_min_cohort: 5

A project on engine-dmo has the portal on by default (engine-dmo describe project shows portal /members, both). A site with no partner businesses turns it off with one file:

# config/portal/portal.yaml
portal:
  mode: "off"

Quote "off", or YAML may read it as a boolean in other tools; the engine accepts either.

KeyTypeDefaultMeaning
portal.modestringbothtemplated (the engine renders the portal through your templates), api (the member API only, for an app of your own), both, or off
portal.templated.enabledbooleantrueServe the templated portal
portal.templated.template_dirstringportalThe portal’s template directory in each template root
portal.templated.routesmap of strings{}A screen’s path under server.portal_path, by screen key; a screen left out keeps its default path
portal.invitations.expiryretention30dHow long an invitation works. Whole days
portal.invitations.reminder_afterretention7dWhen an unanswered invitation is chased. Whole days, before the expiry
portal.report.peer_comparisonbooleantrueCompare a member’s figures with similar businesses
portal.report.peer_min_cohortinteger5The fewest peers a comparison needs; below it the comparison is left out
portal.report.improvement_prompts.enabledbooleantrueShow “make your listing work harder” prompts in the report
portal.report.improvement_prompts.min_impressionsinteger100Impressions a listing needs before prompts are shown
portal.report.improvement_prompts.uplift_min_cohortinteger20The fewest listings an uplift claim is computed from
portal.report.improvement_prompts.uplift_min_percentinteger10The smallest uplift worth quoting
portal.report.improvement_prompts.max_showninteger4The most prompts shown at once
portal.report.improvement_prompts.filter_min_searchesinteger50Searches the window must hold before a filter’s share is quoted as evidence
portal.report.improvement_prompts.rulesmapSee belowThe thresholds each prompt uses
portal.report.email_digest.enabledbooleantrueEmail members their monthly report
portal.report.email_digest.reportstringmember-monthlyThe report (from analytics/reports.yaml) the digest sends
portal.report.email_digest.skip_when_no_databooleantrueSend nothing for a period with no data

The default rules:

rules:
  accessibility: { required: true }
  booking_link: {}
  description_words: { min: 150 }
  opening_hours: { filter: open_now, required: true }
  photos: { min: 4, target: 8 }
  stale_after: 180d
  summary_words: { min: 40 }
  website: { required: true }
  zero_result_terms: { min_searches: 10, radius_km: 10 }

sites/<key>/portal.yaml

One site’s portal, over the install’s: its mode and path, the reference screens it hides, and its own screens and actions.

KeyTypeDefaultMeaning
modestringportal.modetemplated, api, both or off for this site
pathstringserver.portal_pathThe portal’s path on this site
template_dirstringportal.templated.template_dirThe portal template directory for this site
routesmap of stringsScreen paths for this site, by screen key
hidelist of strings[]Reference screens this site does not offer: contact_details, contact_team, enquiries, events, hours, listing_edit, membership, people, photos, promotions, report
screenslist[]The site’s own screens
screens[].keystringRequiredThe screen’s key. A reference screen’s key replaces that screen’s template and takes only template
screens[].idstringWritten for youIts stable id
screens[].pathstring/organisations/{org}/<key>Its path under the portal path, with {org}, {id} or neither
screens[].templatestring<key>.htmlIts template in the portal template directory
screens[].titlemap of stringsIts title per locale
screens[].navanyWhere it appears in the portal navigation
screens[].canstringscreen.<key>The partner permission it needs
screens[].tiersanyEvery tierThe tiers whose organisations see it: a list or { min: <tier> }
screens[].datamapDeclared data the screen reads, scoped to the partner’s organisation: each a name and a source (documents, document, published, report, enquiries, pending, people, membership, organisation, promotions, first_session) with its parameters
actionslist[]Forms the portal posts to, at <portal path>/actions/<key>
actions[].keystringRequired<subject>.<verb>, such as listing.update_offer
actions[].idstringWritten for youIts stable id
actions[].labelmap of stringsThe keyHow a screen lists it
actions[].targetanyRequiredWhat it writes: a document of the organisation, the organisation’s custom fields, or the signed-in person’s
actions[].fieldslist of stringsThe fields it may write
actions[].canstringaction.<key>The partner permission it needs
actions[].tiersanyEvery tierThe tiers whose organisations may use it
actions[].approvalstringFor a document target: tier (the tier’s member_editable rule decides) or required (every change waits for staff)
actions[].input, validation, steps, respond, rate_limitanyAs in an endpoint (see endpoints.yaml)

engine-dmo dev portal screen add and dev portal action add declare these with their ids. engine-dmo portal check checks the portal templates against the portal’s context, and portal scaffold copies the reference portal into the project to restyle.

portal/roles.yaml

Partner roles: what a person can do for an organisation in the portal. The built-in owner, manager, contact and billing may be restated with new grants.

KeyTypeDefaultMeaning
roles[].keystringRequiredThe role’s key; a built-in key restates that role
roles[].idstringWritten for youIts stable id
roles[].labelmap of stringsIts name per locale
roles[].canlist of stringsThe partner permissions it grants, including screen.<key> and action.<key> permissions the sites declare

engine-dmo dev role add declares one with its id.