Skip to content

Latest commit

 

History

History
1018 lines (899 loc) · 28 KB

File metadata and controls

1018 lines (899 loc) · 28 KB

Teven Service APIs

This document outlines the API endpoints for the Teven service, including their purpose, authentication requirements, and the expected request/response data structures. Data structures are presented using Kotlin pseudocode for conciseness.

Base API Response

All API responses will follow a consistent structure to ensure predictable handling of successes and failures.

data class ApiResponse<T>(
  val success: Boolean, 
  val data: T?, 
  val error: ApiError?
)
data class ApiError(
  val message: String, 
  val details: String?
)
data class PaginatedResponse<T>(
  val items: List<T>, 
  val total: Long, 
  val offset: Long, 
  val limit: Int
)
  • success: A boolean indicating if the request was successful.
  • data: The payload of the response. For successful requests, this will contain the requested data. For failed requests, this will be null.
  • error: An object containing error details. For successful requests, this will be null.
  • PaginatedResponse: A standard structure for paginated lists of data.

Common Search, Sort, and Pagination Parameters

Many GET list endpoints support the following optional query parameters:

  • limit (optional, integer): The maximum number of items to return. Defaults to 10 or 1000 depending on the endpoint.
  • offset (optional, integer): The number of items to skip. Defaults to 0.
  • search (optional, string): A search filter applied to relevant fields (e.g., name, title, description).
  • sortBy (optional, string): The field to sort by. Supported fields vary by endpoint.
  • sortOrder (optional, string, asc or desc): The sort order. Defaults to asc.

Authentication: Most API endpoints in Teven will require authentication. We will use JSON Web Tokens (JWT) for authentication. The JWT will be included in the Authorization header of the HTTP request in the format: Bearer <token>. Endpoints not requiring authentication are explicitly marked.

I. Authentication and Authorization API

  • POST /api/users/register: Register a new user.

    • Authentication: Not required.
    • Request:
      data class CreateUserRequest(
        val username: String, 
        val password: String, 
        val email: String, 
        val displayName: String, 
        val roles: List<String> = emptyList(
      ), 
        val organizationId: Int
      )
    • Response:
      data class UserResponse(
        val userId: Int, 
        val username: String, 
        val email: String, 
        val displayName: String, 
        val roles: List<String>, 
        val staffDetails: StaffDetails?, 
        val organization: OrganizationResponse
      )
  • POST /api/users/login: Authenticate a user and return a token.

    • Authentication: Not required.
    • Request:
      data class LoginRequest(
        val username: String, 
        val password: String
      )
    • Response:
      data class LoginResponse(
        val token: String, 
        val user: UserResponse
      )
  • GET /api/users/{user_id}: Retrieve user details.

    • Authentication: Required.
    • Permissions: MANAGE_USERS_SELF to view your own profile, VIEW_USERS_ORGANIZATION to view others in your org, or VIEW_USERS_GLOBAL to view anyone.
    • Response:
      data class UserResponse(
        val userId: Int, 
        val username: String, 
        val email: String, 
        val displayName: String, 
        val roles: List<String>, 
        val staffDetails: StaffDetails?, 
        val organization: OrganizationResponse
      )
  • GET /api/users: Retrieve all users.

    • Authentication: Required.
    • Permissions: VIEW_USERS_ORGANIZATION to view users in your org, or VIEW_USERS_GLOBAL to view all users.
    • Query Parameters:
    • Response: PaginatedResponse<UserResponse>
  • PUT /api/users/{user_id}: Update user details.

    • Authentication: Required.
    • Permissions: MANAGE_USERS_SELF to edit your own profile, MANAGE_USERS_ORGANIZATION to edit others in your org, or MANAGE_USERS_GLOBAL to edit anyone.
    • Request:
      data class UpdateUserRequest(
        val email: String?, 
        val displayName: String?, 
        val roles: List<String>?, 
        val staffDetails: UpdateStaffDetails?, 
        val organizationId: Int?
      )
    • Response:
      data class UserResponse(
        val userId: Int, 
        val username: String, 
        val email: String, 
        val displayName: String, 
        val roles: List<String>, 
        val staffDetails: StaffDetails?, 
        val organization: OrganizationResponse
      )
  • GET /api/users/context: Retrieve context data for the logged-in user.

    • Authentication: Required.
    • Response:
      data class LoggedInContextResponse(
        val user: UserResponse, 
        val permissions: List<String>
      )

II. Invitation API

  • POST /api/invitations: Create a new invitation.

    • Authentication: Required.
    • Permissions: MANAGE_INVITATIONS_ORGANIZATION or MANAGE_INVITATIONS_GLOBAL.
    • Request:
      data class CreateInvitationRequest(
        val roleId: Int, 
        val expiresAt: String?, 
        val organizationId: Int?, 
        val note: String?
      )
    • Response:
      data class InvitationResponse(
        val invitationId: Int, 
        val organizationId: Int, 
        val roleId: Int, 
        val roleName: String, 
        val token: String, 
        val expiresAt: String, 
        val usedByUserId: Int?, 
        val createdAt: String, 
        val note: String?
      )
  • GET /api/invitations: Retrieve all unused invitations for the user's organization.

    • Authentication: Required.
    • Permissions: MANAGE_INVITATIONS_ORGANIZATION or MANAGE_INVITATIONS_GLOBAL.
    • Response: List<InvitationResponse>
  • GET /api/invitations/validate?token={token}: Validates an invitation token.

    • Authentication: Not required.
    • Response:
      data class ValidateInvitationResponse(
        val organizationId: Int, 
        val organizationName: String, 
        val roleName: String
      )
  • POST /api/invitations/accept: Accept an invitation and create a new user account.

    • Authentication: Not required.
    • Request:
      data class AcceptInvitationRequest(
        val token: String, 
        val username: String, 
        val password: String, 
        val email: String, 
        val displayName: String
      )
    • Response:
  • DELETE /api/invitations/{invitationId}: Deletes an unused invitation.

    • Authentication: Required.
    • Permissions: MANAGE_INVITATIONS_ORGANIZATION or MANAGE_INVITATIONS_GLOBAL.
    • Response: StatusResponse

III. Event API

  • POST /api/events: Create a new event.

    • Authentication: Required.
    • Permissions: MANAGE_EVENTS_ORGANIZATION
    • Request:
      data class CreateEventRequest(
        val title: String, 
        val date: String, 
        val time: String, 
        val durationMinutes: Int, 
        val location: String?, 
        val description: String?, 
        val inventoryItems: List<EventInventoryItem>, 
        val customerId: Int?, 
        val staffInvites: StaffInviteDetails, 
        val organizationId: Int
      )
    • Response:
      data class EventResponse(
        val eventId: Int, 
        val title: String, 
        val date: String, 
        val time: String, 
        val durationMinutes: Int, 
        val location: String?, 
        val description: String?, 
        val inventoryItems: List<EventInventoryItem>, 
        val customer: CustomerResponse?, 
        val rsvps: List<RsvpStatus>, 
        val organization: OrganizationResponse, 
        val openInvitation: Boolean = false, 
        val numberOfStaffNeeded: Int = 0
      )
  • GET /api/events: Retrieve all events.

    • Authentication: Required.
    • Permissions: VIEW_EVENTS_ORGANIZATION
    • Query Parameters:
      • See Common Search, Sort, and Pagination Parameters
      • startDate (optional, string, format: YYYY-MM-DD): The start date for the event search.
      • endDate (optional, string, format: YYYY-MM-DD): The end date for the event search.
      • organizationId (optional, integer): Filter events by organization. Requires VIEW_EVENTS_GLOBAL (if not your own org).
    • Response: PaginatedResponse<EventResponse>
  • GET /api/events/{eventId}: Retrieve a specific event.

    • Authentication: Required.
    • Permissions: VIEW_EVENTS_ORGANIZATION
    • Response:
      data class EventResponse(
        val eventId: Int, 
        val title: String, 
        val date: String, 
        val time: String, 
        val durationMinutes: Int, 
        val location: String?, 
        val description: String?, 
        val inventoryItems: List<EventInventoryItem>, 
        val customer: CustomerResponse?, 
        val rsvps: List<RsvpStatus>, 
        val organization: OrganizationResponse, 
        val openInvitation: Boolean = false, 
        val numberOfStaffNeeded: Int = 0
      )
  • PUT /api/events/{eventId}: Update an event.

    • Authentication: Required.
    • Permissions: MANAGE_EVENTS_ORGANIZATION
    • Request:
      data class UpdateEventRequest(
        val title: String?, 
        val date: String?, 
        val time: String?, 
        val durationMinutes: Int?, 
        val location: String?, 
        val description: String?, 
        val inventoryItems: List<EventInventoryItem>?, 
        val customerId: Int?, 
        val staffInvites: StaffInviteDetails?, 
        val organizationId: Int?
      )
    • Response:
      data class EventResponse(
        val eventId: Int, 
        val title: String, 
        val date: String, 
        val time: String, 
        val durationMinutes: Int, 
        val location: String?, 
        val description: String?, 
        val inventoryItems: List<EventInventoryItem>, 
        val customer: CustomerResponse?, 
        val rsvps: List<RsvpStatus>, 
        val organization: OrganizationResponse, 
        val openInvitation: Boolean = false, 
        val numberOfStaffNeeded: Int = 0
      )
  • DELETE /api/events/{eventId}: Delete an event.

    • Authentication: Required.
    • Permissions: MANAGE_EVENTS_ORGANIZATION
    • Response: StatusResponse
  • POST /api/events/{eventId}/staff/{userId}: Assign staff to an event.

    • Authentication: Required.
    • Permissions: ASSIGN_STAFF_TO_EVENTS_ORGANIZATION
    • Response: StatusResponse
  • DELETE /api/events/{eventId}/staff/{userId}: Remove staff from an event.

    • Authentication: Required.
    • Permissions: ASSIGN_STAFF_TO_EVENTS_ORGANIZATION
    • Response: StatusResponse
  • POST /api/events/{eventId}/rsvp: RSVP to an event.

    • Authentication: Required.
    • Request:
      data class RsvpRequest(
        val availability: String
      )
    • Response:
      data class StatusResponse(
        val status: String
      )

IV. Customer API

  • GET /api/customers: Retrieve all customers.

    • Authentication: Required.
    • Permissions: VIEW_CUSTOMERS_ORGANIZATION
    • Query Parameters:
    • Response: PaginatedResponse<CustomerResponse>
  • GET /api/customers/{customerId}: Retrieve a specific customer.

    • Authentication: Required.
    • Permissions: VIEW_CUSTOMERS_ORGANIZATION
    • Response:
      data class CustomerResponse(
        val customerId: Int, 
        val name: String, 
        val phone: String, 
        val address: String, 
        val notes: String, 
        val organization: OrganizationResponse
      )
  • POST /api/customers: Create a new customer.

    • Authentication: Required.
    • Permissions: MANAGE_CUSTOMERS_ORGANIZATION
    • Request:
      data class CreateCustomerRequest(
        val name: String, 
        val phone: String, 
        val address: String, 
        val notes: String, 
        val organizationId: Int?
      )
    • Response:
      data class CustomerResponse(
        val customerId: Int, 
        val name: String, 
        val phone: String, 
        val address: String, 
        val notes: String, 
        val organization: OrganizationResponse
      )
  • PUT /api/customers/{customerId}: Update a customer.

    • Authentication: Required.
    • Permissions: MANAGE_CUSTOMERS_ORGANIZATION
    • Request:
      data class UpdateCustomerRequest(
        val name: String?, 
        val phone: String?, 
        val address: String?, 
        val notes: String?, 
        val organizationId: Int?
      )
    • Response:
      data class CustomerResponse(
        val customerId: Int, 
        val name: String, 
        val phone: String, 
        val address: String, 
        val notes: String, 
        val organization: OrganizationResponse
      )
  • DELETE /api/customers/{customerId}: Delete a customer.

    • Authentication: Required.
    • Permissions: MANAGE_CUSTOMERS_ORGANIZATION
    • Response: StatusResponse

V. Inventory API

  • GET /api/inventory: Retrieve all inventory items.

    • Authentication: Required.
    • Permissions: VIEW_INVENTORY_ORGANIZATION
    • Query Parameters:
    • Response: PaginatedResponse<InventoryItemResponse>
  • GET /api/inventory/{inventoryId}: Retrieve a specific inventory item.

    • Authentication: Required.
    • Permissions: VIEW_INVENTORY_ORGANIZATION
    • Response:
      data class InventoryItemResponse(
        val inventoryId: Int, 
        val name: String, 
        val description: String, 
        val quantity: Int, 
        val events: List<EventSummaryResponse>, 
        val organization: OrganizationResponse
      )
  • POST /api/inventory: Create a new inventory item.

    • Authentication: Required.
    • Permissions: MANAGE_INVENTORY_ORGANIZATION
    • Request:
      data class CreateInventoryItemRequest(
        val name: String, 
        val description: String, 
        val quantity: Int, 
        val organizationId: Int?
      )
    • Response:
      data class InventoryItemResponse(
        val inventoryId: Int, 
        val name: String, 
        val description: String, 
        val quantity: Int, 
        val events: List<EventSummaryResponse>, 
        val organization: OrganizationResponse
      )
  • PUT /api/inventory/{inventoryId}: Update an inventory item.

    • Authentication: Required.
    • Permissions: MANAGE_INVENTORY_ORGANIZATION
    • Request:
      data class UpdateInventoryItemRequest(
        val name: String?, 
        val description: String?, 
        val quantity: Int?, 
        val organizationId: Int?
      )
    • Response:
      data class InventoryItemResponse(
        val inventoryId: Int, 
        val name: String, 
        val description: String, 
        val quantity: Int, 
        val events: List<EventSummaryResponse>, 
        val organization: OrganizationResponse
      )
  • DELETE /api/inventory/{inventoryId}: Delete an inventory item.

    • Authentication: Required.
    • Permissions: MANAGE_INVENTORY_ORGANIZATION
    • Response: StatusResponse
  • POST /api/inventory/{inventoryId}/usage: Track inventory item usage.

    • Authentication: Required.
    • Permissions: MANAGE_INVENTORY_ORGANIZATION
    • Request:
      data class TrackInventoryUsageRequest(
        val eventId: Int, 
        val quantity: Int
      )
    • Response:
      data class StatusResponse(
        val status: String
      )

VI. Report API

  • POST /api/reports/staff_hours: Generate a report of staff hours worked within a date range.

    • Authentication: Required.
    • Permissions: VIEW_REPORTS_ORGANIZATION
    • Request:
      data class StaffHoursReportRequest(
        val startDate: String, 
        val endDate: String
      )
    • Response: List<StaffHoursReportResponse>
  • GET /api/reports/inventory_usage: Generate a report of inventory usage frequency.

    • Authentication: Required.
    • Permissions: VIEW_REPORTS_ORGANIZATION
    • Response: List<InventoryUsageReportResponse>

VII. Role Management API

  • POST /api/roles: Create a new role.

    • Authentication: Required.
    • Permissions: MANAGE_ROLES_GLOBAL
    • Request:
      data class CreateRoleRequest(
        val roleName: String, 
        val permissions: List<String>
      )
    • Response:
      data class RoleResponse(
        val roleId: Int, 
        val roleName: String, 
        val permissions: List<String>
      )
  • GET /api/roles: Retrieve all roles.

    • Authentication: Required.
    • Permissions: VIEW_ROLES_ORGANIZATION or VIEW_ROLES_GLOBAL
    • Response: List<RoleResponse>
  • GET /api/roles/{roleId}: Get a role by ID.

    • Authentication: Required.
    • Permissions: VIEW_ROLES_ORGANIZATION or VIEW_ROLES_GLOBAL
    • Response:
      data class RoleResponse(
        val roleId: Int, 
        val roleName: String, 
        val permissions: List<String>
      )
  • PUT /api/roles/{roleId}: Update a role.

    • Authentication: Required.
    • Permissions: MANAGE_ROLES_GLOBAL
    • Request:
      data class UpdateRoleRequest(
        val roleName: String?, 
        val permissions: List<String>?
      )
    • Response:
      data class RoleResponse(
        val roleId: Int, 
        val roleName: String, 
        val permissions: List<String>
      )
  • DELETE /api/roles/{roleId}: Delete a role.

    • Authentication: Required.
    • Permissions: MANAGE_ROLES_GLOBAL
    • Response: StatusResponse
  • POST /api/users/{userId}/roles: Assign a role to a user.

    • Authentication: Required.
    • Permissions: ASSIGN_ROLES_ORGANIZATION or ASSIGN_ROLES_GLOBAL
    • Request:
    • Response:
      data class StatusResponse(
        val status: String
      )
  • DELETE /api/users/{userId}/roles/{roleId}: Remove a role from a user.

    • Authentication: Required.
    • Permissions: ASSIGN_ROLES_ORGANIZATION or ASSIGN_ROLES_GLOBAL
    • Response: StatusResponse

VIII. Organization Management API (SuperAdmin Only)

  • POST /api/organizations: Create a new organization.

    • Authentication: Required.
    • Permissions: MANAGE_ORGANIZATIONS_GLOBAL
    • Request:
      data class CreateOrganizationRequest(
        val name: String, 
        val contactInformation: String
      )
    • Response:
      data class OrganizationResponse(
        val organizationId: Int, 
        val name: String, 
        val contactInformation: String
      )
  • GET /api/organizations: Retrieve all organizations.

  • GET /api/organizations/{organizationId}: Retrieve a specific organization.

    • Authentication: Required.
    • Permissions: VIEW_ORGANIZATIONS_GLOBAL
    • Response:
      data class OrganizationResponse(
        val organizationId: Int, 
        val name: String, 
        val contactInformation: String
      )
  • PUT /api/organizations/{organizationId}: Update an organization.

    • Authentication: Required.
    • Permissions: MANAGE_ORGANIZATIONS_GLOBAL
    • Request:
      data class UpdateOrganizationRequest(
        val name: String?, 
        val contactInformation: String?
      )
    • Response:
      data class OrganizationResponse(
        val organizationId: Int, 
        val name: String, 
        val contactInformation: String
      )
  • DELETE /api/organizations/{organizationId}: Delete an organization.

    • Authentication: Required.
    • Permissions: MANAGE_ORGANIZATIONS_GLOBAL
    • Response: StatusResponse

Data Models

data class AcceptInvitationRequest(
  val token: String, 
  val username: String, 
  val password: String, 
  val email: String, 
  val displayName: String
)

data class ApiError(
  val message: String, 
  val details: String?
)

data class ApiResponse<T>(
  val success: Boolean, 
  val data: T?, 
  val error: ApiError?
)

data class CreateCustomerRequest(
  val name: String, 
  val phone: String, 
  val address: String, 
  val notes: String, 
  val organizationId: Int?
)

data class CreateEventRequest(
  val title: String, 
  val date: String, 
  val time: String, 
  val durationMinutes: Int, 
  val location: String?, 
  val description: String?, 
  val inventoryItems: List<EventInventoryItem>, 
  val customerId: Int?, 
  val staffInvites: StaffInviteDetails, 
  val organizationId: Int
)

data class CreateInventoryItemRequest(
  val name: String, 
  val description: String, 
  val quantity: Int, 
  val organizationId: Int?
)

data class CreateInvitationRequest(
  val roleId: Int, 
  val expiresAt: String?, 
  val organizationId: Int?, 
  val note: String?
)

data class CreateOrganizationRequest(
  val name: String, 
  val contactInformation: String
)

data class CreateRoleRequest(
  val roleName: String, 
  val permissions: List<String>
)

data class CreateUserRequest(
  val username: String, 
  val password: String, 
  val email: String, 
  val displayName: String, 
  val roles: List<String> = emptyList(
), 
  val organizationId: Int
)

data class CustomerResponse(
  val customerId: Int, 
  val name: String, 
  val phone: String, 
  val address: String, 
  val notes: String, 
  val organization: OrganizationResponse
)

data class EventInventoryItem(
  val inventoryId: Int, 
  val itemName: String, 
  val quantity: Int
)

data class EventResponse(
  val eventId: Int, 
  val title: String, 
  val date: String, 
  val time: String, 
  val durationMinutes: Int, 
  val location: String?, 
  val description: String?, 
  val inventoryItems: List<EventInventoryItem>, 
  val customer: CustomerResponse?, 
  val rsvps: List<RsvpStatus>, 
  val organization: OrganizationResponse, 
  val openInvitation: Boolean = false, 
  val numberOfStaffNeeded: Int = 0
)

data class EventSummaryResponse(
  val eventId: Int, 
  val title: String, 
  val quantity: Int
)

data class InventoryItemResponse(
  val inventoryId: Int, 
  val name: String, 
  val description: String, 
  val quantity: Int, 
  val events: List<EventSummaryResponse>, 
  val organization: OrganizationResponse
)

data class InventoryUsageReportResponse(
  val inventoryId: Int, 
  val name: String, 
  val usageCount: Int
)

data class InvitationResponse(
  val invitationId: Int, 
  val organizationId: Int, 
  val roleId: Int, 
  val roleName: String, 
  val token: String, 
  val expiresAt: String, 
  val usedByUserId: Int?, 
  val createdAt: String, 
  val note: String?
)

data class LoggedInContextResponse(
  val user: UserResponse, 
  val permissions: List<String>
)

data class LoginRequest(
  val username: String, 
  val password: String
)

data class LoginResponse(
  val token: String, 
  val user: UserResponse
)

data class OrganizationResponse(
  val organizationId: Int, 
  val name: String, 
  val contactInformation: String
)

data class PaginatedResponse<T>(
  val items: List<T>, 
  val total: Long, 
  val offset: Long, 
  val limit: Int
)

data class RoleResponse(
  val roleId: Int, 
  val roleName: String, 
  val permissions: List<String>
)

data class RsvpRequest(
  val availability: String
)

data class RsvpStatus(
  val userId: Int, 
  val displayName: String, 
  val email: String, 
  val availability: String
)

data class StaffDetails(
  val contactInformation: String, 
  val skills: List<String>, 
  val hoursWorked: Int, 
  val phoneNumber: String, 
  val dateOfBirth: String
)

data class StaffHoursReportRequest(
  val startDate: String, 
  val endDate: String
)

data class StaffHoursReportResponse(
  val userId: Int, 
  val username: String, 
  val displayName: String, 
  val totalHoursWorked: Int
)

data class StaffInviteDetails(
  val specificStaffIds: List<Int>?, 
  val openInvitation: Boolean = false, 
  val numberOfStaffNeeded: Int
)

data class StatusResponse(
  val status: String
)

data class TrackInventoryUsageRequest(
  val eventId: Int, 
  val quantity: Int
)

data class UpdateCustomerRequest(
  val name: String?, 
  val phone: String?, 
  val address: String?, 
  val notes: String?, 
  val organizationId: Int?
)

data class UpdateEventRequest(
  val title: String?, 
  val date: String?, 
  val time: String?, 
  val durationMinutes: Int?, 
  val location: String?, 
  val description: String?, 
  val inventoryItems: List<EventInventoryItem>?, 
  val customerId: Int?, 
  val staffInvites: StaffInviteDetails?, 
  val organizationId: Int?
)

data class UpdateInventoryItemRequest(
  val name: String?, 
  val description: String?, 
  val quantity: Int?, 
  val organizationId: Int?
)

data class UpdateOrganizationRequest(
  val name: String?, 
  val contactInformation: String?
)

data class UpdateRoleRequest(
  val roleName: String?, 
  val permissions: List<String>?
)

data class UpdateStaffDetails(
  val contactInformation: String?, 
  val skills: List<String>?, 
  val phoneNumber: String?, 
  val dateOfBirth: String?
)

data class UpdateUserRequest(
  val email: String?, 
  val displayName: String?, 
  val roles: List<String>?, 
  val staffDetails: UpdateStaffDetails?, 
  val organizationId: Int?
)

data class UserResponse(
  val userId: Int, 
  val username: String, 
  val email: String, 
  val displayName: String, 
  val roles: List<String>, 
  val staffDetails: StaffDetails?, 
  val organization: OrganizationResponse
)

data class ValidateInvitationResponse(
  val organizationId: Int, 
  val organizationName: String, 
  val roleName: String
)

API Documentation Generation

This API.md file is generated automatically from the API_TEMPLATE.md file and the backend route definitions.

To regenerate the API.md file, run the following command from the root of the project:

./gradlew generateApiDocs