Editor campaigns/Technical design

This document presents the technical design of the Editor campaigns project. The most significant development decision we've taken is to try to use domain-driven design. This approach is justified by the expectation that the domain will get more complex quickly. We've also created general facilities to encapsulate persistence.

Use cases and stories
Here's a use case diagram based on the user stories: Some additional possible use cases and stories, most involving more advanced functionality, are:
 * Campaign organizers, participants and others want to study and compare campaigns using a variety of metrics. They might:
 * Link data about campaigns to data from other sources, including Wikidata.
 * Find campaigns by the Wikidata categories or Geotags of the articles they work on.
 * Place a campaign's activities on a timeline together with events described in Wikidata. (For example: visualize edits by a project about the Ukraine alongside major events there.)
 * Create automatic text analysis of articles and link it to campaigns to compare their results. (Campaign results could be compared in terms of content persistence or the types of discourse on related Talk or Flow pages, for example.)
 * Describe campaign participant networks. See, for example, this study of Twitter networks.
 * Campaign organizers and participants want to organize their work in steps (i.e., as workflows) according to the requirements of a specific campaign or type of campaign, and link those workflows to UI elements.
 * Campaign organizers and participants want a variety UXs and data points for different types of campaign.
 * Users want flexible, productive, fun and easy-to-use tools for working and hanging out on Wikipedia in groups.

Architecture

 * Persistence
 * This layer is the only link between domain entities and a persistence store (i.e., a database, at least initially). It uses the store to persist, find and instantiate domain entities, following the data mapper pattern. This is the only layer that directly interacts with Mediawiki′s database classes. It doesn′t depend on anything Campaigns-specific, and could be included in Mediawiki core; see the related RFC (todo: add link).


 * Domain
 * This layer expresses core Editor Campaigns domain logic and provides a narrow interface for simple operations on campaigns and user participations. It depends only on the persistence layer. See below for more details.


 * Services (tentative)
 * We may find there are typical Campaigns actions that are more complex than the actions available via the domain layer and that involve additional Mediawiki components (like logging and page revisions). Such actions could be encapsulated in this layer, which would depend on the Campaigns domain layer and whatever Mediawiki components are involved. It seems likely that services would be created mainly for modifying Campaigns entities (in the spirit of CQRS).


 * UI (tentative) and Web API
 * Details of the UI and its internal structure remain to be worked out. So far, we've implemented a read-only Web API and opt-out controls on the Create account page. The UI and the Web API may depend on the domain and services layers. See below for more.


 * Components that build on Campaigns
 * Campaigns provides core functionality for using Mediawiki in groups. Further specialization for specific use cases (Education Program courses, projects, edit-a-thons, etc.) should be built in other components, which may depend on the Campaigns domain and services layers and, if they add data points, the generic persistence layer. It is unclear whether any sharing of UI functionality will be appropriate.

Domain-driven design
Domain-driven design involves building software around a model of what the software is “about” in the real world. That model goes in the domain layer. Two authors we've drawn on for ideas about this are Martin Fowler and Eric Evans.

According to Fowler, “With a Domain Model […] we build a model of our domain which, at least on a first approximation, is organized primarily around the nouns in the domain."

Here are some points Evans makes:
 * “The goal of domain-driven design is to create better software by focusing on a model of the domain rather than the technology.”
 * “In a model-driven design, the software constructs of the domain layer mirror the model concepts. It is not practical to achieve that correspondence when the domain logic is mixed with other concerns of the program. Isolating the domain implementation is a prerequisite for domain-driven design.”
 * “The domain objects, free of the responsibility of displaying themselves, storing themselves, managing application tasks, and so forth, can be focused on expressing the domain model. This allows a model to evolve to be rich enough and clear enough to capture essential business knowledge and put it to work.”
 * Domain-driven design makes a lot of sense when you expect a system to grow more complex.
 * The problem with not following this methodology is that as a system grows, “more and more domain rules become embedded in query code or simply lost.” In such cases “[W]e are no longer thinking about concepts in our domain model. Our code will not be communicating about the business; it will be manipulating the technology of data retrieval.”

Domain layer
The domain layer provides the following outward-facing PHP interface: ** Method not yet implemented.

UI (tentative)
(include here opt-in message as well as some ideas for future UI)