AIRBNB
FRONTEND GUIDE FOR AI CODING AGENTS - PART 3 - Profile Management
This document is a part of a REST API guide for the airbnb project. It is designed for AI agents that will generate frontend code to consume the project’s backend.
This document includes information and api descriptions about building a profile page in the frontend using the auth service profile api calls, and also in this document the bucket service will be introduced to manage the avatar.
The project has 1 auth service, 1 notification service, 1 BFF service, and 5 business services, plus other helper services such as bucket and realtime. In this document you will use the auth service and bucket service.
Each service is a separate microservice application and listens for HTTP requests at different service URLs.
Services may be deployed to the preview server, staging server, or production server. Therefore, each service has 3 access URLs. The frontend application must support all deployment environments during development, and the user should be able to select the target API server on the home page.
Accessing the backend
Each backend service has its own URL for each deployment environment. Users may want to test the frontend in one of the three deployments—preview, staging, or production. Please ensure that the register and login pages include a deployment server selection option so that, as the frontend coding agent, you can set the base URL for all services.
The base URL of the application in each environment is as follows:
-
Preview:
https://airbnb3.prw.mindbricks.com -
Staging:
https://airbnb3-stage.mindbricks.co -
Production:
https://airbnb3.mindbricks.co
For the auth service, service urls are as follows:
-
Preview:
https://airbnb3.prw.mindbricks.com/auth-api -
Staging:
https://airbnb3-stage.mindbricks.co/auth-api -
Production:
https://airbnb3.mindbricks.co/auth-api
For each other service, the service URL will be given in the service sections.
Any request that requires login must include a valid token in the Bearer authorization header.
Bucket Management
This application has a bucket service used to store user files and other object-related files. The bucket service is login-agnostic, so for write operations or private reads, include a bucket token (provided by services) in the request’s Authorization header as a Bearer token.
Please note that all other business services require the access token in the Bearer header, while the bucket service expects a bucket token because it is login-agnostic. Ensure you manage the required token injection properly; any auth interceptor should not replace the bucket token with the access token.
To access the bucket service in each environement use the bucket service api urls below:
-
Preview:
https://airbnb3.prw.mindbricks.com/bucket -
Staging:
https://airbnb3-stage.mindbricks.co/bucket -
Production:
https://airbnb3.mindbricks.co/bucket
User Bucket This bucket stores public user files for each user.
When a user logs in—or in the
/currentuser
response—there is a
userBucketToken
to use when sending user-related public files to the bucket
service.
{
//...
"userBucketToken": "e56d...."
}
To upload a file
POST {bucketServiceUrl}/upload
The request body is form-data which includes the
bucketId
and the file binary in the
files
field.
{
bucketId: "{userId}-public-user-bucket",
files: {binary}
}
Response status is 200 on success, e.g., body:
{
"success": true,
"data": [
{
"fileId": "9da03f6d-0409-41ad-bb06-225a244ae408",
"originalName": "test (10).png",
"mimeType": "image/png",
"size": 604063,
"status": "uploaded",
"bucketName": "f7103b85-fcda-4dec-92c6-c336f71fd3a2-public-user-bucket",
"isPublic": true,
"downloadUrl": "https://babilcom.mindbricks.co/bucket/download/9da03f6d-0409-41ad-bb06-225a244ae408"
}
]
}
To download a file from the bucket, you need its
fileId. If you upload an avatar or other asset, ensure the download URL
or the
fileId
is stored in the backend.
Buckets are mostly used in object creations that require an additional file, such as a product image or user avatar. After uploading your image to the bucket, insert the returned download URL into the related property of the target object record.
Application Bucket
This Airbnb application also includes a common public bucket that
anyone can read, but only users with the
superAdmin,
admin, or
saasAdmin
roles can write (upload) to it.
When a user with one of these admin roles is logged in, the
/login
response or the
/currentuser
response also returns an
applicationBucketToken
field, which is used when uploading any file to the application
bucket.
{
//...
"applicationBucketToken": "e23fd...."
}
The common public application bucket ID is
"airbnb3-public-common-bucket"
In certain admin areas—such as product management pages—since the user already has the application bucket token, they will be able to upload related object images.
Please configure your UI to upload files to the application bucket using this bucket token whenever needed.
Object Buckets Some objects may also return a bucket token for uploading or accessing files related to that object. For example, in a project management application, when you fetch a project’s data, a public or private bucket token may be provided to upload or download project-related files.
These buckets will be used as described in the relevant object definitions.
Profile Page
Design a profile page to manage (view and edit) user information. The profile page should also be able to upload the user avatar to the user’s public bucket. For bucket information, see the Bucket Management section above.
On the profile page, you will need 4 business APIs:
getUser
,
updateProfile,
updateUserPassword
and
archiveProfile. Do not rely on the
/currentuser
response for profile data, because it contains session
information. The most recent user data is in the user database and
should be accessed via the
getUser
business API.
The
updateProfile,
updateUserPassword
and
archiveProfile
api can only be called by the users themselves. They are designed
specific to the profile page.
The avatar upload component should include an image-cropping component with zoom and pan capabilities. The frontend will send the image to the bucket after it is scaled and cropped.
Do not implement your own cropping component; instead, use the
library component
react-easy-crop
by installing it.
Note that the user cannot change/update their
email
or
roleId.
For password update you should make a separate block in the UI, so
that user can enter old password, new password and confirm new
password before calling the
updateUserPassword.
Here are the 3 auth APIs—getUser
,
updateProfile
and
updateUserPassword— as follows: You can access these APIs through the auth service
base URL,
{appUrl}/auth-api.
Get User
API
This api is used by admin roles or the users themselves to get the user profile information.
Rest Route
The
getUser
API REST controller can be triggered via the following route:
/v1/users/:userId
Rest Request Parameters
The
getUser
api has got 1 request parameter
| Parameter | Type | Required | Population |
|---|---|---|---|
| userId | ID | true | request.params?.userId |
| userId : This id paremeter is used to query the required data object. |
REST Request To access the api you can use the REST controller with the path GET /v1/users/:userId
axios({
method: 'GET',
url: `/v1/users/${userId}`,
data: {
},
params: {
}
});
REST Response
{
"status": "OK",
"statusCode": "200",
"elapsedMs": 126,
"ssoTime": 120,
"source": "db",
"cacheKey": "hexCode",
"userId": "ID",
"sessionId": "ID",
"requestId": "ID",
"dataName": "user",
"method": "GET",
"action": "get",
"appVersion": "Version",
"rowCount": 1,
"user": {
"id": "ID",
"email": "String",
"password": "String",
"fullname": "String",
"avatar": "String",
"roleId": "String",
"emailVerified": "Boolean",
"isActive": true,
"recordVersion": "Integer",
"createdAt": "Date",
"updatedAt": "Date",
"_owner": "ID"
}
}
Update Profile
API
This route is used by users to update their profiles.
Rest Route
The
updateProfile
API REST controller can be triggered via the following route:
/v1/profile/:userId
Rest Request Parameters
The
updateProfile
api has got 3 request parameters
| Parameter | Type | Required | Population |
|---|---|---|---|
| userId | ID | true | request.params?.userId |
| fullname | String | false | request.body?.fullname |
| avatar | String | false | request.body?.avatar |
| userId : This id paremeter is used to select the required data object that will be updated | |||
| fullname : A string value to represent the fullname of the user | |||
| avatar : The avatar url of the user. A random avatar will be generated if not provided |
REST Request To access the api you can use the REST controller with the path PATCH /v1/profile/:userId
axios({
method: 'PATCH',
url: `/v1/profile/${userId}`,
data: {
fullname:"String",
avatar:"String",
},
params: {
}
});
REST Response
{
"status": "OK",
"statusCode": "200",
"elapsedMs": 126,
"ssoTime": 120,
"source": "db",
"cacheKey": "hexCode",
"userId": "ID",
"sessionId": "ID",
"requestId": "ID",
"dataName": "user",
"method": "PATCH",
"action": "update",
"appVersion": "Version",
"rowCount": 1,
"user": {
"id": "ID",
"email": "String",
"password": "String",
"fullname": "String",
"avatar": "String",
"roleId": "String",
"emailVerified": "Boolean",
"isActive": true,
"recordVersion": "Integer",
"createdAt": "Date",
"updatedAt": "Date",
"_owner": "ID"
}
}
Update Userpassword
API
This route is used to update the password of users in the profile page by users themselves
Rest Route
The
updateUserPassword
API REST controller can be triggered via the following route:
/v1/userpassword/:userId
Rest Request Parameters
The
updateUserPassword
api has got 3 request parameters
| Parameter | Type | Required | Population |
|---|---|---|---|
| userId | ID | true | request.params?.userId |
| oldPassword | String | true | request.body?.oldPassword |
| newPassword | String | true | request.body?.newPassword |
| userId : This id paremeter is used to select the required data object that will be updated | |||
| oldPassword : The old password of the user that will be overridden bu the new one. Send for double check. | |||
| newPassword : The new password of the user to be updated |
REST Request To access the api you can use the REST controller with the path PATCH /v1/userpassword/:userId
axios({
method: 'PATCH',
url: `/v1/userpassword/${userId}`,
data: {
oldPassword:"String",
newPassword:"String",
},
params: {
}
});
REST Response
{
"status": "OK",
"statusCode": "200",
"elapsedMs": 126,
"ssoTime": 120,
"source": "db",
"cacheKey": "hexCode",
"userId": "ID",
"sessionId": "ID",
"requestId": "ID",
"dataName": "user",
"method": "PATCH",
"action": "update",
"appVersion": "Version",
"rowCount": 1,
"user": {
"id": "ID",
"email": "String",
"password": "String",
"fullname": "String",
"avatar": "String",
"roleId": "String",
"emailVerified": "Boolean",
"isActive": true,
"recordVersion": "Integer",
"createdAt": "Date",
"updatedAt": "Date",
"_owner": "ID"
}
}
Archiving A Profile
A user may want to archive their profile. So the profile page should include an archive section for the users to archive their accounts. When an account is archived, it is marked as archived and an aarchiveDate is atteched to the profile. All user data is kept in the database for 1 month after user archived. If user tries to login or register with the same email, the account will be activated again. But if no login or register occures in 1 month after archiving, the profile and its related data will be deleted permanenetly. So in the profile page,
- The arcihve options should be accepted after user writes a text like ("ARCHİVE MY ACCOUNT") to a confirmation dialog, so that frontend UX can ensure this is not an unconscious request.
- The user should be warned about the process, that his account will be available for a restore for 1 month.
The archive api, can only be called by the users themselves and its used as follows.
Archive Profile
API
This api is used by users to archive their profiles.
Rest Route
The
archiveProfile
API REST controller can be triggered via the following route:
/v1/archiveprofile/:userId
Rest Request Parameters
The
archiveProfile
api has got 1 request parameter
| Parameter | Type | Required | Population |
|---|---|---|---|
| userId | ID | true | request.params?.userId |
| userId : This id paremeter is used to select the required data object that will be deleted |
REST Request To access the api you can use the REST controller with the path DELETE /v1/archiveprofile/:userId
axios({
method: 'DELETE',
url: `/v1/archiveprofile/${userId}`,
data: {
},
params: {
}
});
REST Response
{
"status": "OK",
"statusCode": "200",
"elapsedMs": 126,
"ssoTime": 120,
"source": "db",
"cacheKey": "hexCode",
"userId": "ID",
"sessionId": "ID",
"requestId": "ID",
"dataName": "user",
"method": "DELETE",
"action": "delete",
"appVersion": "Version",
"rowCount": 1,
"user": {
"id": "ID",
"email": "String",
"password": "String",
"fullname": "String",
"avatar": "String",
"roleId": "String",
"emailVerified": "Boolean",
"isActive": false,
"recordVersion": "Integer",
"createdAt": "Date",
"updatedAt": "Date",
"_owner": "ID"
}
}
After you complete this step, please ensure you have not made the following common mistakes:
- The auth API and bucket API are different services, and both URLs should be set according to the selected environment (production, staging, preview).
-
Note that any api call to the application backend is based on a
service base url, in this propmpt all auth apis should be called
by
/auth-apiprefix after application's base url, and bucket apis should be called by/bucketprefix after base url. -
The auth API and bucket API use different tokens. The auth API
requires the
accessTokenin the Bearer header; the bucket API requires bucket-specific tokens such asuserBucketTokenor other application-specific bucket tokens. You may need two separate Axios clients: one for auth (always using the access token) and one for bucket operations (using the relevant bucket token). -
On the profile page, fetch the latest user data from the service
using
getUser. The/currentuserAPI is session-stored data; the latest data is in the database. -
When you upload the avatar image on the profile page, use the
returned download URL as the user’s
avatarproperty and update the user record when the Save button is clicked.
After this prompt, the user may give you new instructions to update your first output or provide subsequent prompts about the project.