Files
MilkyShots/USE_CASES.md
REDCODE d799c3eb1f docs: clarify Curators and Admins can be maintainers for credited attribution
- Update Actors table: Curator and Admin entries mention maintainer assignment
- Update Role Design Philosophy: same clarification
- Update Curator section: note about PersonMaintainer as credit/attribution
- Update Admin section: same note
2026-07-15 17:40:49 +02:00

14 KiB

MilkyShots Use Cases

Target architecture for the new auth/permissions system. Replaces the current EAccessLevel (User/Curator/Admin) with 5 actors, Album.UserOwnerId is removed, Asset.OwnerIdUploadedBy (attribution only), and a Maintainer role bridges User ↔ Curator.


Actors

Actor Description Notes
Anonymous Unauthenticated visitor Can only see Public content (per #93 visibility levels)
User Registered, authenticated account Sees Public + Protected content
Maintainer Assigned to zero or more cosplayers Two-dimensional role: scoped cosplayer management (CRUD on albums/assets/profiles for assigned cosplayers only) plus unscoped tag management (create/edit any tag, assign tags anywhere, conditional delete). Sees Private content for assigned cosplayers. Cannot create people or view stats
Curator Full content editor Full CRUD on all people, albums, assets, tags. Can view stats. Cannot manage users/settings/folders/jobs. May also be assigned as a maintainer of specific cosplayers for credited attribution
Admin System administrator Everything Curator can do + user management, settings, folders, jobs. May also be assigned as a maintainer of specific cosplayers for credited attribution

Role Design Philosophy

The role hierarchy is strictly cumulative — each level inherits everything from the level below it.

Role What it adds Key constraint
Anonymous Browse public content Cannot see anything above Public visibility
User See Protected content, self-profile management Cannot mutate any content
Maintainer Two capabilities: (A) cosplayer-scoped curator powers (albums, assets, profiles for assigned cosplayers), (B) global tag management (create, edit, assign, conditional delete) Cannot create/delete people. Cosplayer management is gated by PersonMaintainer assignment. A Maintainer may have zero cosplayer assignments — in that case only tag management applies
Curator Unscoped content CRUD on people, albums, assets, tags; view stats Cannot manage users, settings, folders, or jobs. May be assigned as a maintainer of specific cosplayers (credited attribution, not access gating)
Admin User management, maintainer assignment, settings, folders, jobs No restrictions. May be assigned as a maintainer of specific cosplayers (credited attribution, not access gating)

Visibility & #93 Integration

Per #93, EVisibility has three tiers: Public, Protected, Private. The actor visibility rules are:

Actor Public Protected Private
Anonymous
User
Maintainer (unassigned)
Maintainer (assigned cosplayer)
Curator ✓ (non-deleted)
Admin ✓ (all)

Maintainer sees Private content only for cosplayers they're assigned to. For unassigned cosplayers they fall back to User-level visibility (Public + Protected).


Use Cases

Anonymous

ID Use Case Endpoint Visibility
UC-01 Browse albums GET /api/album Public only
UC-02 View album details with assets GET /api/album/{id} Public only
UC-03 Search albums by title GET /api/album?search= Public only
UC-04 Browse people (cosplayers) GET /api/person Public only
UC-05 View person detail with albums GET /api/person/{id} Public only
UC-06 Search people by name GET /api/person?search= Public only
UC-07 Browse assets GET /api/asset Public only
UC-08 View asset details GET /api/asset/{id} Public only
UC-09 Search assets by type/date/random GET /api/asset?type=&startDate=&endDate= Public only
UC-10 View media files (original/thumb/preview) GET /api/media/* Public only
UC-11 Browse tags GET /api/tag All
UC-12 View tag hierarchy (children/ancestors) GET /api/tag/{id} All
UC-13 Register a new account POST /api/auth/register
UC-14 Login POST /api/auth/login

User (all Anonymous +)

ID Use Case Endpoint Scope
UC-15 View protected albums GET /api/album (with auth) Public + Protected
UC-16 View protected album details GET /api/album/{id} (with auth) Public + Protected
UC-17 View protected assets GET /api/asset (with auth) Public + Protected
UC-18 View protected asset details GET /api/asset/{id} (with auth) Public + Protected
UC-19 View protected media files GET /api/media/* (with auth) Public + Protected
UC-20 View protected people with their albums GET /api/person/{id} (with auth) Public + Protected
UC-21 View own user profile GET /api/user/{id} Self
UC-22 Update own profile (username, email, password) POST /api/user/update Self
UC-23 Logout (invalidate refresh token) POST /api/auth/logout
UC-24 Refresh access token POST /api/auth/refresh

Protected = Visibility == Protected per #93. Private content requires assignment (Maintainer) or elevation (Curator+).


Maintainer (all User +)

Assigned to zero or more cosplayers (Person) via the PersonMaintainer table. Scoped powers: full CRUD on albums and assets for assigned cosplayers. Sees Private content for assigned cosplayers. Unscoped powers: create, edit, and assign tags to any content. Conditional tag deletion.

A Maintainer with no cosplayer assignments still retains full tag management capabilities.

ID Use Case Endpoint Scope
UC-25 Create album for assigned cosplayer PUT /api/album Assigned cosplayers only
UC-26 Update assigned cosplayer's albums POST /api/album/{id} Assigned cosplayers only
UC-27 Bulk update assigned albums POST /api/album Assigned cosplayers only
UC-28 Delete assigned cosplayer's albums DELETE /api/album/{id} Assigned cosplayers only
UC-29 Bulk delete assigned albums DELETE /api/album Assigned cosplayers only
UC-30 Update assigned cosplayer's profile POST /api/person/{id} Assigned cosplayers only
UC-31 Upload asset (attributed as uploader) PUT /api/asset Assigned cosplayers' albums
UC-32 Update asset metadata in assigned albums POST /api/asset/{id} Assigned cosplayers only
UC-33 Bulk update assets in assigned albums POST /api/asset Assigned cosplayers only
UC-34 Soft-delete asset in assigned albums DELETE /api/asset/{id} Assigned cosplayers only
UC-35 Bulk soft-delete assets in assigned albums DELETE /api/asset Assigned cosplayers only
UC-36 Create tag PUT /api/tag
UC-37 Assign/unassign tags to any content POST /api/album/{id} / POST /api/asset/{id} Unscoped (any content)

Maintainers cannot create people or view stats. They can create and edit any tag, and assign tags to any content. Tag deletion is allowed only if all content using that tag is maintained by them. Moving a Maintainer's last cosplayer assignment (or setting them to zero assignments) leaves them with only tag management powers.


Curator (all User + Maintainer +)

Full content management — no assignment boundaries. Note: Curators may also be assigned as maintainers of specific cosplayers via the PersonMaintainer table, serving as credited attribution (specifically credited to work on assets from that cosplayer). This does not gate their access — they already have full CRUD on all content — but signals a direct contributor relationship.

ID Use Case Endpoint
UC-38 Create cosplayer PUT /api/person
UC-39 Update any cosplayer POST /api/person/{id}
UC-40 Bulk update any cosplayer POST /api/person
UC-41 Delete any cosplayer DELETE /api/person/{id}
UC-42 Bulk delete cosplayers DELETE /api/person
UC-43 Create album (for any cosplayer) PUT /api/album
UC-44 Update any album POST /api/album/{id}
UC-45 Bulk update any albums POST /api/album
UC-46 Delete any album DELETE /api/album/{id}
UC-47 Bulk delete any albums DELETE /api/album
UC-48 Upload asset (for any cosplayer) PUT /api/asset
UC-49 Update any asset POST /api/asset/{id}
UC-50 Bulk update any assets POST /api/asset
UC-51 Soft-delete any asset DELETE /api/asset/{id}
UC-52 Bulk soft-delete any assets DELETE /api/asset
UC-53 Create tag PUT /api/tag
UC-54 Update tag POST /api/tag/{id}
UC-55 Bulk update tags POST /api/tag
UC-56 Delete tag DELETE /api/tag/{id}
UC-57 Bulk delete tags DELETE /api/tag
UC-58 View instance statistics GET /api/stats

Admin (all Curator +)

Admins may also be assigned as maintainers of specific cosplayers via the PersonMaintainer table, serving as credited attribution (specifically credited to work on assets from that cosplayer). Like Curators, this is a signalling mechanism rather than a gating one — Admins already have unrestricted access.

ID Use Case Endpoint
UC-59 List all users GET /api/user
UC-60 Create user with any role PUT /api/user
UC-61 Update any user (ban, role change, soft-delete) POST /api/user/update
UC-62 Soft-delete user DELETE /api/user/{id}
UC-63 Assign/revoke maintainer-to-cosplayer links TBD
UC-64 Manage application settings (CRUD + delete-all) GET/PUT/POST/DELETE /api/settings
UC-65 List tracked folders GET /api/folder
UC-66 Create folder PUT /api/folder
UC-67 Update folder POST /api/folder/{id}
UC-68 Get folder detail GET /api/folder/{id}
UC-69 Get random sample paths from folder GET /api/folder/{id}/sample-paths
UC-70 Delete folder DELETE /api/folder/{id}
UC-71 List active root jobs GET /api/jobs
UC-72 List past root jobs (paginated) GET /api/jobs/past
UC-73 Get job children (delta sync) GET /api/jobs/{parentId}/children
UC-74 Get job status by ID GET /api/jobs/{jobId}
UC-75 Cancel job DELETE /api/jobs/{jobId}
UC-76 Enqueue background job PUT /api/jobs
UC-77 View any content regardless of visibility/deletion All GET endpoints

Permission Matrix

Capability Anon User Maint Curator Admin
Browse/search public content
Register / Login
View protected content
Profile self-management
Edit assigned cosplayer's profile
CRUD albums for assigned cosplayer
Upload/update/delete assets (assigned)
Create cosplayers
Create tags
Assign tags to content ✓ (any) ✓ (any) ✓ (any)
Edit any tag
Delete tag ✓*
View statistics
Manage users (CRUD, roles, bans)
Assign maintainers to cosplayers
Settings / Folders / Jobs
View private content ✓ (assigned only) ✓ (any) ✓ (any)
View deleted content

* Maintainer can delete a tag only if all content using it is content they maintain.


DB Schema Changes

Change Detail
Album.UserOwnerId Remove — albums belong to cosplayer only (PersonOwnerId). Existing albums with no PersonOwnerId are orphaned until a Curator/Admin assigns them. The UI will show a list of all contributors (uploaders) to an album rather than a single owner
Asset.OwnerIdAsset.UploadedBy Rename — attribution only, no permission gating. Scanner-created assets (no uploading user) default to the admin account (first user) or a configurable system uploader stored in Settings
PersonMaintainer join table New M:N — PersonId, UserId. Cascade-deleted when the cosplayer is removed. If that was a maintainer's only assignment, they retain their tag management powers but lose cosplayer-scoped access
EAccessLevel enum Add Maintainer value. If preceded by the CurrentUser scoped service refactor: Anonymous=0, User=1, Maintainer=2, Curator=3, Admin=4. Otherwise: User=0, Maintainer=1, Curator=2, Admin=3. Migration must remap existing int values. Important: do not risk a privilege de-escalation — validate that at least one Admin exists post-migration
EVisibility enum New per #93 — Public / Protected / Private on Person, Album, Asset
System uploader setting New Setting entry — configurable user ID that scanner-created assets are attributed to. Defaults to the first-created (admin) user

API Conventions (TBD)

Decision Options Status
Maintainer assignment endpoint Reuse POST /api/user/update with a maintainerOf field, or dedicated endpoints Deferred to implementation
CurrentUser scoped service Replace inline authService.GetUserData(User) calls Separate issue
Controller refactoring Replace [Authorize(Roles)] with policy-based auth Separate follow-up

See also: #93 Visibility Levels, #94 Curation Mode, #79 Maintainer Role (superseded)