The backend should take care of sending and accepting the mood images. As channel I use a simple email. The email should contain five links that reflect the current mood. I chose email because everybody has an e-mail account. Be it in a private or business environment. No one has to register for a new service or install software for it. I would like to use the following approach:
Hardly worth mentioning, so simple and so valuable! A special feature is the start event. It is a timer event with the following configuration:
With this configuration we tell the workflow engine to start a new instance every day.
The worker should do two things:
import { v4 } from "uuid";
import { Document } from "../types/Document.type";
import { Mood, MoodRequest } from "../types/Mood.type";
import { User } from "../types/User.type";
import { Error, ErrorType } from "../utils/Error";
import { StorageController } from "./storage.controller";
export class MoodController {
constructor(private store: StorageController) {}
public createRequest(user: User) {
const now = new Date().getTime();
const moodRequest: MoodRequest = {
uuid: v4(),
team: user.team,
ts: now,
expiration: now + 1000 * 60 * 60 * 12,
};
return moodRequest;
}
public async saveMoodRequest(moodRequest: MoodRequest) {
await this.store.set(Document.MOOD_REQUEST, moodRequest.uuid, moodRequest);
}
public async setMood(moodRequestId: string, moodValue: number) {
const moodRequest: MoodRequest = await this.store.get( Document.MOOD_REQUEST, moodRequestId );
if (!moodRequest) {
throw new Error(ErrorType.NotFound, `Mood not found`);
}
const now = new Date().getTime();
if (moodRequest.expiration < now) {
this.store.delete(Document.MOOD_REQUEST, moodRequestId);
throw new Error(ErrorType.BadRequest, `Request expired`);
}
const mood: Mood = {
uuid: moodRequest.uuid,
mood: moodValue,
team: moodRequest.team,
ts: now,
requestTs: moodRequest.ts,
};
await Promise.all([
this.store.delete(Document.MOOD_REQUEST, moodRequestId),
this.store.set(Document.MOOD, mood.uuid, mood),
]);
}
}
Via createRequest() a new record is created with a random Id and the associated team. Then the record is stored in a database.
The worker uses this controller to create the request. Afterwards the email is sent via an SMTP server. For the sake of simplicity, the name, the email address and the associated team are set as parameters.
The backend is very simple, it accepts the request, checks if there is already a result for the id and if not it is persisted:
const express = require("express");
import { NextFunction, Request, Response } from "express";
import { MoodController } from "../../controller/mood.controller";
import { StorageController } from "../../controller/storage.controller";
import { Error, ErrorType } from "../../utils/Error";
export class MoodRouter {
public router = express.Router({ mergeParams: true });
constructor(store: StorageController) {
this.router.post( "/:moodRequestId/:moodValue", async (req: Request, res: Response, next: NextFunction) => {
const moodRequestId: string = req.params.moodRequestId;
const moodValue: number = Number(req.params.moodValue);
try {
if (!moodRequestId || !moodValue) {
throw new Error( ErrorType.BadRequest, `Mandatory parameter missing` );
}
if (moodValue < 1 || moodValue > 5) {
throw new Error( ErrorType.BadRequest, `Mood ${moodValue} is not in range [1,5]` );
}
const moodController = new MoodController(store);
await moodController.setMood(moodRequestId, moodValue);
res.send();
} catch (error) {
next(error);
}
} );
}
}
Here I don’t want to go into too much detail, it’s just for routing the request ;)
Play With a few simple steps a service is created that can track your team’s mood. Since the orchestrating component is a process, you can of course add more steps, or customize the flow to send an email only on certain days. And now: relax! :)