Account Operations
Account Operations handles the core functionality for account creation, advanced filtering, and retrieval operations within the administrative interface.
API Endpoints Overview
| Method | Endpoint | Description |
|---|---|---|
GET | /v1/admin/accounts | Retrieve accounts with advanced filtering |
POST | /v1/admin/accounts | Create new administrative account |
GET | /v1/admin/accounts/filters | Get account statistics for filters |
GET | /v1/admin/accounts/:id/people | Get people/contacts associated with account |
Service Methods & Business Logic
Account Retrieval Services
queryAccounts(filters, sort, pagination) - Advanced account filtering system
- Service Method:
accountService.queryAccounts(filters, sort, pagination) - Controller:
accountController.getAccounts - Route:
GET /v1/admin/accounts - Parameters:
status- Comma-separated status filters ('active', 'archived')type- Comma-separated type filters ('main', 'sub')search- Search term across multiple fieldsaccountid- Filter by parent account ID for sub-accountsinclude_pending- Boolean to include/exclude pending accounts (token existence check)page,limit- Pagination parameterssort_by,order- Sorting configuration
- Search Functionality: Multi-field search across:
- Account ID (ObjectId matching)
- Account name (case-insensitive regex)
- Account email (case-insensitive regex)
- Owner name and email (case-insensitive regex)
- Stripe connected account (case-insensitive regex)
- MongoDB Collections:
_accountswith aggregation pipeline including:- Lookup to
_store.promocodesfor promotional codes - Lookup to
_tier-overridesfor plan override information
- Lookup to
- Returns: Paginated response with account data, owner info, promotional codes, and plan override status
Account Creation Services
createAccount({ business, user, send_email, extended_trial, account_pricing_type }) - Complete account setup
- Service Method:
accountService.createAccount({ business, user, send_email, extended_trial, account_pricing_type }) - Controller:
accountController.createAccount - Route:
POST /v1/admin/accounts - Parameters:
business- Business information (name, phone, stripe_customer)user- Owner details (first_name, last_name, email)send_email- Boolean to send welcome emailextended_trial- Extended trial configurationaccount_pricing_type- Account pricing type (defaults to DEFAULT_PRICING_TYPE)
- Process Flow:
- Email Validation: Checks for existing owner accounts with same email
- Transaction Start: Uses MongoDB transaction for atomic operations
- Business Creation: Creates Contact record for business entity
- Domain Assignment: Auto-generates available dashclicks.com subdomain
- Affiliate Code: Generates unique affiliate code
- Account Creation: Creates main account with full configuration
- User Creation: Creates owner user with reset token
- Email Notification: Sends welcome email if requested
- Collections Used:
_accounts,crm.contacts,_users - Returns: Created account and user objects with status confirmation
- SSO settings (main_menu, app_drawer)
- Conversation preferences with live chat configuration
- Office hours and availability settings
- Required information collection settings
- Email Notifications: Optional welcome email with account setup instructions
- Extended Trial Support: Optional extended trial period configuration
- MongoDB Collections:
_accounts,crm.contactswith transaction support - Returns: Created account and user data with status confirmation
Account People Services
getPeopleOfAccount({ accountId }) - Retrieve people associated with an account
- Service Method:
accountService.getPeopleOfAccount({ accountId }) - Controller:
accountController.getPeopleOfAccount - Route:
GET /v1/admin/accounts/:id/people - Parameters:
accountId- Account ID from URL parameter
- Process Flow:
- Account Lookup: Finds account by ID
- Business Population: Populates business contact from
crm.contacts - People Aggregation: Retrieves all people associated with the business entity
- Contact Details: Returns complete contact information for each person
- MongoDB Collections:
_accountswith lookup tocrm.contacts - Returns: Array of people/contacts associated with the account's business entity
Technical Implementation Details
Advanced Filtering Pipeline
const accountFiltering = {
// Status filtering (active/archived)
statusMatch: {
$and: [
{
active: filters.status.includes('active') ? true : { $ne: true },
},
],
},
// Account type filtering (main/sub)
typeMatch: {
main: filters.type.includes('main') ? true : { $ne: true },
},
// Search across multiple fields
searchMatch: {
$or: [
{ _id: { $eq: new ObjectId(searchTerm) } },
{ name: { $regex: searchTerm, $options: 'i' } },
{ email: { $regex: searchTerm, $options: 'i' } },
{ 'owner.name': { $regex: searchTerm, $options: 'i' } },
{ 'owner.email': { $regex: searchTerm, $options: 'i' } },
{ stripe_connected_account: { $regex: searchTerm, $options: 'i' } },
],
},
};
Account Creation Transaction
await withTransaction(async session => {
// 1. Create business contact entity
const newBiz = await new Contact({
name: business.name,
email: user.email,
type: 'business',
locked: true,
phone: business.phone,
}).save({ session });
// 2. Generate unique domain
const domain = generateUniqueDomain(business.name);
// 3. Generate affiliate code
const affiliateCode = generateUniqueAffiliateCode();
// 4. Create account with full configuration
const newAccount = await new Account({
active: true,
main: true,
business: newBiz._id,
verified: new Date(),
pricing_type: account_pricing_type,
domain: { dashclicks: domain },
affiliate: { code: affiliateCode, clicks: 0, level: 1 },
preferences: {
/* complete preference structure */
},
}).save({ session });
// 5. Update business with account reference
newBiz.account = newAccount._id;
await newBiz.save({ session });
// 6. Create user with JWT token
const token = jwt.sign({ email: user.email, account: newAccount._id }, process.env.APP_SECRET, {
expiresIn: 84600,
});
const newUser = await new User({
name: `${user.first_name} ${user.last_name}`,
first_name: user.first_name,
last_name: user.last_name,
email: user.email,
account: newAccount._id,
active: true,
is_owner: true,
verified: new Date(),
phone: business.phone,
reset_token: token,
}).save({ session });
});
Domain Generation Logic
const generateUniqueDomain = async businessName => {
let domain = businessName.replace(/[\W_]+/g, '').toLowerCase();
let available = false;
let postfix = 0;
// Check against v1 domains list
const v1Domains = require('../../accounts/v1-domains.json');
while (!available) {
const tentativeDomain = `${domain}${postfix || ''}.${
process.env.DASHBOARD_DOMAIN || 'dashclicks.com'
}`.toLowerCase();
// Check v1 compatibility
const v1Check = v1Domains.find(d => d.toLowerCase() === tentativeDomain);
if (v1Check) {
postfix++;
continue;
}
// Check database availability
const existingAccount = await Account.findOne({
'domain.dashclicks': tentativeDomain,
});
if (!existingAccount) {
available = true;
return tentativeDomain;
} else {
postfix++;
}
}
};
API Response Formats
Account Query Response
{
"success": true,
"message": "SUCCESS",
"data": [
{
"id": "account_id",
"active": true,
"main": true,
"business": "business_contact_id",
"stripe_connected_account": "acct_xxxxx",
"stripe_customer": "cus_xxxxx",
"pricing_type": "standard",
"plan_override_enabled": false,
"promocodes": [
{
"_id": "promo_id",
"code": "DISCOUNT10",
"active": true,
"created": "2024-10-01T00:00:00.000Z",
"expires_at": "2024-12-31T23:59:59.999Z"
}
],
"acc_info": {
"id": "account_id",
"name": "Business Name",
"email": "business@example.com"
},
"owner": {
"id": "user_id",
"name": "John Doe",
"email": "john@example.com"
},
"created_at": "2024-10-01T00:00:00.000Z",
"plan_override": null,
"banned": false
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 50,
"pages": 5
}
}
Account Creation Response
{
"statusMessage": "SUCCESS",
"newUser": {
"_id": "user_id",
"name": "John Doe",
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"account": "account_id",
"active": true,
"is_owner": true,
"verified": "2024-10-01T00:00:00.000Z",
"reset_token": "jwt_token_here"
},
"newAccount": {
"_id": "account_id",
"active": true,
"main": true,
"business": "business_contact_id",
"verified": "2024-10-01T00:00:00.000Z",
"pricing_type": "standard",
"domain": {
"dashclicks": "businessname.dashclicks.com"
},
"affiliate": {
"code": "ABC123XYZ",
"clicks": 0,
"level": 1
},
"name": "Business Name",
"email": "business@example.com"
}
}
Account People Response
{
"success": true,
"message": "SUCCESS",
"data": [
{
"id": "account_id",
"people": [
{
"id": "contact_id_1",
"_id": "contact_id_1",
"name": "John Doe",
"email": "john@example.com",
"phone": "+1234567890",
"type": "person"
},
{
"id": "contact_id_2",
"_id": "contact_id_2",
"name": "Jane Smith",
"email": "jane@example.com",
"phone": "+1987654321",
"type": "person"
}
]
}
]
}
Query Parameters
Account Filtering Parameters
status(array) - Filter by account status: ['active', 'archived']type(array) - Filter by account type: ['main', 'sub']accountid(ObjectId) - Filter sub-accounts by parent account IDinclude_pending(boolean) - Include accounts with pending verificationsearch(string) - Search across names, emails, and account identifierssort_by(string) - Sort field (default: 'created')order(string) - Sort order: 'asc' or 'desc' (default: 'desc')page(number) - Page number for paginationlimit(number) - Items per page for pagination
Account Creation Parameters
business(object) - Business information (name, phone, stripe_customer)user(object) - User information (first_name, last_name, email)send_email(boolean) - Send welcome email to new accountextended_trial(object) - Extended trial configuration (optional)account_pricing_type(string) - Pricing type (default: 'standard')
Error Handling
Common Error Scenarios
- 400 Bad Request: Missing required parameters or invalid data format
- 409 Conflict: Account with email already exists
- 500 Internal Server Error: Database transaction failures or external service errors
Account Creation Error Response
{
"success": false,
"message": "An account with that email already exists.",
"errno": 400
}
Usage Examples
Query Accounts with Advanced Filtering
GET /v1/admin/accounts?status=active&type=main&search=acme&sort_by=created&order=desc&page=1&limit=10
X-Session-Id: MongoDB ObjectId
Create New Account
POST /v1/admin/accounts
Content-Type: application/json
X-Session-Id: MongoDB ObjectId
{
"business": {
"name": "ACME Corp",
"phone": "+1234567890",
"stripe_customer": "cus_customer_id"
},
"user": {
"first_name": "John",
"last_name": "Doe",
"email": "john@acme.com"
},
"send_email": true,
"account_pricing_type": "standard"
}
Get Filter Statistics
GET /v1/admin/accounts/filters
X-Session-Id: MongoDB ObjectId
Get Account People
GET /v1/admin/accounts/507f1f77bcf86cd799439011/people
X-Session-Id: MongoDB ObjectId