npm package: @manuscripts/manuscripts-sync
Description: Sync function for Couchbase Sync Gateway
Latest version: 1.1.4

# manuscripts-sync

This repository provides a Dockerfile for a copy of Couchbase Sync Gateway configured for Manuscripts backend purposes, as well as an NPM published package which is baked into the Sync Gateway configuration.

- The copy of Sync Gateway used a minor fork that [allows for session cookies for multiple domains](https://github.com/couchbase/sync_gateway/pull/3820).
- It is built with a Manuscripts specific [sync function](https://docs.couchbase.com/sync-gateway/2.1/sync-function-api.html) that includes Manuscripts specific access control rules and a 0-dependency JSON schema validator for the [Manuscripts JSON schema](https://gitlab.com/mpapp-public/manuscripts-json-schema#readme).

## Module usage

```typescript
import { Project } from '@manuscripts/manuscripts-sync'

const p: Project = {
  _id: 'MPProject:id',
  owners: ['User_Foo'],
  writers: [],
  viewers: [],
  objectType: 'MPProject',
}
```

```javascript
const { syncFn } = require('@manuscripts/manuscripts-sync')

console.log(syncFn)
```

## Building the Sync Gateway configuration file

To build the Sync Gateway configuration file at `./docker/sync_gateway/sync-gateway-config.json` with the values present in `.env`, do the following:

```bash
env $(cat .env | xargs) npx gulp
```

The environment variables in .env are defaults, and none of them at least at the time of writing are treated as build arguments in the Dockerfiles present in this repo.

## Dockerfiles

This repository contains a CI build configuration which keeps the following two GitLab Docker registry published images up to date:

- registry.gitlab.com/mpapp-private/manuscripts-sync/sync_gateway
- registry.gitlab.com/mpapp-private/manuscripts-sync/couchbase

Both of these images are tagged with the value of the "version" field present in the package.json.

The images are published to the registry upon tagging commits (or with manual CD pipeline `"prepare_images_manual"` button pressing action).

## Building Sync Gateway for local development

To develop [manuscripts-api](https://gitlab.com/mpapp-private/manuscripts-api) against a locally built manuscripts-sync flavoured Sync Gateway, do the following:

0. Create a [GitLab account](https://gitlab.com) if you don't already have one.
1. `docker login registry.gitlab.com` with your GitLab credentials.
2. `IMAGE_NAME=your-sg-image-name ./docker/build-image.sh`.
3. Follow the local development steps for [manuscripts-frontend](https://gitlab.com/mpapp-public/manuscripts-frontend#running-the-backend-api-in-docker), except before launching the services, modify `docker-compose.yml` to set the image name so that it matches the `$IMAGE_NAME` you used above.

```yaml
  sync_gateway:
    image: your-sg-image-name
    …
```

If you want to make local changes to manuscripts-sync JavaScript code (such as `manuscripts-sync-fn.js`) or _manuscripts-json-schema_, pass `COPY_LOCAL_PACKAGES=true` to the `./docker/build-image.sh` script, like so:

```
COPY_LOCAL_PACKAGES=true IMAGE_NAME=your-sg-image-name ./docker/build-image.sh
```

### Local changes to manuscripts-json-schema

To build the image with steps described above with a locally changed manuscripts-json-schema, use `npm link` and a local copy of manuscripts-json-schema, for example if your working copy of the schema repository is next to your _manuscripts-sync_ repository on your disk, do the following to link it:

```bash
npm link ../manuscripts-json-schema/
```

The `build-image.sh` script will deal with an `npm link`ed copy of _manuscripts-json-schema_ similarly to one that is referenced and fetched by NPM via the `package.json` reference, allowing you to work with unpublished versions of the schema.

## Creating a release

To create a release, do the following:

1. Decide to make a release: is the correct schema version referenced? are tests in good order? have you tested compatibility with manuscripts-api?
2. Update version in package.json, commit and push it.
3. [Create a new tag](https://gitlab.com/mpapp-public/manuscripts-sync/-/tags/new), and enter a brief description and release notes.
4. [Watch](https://gitlab.com/mpapp-public/manuscripts-sync/pipelines) as the CI tasks for NPM package and Docker image publishing complete.
5. Celebrate 🎉

## Channels contents and description

##### The following are data bucket channels:

- `{userID}-projects` =>
  - contains:
    - `MPProject` with one of owners/writers/viewers = {userID}.
  - description:
    - contains any project in which the user with {userID} is a collaborator.
    - access granted to the user with id = {userID}.
- `{userID}-libraries` =>
  - contains:
    - `MPLibrary` with one of owners/writers/viewers = {userID}.
  - description:
    - contains any library in which the user with {userID} is a collaborator.
    - access granted to the user with id = {userID}.
- `{userID}-library-collections` =>
  - contains:
    - `MPLibraryCollection` with one of owners/writers/viewers = {userID}.
  - description:
    - contains any library collection in which the user with {userID} is a collaborator.
    - access granted to the user with id = {userID}.
- `{containerID}-read` =>
  - contains:
    - `MPProject` with \_id = {containerID}.
    - `MPLibrary` with \_id = {containerID}.
    - `MPLibraryCollection` with \_id = {containerID}.
    - `MPContainerInvitations` with containerID = {containerID}.
    - any other objects with containerID = {containerID}.
  - description:
    - contains all the objects related to a container with id {containerID}, including the container itself.
    - access granted to any container collaborator.
- `{containerID}-readwrite` =>
  - contains:
    - `MPProject` with \_id = {containerID}.
    - `MPLibrary` with \_id = {containerID}.
    - `MPLibraryCollection` with \_id = {containerID}.
    - `MPContainerInvitations` with containerID = {containerID}.
    - any other objects with containerID = {containerID}.
  - description:
    - contains all the objects related to a container with id {containerID}, including the container itself.
    - access granted to any container owners and writers.
- `{userID}-read` =>
  - contains:
    - `MPUserProfile` with userID = {userID}.
  - description:
    - contains the profile of the user with {userID}.
    - access granted to the user with id = {userID}.
- `{userID}-readwrite` =>
  - contains:
    - `MPUserProfile` with userID = {userID}.
  - description:
    - contains the profile of the user with {userID}.
    - access granted to the user with id = {userID}.
- `{userID}` =>
  - contains:
    - `MPCollaboration` with invitingUserID = {userID} or `User_` + invitedUserEmail = {userID}.
    - `MPInvitation` with invitingUserID = {userID} or `User_` + invitedUserEmail = {userID}.
    - `MPContainerInvitation` with invitingUserID = {userID} or `User_` + invitedUserEmail = {userID}.
  - description:
    - contains all collaborations, invitations and container invitations which are send by the user or to the user.
    - access granted to the user with id = {userID}.
- `{containerID}-owner` =>
  - contains:
    - `MPContainerRequest` with containerID = {containerID}.
  - description:
    - contains all the objects which are only accessible to the owner of a container with {containerID}.
    - access granted to any container owners.
- `{preferenceID}` without `MPPreferences:` prefix =>
  - contains:
    - `MPPreference` with \_id = `{preferenceID}`
  - description: ?
- `{userID}-citation-alerts` =>
  - contains:
    - `MPMutedCitationAlert` with userID = {userID}.
    - `MPCitationAlert` with userID = {userID}.
  - description:
    - contains all citation alert objects.
    - access granted to the user with id = {userID}.
- `{containerID}-bibitems` =>
  - contains:
    - `MPBibliographyItem` with containerID = {containerID}.
  - description:
    - contains all the bibliography items for the container with containerID = {containerID}.
    - access granted to any container collaborator.
- `{keywordID}-read` =>
  - contains:
    - `MPBibliographyItem` with one of keywordIDs = {keywordID}.
  - description: ?
- `{keywordID}-readwrite` =>
  - contains:
    - `MPBibliographyItem` with one of keywordIDs = {keywordID}.
  - description: ?
- `{userID}-templates` =>
  - contains:
    - `MPProject` with one of owners/writers/viewers = {userID} and templateContainer = true.
  - description:
    - contains projects that contain published MPManuscriptTemplate objects.
    - access granted to the user with id = {userID}.

##### The following are derived data bucket channels:

- `{userID}-collaborators` =>
  - contains:
    - `MPUserCollaborator` with userID = {userID}.
  - description:
    - contains all user collaborators for the user with userID = {userID}.
    - access granted to user with id = {userID}.
- `{userID}-project-mementos` =>
  - contains:
    - `MPProjectMemento` with userID = {userID}.
  - description:
    - contains all project mementos for the user with userID = {userID}.
    - access granted to user with id = {userID}.
- `{containerID}-summaries` =>
  - contains:
    - `MPProjectSummary` with containerID = {containerID}.
    - `MPLibrarySummary` with containerID = {containerID}.
    - `MPLibraryCollectionSummary` with containerID = {containerID}.
  - description:
    - contains a container summary with containerID = {containerID}.
    - access granted to any container collaborator.