Core Services vs. Customizations
We differentiate between core services that we view as critical to the success of any community and services that customize the platform for specialized use cases. Our core services are:
Theming. This includes the visual styling of existing functionality and pages to reflect the use cases, tone, and branding requirements of each customer. It includes device & browser compatibility and the use of existing modules leveraging data and options that already exist within the product. This process typically starts with receiving mockups. Working closely with the theming team helps ensure success and will allow us to advise you if new features are accidentally included in mockups, which would fall outside the scope of core services.
Migrations. We view preserving community data as critically important. We offer data migration services from any platform that allows structured data access via either exports or API. Our extensive tooling allows for cost-effective transformations of data from a large number of sources and we are always willing to build new tools as required to meet your needs.
Single Sign On integrations. Community ownership starts with owning the user experience across platforms. We offer “out-of-box” solutions for OAuth2 and SAML-based SSO, and via core services we offer modified solutions based on these standards for specialized compatibility needs. For customers without an existing SSO solution, we offer an in-house solution that offloads most of the “heavy lifting” to our side of the connection and simplifies setup. However, it still requires a developer to be available to you for setup.
We strive to make these services available at-cost to our customers to ensure a successful onboarding experience, a timely launch, and effective ongoing updates to branding and technical needs.
We never provide services that involve direct access to your servers, databases, or hosting controls. This includes the export of data from your internal databases or configuring the Identity Provider side of an SSO connection.
How We Provide Services
There are 3 models for developing core services and customizations.
- Full Professional Services: We build and maintain a deliverable on your behalf as if it were part of our product. We strongly recommend this option for all customizations, and especially for customers without internal development teams that can easily be brought onto community projects.
- Guided Self-Development: Scope of work is limited to theming with our existing feature set unless explicitly approved otherwise on a per-case basis. We provide guidance on development, but you take ownership of the work and maintenance. Our SLA does not apply. Developer contacts must be part of your internal teams, not third-party contractors.
- Hybrid: The most common hybrid model is that we provide an initial service (most frequently a theme) and then you provide ongoing maintenance and updates. This leverages our experience to ensure a timely launch and low maintenance costs, while providing ongoing flexibility without internal budgeting constraints.
We currently have customers using all 3 of these models successfully. Having a serious conversation with your Customer Success Manager about which is most appropriate for your situation is the best way to guarantee success. We have a great deal of experience building successful communities and managing their technical requirements.
Your project manager may provide a more nuanced process. This broadly covers all types of services under all models in a nutshell:
- You present requirements that include your high-level goals.
- Both parties negotiate acceptance criteria based on goals.
- We determine whether this is core services work or a customization.
- We must approve customizations before they proceed past this point.
- We produce a formal estimate.
- Self-Guided Development process forks here (see below).
- You sign a Statement of Work.
- We schedule the work and complete it via developer sprints.
- The deliverable is presented for your review.
- We address feedback per the terms of the SOW and estimate.
- We schedule and complete deployment.
Self-Guided Development follows a different process after 4a. Instead, it continues with code review and self-deployment. The section below titled Self-Development Guidance covers this process and its challenges in greater detail.
Our Product Goals
We want to enable full platform transparency via our API and webhooks that allow customers to remotely program any desired functionality through secure, testable, and maintainable endpoints. While we have made great strides in that direction, we recognize there are incomplete areas of our API and we do not yet support native webhooks. Wherever possible, we will enable the development of custom webhooks that adhere to our requirements until such time as we offer a full range of native ones.
Appropriate Customer Goals
The purpose of customizations (non-core services) are to more closely tailor our platform to your business and community needs. Typically this includes small gaps in desired functionality like storing an extra piece of data, displaying additional context, or adding an option. They may include syncing or connecting data to third-party services.
Customizations are not for creating complex native features, creating custom workflows within the product (excepting light integrations with third-party services), substantively changing how the platform works, or generally conducting self-directed software development on our cloud infrastructure.
Our Priorities for Customizations
The most valuable service we provide is a stable, secure, fast, and steadily improving experience for your users who want to interact with your community. Therefore, we have a number of criteria and requirements for customizations so that they do not compromise those priorities.
Self-development necessarily includes a number of legal, process, and technical safeguards.
- We can only collaborate on code through the official client repo that is under our organization on GitHub.
- Code changes submitted by the client for review must be via pull request.
- Limit 6 collaborators per customer.
- We cannot release or share the source code for cloud-only features for any reason.
- Clients may not create new addons without approval of their scope and methodology (i.e. following the process outlined in this document).
- We may impose any limitations we think are necessary to insure security & performance, and minimize maintenance problems.
- We will veto feature changes or additions that conflict with our roadmap.
- Our coding standards must be used in the shared repo.
- We are not responsible for downtime caused by client-initiated deploys regardless of SLAs in place.
- We retain ownership of all code authored by our staff. You grant us non-revocable, unrestricted license to use code added to the shared repository (this is covered in the legal agreement).
Local development environments can be very challenging to setup and maintain. This is compounded when dealing with a product that has both open source and closed source components. Keep in mind:
- While most of our code is open source, some key components like Subcommunities and Groups are not. We cannot provide these assets.
- We offer a Mac-based Docker container (open source). Unfortunately this is the only platform we maintain at this time, and it is development only (we do not use it in production).
- We strongly recommend developing with memcached enabled.
- We offer a cloud-hosted development environment (additional cost may apply) for testing code. It is for functionality testing, not performance evaluation.
- While we do have public documentation related to hosting and local environment setup and are generally happy to answer specific questions, we do not provide general support for local setups.
Minimum Technical Requirements
This represents the bare minimum of what is necessary to pass a code review. It is a combination of common pitfalls, particular technical limitations in our platform, and general best practices. We may impose additional requirements at our discretion to fit particular situations. It is imperative you communicate with us early and often.
- Do not create new database tables. Avoid creating new database columns.
- Do not write SQL queries without using our structured query builder. Avoid creating any new database queries whatsoever wherever possible. Instead, use existing methods on existing models.
- If data is expected to be queried on most page loads, it must be cached using memcached with a reasonable TTL.
- Due to platform limitations, do not exceed:
- 100 records retrieved in one query;
- an offset of more than 10,000 records (e.g. pagination);
- notifying more than 100 users via email at once;
- 2,000 categories total without using Flat Categories.
- ANY additional queries (or direct invocations of queries, i.e. not via existing model methods) must be accompanied (in the pull request description) by an estimate of how often those queries are expected to run, and specifically itemizing what work has been done to mitigate database impact (e.g. caching strategy; index use; and/or limiting contexts in which the query is invoked).
- User-generated content (UGC) must always be escaped (e.g. using `htmlspecialchars()`) or purified (using HTMLawed, a core dependency available in our platform). UGC includes things like usernames, email addresses, comments, discussion titles, and any custom data you create.
- Do not exceed 1 outbound request per inbound request (i.e. batch outbound API calls and cache their responses appropriately; do not fire multiple webhooks per action).
- Enforce dependencies on other addons via the addon.json. Use class detection to ensure code from other addons exists before calling it (e.g. before calling a Pocket, ensure the Pockets addon is available).
- Do not fork our addons or other assets. (Limitations typically exists for reasons).
- All customizations MUST be described in your repo's CUSTOMIZATIONS.md.
- All plugins and themes MUST get their own subfolders under the appropriate folder (named ‘plugins’ and ‘themes’).
- The ‘media’ folder is for storing assets and images. It may not be used in production (or staging), therefore do not link to assets in it from your theme.
Code that violates any of these principles will be immediately rejected. If you are unclear how you can fulfill your goals without violating one or more principles, that is a good indication it’s time for a developer call scheduled via your Customer Success Manager.
Code reviews are often time-sensitive. Turnaround time hinges almost entirely on good communication (maximized) and overall complexity (minimized). Use the following guidelines to achieve this.
- Write a good PR description that explains what is being achieved and why. Do not assume your reviewer is familiar with your entire project.
- Link to related issues. (Filing issues before coding is a great practice.)
- Include a README file for new addons that includes scope, requirements, testing criteria, and summarizes major interactions.
- Use generous inline documentation. We do not believe in “self-documenting code” when multiple team cultures are involved.
- Use a “WIP” (work in progress) label if a PR is not ready for review, and remove it when it is.
- Notify your project manager of new PRs promptly via agreed channels.
- Limit 1 deliverable, feature, or change per pull request.
- Make the initial PR for a new addon as small as possible. Aim for an “MVP” version to make sure we’re on the same page before progressing.
- Do not continue adding code after requesting review (unless addressing specific feedback or fixing typos).
- Write small functions/methods. If you can’t document a method easily, it’s probably too complicated.
- Follow our guidance and don’t get clever with our framework. Use existing code as reference whenever possible.
- Consider resiliency and whether failure of your component could take down a critical path (e.g. user sign in or posting). Domino effects complicate troubleshooting.
- Don’t modify deploy.json in the same PR as other changes.
We will generally provide two kinds of feedback: suggestions and required changes. If you are unclear which type of feedback a comment qualifies as, please ask for clarification immediately. The back-and-forth process of reviews is the biggest challenge of completing them in a timely way.
Using Enterprise Self-Deploy
Guidelines & Warnings
Self-Deploy is primarily intended for theme updates and minor, iterative changes that do not require code review. It is not a DIY feature release mechanism.
Use caution when deploying new code.
- Fatal errors in your code can and will take your site down.
- If your site is down, you cannot self-deploy again and must contact support.
- There is no “undo” button. You need to rollback your code state via git and redeploy.
New addons (including themes) must be connected and deployed by our staff before they become initially available.
Beware of process complexity that arises when multiple services are in progress at the same time. By default, we use `master` branch in production and `stage` branch for staging. This assumes a waterfall-esque approach: Changes are merged to `stage` individually via PR, and then ALL pending changes are deployed to production at once (by merging `stage` into `master`).
This typically works well for a launch process where all services are completed prior to launch. However, it can quickly become a problem when multiple services must be reviewed and deployed under different, overlapping timelines. Code becomes trapped on stage if other features on stage aren’t ready for release.
The deploy.json file in the root of your repo defines which branches will be deployed to which sites. You can use this to enable a release-based branching strategy. If you need help organizing this, contact your Customer Success Manager.