Skip to main content

POS Profile API

The POS Profile API provides endpoints for managing POS (Point of Sale) profiles within a store. Profiles represent user accounts or cashier identities associated with a specific store.
All POS Profile API endpoints require authentication and automatically use the authenticated store ID.

Overview

Each profile:
  • Belongs to one store
  • Has a unique name within that store
  • Stores a hashed password
  • Can be created, updated, listed, or deleted via these endpoints

Endpoint Details

Base URL: /pos-shift
Content-Type: application/json

Required Headers

Authorization: Bearer <token>
All routes require a valid storeId which is automatically injected via the @StoreId() decorator. Passwords are never returned in API responses.

Entity: POS Profile

FieldTypeDescription
idstringUnique profile ID
storeIdstringAssociated store identifier
namestringProfile name (unique per store)
passwordstringHashed password (not returned in API)
createdAtDateCreation timestamp
updatedAtDateLast update timestamp

Create POS Profile

POST /pos-shift/create-shift Creates a new POS profile under the authenticated store. The password is securely hashed before saving. Requires Authentication: Bearer token in Authorization header

Request Body

{
  "name": "Cashier 1",
  "password": "secret123"
}
FieldTypeRequiredDescription
namestringYesProfile name (unique per store)
passwordstringYesPassword (minimum 6 characters)

Success Response

Status Code: 201 Created
{
  "id": "pf_123abc",
  "storeId": "st_456xyz",
  "name": "Cashier 1",
  "createdAt": "2025-11-03T10:00:00.000Z",
  "updatedAt": "2025-11-03T10:00:00.000Z"
}

Possible Errors

CodeMessage
400Store ID, name, and password are required
400Password must be at least 6 characters
409Profile with name already exists

Example Request

curl -X POST "https://jethings-backend.fly.dev/pos-shift/create-shift" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "name": "Cashier 1",
    "password": "secret123"
  }'

Get All POS Profiles

GET /pos-shift/profiles Retrieves all POS profiles for the current store, excluding passwords. Requires Authentication: Bearer token in Authorization header

Success Response

Status Code: 200 OK
{
  "profiles": [
    {
      "id": "pf_123abc",
      "name": "Cashier 1",
      "storeId": "st_456xyz",
      "createdAt": "2025-10-30T12:00:00.000Z",
      "updatedAt": "2025-10-30T12:00:00.000Z"
    },
    {
      "id": "pf_456def",
      "name": "Manager",
      "storeId": "st_456xyz",
      "createdAt": "2025-10-28T09:00:00.000Z",
      "updatedAt": "2025-10-28T09:00:00.000Z"
    }
  ],
  "total": 2
}

Response Fields

Profile Object

FieldTypeDescription
idstringUnique profile identifier
namestringProfile name
storeIdstringAssociated store identifier
createdAtstringCreation timestamp (ISO 8601)
updatedAtstringLast update timestamp (ISO 8601)

Response Object

FieldTypeDescription
profilesarrayArray of profile objects
totalnumberTotal number of profiles

Possible Errors

CodeMessage
400Store ID is required

Example Request

curl -X GET "https://jethings-backend.fly.dev/pos-shift/profiles" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Update POS Profile

PATCH /pos-shift/profile/:profileId Updates a profile’s name and/or password for a given store. Requires Authentication: Bearer token in Authorization header

Path Parameters

ParameterTypeRequiredDescription
profileIdstringYesProfile ID

Request Body

{
  "name": "Cashier A",
  "password": "newpassword123"
}
FieldTypeRequiredDescription
namestringNoNew profile name (unique per store)
passwordstringNoNew password (minimum 6 characters)
Note: At least one field (name or password) must be provided.

Success Response

Status Code: 200 OK
{
  "id": "pf_123abc",
  "storeId": "st_456xyz",
  "name": "Cashier A",
  "createdAt": "2025-10-30T12:00:00.000Z",
  "updatedAt": "2025-11-03T10:05:00.000Z"
}

Possible Errors

CodeMessage
400Profile ID and Store ID are required
400Password must be at least 6 characters
404Profile not found
409Name already exists in this store

Example Request

curl -X PATCH "https://jethings-backend.fly.dev/pos-shift/profile/pf_123abc" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{
    "name": "Cashier A",
    "password": "newpassword123"
  }'

Delete POS Profile

DELETE /pos-shift/profile/:profileId Deletes a POS profile permanently. If related records exist, they are deleted via database cascade. Requires Authentication: Bearer token in Authorization header

Path Parameters

ParameterTypeRequiredDescription
profileIdstringYesProfile ID

Success Response

Status Code: 200 OK
{
  "success": true,
  "message": "Profile 'Cashier 1' has been deleted"
}

Possible Errors

CodeMessage
400Profile ID and Store ID are required
404Profile not found

Example Request

curl -X DELETE "https://jethings-backend.fly.dev/pos-shift/profile/pf_123abc" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Security & Validation

  • All routes require a valid storeId (automatically injected via @StoreId() decorator)
  • Passwords are hashed using bcrypt with SALT_ROUNDS = 10
  • Input validation prevents empty fields or weak passwords
  • Duplicate profile names within the same store are disallowed
  • No password is ever returned in API responses

Data Transfer Objects (DTOs)

posProfileDto

export interface posProfileDto {
  name: string;
  password: string;
}

Business Logic

Profile Creation

  • Profile name must be unique within the store
  • Password is automatically hashed before storage
  • Store ID is automatically associated from the authenticated context

Profile Updates

  • Either name or password (or both) can be updated
  • Name uniqueness is validated within the store scope
  • Password updates trigger re-hashing with bcrypt

Profile Deletion

  • Deletion is permanent (not soft delete)
  • Related records (if any) are deleted via database cascade
  • Profile ID and Store ID validation prevents unauthorized deletions

Password Security

  • All password operations (create/update/verify) are performed in the service layer
  • Passwords are hashed using bcrypt with 10 salt rounds
  • Raw passwords are never stored or returned in responses
  • Minimum password length is 6 characters

Notes for Developers

  • All password operations (create/update/verify) are performed in the service layer
  • No password is ever returned in API responses
  • Profiles can later be linked to shift or POS session logic
  • The verifyProfilePassword() method exists in the service but is not yet exposed as an endpoint

Error Responses

Common Error Codes

CodeDescription
400Bad Request - Invalid input or validation
404Not Found - Profile doesn’t exist
409Conflict - Duplicate profile name

Error Response Format

{
  "message": "Error description",
  "statusCode": 400
}