// Require Services
const {Service, Entity} = require("electrodb");
const uuid = require("uuid").v4;
// Define a model for Employees
const EmployeesModel = {
model: {
entity: "employees",
version: "1",
service: "taskapp",
},
attributes: {
employee: {
type: "string",
default: () => uuid(),
},
firstName: {
type: "string",
required: true,
},
lastName: {
type: "string",
required: true,
},
office: {
type: "string",
required: true,
},
title: {
type: "string",
required: true,
},
team: {
type: ["development", "marketing", "finance", "product", "cool cats and kittens"],
required: true,
},
salary: {
type: "string",
required: true,
},
manager: {
type: "string",
},
dateHired: {
type: "string",
validate: /^\d{4}-\d{2}-\d{2}$/gi
},
birthday: {
type: "string",
validate: /^\d{4}-\d{2}-\d{2}$/gi
},
},
indexes: {
employee: {
pk: {
field: "pk",
facets: ["employee"],
},
sk: {
field: "sk",
facets: [],
},
},
coworkers: {
index: "gsi1pk-gsi1sk-index",
collection: "workplaces",
pk: {
field: "gsi1pk",
facets: ["office"],
},
sk: {
field: "gsi1sk",
facets: ["team", "title", "employee"],
},
},
teams: {
index: "gsi2pk-gsi2sk-index",
pk: {
field: "gsi2pk",
facets: ["team"],
},
sk: {
field: "gsi2sk",
facets: ["title", "salary", "employee"],
},
},
employeeLookup: {
collection: "assignments",
index: "gsi3pk-gsi3sk-index",
pk: {
field: "gsi3pk",
facets: ["employee"],
},
sk: {
field: "gsi3sk",
facets: [],
},
},
roles: {
index: "gsi4pk-gsi4sk-index",
pk: {
field: "gsi4pk",
facets: ["title"],
},
sk: {
field: "gsi4sk",
facets: ["salary", "employee"],
},
},
directReports: {
index: "gsi5pk-gsi5sk-index",
pk: {
field: "gsi5pk",
facets: ["manager"],
},
sk: {
field: "gsi5sk",
facets: ["team", "office", "employee"],
},
},
},
filters: {
upcomingCelebrations: (attributes, startDate, endDate) => {
let { dateHired, birthday } = attributes;
return `${dateHired.between(startDate, endDate)} OR ${birthday.between(
startDate,
endDate,
)}`;
},
},
};
// Define a model for Tasks
const TasksModel = {
model: {
entity: "tasks",
version: "1",
service: "taskapp",
},
attributes: {
task: {
type: "string",
default: () => uuid(),
},
project: {
type: "string",
},
employee: {
type: "string",
},
description: {
type: "string",
},
},
indexes: {
task: {
pk: {
field: "pk",
facets: ["task"],
},
sk: {
field: "sk",
facets: ["project", "employee"],
},
},
project: {
index: "gsi1pk-gsi1sk-index",
pk: {
field: "gsi1pk",
facets: ["project"],
},
sk: {
field: "gsi1sk",
facets: ["employee", "task"],
},
},
assigned: {
collection: "assignments",
index: "gsi3pk-gsi3sk-index",
pk: {
field: "gsi3pk",
facets: ["employee"],
},
sk: {
field: "gsi3sk",
facets: ["project", "task"],
},
},
},
};
/** SERVICES: FOR RELATIONSHIPS AND CROSS ENTITY QUERIES **/
// Create a new service called `taskapp`, join the Employee and Task models
let TaskApp = new Service("taskapp", {table: "projectmanagement"});
TaskApp
.join(EmployeesModel) // TaskApp.entities.employees
.join(TasksModel); // TaskApp.entities.tasks
// Query Across Entities
let assignment_params = TaskApp.collections.assignments({employee: "JExotic"}).params();
JSON.stringify(assignment_params, null, 2);
/** ENTITIES: FOR SIMPLE, SINGLE ENTITY USE CASES **/
// Alternatively you can also also create individual Entities if you don't need to use Collections or join additional models.
let Employees = new Entity(EmployeesModel, {table: "projectmanagement"});
// Query the specific Entity
let employee_params = Employees.query
.coworkers({ office: "Scranton Branch", team: "marketing" })
.where(({salary, title}, {between, contains}) => `
${between(salary, "120000", "140000")} AND ${contains(title, "junior")}
`)
.params();
JSON.stringify(employee_params, null, 2);