253 lines
8.8 KiB
Plaintext
253 lines
8.8 KiB
Plaintext
|
|
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!
|
|
|
|
|