1. Overview

This service provides functionalities related to repository management, including plans, usage tracking, and user interactions. The following sections detail the available API endpoints, their request/response structures, and the internal logic.

2. Libraries and Dependencies

This section lists the common libraries and dependencies used throughout the service. Route-specific dependencies will be detailed in their respective sections.

  • @google-cloud/functions-framework: Framework for running Google Cloud Functions.

  • @google-cloud/storage: Google Cloud Storage client library.

  • @google-cloud/trace-agent: Google Cloud Trace agent for Node.js.

  • @nimbly-technologies/entity-node: Library for defining and managing entities in Node.js.

  • @nimbly-technologies/nimbly-backend-utils: Backend utilities for Nimbly projects.

  • @nimbly-technologies/nimbly-common: Common utilities for Nimbly projects.

  • @sendgrid/mail: SendGrid library for sending emails.

  • archiver: Library for creating archive files (zip, tar, etc.).

  • cors: Middleware for enabling Cross-Origin Resource Sharing (CORS).

  • dotenv: Loads environment variables from a .env file.

  • express: Fast, unopinionated, minimalist web framework for Node.js.

  • express-http-context: Middleware for accessing request-scoped context.

  • firebase-admin: Firebase Admin SDK for Node.js.

  • google-auth-library: Google authentication library for Node.js.

  • joi: Object schema validation library.

  • mongoose: MongoDB object modeling tool designed to work in an asynchronous environment.

  • prettier: Opinionated code formatter.

  • uuidv4: Library for generating UUID version 4.

Dev Dependencies

  • @types/archiver: TypeScript definitions for archiver.

  • @types/cors: TypeScript definitions for cors.

  • @types/express: TypeScript definitions for express.

  • @types/jest: TypeScript definitions for jest.

  • @types/mongoose: TypeScript definitions for mongoose.

  • @typescript-eslint/eslint-plugin: ESLint plugin for TypeScript.

  • @typescript-eslint/parser: ESLint parser for TypeScript.

  • eslint: JavaScript linting tool.

  • husky: Git hooks made easy.

  • jest: JavaScript testing framework.

  • nodemon: Utility that automatically restarts the server when file changes are detected.

  • typescript: TypeScript language.

3. API Endpoint Summary

HTTP MethodPathShort Description
GET/pingChecks the connectivity of the service.
GET/signedUploadURLGenerates a pre-signed URL for direct file uploads.
GET/resumableSignedUploadURLGenerates a pre-signed URL for resumable file uploads.
GET/autoCompleteProvides auto-completion suggestions for repository entities.
POST/Creates a new repository entity.
GET/Retrieves repository entities based on query parameters.
GET/foldersLists all folders within the repository.
PUT/Updates an existing repository entity.
PUT/sideEffectTriggers a side effect related to an update operation.
POST/downloadDownloads specified repository entities.
POST/planCreates a new repository plan.
PUT/plan/:idUpdates an existing repository plan.
POST/trackerCreates a new repository usage tracker.
PUT/tracker/:organizationIDUpdates an existing repository usage tracker.
GET/tracker/:organizationIDRetrieves a repository usage tracker for an organization.
GET/userFinds repository data for the authenticated user.
POST/userCreates repository data for the authenticated user.
PUT/userUpdates repository data for the authenticated user.
GET/user/allRetrieves storage data details for all users.

4. Repository Routes (/)

The routes defined in src/routes/repository.route.ts manage operations related to file and folder entities within a repository concept. These operations include creating, retrieving, updating, and managing files, as well as generating secure URLs for uploads and downloads.

All routes in this module are protected by AuthMiddleware, ensuring that only authenticated users can access these functionalities. JWT (JSON Web Tokens) are used for verifying user authentication.

Input validation for these routes is handled by validatorHandler middleware, utilizing schemas defined in fileRepositoryValidator. This ensures that incoming requests meet the required data structure and type specifications before being processed by the controllers.

The primary controller responsible for handling the logic for these routes is the storageController, which is instantiated via makeDomains().

4.1. GET /signedUploadURL

Description: Generates a pre-signed URL that can be used for direct, secure file uploads to a storage service (e.g., S3, Google Cloud Storage). This URL is typically short-lived and grants temporary write access to a specific storage location.

Request Validation:

  • Uses fileRepositoryValidator with the getSignedURL schema. This schema likely expects parameters such as fileName, fileType, and potentially repositoryId or path to determine where the file should be stored.

Authentication:

Core Logic Flow:

  1. Request is received by the Express application.
  2. AuthMiddleware verifies the JWT token from the request headers.
  3. validatorHandler middleware validates the request query parameters using the getSignedURL schema from fileRepositoryValidator.
  4. The request is passed to the storageController.generateUploadURL method.
  5. The storageController.generateUploadURL method interacts with an underlying storage service (e.g., AWS S3 SDK, Google Cloud Storage SDK) to request a pre-signed URL for an HTTP PUT operation. It typically provides the bucket name, object key (derived from fileName and path), content type, and an expiration time for the URL.
  6. The storage service returns the pre-signed URL.
  7. The storageController returns this URL, which is then sent back to the client via expressMiddlewareHandler.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant StorageController
    participant StorageService

    Client->>API Gateway: GET /signedUploadURL?fileName=example.jpg&fileType=image/jpeg
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Parameters (schema: getSignedURL)
    Validator-->>API Gateway: Parameters Valid
    API Gateway->>StorageController: generateUploadURL(fileName, fileType)
    StorageController->>StorageService: Request PUT pre-signed URL (for example.jpg)
    StorageService-->>StorageController: Return pre-signed URL
    StorageController-->>API Gateway: { signedUrl: "..." }
    API Gateway-->>Client: HTTP 200 OK { signedUrl: "..." }

Key Dependencies/Modules:

  • express.Router: For route definition.
  • jsonwebtoken: Used by AuthMiddleware for token verification.
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares: Provides AuthMiddleware, expressMiddlewareHandler, validatorHandler.
  • ./domain: Specifically makeDomains() which provides storageController.
  • ./validators/file.repository.validator: Provides the getSignedURL validation schema.

Code Snippet (Route Definition):

// From src/routes/repository.route.ts
router.get(
    '/signedUploadURL',
    validatorHandler(fileRepositoryValidator, 'getSignedURL'),
    expressMiddlewareHandler(storageController.generateUploadURL),
);

Notes:

  • The generated URL is for a PUT request. The client is expected to use this URL to upload the file directly to the storage service.
  • Pre-signed URLs are a security best practice as they limit exposure of storage credentials.

4.2. GET /resumableSignedUploadURL

Description: Generates a pre-signed URL specifically for initiating or continuing resumable file uploads. This is useful for large files, allowing uploads to be paused and resumed.

Request Validation:

  • Uses fileRepositoryValidator with the getResumableSignedURL schema. Expected parameters likely include fileName, fileType, fileSize, and potentially an uploadId if resuming an existing upload.

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication).

Core Logic Flow:

  1. Request is received.
  2. AuthMiddleware verifies the JWT.
  3. validatorHandler validates request parameters using the getResumableSignedURL schema.
  4. The request is passed to storageController.generateResumableUploadURL.
  5. The storageController.generateResumableUploadURL method interacts with the storage service to obtain a URL that can be used to initiate a resumable upload session (e.g., for Google Cloud Storage) or to get URLs for uploading parts of a multipart upload (e.g., for AWS S3).
  6. The controller returns the necessary URL(s) or session ID to the client.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant StorageController
    participant StorageService

    Client->>API Gateway: GET /resumableSignedUploadURL?fileName=large_video.mp4&fileType=video/mp4&fileSize=104857600
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Parameters (schema: getResumableSignedURL)
    Validator-->>API Gateway: Parameters Valid
    API Gateway->>StorageController: generateResumableUploadURL(params)
    StorageController->>StorageService: Initiate Resumable Upload Session / Request Part URLs
    StorageService-->>StorageController: Return Session URL / Part URLs
    StorageController-->>API Gateway: Response (e.g., { uploadUrl: "..." } or { uploadId: "...", partUrls: [...] })
    API Gateway-->>Client: HTTP Response

Key Dependencies/Modules:

  • express.Router
  • jsonwebtoken
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares
  • ./domain (storageController)
  • ./validators/file.repository.validator (getResumableSignedURL schema)

Code Snippet (Route Definition):

// From src/routes/repository.route.ts
router.get(
    '/resumableSignedUploadURL',
    validatorHandler(fileRepositoryValidator, 'getResumableSignedURL'),
    expressMiddlewareHandler(storageController.generateResumableUploadURL),
);

Notes:

  • The exact mechanism for resumable uploads varies between storage providers (e.g., Tus protocol, S3 Multipart Upload, GCS Resumable Uploads). The controller abstracts this complexity.

4.3. GET /autoComplete

Description: Provides auto-completion suggestions for repository entities (files, folders) based on a query string. Useful for search bars or predictive input fields.

Request Validation:

  • Uses fileRepositoryValidator with the autoComplete schema. This likely expects a query or prefix parameter.

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication).

Core Logic Flow:

  1. Request is received.
  2. AuthMiddleware verifies JWT.
  3. validatorHandler validates request parameters using the autoComplete schema.
  4. Request is passed to storageController.search.
  5. The storageController.search method queries a data store (e.g., database, search index like Elasticsearch) for entities matching the provided query/prefix, likely scoped to the authenticated user’s accessible repositories or current context.
  6. The controller returns a list of suggestions.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant StorageController
    participant DataStore 

    Client->>API Gateway: GET /autoComplete?query=doc
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Parameters (schema: autoComplete)
    Validator-->>API Gateway: Parameters Valid
    API Gateway->>StorageController: search(query="doc")
    StorageController->>DataStore: Query for entities matching "doc"
    DataStore-->>StorageController: Return matching entities
    StorageController-->>API Gateway: Response (e.g., [{ name: "document1.pdf", type: "file"}, { name: "docs_folder", type: "folder"}])
    API Gateway-->>Client: HTTP Response

Key Dependencies/Modules:

  • express.Router
  • jsonwebtoken
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares
  • ./domain (storageController)
  • ./validators/file.repository.validator (autoComplete schema)

Code Snippet (Route Definition):

// From src/routes/repository.route.ts
router.get(
    '/autoComplete',
    validatorHandler(fileRepositoryValidator, 'autoComplete'),
    expressMiddlewareHandler(storageController.search),
);

Notes:

  • Performance is key for auto-completion. The storageController.search method should be optimized for fast lookups.

4.4. POST /

Description: Creates a new repository entity, which could be a file metadata entry or a folder.

Request Validation:

  • Uses fileRepositoryValidator with the create schema. The schema likely expects parameters such as name, type (file/folder), parentId (for nesting), mimeType, size, etc.

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication).

Core Logic Flow:

  1. Request with entity data in the body is received.
  2. AuthMiddleware verifies JWT.
  3. validatorHandler validates the request body using the create schema.
  4. Request is passed to storageController.create.
  5. The storageController.create method interacts with a database or metadata store to create a new record for the file or folder. It may also involve interactions with the actual file storage system if file metadata is tied to an existing (but unreferenced) uploaded file.
  6. The controller returns details of the created entity.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant StorageController
    participant DataStore 

    Client->>API Gateway: POST / (Body: { name: "new_folder", type: "folder", parentId: "root" })
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Body (schema: create)
    Validator-->>API Gateway: Body Valid
    API Gateway->>StorageController: create(entityData)
    StorageController->>DataStore: Insert new entity record
    DataStore-->>StorageController: Return created entity details
    StorageController-->>API Gateway: Response (e.g., { id: "xyz123", name: "new_folder", ... })
    API Gateway-->>Client: HTTP 201 Created

Key Dependencies/Modules:

  • express.Router
  • jsonwebtoken
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares
  • ./domain (storageController)
  • ./validators/file.repository.validator (create schema)

Code Snippet (Route Definition):

// From src/routes/repository.route.ts
router.post(
    '/',
    validatorHandler(fileRepositoryValidator, 'create'),
    expressMiddlewareHandler(storageController.create),
);

Notes:

  • This endpoint typically creates metadata. The actual file upload might be a separate step using /signedUploadURL.

4.5. GET /

Description: Retrieves a list of repository entities (files, folders) based on query parameters. This allows for filtering, pagination, and sorting.

Request Validation:

  • Uses fileRepositoryValidator with the getAll schema. Expected parameters could include parentId (to list contents of a folder), page, limit, sortBy, filterByType, etc.

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication).

Core Logic Flow:

  1. Request with query parameters is received.
  2. AuthMiddleware verifies JWT.
  3. validatorHandler validates query parameters using the getAll schema.
  4. Request is passed to storageController.getAll.
  5. The storageController.getAll method queries the data store based on the provided filters and pagination parameters, scoped to the user’s access.
  6. The controller returns a list of entities and potentially pagination metadata.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant StorageController
    participant DataStore 

    Client->>API Gateway: GET /?parentId=xyz123&page=1&limit=20
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Parameters (schema: getAll)
    Validator-->>API Gateway: Parameters Valid
    API Gateway->>StorageController: getAll(queryParams)
    StorageController->>DataStore: Query entities (filter by parentId, paginate)
    DataStore-->>StorageController: Return list of entities and pagination info
    StorageController-->>API Gateway: Response (e.g., { data: [...], total: 100, page: 1 })
    API Gateway-->>Client: HTTP 200 OK

Key Dependencies/Modules:

  • express.Router
  • jsonwebtoken
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares
  • ./domain (storageController)
  • ./validators/file.repository.validator (getAll schema)

Code Snippet (Route Definition):

// From src/routes/repository.route.ts
router.get(
    '/',
    validatorHandler(fileRepositoryValidator, 'getAll'),
    expressMiddlewareHandler(storageController.getAll),
);

Notes:

  • Proper indexing on the fields used for filtering (like parentId, type) is crucial for performance.

4.6. GET /folders

Description: Specifically lists all folders within the repository, possibly in a hierarchical or flat structure.

Request Validation:

  • Uses fileRepositoryValidator with the getFolders schema. This might expect parameters like parentId or recursive (boolean).

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication).

Core Logic Flow:

  1. Request is received.
  2. AuthMiddleware verifies JWT.
  3. validatorHandler validates request parameters using the getFolders schema.
  4. Request is passed to storageController.getFolders.
  5. The storageController.getFolders method queries the data store for entities of type ‘folder’, applying any specified filters (e.g., parent folder, recursive depth).
  6. The controller returns a list of folder entities.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant StorageController
    participant DataStore 

    Client->>API Gateway: GET /folders?parentId=abc987
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Parameters (schema: getFolders)
    Validator-->>API Gateway: Parameters Valid
    API Gateway->>StorageController: getFolders(queryParams)
    StorageController->>DataStore: Query for folder entities (filter by parentId)
    DataStore-->>StorageController: Return list of folder entities
    StorageController-->>API Gateway: Response (e.g., [{ id: "folder1", name: "Project A"}, ...])
    API Gateway-->>Client: HTTP 200 OK

Key Dependencies/Modules:

  • express.Router
  • jsonwebtoken
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares
  • ./domain (storageController)
  • ./validators/file.repository.validator (getFolders schema)

Code Snippet (Route Definition):

// From src/routes/repository.route.ts
router.get(
    '/folders',
    validatorHandler(fileRepositoryValidator, 'getFolders'),
    expressMiddlewareHandler(storageController.getFolders),
);

Notes:

  • This endpoint is a specialized version of GET / for retrieving only folders, potentially optimized for this purpose.

4.7. PUT /

Description: Updates an existing repository entity (e.g., renaming a file or folder, moving it, updating metadata).

Request Validation:

  • Uses fileRepositoryValidator with the update schema. This schema likely requires an id of the entity to update, along with fields to be modified (e.g., name, parentId, description).

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication).

Core Logic Flow:

  1. Request with entity ID and update data in the body is received.
  2. AuthMiddleware verifies JWT.
  3. validatorHandler validates the request body using the update schema.
  4. Request is passed to storageController.update.
  5. The storageController.update method finds the entity by its ID in the data store and applies the updates. This might involve checks for naming conflicts or valid parent IDs if moving an entity.
  6. The controller returns the updated entity details.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant StorageController
    participant DataStore 

    Client->>API Gateway: PUT / (Body: { id: "file123", name: "new_document_name.docx" })
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Body (schema: update)
    Validator-->>API Gateway: Body Valid
    API Gateway->>StorageController: update(entityId, updateData)
    StorageController->>DataStore: Find entity by ID and update its attributes
    DataStore-->>StorageController: Return updated entity details
    StorageController-->>API Gateway: Response (e.g., { id: "file123", name: "new_document_name.docx", ... })
    API Gateway-->>Client: HTTP 200 OK

Key Dependencies/Modules:

  • express.Router
  • jsonwebtoken
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares
  • ./domain (storageController)
  • ./validators/file.repository.validator (update schema)

Code Snippet (Route Definition):

// From src/routes/repository.route.ts
router.put(
    '/',
    validatorHandler(fileRepositoryValidator, 'update'),
    expressMiddlewareHandler(storageController.update),
);

Notes:

  • Operations like moving a folder might trigger cascading updates or checks, which should be handled by the controller.

4.8. PUT /sideEffect

Description: Triggers a side effect related to an update operation. This is a less common pattern and might be used for operations that are not direct CRUD actions but are related to an entity’s state change (e.g., triggering a webhook, starting a processing job after an update).

Request Validation:

  • Uses fileRepositoryValidator with the sideEffect schema. The schema would define the parameters needed to identify the entity and the nature of the side effect.

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication).

Core Logic Flow:

  1. Request with data in the body is received.
  2. AuthMiddleware verifies JWT.
  3. validatorHandler validates the request body using the sideEffect schema.
  4. Request is passed to storageController.sideEffect.
  5. The storageController.sideEffect method performs the specified side effect. This could involve interacting with other services, queuing a task, or updating related data.
  6. The controller returns a status or result of the side effect operation.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant StorageController
    participant OtherService 

    Client->>API Gateway: PUT /sideEffect (Body: { entityId: "file456", action: "notifyTeam" })
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Body (schema: sideEffect)
    Validator-->>API Gateway: Body Valid
    API Gateway->>StorageController: sideEffect(params)
    StorageController->>OtherService: Trigger action (e.g., send notification, enqueue job)
    OtherService-->>StorageController: Acknowledge / Result
    StorageController-->>API Gateway: Response (e.g., { status: "success", message: "Team notified" })
    API Gateway-->>Client: HTTP 200 OK

Key Dependencies/Modules:

  • express.Router
  • jsonwebtoken
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares
  • ./domain (storageController)
  • ./validators/file.repository.validator (sideEffect schema)

Code Snippet (Route Definition):

// From src/routes/repository.route.ts
router.put(
    '/sideEffect',
    validatorHandler(fileRepositoryValidator, 'sideEffect'),
    expressMiddlewareHandler(storageController.sideEffect),
);

Notes:

  • This endpoint should be used for actions that are asynchronous or don’t fit neatly into standard CRUD updates.

4.9. POST /download

Description: Downloads specified repository entities. This could involve generating temporary download links or streaming file content.

Request Validation:

  • Uses fileRepositoryValidator with the download schema. This likely expects a list of entity IDs (ids) or other identifiers for the files/folders to be downloaded.

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication).

Core Logic Flow:

  1. Request with entity IDs in the body is received.
  2. AuthMiddleware verifies JWT.
  3. validatorHandler validates the request body using the download schema.
  4. Request is passed to storageController.download.
  5. The storageController.download method processes the request. This could involve: a. For single files: Generating a pre-signed GET URL from the storage service. b. For multiple files/folders: Potentially zipping them on the fly and providing a stream or a link to the generated archive.
  6. The controller returns the download link(s) or streams the file(s).

Mermaid Diagram (Illustrative Flow - Single File Download via Pre-signed URL):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant StorageController
    participant StorageService

    Client->>API Gateway: POST /download (Body: { ids: ["file789.txt"] })
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Body (schema: download)
    Validator-->>API Gateway: Body Valid
    API Gateway->>StorageController: download({ ids: ["file789.txt"] })
    StorageController->>StorageService: Request GET pre-signed URL for file789.txt
    StorageService-->>StorageController: Return pre-signed URL
    StorageController-->>API Gateway: Response (e.g., { downloadUrl: "..." })
    API Gateway-->>Client: HTTP 200 OK (Client then uses this URL to download)

Mermaid Diagram (Illustrative Flow - Multiple Files Zipped):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant StorageController
    participant FileArchiver // Internal component for zipping
    participant StorageService

    Client->>API Gateway: POST /download (Body: { ids: ["file1", "folderA"] })
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Body (schema: download)
    Validator-->>API Gateway: Body Valid
    API Gateway->>StorageController: download({ ids: ["file1", "folderA"] })
    StorageController->>StorageService: Fetch file metadata/locations
    StorageService-->>StorageController: File details
    StorageController->>FileArchiver: Create archive with specified files/folders
    FileArchiver-->>StorageController: Archive stream / temporary archive URL
    StorageController-->>API Gateway: Stream archive / provide URL
    API Gateway-->>Client: HTTP 200 OK (Streaming data or JSON with URL)

Key Dependencies/Modules:

  • express.Router
  • jsonwebtoken
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares
  • ./domain (storageController)
  • ./validators/file.repository.validator (download schema)
  • Potentially a library for creating zip archives (e.g., archiver).

Code Snippet (Route Definition):

// From src/routes/repository.route.ts
router.post(
    '/download',
    validatorHandler(fileRepositoryValidator, 'download'),
    expressMiddlewareHandler(storageController.download),
);

Notes:

  • Downloading multiple files or large folders can be resource-intensive if archives are generated on-the-fly. This might be handled by background jobs for very large requests.
  • Security considerations for download URLs (e.g., expiration, one-time use) are important.

5. Repository Plan Routes (/plan)

The routes defined in src/routes/repository.plan.route.ts are responsible for managing repository plans. These plans likely define different tiers of service, storage quotas, feature access, or other configurable parameters for repositories.

All routes within this module are secured using AuthMiddleware, which implies JWT-based authentication for all plan management operations. Incoming request data is validated by the validatorHandler middleware, which uses schemas defined in fileRepositoryPlanValidator. The core business logic for these routes is handled by the repositoryPlanController, provided via the makeDomains() factory.


5.1. POST /plan

Description: This endpoint allows for the creation of a new repository plan with specified attributes. It is used to define new service tiers or configurations that can be applied to repositories.

Request Validation:

  • Uses fileRepositoryPlanValidator with the schema key ‘create’.
  • Expected parameters likely include: name (string, e.g., “Basic”, “Premium”), storageLimit (number, in bytes or GB), featureFlags (object or array, e.g., { “customDomains”: true, “advancedAnalytics”: false }), price (number), billingCycle (string, e.g., “monthly”, “annually”).

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication).

Core Logic Flow:

  1. Request is received by the Express application.
  2. AuthMiddleware verifies the JWT token from the request headers.
  3. validatorHandler middleware validates the request body using the create schema from fileRepositoryPlanValidator.
  4. The request is then passed to the repositoryPlanController.create method.
  5. The repositoryPlanController.create method processes the validated data. This typically involves interacting with a database (e.g., via a service layer or ORM) to store the new plan’s details, ensuring that plan names or other unique identifiers are not duplicated.
  6. The controller’s response, usually containing the newly created plan details (including its generated ID), is returned to the client via expressMiddlewareHandler.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant RepositoryPlanController
    participant PlanServiceOrDB 

    Client->>API Gateway: POST /plan (Body: { name: "Pro Plan", storageLimit: 100, ... })
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Body (schema: create)
    Validator-->>API Gateway: Parameters Valid
    API Gateway->>RepositoryPlanController: create(planData)
    RepositoryPlanController->>PlanServiceOrDB: Create Plan (name: "Pro Plan", ...)
    PlanServiceOrDB-->>RepositoryPlanController: Return Confirmation/Result (e.g., new plan object with ID)
    RepositoryPlanController-->>API Gateway: Response (e.g., { id: "plan_abc123", name: "Pro Plan", ... })
    API Gateway-->>Client: HTTP 201 Created

Key Dependencies/Modules:

  • express.Router: For route definition.
  • jsonwebtoken: Used by AuthMiddleware for token verification.
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares: Provides AuthMiddleware, expressMiddlewareHandler, validatorHandler.
  • ./domain: Specifically makeDomains() which provides repositoryPlanController.
  • ./validators/file.repository.plan.validator: Provides the create validation schema.

Code Snippet (Route Definition):

// From src/routes/repository.plan.route.ts
router.post(
    '/', // Corresponds to /plan due to router mounting
    validatorHandler(fileRepositoryPlanValidator, 'create'),
    expressMiddlewareHandler(repositoryPlanController.create),
);

Notes:

  • The comment // TODO validation middleware in the original repository.plan.route.ts for the POST route seems outdated, as validatorHandler is indeed used.
  • Plan creation should be an idempotent operation if possible, or at least handle potential duplicate creations gracefully (e.g., based on plan name).

5.2. PUT /plan/:id

Description: This endpoint is used to update an existing repository plan, identified by its unique id. This allows modification of attributes like storage limits, features, or pricing for a specific plan.

Request Validation:

  • Uses fileRepositoryPlanValidator with the schema key ‘update’.
  • The id of the plan to update is passed as a URL parameter.
  • The request body is expected to contain the fields to be updated, e.g., name, storageLimit, featureFlags, price. Not all fields may be required; only provided fields are typically updated.

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication).

Core Logic Flow:

  1. Request is received by the Express application, including the plan id in the URL path.
  2. AuthMiddleware verifies the JWT token.
  3. validatorHandler middleware validates the request body (for updatable fields) and URL parameters (for the id) using the update schema from fileRepositoryPlanValidator.
  4. The request is then passed to the repositoryPlanController.update method, with both the id and the update payload.
  5. The repositoryPlanController.update method first attempts to retrieve the existing plan by its id from the database. If found, it applies the validated changes to the plan’s attributes and saves the updates back to the database.
  6. The controller’s response, typically the updated plan details or a success confirmation, is returned to the client via expressMiddlewareHandler.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant RepositoryPlanController
    participant PlanServiceOrDB 

    Client->>API Gateway: PUT /plan/plan_abc123 (Body: { storageLimit: 150 })
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request (params: id='plan_abc123', body, schema: update)
    Validator-->>API Gateway: Parameters Valid
    API Gateway->>RepositoryPlanController: update(id='plan_abc123', updateData)
    RepositoryPlanController->>PlanServiceOrDB: Fetch Plan (id='plan_abc123')
    PlanServiceOrDB-->>RepositoryPlanController: Return Existing Plan
    RepositoryPlanController->>PlanServiceOrDB: Update Plan (id='plan_abc123', changes={storageLimit: 150})
    PlanServiceOrDB-->>RepositoryPlanController: Return Confirmation/Result (e.g., updated plan object)
    RepositoryPlanController-->>API Gateway: Response (e.g., { id: "plan_abc123", storageLimit: 150, ... })
    API Gateway-->>Client: HTTP 200 OK

Key Dependencies/Modules:

  • express.Router: For route definition.
  • jsonwebtoken: Used by AuthMiddleware for token verification.
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares: Provides AuthMiddleware, expressMiddlewareHandler, validatorHandler.
  • ./domain: Specifically makeDomains() which provides repositoryPlanController.
  • ./validators/file.repository.plan.validator: Provides the update validation schema.

Code Snippet (Route Definition):

// From src/routes/repository.plan.route.ts
router.put(
    '/:id', // Corresponds to /plan/:id
    validatorHandler(fileRepositoryPlanValidator, 'update'),
    expressMiddlewareHandler(repositoryPlanController.update),
);

Notes:

  • It’s important to handle cases where the plan id does not exist (the controller should return a 404 Not Found error).
  • Consideration should be given to how plan updates affect existing repositories using that plan. This might involve versioning plans or applying changes selectively.

6. Repository Usage Tracker Routes (/tracker)

The routes defined in src/routes/respository.usage.tracker.ts (note the typo “respository” in the filename) are dedicated to managing and retrieving usage tracking information for organizations. This typically involves monitoring resource consumption (e.g., storage used, number of operations) against defined limits.

All routes in this module are protected by AuthMiddleware, ensuring that only authenticated users can access these functionalities. JWT (JSON Web Tokens) are used for verifying user authentication.

Input validation for these routes is handled by the validatorHandler middleware, utilizing schemas defined in fileRepositoryUsageTrackerValidator. This ensures that incoming requests meet the required data structure and type specifications before being processed by the repositoryUsageTrackerController, which is provided via makeDomains().


6.1. POST /tracker

Description: This endpoint allows for the creation of a new usage tracker record for an organization. It’s typically used to initialize tracking when an organization is provisioned or a new tracking period begins.

Request Validation:

  • Uses fileRepositoryUsageTrackerValidator with the schema key ‘create’.
  • Expected parameters in the request body likely include: organizationID (string, identifier for the organization), usageLimit (number, e.g., maximum storage in GB, max API calls), currentUsage (number, initial usage, often 0).

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication).

Core Logic Flow:

  1. Request is received by the Express application.
  2. AuthMiddleware verifies the JWT token from the request headers.
  3. validatorHandler middleware validates the request body using the create schema from fileRepositoryUsageTrackerValidator.
  4. The request is then passed to the repositoryUsageTrackerController.create method.
  5. The repositoryUsageTrackerController.create method interacts with a data store (e.g., a database) to create a new usage tracking record for the specified organizationID with the provided usageLimit and currentUsage. It would typically check if a tracker already exists for the organization to prevent duplicates, or handle such cases as an update if appropriate.
  6. The controller’s response, usually containing the newly created usage tracker details, is returned to the client via expressMiddlewareHandler.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant RepositoryUsageTrackerController
    participant UsageDataStore // Abstracted data store

    Client->>API Gateway: POST /tracker (Body: { organizationID: "org123", usageLimit: 1000, currentUsage: 0 })
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Body (schema: create)
    Validator-->>API Gateway: Parameters Valid
    API Gateway->>RepositoryUsageTrackerController: create(trackerData)
    RepositoryUsageTrackerController->>UsageDataStore: Create Usage Record (organizationID: "org123", ...)
    UsageDataStore-->>RepositoryUsageTrackerController: Return Confirmation/Created Record
    RepositoryUsageTrackerController-->>API Gateway: Response (e.g., { id: "tracker_xyz", organizationID: "org123", ... })
    API Gateway-->>Client: HTTP 201 Created

Key Dependencies/Modules:

  • express.Router: For route definition.
  • jsonwebtoken: Used by AuthMiddleware for token verification.
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares: Provides AuthMiddleware, expressMiddlewareHandler, validatorHandler.
  • ./domain: Specifically makeDomains() which provides repositoryUsageTrackerController.
  • ./validators/file.repository.tracker.validator: Provides the create validation schema. (Note: filename in source is file.repository.tracker.validator.ts vs file.repository.usage.tracker.validator.ts in instructions, assuming the former based on typical naming).

Code Snippet (Route Definition):

// From src/routes/respository.usage.tracker.ts
router.post(
    '/', // Corresponds to /tracker
    validatorHandler(fileRepositoryUsageTrackerValidator, 'create'),
    expressMiddlewareHandler(repositoryUsageTrackerController.create),
);

Notes:

  • The comment // TODO validation middleware in the original route definition is outdated as validatorHandler is used.
  • This endpoint is crucial for setting up initial usage parameters for an organization.

6.2. PUT /tracker/:organizationID

Description: This endpoint updates an existing repository usage tracker for a specific organization, identified by organizationID. This is used to modify usage limits or reflect changes in current usage.

Request Validation:

  • Uses fileRepositoryUsageTrackerValidator with the schema key ‘update’.
  • The organizationID is passed as a URL parameter.
  • The request body is expected to contain fields to be updated, such as usageLimit (number) and/or currentUsage (number).

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication).

Core Logic Flow:

  1. Request is received, with organizationID in the URL path and update data in the body.
  2. AuthMiddleware verifies the JWT token.
  3. validatorHandler validates the URL parameters (for organizationID) and the request body using the update schema from fileRepositoryUsageTrackerValidator.
  4. The request is passed to repositoryUsageTrackerController.update.
  5. The repositoryUsageTrackerController.update method uses the organizationID to find the existing usage tracker record in the data store. If found, it applies the updates (e.g., new usageLimit, incremented currentUsage) and saves the changes.
  6. The controller returns the updated usage tracker details or a success confirmation via expressMiddlewareHandler.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant RepositoryUsageTrackerController
    participant UsageDataStore // Abstracted data store

    Client->>API Gateway: PUT /tracker/org123 (Body: { currentUsage: 50 })
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request (params: organizationID='org123', body, schema: update)
    Validator-->>API Gateway: Parameters Valid
    API Gateway->>RepositoryUsageTrackerController: update(organizationID='org123', updateData)
    RepositoryUsageTrackerController->>UsageDataStore: Find and Update Usage Record (organizationID='org123', changes={currentUsage: 50})
    UsageDataStore-->>RepositoryUsageTrackerController: Return Confirmation/Updated Record
    RepositoryUsageTrackerController-->>API Gateway: Response (e.g., { id: "tracker_xyz", organizationID: "org123", currentUsage: 50, ... })
    API Gateway-->>Client: HTTP 200 OK

Key Dependencies/Modules:

  • express.Router
  • jsonwebtoken
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares
  • ./domain (repositoryUsageTrackerController)
  • ./validators/file.repository.tracker.validator (Provides the update validation schema)

Code Snippet (Route Definition):

// From src/routes/respository.usage.tracker.ts
router.put(
    '/:organizationID', // Corresponds to /tracker/:organizationID
    validatorHandler(fileRepositoryUsageTrackerValidator, 'update'),
    expressMiddlewareHandler(repositoryUsageTrackerController.update),
);

Notes:

  • This endpoint is vital for dynamically reflecting resource consumption and for administrative adjustments to usage limits.
  • Error handling for cases where the organizationID does not have an existing tracker (should return 404 Not Found) is important.

6.3. GET /tracker/:organizationID

Description: Retrieves the current repository usage tracker information for a specific organization, identified by organizationID.

Request Validation:

  • Uses fileRepositoryUsageTrackerValidator with the schema key ‘get’.
  • The organizationID is passed as a URL parameter.

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication).

Core Logic Flow:

  1. Request is received with organizationID in the URL path.
  2. AuthMiddleware verifies the JWT token.
  3. validatorHandler validates the URL parameters (specifically organizationID) using the get schema from fileRepositoryUsageTrackerValidator.
  4. The request is passed to repositoryUsageTrackerController.find.
  5. The repositoryUsageTrackerController.find method queries the data store for the usage tracking record associated with the given organizationID.
  6. The controller returns the found usage tracker data (e.g., usageLimit, currentUsage) or an appropriate response if not found, via expressMiddlewareHandler.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant RepositoryUsageTrackerController
    participant UsageDataStore // Abstracted data store

    Client->>API Gateway: GET /tracker/org123
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Parameters (schema: get, params: organizationID='org123')
    Validator-->>API Gateway: Parameters Valid
    API Gateway->>RepositoryUsageTrackerController: find(organizationID='org123')
    RepositoryUsageTrackerController->>UsageDataStore: Find Usage Record (organizationID='org123')
    UsageDataStore-->>RepositoryUsageTrackerController: Return Usage Record Data
    RepositoryUsageTrackerController-->>API Gateway: Response (e.g., { organizationID: "org123", usageLimit: 1000, currentUsage: 50, ... })
    API Gateway-->>Client: HTTP 200 OK

Key Dependencies/Modules:

  • express.Router
  • jsonwebtoken
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares
  • ./domain (repositoryUsageTrackerController)
  • ./validators/file.repository.tracker.validator (Provides the get validation schema)

Code Snippet (Route Definition):

// From src/routes/respository.usage.tracker.ts
router.get(
    '/:organizationID', // Corresponds to /tracker/:organizationID
    validatorHandler(fileRepositoryUsageTrackerValidator, 'get'),
    expressMiddlewareHandler(repositoryUsageTrackerController.find),
);

Notes:

  • This endpoint is used to monitor an organization’s current usage against its limits.
  • Should return a 404 Not Found if no tracker exists for the organizationID.

7. User Repository Routes (/user)

The routes defined in src/routes/repository.user.route.ts are focused on managing and retrieving repository-related data specific to individual users. This includes operations for the authenticated user to manage their own data, as well as an administrative endpoint to view storage data across all users.

All routes in this module are protected by AuthMiddleware, ensuring that only authenticated users can access these functionalities. JWT (JSON Web Tokens) are used for verifying user authentication.

For routes that require input validation (PUT /user and GET /user/all), the validatorHandler middleware is used. This middleware leverages the fileRepositoryValidator instance, which is configured with validation schemas from fileRepositoryUserValidators (as seen in src/routes/index.ts, though the validator file itself is src/validators/file.repository.user.validator.ts). The core business logic for these routes is handled by the userFileRepositoryController, instantiated via makeDomains(). For GET /user and POST /user, explicit validation middleware is not present at the route definition level, and TODO comments indicate this is pending.


7.1. GET /user

Description: Finds and retrieves repository-related data for the currently authenticated user. This could include user-specific settings, associated files/folders, or profile information relevant to the repository system.

Request Validation:

  • An explicit validatorHandler middleware is not present in the route definition. A TODO validation middleware comment exists in the source code.
  • It’s expected that the primary identifier for the user is derived from the authenticated JWT by the AuthMiddleware and subsequently used by the userFileRepositoryController.find method. No explicit request parameters or body are typically needed for this type of GET request for the current user.

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication). The authenticated user’s identity is implicitly available to the controller.

Core Logic Flow:

  1. Request is received by the Express application.
  2. AuthMiddleware verifies the JWT token from the request headers, identifying the authenticated user.
  3. The request is directly passed to the userFileRepositoryController.find method. The controller uses the authenticated user’s context (e.g., user ID from JWT payload).
  4. The userFileRepositoryController.find method interacts with a data store to retrieve repository-specific information associated with the authenticated user.
  5. The controller’s response, containing the user’s repository data, is returned to the client via expressMiddlewareHandler.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant UserFileRepositoryController
    participant UserDataStore // Abstracted data store

    Client->>API Gateway: GET /user
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated (User context available)
    API Gateway->>UserFileRepositoryController: find(authenticatedUserContext)
    UserFileRepositoryController->>UserDataStore: Fetch data for user ID
    UserDataStore-->>UserFileRepositoryController: Return User-Specific Repository Data
    UserFileRepositoryController-->>API Gateway: Response (e.g., { userId: "user123", settings: {...}, files: [...] })
    API Gateway-->>Client: HTTP 200 OK

Key Dependencies/Modules:

  • express.Router: For route definition.
  • jsonwebtoken: Used by AuthMiddleware for token verification.
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares: Provides AuthMiddleware, expressMiddlewareHandler.
  • ./domain: Specifically makeDomains() which provides userFileRepositoryController.
  • ./validators/file.repository.user.validator: While not used directly in this route’s definition, it’s part of the overall setup for fileRepositoryValidator.

Code Snippet (Route Definition):

// From src/routes/repository.user.route.ts
router.get('/', expressMiddlewareHandler(userFileRepositoryController.find));

Notes:

  • The TODO validation middleware comment suggests that query parameter validation (e.g., for specific fields or views of user data) might be added in the future.
  • The userFileRepositoryController.find method likely uses the user ID from the JWT payload passed by AuthMiddleware to fetch the correct data.

7.2. POST /user

Description: Creates new repository-related data for the currently authenticated user. This could involve initializing a user’s repository profile, creating a root folder, or setting initial preferences.

Request Validation:

  • An explicit validatorHandler middleware is not present in the route definition. A TODO validation middleware comment exists in the source code.
  • Expected parameters would be in the request body, defining the user-specific repository data to be created (e.g., preferences: {...}, initialSetup: true). The structure of this data would eventually be defined by a validation schema.

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication). The authenticated user’s identity is implicitly available to the controller.

Core Logic Flow:

  1. Request is received by the Express application with data in the request body.
  2. AuthMiddleware verifies the JWT token, identifying the authenticated user.
  3. The request (including the body) is directly passed to the userFileRepositoryController.create method. The controller uses the authenticated user’s context.
  4. The userFileRepositoryController.create method processes the request body. It interacts with a data store to create new repository-specific records or settings associated with the authenticated user.
  5. The controller’s response, typically confirming creation and returning the created data, is sent to the client via expressMiddlewareHandler.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant UserFileRepositoryController
    participant UserDataStore // Abstracted data store

    Client->>API Gateway: POST /user (Body: { initialSettings: "..." })
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated (User context available)
    API Gateway->>UserFileRepositoryController: create(authenticatedUserContext, requestBody)
    UserFileRepositoryController->>UserDataStore: Create new repository data for user ID with payload
    UserDataStore-->>UserFileRepositoryController: Return Confirmation/Created Data
    UserFileRepositoryController-->>API Gateway: Response (e.g., { userId: "user123", status: "created", ... })
    API Gateway-->>Client: HTTP 201 Created

Key Dependencies/Modules:

  • express.Router
  • jsonwebtoken
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares
  • ./domain (userFileRepositoryController)
  • ./validators/file.repository.user.validator: Intended for future use with fileRepositoryValidator for this route.

Code Snippet (Route Definition):

// From src/routes/repository.user.route.ts
router.post('/', expressMiddlewareHandler(userFileRepositoryController.create));

Notes:

  • The TODO validation middleware comment highlights the need to add validation for the request body to ensure data integrity. The fileRepositoryValidator (configured with fileRepositoryUserValidators) would be the designated tool.
  • This endpoint allows users to establish their initial presence or data within the repository system.

7.3. PUT /user

Description: Updates existing repository-related data for the currently authenticated user. This can be used to modify user preferences, profile details, or other repository-specific settings.

Request Validation:

  • Uses validatorHandler with the fileRepositoryValidator instance, configured with the ‘update’ schema from fileRepositoryUserValidators.
  • The request body is expected to contain the fields to be updated for the user’s repository data.

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication). The authenticated user’s identity is implicitly available to the controller.

Core Logic Flow:

  1. Request is received with update data in the request body.
  2. AuthMiddleware verifies the JWT token.
  3. validatorHandler middleware validates the request body using the update schema from fileRepositoryValidator (which uses fileRepositoryUserValidators).
  4. The validated request (including the body) is passed to the userFileRepositoryController.update method. The controller uses the authenticated user’s context.
  5. The userFileRepositoryController.update method interacts with a data store to find and update the repository-specific information for the authenticated user based on the provided data.
  6. The controller’s response, confirming the update and typically returning the updated data, is sent via expressMiddlewareHandler.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant UserFileRepositoryController
    participant UserDataStore // Abstracted data store

    Client->>API Gateway: PUT /user (Body: { preferences: "new_value" })
    API Gateway->>AuthMiddleware: Verify Token
    AuthMiddleware-->>API Gateway: Token Validated (User context available)
    API Gateway->>Validator: Validate Request Body (schema: update)
    Validator-->>API Gateway: Parameters Valid
    API Gateway->>UserFileRepositoryController: update(authenticatedUserContext, validatedBody)
    UserFileRepositoryController->>UserDataStore: Find and Update repository data for user ID
    UserDataStore-->>UserFileRepositoryController: Return Confirmation/Updated Data
    UserFileRepositoryController-->>API Gateway: Response (e.g., { userId: "user123", status: "updated", ... })
    API Gateway-->>Client: HTTP 200 OK

Key Dependencies/Modules:

  • express.Router
  • jsonwebtoken
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares
  • ./domain (userFileRepositoryController)
  • ./validators/file.repository.user.validator: Provides the update schema used by fileRepositoryValidator.

Code Snippet (Route Definition):

// From src/routes/repository.user.route.ts
router.put(
    '/',
    validatorHandler(fileRepositoryValidator, 'update'),
    expressMiddlewareHandler(userFileRepositoryController.update),
);

Notes:

  • This endpoint allows users to manage and customize their repository-related information over time.
  • The update schema in fileRepositoryUserValidators defines which fields are permissible for update.

7.4. GET /user/all

Description: Retrieves storage data details for all users. This is likely an administrative endpoint used for monitoring, reporting, or managing user storage across the platform.

Request Validation:

  • Uses validatorHandler with the fileRepositoryValidator instance, configured with the ‘findUsersDetails’ schema from fileRepositoryUserValidators.
  • This schema likely defines query parameters for filtering (e.g., by organization, by user status) and pagination (e.g., page, limit).

Authentication:

  • Protected by AuthMiddleware (JWT-based authentication). It’s expected that this route also has additional authorization checks (e.g., role-based access control) to ensure only administrators can access it, though this is not explicitly shown in the route definition snippet.

Core Logic Flow:

  1. Request is received, potentially with query parameters for filtering/pagination.
  2. AuthMiddleware verifies the JWT token. (Further authorization for admin rights is assumed).
  3. validatorHandler middleware validates the request query parameters using the findUsersDetails schema from fileRepositoryValidator.
  4. The validated request parameters are passed to the userFileRepositoryController.findUsersStorageData method.
  5. The userFileRepositoryController.findUsersStorageData method interacts with a data store to fetch storage-related information for all users, applying any specified filters or pagination.
  6. The controller’s response, containing a list of user storage data and potentially pagination metadata, is returned via expressMiddlewareHandler.

Mermaid Diagram (Illustrative Flow):

sequenceDiagram
    participant Client
    participant API Gateway
    participant AuthMiddleware
    participant Validator
    participant UserFileRepositoryController
    participant UserDataStore // Abstracted data store

    Client->>API Gateway: GET /user/all?page=1&limit=50
    API Gateway->>AuthMiddleware: Verify Token (and check admin privileges - assumed)
    AuthMiddleware-->>API Gateway: Token Validated
    API Gateway->>Validator: Validate Request Query Params (schema: findUsersDetails)
    Validator-->>API Gateway: Parameters Valid
    API Gateway->>UserFileRepositoryController: findUsersStorageData(validatedQueryParams)
    UserFileRepositoryController->>UserDataStore: Fetch storage data for all users (with filters/pagination)
    UserDataStore-->>UserFileRepositoryController: Return List of User Storage Data
    UserFileRepositoryController-->>API Gateway: Response (e.g., { data: [...], total: 1000, page: 1 })
    API Gateway-->>Client: HTTP 200 OK

Key Dependencies/Modules:

  • express.Router
  • jsonwebtoken
  • @nimbly-technologies/nimbly-backend-utils/lib/middlewares
  • ./domain (userFileRepositoryController)
  • ./validators/file.repository.user.validator: Provides the findUsersDetails schema used by fileRepositoryValidator.

Code Snippet (Route Definition):

// From src/routes/repository.user.route.ts
router.get(
    '/all',
    validatorHandler(fileRepositoryValidator, 'findUsersDetails'),
    expressMiddlewareHandler(userFileRepositoryController.findUsersStorageData),
);

Notes:

  • This endpoint is powerful and should be strictly controlled with authorization logic beyond basic authentication to ensure only privileged users (e.g., administrators) can access it.
  • The findUsersDetails schema is crucial for defining how an administrator can query and paginate through the user storage data.

8. Core Domain Logic and Dependency Injection (src/routes/domain/index.ts)

The src/routes/domain/index.ts file plays a pivotal role in the architecture of this service. It acts as a centralized Dependency Injection (DI) container, responsible for instantiating and wiring together various components of the application, such as repositories, use cases, and controllers. This approach promotes a clean separation of concerns, enhances modularity, and improves the testability of the codebase.

8.1. Key Function: makeDomains()

The primary export of this file is the makeDomains() function. This function is invoked at the application’s setup stage (likely within src/routes/index.ts or a similar entry point for the routing layer). The controllers returned by makeDomains() are then used by the individual route definition files (e.g., repository.route.ts, repository.user.route.ts) to handle incoming HTTP requests.

makeDomains() initializes and connects the following types of components:

Repositories

Repositories are responsible for data access and abstracting the underlying data sources. They provide a consistent API for use cases to interact with data without needing to know the specifics of the database or external service implementation. Key repositories instantiated include:

  • StorageRepository: Manages interactions with the primary storage for files/folders (likely MongoDB, based on mongoose usage).
  • RepositoryPlanRepository: Handles CRUD operations for repository plans (MongoDB).
  • RepositoryUsageTrackerRepository: Manages usage tracking data for organizations (MongoDB).
  • UserRepositoryRepo: Deals with user-specific repository data and settings (MongoDB).
  • OrganizationFirebaseRepository: Interacts with Firebase (likely Realtime Database or Firestore via firebase-admin) for organization-related data that might be stored separately or require real-time capabilities.
  • UserMongoRepository: Potentially manages core user profile data in MongoDB, distinct from UserRepositoryRepo which might handle user data specific to the repository application context.
  • PubsubAPI: Wraps interactions with Google Pub/Sub for asynchronous messaging.
  • RecentActivityRepository: Manages records of recent activities within the repository (MongoDB).
  • OrganizationFeaturesRepository: Handles data related to features enabled for specific organizations (MongoDB).

These repositories often leverage @nimbly-technologies/entity-node for base repository/entity classes, providing a common structure for data management.

Use Cases

Use cases encapsulate the core business logic of the application. They orchestrate actions by interacting with one or more repositories to fulfill specific tasks or operations. Key use cases include:

  • StorageUsecase: Contains logic for file/folder operations, signed URL generation, downloads, etc. It coordinates StorageRepository, RepositoryUsageTrackerRepository, UserRepositoryRepo, OrganizationFirebaseRepository, RecentActivityRepository, UserMongoRepository, and PubsubAPI.
  • RepositoryPlanUsecase: Manages the business rules for creating and updating repository plans, primarily using RepositoryPlanRepository.
  • RepositoryUsageTrackerUsecase: Handles logic for tracking and updating resource usage. For example, it might use RepositoryUsageTrackerRepository to update usage and RepositoryPlanRepository to check against plan limits, and OrganizationFirebaseRepository for organization context.
  • UserRepositoryUsecase: Contains business logic for user-specific repository actions, such as retrieving user profiles or managing user settings. It interacts with UserRepositoryRepo, RepositoryUsageTrackerRepository, RepositoryUsageTrackerUsecase (for related usage updates), OrganizationFeaturesRepository, and RepositoryPlanRepository.

Controllers

Controllers act as the bridge between the routing layer (HTTP requests) and the use cases. They parse incoming requests, call the appropriate use case methods with validated data, and then format the use case’s response to be sent back to the client. The controllers initialized are:

  • StorageController: Handles requests for the / (repository) routes.
  • RepositoryPlanController: Handles requests for the /plan routes.
  • RepositoryUsageTrackerController: Handles requests for the /tracker routes.
  • UserFileRepositoryController: Handles requests for the /user routes.

8.2. Dependency Flow

The typical flow of control and dependencies in this architecture is as follows:

  1. Routes (e.g., repository.route.ts): Define HTTP endpoints and pass request/response objects to Controllers.
  2. Controllers (e.g., StorageController): Extract and validate data from requests (often with validatorHandler), then invoke methods on Use Cases.
  3. Use Cases (e.g., StorageUsecase): Execute business logic, coordinating actions by calling methods on one or more Repositories.
  4. Repositories (e.g., StorageRepository): Perform CRUD operations and interact with specific data stores (like MongoDB, Firebase) or external services (like Google Pub/Sub).
  5. Data Stores / External Services: The underlying databases or messaging systems.

8.3. Key Technologies/Libraries Utilized in Domain Layer

  • mongoose: An ODM library for MongoDB, used by repositories interacting with MongoDB.
  • firebase-admin: Allows backend services to interact with Firebase services (e.g., Firestore, Realtime Database).
  • @nimbly-technologies/entity-node: Provides base classes and utilities for entities and repositories, promoting a standardized approach to data access.
  • tracer: Integrated for distributed tracing, allowing requests to be monitored as they flow through different components of the domain layer and beyond.

8.4. Illustrative Architecture Diagram

The following diagram provides a high-level overview of the architecture facilitated by makeDomains():

graph TD
     Domain Layer
    subgraph Domain Layer
        direction TB

         Usecases
        U1[StorageUsecase]
        U2[RepositoryPlanUsecase]
        U3[RepositoryUsageTrackerUsecase]
        U4[UserRepositoryUsecase]

         Controller → Usecase
        C1 --> U1
        C2 --> U2
        C3 --> U3
        C4 --> U4

         Route Layer → Controllers
    R1 --> C1
    R2 --> C2
    R3 --> C3
    R4 --> C4

     Repositories → External Services
    Repo1 --> DB1
    Repo2 --> DB1
    Repo3 --> DB1
    Repo4 --> DB1
    Repo5 --> DB2
    Repo6 --> DB1
    Repo7 --> PS
    Repo8 --> DB1
    Repo9 --> DB1

9. Request Validation (src/routes/validators/)

The files located within the src/routes/validators/ directory are essential for ensuring the integrity and security of data entering the API. Their primary purpose is to define and apply validation schemas to incoming request data, including query parameters and request bodies. This preemptive validation step is crucial before data is processed by controllers and subsequently by the business logic within use cases.

9.1. Mechanism of Validation

  1. Schema Definition: Each validator file (e.g., file.repository.validator.ts) defines a set of schemas. While the specific schema definition library isn’t explicitly detailed in domain/index.ts, it’s common practice to use robust libraries like Zod or Joi. These libraries allow developers to define the expected structure, data types, required fields, and other constraints (e.g., string patterns, numerical ranges) for the request data.
  2. Import and Configuration: Route definition files (e.g., repository.route.ts) import the relevant validator schemas. In this project, a central Validator class (likely from @nimbly-technologies/nimbly-backend-utils) is instantiated in src/routes/index.ts (e.g., fileRepositoryValidator, fileRepositoryPlanValidator, etc.). These instances are configured by passing the schemas from the corresponding validator files.
  3. Middleware Application: The validatorHandler middleware (also from @nimbly-technologies/nimbly-backend-utils) is then used in the route definitions. This middleware takes an instance of the configured Validator class and a schema key (a string identifying which specific schema to use for the current route) to validate the incoming request. If validation fails, the validatorHandler typically sends an error response to the client, preventing the request from reaching the controller.

9.2. List of Validator Files and Their Scope

The project includes several validator files, each tailored to a specific functional area of the API:

  • file.repository.validator.ts: Contains schemas for operations related to general file and folder management, used by src/routes/repository.route.ts. This includes schemas for creating files/folders, generating signed URLs, listing entities, etc.
  • file.repository.plan.validator.ts: Provides schemas for creating and updating repository plans, used by src/routes/repository.plan.route.ts.
  • file.repository.tracker.validator.ts: Defines schemas for managing repository usage trackers (creating, updating, retrieving), used by src/routes/respository.usage.tracker.ts.
  • file.repository.user.validator.ts: Contains schemas for user-specific repository actions, such as updating user repository settings or fetching details for all users (for admin purposes), used by src/routes/repository.user.route.ts.

9.3. Importance of the Validation Layer

This dedicated validation layer offers several significant benefits:

  • Security: By rigorously checking incoming data, it helps protect against common web vulnerabilities, such as injection attacks or data corruption caused by malformed payloads.
  • Data Integrity: Ensures that the data processed by controllers and use cases conforms to the expected format and constraints, reducing the likelihood of runtime errors and inconsistent data states.
  • Clear Contracts: Validation schemas serve as a clear definition of the API’s expected input, aiding both frontend and backend developers.
  • Reduced Boilerplate in Controllers: By handling validation in middleware, controllers can focus on their primary responsibility of orchestrating business logic, rather than being cluttered with repetitive validation code.

In summary, the validator files and the associated validatorHandler middleware form a critical part of the application’s input processing pipeline, safeguarding the system and ensuring reliable data handling.