Skip to content

FileNode schema & permission model (3.1.1)#307

Open
leynos wants to merge 45 commits intomainfrom
implement-file-node-schema-permissions-23omhv
Open

FileNode schema & permission model (3.1.1)#307
leynos wants to merge 45 commits intomainfrom
implement-file-node-schema-permissions-23omhv

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Apr 12, 2026

Summary

  • Introduces the ExecPlan for implementing a FileNode schema and a shared permission model (roadmap 3.1.1).
  • Documents a staged approach to evolve from the current flat files schema to a hierarchical FileNode model with dual-backend support (SQLite and PostgreSQL).
  • Establishes design decisions, migrations approach, tests strategy, and documentation alignment to guide subsequent workstreams.

What changed in this PR

  • Adds docs/execplans/3-1-1-file-node-schema-and-permission-model.md containing the full ExecPlan for 3.1.1, including constraints, tolerances, risks, ownership, plan stages, validation gates, and concrete implementation checklist.
  • This PR does not yet implement code changes; it sets the plan and gates for future work.

Why this is important

  • Establishes a coherent, cross-backend schema for FileNode (folders, files, aliases, comments, drop boxes) and a shared permission model.
  • Aligns database migrations, Diesel schema, and repository helpers with a unified permission architecture before performing backfills or destructive migrations.
  • Provides a clear, testable path (rstest/rstest-bdd) and documentation updates to keep the roadmap synchronized.

Plan & milestones (Stages A–H)

  • Stage A: Reconcile permission architecture
    • Audit current repo against docs/file-sharing-design.md, docs/news-schema.md, docs/design.md, docs/protocol.md
    • Produce a design decision documenting final permission architecture and integration points
    • Outcome: documented final architecture in docs/design.md
  • Stage B: Add dual-backend schema for FileNode and shared permissions
    • Introduce file_nodes and selected shared permission structures via additive migrations
    • Ensure legacy files/file_acl remain available for backfill in Stage C/D
    • Outcome: migrations scaffold and schema groundwork ready for Diesel models
  • Stage C: Update Diesel schema, models, and minimal persistence helpers
    • Refresh src/schema.rs and add FileNode-related models and minimal helpers
    • Keep surface small; support seed, path resolution, and basic hierarchy queries
  • Stage D: Add hierarchical query helpers with diesel-cte-ext
    • Implement backend-neutral path/ancestor/descendant helpers and alias resolution
  • Stage E: Migrate tests to the new schema with rstest
    • Update fixtures to seed via FileNode and permission tables; cover core paths
  • Stage F: Add behavioural regression with rstest-bdd
    • Focus on observable contracts like GetFileNameList via existing transport path
  • Stage G: Documentation and roadmap synchronization
    • Update docs/design.md, docs/file-sharing-design.md, docs/users-guide.md, docs/roadmap.md
  • Stage H: Verification and quality gates
    • Run pg_embedded setups, fmt/typecheck/lint/test, and documentation checks

Validation gates & success criteria

  • Stage A: No unresolved contradictions between file-sharing design and current code/docs
  • Stage B: Fresh SQLite/PostgreSQL databases apply migrations; legacy data remains accessible
  • Stage C: Code compiles for both backends; repository helpers cover seed/query needs
  • Stage D: diesel-cte-ext powered queries implemented and tested
  • Stage E: Unit/integration tests for new schema pass on both backends
  • Stage F: Behavioural tests cover observable contracts where applicable
  • Stage G: Documentation reflects the implemented schema and decisions
  • Stage H: All gates pass (formatting, type checks, tests, docs) before marking 3.1.1 done

Testing plan (high level)

  • Use rstest for unit/integration coverage of schema invariants and helper queries
  • Use rstest-bdd for behavioural scenarios tied to the current transport path (e.g., file listing)
  • Validate on both SQLite and PostgreSQL backends, using pg_embedded_setup_unpriv where applicable

Risks & mitigations

  • Risk: schema and permission designs are not yet reconciled across docs and code
    • Mitigation: capture final decisions in docs/design.md before migrations
  • Risk: blocking backfills if early changes disrupt legacy files/file_acl data
    • Mitigation: add migrations additively; avoid destructive changes in 3.1.1
  • Risk: cross-backend differences for aliases/folders
    • Mitigation: portable modeling with CHECK constraints and test coverage on both backends
  • Risk: behavioural tests flaky with PostgreSQL in loop
    • Mitigation: deterministic fixtures and controlled test clusters

Documentation touched

  • docs/design.md: planned final permission architecture
  • docs/file-sharing-design.md: refinement if needed to reflect implemented shape
  • docs/users-guide.md: notes on schema-only changes vs user-visible behaviour
  • docs/roadmap.md: mark 3.1.1 done only after gates pass

How to review

  • Review the ExecPlan structure for completeness and alignment with repository goals
  • Confirm the staged approach (A–H) and the validation gates cover the critical risks
  • Provide feedback on any missing documents or gaps that should be addressed in later commits

Next steps

  • Upon approval, begin Stage A work immediately and align migrations/docs in parallel
  • Iterate on design decisions with the team and update docs accordingly

◳ Generated by DevBoxer


ℹ️ Tag @devboxerhub to ask questions and address PR feedback

📎 Task: https://www.devboxer.com/task/7d2b3e56-da4e-44e8-9730-e922b927f924

Summary by Sourcery

Introduce a hierarchical FileNode schema and shared permission model, wire the existing file-list path to the new adapter, and document completion of roadmap item 3.1.1 while keeping legacy tables for later backfill.

New Features:

  • Add dual-backend migrations for file_nodes, permissions, user_permissions, groups, user_groups, and resource_permissions to model hierarchical files and shared ACLs.
  • Expose new Diesel models and repository helpers for creating file nodes, managing groups and permissions, resolving paths and aliases, and listing visible file nodes per user.
  • Introduce dedicated integration tests for the FileNode repository layer and new SQLite fixtures that seed file_nodes and ACL data for transport tests.
  • Add an ExecPlan document detailing the 3.1.1 FileNode schema and permission model implementation and its validation gates.

Enhancements:

  • Refactor the DB files module and command handler to use the new FileNode/ACL adapter instead of the legacy flat files/file_acl helpers while preserving existing file-list behaviour.
  • Update design, file-sharing, users, roadmap, and migration documentation to describe the implemented FileNode schema, shared permission split, and roadmap 3.1.1 completion.
  • Extend the Diesel schema with join definitions and allow-together declarations for the new tables, and increase the migration timeout to keep embedded DB setup stable under parallel CI loads.

Build:

  • Add additive SQLite and PostgreSQL migrations to create the FileNode and shared-permission tables with portable constraints and indexes, while keeping legacy files/file_acl in place for later backfill.
  • Increase the embedded migration timeout to 15 seconds to accommodate the heavier schema when running parallel SQLite test databases.

Documentation:

  • Add docs/execplans/3-1-1-file-node-schema-and-permission-model.md capturing the plan, decisions, and retrospective for introducing the FileNode schema and permission model.
  • Refresh docs/file-sharing-design.md and docs/design.md to describe the implemented FileNode hierarchy, shared permission tables, and ACL relationships, including Mermaid diagrams and SQL sketches.
  • Update docs/users-guide.md and docs/roadmap.md to note the schema-only nature of 3.1.1, the new tables, and the completion and acceptance details for roadmap item 3.1.1.
  • Tidy several existing docs (wireframe migration guides, repository layout, contents) for consistency and clarity without changing their semantics.

Tests:

  • Adapt existing DB and fixture tests to the new FileNode/permission schema, including SQLite-only ACL and path-resolution coverage and new group-based visibility tests.
  • Add a dedicated tests/file_nodes_repository.rs integration suite that exercises path resolution, child listing, alias resolution, and group ACL visibility over the new adapter.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d4c60bf3-3427-4d1a-869a-c3766ffb7a6e

📥 Commits

Reviewing files that changed from the base of the PR and between db43ad6 and 7df9da0.

📒 Files selected for processing (1)
  • src/db/migrations.rs

FileNode schema & permission model (roadmap 3.1.1) — documentation, migrations, repo helpers and tests

This PR adds the execution plan docs/execplans/3-1-1-file-node-schema-and-permission-model.md and implements the planned, additive transition from the legacy flat files/file_acl model to a hierarchical FileNode schema with a normalised permission model (SQLite and PostgreSQL). The change set is documentation-first: it includes schema migrations, Diesel schema/models, repository helpers, test scaffolding and developer/user docs to gate and guide a staged implementation; no behavioural protocol changes beyond repository-query surface shifts are included.

Key points

  • ExecPlan

    • Adds docs/execplans/3-1-1-file-node-schema-and-permission-model.md and references in docs/repository-layout.md and docs/roadmap.md. The ExecPlan documents staged implementation (Stages A–H), design decisions, constraints, risks, migrations/backfill strategy, validation gates, testing strategy (rstest/rstest-bdd), cross-backend verification, and success criteria. Consult the ExecPlan for the stage-by-stage checklist and acceptance criteria.
  • Schema & migrations

    • Additive migrations for sqlite and postgres create:
      • file_nodes (kind=file|folder|alias) with parent/alias relations, kind-specific CHECK constraints, uniqueness/indexes, creator/timestamps.
      • permissions catalogue, user_permissions, groups, user_groups and resource_permissions (polymorphic principal_type).
      • triggers for principal referential validation and cleanup on principal deletion.
    • Backfill approach preserves legacy files/file_acl; repository-side lookups perform a conditional union to maintain GetFileNameList protocol behaviour during migration.
  • Models & repository

    • Models: replaces FileEntry/NewFileEntry/NewFileAcl with FileNodeKind, FileNode/NewFileNode, VisibleFileNode and permission/group/resource-permission types.
    • Repositories: new hierarchical APIs in src/db/files.rs (seed_permission, create_group, add_user_to_group, create_file_node, grant_resource_permission, get_file_node, resolve_file_node_path, list_child_file_nodes, resolve_alias_target, list_visible_root_file_nodes_for_user). A legacy visibility helper (file_legacy_visibility.rs) is provided and merged at the repository edge.
    • Path handling moved into src/db/file_path.rs: prepare_path (normalisation and validation), backend-specific recursive CTE fragments and builders (build_path_cte).
  • Migrations runtime config

    • Migration watchdog made configurable: AppConfig.migration_timeout_secs (CLI flag --migration-timeout-secs, env MXD_MIGRATION_TIMEOUT_SECS), defaulting to 15s. Migrations are cancellation-aware (CancellationToken) and return a MigrationTimeout error on expiry. Server wiring and test harnesses updated to forward the timeout.
  • Tests & fixtures

    • Extensive test surface added/rewired: backend-agnostic scenario bodies (src/db/tests/file_node_tests/shared*.rs, shared_core.rs), sqlite-specific helpers, and Postgres harnessing via with_embedded_pg.
    • Fixture helpers: test-util/src/fixtures/file_sharing_fixtures.rs seeds permissions, groups and root file nodes; test-util/src/fixtures/mod.rs updated to use these.
    • New integration/unit tests cover path resolution and validation, alias resolution, child listing, direct-user and group ACL flows (idempotency included), legacy visibility fallback and merge ordering, kind CHECK constraints, principal-delete cleanup, and migration timeout/cancellation behaviour.
    • Test-harness duplication reduced: with_embedded_pg centralises embedded-Postgres setup/teardown; Postgres cleanup during Drop moved to a spawned OS thread to avoid "Cannot start a runtime from within a runtime" panics.
  • Documentation & developer guidance

    • Rewrites and additions:
      • docs/file-sharing-design.md: shifts from bitmask ACLs to a normalised permissions model, updates ERD/DDL examples, and documents permission-resolve flow and legacy fallback.
      • docs/design.md: aligns narrative with roadmap 3.1.1.
      • docs/users-guide.md: documents AppConfig/migration timeout and upgrade behaviour.
      • docs/developers-guide.md: documents the database module, recursive CTE helpers, re-exported repo APIs, and migration timeout/cancellation behaviour.
      • docs/execplans/...: detailed implementation plan and decision log.
    • Style and clarity edits applied (en-GB spelling, doc-comments for constants and prepare_path, guidance for follow-up issues).
  • Tooling & build

    • CLI/AppConfig: migration_timeout_secs added to AppConfig and CLI.
    • Makefile: fallback resolution for cargo/whitaker in developer CI environments.
    • serial_test dev-dependency enables file_locks feature.
  • Implementation notes and review responses

    • Insert-then-select duplication reduced via private macros and shared test helpers where applied.
    • Migration timeout increased to 15s and made configurable; tests added for default and override behaviour and cancellation semantics.
    • Postgres cleanup moved to an OS thread to avoid nested Tokio runtime panics.
    • Broader architectural/observability concerns (property tests, tracing at ACL boundaries, performance optimisations) were captured as follow-up issues and deferred.

Scope and intent

  • This PR is documentation, schema, model and repository scaffolding plus a comprehensive test harness and fixtures to enable a staged implementation of roadmap 3.1.1. It does not change public protocol semantics beyond replacing list-file queries with the modern visibility query that still merges legacy rows until backfill completes. The ExecPlan in docs/execplans/3-1-1-file-node-schema-and-permission-model.md should be consulted for stage-by-stage work and success criteria; subsequent PRs will implement runtime behaviour and complete migration/backfill operations.

Walkthrough

Summarise migration to a hierarchical file_nodes schema with a normalized permissions catalogue, add recursive CTE path helpers and dual‑backend migrations with legacy backfill/union, introduce new DB APIs and tests, and add a configurable migration watchdog with cancellation support.

Changes

Cohort / File(s) Summary
Design & docs
docs/design.md, docs/file-sharing-design.md, docs/repository-layout.md, docs/roadmap.md, docs/users-guide.md, docs/developers-guide.md
Rewrite file‑sharing design to authoritative file_nodes + normalized permissions (permissions, user_permissions, resource_permissions); update ERD/DDL, permission resolution, legacy backfill/union behaviour, and rename typekind.
Execution plans
docs/execplans/3-1-1-file-node-schema-and-permission-model.md, docs/execplans/wireframe-v0-3-0-migration.md
Add detailed 3.1.1 exec plan for dual‑backend migration, Diesel/CTE strategy, tests and decision log; minor text reflow in wireframe doc.
Migrations (Postgres/SQLite)
migrations/postgres/.../00000000000006_add_file_nodes_and_permissions/*.sql, migrations/sqlite/.../00000000000006_add_file_nodes_and_permissions/*.sql
Add permissions, user_permissions, groups, user_groups, file_nodes, resource_permissions with CHECK constraints, principal‑validation/cleanup triggers, indexes and down scripts.
Schema & models
src/schema.rs, src/models.rs
Add Diesel tables and Rust models for file nodes, permissions, groups and resource permissions; remove legacy FileEntry/FileAcl; add FileNodeKind, FileNode/NewFileNode, VisibleFileNode and permission/group structs.
DB layer & path helpers
src/db/files.rs, src/db/file_path.rs, src/db/mod.rs, src/db/file_legacy_visibility.rs
Replace legacy file CRUD/ACL with node‑based APIs: permission seed/grant helpers, CTE‑backed path resolution and alias resolution, child listing, visible‑root resolution using resource_permissions filtered by download/list code, legacy merge/dedupe fallback, and FileNodeLookupError.
Migrations runtime
src/db/migrations.rs
Add configurable migration timeout (Option<u64>), CancellationToken‑aware watchdog racing logic; change migration runner to iterative run_next_migration; add tests for timeout/cancellation.
Server & CLI
cli-defs/src/lib.rs, src/server/admin.rs, src/server/cli.rs, src/server/legacy/mod.rs
Add migration_timeout_secs: Option<u64> CLI/env flag; thread timeout through admin/startup/daemon flows; forward timeout into migration runner and tests.
Handlers
src/commands/handlers.rs
Change GetFileNameList to query visible root file_nodes for authenticated user (joins resource_permissions/permissions), with legacy files/file_acl union fallback; preserve response encoding.
Tests & fixtures
test-util/src/fixtures/mod.rs, test-util/src/fixtures/file_sharing_fixtures.rs, test-util/src/postgres.rs, tests/*.rs, tests/file_nodes_repository.rs, tests/create_user_bdd.rs, tests/news_categories.rs
Refactor file‑sharing fixtures; add repository/integration tests for path resolution, aliases, group grants, cleanup and legacy fallback; update test callsites for new migration signature; run Postgres cleanup/reset in threads with redacted URL logging.
Test harness & helpers
src/db/tests/*, src/db/tests/file_node_tests/*
Add shared file‑node test bodies, sqlite/postgres harnesses (embedded Postgres helper), migrate test wiring and new test suites; remove legacy src/db/tests.rs.
Makefile & dev deps
Makefile, Cargo.toml
Add Makefile fallbacks for tool locations and PATH handling; enable file_locks feature for serial_test dev‑dependency.
Misc wiring
src/server/admin.rs, src/server/legacy/mod.rs, test-util/src/fixtures/mod.rs
Forward configured migration timeout into database initialisation/migration calls; update test fixture migration invocations to accept new timeout parameter.

Sequence Diagram(s)

sequenceDiagram
    rect rgba(220,240,255,0.5)
    participant Client
    participant Handler
    participant Database
    participant Cache
    end

    Client->>Handler: Request file list
    Handler->>Database: Query visible root file_nodes for user
    Database->>Database: Resolve resource_permissions join (file_nodes, permissions)
    Database->>Database: Filter by permission code (download/list = 2)
    Database->>Database: Include direct user and group principals
    alt Legacy rows present
        Database->>Database: Query legacy `files` + `file_acl`
        Database->>Database: Map legacy rows to VisibleFileNode
    end
    Database->>Database: Merge results, dedupe preferring file_nodes
    Database-->>Handler: Return unified list
    Handler->>Cache: Cache permission decisions
    Handler-->>Client: Respond with file name list
Loading
sequenceDiagram
    rect rgba(255,245,220,0.5)
    participant Admin
    participant AppConfig
    participant MigrationRunner
    participant Watchdog
    participant Database
    end

    Admin->>AppConfig: Load (migration_timeout_secs)
    Admin->>MigrationRunner: run_migrations(timeout_secs)
    MigrationRunner->>Watchdog: Spawn watchdog (sleep for duration)
    par Migrate vs Watchdog
        MigrationRunner->>Database: Execute migrations
    and
        Watchdog->>MigrationRunner: Trigger cancel if timeout reached
    end
    alt Completed before timeout
        Database-->>MigrationRunner: Migrations done
        MigrationRunner-->>Admin: Success
    else Timeout fired
        Watchdog->>MigrationRunner: Cancel via token
        MigrationRunner->>Database: Await in‑flight work, then return timeout error
        MigrationRunner-->>Admin: Return MigrationTimeout error
    end
Loading

Poem

🌿 From bitmasks old to nodes reclaimed,
Permissions catalogued, groups proclaimed,
CTEs map paths where aliases hide,
Legacy rows and modern grants allied,
Launch the migrations, keep the watchdogs primed.


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (2 errors, 6 warnings)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error Test suite lacks coverage for grant revocation, group membership removal, legacy/modern visibility merging, positive kind-constraint validation, concurrent migrations, and grace-period timeout handling. Add explicit revocation tests, group removal tests, Postgres legacy/modern merge tests, positive constraint tests, concurrent migration tests, and grace-period timeout tests with implementation verification.
Module-Level Documentation ❌ Error The migrated_conn fixture in src/db/tests/mod.rs lacks module-level documentation despite being a public test API exposed via the #[fixture] attribute, violating documentation standards for exported functionality. Add a comprehensive docstring to the migrated_conn fixture preceding the #[fixture] attribute, documenting that it establishes an in-memory SQLite database connection with all pending migrations applied, and include an "# Errors" section.
Developer Documentation ⚠️ Warning Developer documentation incompletely reflects new internal APIs and architectural changes. The file_path module's recursive CTE implementation, key error types, and several exported functions lack adequate coverage in developers-guide.md despite design.md being updated. Document the file_path module's recursive CTE implementation, add docstrings to FileNodeLookupError and public types, and explicitly describe all re-exported functions with parameters and error semantics in developers-guide.md.
Testing (Unit) ⚠️ Warning Unit tests for prepare_path input normalisation, edge cases (empty paths, interior empty segments, slash trimming), and error paths are absent from src/db/file_path.rs; integration tests alone cannot verify local module invariants. Add inline unit tests within src/db/file_path.rs testing prepare_path normalisation, boundary conditions, rejection of invalid paths, and all FileNodeLookupError variants with assertion of invariants.
Domain Architecture ⚠️ Warning Domain layer leaks infrastructure and persistence concerns through transparent error propagation, untyped strings for enums, and hardcoded infrastructure constants rather than domain abstractions. Extract domain enums for PrincipalType, ResourceType, and PermissionCode; update FileNode to use FileNodeKind enum; translate infrastructure errors to domain variants; create domain-shaped constructors enforcing valid combinations; encapsulate visibility query logic behind domain-level functions.
Observability ⚠️ Warning PR introduces significant operational changes to file-node hierarchy and permission resolution but lacks adequate observability for maintainers to diagnose failures and unexpected state transitions in production. Add structured logging at database-error boundaries, emit info-level logs for permission denials, introduce distributed tracing spans for permission-resolution flows, add metrics for permission checks, and implement audit logging for ACL mutations.
Performance And Resource Use ⚠️ Warning Implementation exhibits avoidable resource inefficiency: unnecessary string cloning during visibility deduplication and unbounded path depth in recursive CTE iterations. Enforce maximum path segment limit (128) in prepare_path and replace two-query visibility pattern with single SQL UNION DISTINCT query to eliminate unnecessary cloning.
Concurrency And State ⚠️ Warning Migration timeout implementation ignores grace period result, always returning timeout error despite successful completion within grace window, causing non-deterministic state transitions. Refactor to return Ok(result) if future completes before timeout, return timeout error only if grace period expires, and document rollback behaviour on timeout.
✅ Passed checks (10 passed)
Check name Status Explanation
Title check ✅ Passed Title directly references the roadmap item (3.1.1) and accurately summarises the core change: introducing FileNode schema and permission model.
Description check ✅ Passed Description is comprehensive and clearly related to the changeset, covering the ExecPlan, staged implementation approach, design decisions, migrations strategy, testing plan, and documentation updates.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
User-Facing Documentation ✅ Passed The pull request has properly documented all user-facing changes in docs/users-guide.md, including the migration timeout configuration parameter and internal file-metadata schema milestone with appropriate examples, caveats, and cross-references.
Testing (Property / Proof) ✅ Passed PR correctly documents property-based testing and formal verification as deferred roadmap work, not scope for 3.1.1, with concrete test coverage matching documented strategy.
Testing (Compile-Time / Ui) ✅ Passed PR introduces no compile-time behaviour requiring trybuild tests and no UI-adjacent or structured output requiring snapshot tests. Error types use straightforward thiserror annotations with static messages. All new tests follow standard Rust testing patterns to verify database behaviour and migration logic.
Unit Architecture ✅ Passed Pull request maintains clear separation between query and command paths with explicit return types, proper dependency injection, and isolated error handling.
Security And Privacy ✅ Passed The pull request maintains strong security and privacy controls with database-layer authorisation validation, path injection protection, referential integrity enforcement, and use of only fake credentials in test fixtures.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch implement-file-node-schema-permissions-23omhv

Review rate limit: 9/10 reviews remaining, refill in 6 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Apr 12, 2026

Reviewer's Guide

Introduces a hierarchical FileNode-based file/ACL schema shared across SQLite and PostgreSQL, wires it into Diesel models and db helpers, migrates tests and fixtures to use the new structures, and documents the final permission architecture and roadmap completion while keeping legacy tables for backfill.

Sequence diagram for GetFileNameList using FileNode permissions

sequenceDiagram
  actor Client
  participant CommandHandler
  participant DbPool
  participant DbConnection
  participant FilesRepository

  Client->>CommandHandler: send GetFileNameList
  CommandHandler->>DbPool: get()
  DbPool-->>CommandHandler: DbConnection
  CommandHandler->>DbConnection: list_visible_root_file_nodes_for_user(user_id)
  DbConnection->>FilesRepository: join file_nodes, resource_permissions, permissions, user_groups
  FilesRepository-->>DbConnection: Vec<VisibleFileNode>
  DbConnection-->>CommandHandler: visible roots
  CommandHandler-->>Client: FileNameList response
Loading

ER diagram for new FileNode and shared permission schema

erDiagram
  User {
    int id
    varchar username
    varchar email
    boolean active
  }

  Group {
    int id
    varchar name
  }

  UserGroup {
    int user_id
    int group_id
  }

  Permission {
    int id
    int code
    varchar name
    varchar description
  }

  UserPermission {
    int user_id
    int permission_id
  }

  FileNode {
    int id
    enum kind
    varchar name
    int parent_id
    int alias_target_id
    varchar object_key
    bigint size
    text comment
    boolean is_dropbox
    int creator_id
    timestamptz created_at
    timestamptz updated_at
  }

  ResourcePermission {
    varchar resource_type
    int resource_id
    varchar principal_type
    int principal_id
    int permission_id
  }

  %% Membership
  User ||--o{ UserGroup : member
  Group ||--o{ UserGroup : membership

  %% Global privileges
  Permission ||--o{ UserPermission : grants
  User ||--o{ UserPermission : holds

  %% File hierarchy
  FileNode ||--o| FileNode : parent
  FileNode ||--o| FileNode : alias_target
  User ||--o{ FileNode : creates

  %% Resource ACLs
  Permission ||--o{ ResourcePermission : grants
  FileNode ||--o{ ResourcePermission : protected_resource
  User ||--o{ ResourcePermission : principal_user
  Group ||--o{ ResourcePermission : principal_group
Loading

Class diagram for FileNode models and DB helpers

classDiagram
  direction LR

  class FileNodeKind {
    <<enum>>
    +File
    +Folder
    +Alias
    +as_str() str
  }

  class Permission {
    +i32 id
    +i32 code
    +String name
    +String description
  }

  class NewPermission {
    +i32 code
    +&str name
    +&str description
  }

  class Group {
    +i32 id
    +String name
  }

  class NewGroup {
    +&str name
  }

  class NewUserGroup {
    +i32 user_id
    +i32 group_id
  }

  class NewUserPermission {
    +i32 user_id
    +i32 permission_id
  }

  class FileNode {
    +i32 id
    +String kind
    +String name
    +Option~i32~ parent_id
    +Option~i32~ alias_target_id
    +Option~String~ object_key
    +Option~i64~ size
    +Option~String~ comment
    +bool is_dropbox
    +i32 creator_id
    +NaiveDateTime created_at
    +NaiveDateTime updated_at
  }

  class NewFileNode {
    +&str kind
    +&str name
    +Option~i32~ parent_id
    +Option~i32~ alias_target_id
    +Option~&str~ object_key
    +Option~i64~ size
    +Option~&str~ comment
    +bool is_dropbox
    +i32 creator_id
  }

  class VisibleFileNode {
    +i32 id
    +String name
    +String kind
  }

  class NewResourcePermission {
    +&str resource_type
    +i32 resource_id
    +&str principal_type
    +i32 principal_id
    +i32 permission_id
  }

  class FileNodeLookupError {
    <<enum>>
    +InvalidPath
    +Diesel
    +Serde
  }

  class DbConnection {
  }

  class FilesRepository {
    <<module>>
    +seed_permission(conn, permission) Result~i32~
    +create_group(conn, group) Result~i32~
    +add_user_to_group(conn, membership) Result~bool~
    +create_file_node(conn, node) Result~i32~
    +grant_resource_permission(conn, permission) Result~bool~
    +get_file_node(conn, node_id) Result~Option~FileNode~~
    +resolve_file_node_path(conn, path) Result~Option~FileNode~~
    +list_child_file_nodes(conn, parent_id) Result~Vec~FileNode~~
    +resolve_alias_target(conn, node_id) Result~Option~FileNode~~
    +list_visible_root_file_nodes_for_user(conn, user_id) Result~Vec~VisibleFileNode~~
  }

  FileNodeKind --> FileNode : kind_string
  Permission <.. NewPermission : builds
  Group <.. NewGroup : builds
  FileNode <.. NewFileNode : builds
  Permission <.. NewResourcePermission : permission_id

  DbConnection --> FilesRepository : used_by
  FilesRepository --> FileNode : queries
  FilesRepository --> VisibleFileNode : projects
  FilesRepository --> Permission : seeds
  FilesRepository --> Group : seeds
Loading

Architecture flow for FileNode outbound adapter

flowchart LR
  subgraph InboundPort
    WF["Wireframe transport
(Hotline transactions)"]
    CMD["Command handlers
(GetFileNameList)"]
  end

  subgraph ApplicationCore
    SVC["FileListingService
(port interface)"]
  end

  subgraph OutboundAdapter
    DBMOD["mxd::db::files
(Diesel helpers)"]
    SCHEMA["Diesel schema.rs
(FileNode, permissions)"]
  end

  subgraph Persistence
    DB1[(SQLite DB)]
    DB2[(PostgreSQL DB)]
  end

  WF --> CMD
  CMD --> SVC
  SVC --> DBMOD
  DBMOD --> SCHEMA
  DBMOD --> DB1
  DBMOD --> DB2
Loading

File-Level Changes

Change Details Files
Add FileNode-based schema and shared permission tables via dual-backend migrations and Diesel schema updates.
  • Introduce file_nodes, permissions, user_permissions, groups, user_groups, and resource_permissions tables for both PostgreSQL and SQLite with appropriate constraints and indexes.
  • Regenerate Diesel schema.rs to include new tables, joins, and allow-tables clauses while preserving legacy files/file_acl.
  • Define FileNodeKind enum and corresponding FileNode/NewFileNode/VisibleFileNode and permission/group-related structs for Diesel models and inserts.
migrations/postgres/00000000000006_add_file_nodes_and_permissions/up.sql
migrations/postgres/00000000000006_add_file_nodes_and_permissions/down.sql
migrations/sqlite/00000000000006_add_file_nodes_and_permissions/up.sql
migrations/sqlite/00000000000006_add_file_nodes_and_permissions/down.sql
src/schema.rs
src/models.rs
Implement repository helpers and path/hierarchy resolution around FileNode and shared ACLs, and switch file listing to use them.
  • Replace flat files/file_acl helpers with create_file_node, seed_permission, create_group, add_user_to_group, grant_resource_permission, path resolution, alias resolution, child listing, and visible-root listing functions in db::files.
  • Introduce FileNodeLookupError and JSON/CTE-based path resolution helpers using diesel-cte-ext through the new file_path module.
  • Update Command::Files handler to call list_visible_root_file_nodes_for_user so GetFileNameList now uses FileNode and resource_permissions instead of files/file_acl.
src/db/files.rs
src/db/mod.rs
src/commands/handlers.rs
src/lib.rs
src/file_path.rs
tests/file_nodes_repository.rs
Update tests and fixtures to seed through FileNode and shared permissions and add coverage for hierarchy and ACL behaviour.
  • Rewrite db tests from file_acl-centric flows to file_nodes/resource_permissions, including path resolution, alias resolution, and group ACL visibility cases with rstest.
  • Adjust test-util fixtures to create file_nodes, permissions, groups, user_groups, and resource_permissions for the alice test user, and update helpers like resolve_file_node_id.
  • Add a standalone integration test file_nodes_repository.rs exercising repository helpers against the login database setup.
src/db/tests.rs
test-util/src/fixtures/mod.rs
tests/file_nodes_repository.rs
Document the final FileNode schema and permission model and mark roadmap item 3.1.1 as completed.
  • Expand docs/file-sharing-design.md with the concrete relational model, updated Mermaid ERD, SQL DDL sketch, and narrative explaining the split between Permission/UserPermission and ResourcePermission as implemented.
  • Update docs/design.md to describe the new shared file metadata and ACL architecture, including FileNode, groups, and resource_permissions, and embed the implemented ER diagram.
  • Add docs/execplans/3-1-1-file-node-schema-and-permission-model.md capturing the ExecPlan, constraints, risks, stages, progress, and decision log for roadmap 3.1.1, and mark 3.1.1 as done in docs/roadmap.md.
  • Note the schema-only nature of this milestone and its impact on Get File Name List in docs/users-guide.md, and apply minor wording/formatting touch-ups in other affected docs.
docs/file-sharing-design.md
docs/design.md
docs/users-guide.md
docs/roadmap.md
docs/execplans/3-1-1-file-node-schema-and-permission-model.md
docs/wireframe-v0-2-0-to-v0-3-0-migration-guide.md
docs/execplans/wireframe-v0-3-0-migration.md
docs/adopting-hexagonal-architecture-in-the-mxd-wireframe-migration.md
docs/wireframe-users-guide.md
docs/migration-plan-moving-mxd-protocol-implementation-to-wireframe.md
docs/repository-layout.md
docs/CONTENTS.md
Tighten migration timeout and minor formatting/consistency improvements to support the new schema and docs.
  • Increase MIGRATION_TIMEOUT from 5s to 15s to accommodate the heavier additive migrations under parallel SQLite creation.
  • Apply small wording/formatting fixes across design and wireframe docs and adjust Markdown tables and sequences for consistency.
src/db/migrations.rs
docs/wireframe-v0-2-0-migration-guide.md
docs/roadmap.md
docs/adopting-hexagonal-architecture-in-the-mxd-wireframe-migration.md
docs/wireframe-users-guide.md
docs/migration-plan-moving-mxd-protocol-implementation-to-wireframe.md
docs/repository-layout.md
docs/CONTENTS.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Apr 20, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response.

src/db/files.rs

Comment on file

/// Returns any error produced by the database.
#[must_use = "handle the result"]
pub async fn create_file(
pub async fn seed_permission(

❌ New issue: Code Duplication
The module contains 4 functions with similar structure: create_file_node,create_file_node,create_group,seed_permission

@coderabbitai

This comment was marked as resolved.

@leynos leynos changed the title Plan: FileNode schema & permission model (3.1.1) FileNode schema & permission model (3.1.1) Apr 21, 2026
@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Apr 21, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response.

Code Duplication

src/db/files.rs:

What lead to degradation?

The module contains 4 functions with similar structure: create_file_node,create_file_node,create_group,seed_permission

Why does this problem occur?

Duplicated code often leads to code that's harder to change since the same logical change has to be done in multiple functions. More duplication gives lower code health.

How to fix it?

A certain degree of duplicated code might be acceptable. The problems start when it is the same behavior that is duplicated across the functions in the module, ie. a violation of the Don't Repeat Yourself (DRY) principle. DRY violations lead to code that is changed together in predictable patterns, which is both expensive and risky. DRY violations can be identified using CodeScene's X-Ray analysis to detect clusters of change coupled functions with high code similarity. Read More
Once you have identified the similarities across functions, look to extract and encapsulate the concept that varies into its own function(s). These shared abstractions can then be re-used, which minimizes the amount of duplication and simplifies change.

@coderabbitai

This comment was marked as resolved.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Apr 21, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph.

If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced.

src/db/files.rs

Comment on file

/// Returns any error produced by the database.
#[must_use = "handle the result"]
pub async fn create_file(
pub async fn seed_permission(

❌ New issue: Code Duplication
The module contains 2 functions with similar structure: create_group,seed_permission

@coderabbitai

This comment was marked as resolved.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos leynos marked this pull request as ready for review April 22, 2026 08:14
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: db7aac141f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/commands/handlers.rs
sourcery-ai[bot]

This comment was marked as resolved.

@coderabbitai coderabbitai Bot added the Roadmap label Apr 22, 2026
coderabbitai[bot]

This comment was marked as resolved.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as resolved.

codescene-delta-analysis[bot]

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as resolved.

@lodyai lodyai Bot force-pushed the implement-file-node-schema-permissions-23omhv branch from 8db4f39 to 2a9bb60 Compare April 22, 2026 12:11
@leynos

This comment was marked as resolved.

@coderabbitai

This comment was marked as resolved.

Explain the Makefile fallback lookup for Cargo, Whitaker, and markdownlint so
contributors understand why the build gates do not require every tool location
to be preloaded into PATH.
codescene-delta-analysis[bot]

This comment was marked as outdated.

@coderabbitai coderabbitai Bot added Roadmap and removed Issue labels Apr 27, 2026
coderabbitai[bot]

This comment was marked as resolved.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== src/db/file_path.rs (full) ==="
fd -e rs file_path.rs src/ | xargs cat -n

echo ""
echo "=== docs/developers-guide.md — Makefile/tool resolution section ==="
fd -e md developers-guide.md docs/ | xargs grep -n 'Makefile\|CARGO\|WHITAKER\|MDLINT\|shadow\|fallback\|tool.*resolut\|Build-tool\|PATH.*prepend\|well-known' 2>/dev/null | head -20

echo ""
echo "=== docs/developers-guide.md — last 60 lines ==="
tail -60 docs/developers-guide.md

echo ""
echo "=== docs/users-guide.md — grep mixed-state/upgrade/backfill ==="
fd -e md users-guide.md docs/ | xargs grep -n 'upgrade\|mixed.state\|backfill\|transition\|legacy.*table.*remov\|operational' | head -20

echo ""
echo "=== src/db/tests/file_node_tests/mod.rs — with_embedded_pg cleanup guarantee ==="
fd -e rs mod.rs src/db/tests/file_node_tests/ | xargs grep -n 'with_embedded_pg\|pg\.stop\|stop_result\|and_then\|scopeguard\|defer\|finally\|spawn' 2>/dev/null | head -30

echo ""
echo "=== src/db/tests/ directory structure ==="
find src/db/tests -type f -name "*.rs" 2>/dev/null | sort

echo ""
echo "=== src/db/migrations.rs — watchdog/timeout tests ==="
fd -e rs migrations.rs src/db/ | xargs grep -n 'fn test_\|fn.*timeout\|fn.*watchdog\|migration_watchdog\|cancell\|MigrationTimeoutError\|finishes_in_time' 2>/dev/null | head -20

echo ""
echo "=== docs/developers-guide.md — line count ==="
wc -l docs/developers-guide.md

Length of output: 15075


@leynos: All checks are now resolved. Here is the full status:

Error checks — all resolved ✅

Check Sub-item Status
Testing (Overall) prepare_path empty-interior-segment test prepare_path_rejects_empty_interior_segment present in src/db/file_path.rs (line 177)
Migration timeout execution + cancellation tests migration_watchdog_allows_work_that_finishes_in_time (line 305) and migration_watchdog_cancels_work_and_reports_the_applied_timeout (line 319)
Module-Level Documentation FILE_NODE_BODY_SQL doc comments ✅ Both cfg_if! branches documented (lines 22–26 and 40–45)
Unit Architecture prepare_path interior segment rejection ✅ Lines 92–94 reject empty parts; FileNodeLookupError::InvalidPath returned

Warning checks — resolved or properly deferred ✅

Warning Status
User-Facing Documentation (mixed-state window) docs/users-guide.md lines 110–122 cover transition window, legacy tables, mixed-state merge, and operator caution
Developer Documentation (Makefile rationale) ✅ "Build-tool resolution" section in docs/developers-guide.md documents CARGO/WHITAKER/MDLINT fallbacks and override mechanism
Developer Documentation (prepare_path validation docs) ✅ Doc comment updated to document InvalidPath variant
Developer Documentation (normalizes spelling) -ize form used throughout
Testing (Property/Proof) ✅ Deferred — GitHub issue #309
Domain Architecture ✅ Deferred — GitHub issue #310
Observability ✅ Deferred — GitHub issue #311
Performance ✅ Deferred — GitHub issue #312
Concurrency and State ✅ Deferred — GitHub issue #313

Inconclusive check — resolved ✅

Sub-item Status
prepare_path empty-interior-segment test
src/db/tests.rs → submodules ✅ Refactored into src/db/tests/{mod,file_node_tests/mod,file_node_tests/shared,file_node_tests/sqlite}.rs
with_embedded_pg cleanup on error paths pg.stop() runs unconditionally in a spawned OS thread (line 135); result.and(stop_result) (line 144) combines both outcomes

No further work is required.

Route the shared Postgres DB test harness through `PostgresTestDb` when
`POSTGRES_TEST_URL` is set. This lets CI coverage jobs use their
provisioned database instead of downloading embedded PostgreSQL binaries.

Keep the embedded harness as the fallback for local runs without an
external test database.
codescene-delta-analysis[bot]

This comment was marked as outdated.

Expand the first CTE reference and update the `InvalidPath` description
so the developer guide matches the file-node path handling contract.
codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos

This comment was marked as resolved.

@coderabbitai

This comment was marked as resolved.

Add backend-agnostic file-node scenarios for missing paths, permission
filtering, nested child visibility, and kind-specific constraints.

Instrument file visibility, path resolution, permission grants, and
migration watchdog cancellation. Split the legacy visibility query into a
small helper module so the repository module stays within the line budget.
codescene-delta-analysis[bot]

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as resolved.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Apr 28, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response.

src/db/tests/file_node_tests/additional.rs

Comment on lines +365 to +389

async fn assert_alias_without_target_rejected(
    conn: &mut DbConnection,
    creator_id: i32,
) -> Result<(), AnyError> {
    let alias_without_target = create_file_node(
        conn,
        &NewFileNode {
            kind: FileNodeKind::Alias.as_str(),
            name: "orphan-alias",
            parent_id: None,
            alias_target_id: None,
            object_key: None,
            size: None,
            comment: None,
            is_dropbox: false,
            creator_id,
        },
    )
    .await;
    anyhow::ensure!(
        alias_without_target.is_err(),
        "alias without alias_target_id should be rejected"
    );
    Ok(())
}

❌ New issue: Code Duplication
The module contains 3 functions with similar structure: assert_alias_without_target_rejected,assert_file_without_data_rejected,assert_folder_with_object_key_rejected

@coderabbitai

This comment was marked as resolved.

Move the new backend-agnostic file-node scenario bodies into the shared test
module and expose the requested SQLite wrappers from the parent DB test
module.

Split the older shared scenarios into a small core helper module and move
SQLite-only wrappers into the SQLite helper module so all touched Rust files
stay within the line budget while preserving Postgres coverage.
codescene-delta-analysis[bot]

This comment was marked as outdated.

Document the legacy visibility helper contract and bound watchdog
cancellation so timed-out migrations cannot stall indefinitely while waiting
for non-cooperative work to finish.
codescene-delta-analysis[bot]

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as resolved.

Replace the redundant timeout result match with a direct discard binding while
preserving the bounded grace wait after migration cancellation.
codescene-delta-analysis[bot]

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/db/migrations.rs (1)

209-227: 🛠️ Refactor suggestion | 🟠 Major

Document the new timeout parameter and failure mode.

Update the Rustdoc for run_migrations and apply_migrations. The docs still describe only generic Diesel failures, but these APIs now accept timeout_secs and can return a wrapped watchdog timeout after cancellation. As per coding guidelines: "Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc" and "Public functions must be fully documented with all sections required by the relevant documentation standard".

Also applies to: 247-268, 273-300

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/db/migrations.rs` around lines 209 - 227, The Rustdoc for run_migrations
(and apply_migrations) is out of date: update the /// comments to document the
new timeout_secs parameter and the new failure mode when the watchdog cancels
the operation; explicitly describe the timeout_secs argument (Option<u64> in
seconds), how the function behaves when a timeout occurs (returns a wrapped
timeout/cancellation error in the QueryResult), and note that Diesel errors may
still be returned; ensure the doc includes a Parameters section for timeout_secs
and an Errors section describing both Diesel QueryResult errors and the watchdog
timeout/cancellation error for run_migrations and apply_migrations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/db/migrations.rs`:
- Around line 302-303: Add a module-level doc comment for the test module by
placing a //! comment immediately above the `mod tests {` declaration (the
`tests` module) that briefly describes the module's purpose and scope (what
kinds of tests live here and why), matching the project's module-doc convention.
- Around line 306-319: Collapse the three tests that call migration_timeout into
a single parameterized rstest: replace
migration_timeout_uses_default_when_config_value_is_missing,
migration_timeout_uses_default_when_config_value_is_zero, and
migration_timeout_accepts_positive_config_override with one #[rstest] that
supplies the input/config values (None, Some(0), Some(7)) and the expected
Duration results (DEFAULT_MIGRATION_TIMEOUT, DEFAULT_MIGRATION_TIMEOUT,
Duration::from_secs(7)), then assert_eq!(migration_timeout(input), expected);
add the rstest attribute (use rstest::rstest) and a clear test name to keep
coverage while removing duplication and relying on the migration_timeout
function, DEFAULT_MIGRATION_TIMEOUT symbol and Duration::from_secs for
expectations.

---

Outside diff comments:
In `@src/db/migrations.rs`:
- Around line 209-227: The Rustdoc for run_migrations (and apply_migrations) is
out of date: update the /// comments to document the new timeout_secs parameter
and the new failure mode when the watchdog cancels the operation; explicitly
describe the timeout_secs argument (Option<u64> in seconds), how the function
behaves when a timeout occurs (returns a wrapped timeout/cancellation error in
the QueryResult), and note that Diesel errors may still be returned; ensure the
doc includes a Parameters section for timeout_secs and an Errors section
describing both Diesel QueryResult errors and the watchdog timeout/cancellation
error for run_migrations and apply_migrations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c8a19144-4bc5-49e1-a6ed-7a6efcf23833

📥 Commits

Reviewing files that changed from the base of the PR and between 16ce33e and db43ad6.

📒 Files selected for processing (1)
  • src/db/migrations.rs

Comment thread src/db/migrations.rs
Comment thread src/db/migrations.rs Outdated
Update migration Rustdoc to describe the timeout parameter and watchdog
failure mode, and collapse the migration timeout unit checks into one
parameterized rstest case.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
echo "=== src/db/tests/file_node_tests/shared.rs — check for new test bodies ==="
grep -n 'resolve_file_node_path_returns_none\|non_download_permission_does_not_grant\|nested_child_not_visible\|file_node_check_kind_constraint\|pub(crate) async fn' src/db/tests/file_node_tests/shared.rs 2>/dev/null || echo "FILE NOT FOUND OR NO MATCHES"

echo ""
echo "=== src/db/tests/file_node_tests/additional.rs — check for new test bodies ==="
grep -n 'resolve_file_node_path_returns_none\|non_download_permission_does_not_grant\|nested_child_not_visible\|file_node_check_kind_constraint\|pub(crate) async fn' src/db/tests/file_node_tests/additional.rs 2>/dev/null || echo "FILE NOT FOUND OR NO MATCHES"

echo ""
echo "=== all pub(crate)/pub(super) async fn in file_node_tests — with doc comments ==="
for f in src/db/tests/file_node_tests/shared.rs src/db/tests/file_node_tests/shared_core.rs src/db/tests/file_node_tests/mod.rs src/db/tests/file_node_tests/sqlite.rs src/db/tests/file_node_tests/additional.rs; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    grep -n '/// \|pub(crate) async fn\|pub(super) async fn' "$f" | head -60
  else
    echo "$f NOT FOUND"
  fi
done

echo ""
echo "=== src/db/tests/mod.rs — check for new test wrappers ==="
grep -n 'test_resolve_file_node_path_returns_none\|test_non_download_permission\|test_nested_child\|test_file_node_check_kind' src/db/tests/mod.rs 2>/dev/null || echo "NOT FOUND"

echo ""
echo "=== src/db/files.rs — check for tracing instrumentation ==="
grep -n 'tracing\|info!\|debug!\|warn!\|error!\|instrument' src/db/files.rs 2>/dev/null | head -20

echo ""
echo "=== src/db/migrations.rs — check for tracing on timeout ==="
grep -n 'tracing\|info!\|debug!\|warn!\|error!\|watchdog\|timeout.*log\|log.*timeout' src/db/migrations.rs 2>/dev/null | head -20

echo ""
echo "=== list all files in src/db/tests/file_node_tests/ ==="
find src/db/tests -type f -name "*.rs" | sort

echo ""
echo "=== src/db/tests/file_node_tests/mod.rs — all pub(super) functions with doc comments ==="
grep -n '/// \|pub(super) async fn\|pub(super) fn' src/db/tests/file_node_tests/mod.rs 2>/dev/null | head -60

Length of output: 9560


@leynos: All four checks are fully resolved.

Check Sub-item Status
Testing (Overall) resolve_file_node_path_returns_none_for_missing_path_body ✅ Present in shared.rs line 26, wired in additional.rs and tests/mod.rs
non_download_permission_does_not_grant_visibility_body ✅ Present in shared.rs line 43
nested_child_not_visible_without_explicit_grant_body ✅ Present in shared.rs line 111
Module-Level Documentation shared.rs — 4 functions ✅ All carry /// doc comments with # Errors sections
shared_core.rs — 3 functions ✅ All documented
mod.rs — 6 pub(super) functions ✅ All documented (seed_download_permission, with_embedded_pg, reject_self_parent_body, reject_invalid_basenames_body, cleanup_on_principal_delete_body, reject_unknown_principal_body)
sqlite.rs — 2 functions ✅ Both documented
Testing (Unit) ⚠️ Kind-specific CHECK constraint violations file_node_check_kind_constraint_body present (line 184 shared.rs), wired at line 264 of tests/mod.rs
FileNodeLookupError::Serde ✅ Structurally unreachable for well-formed input; doc-note on variant is the appropriate remedy (no forced test)
Observability ⚠️ tracing in src/db/files.rs use tracing::{debug, info} at line 17; info! at line 213 (permission grant), debug! at lines 246 and 393 (visibility query and path resolution)
tracing in src/db/migrations.rs use tracing::info at line 12; info! at lines 118–120 on watchdog expiry

No further work is required.

Copy link
Copy Markdown

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Choose a reason for hiding this comment

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

Gates Passed
6 Quality Gates Passed

See analysis details in CodeScene

Quality Gate Profile: Pay Down Tech Debt
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant