Skip to content

Conversation

@JoshuaSBrown
Copy link
Collaborator

@JoshuaSBrown JoshuaSBrown commented Oct 22, 2025

Ticket

Description

How Has This Been Tested?

Artifacts (if appropriate):

Tasks

  • - A description of the PR has been provided, and a diagram included if it is a new feature.
  • - Formatter has been run
  • - CHANGELOG comment has been added
  • - Labels have been assigned to the pr
  • - A reviwer has been added
  • - A user has been assigned to work on the pr
  • - If new feature a unit test has been added

Summary by Sourcery

Implement a new repository abstraction layer for Foxx service that cleanly separates metadata and Globus-backed repositories, introduces a factory for creating them, updates the router to use the models directly, reorganizes validation code, and adds comprehensive unit and integration tests

New Features:

  • Introduce a repository model layer with BaseRepository, GlobusRepo, and MetadataRepo classes under api/models/repositories
  • Add a factory (Repositories.createRepositoryByType) to instantiate repositories by type
  • Integrate the new repository model into the Foxx repo_router create endpoint to support metadata and Globus repositories

Enhancements:

  • Consolidate validation logic under api/models/repositories/validation.js and remove legacy validation
  • Enhance permissions checks with optional chaining and more detailed error messages
  • Rename execution task type to DEFERRED and add ERR_INVALID_OPERATION code

Build:

  • Update CMakeLists tests patterns to add new foxx_ test targets for repository, metadata, globus, factory, and router

Tests:

  • Add extensive unit tests for BaseRepository, MetadataRepo, GlobusRepo, validation, and repository factory
  • Add integration tests for repo_router create endpoint and Repositories factory

JoshuaSBrown and others added 30 commits October 9, 2025 09:33
…ove circular dependency from validation.js by removing validateRepositorySupportsDataOperations

Co-authored-by: Aaron Perez <[email protected]>
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Oct 22, 2025

Reviewer's Guide

This PR introduces a new class-based repository model layer under api/models/repositories with Rust-style Result handling, integrates it into the Foxx router via a factory, refactors validation and permissions, and overhauls the test suite and CMake targets accordingly.

Sequence diagram for repository creation via Foxx router and factory

sequenceDiagram
    participant User as actor User
    participant Router as "Repo Router"
    participant Factory as "Repositories (Factory)"
    participant RepoClass as "Repository Class (GlobusRepo/MetadataRepo)"
    participant DB as "ArangoDB"
    User->>Router: POST /repo (create repository)
    Router->>Factory: createRepositoryByType(config)
    Factory->>RepoClass: new Repository(config)
    RepoClass->>DB: Check if repo exists
    alt Repo exists
        RepoClass->>DB: Load existing repo
    else Repo does not exist
        RepoClass->>DB: Prepare new repo data
    end
    RepoClass->>Router: Return Result (ok/error)
    Router->>DB: Save repository
    Router->>User: Respond with repository info
Loading

ER diagram for repository and allocation entities

erDiagram
    REPO {
        string _id
        string _key
        string type
        string title
        string desc
        int capacity
    }
    ALLOC {
        string _id
        string _from
        string _to
        int data_limit
        int rec_limit
        int rec_count
        int data_size
        string path
        string type
    }
    REPO ||--o{ ALLOC : "allocations"
    ALLOC }o--|| REPO : "allocated to repo"
Loading

Class diagram for the new repository model layer

classDiagram
    class BaseRepository {
        +constructor(config, typeSpecificConfig)
        +id()
        +save()
        +update(updates)
        +type()
        +createAllocation(allocationParams)
        +deleteAllocation(subjectId)
        +supportsDataOperations()
        +getCapacityInfo()
    }
    class GlobusRepo {
        +constructor(config)
        +type()
        +createAllocation(params)
        +deleteAllocation(client, subject)
        +supportsDataOperations()
        +getCapacityInfo()
        +validate(config)
    }
    class MetadataRepo {
        +constructor(config)
        +type()
        +createAllocation(params)
        +deleteAllocation(client, subject)
        +supportsDataOperations()
        +getCapacityInfo()
        +validate(config)
    }
    class Repositories {
        +static createRepositoryByType(config)
        +static find(repoId)
        +static list(filter)
    }
    BaseRepository <|-- GlobusRepo
    BaseRepository <|-- MetadataRepo
    Repositories --> GlobusRepo
    Repositories --> MetadataRepo
Loading

Class diagram for Result and types utilities

classDiagram
    class Result {
        +ok(value)
        +err(error)
    }
    class RepositoryType {
        <<enumeration>>
        GLOBUS
        METADATA
    }
    class ExecutionMethod {
        <<enumeration>>
        DEFERRED
        DIRECT
    }
    class AllocationResult {
        +execution_method
        +task
        +result
    }
    Result ..> AllocationResult
    AllocationResult ..> ExecutionMethod
    AllocationResult ..> RepositoryType
Loading

File-Level Changes

Change Details Files
Introduce new repository model layer with class-based implementations and factory
  • Defined RepositoryType enum, Result and createAllocationResult helpers in types.js
  • Moved pure validation functions into models/repositories/validation.js
  • Implemented BaseRepository, GlobusRepo, and MetadataRepo classes with create/delete allocation logic
  • Added Repositories.createRepositoryByType factory for dynamic repository instantiation
core/database/foxx/api/models/repositories/types.js
core/database/foxx/api/models/repositories/validation.js
core/database/foxx/api/models/repositories/base_repository.js
core/database/foxx/api/models/repositories/repository/globus.js
core/database/foxx/api/models/repositories/repository/metadata.js
core/database/foxx/api/models/repositories/repositories.js
Refactor repo_router create endpoint to use new model layer
  • Imported RepositoryType and Repositories instead of raw DB collections
  • Replaced direct g_db.repo.save calls with Repositories.createRepositoryByType and repo.save()
  • Adjusted Joi schema to make legacy Globus fields optional and add 'type' validation
  • Removed inline path normalization and replaced with model logic
core/database/foxx/api/repo_router.js
Refactor validation module and update tests
  • Moved repository validation functions under api/models/repositories/validation.js
  • Updated validation.test.js imports to new paths and pruned obsolete tests
  • Renamed import paths in tests to use ../api/models/repositories/validation
core/database/foxx/api/models/repositories/validation.js
core/database/foxx/tests/validation.test.js
Enhance permissions library with null-safe checks and detailed errors
  • Replaced a_client.is_admin checks with a_client?.is_admin for safety
  • Extended ensureAdminPermRepo to include client and repo IDs in error message
core/database/foxx/api/lib/permissions.js
Overhaul test suite and CMakeLists targets to cover new models and router
  • Updated CMakeLists.txt to use colon-suffix patterns and added new test targets
  • Added unit and integration tests for metadata, globus, base repository, factory, and router
  • Renamed describe strings in existing tests to match new test tags
core/database/CMakeLists.txt
core/database/foxx/tests/repo_metadata.test.js
core/database/foxx/tests/repo_globus.test.js
core/database/foxx/tests/repo_router.test.js
core/database/foxx/tests/base_repository.test.js
core/database/foxx/tests/repositories.test.js
Minor supporting updates: execution types, error codes, and task messages
  • Renamed ExecutionMethod.TASK to DEFERRED in execution_types.js
  • Added ERR_INVALID_OPERATION code in error_codes.js
  • Appended task ID information to duplicate‐task error messages in tasks.js
core/database/foxx/api/lib/execution_types.js
core/database/foxx/api/lib/error_codes.js
core/database/foxx/api/tasks.js

Possibly linked issues

  • #Issue 1: The PR integrates metadata and globus repository factory patterns into the repo_router, directly fulfilling the issue's feature request.
  • Feature [Foxx] - integrate metadata and globus factory patterns into repo_router. #1705: The PR introduces a repository type system, implements distinct metadata and Globus repository classes with type-specific allocation logic, and updates the repository creation API as required by the issue.
  • #[Foxx, ArangoDB] - CRUD Update Repo Metadata: The PR directly implements the refactoring of repository metadata validation logic into new Globus and Metadata repository classes, as requested in the issue.

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

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

Blocking issues:

  • Detected directly writing to a Response object from user-defined input. This bypasses any HTML escaping and may expose your application to a Cross-Site-scripting (XSS) vulnerability. Instead, use 'resp.render()' to render safely escaped HTML. (link)

General comments:

  • Remove all debug console.log statements and commented-out code before merging to avoid log spam and keep the codebase clean.
  • Review and unify repository key references in repo_router (using obj.key vs obj._key) to ensure the path validation and key assignment logic still works correctly.
  • Double-check the CMakeLists test definitions—adding trailing colons to the test names may break the test discovery in test_foxx.sh.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Remove all debug console.log statements and commented-out code before merging to avoid log spam and keep the codebase clean.
- Review and unify repository key references in repo_router (using obj.key vs obj._key) to ensure the path validation and key assignment logic still works correctly.
- Double-check the CMakeLists test definitions—adding trailing colons to the test names may break the test discovery in test_foxx.sh.

## Individual Comments

### Comment 1
<location> `core/database/foxx/api/repo_router.js:133-134` </location>
<code_context>
-                            error.ERR_INVALID_PARAM,
-                            "Repository path must be an absolute path file system path.",
-                        ];
+                    if (req.body?.type == undefined || req.body?.type == RepositoryType.GLOBUS) {
+                        obj["type"] = RepositoryType.GLOBUS;
+                        console.log("create 6");
+                        g_lib.procInputParam(req.body, "domain", false, obj);
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Defaulting to GLOBUS type when type is undefined may mask client errors.

Explicitly require the type field and return an error if it is missing, unless backward compatibility necessitates defaulting to GLOBUS.
</issue_to_address>

### Comment 2
<location> `core/database/foxx/api/repo_router.js:143-145` </location>
<code_context>
-                        ];
+                        if (!obj.path.endsWith("/")) obj.path += "/";

-                    if (req.body.exp_path) {
-                        obj.exp_path = req.body.exp_path;
-                        if (!obj.exp_path.endsWith("/")) obj.path += "/";
+                        var idx = obj.path.lastIndexOf("/", obj.path.length - 2);
+                        if (obj.path.substr(idx + 1, obj.path.length - idx - 2) != obj.key)
</code_context>

<issue_to_address>
**issue (bug_risk):** Potential bug: appending '/' to obj.path instead of obj.exp_path.

Please check if '/' should be appended to exp_path instead of path to avoid incorrect path assignment.
</issue_to_address>

### Comment 3
<location> `core/database/foxx/api/repo_router.js:134-143` </location>
<code_context>
-                    if (req.body.exp_path) {
-                        obj.exp_path = req.body.exp_path;
-                        if (!obj.exp_path.endsWith("/")) obj.path += "/";
+                        var idx = obj.path.lastIndexOf("/", obj.path.length - 2);
+                        if (obj.path.substr(idx + 1, obj.path.length - idx - 2) != obj.key)
+                            throw [
+                                error.ERR_INVALID_PARAM,
</code_context>

<issue_to_address>
**issue:** Inconsistent use of obj.key and obj._key in error message.

The error message should reference obj.key instead of obj._key to avoid confusion and ensure consistency with the validation logic.
</issue_to_address>

### Comment 4
<location> `core/database/foxx/api/repo_router.js:184-197` </location>
<code_context>
+                    let repo_doc = repo_doc_result.value;
+                    console.log("create 13");

                     for (var i in req.body.admins) {
+                        console.log("create 14");
                         if (!g_db._exists(req.body.admins[i]))
                             throw [
                                 error.ERR_NOT_FOUND,
                                 "User, " + req.body.admins[i] + ", not found",
                             ];

+                        console.log("create 15");
                         g_db.admin.save({
-                            _from: repo._id,
+                            _from: repo.id(),
</code_context>

<issue_to_address>
**suggestion:** Using for...in to iterate over array may cause unexpected behavior.

'for...in' may iterate over inherited or custom properties, not just array elements. Use a standard for loop or 'for...of' for safer array iteration.

```suggestion
                    for (const admin of req.body.admins) {
                        console.log("create 14");
                        if (!g_db._exists(admin))
                            throw [
                                error.ERR_NOT_FOUND,
                                "User, " + admin + ", not found",
                            ];

                        console.log("create 15");
                        g_db.admin.save({
                            _from: repo.id(),
                            _to: admin,
                        });
                    }
```
</issue_to_address>

### Comment 5
<location> `core/database/foxx/api/models/repositories/base_repository.js:43-44` </location>
<code_context>
+
+class BaseRepository {
+    constructor(config, typeSpecificConfig) {
+        if (new.target === BaseRepository) {
+            return Result.err({
+                code: error.ERR_INTERNAL_FAULT,
+                message: "BaseRepository cannot be instantiated directly",
</code_context>

<issue_to_address>
**issue (bug_risk):** Returning Result.err from constructor may break subclass instantiation expectations.

Throwing an error or using a factory method is preferable for enforcing abstract class constraints, as returning a value from a constructor is non-standard and may cause issues with subclassing.
</issue_to_address>

### Comment 6
<location> `core/database/foxx/api/models/repositories/base_repository.js:185-188` </location>
<code_context>
+            console.log(key);
+            console.log(this.repoData);
+            if (key != undefined) {
+                if (g_db._exists(id)) {
+                    const updated = g_db.repo.update(
+                        { _key: key, ...repo_data },
+                        { returnNew: true },
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Update operation may overwrite fields unintentionally due to object spread.

Explicitly define updatable fields to prevent unintended overwrites and ensure data integrity.

```suggestion
                    // Define updatable fields
                    const updatableFields = ['name', 'description', 'url', 'owner']; // Add all allowed fields here
                    const updateData = { _key: key };
                    updatableFields.forEach(field => {
                        if (repo_data.hasOwnProperty(field)) {
                            updateData[field] = repo_data[field];
                        }
                    });
                    const updated = g_db.repo.update(
                        updateData,
                        { returnNew: true },
                    );
```
</issue_to_address>

### Comment 7
<location> `core/database/foxx/api/models/repositories/repository/globus.js:86-90` </location>
<code_context>
+
+        console.log("Normalized COnfig");
+        console.log(normalizedConfig);
+        const result = super(normalizedConfig, globusConfig);
+        if (result.ok == false) {
+            return result;
+        }
+        this.repoData = result.value.repoData;
+
+        console.log("repoData after calling super");
</code_context>

<issue_to_address>
**nitpick:** Excessive use of console.log for debugging may clutter logs in production.

Consider removing or gating the console.log statements with a debug flag to prevent unnecessary output in production.
</issue_to_address>

### Comment 8
<location> `core/database/foxx/api/repo_router.js:206` </location>
<code_context>
                    res.send([repo_doc]);
</code_context>

<issue_to_address>
**security (javascript.express.security.audit.xss.direct-response-write):** Detected directly writing to a Response object from user-defined input. This bypasses any HTML escaping and may expose your application to a Cross-Site-scripting (XSS) vulnerability. Instead, use 'resp.render()' to render safely escaped HTML.

*Source: opengrep*
</issue_to_address>

### Comment 9
<location> `core/database/foxx/api/models/repositories/base_repository.js:62-66` </location>
<code_context>
        if (config.id !== undefined) {
            if (config.id.startsWith("repo/") && config.id.length > "repo/".length) {
                id_defined = true;
            }
        }

</code_context>

<issue_to_address>
**suggestion (code-quality):** Merge nested if conditions ([`merge-nested-ifs`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/merge-nested-ifs))

```suggestion
        if (config.id !== undefined && (config.id.startsWith("repo/") && config.id.length > "repo/".length)) {
              id_defined = true;
        }

```

<br/><details><summary>Explanation</summary>Reading deeply nested conditional code is confusing, since you have to keep track of which
conditions relate to which levels. We therefore strive to reduce nesting where
possible, and the situation where two `if` conditions can be combined using
`and` is an easy win.
</details>
</issue_to_address>

### Comment 10
<location> `core/database/foxx/api/models/repositories/base_repository.js:73-80` </location>
<code_context>
        if (key_defined && id_defined) {
            if (config.id !== `repo/${config.key}`) {
                return Result.err({
                    code: error.ERR_INVALID_PARAM,
                    message: `BaseRepository - provided key ${config.key} is in conflict with id ${config.id}.`,
                });
            }
        }

</code_context>

<issue_to_address>
**suggestion (code-quality):** Merge nested if conditions ([`merge-nested-ifs`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/merge-nested-ifs))

```suggestion
        if (key_defined && id_defined && config.id !== `repo/${config.key}`) {
              return Result.err({
                  code: error.ERR_INVALID_PARAM,
                  message: `BaseRepository - provided key ${config.key} is in conflict with id ${config.id}.`,
              });
        }

```

<br/><details><summary>Explanation</summary>Reading deeply nested conditional code is confusing, since you have to keep track of which
conditions relate to which levels. We therefore strive to reduce nesting where
possible, and the situation where two `if` conditions can be combined using
`and` is an easy win.
</details>
</issue_to_address>

### Comment 11
<location> `core/database/foxx/api/models/repositories/repository/globus.js:128` </location>
<code_context>
            const task = taskResult.task;

</code_context>

<issue_to_address>
**suggestion (code-quality):** Prefer object destructuring when accessing and using properties. ([`use-object-destructuring`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/use-object-destructuring))

```suggestion
            const {task} = taskResult;
```

<br/><details><summary>Explanation</summary>Object destructuring can often remove an unnecessary temporary reference, as well as making your code more succinct.

From the [Airbnb Javascript Style Guide](https://airbnb.io/javascript/#destructuring--object)
</details>
</issue_to_address>

### Comment 12
<location> `core/database/foxx/api/models/repositories/repository/metadata.js:95-98` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Use `const` or `let` instead of `var`. ([`avoid-using-var`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-using-var))

<details><summary>Explanation</summary>`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code).
`let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than
function-scoped.

From the [Airbnb JavaScript Style Guide](https://airbnb.io/javascript/#references--prefer-const)
</details>
</issue_to_address>

### Comment 13
<location> `core/database/foxx/api/models/repositories/repository/metadata.js:169` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Use `const` or `let` instead of `var`. ([`avoid-using-var`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-using-var))

<details><summary>Explanation</summary>`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code).
`let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than
function-scoped.

From the [Airbnb JavaScript Style Guide](https://airbnb.io/javascript/#references--prefer-const)
</details>
</issue_to_address>

### Comment 14
<location> `core/database/foxx/api/models/repositories/repository/metadata.js:208-216` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Use `const` or `let` instead of `var`. ([`avoid-using-var`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-using-var))

<details><summary>Explanation</summary>`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code).
`let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than
function-scoped.

From the [Airbnb JavaScript Style Guide](https://airbnb.io/javascript/#references--prefer-const)
</details>
</issue_to_address>

### Comment 15
<location> `core/database/foxx/api/repo_router.js:115-123` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Use `const` or `let` instead of `var`. ([`avoid-using-var`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-using-var))

<details><summary>Explanation</summary>`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code).
`let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than
function-scoped.

From the [Airbnb JavaScript Style Guide](https://airbnb.io/javascript/#references--prefer-const)
</details>
</issue_to_address>

### Comment 16
<location> `core/database/foxx/api/repo_router.js:147` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Use `const` or `let` instead of `var`. ([`avoid-using-var`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-using-var))

<details><summary>Explanation</summary>`const` is preferred as it ensures you cannot reassign references (which can lead to buggy and confusing code).
`let` may be used if you need to reassign references - it's preferred to `var` because it is block- rather than
function-scoped.

From the [Airbnb JavaScript Style Guide](https://airbnb.io/javascript/#references--prefer-const)
</details>
</issue_to_address>

### Comment 17
<location> `core/database/foxx/tests/base_repository.test.js:29-37` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

### Comment 18
<location> `core/database/foxx/tests/base_repository.test.js:38-46` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

### Comment 19
<location> `core/database/foxx/tests/base_repository.test.js:47-53` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

### Comment 20
<location> `core/database/foxx/tests/repo_globus.test.js:38-50` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

### Comment 21
<location> `core/database/foxx/tests/repo_globus.test.js:52-64` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

### Comment 22
<location> `core/database/foxx/tests/repo_globus.test.js:66-75` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

### Comment 23
<location> `core/database/foxx/tests/repo_globus.test.js:77-86` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

### Comment 24
<location> `core/database/foxx/tests/repo_globus.test.js:88-97` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

### Comment 25
<location> `core/database/foxx/tests/repo_globus.test.js:99-111` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

### Comment 26
<location> `core/database/foxx/tests/repo_globus.test.js:113-119` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

### Comment 27
<location> `core/database/foxx/tests/repo_globus.test.js:121-131` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

### Comment 28
<location> `core/database/foxx/tests/repo_globus.test.js:133-143` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

### Comment 29
<location> `core/database/foxx/tests/repo_metadata.test.js:26-33` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

### Comment 30
<location> `core/database/foxx/tests/repo_metadata.test.js:35-40` </location>
<code_context>

</code_context>

<issue_to_address>
**issue (code-quality):** Avoid function declarations, favouring function assignment expressions, inside blocks. ([`avoid-function-declarations-in-blocks`](https://docs.sourcery.ai/Reference/Rules-and-In-Line-Suggestions/JavaScript/Default-Rules/avoid-function-declarations-in-blocks))

<details><summary>Explanation</summary>Function declarations may be hoisted in Javascript, but the behaviour is inconsistent between browsers.
Hoisting is generally confusing and should be avoided. Rather than using function declarations inside blocks, you
should use function expressions, which create functions in-scope.
</details>
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines 143 to 145
];

var idx = obj.path.lastIndexOf("/", obj.path.length - 2);
if (obj.path.substr(idx + 1, obj.path.length - idx - 2) != obj._key)
throw [
error.ERR_INVALID_PARAM,
"Last part of repository path must be repository ID suffix (" +
obj._key +
")",
];
if (!obj.path.endsWith("/")) obj.path += "/";
Copy link
Contributor

Choose a reason for hiding this comment

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

issue (bug_risk): Potential bug: appending '/' to obj.path instead of obj.exp_path.

Please check if '/' should be appended to exp_path instead of path to avoid incorrect path assignment.

Comment on lines 43 to 44
if (new.target === BaseRepository) {
return Result.err({
Copy link
Contributor

Choose a reason for hiding this comment

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

issue (bug_risk): Returning Result.err from constructor may break subclass instantiation expectations.

Throwing an error or using a factory method is preferable for enforcing abstract class constraints, as returning a value from a constructor is non-standard and may cause issues with subclassing.

@JoshuaSBrown JoshuaSBrown force-pushed the 1705-DAPS-feature-foxx-integrate-metadata-globus-factory-repo-router-create branch from 7e27a13 to d1e5c1f Compare October 22, 2025 19:49
@JoshuaSBrown JoshuaSBrown changed the base branch from devel to master October 22, 2025 20:24
@JoshuaSBrown JoshuaSBrown changed the base branch from master to devel October 22, 2025 20:25
@JoshuaSBrown JoshuaSBrown self-assigned this Oct 22, 2025
@JoshuaSBrown JoshuaSBrown requested a review from nedvedba October 22, 2025 20:26
@JoshuaSBrown JoshuaSBrown added the Component: Foxx Foxx Arango micro services. label Oct 22, 2025
@JoshuaSBrown JoshuaSBrown force-pushed the 1705-DAPS-feature-foxx-integrate-metadata-globus-factory-repo-router-create branch from adb1bb0 to 3caf6ca Compare October 23, 2025 00:46
@JoshuaSBrown JoshuaSBrown merged commit c70b4a7 into devel Oct 23, 2025
4 checks passed
@JoshuaSBrown JoshuaSBrown deleted the 1705-DAPS-feature-foxx-integrate-metadata-globus-factory-repo-router-create branch October 23, 2025 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component: Foxx Foxx Arango micro services.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant