E1-F3: Default Ticketing Profile¶
Epic: E1: User & Profile Management
Size: S (Small)
Problem / Outcome¶
Users need to create and maintain their own ticketing profile before they can purchase tickets. The profile captures identity information required for ticket issuance and stadium entry validation.
Scope¶
In-Scope:
- POST /users/me/profile endpoint (initial creation)
- GET /users/me/profile endpoint (retrieve)
- PUT /users/me/profile endpoint (update)
- Fields: full_name, date_of_birth, nationality, OIB, passport_number, phone
- Pre-population from Drupal profile data (mobile app responsibility)
- Field editability rules
- OIB checksum validation (ISO 7064 MOD 11-10)
Out-of-Scope:
- Profile picture
- Address fields
- Drupal profile synchronization (handled by mobile app)
Profile Creation Flow¶
sequenceDiagram
participant User
participant MobileApp
participant Drupal
participant TicketingAPI
User->>MobileApp: Open ticket purchase
MobileApp->>TicketingAPI: GET /users/me/profile
alt Profile exists
TicketingAPI-->>MobileApp: 200 OK (profile data)
MobileApp-->>User: Show profile / proceed to purchase
else Profile not found
TicketingAPI-->>MobileApp: 404 Not Found
MobileApp->>Drupal: Get user data (name, DOB, etc.)
Drupal-->>MobileApp: User data
MobileApp-->>User: Show pre-filled profile form
User->>MobileApp: Confirm/complete profile (add OIB)
MobileApp->>TicketingAPI: POST /users/me/profile
TicketingAPI-->>MobileApp: 201 Created (profile)
MobileApp-->>User: Profile created, proceed to purchase
end
Business Rules¶
- Profile Required for Purchase: Users cannot purchase tickets until they have created their ticketing profile.
- OIB Global Uniqueness: The OIB in the default profile must be globally unique across all users. Two different users cannot register with the same OIB. This ensures each buyer is uniquely identified.
- OIB Immutability: Once OIB is set, it cannot be changed by the user. Changes require customer support intervention.
- Age Requirement: User must be 18+ to complete the default profile (primary buyer requirement).
- Identity Requirement: Either OIB (Croatian citizens) or passport_number (non-Croatian) must be provided.
- Pre-population: Mobile app may pre-fill fields from Drupal profile, but user must explicitly create the ticketing profile via POST.
Acceptance Criteria¶
- AC1: Given authenticated user without profile, when calling GET /profile, then 404 "Profile not set up yet" is returned
- AC2: Given authenticated user without profile, when calling POST /profile with valid data, then profile is created and 201 returned
- AC3: Given authenticated user with profile, when calling POST /profile, then 409 "Profile already exists" is returned
- AC4: Given authenticated user with profile, when viewing profile, then all profile fields are returned
- AC5: Given complete profile data, when user updates profile via PUT, then changes are saved with timestamp
- AC6: Given OIB already set, when user attempts to change OIB, then error "Cannot change OIB" is returned
- AC7: Given OIB already used by another user, when user attempts to set OIB, then error "This OIB is already registered with another account. If you think this is a mistake, please contact customer support." is returned
- AC8: Given user under 18, when creating profile, then error "Primary buyer must be 18 years or older" is returned
- AC9: Given Croatian nationality without OIB, when creating profile, then error "OIB is required for Croatian citizens" is returned
Data Model Impact¶
UserProfile table:
- user_id (UUID, FK, PK)
- full_name (VARCHAR)
- date_of_birth (DATE)
- nationality (VARCHAR)
- oib (VARCHAR(11), UNIQUE) -- Globally unique constraint
- email (VARCHAR)
- phone (VARCHAR)
- updated_at (TIMESTAMP)
Constraints:
- UNIQUE(oib) - Ensures no two users can have the same OIB in their default profile
Permissions/Roles¶
- Authenticated user
How to Verify¶
npm test -- --grep "default profile"
Expected: Profile CRUD works, OIB immutability enforced.
Dependencies¶
- E1-F1: User Registration API
- E1-F2: User Authentication
Implementation Tasks¶
Last Updated: January 2026