Skip to content

add observer role for fw lite projects#1710

Merged
hahn-kev merged 19 commits into
developfrom
observer-role-fw-lite
Jun 5, 2025
Merged

add observer role for fw lite projects#1710
hahn-kev merged 19 commits into
developfrom
observer-role-fw-lite

Conversation

@hahn-kev

@hahn-kev hahn-kev commented May 27, 2025

Copy link
Copy Markdown
Collaborator

closes #1708 Should we indicate in the UI when in read-only mode?

@coderabbitai

coderabbitai Bot commented May 27, 2025

Copy link
Copy Markdown

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This update introduces the "Observer" project role across the backend, frontend, and API layers. It modifies enums, models, permission checks, database schema, and UI components to support and display the new role. Role-based logic for editing and viewing is refined, and feature flags are integrated for write permissions. Supporting migrations and documentation are included.

Changes

Files / Areas Change Summary
backend/FwLite/FwLiteShared/Projects/CombinedProjectsService.cs
backend/FwLite/FwLiteShared/Projects/LexboxProjectService.cs
backend/FwLite/FwLiteShared/Services/MiniLcmJsInvokable.cs
Propagate and handle project roles, add role conversion helpers, update write permission logic, and switch to external project types.
backend/FwLite/LcmCrdt/CrdtProject.cs
backend/FwLite/LcmCrdt/CrdtProjectsService.cs
backend/FwLite/LcmCrdt/CurrentProjectService.cs
Add UserProjectRole enum and properties, update methods to track and update user roles, extend project creation and update logic.
backend/FwLite/LcmCrdt/Migrations/20250526102635_AddProjectDataRole.*
backend/FwLite/LcmCrdt/Migrations/LcmCrdtDbContextModelSnapshot.cs
Add database migration and snapshot to support the new Role column in ProjectData.
backend/LexBoxApi/Controllers/CrdtController.cs
backend/LexBoxApi/Controllers/LegacyProjectApiController.cs
backend/LexBoxApi/GraphQL/LexAuthUserOutOfSyncExtensions.cs
backend/LexBoxApi/Hub/CrdtProjectChangeHub.cs
backend/LexBoxApi/Services/PermissionService.cs
Update endpoints, permission checks, and out-of-sync logic to handle and expose project roles, including download permissions.
backend/LexCore/Auth/LexAuthUser.cs
backend/LexCore/Entities/Project.cs
backend/LexCore/Entities/ProjectRole.cs
backend/LexCore/ServiceInterfaces/IPermissionService.cs
Add and expose the Observer role in enums, records, and service interfaces; update serialization and membership logic.
backend/LexData/Entities/UserEntityConfiguration.cs Allow unverified emails for Observer role in verification logic.
deployment/Taskfile.yml Add a new task for local port forwarding to the fw-headless service.
frontend/schema.graphql Add OBSERVER to ProjectRole enum and remove deprecated field.
frontend/src/lib/components/Projects/FormatUserProjectRole.svelte
frontend/src/lib/i18n/locales/en.json
frontend/src/lib/user.ts
Add Observer role to role mappings, localization, and user role parsing.
frontend/src/lib/forms/ProjectRoleSelect.svelte
frontend/src/routes/(authenticated)/project/[project_code]/ChangeMemberRoleModal.svelte
frontend/src/routes/(authenticated)/project/[project_code]/MembersList.svelte
Add optional showObserver prop to support Observer role selection and display.
frontend/src/routes/(authenticated)/project/[project_code]/AddProjectMember.svelte
frontend/src/routes/(authenticated)/project/[project_code]/BulkAddProjectMembers.svelte
Update validation and UI to support Observer role; add comments for future Observer support.
frontend/src/routes/(authenticated)/project/[project_code]/+page.svelte Refactor permission logic, add derived stores, update member list to support Observer role, and improve conditional rendering.
frontend/src/lib/util/enums.ts Remove obsolete enum utility for project roles.
frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Projects/IProjectModel.ts
frontend/viewer/src/lib/dotnet-types/generated-types/LcmCrdt/IProjectData.ts
Add role: number property to project model/data interfaces.
frontend/viewer/src/project/NewEntryButton.svelte
frontend/viewer/src/project/browse/BrowseView.svelte
frontend/viewer/src/project/browse/EntryMenu.svelte
frontend/viewer/src/project/browse/EntryView.svelte
Integrate feature flags for write permissions and update conditional rendering for entry actions.

Poem

🐇
A new role appears, Observer in tow,
With permissions refined, the projects now grow.
From backend to frontend, the changes cascade,
Feature flags check if edits are made.
Migrations and enums, all up to date—
The rabbit approves, this release is great!
🌱✨


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions

github-actions Bot commented May 27, 2025

Copy link
Copy Markdown
Contributor

UI unit Tests

10 tests  ±0   10 ✅ ±0   0s ⏱️ ±0s
 3 suites ±0    0 💤 ±0 
 1 files   ±0    0 ❌ ±0 

Results for commit 889e74a. ± Comparison against base commit d31c143.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented May 27, 2025

Copy link
Copy Markdown
Contributor

C# Unit Tests

116 tests  ±0   116 ✅ ±0   10s ⏱️ ±0s
 17 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 889e74a. ± Comparison against base commit d31c143.

♻️ This comment has been updated with latest results.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
deployment/Taskfile.yml (1)

79-81: Add a desc field for better self-documentation
To improve discoverability and clarify the purpose of this task, consider adding a brief description:

  local-fw-headless-forward:
+   desc: "Port-forward the fw-headless service (5275→8081) for FieldWorks Lite"
    cmds:
      - kubectl port-forward service/fw-headless 5275:8081 -n languagedepot --context docker-desktop
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 404ae07 and ca9d51b.

📒 Files selected for processing (37)
  • backend/FwLite/FwLiteShared/Projects/CombinedProjectsService.cs (6 hunks)
  • backend/FwLite/FwLiteShared/Projects/LexboxProjectService.cs (4 hunks)
  • backend/FwLite/FwLiteShared/Services/MiniLcmJsInvokable.cs (1 hunks)
  • backend/FwLite/LcmCrdt/CrdtProject.cs (2 hunks)
  • backend/FwLite/LcmCrdt/CrdtProjectsService.cs (3 hunks)
  • backend/FwLite/LcmCrdt/CurrentProjectService.cs (1 hunks)
  • backend/FwLite/LcmCrdt/Migrations/20250526102635_AddProjectDataRole.Designer.cs (1 hunks)
  • backend/FwLite/LcmCrdt/Migrations/20250526102635_AddProjectDataRole.cs (1 hunks)
  • backend/FwLite/LcmCrdt/Migrations/LcmCrdtDbContextModelSnapshot.cs (1 hunks)
  • backend/LexBoxApi/Controllers/CrdtController.cs (3 hunks)
  • backend/LexBoxApi/Controllers/LegacyProjectApiController.cs (1 hunks)
  • backend/LexBoxApi/GraphQL/LexAuthUserOutOfSyncExtensions.cs (1 hunks)
  • backend/LexBoxApi/Hub/CrdtProjectChangeHub.cs (1 hunks)
  • backend/LexBoxApi/Services/PermissionService.cs (2 hunks)
  • backend/LexCore/Auth/LexAuthUser.cs (3 hunks)
  • backend/LexCore/Entities/Project.cs (2 hunks)
  • backend/LexCore/Entities/ProjectRole.cs (1 hunks)
  • backend/LexCore/ServiceInterfaces/IPermissionService.cs (1 hunks)
  • backend/LexData/Entities/UserEntityConfiguration.cs (1 hunks)
  • deployment/Taskfile.yml (1 hunks)
  • frontend/schema.graphql (1 hunks)
  • frontend/src/lib/components/Projects/FormatUserProjectRole.svelte (1 hunks)
  • frontend/src/lib/forms/ProjectRoleSelect.svelte (2 hunks)
  • frontend/src/lib/i18n/locales/en.json (1 hunks)
  • frontend/src/lib/user.ts (2 hunks)
  • frontend/src/lib/util/enums.ts (0 hunks)
  • frontend/src/routes/(authenticated)/project/[project_code]/+page.svelte (3 hunks)
  • frontend/src/routes/(authenticated)/project/[project_code]/AddProjectMember.svelte (2 hunks)
  • frontend/src/routes/(authenticated)/project/[project_code]/BulkAddProjectMembers.svelte (1 hunks)
  • frontend/src/routes/(authenticated)/project/[project_code]/ChangeMemberRoleModal.svelte (2 hunks)
  • frontend/src/routes/(authenticated)/project/[project_code]/MembersList.svelte (3 hunks)
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Projects/IProjectModel.ts (1 hunks)
  • frontend/viewer/src/lib/dotnet-types/generated-types/LcmCrdt/IProjectData.ts (1 hunks)
  • frontend/viewer/src/project/NewEntryButton.svelte (3 hunks)
  • frontend/viewer/src/project/browse/BrowseView.svelte (1 hunks)
  • frontend/viewer/src/project/browse/EntryMenu.svelte (1 hunks)
  • frontend/viewer/src/project/browse/EntryView.svelte (2 hunks)
💤 Files with no reviewable changes (1)
  • frontend/src/lib/util/enums.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
backend/LexData/Entities/UserEntityConfiguration.cs (1)
backend/LexCore/Exceptions/ProjectMembersMustBeVerifiedForRole.cs (2)
  • ProjectMembersMustBeVerifiedForRole (5-11)
  • ProjectMembersMustBeVerifiedForRole (7-10)
backend/FwLite/LcmCrdt/Migrations/20250526102635_AddProjectDataRole.Designer.cs (2)
backend/FwLite/LcmCrdt/Migrations/LcmCrdtDbContextModelSnapshot.cs (1)
  • DbContext (13-639)
backend/FwLite/LcmCrdt/Migrations/20250526102635_AddProjectDataRole.cs (1)
  • AddProjectDataRole (8-28)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Build FwHeadless / publish-fw-headless
  • GitHub Check: Build FW Lite and run tests
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (63)
frontend/viewer/src/lib/dotnet-types/generated-types/LcmCrdt/IProjectData.ts (1)

16-16: Generated type correctly reflects backend changes.

The addition of the required role: number property aligns with the backend ProjectData record changes. The numeric type correctly represents the UserProjectRole enum values from the backend.

Consider adding a TypeScript enum or const assertion in the frontend to improve type safety when working with role values, rather than using raw numbers throughout the codebase.

frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Projects/IProjectModel.ts (1)

15-15: Consistent type generation for project role support.

The role: number property addition is consistent with the IProjectData interface and correctly reflects the backend ProjectModel changes. This enables role-based UI behavior across both project data models.

backend/LexCore/Entities/ProjectRole.cs (1)

9-9: LGTM! Observer role properly activated.

The Observer role is correctly added with sequential value 4, maintaining the enum's numbering pattern. This change supports the PR objective of introducing observer functionality for fw lite projects.

frontend/src/lib/components/Projects/FormatUserProjectRole.svelte (1)

14-14: Consistent role mapping implementation.

The Observer role is properly added to the roles mapping following the same pattern as other roles, correctly using the i18n localization system.

frontend/src/lib/user.ts (1)

1-18: Import reformatting looks good.

The import statements have been properly organized with consistent spacing and ordering. No functional changes detected.

frontend/src/routes/(authenticated)/project/[project_code]/MembersList.svelte (3)

31-31: Well-structured optional prop addition.

The showObserver prop is properly typed as optional boolean, following good TypeScript practices.


44-44: Consistent prop destructuring.

The showObserver prop is correctly included in the destructured props, maintaining consistency with the component's prop handling pattern.


170-170: Proper prop propagation to child component.

The showObserver prop is correctly passed to the ChangeMemberRoleModal component, enabling conditional Observer role display functionality.

backend/LexBoxApi/Controllers/LegacyProjectApiController.cs (1)

81-81: Good documentation improvement for backward compatibility.

The comment clearly explains why the Observer role (and potentially future roles) maps to "unknown" in the legacy API, which is important for maintaining compatibility with older FieldWorks clients that don't understand new role types.

backend/LexCore/ServiceInterfaces/IPermissionService.cs (1)

13-13: Well-designed permission method addition.

The new AssertCanDownloadProject method follows the established pattern of other permission assertion methods in the interface. This separation of download and sync permissions is appropriate for supporting the observer role, where observers may have download permissions but limited sync capabilities.

frontend/schema.graphql (1)

1273-1273: Proper schema extension for observer role support.

The addition of OBSERVER to the ProjectRole enum follows the established naming convention and maintains logical ordering. This enables full GraphQL support for the new observer role across the API layer.

frontend/viewer/src/project/browse/EntryMenu.svelte (1)

53-57: Excellent permission-based UI rendering.

Conditionally showing the delete menu item based on the features.write flag is a proper implementation of role-based access control in the UI. This ensures that observers and other users without write permissions won't see destructive actions they cannot perform, improving both security and user experience.

backend/FwLite/LcmCrdt/Migrations/LcmCrdtDbContextModelSnapshot.cs (1)

50-52: LGTM! Auto-generated migration snapshot correctly reflects schema changes.

The addition of the Role property with INTEGER column type appropriately supports the new UserProjectRole enum storage in the database.

frontend/src/routes/(authenticated)/project/[project_code]/AddProjectMember.svelte (2)

25-25: LGTM! Validation schema correctly includes Observer role.

The schema now properly validates the Observer role alongside Editor and Manager, maintaining Editor as the default.


102-102: LGTM! Conditional Observer role display is well-implemented.

The showObserver={project.hasHarmonyCommits} logic correctly limits Observer role visibility to FW Lite projects, which aligns with the PR objectives of Observer being "FieldWorks Lite only".

frontend/src/lib/i18n/locales/en.json (1)

607-608: LGTM! Clear and appropriate localization for Observer role.

The description "Observer (can not edit, FieldWorks Lite only)" effectively communicates both the read-only nature and the scope limitation of the role.

backend/FwLite/LcmCrdt/CrdtProject.cs (2)

30-31: LGTM! ProjectData record appropriately extended with role support.

The addition of the Role parameter with UserProjectRole.Unknown as the default value provides good backward compatibility and fallback behavior for existing projects.


41-47: LGTM! Well-structured enum for user project roles.

The UserProjectRole enum provides comprehensive role coverage with clear, descriptive values. The inclusion of Unknown as a fallback and Observer for read-only access aligns perfectly with the PR objectives.

frontend/src/lib/forms/ProjectRoleSelect.svelte (1)

10-10: LGTM! Clean conditional role display implementation.

The showObserver prop with default false provides a clean way to control Observer role visibility. The implementation follows consistent patterns with proper i18n usage and maintains backward compatibility.

Also applies to: 13-13, 23-27

backend/LexBoxApi/Hub/CrdtProjectChangeHub.cs (1)

14-14: Appropriate permission relaxation for Observer role support.

Changing from AssertCanSyncProject to AssertCanDownloadProject is correct for supporting Observer roles. Observers should be able to listen for project changes (to receive real-time updates) but don't need sync permissions, which typically imply write access.

frontend/viewer/src/project/browse/EntryView.svelte (1)

22-22: Proper feature flag integration for write permission control.

The implementation correctly combines the existing readonly state with the features.write feature flag using logical OR. This ensures the entry editor becomes read-only when either the local readonly state is true OR the write feature is disabled, which aligns perfectly with supporting Observer roles.

Also applies to: 28-28, 105-105

frontend/viewer/src/project/NewEntryButton.svelte (1)

16-16: Correct feature flag gating for write operations.

The implementation properly gates the "New Entry" button behind the features.write flag while preserving the existing isActive logic. This ensures Observer role users won't see UI elements for operations they can't perform, providing a better user experience.

Also applies to: 35-35, 44-44

frontend/src/routes/(authenticated)/project/[project_code]/ChangeMemberRoleModal.svelte (4)

12-12: LGTM! Optional prop correctly typed.

The optional showObserver prop is properly typed and maintains backward compatibility.


15-15: LGTM! Props destructuring updated correctly.

The destructuring properly includes the new showObserver prop with correct TypeScript typing.


18-18: LGTM! Schema validation correctly includes Observer role.

The Zod schema properly validates the Observer role alongside Editor and Manager, ensuring form validation works correctly for all supported roles.


55-55: LGTM! Observer prop correctly passed to child component.

The showObserver prop is properly passed to the ProjectRoleSelect component, enabling conditional display of the Observer role option.

backend/FwLite/FwLiteShared/Services/MiniLcmJsInvokable.cs (2)

24-24: LGTM! Dynamic write permission based on user role.

Good change from hardcoded true to the computed CanWrite property, enabling role-based write access control.


27-29: LGTM! Role-based write permission logic is sound.

The implementation correctly:

  • Allows write access for non-CRDT projects (maintains existing behavior)
  • Restricts CRDT projects to Editor and Manager roles only
  • Defaults to Editor role for backward compatibility with existing projects
  • Effectively excludes Observer role from write permissions

This properly implements the Observer role as read-only access.

backend/FwLite/LcmCrdt/Migrations/20250526102635_AddProjectDataRole.cs (2)

13-18: LGTM! Well-structured database migration.

The migration correctly:

  • Adds a non-nullable integer Role column to ProjectData table
  • Uses default value 0 (likely Editor role) for existing records
  • Follows Entity Framework migration conventions

The default value ensures existing projects maintain write access during the migration.


22-27: LGTM! Proper rollback implementation.

The Down method correctly removes the Role column, ensuring the migration is fully reversible.

backend/FwLite/LcmCrdt/CurrentProjectService.cs (1)

139-145: LGTM! Well-implemented role update method.

The UpdateUserRole method demonstrates good practices:

  • Early return optimization prevents unnecessary database operations
  • Uses ExecuteUpdateAsync for efficient bulk updates without entity loading
  • Properly refreshes cached project data to maintain consistency
  • Async implementation with proper awaiting

This provides a clean API for role updates while maintaining performance and data consistency.

backend/LexData/Entities/UserEntityConfiguration.cs (1)

72-73: LGTM! Observer role exemption aligns with read-only permissions.

The addition of ProjectRole.Observer to the email verification exemption is appropriate for a read-only role. The updated comment accurately reflects the current logic.

backend/LexCore/Entities/Project.cs (2)

3-3: LGTM! Necessary import for JSON serialization.

The System.Text.Json.Serialization namespace is correctly added to support the JsonStringEnumConverter attribute used in the FieldWorksLiteProject record.


77-83: LGTM! Well-designed record with proper JSON serialization.

The FieldWorksLiteProject record is well-implemented:

  • Clean positional record syntax
  • Appropriate use of JsonStringEnumConverter for the Role property to ensure proper enum serialization
  • All properties have meaningful types and names
  • Enables role-aware project operations
backend/LexBoxApi/GraphQL/LexAuthUserOutOfSyncExtensions.cs (1)

22-31: LGTM! Consistent implementation following established patterns.

The new overload correctly implements role-aware synchronization checking:

  • Follows the same pattern as existing overloads with admin check and count validation
  • Safely handles potential null token membership with SingleOrDefault
  • Properly compares roles to detect mismatches
  • Integrates well with the new FieldWorksLiteProject record
backend/LexBoxApi/Controllers/CrdtController.cs (4)

38-38: LGTM! Appropriate permission check for read operation.

Changing from AssertCanSyncProject to AssertCanDownloadProject is correct for the GetSyncState endpoint, which is a read operation that doesn't modify data.


64-64: LGTM! Consistent permission check for read operation.

The permission change to AssertCanDownloadProject is appropriate for the Changes endpoint, which retrieves commits without modifying the project.


79-89: LGTM! Enhanced return type with role information.

The changes correctly:

  • Update return type to FieldWorksLiteProject[] to include role information
  • Project to the new record type with proper property mapping
  • Include user's role via the relationship query p.Users.Where(u => u.UserId == loggedInContext.User.Id).Select(m => m.Role).FirstOrDefault()

The role lookup logic is sound and will return the user's role in each project or Unknown if not found.


90-90: LGTM! Improved sync checking with role information.

The change to pass full project objects to IsOutOfSyncWithMyProjects enables more accurate synchronization checking by comparing role information, not just project membership.

backend/FwLite/FwLiteShared/Projects/LexboxProjectService.cs (4)

6-6: LGTM: Import added for role-aware project model.

The import of LexCore.Entities is necessary to use the FieldWorksLiteProject type that includes role information.


77-77: LGTM: JSON deserialization updated to match new return type.

The deserialization target type correctly matches the updated method signature.


87-90: LGTM: New user retrieval method properly implemented.

The GetLexboxUser method correctly delegates to the OAuth client to retrieve the current user, which supports role-based functionality.


67-67:

Details

❓ Verification inconclusive

Verify breaking change: Return type changed from LexboxProject to FieldWorksLiteProject.

The method signature change from LexboxProject[] to FieldWorksLiteProject[] is a breaking change that should be verified across all calling code.


🏁 Script executed:

#!/bin/bash
# Description: Find all usages of GetLexboxProjects to verify they handle the new return type
# Expected: All callers should be updated to handle FieldWorksLiteProject instead of LexboxProject

rg -A 3 "GetLexboxProjects" --type cs

Length of output: 1006


Verify handling of updated return type in callers

All callers of GetLexboxProjects now receive FieldWorksLiteProject[] instead of LexboxProject[]. Ensure FieldWorksLiteProject exposes the same members used by callers.

• In CombinedProjectsService.cs, lexboxProjects.Select(p => new ProjectModel(p.Name, …)) now passes FieldWorksLiteProject.Name.
– Confirm FieldWorksLiteProject defines Name.
– Review any other property or method used on the returned items.

No other calls to GetLexboxProjects were found.

Please verify that:

  • FieldWorksLiteProject includes all fields and behaviors expected by each caller.
  • No downstream code still refers to the old LexboxProject type.
  • Update any mismatches or add mapping logic if needed.
backend/LexCore/Auth/LexAuthUser.cs (4)

211-211: LGTM: Observer role mapping added consistently.

The mapping of ProjectRole.Observer to character 'o' is consistent with the existing pattern for Manager ('m') and Editor ('e').


223-223: LGTM: Simplified array initialization using modern C# syntax.

The use of [] syntax for array initialization is cleaner and more modern.

Also applies to: 228-228


233-233: LGTM: Observer role parsing added consistently.

The parsing of character 'o' to ProjectRole.Observer correctly mirrors the serialization logic.


303-316:

Details

✅ Verification successful

Verify backward compatibility of IsProjectMember method signature change.

The method signature changed from accepting a single nullable ProjectRole to accepting multiple roles via params Span<ProjectRole>. This is a breaking change that needs verification.

The new logic correctly handles:

  • Empty roles (line 307): Returns true if user is a member regardless of role
  • Multiple roles (lines 309-313): Returns true if user has any of the specified roles

🏁 Script executed:

#!/bin/bash
# Description: Find all usages of IsProjectMember to verify they're updated for the new signature
# Expected: All callers should be updated to pass roles as individual parameters instead of nullable single role

rg -A 3 "IsProjectMember" --type cs

Length of output: 4058


Backward compatibility verified for LexAuthUser.IsProjectMember signature change

All existing calls to IsProjectMember(Guid projectId) continue to work (empty-roles path preserved) and callers that need role checks have been updated to pass one or more ProjectRole values. No breaking changes detected.

backend/FwLite/LcmCrdt/Migrations/20250526102635_AddProjectDataRole.Designer.cs (2)

53-54: LGTM: Role property correctly added to ProjectData entity.

The migration designer correctly defines the new Role property as an integer type in the ProjectData entity, which aligns with the UserProjectRole enum being stored as an integer.


1-643: LGTM: Auto-generated migration designer file is well-structured.

The migration designer file correctly defines the complete database schema including the new Role property and all existing entities with their relationships, indexes, and constraints.

backend/FwLite/LcmCrdt/CrdtProjectsService.cs (3)

49-62: LGTM: UpdateProjectServerInfo method properly implemented with optimization.

The method correctly:

  • Performs early return if values haven't changed (line 54)
  • Uses proper async disposal pattern with scoped services
  • Calls appropriate update methods on CurrentProjectService

The conditional check prevents unnecessary database updates when values are unchanged.


101-101: LGTM: Role parameter properly added to CreateProjectRequest record.

The optional UserProjectRole? Role parameter allows callers to specify a role during project creation while maintaining backward compatibility.


140-140: LGTM: Role parameter properly handled with sensible default.

The ProjectData instantiation correctly uses the role from the request, defaulting to UserProjectRole.Editor when not specified. This is a sensible default that maintains existing behavior while supporting the new Observer role.

backend/LexBoxApi/Services/PermissionService.cs (3)

55-62: LGTM: Sync permission logic correctly restricts Observer role.

The updated CanSyncProject method appropriately restricts sync permissions to only Editor and Manager roles, excluding the new Observer role. This aligns with the read-only nature of the Observer role.


64-71: LGTM: Download permission logic appropriately includes Observer role.

The new CanDownloadProject method correctly allows any project member (including Observer) to download projects while maintaining the same organization manager permissions. This is appropriate since Observer users should be able to access project data for viewing purposes.


83-86: LGTM: Download assertion method follows established pattern.

The new AssertCanDownloadProject method correctly follows the same pattern as other assertion methods in the service.

backend/FwLite/FwLiteShared/Projects/CombinedProjectsService.cs (4)

18-18: LGTM: Appropriate default role for backward compatibility.

Setting ProjectRole.Editor as the default is appropriate for maintaining backward compatibility with existing projects that don't have explicit roles assigned.


73-81: LGTM: Role synchronization logic is well-implemented.

The UpdateProjectServerInfo method correctly synchronizes user roles between server projects and local CRDT projects, ensuring consistency across the system.


128-144: LGTM: Role conversion methods handle all cases appropriately.

The role conversion helper methods correctly map between ProjectRole and UserProjectRole enums, including the new Observer role. The fallback to Unknown for unmapped roles is appropriate and safe.


105-105: LGTM: Safe handling of missing role data.

The null-safe role conversion with fallback to ProjectRole.Unknown when project data is missing is appropriate and prevents runtime errors.

frontend/src/routes/(authenticated)/project/[project_code]/+page.svelte (4)

148-148: LGTM: Good refactoring for readability.

Extracting userIsOrgAdmin into a separate derived store improves code readability and eliminates duplication.


160-160: LGTM: Frontend sync permissions align with backend logic.

The canSyncProject logic correctly mirrors the backend CanSyncProject method by allowing only admin, Manager, Editor roles, and org admins. This appropriately excludes Observer roles from sync operations.


368-430: LGTM: Improved project action button logic.

The updated conditional logic for project action buttons correctly uses canSyncProject to determine when to show sync-related actions, which aligns with the new permission model. The restructured dropdown content improves code organization.


593-593: LGTM: Appropriate Observer role visibility.

Showing the Observer role option only when project.hasHarmonyCommits is true correctly limits Observer role to FW lite projects, which aligns with the PR objective of adding Observer role specifically for FW lite projects.

Comment thread frontend/viewer/src/project/browse/BrowseView.svelte Outdated
Comment thread frontend/src/lib/user.ts
Comment thread backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs Outdated
Comment thread backend/FwLite/LcmCrdt/Migrations/20250526102635_AddProjectDataRole.cs Outdated
Comment thread backend/LexBoxApi/Controllers/LegacyProjectApiController.cs Outdated
Comment thread backend/LexBoxApi/Services/PermissionService.cs
Comment thread backend/LexBoxApi/Services/PermissionService.cs
Comment thread backend/LexCore/Entities/ProjectRole.cs
Comment thread backend/LexData/Entities/UserEntityConfiguration.cs
Comment thread frontend/src/lib/i18n/locales/en.json Outdated
Comment thread frontend/src/routes/(authenticated)/project/[project_code]/+page.svelte Outdated
Co-authored-by: Tim Haasdyk <tim_haasdyk@sil.org>

@myieye myieye left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty cool stuff 🤓 🤠

Comment thread frontend/viewer/src/lib/dotnet-types/generated-types/LcmCrdt/IProjectData.ts Outdated
Comment thread frontend/viewer/src/project/browse/BrowseView.svelte Outdated
@hahn-kev hahn-kev requested a review from myieye May 30, 2025 09:04
@argos-ci

argos-ci Bot commented Jun 4, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Jun 4, 2025, 3:26 PM

@myieye myieye left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I tweaked some tiny ui things.

The rich-text fields currently collapse in read-only mode. Not sure when that started happening, but a quick tests indicates that 07ebfb5 will fix that.

image

@hahn-kev hahn-kev merged commit 0cdfd99 into develop Jun 5, 2025
28 checks passed
@hahn-kev hahn-kev deleted the observer-role-fw-lite branch June 5, 2025 04:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

readonly fw lite role

2 participants