QuartermasterController

struct QuartermasterController : APIRouteCollection

Provides API endpoints for the Quartermaster “have / need” item board.

Quartermaster is a standalone searchable database of items that cruise guests are offering or looking for, modeled on the Fez/LFG subsystem. All endpoints require a logged-in user (cruise-internal contact info). Creating and editing items requires the standard content guard (blocks banned/quarantined users).

All routes are gated by the .quartermaster feature flag and accept Bearer token auth only.

Routes registered by this controller:

GET  /api/v3/quartermaster                    list items (filters: category, search, mine)
GET  /api/v3/quartermaster/:quartermaster_id  get a single item
POST /api/v3/quartermaster/create             batch-create one or more items
POST /api/v3/quartermaster/:id/update         update a single item
POST /api/v3/quartermaster/:id/delete         soft-delete an item

DELETE /api/v3/quartermaster/:id soft-delete an item (REST alias) POST /api/v3/quartermaster/:id/report report an item to the mod queue

Route Registration

URL Query Struct

Handlers

  • listHandler(_:) Asynchronous

    GET /api/v3/quartermaster

    Returns a paginated list of Quartermaster items, sorted by most-recently-modified first. Items owned by blocked or muted users are excluded from results.

    Query Parameters:

    • category=have|need — filter to one category
    • search=<string> — full-text search across name, description, and location
    • mine=true — return only the authenticated user’s own items
    • start=<n> / limit=<n> — pagination (max size: Settings.shared.maximumTwarrts)

    Throws

    400 if category is not a recognized value; 401 if unauthenticated.

    See more

    Declaration

    Swift

    func listHandler(_ req: Request) async throws -> QuartermasterListData

    Return Value

    QuartermasterListData

  • getHandler(_:) Asynchronous

    GET /api/v3/quartermaster/:quartermaster_id

    Returns the details for a single Quartermaster item.

    Throws

    400 if item not found or owner is blocked/muted; 401 if unauthenticated.

    Declaration

    Swift

    func getHandler(_ req: Request) async throws -> QuartermasterData

    Return Value

    QuartermasterData

  • createHandler(_:) Asynchronous

    POST /api/v3/quartermaster/create

    Creates one or more QuartermasterItems in a single batch. All items share the same category, location, and hideOwnerName; each item has its own itemName and optional itemDescription. All items are saved inside a single transaction so the batch is all-or-nothing.

    location is required when hideOwnerName is true.

    Throws

    400 on validation failure; 401 if unauthenticated; 403 if the user cannot create content (banned/quarantined).

    Declaration

    Swift

    func createHandler(_ req: Request) async throws -> Response

    Return Value

    [QuartermasterData] with HTTP 201 Created.

  • updateHandler(_:) Asynchronous

    POST /api/v3/quartermaster/:quartermaster_id/update

    Updates a single Quartermaster item. The owner may update any field; a moderator may also update items belonging to other users.

    When any text field (itemName, itemDescription, or location) or hideOwnerName changes, a QuartermasterItemEdit is created first to snapshot the prior state for mod accountability. Category-only changes do not create an edit record.

    Throws

    400 on validation failure or item not found; 401 if unauthenticated; 403 if the caller cannot modify this item.

    Declaration

    Swift

    func updateHandler(_ req: Request) async throws -> QuartermasterData

    Return Value

    QuartermasterData

  • deleteHandler(_:) Asynchronous

    POST /api/v3/quartermaster/:quartermaster_id/delete DELETE /api/v3/quartermaster/:quartermaster_id

    Soft-deletes a Quartermaster item. The item’s owner may delete their own item; a moderator may delete any item. The soft-delete timestamp is recorded so moderators can still view deleted items during review.

    Throws

    400 if item not found; 401 if unauthenticated; 403 if the caller is neither the owner nor a moderator.

    Declaration

    Swift

    func deleteHandler(_ req: Request) async throws -> HTTPStatus

    Return Value

    HTTP 204 No Content.

Private Helpers

  • Resolves an optional ImageUploadData to the filename that should be stored on the item: processes and saves new image data when present, otherwise passes an existing filename through unchanged (or nil, when there’s no image at all).

    Declaration

    Swift

    private func resolvedImageFilename(from upload: ImageUploadData?, on req: Request) async throws -> String?
  • findItem(on:) Asynchronous

    Looks up the QuartermasterItem identified by quartermasterIDParam, converting a not-found result to a 400 Bad Request per the Swiftarr API convention (404 is reserved for endpoints that do not exist).

    Declaration

    Swift

    private func findItem(on req: Request) async throws -> QuartermasterItem
  • reportHandler(_:) Asynchronous

    POST /api/v3/quartermaster/:quartermaster_id/report

    Files a report against a Quartermaster item, feeding it into the moderation queue. Duplicate reports from the same user are silently ignored. No auto-quarantine occurs — moderators must manually quarantine items.

    Throws

    400 if item not found; 401 if unauthenticated.

    Declaration

    Swift

    func reportHandler(_ req: Request) async throws -> HTTPStatus

    Return Value

    HTTP 201 Created.