Phase 3 Readiness — Resource Sharing Tasks (0a–9) — Actionable Plan (2025-10-06) #103
Labels
No labels
Epic 5
MCP
P1
PR-0
PR-1
api
api-layer
architecture
area:backend
area:frontend
arrow
authentication
backend
bug
chat
client
clipboard
common-module
compose
cross-cutting
cross-cutting-requirement
data-layer
data-models
database
desktop-client
documentation
duplicate
enhancement
epic
epic-1
epic-2
epic-3
epic-4
epic-5
epic-6
epic-7
epic-llm-config
error-handling
feature
frontend
good first issue
help wanted
implementation
infrastructure
installer
invalid
kotlin
ktor
llm
medium-priority
message
multiplatform
needs-review
needs-triage
packaging
performance
phase-1
phase-2
phase-3
phase-4
phase-5
phase3
phase:3
priority: high
question
refactor
refactoring
resource-sharing
security
server
server-module
services
session
session-management
settings
setup
shutdown
state
storage
streaming
sub-issue
tests
tooling
type:task
ui
ui/ux
user-accounts
user-management
ux
viewmodel
websocket
windows
windows-integration
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Torvian.eu/chatbot#103
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 3 Readiness — Resource Sharing Tasks (0a–9)
Reference:
temp/Phase 3 Readiness Report.md(2025-10-06)Checklist
AccessModeto inline value class (BLOCKING)access_modecolumn to access tables (CRITICAL)Executive summary
Phases 1 and 2 are complete. Phase 3 (Resource Sharing) is ready to start but several critical issues must be addressed first. This issue contains the actionable Task list 0a–9 extracted from the Phase 3 Readiness Report. Each task is in its own section with action items, affected files/symbols, acceptance criteria, priority and time estimate.
Task 0a — Backend: Refactor
AccessModeto inline value class (BLOCKING)Summary: Replace the rigid
AccessModeenum with a type-safe inline value class that wraps aString, expose common modes in the companion object (e.g.AccessMode.READ,AccessMode.WRITE).Action items:
AccessModeinline value class in common module.ResourceAuthorizerinterface to acceptAccessMode.AuthorizationServiceinterface &AuthorizationServiceImplto useAccessMode.SessionResourceAuthorizerandGroupResourceAuthorizerto accept/useAccessMode.AccessMode.READ/AccessMode.WRITEwhere applicable.AccessModeusage and ensure compile-time updates.AccessModeenum or provide a small adapter for migration/tests.Affected files/symbols (examples):
common/src/commonMain/kotlin/eu/torvian/chatbot/common/api/AccessMode.kt(new)server/.../service/security/authorizer/AccessMode.kt(delete/adapter)ResourceAuthorizer.kt,AuthorizationService.kt,AuthorizationServiceImpl.ktSessionResourceAuthorizer.kt,GroupResourceAuthorizer.ktAccessMode(e.g.configureGroupRoutes.kt,configureSessionRoutes.kt,configureMessageRoutes.kt)Acceptance criteria:
AccessModeexists in common module withREAD/WRITEconstants.Priority / Est.: ⚠️ BLOCKING — 2–3 days
Task 0b — Backend: Add
access_modecolumn to access tables (CRITICAL)Summary: Access tables currently track only which groups have access. Add an
access_modevarchar column and include it in the composite primary key so multiple access modes per group/resource are possible.Action items:
LLMProviderAccessTableto addaccess_modevarchar(50) and include it in the primary key.LLMModelAccessTablesimilarly.ModelSettingsAccessTablesimilarly.Affected files:
server/src/main/kotlin/eu/torvian/chatbot/server/data/tables/LLMProviderAccessTable.ktserver/src/main/kotlin/eu/torvian/chatbot/server/data/tables/LLMModelAccessTable.ktserver/src/main/kotlin/eu/torvian/chatbot/server/data/tables/ModelSettingsAccessTable.ktAcceptance criteria:
access_modeon all three tables and composite PK includes it.access_mode.Priority / Est.: ⚠️ CRITICAL — 1–2 days
Task 1 — Backend: Add authentication to provider/model/settings routes (HIGH PRIORITY)
Summary: Several route modules are currently unauthenticated and must be protected.
Action items:
configureProviderRoutes.ktroutes inauthenticate(AuthSchemes.USER_JWT) { ... }.configureModelRoutes.ktroutes inauthenticate(AuthSchemes.USER_JWT) { ... }.configureSettingsRoutes.ktroutes inauthenticate(AuthSchemes.USER_JWT) { ... }.Affected files:
server/src/.../routes/configureProviderRoutes.ktserver/src/.../routes/configureModelRoutes.ktserver/src/.../routes/configureSettingsRoutes.ktAcceptance criteria:
Priority / Est.: ⚠️ HIGH — 1 day
Task 2 — Backend: Implement "All Users" group
Summary: Provide a built-in "All Users" group to represent public resources; auto-assign new users to it; protect it from deletion/removal.
Action items:
InitialSetupServiceto create the "All Users" group on setup and store its ID as a constant/config.UserService.registerUser()to auto-assign new users to "All Users" group.Affected files:
InitialSetupService(server)UserService/UserService.registerUser()UserGroupsrelated DAO/servicesAcceptance criteria:
Priority / Est.: 2 days
Task 3 — Backend: Create resource ownership & access DAOs
Summary: Implement ownership DAOs and access DAOs for providers, models, and settings so authorizers can check owners and group-based access (including access mode).
Action items:
ProviderOwnershipDao,ModelOwnershipDao,SettingsOwnershipDaowith:getOwner(resourceId): Either<GetOwnerError, Long>setOwner(resourceId, userId): Either<SetOwnerError, Unit>deleteOwner(resourceId): Either<DeleteOwnerError, Unit>ProviderAccessDao,ModelAccessDao,SettingsAccessDaowith:getAccessGroups(resourceId, accessMode: String): List<UserGroup>hasAccess(resourceId, groupIds: List<Long>, accessMode: String): BooleangrantAccess(resourceId, groupId, accessMode: String): Either<GrantAccessError, Unit>revokeAccess(resourceId, groupId, accessMode: String): Either<RevokeAccessError, Unit>getResourcesAccessibleByGroups(groupIds: List<Long>, accessMode: String): List<Long>Affected files / packages: new DAO files under
server/src/main/kotlin/.../dao(or existing DAO package).Acceptance criteria:
hasAccessrespects theaccess_modevalues stored in DB.Priority / Est.: 3–4 days
Task 4 — Backend: Create resource authorizers
Summary: Implement
ProviderResourceAuthorizer,ModelResourceAuthorizer,SettingsResourceAuthorizerfollowing theResourceAuthorizerpattern (useAccessModevalue class).Action items:
ProviderResourceAuthorizerthat:ProviderAccessDao.hasAccess(...)with the requestedAccessModeModelResourceAuthorizerandSettingsResourceAuthorizersimilarly.Example method signature:
suspend fun requireAccess(userId: Long, resourceId: Long, accessMode: AccessMode): Either<ResourceAuthorizerError, Unit>Affected files:
*ResourceAuthorizer.ktfiles under service/security/authorizerAcceptance criteria:
AuthorizationService.requireAccess().Priority / Est.: 2–3 days
Task 5 — Backend: Add authorization to routes (route-layer enforcement)
Summary: Add
requireAccess()route-layer checks for write operations and keep authorization at route layer (do not add userId to service methods).Action items:
configureProviderRoutes.kt:requireAccess()checks for write operations (create/update/delete).requirePermission()for admin-only actions.configureModelRoutes.ktsimilarly.configureSettingsRoutes.ktsimilarly.Affected files:
configureProviderRoutes.kt,configureModelRoutes.kt,configureSettingsRoutes.ktAcceptance criteria:
AccessMode.Priority / Est.: 2–3 days
Task 6 — Backend: Update services for resource sharing
Summary: Make service-layer methods that return lists filter by user access (ownership + group access) while keeping authorization checks in routes for write operations.
Action items:
LLMProviderService.getAllProviders()to acceptuserId(or provide a filtering hook) and return only resources accessible to that user.LLMModelService.getAllModels()similarly.ModelSettingsService.getAllSettings()similarly.Affected files:
LLMProviderService,LLMModelService,ModelSettingsServiceand their implementationsAcceptance criteria:
Priority / Est.: 2–3 days
Task 7 — Frontend: Public / Private resource indicators
Summary: Add UI indicators (badges) and ownership information so users can see whether a provider/model/settings is public (in "All Users") or private.
Action items:
ProviderListItemwhen provider is in "All Users" group.ModelListItemwhen model is in "All Users" group.SettingsListPanelwhen settings is in "All Users" group.Affected files/components:
ProviderListItem,ModelListItem,SettingsListPanel, provider/model/settings detail panels.Acceptance criteria:
Priority / Est.: 1–2 days
Task 8 — Frontend: Admin controls for resource sharing
Summary: Provide admin UI to make resources public or share with specific groups, with permission checks.
Action items:
MANAGE_PUBLIC_RESOURCES).Affected files/components:
Acceptance criteria:
AccessMode.Priority / Est.: 2–3 days
Task 9 — Testing & Integration
Summary: End-to-end verification of resource sharing, access enforcement, public access semantics, and admin controls.
Action items:
Acceptance criteria:
Priority / Est.: 2–3 days
If you'd like I can:
Created from
temp/Phase 3 Readiness Report.md(2025-10-06)