-
-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Assign users to tasks #2237
base: development
Are you sure you want to change the base?
Assign users to tasks #2237
Conversation
project_id INTEGER NOT NULL, | ||
task_id INTEGER NOT NULL, | ||
user_id INTEGER NOT NULL, | ||
assigned_at TIMESTAMPTZ NOT NULL DEFAULT now() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need a new table for this?
I thought we would just have an ASSIGN event in the task events table?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding new things to the database should always be a last resort
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we rely solely on the task_events table, we'd either have multiple event records per user (causing redundancy and data bloat) or a separate field for assignees that stores a list of user IDs resulting in slower querying and an empty column for non-assignment events.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point - we need to reference both the assigner (eg manager) and the assigned (mapper) in one event.
Instead, how about we add a field to the tasks table assigned_to
, then also make a task events entry.
The task event will have the user id for the assigner (plus a comment containing the username of who it was assigned to), while the assigned_to field will have the user id of the assigned.
Do you think that could be good?
(the task unlocking logic may have to be tweaked though to remove the assigned_to
value from the tasks table though)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are to assign multiple users to a task, the field we add to the tasks table would need to be a list of integers (since the table can only have one row for each task ID). We would need to append or extend to the assigned_to field, which would be a list of user IDs. This is not the best approach.
It would be better to store it in a new task assignments table for faster querying, simple insert and delete for assignments and referential integrity with foreign keys. The assignments would also be automatically deleted without any new query code if the user, project or task were to be deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fully agree - if we need to assign multiple users then this is the way to go π
Assigning multiple users doesn't really fit into our model though. A task can only be locked by one user. The credit for mapping a task will only go to one user. I thought we always discussed team mapping as an informal process, not recorded.
Anyway, if this was discussed in my absence and agreed on, I will defer to your judgement π
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some minor comments π
I'm still in two minds about this. Task assignment seems like something ephemeral to me - an event that occurs, but something that can be easily overwritten or chaged and not data that needs to be recorded in a separate table.
The requirement for multiple users to be assigned at once is a new one for me though - we haven't discussed this before - perhaps I missed it. With that in mind as the key criteria this could make sense (although the implication here is that perhaps we need to redesign how task locking and completion works).
So in summary, I kinda disagree with this approach, but don't want to hold up the process if this is needed π Go ahead and merge when you think this is ready!
-- Create task_assignments table only if it does not exist | ||
DO $$ | ||
BEGIN | ||
IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'task_assignments') THEN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a simpler syntax in postgres for this: create table if not exists task_assignments
Checking the information schema is only needed when this is not possible, such as with enums
@@ -467,6 +475,9 @@ ADD CONSTRAINT xlsforms_title_key UNIQUE (title); | |||
ALTER TABLE ONLY public.geometrylog | |||
ADD CONSTRAINT geometrylog_pkey PRIMARY KEY (id); | |||
|
|||
ALTER TABLE ONLY public.task_assignments | |||
ADD CONSTRAINT task_assignments_pkey PRIMARY KEY (task_id, user_id); | |||
|
|||
-- Indexing | |||
|
|||
CREATE INDEX idx_projects_outline ON public.projects USING gist (outline); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably need an index for faster lookup. Choosing the column depends what you will query on most frequently.
Oh by the way, I remembered what my original idea here was from months ago, as part of the event driven redesign (for reference).
I think this approach is simpler and avoids changing too much, but I'm sure it has downsides I have missed too (or forgot we discussed) |
Will there be a scenario where multiple users will be assigned to a single task? To whom do we assign tasks, mappers? Are assigning tasks and locking tasks the same? I think I am a bit out of context here. @spwoodcock @Anuj-Gupta4 |
|
Perhaps I made a mistake here when suggesting the ASSIGN event should automatically set the task state to LOCKED_FOR_MAPPING? As the assign event is by the manager, but we want the task locking to be done by the mapper. Should we possibly revert this and instead create two event entries as mentioned above? |
I am not sure there will be only one user/mapper assigned to a task. Some projects might need numbers of enumerators to do field surveys even for a single task (if the number of features within the task is huge), like a group of people assigned to a single task. In the case of Tokha, there are 4,5 people in a single task to do a survey. So, the concept of assigning tasks to users is to restrict users to not to select task that is not assigned to them? |
Yep basically! Task assignment is pretty arbitrary - it only serves two purposes:
Showing a task as assigned to multiple people might complicate the frontend. Could we consider assigning the task to only one user, but notifying multiple people? Its not perfect, but this kind of requirement suggests we need mapper teams that can be assigned to, not multiple individuals (still a 1 task to 1 mapper team assignment). We could look into that in the future. |
yeah we could do that. what if it restricts users who needs to do mapping on same task? |
I think we removed the restrictions in place previously - any user should be able to map regardless of who locked a task. Task locking should only be an indication / helper and not restrictive |
Okay, so we are just assigning users to let them know that it is assigned for you, just to notify? |
How about we use the task event table to assign only one user and lock the task but keep the task assignments table to keep track of all the mappers that are expected to map the task and were notified about it? There could be a small section in the frontend to show that (maybe only for the project manager) if needed. I think it's better to not implement any restrictions on the tasks as well. |
Yeah that could work π But what about if the task gets re-assigned to new people? How do we handle that? |
I would say let's implement bulk assign and bulk remove for a single task. In the frontend, there would be a list of users assigned to a task, and we would allow the project manager to select multi users and either add or remove them. There would be OSM message and email for both assign and remove as well. What do you think? |
We discussed on our team call today - decided to implement teams to keep a 1:1 assignment for tasks.
table structure: CREATE TABLE IF NOT EXISTS project_teams (
team_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
# team_name is optional - should we set a default here so it's more easy to display on the UI?
team_name VARCHAR,
project_id INTEGER NOT NULL,
user_id INTEGER NOT NULL
);
ALTER TABLE public.project_teams OWNER TO fmtm;
ALTER TABLE ONLY public.project_teams
ADD CONSTRAINT project_teams_pkey PRIMARY KEY (team_id);
ALTER TABLE ONLY public.project_teams
ADD CONSTRAINT fk_projects FOREIGN KEY (project_id) REFERENCES public.projects (id);
ALTER TABLE ONLY public.project_teams
ADD CONSTRAINT fk_users FOREIGN KEY (user_id) REFERENCES public.users (id);
# index by project as it's the most important for searching
CREATE INDEX idx_project_teams ON public.project_teams USING btree (project_id); Note This would also mean we need to modify task_events to accept a team_id instead of a user_id. Any thoughts on if we need extra fields? |
Won't this structure result in each team having only one user? Also, this table doesn't seem to be connected to tasks at all? Edit: never mind, just read the note |
You are right - we actually need two tables π |
Second try: CREATE TABLE IF NOT EXISTS project_teams (
team_id UUID DEFAULT gen_random_uuid(),
# team_name is optional - should we set a default here so it's more easy to display on the UI?
team_name VARCHAR,
project_id INTEGER NOT NULL
);
ALTER TABLE public.project_teams OWNER TO fmtm;
ALTER TABLE ONLY public.project_teams
ADD CONSTRAINT project_teams_pkey PRIMARY KEY (team_id);
ALTER TABLE ONLY public.project_teams
ADD CONSTRAINT fk_projects FOREIGN KEY (project_id) REFERENCES public.projects (id);
CREATE TABLE IF NOT EXISTS project_team_users (
team_id UUID PRIMARY KEY DEFAULT,
user_id INTEGER NOT NULL
);
ALTER TABLE public.project_team_users OWNER TO fmtm;
# composite
ALTER TABLE ONLY public.project_team_users
ADD CONSTRAINT project_teams_pkey PRIMARY KEY (team_id, user_id );
ALTER TABLE ONLY public.project_team_users
ADD CONSTRAINT fk_teams FOREIGN KEY (team_id) REFERENCES public.users (project_teams);
ALTER TABLE ONLY public.project_team_users
ADD CONSTRAINT fk_users FOREIGN KEY (user_id) REFERENCES public.users (id);
# index users by their team id, to allow for faster lookup when joining these tables
CREATE INDEX idx_project_team_users_team_id
ON public.project_team_users (team_id); Does this work? |
I think this should work. |
What type of PR is this? (check all applicable)
Related Issue
Checklist before requesting a review
[optional] What gif best describes this PR or how it makes you feel?