Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/edgar2420/QrPermision/llms.txt

Use this file to discover all available pages before exploring further.

QR codes are the core identity primitive in PermisosQR. Each code is a numeric ID stored in the database with a lifecycle status of available, active, expired, or disabled. Authenticated operators manage the pool of codes through the protected endpoints below; the public endpoints allow a mobile browser — scanning the physical QR label — to activate and close a permission without needing a pre-issued JWT.

Authenticated Endpoints

All endpoints in this section require an Authorization: Bearer <token> header obtained from POST /api/auth/login.

GET /api/qr

Returns a paginated list of all QR codes, optionally filtered by status or ID fragment. Each record is joined with the active permission (if any) to expose real-time bearer and exit information. Auth required: Bearer Query parameters
status
string
Filter by QR lifecycle status. One of available, active, expired, or disabled.
Partial match against the numeric QR ID (e.g. "42" matches IDs 42, 142, 420).
page
integer
Page number. Defaults to 1.
limit
integer
Records per page. Defaults to 20.
Response 200
{
  "success": true,
  "data": [
    {
      "id": 7,
      "status": "active",
      "created_at": "2024-01-10T09:00:00.000Z",
      "updated_at": "2024-01-15T14:30:00.000Z",
      "created_by_name": "Ana Torres",
      "active_permission_id": 142,
      "received_by": "Juan Pérez",
      "allowed_minutes": 15,
      "exit_time": "2024-01-15T14:30:00.000Z",
      "enabled_by": 2,
      "enabled_by_name": "Ana Torres"
    }
  ],
  "total": 20,
  "page": 1,
  "limit": 20,
  "pages": 1
}

POST /api/qr/generate

Bulk-generates a specified number of new QR codes, all with available status. Restricted to Super Admins. Auth required: Bearer — Super Admin only
quantity
integer
required
Number of QR codes to create. Must be between 1 and 500 (inclusive).
Response 201
{
  "success": true,
  "data": [
    { "id": 21, "status": "available", "created_at": "2024-01-15T15:00:00.000Z" },
    { "id": 22, "status": "available", "created_at": "2024-01-15T15:00:00.000Z" }
  ],
  "count": 2
}
Error responses
StatusCondition
400quantity is missing, less than 1, or greater than 500
403Authenticated user does not have the super_admin role
curl -X POST http://localhost:4000/api/qr/generate \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{ "quantity": 50 }'

GET /api/qr/:id

Fetches a single QR code by its numeric ID, including joined permission details if the code is currently active. Auth required: Bearer Path parameter: id — integer QR code ID Response 200 — Same QRCode object shape as GET /api/qr. Error responses
StatusCondition
404No QR code with the given ID exists

PATCH /api/qr/:id/disable

Sets a QR code’s status to disabled, preventing it from being scanned or activated. Cannot be applied while the code is actively in use. Auth required: Bearer Path parameter: id — integer QR code ID Response 200 — Updated QRCode object (full row from qr_codes). Error responses
StatusCondition
400QR status is currently active — close the open permission first
404QR not found

PATCH /api/qr/:id/reactivate

Restores a disabled or expired QR code to available status so it can be activated again. Auth required: Bearer Path parameter: id — integer QR code ID Response 200 — Updated QRCode object with status: "available". Error responses
StatusCondition
400QR is already active
404QR not found

DELETE /api/qr/:id

Permanently removes a QR code and all associated permission records from the database. This action is irreversible. Restricted to Super Admins. Auth required: Bearer — Super Admin only Path parameter: id — integer QR code ID Response 200
{ "success": true, "message": "QR eliminado permanentemente" }
Error responses
StatusCondition
400QR is currently active — cannot delete a code in use
403Authenticated user is not a Super Admin
404QR not found
Deleting a QR code cascades to all historical permission records linked to that code. Export any audit data before proceeding.

Public Endpoints

These endpoints do not require a pre-issued JWT. Instead, they accept an email and password in the request body to identify the operator performing the action. They are designed to be called directly from a mobile browser that has scanned a physical QR label.

GET /api/qr/public/:id

Returns the current public-facing state of a QR code — enough information for a mobile UI to show the bearer’s name, remaining time, and compliance status. No credentials required. Auth required: None Path parameter: id — integer QR code ID Response 200
{
  "success": true,
  "data": {
    "id": 7,
    "status": "active",
    "created_at": "2024-01-10T09:00:00.000Z",
    "received_by": "Juan Pérez",
    "allowed_minutes": 15,
    "exit_time": "2024-01-15T14:30:00.000Z",
    "return_time": null,
    "time_used_minutes": null,
    "delay_minutes": null,
    "is_compliant": null,
    "enabled_by_name": "Ana Torres"
  }
}

POST /api/qr/public/:id/enable

Activates a QR code from a mobile scan. The operator supplies their credentials in the body; the server validates them against the users table, then atomically creates a permission record and flips the QR status to active. exit_time is set to NOW() at the moment of the database write. Auth required: None (credentials in body)
receivedBy
string
required
Full name of the person receiving the pass (e.g. employee or visitor name).
allowedMinutes
integer
Time budget in minutes granted for this exit. Defaults to 15 if omitted.
email
string
required
Email of the operator authorising the exit. Verified against the database.
password
string
required
Plaintext password of the authorising operator. Compared against the stored bcrypt hash.
Response 200 — Public QR object (same shape as GET /api/qr/public/:id, now with status: "active" and a populated exit_time). Error responses
StatusCondition
400receivedBy is missing; or email/password is missing; or QR is not in available status
401Operator email not found, or password does not match stored hash
403Operator account is inactive (is_active = false)
404QR not found
curl -X POST http://localhost:4000/api/qr/public/7/enable \
  -H "Content-Type: application/json" \
  -d '{
    "receivedBy": "Juan Pérez",
    "allowedMinutes": 20,
    "email": "ana@example.com",
    "password": "secret123"
  }'

POST /api/qr/public/:id/return

Closes an active permission from a mobile scan. The server verifies operator credentials, then calculates time_used_minutes, delay_minutes, and is_compliant before resetting the QR to available. Compliance rule: A permission is compliant (is_compliant: true) when delay_minutes <= 0, i.e. the bearer returned before or exactly at the allowed_minutes deadline. Auth required: None (credentials in body)
email
string
required
Email of the operator recording the return.
password
string
required
Plaintext password of the operator recording the return.
Response 200
{
  "success": true,
  "data": {
    "time_used_minutes": "18.00",
    "delay_minutes": "3.00",
    "is_compliant": false
  }
}
Error responses
StatusCondition
400email/password is missing; or QR is not in active status
401Operator email not found, or password does not match stored hash
403Operator account is inactive (is_active = false)
404QR not found, or no open permission record found
After a successful return, the QR status reverts to available immediately. A new POST /api/qr/public/:id/enable can be issued right away for the next exit.

Build docs developers (and LLMs) love