Private/restricted Projects (visibility scoped to selected members, not the whole Circle) #718
Replies: 3 comments 3 replies
|
Hi @raulanatol, that sounds good. Let me get back to you in the next couple of days about the open questions. Thank you for putting this together! |
|
The PRs for this are up:
I followed your answers: a private project forces all its tasks private and the task toggle is disabled with an "inherited from the project" hint, private stays private for admins too, and the flag propagates in both directions when it changes on the project. I left One thing I ran into while doing it: chores assigned to "Anyone" fan their reminders out to every circle member without checking visibility, so a private "Anyone" chore was sending its name to the whole circle. It was already reachable through the API, but private projects make it easy to hit from the UI, so I fixed it in the same PR. I also spotted two pre-existing gaps that affect private chores today and left them alone — no tombstone when a chore becomes private (stale copies on clients that already synced it), and |
|
Thanks heaps. There's a bit missing though for the self-hosted use case and you are not the only project to miss it. Think of a family using this for managing tasks with their children, especially when trying to reward their children for their hard efforts which this project supports so well. You'd ideally want:
Now I'll admit I haven't read the code hard, but the above suggests you would want a "can update" option. If "can view" already means that a user can mark a task done and add comments then I'm sorry to have wasted time mentioning something that is already implemented. I really like donetick and I'm trialling it with a couple of other similar projects. It means I've sometimes forgotten what one project can and cannot do currently. Like I said though, other projects have missed "can update" as well. |
Uh oh!
There was an error while loading. Please reload this page.
Feature Request: Private/restricted Projects (visibility scoped to selected members, not the whole Circle)
Problem
Right now, visibility in Donetick has two levels:
IsPrivateon a chore restricts visibility to the creator + assignees (Chore.CanView).There's no equivalent for Projects.
GetCircleProjectsreturns every project scoped to acircle_id, with no per-user filtering:This means any project — including one a user creates for themselves (e.g. a "Personal" project) — is visible to every other member of the circle. For households sharing a single circle (the common self-hosted use case), there's no way to keep a personal set of tasks organized under a project without every task also being manually marked
isPrivate.Proposed solution
Add the same visibility pattern that already exists for chores, one level up, at the project level:
Project:IsPrivate bool(defaultfalse, so existing projects stay visible — no behavior change on upgrade).project_members:project_id,user_id— the list of users allowed to see a private project, beyond its creator.Project.CanView(userID, circleUsers): mirrorsChore.CanView— if not private, anyone in the circle can see it; if private, only the creator and listed members can.chore.CanView(...) && (chore.Project == nil || chore.Project.CanView(...)). A chore's ownisPrivateflag and its project's privacy would both apply (whichever is stricter wins), so existing per-task privacy keeps working unchanged for chores with no project.is_private = falsefor all existing projects, same approach as20250825_set_existing_chores_private.godid for chores (but defaulting to public, to preserve current behavior).Frontend
The "Privacy Settings" UI already built for chores in
ChoreEdit.jsx(Public / Limited radio + assignee picker) is a close match for what a project's privacy control would need — same interaction pattern, different membership list (project members instead of chore assignees).Why this is a small change
The mechanism isn't new — it's an extension of the exact pattern
Chore.IsPrivate+Chore.CanViewalready implements and enforces at the SQL layer:The same shape of query would apply to
GetCircleProjects, plus a join-through when listing chores so a chore under a private project respects that project's membership.Backward compatibility
is_private = falseon the new column means zero behavior change for existing installs until someone opts in.DT_SINGLE_CIRCLE_INSTANCEor existing circle-level permission logic.Related discussions
This overlaps with the underlying problem raised in #594 "Managing multiple circles" and #448 "Multi-Circle Support" — both describe wanting to keep personal tasks separate from a shared household circle. Those threads lean toward solving it via multi-circle support (switching/viewing multiple circles per account), which is a bigger architectural change.
Project-level privacy wouldn't replace that — multi-circle support is still valuable for people who want fully separate spaces (different labels, different members, different notification channels). But it would cover a good chunk of the same need with much less surface area, reusing the exact mechanism Chore.IsPrivate already implements, for people who are fine sharing one circle but want to organize personal tasks under their own project without the rest of the household seeing them.
Open questions for maintainers
admin/managerroles bypass project-level restrictions (similar to how they can complete any public chore today), or should private projects be strictly opaque even to admins?project_membersvs. reusing a more generic ACL table if something similar is planned elsewhere.Happy to put together a PR for this if the approach sounds reasonable — wanted to check the design direction first per the contribution guidelines before writing code.
All reactions