Initial commit of Doormile CRM Mobile with UI modernizations
This commit is contained in:
252
api.txt
Normal file
252
api.txt
Normal file
@@ -0,0 +1,252 @@
|
||||
|
||||
like how we are doing thi specifer using mobile or wb
|
||||
|
||||
|
||||
To specify whether the survey was taken on mobile or web, you just need to hardcode the registration_source identifier directly into the API request code of your respective frontends.
|
||||
|
||||
This is the most reliable way to handle it, because your mobile codebase uniquely knows it's the mobile app, and your web codebase uniquely knows it's the web app.
|
||||
|
||||
Here is exactly how you handle it in both environments:
|
||||
|
||||
1. In your Flutter (Mobile) App
|
||||
When you build the JSON body to send your POST request via the http package or dio, you simply inject "mobile" and grab the current logged-in user's ID from your local state:
|
||||
|
||||
dart
|
||||
// Inside your Flutter API service
|
||||
Future<void> submitSurvey(String firstName, double lat, double lon, int currentUserId) async {
|
||||
final payload = {
|
||||
"first_name": firstName,
|
||||
// ... other fields
|
||||
"survey_lat": lat,
|
||||
"survey_long": lon,
|
||||
|
||||
// Explicitly tag this as coming from the mobile app
|
||||
"registration_source": "mobile",
|
||||
"registered_by_id": currentUserId
|
||||
};
|
||||
await http.post(
|
||||
Uri.parse('https://api.doormile.com/api/v1/crm/clients'),
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: jsonEncode(payload),
|
||||
);
|
||||
}
|
||||
2. In your React / Web App
|
||||
Similarly, inside your Web frontend's API submission function, you explicitly hardcode "web" as the source:
|
||||
|
||||
javascript
|
||||
// Inside your Web frontend API utility
|
||||
async function submitSurvey(formData, lat, lon, currentUserId) {
|
||||
const payload = {
|
||||
first_name: formData.firstName,
|
||||
// ... other fields
|
||||
survey_lat: lat,
|
||||
survey_long: lon,
|
||||
|
||||
// Explicitly tag this as coming from the web dashboard
|
||||
registration_source: "web",
|
||||
registered_by_id: currentUserId
|
||||
};
|
||||
await fetch('https://api.doormile.com/api/v1/crm/clients', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
}
|
||||
Alternative Option: Backend "User-Agent" Detection
|
||||
If you don't want to pass it manually in the JSON payload, we can modify the Golang backend to automatically detect the platform by reading the HTTP Headers.
|
||||
|
||||
When a request hits your API, Fiber can check the User-Agent header (Flutter usually sends Dart/<version> (dart:io), while Web sends standard browser data like Mozilla/5.0...). Let me know if you would prefer the backend to automate this detection instead!
|
||||
|
||||
12:16 PM
|
||||
|
||||
|
||||
Here are the **GET** and **POST** APIs that are now fully functional and mapped in your backend.
|
||||
|
||||
All endpoints use the base URL path: `http://localhost:8081/api/v1/crm/clients`
|
||||
|
||||
### 1. Create a New Client (POST)
|
||||
**Endpoint:** `POST /api/v1/crm/clients`
|
||||
**Description:** Registers a new client in `doormile_clients`, hashes their password, sets up their auth credentials in `doormile_auth`, and optionally accepts a vector for future AI search.
|
||||
|
||||
**Request Body (JSON):**
|
||||
```json
|
||||
{
|
||||
"first_name": "John",
|
||||
"last_name": "Doe",
|
||||
"email": "john.doe@example.com",
|
||||
"password": "securepassword123",
|
||||
"phone": "+1234567890",
|
||||
"address": "123 Main St, Tech City",
|
||||
"vector": [0.1, 0.5, -0.3] // Optional: For Qdrant AI embedding integration
|
||||
}
|
||||
```
|
||||
|
||||
**Success Response (201 Created):**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"first_name": "John",
|
||||
"last_name": "Doe",
|
||||
"email": "john.doe@example.com",
|
||||
"phone": "+1234567890",
|
||||
"address": "123 Main St, Tech City",
|
||||
"role": "user"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Fetch All Clients (GET)
|
||||
**Endpoint:** `GET /api/v1/crm/clients`
|
||||
**Description:** Returns a list of all registered clients alongside their authentication details (like email and role) by performing a SQL join behind the scenes.
|
||||
|
||||
**Request Body:** None
|
||||
|
||||
**Success Response (200 OK):**
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"first_name": "John",
|
||||
"last_name": "Doe",
|
||||
"email": "john.doe@example.com",
|
||||
"phone": "+1234567890",
|
||||
"address": "123 Main St, Tech City",
|
||||
"role": "user"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"first_name": "Jane",
|
||||
"last_name": "Smith",
|
||||
"email": "jane@example.com",
|
||||
"phone": "+1987654321",
|
||||
"address": "456 Commerce Rd",
|
||||
"role": "user"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Fetch a Specific Client (GET)
|
||||
**Endpoint:** `GET /api/v1/crm/clients/:id`
|
||||
**Description:** Returns the details for a specific client matching the provided ID in the URL.
|
||||
|
||||
**Request Body:** None
|
||||
|
||||
**Success Response (200 OK) for `/api/v1/crm/clients/1`:**
|
||||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"first_name": "John",
|
||||
"last_name": "Doe",
|
||||
"email": "john.doe@example.com",
|
||||
"phone": "+1234567890",
|
||||
"address": "123 Main St, Tech City",
|
||||
"role": "user"
|
||||
}
|
||||
```
|
||||
|
||||
### Implementation Notes:
|
||||
* You can find the exact backend logic for these in `controllers/clientController.go`.
|
||||
* The structured structs representing these API JSON payloads are located in `dto/client.go`.
|
||||
|
||||
Edited client.go
|
||||
Edited client.go
|
||||
Edited clientController.go
|
||||
Ran command: `& "C:\Program Files\Go\bin\go.exe" run main.go`
|
||||
|
||||
This makes perfect sense—having an exact audit trail of exactly *where*, *when*, and *by whom* the survey was captured (alongside whether it was captured in the field on `mobile` or from the office on `web`) is crucial for data integrity.
|
||||
|
||||
I have completely refactored the models, DTOs, and API logic to rename the columns and add these tracking fields. Additionally, I successfully booted up the backend in the background to automatically migrate these changes into your active PostgreSQL database!
|
||||
|
||||
Here is exactly what was updated:
|
||||
|
||||
1. **Renamed GPS Columns**: `latitude` and `longitude` were renamed strictly to `surveylat` and `surveylong` across the database columns and the JSON payload schemas.
|
||||
2. **Registration Origin Tracking**: Added a `registration_source` string field (so you can pass "mobile" or "web").
|
||||
3. **Creator Identifier**: Added a `registered_by_id` (Integer) field to uniquely track the specific logged-in user who submitted the survey payload.
|
||||
|
||||
### Your Updated POST Payload Schema
|
||||
Your `POST /api/v1/crm/clients` payload originating from both your Mobile Flutter App and your Web App should now look exactly like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"first_name": "John",
|
||||
"last_name": "Doe",
|
||||
"email": "john.doe@example.com",
|
||||
"password": "securepassword123",
|
||||
"phone": "+1234567890",
|
||||
"address": "123 Main St, Tech City",
|
||||
"survey_lat": 37.7749,
|
||||
"survey_long": -122.4194,
|
||||
"pincode": "94103",
|
||||
"registration_source": "mobile",
|
||||
"registered_by_id": 42
|
||||
}
|
||||
```
|
||||
|
||||
Whenever you retrieve a client record using `GET /api/v1/crm/clients/:id`, it will return these exact fields so you'll always know the survey's origin platform, the exact location it was plotted, and the user who processed it!
|
||||
|
||||
|
||||
To specify whether the survey was taken on **mobile** or **web**, you just need to hardcode the `registration_source` identifier directly into the API request code of your respective frontends.
|
||||
|
||||
This is the most reliable way to handle it, because your mobile codebase uniquely knows it's the mobile app, and your web codebase uniquely knows it's the web app.
|
||||
|
||||
Here is exactly how you handle it in both environments:
|
||||
|
||||
### 1. In your Flutter (Mobile) App
|
||||
When you build the JSON body to send your POST request via the `http` package or `dio`, you simply inject `"mobile"` and grab the current logged-in user's ID from your local state:
|
||||
|
||||
```dart
|
||||
// Inside your Flutter API service
|
||||
Future<void> submitSurvey(String firstName, double lat, double lon, int currentUserId) async {
|
||||
final payload = {
|
||||
"first_name": firstName,
|
||||
// ... other fields
|
||||
"survey_lat": lat,
|
||||
"survey_long": lon,
|
||||
|
||||
// Explicitly tag this as coming from the mobile app
|
||||
"registration_source": "mobile",
|
||||
"registered_by_id": currentUserId
|
||||
};
|
||||
|
||||
await http.post(
|
||||
Uri.parse('https://api.doormile.com/api/v1/crm/clients'),
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: jsonEncode(payload),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. In your React / Web App
|
||||
Similarly, inside your Web frontend's API submission function, you explicitly hardcode `"web"` as the source:
|
||||
|
||||
```javascript
|
||||
// Inside your Web frontend API utility
|
||||
async function submitSurvey(formData, lat, lon, currentUserId) {
|
||||
const payload = {
|
||||
first_name: formData.firstName,
|
||||
// ... other fields
|
||||
survey_lat: lat,
|
||||
survey_long: lon,
|
||||
|
||||
// Explicitly tag this as coming from the web dashboard
|
||||
registration_source: "web",
|
||||
registered_by_id: currentUserId
|
||||
};
|
||||
|
||||
await fetch('https://api.doormile.com/api/v1/crm/clients', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Alternative Option: Backend "User-Agent" Detection
|
||||
If you don't want to pass it manually in the JSON payload, we can modify the Golang backend to automatically detect the platform by reading the HTTP Headers.
|
||||
|
||||
When a request hits your API, Fiber can check the `User-Agent` header (Flutter usually sends `Dart/<version> (dart:io)`, while Web sends standard browser data like `Mozilla/5.0...`). Let me know if you would prefer the backend to automate this detection instead!
|
||||
|
||||
|
||||
Reference in New Issue
Block a user