SocexSolutions / agenda-v2

A monorepo for a 3-tiered application built on the MERN stack and GCP designed to improve meeting efficiency.
https://www.meetingminder.dev
MIT License
7 stars 2 forks source link

Proposal: Groups, Tags, and Invites #318

Open thudsonbu opened 1 year ago

thudsonbu commented 1 year ago

Context

In many applications a system of tags or labels is used as an easy way for user's to organize content. I think that a similar system should be present in agenda. User's should be able to create tags with arbitrary names and colors and attach them to various objects like meetings, topics, takeaways and the like.

Implementation

Summary

While tags are a simple idea, the implementation is not so, primarily due to issues of scope. When user's are in a meeting together they should be able to see the same tags suggested as others in the meeting and user's should only be able to see tags that are in some way related to them.

To solve this scoping/namespacing problem I propose we use a new groups collection. Tags and users will be related to a group, thus users within a group can share tags. Groups can also be parts of other groups (acting as a subset) and they can also have sub groups within them (acting as a superset).

Group Data Model

const groupSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  owner_ids: {
    type: [ Schema.Types.ObjectId ],
    ref: 'User',
    required: true
  },
  parent_groups: {
    type: [ Schema.Types.ObjectId ],
    ref: 'Group'
  },
  child_groups: {
    type: [ Schema.Types.ObjectId ],
    ref: 'Group'
  }
});

I don't think we need very much else for an initial version. User's will then have a groups array on their schema referencing groups that they are a part of.

With the groups collection in place, user's will need a way to create and join groups. This will require a new item on the profile menu called groups. This will open a modal or page where they can create a new group, join a group, or leave a group if they have received an invite. invites will be a second collection necessary for the implementation of groups.

Invite Data Model

const invite = new mongoose.Schema({
  owner_id: {
    type: Schema.Types.ObjectId,
    ref: 'User',
    required: true
  },
  invitee: {
    type: Schema.Types.ObjectId,
    ref: 'User',
    required: true
  },
  status: {
    type: String,
    enum: [ 'open', 'accepted', 'rejected', 'canceled' ],
    required: true,
    default: false
  },
  subject_type: {
    type: String,
    enum: [ 'Meeting', 'Group' ],
    required: true,
  }
});

From the new groups page/modal, users will be able to accept and reject invites.

With the invites and groups infrastructure in place, tags can finally be added.

Tags Data Model

const tag = new mongoose.Schema({
  group_id: {
    type: Schema.Types.ObjectId,
    ref: 'User',
    required: true
  },
  name: {
    type: String,
    required: true
  },
  color: {
    type: String,
    enum: [ 'red', 'orange', 'yellow', ... ],
    default: [ 'black' ],
  }
};

Tags are related to a single group and have no owner. Tags will be able to be created and edited with a small popup in the meeting. Deleting tags could be done from the organization page but I am not sure we need that functionality. Tags will be referenced from meetings and topics using an array of tag ids.

zbarnz commented 1 year ago

I like it but I dont really understand the parent and child groups thing. Why would groups be a part of other groups? Wouldnt it be better to have two different models?

thudsonbu commented 1 year ago

@zbarnz The parent child relationships will allow parent groups to reference their child groups tags so an engineering meeting can reference all of the engineering tags and tags on different engineering teams. Taking if further The companies group could reference tags from all of engineering which references all of the engineering teams specific tags. That might be excessive though.

What were you thinking about doing with two models?