SERVERS

Server :3010 (ai.js)
File:
ai.js
Port:
3010
Protocol:
http
Workers:
cpuCount

Mounts (2)

Server :3001 (app.js)
File:
app.js
Port:
3001
Protocol:
http
Workers:
cpuCount

Mounts (16)

Server :3012 (message.js)
File:
message.js
Port:
3012
Protocol:
http
Workers:
cpuCount

Mounts (1)

Server :3003 (metrics-server.js)
File:
metrics-server.js
Port:
3003
Protocol:
http
Workers:
1
Server :3111 (paypal.js)
File:
paypal.js
Port:
3111
Protocol:
http
Workers:
1
Server :3008 (user.js)
File:
user.js
Port:
3008
Protocol:
http
Workers:
1

Mounts (1)

MOUNTS

/ai → ./routes/ai
Mount Path:
/ai
Router:
./routes/ai
File:
ai.js

Routes (6)

/admin → ./routes/admin
Mount Path:
/admin
Router:
./routes/admin
File:
ai.js

No routes found

/users → ./routes/user
/language → ./routes/language
Mount Path:
/language
Router:
./routes/language
File:
app.js

Routes (5)

/component → ./routes/component
/settings → ./routes/settings
Mount Path:
/settings
Router:
./routes/settings
File:
app.js

Routes (8)

/tarot → ./routes/tarot
Mount Path:
/tarot
Router:
./routes/tarot
File:
app.js

Routes (7)

/help → ./routes/help
Mount Path:
/help
Router:
./routes/help
File:
app.js

Routes (5)

/forecasts → ./routes/forecasts.js
Mount Path:
/forecasts
Router:
./routes/forecasts.js
File:
app.js

Routes (5)

/products → ./routes/products.js
Mount Path:
/products
Router:
./routes/products.js
File:
app.js

Routes (11)

/traits → ./routes/traits
Mount Path:
/traits
Router:
./routes/traits
File:
app.js

Routes (14)

/payments → ./routes/payments
Mount Path:
/payments
Router:
./routes/payments
File:
app.js

No routes found

/journals → ./routes/journals
Mount Path:
/journals
Router:
./routes/journals
File:
app.js

Routes (7)

/affiliate → ./routes/affiliates.js
Mount Path:
/affiliate
Router:
./routes/affiliates.js
File:
app.js

Routes (10)

/events/metrics → ./routes/metrics
Mount Path:
/events/metrics
Router:
./routes/metrics
File:
app.js

Routes (4)

/friends → ./routes/friend
Mount Path:
/friends
Router:
./routes/friend
File:
app.js

Routes (11)

/messages → ./routes/messages
/ai → ./routes/ai
Mount Path:
/ai
Router:
./routes/ai
File:
app.js

Routes (6)

/messages → ./routes/messages
/users → ./routes/user

ROUTES

GET /

Returns a simple health check message to confirm the server is running.

Method:
GET
Path:
/
File:
ai.js

Returns

200 string

GET /

Returns a simple health check message to confirm the server is running.

Method:
GET
Path:
/
File:
app.js

Returns

200 text - "Node Running"

GET /metrics

Exposes Prometheus metrics for scraping.

Method:
GET
Path:
/metrics
File:
metrics-server.js

Returns

200 metricsText:string

Throws

  • 500
GET /

Exposes Prometheus metrics at the root path for convenience.

Method:
GET
Path:
/
File:
metrics-server.js

Returns

200 metricsText:string

Throws

  • 500
POST /metrics/updateMetric

Creates or updates a Prometheus gauge or counter metric.

Method:
POST
Path:
/metrics/updateMetric
File:
metrics-server.js

Parameters

Name Type Description
name string, type:string, value:number, labels:object

Returns

200 message:string

Throws

  • 400 , 500
POST /metrics/pingonline

Records a user's online heartbeat to track active users.

Method:
POST
Path:
/metrics/pingonline
File:
metrics-server.js

Parameters

Name Type Description
uid string

Returns

200 success:boolean, activeUsers:number

Throws

  • 400
GET /metrics/usersonline

Returns the number of currently active users and updates a Prometheus gauge.

Method:
GET
Path:
/metrics/usersonline
File:
metrics-server.js

Returns

200 activeUsers:number

GET /health

Simple health check endpoint that reports service is alive.

Method:
GET
Path:
/health
File:
metrics-server.js

Returns

200 ok:boolean

GET /check

Sends a test email based on query parameters name and who.

Method:
GET
Path:
/check
File:
paypal.js

Parameters

Name Type Description
name string, who:string

Returns

200 string - "Paypal IPN Listener"

Throws

  • 500
GET /

Returns a basic service status string.

Method:
GET
Path:
/
File:
paypal.js

Returns

200 string - "Paypal IPN Listener v5.5.0"

GET /sendtarotemails

Sends intro emails to buyers of the Tarot Deck who have no Intro set and marks them as sent.

Method:
GET
Path:
/sendtarotemails
File:
paypal.js

Returns

200 string - concatenated names of recipients

Throws

  • 500

Models Used

GET /all

Returns all Paypal payment records.

Method:
GET
Path:
/all
File:
paypal.js

Returns

200 Array<Paypal>

Throws

  • 500

Models Used

GET /some

Retrieves Paypal records created within a specific month and year.

Method:
GET
Path:
/some
File:
paypal.js

Parameters

Name Type Description
month number, year:number

Returns

200 Array<Paypal>

Throws

  • 500

Models Used

GET /get

Finds Paypal records by a custom identifier.

Method:
GET
Path:
/get
File:
paypal.js

Parameters

Name Type Description
id string

Returns

200 Array<Paypal>

Throws

  • 500

Models Used

POST /update

Updates a Paypal record by _id and sends confirmation emails to buyer and reader.

Method:
POST
Path:
/update
File:
paypal.js

Parameters

Name Type Description
_id string, payer_email:string, from:string, og_email:string

Returns

200 string - "OK"

Throws

  • 500

Models Used

POST /

Receives Paypal IPN messages, stores a record, and performs basic verification logging.

Method:
POST
Path:
/
File:
paypal.js

Parameters

Name Type Description
item_name string, item_number:string, payment_status:string, mc_gross:string, mc_currency:string, txn_id:string, receiver_email:string, payer_email:string

Returns

200 string - "OK"

Throws

  • 500

Models Used

GET /check

Responds with a simple health-check message and triggers a test email send for provided name/who query params.

Method:
GET
Path:
/check
File:
paypal.js

Parameters

Name Type Description
name string, who:string

Returns

200 string

Throws

  • 500

Models Used

GET /

Root endpoint that returns the service name and version.

Method:
GET
Path:
/
File:
paypal.js

Returns

200 string

Models Used

GET /sendtarotemails

Finds all Paypal records for Tarot Deck preorders that haven't had an intro sent, sends them emails, and marks them as processed.

Method:
GET
Path:
/sendtarotemails
File:
paypal.js

Returns

200 string - concatenated names

Throws

  • 500

Models Used

GET /all

Returns all Paypal records from the database.

Method:
GET
Path:
/all
File:
paypal.js

Returns

200 array

Throws

  • 500

Models Used

GET /some

Returns Paypal records created within a specific month and year.

Method:
GET
Path:
/some
File:
paypal.js

Parameters

Name Type Description
month number, year:number

Returns

200 array

Throws

  • 500

Models Used

POST /update

Updates a Paypal record by _id using the posted body and attempts to notify recipient and reader via email.

Method:
POST
Path:
/update
File:
paypal.js

Parameters

Name Type Description
_id string

Returns

200 string - 'OK' or error object

Throws

  • 500

Models Used

POST /

Main IPN endpoint: accepts PayPal POST notifications, stores a record, responds OK, and attempts to validate the IPN with PayPal.

Method:
POST
Path:
/
File:
paypal.js

Parameters

Name Type Description
item_name string, item_number:string, payment_status:string, mc_gross:string, mc_currency:string, txn_id:string, receiver_email:string, payer_email:string

Returns

200 string - 'OK'

Throws

  • 500

Models Used

GET /a

Logs an affiliate click when a user opens an affiliate link and redirects them to the appropriate store or web page.

Method:
GET
Path:
/a
File:
affiliates.js
Function:
affiliate_code

Parameters

Name Type Description
r string, report:string, screen:string, timezone:string, lang:string, platform:string

Returns

200 unknown - 200 HTML page that redirects to Play Store, App Store resolver, or web URL

Throws

  • 400 (Missing affiliate code), 403 (Bot traffic), 404 (Affiliate not found), 500

Models Used

POST /click

Records a server-side affiliate click when client sends click data (used by mobile SDKs or servers).

Method:
POST
Path:
/click
File:
affiliates.js

Parameters

Name Type Description
code string, productId:string, install_token:string, device_info:object, device_info.language:string, device_info.timezone:string, device_info.screen:string, device_info.platform:string

Returns

201 success: true, message: 'Click recorded', clickId: string, install_token: string|null - or 200 duplicate response

Throws

  • 404 (Affiliate not found), 500

Models Used

GET /a/resolve

Shows a small web page that redirects iOS users to the App Store and receives a resolver token.

Method:
GET
Path:
/a/resolve
File:
affiliates.js

Parameters

Name Type Description
r_token string

Returns

200 unknown - 200 HTML page with App Store link

POST /click/install

Matches a received install event to a prior affiliate click using token first, then heuristic scoring (IP, fingerprint, metadata).

Method:
POST
Path:
/click/install
File:
affiliates.js

Parameters

Name Type Description
install_token string, device_info:object, device_info.language:string, device_info.timezone:string, device_info.screen:string, device_info.platform:string

Returns

200 unknown - 201 JSON with match details (match: 'token'|'heuristic'|'none', affiliate_code?, installId)

Throws

  • 500

Models Used

GET /getAffiliateCodes

Returns a list of active affiliate codes.

Method:
GET
Path:
/getAffiliateCodes
File:
affiliates.js

Parameters

Name Type Description
none any

Returns

200 unknown - 200 JSON array of codes

Throws

  • 500

Models Used

GET /getAllAffiliates

Returns all affiliates sorted by creation date (most recent first).

Method:
GET
Path:
/getAllAffiliates
File:
affiliates.js

Parameters

Name Type Description
none any

Returns

200 unknown - 200 JSON array of affiliate objects

Throws

  • 500

Models Used

GET /getAffiliateClicks

Retrieves all clicks for the affiliate owned by the provided email address.

Method:
GET
Path:
/getAffiliateClicks
File:
affiliates.js

Parameters

Name Type Description
email string

Returns

200 owner:string, code:string, total:number, clicks:array

Throws

  • 400 (Missing email), 404 (Affiliate not found), 500

Models Used

POST /saveAffiliate

Creates or updates an affiliate record for a given email and code.

Method:
POST
Path:
/saveAffiliate
File:
affiliates.js

Parameters

Name Type Description
email string, code:string, status:string

Returns

200 unknown - 200 JSON { Success:boolean, Message:string, Data:affiliate }

Throws

  • 400 (Email and code required), 500

Models Used

GET /getAffiliateStats

Returns weekly click counts for the affiliate owner identified by email.

Method:
GET
Path:
/getAffiliateStats
File:
affiliates.js

Parameters

Name Type Description
email string

Returns

200 owner:string, code:string, weeklyClicks:array

Throws

  • 400 (Missing email), 404 (Affiliate not found), 500

Models Used

GET /getAffiliatePayments

Retrieves payments associated with an affiliate (by owner email) and calculates commission totals.

Method:
GET
Path:
/getAffiliatePayments
File:
affiliates.js

Parameters

Name Type Description
email string

Returns

200 code:string, totalAmount:number, totalCommission:number, payments:array

Throws

  • 400 (Missing email), 404 (Affiliate not found), 500

Models Used

POST /completion

Generates a simple AI completion from a prompt.

Method:
POST
Path:
/completion
File:
ai.js

Parameters

Name Type Description
prompt string, systemMessage:string (optional), temperature:number (optional), maxTokens:number (optional)

Returns

200 content:string - The AI-generated text response.

Throws

  • 400 , 500
POST /getpracticaltips

Generates four practical exercise tips for a user's question using OpenAI and returns the parsed JSON tips.

Method:
POST
Path:
/getpracticaltips
File:
ai.js

Parameters

Name Type Description
question string

Returns

200 jsonObject:object - The parsed JSON object returned by the AI containing tips (e.g., tips array).

Throws

  • 400 , 500
POST /calculatereport

Calculates an astrological or relocation report based on provided chart data and returns the result.

Method:
POST
Path:
/calculatereport
File:
ai.js

Parameters

Name Type Description
chart object, reportType:string, question:string

Returns

200 reportName:string, question:string, report:object - The generated report and related metadata.

Throws

  • 400 , 500

Models Used

GET /asktarotoracle

Fetches a tarot oracle reading for the provided question and returns the oracle's response.

Method:
GET
Path:
/asktarotoracle
File:
ai.js

Parameters

Name Type Description
question string

Returns

200 object - The tarot oracle reading returned by the tarot module (structure depends on tarot.getTarotOracleReading).

Throws

  • 400 , 500

Models Used

POST /generateDataReport

Generates AI-powered data reports (Matrix, Tarot, Transit) with automatic self-rating

Method:
POST
Path:
/generateDataReport
File:
ai.js

Parameters

Name Type Description
reportType string, data:object, metadata:object

Returns

200 report:string, reportType:string, metadata:object

Throws

  • 400 , 500
GET /searchapi

Looks up birth locations matching a small town name using an external astrology API and returns them.

Method:
GET
Path:
/searchapi
File:
cities.js

Parameters

Name Type Description
id string

Returns

200 Array of location objects

Throws

  • 500

External APIs Called

GET /getapi/:id

Fetches detailed city information for a town name from an external astrology API.

Method:
GET
Path:
/getapi/:id
File:
cities.js

Parameters

Name Type Description
id string

Returns

200 object

Throws

  • 500

External APIs Called

GET /get/:id

Retrieves a city record from the database by its ID.

Method:
GET
Path:
/get/:id
File:
cities.js

Parameters

Name Type Description
id string

Returns

200 Cities document

Throws

  • 404 , 500

Models Used

GET /search

Searches the Cities collection for towns whose full name starts with the given query and returns up to 5 matches.

Method:
GET
Path:
/search
File:
cities.js

Parameters

Name Type Description
id string

Returns

200 Array of objects with FullName

Throws

  • 500

Models Used

GET /populatecity

Downloads region code data from an external API and inserts them into the Region collection.

Method:
GET
Path:
/populatecity
File:
cities.js

Returns

200 Array of inserted region documents

Throws

  • 500

Models Used

External APIs Called

GET /update

Starts a recurring background task to update city FullName fields every 5 seconds.

Method:
GET
Path:
/update
File:
cities.js

Returns

200 started timer

GET /test

Returns cities whose name matches "Albuquerque" from an in-memory cities array.

Method:
GET
Path:
/test
File:
cities.js

Returns

200 Array

GET /populate

Builds city documents from an in-memory cities array and inserts them into the Cities collection.

Method:
GET
Path:
/populate
File:
cities.js

Returns

200 Array of inserted documents

Models Used

GET /component/healthz

Liveness + database readiness probe. Declared before the other routes so it cannot be shadowed by a parameterised path, and so it stays reachable when everything below is failing. Reads the existing mongoose connection only -- it does not create or configure one. Under /component rather than the root because IIS only proxies specific prefixes through to Node; a root /healthz returns IIS's 403 and never arrives here.

Method:
GET
Path:
/component/healthz
File:
component.js

Returns

200 ok:true - when Mongo answers a ping, 503 otherwise

GET /Delete

Deletes component items that match the provided ComponentName and Category.

Method:
GET
Path:
/Delete
File:
component.js

Parameters

Name Type Description
ComponentName string, Category:string

Returns

200 "Ok"

Throws

  • 500

Models Used

POST /Update

Updates or creates component entries with the provided fields.

Method:
POST
Path:
/Update
File:
component.js

Parameters

Name Type Description
component string, category:string, id:string, description:string, image:string, phrase:string

Returns

200 "OK"

Throws

  • 500

Models Used

GET /FlushDelete

Removes all forecast components in English.

Method:
GET
Path:
/FlushDelete
File:
component.js

Returns

200 "Ok"

Throws

  • 500

Models Used

GET /CheckForDuplicateKeys

Scans components in a category for reversed-key duplicates and removes the shorter description entry.

Method:
GET
Path:
/CheckForDuplicateKeys
File:
component.js

Parameters

Name Type Description
Category string

Returns

200 "Duplicate key check complete"

Throws

  • 500

Models Used

GET /UpdateServerComponent

Updates server components by fetching horoscope items and saving descriptions when available.

Method:
GET
Path:
/UpdateServerComponent
File:
component.js

Returns

200 "Update server component process complete"

Throws

  • 500

Models Used

GET /CleanUpComponents

Cleans up component collection: removes items with 'Earth' in Component or aligns Component to Key.

Method:
GET
Path:
/CleanUpComponents
File:
component.js

Returns

200 "Cleanup complete"

Throws

  • 500

Models Used

GET /GetLanguageTable

Retrieves language tags for the requested language.

Method:
GET
Path:
/GetLanguageTable
File:
component.js

Parameters

Name Type Description
Language string

Returns

200 unknown - 200 [{Name, Value}]

Throws

  • 500

Models Used

GET /TranslateItems

Triggers translation checks for items of a specific type into a given language.

Method:
GET
Path:
/TranslateItems
File:
component.js

Parameters

Name Type Description
Language string, type:string

Returns

200 unknown - 200

Throws

  • 500

Models Used

GET /GetLanguageItem

Returns a translated language item if present, otherwise translates on demand and stores it.

Method:
GET
Path:
/GetLanguageItem
File:
component.js

Parameters

Name Type Description
Language string, Name:string

Returns

200 Language item

Throws

  • 500

Models Used

GET /GetComponentTraits/:component/:componentCategory

Retrieves traits associated with a specific component and component category.

Method:
GET
Path:
/GetComponentTraits/:component/:componentCategory
File:
component.js

Parameters

Name Type Description
component string, componentCategory:string

Returns

200 Array

Throws

  • 500

Models Used

GET /GetComponent

Retrieves a component by name, category, language, and id — uses cache, DB, or main server and returns enriched object.

Method:
GET
Path:
/GetComponent
File:
component.js

Parameters

Name Type Description
Language string, Id:string, Category:string, uid:string, ComponentName:string

Returns

200 Component object

Throws

  • 404 , 500

Models Used

GET /GetCategory

Returns all components in the specified category and language.

Method:
GET
Path:
/GetCategory
File:
component.js

Parameters

Name Type Description
language string, category:string

Returns

200 Array

Throws

  • 500

Models Used

GET /GetCategoryItems

Aggregates category items with view counts and image URLs.

Method:
GET
Path:
/GetCategoryItems
File:
component.js

Parameters

Name Type Description
language string, category:string

Returns

200 Array

Throws

  • 500

Models Used

GET /flush

Clears all entries from the in-memory forecast cache.

Method:
GET
Path:
/flush
File:
forecasts.js

Returns

200 string - "OK"

GET /get

Retrieves forecast items for a supplied date, type, and limit.

Method:
GET
Path:
/get
File:
forecasts.js

Parameters

Name Type Description
date string, limit:number, type:string

Returns

200 Array

Throws

  • 500

Models Used

GET /getForecasts

Retrieves forecasts with caching to reduce database load. If the requested data is not cached, it fetches moon phases and horoscopes and combines them.

Method:
GET
Path:
/getForecasts
File:
forecasts.js

Parameters

Name Type Description
date string, limit:number, type:string

Returns

200 Array

Throws

  • 500

Models Used

GET /get

Retrieves forecast items with caching; older/deprecated version of /get route. This endpoint will check an in-memory cache and otherwise query the forecasts collection.

Method:
GET
Path:
/get
File:
forecasts.js

Parameters

Name Type Description
date string, type:string, limit:number

Returns

200 Array

Throws

  • 500

Models Used

GET /getall

Imports all forecasts from an external API into the local database and clears the cache. This route calls an external service to fetch all forecasts, replaces the local forecasts collection, and stores the items.

Method:
GET
Path:
/getall
File:
forecasts.js

Returns

200 string - "ok"

Throws

  • 500

Models Used

External APIs Called

GET /requests/:uid

Incoming pending requests for a profile (what others sent to me).

Method:
GET
Path:
/requests/:uid
File:
friend.js

Parameters

Name Type Description
uid: string, page, limit any
GET /sent/:uid

Outgoing pending requests sent by a profile.

Method:
GET
Path:
/sent/:uid
File:
friend.js

Parameters

Name Type Description
uid: string, page, limit any
GET /details/:uid

Returns accepted friends with full profile and birth details for the requesting profile. Only ACCEPTED connections are included. Each result includes the friend's handle, name, profileId, and their main user's birth data from the users collection.

Method:
GET
Path:
/details/:uid
File:
friend.js

Parameters

Name Type Description
uid string, page:number, limit:number

Returns

200 friends: [{ friendRecord, profile, mainUser - ], count, totalPages, currentPage }

GET /:userId

Returns a paginated list of accepted friends for a profile and incoming pending requests on page 1.

Method:
GET
Path:
/:userId
File:
friend.js

Parameters

Name Type Description
userId string (uid), page:number, limit:number

Returns

200 requests, friends, count

POST /request

Send a friend request from uid → target profile ObjectId.

Method:
POST
Path:
/request
File:
friend.js

Returns

200 message, friend

PUT /:id/accept

Accept an incoming friend request. Only the recipient (friend field) may accept.

Method:
PUT
Path:
/:id/accept
File:
friend.js

Parameters

Name Type Description
id: Friend record ObjectId any
PUT /:id/reject

Reject an incoming friend request. Only the recipient may reject. Terminal state.

Method:
PUT
Path:
/:id/reject
File:
friend.js
PUT /:id/block

Block a profile. Either party in an existing relationship may block. Bidirectional — the blocked party cannot message or see private data.

Method:
PUT
Path:
/:id/block
File:
friend.js
GET /blocked/:uid

List all connections blocked by a given user.

Method:
GET
Path:
/blocked/:uid
File:
friend.js

Parameters

Name Type Description
uid: string (the user who did the blocking) any
PUT /:id/unblock

Unblock a connection. Only the person who blocked may unblock. Sets status to Deleted so the connection can be re-initiated.

Method:
PUT
Path:
/:id/unblock
File:
friend.js
DELETE /:id

Remove a connection (unfriend). Either party may remove an accepted connection.

Method:
DELETE
Path:
/:id
File:
friend.js
GET /get

Fetches help entries filtered by page, section, or type and returns only entries that have a non-empty description.

Method:
GET
Path:
/get
File:
help.js

Parameters

Name Type Description
page string, section:string, type:string

Returns

200 Array of help objects with non-empty Description

Throws

  • 400 , 500

Models Used

GET /:id

Retrieves a single help entry by its ID.

Method:
GET
Path:
/:id
File:
help.js

Parameters

Name Type Description
id string

Returns

200 Help object

Throws

  • 500

Models Used

POST /

Creates a new help entry in the database.

Method:
POST
Path:
/
File:
help.js

Parameters

Name Type Description
help object

Returns

200 Created help object

Throws

  • 500

Models Used

PUT /:id

Updates an existing help entry by its ID with the provided data.

Method:
PUT
Path:
/:id
File:
help.js

Parameters

Name Type Description
id string, help:object

Returns

200 Updated help object

Throws

  • 500

Models Used

DELETE /:id

Removes a help entry by its ID from the database.

Method:
DELETE
Path:
/:id
File:
help.js

Parameters

Name Type Description
id string

Returns

200 Deleted help object

Throws

  • 500

Models Used

GET /count

Returns a count of journal entries filtered by user ID and optionally by category. Category logic: - 'reports': componentData.reportType contains 'matrix' - 'charts': componentData.chartType exists

Method:
GET
Path:
/count
File:
journals.js

Parameters

Name Type Description
uid string, category:string (either 'reports' or 'charts')

Returns

200 count:number

Throws

  • 400 , 500

Models Used

GET /list

Returns a list of journal entries, optionally filtered by user ID, category, and component.

Method:
GET
Path:
/list
File:
journals.js

Parameters

Name Type Description
limit number, uid:string, category:string, component:string

Returns

200 Array - Array of journal objects

Throws

  • 500

Models Used

GET /get/:id

Retrieves a single journal entry by its ID.

Method:
GET
Path:
/get/:id
File:
journals.js

Parameters

Name Type Description
id string

Returns

200 Object - Journal object

Throws

  • 404 , 500

Models Used

POST /save

Creates a new journal entry for an existing profile.

Method:
POST
Path:
/save
File:
journals.js

Parameters

Name Type Description
profileId string

Returns

201 Object - Created journal object

Throws

  • 404 , 400

Models Used

PUT /edit/:id

Updates an existing journal entry by ID with provided data.

Method:
PUT
Path:
/edit/:id
File:
journals.js

Parameters

Name Type Description
id string

Returns

200 Object - Updated journal object

Throws

  • 400

Models Used

DELETE /delete/:id

Deletes a journal entry by its ID.

Method:
DELETE
Path:
/delete/:id
File:
journals.js

Parameters

Name Type Description
id string

Returns

200 Object - Deleted journal object

Throws

  • 500

Models Used

GET /view/:id

Get journal entry with full component data for viewing

Method:
GET
Path:
/view/:id
File:
journals.js

Parameters

Name Type Description
id string

Returns

200 Object - Journal with complete component data

Throws

  • 404

Models Used

GET /

Retrieves all language tag records from the database.

Method:
GET
Path:
/
File:
language.js

Returns

200 Language[]

Throws

  • 500

Models Used

GET /:id

Retrieves a single language tag by its ID.

Method:
GET
Path:
/:id
File:
language.js

Parameters

Name Type Description
id string

Returns

200 Language

Throws

  • 404 , 500

Models Used

POST /

Saves a new language tag document to the database.

Method:
POST
Path:
/
File:
language.js

Parameters

Name Type Description
body object

Returns

200 Language

Throws

  • 500

Models Used

PUT /:id

Updates an existing language tag by ID and records an update metric.

Method:
PUT
Path:
/:id
File:
language.js

Parameters

Name Type Description
id string, body:object

Returns

200 Language

Throws

  • 500

Models Used

DELETE /:id

Placeholder for deleting a language tag by ID (not implemented).

Method:
DELETE
Path:
/:id
File:
language.js

Parameters

Name Type Description
id string

Returns

204 void

Throws

  • 500

Models Used

POST /SendMessage

Saves a new support message and triggers a user notification.

Method:
POST
Path:
/SendMessage
File:
messages.js

Parameters

Name Type Description
FromEmail string, FromUserId:string, ToUserId:string, Content:string

Returns

200 message:string, data:Message - or 200 { message:'Message ignored.' } when ignored

Throws

  • 500

Models Used

External APIs Called

POST /SendEmail

Sends an email message using the application's message service.

Method:
POST
Path:
/SendEmail
File:
messages.js

Parameters

Name Type Description
FromEmail string, FromUserId:string, ToUserId:string, Content:string

Returns

200 success:boolean, ... - (result from sendEmailMessage)

Throws

  • 400 , 500

Models Used

POST /SendNewMessage

Stores a new message and returns automated support responses based on message content.

Method:
POST
Path:
/SendNewMessage
File:
messages.js

Parameters

Name Type Description
FromEmail string, FromUserId:string, ToUserId:string, Content:string

Returns

200 question:string, options:array - or 200 lookIntoIssueResponse / needToLoginResponse

Throws

  • 500

Models Used

GET /GetUserMessages/:ToUserId

Retrieves conversation summaries for a user, grouped by conversation partner. Each item includes the latest message, unread count, display name/email/avatar, and reply status.

Method:
GET
Path:
/GetUserMessages/:ToUserId
File:
messages.js

Parameters

Name Type Description
ToUserId string

Returns

200 unknown - 200 [ { userId:string, latestMessage:Message, unreadCount:number, replyStatus:string, displayEmail:string, displayName:string, displayAvatar:string, userDetails:{uid:string,name:string,email:string,avatar:string} } ]

Throws

  • 500

Models Used

PUT /mark-seen?from=<senderUid>&to=<recipientUid>

Marks all messages from one user to another as Seen.

Method:
PUT
Path:
/mark-seen?from=<senderUid>&to=<recipientUid>
File:
messages.js
GET /unread-counts?uid=

Returns unread message counts grouped by sender, for a given recipient uid.

Method:
GET
Path:
/unread-counts?uid=
File:
messages.js

Returns

200 counts: { [fromUserId]: number - }

GET /GetMessage/:FromUserId/:ToUserId

Retrieves full chronological message history between two users.

Method:
GET
Path:
/GetMessage/:FromUserId/:ToUserId
File:
messages.js

Parameters

Name Type Description
FromUserId string, ToUserId:string

Returns

200 unknown - 200 [ Message ] (no page/limit, oldest-first)

Throws

  • 500

Models Used

GET /GetNewMessage/:FromUserId/:ToUserId

Fetches messages between two users and returns main support options if none exist.

Method:
GET
Path:
/GetNewMessage/:FromUserId/:ToUserId
File:
messages.js

Parameters

Name Type Description
FromUserId string, ToUserId:string

Returns

200 unknown - 200 [ Message ] or 200 [ mainOptions:string[] ]

Throws

  • 500

Models Used

GET /

Retrieves Prometheus-formatted metrics for scraping by Prometheus.

Method:
GET
Path:
/
File:
metrics.js

Returns

200 string - Prometheus metrics text/plain content

Throws

  • 500
POST /updateMetric

Registers or updates a dynamic Prometheus metric (gauge or counter).

Method:
POST
Path:
/updateMetric
File:
metrics.js

Parameters

Name Type Description
name string, type:string, value:number, labels:object

Returns

200 string - Success message indicating metric updated

Throws

  • 400 , 500
POST /pingonline

Records a user's heartbeat to mark them as online.

Method:
POST
Path:
/pingonline
File:
metrics.js

Parameters

Name Type Description
uid string

Returns

200 success:boolean, activeUsers:number

Throws

  • 400 , 500
GET /usersonline

Returns the current number of active users and reports the value to the external metric endpoint.

Method:
GET
Path:
/usersonline
File:
metrics.js

Returns

200 activeUsers:number

Throws

  • 500

External APIs Called

GET /flush

Clears the in-memory cache used for video and product lookups.

Method:
GET
Path:
/flush
File:
products.js

Returns

200 string - "OK"

Throws

  • 500

Models Used

GET /all

Returns all products that have a ProductID field set.

Method:
GET
Path:
/all
File:
products.js

Returns

200 array - list of products

Throws

  • 500

Models Used

GET /specialvideo

Returns active video products filtered by a tag provided in the query string.

Method:
GET
Path:
/specialvideo
File:
products.js

Parameters

Name Type Description
type string

Returns

200 array - list of videos

Throws

  • 500

Models Used

GET /videos

Returns video products, optionally filtered by a tag type or a title-derived consciousness level. Results are cached in memory keyed by type and title to reduce database queries.

Method:
GET
Path:
/videos
File:
products.js

Parameters

Name Type Description
type string, title:string

Returns

200 array - list of videos

Throws

  • 500

Models Used

GET /allvideos

Returns all products that are videos, sorted by placement.

Method:
GET
Path:
/allvideos
File:
products.js

Returns

200 array - list of all videos

Throws

  • 500

Models Used

GET /getAd

Fetches active advertisement content for a given tag type.

Method:
GET
Path:
/getAd
File:
products.js

Parameters

Name Type Description
type string

Returns

200 array - list of ads

Throws

  • 500

Models Used

GET /getVideoAd

Fetches active advertisement video content for a given tag type.

Method:
GET
Path:
/getVideoAd
File:
products.js

Parameters

Name Type Description
type string

Returns

200 array - list of video ads

Throws

  • 500

Models Used

GET /getAdSummary

Fetches active advertisement content that includes a promo image for a given tag type.

Method:
GET
Path:
/getAdSummary
File:
products.js

Parameters

Name Type Description
type string

Returns

200 array - list of ad summaries with images

Throws

  • 500

Models Used

GET /getAllAd

Returns all advertisement records from the products collection.

Method:
GET
Path:
/getAllAd
File:
products.js

Returns

200 array - list of ads and ad videos

Throws

  • 500

Models Used

POST /updateAd

Updates an existing ad document by _id using the request body data.

Method:
POST
Path:
/updateAd
File:
products.js

Parameters

Name Type Description
_id string

Returns

200 string - "OK"

Throws

  • 500

Models Used

GET /addproducts

Placeholder endpoint intended to add products; currently has no implementation.

Method:
GET
Path:
/addproducts
File:
products.js

Returns

200 empty

Models Used

GET /get/:id

Retrieves a configuration record by its CID, creating a default one if none exists.

Method:
GET
Path:
/get/:id
File:
settings.js

Parameters

Name Type Description
id string

Returns

200 CID:string, Amount:number, Value:number

Throws

  • 404 , 500

Models Used

GET /get

Immediately responds with a small test JSON object to confirm the route is working.

Method:
GET
Path:
/get
File:
settings.js

Returns

200 test:string

Throws

  • 404 , 500
GET /test

Returns a short identifier string "sdk" to confirm the test endpoint is reachable.

Method:
GET
Path:
/test
File:
settings.js

Returns

200 string

Throws

  • 404 , 500
GET /ads-threshold

Returns the ads threshold value for the application. This endpoint can be called by anyone without authentication. Reads from ADS_THRESHOLD environment variable (default: 50)

Method:
GET
Path:
/ads-threshold
File:
settings.js

Returns

200 adsThreshold:number, message:string

Throws

  • 500
GET /ads-interval

Returns the minimum number of minutes allowed between full-screen interstitial ads. This endpoint can be called by anyone without authentication. Reads from ADS_INTERVAL environment variable (default: 3)

Method:
GET
Path:
/ads-interval
File:
settings.js

Returns

200 Success:boolean, adsInterval:number

Throws

  • 500
GET /ads-configs

Returns all ad configuration values from a single MongoDB configs doc.

Method:
GET
Path:
/ads-configs
File:
settings.js

Returns

200 adRefreshMs:number, useRewardAds:boolean, adsThreshold:number, rewardTiers:Array

Throws

  • 500
GET /env-check

Diagnostic endpoint to check if .env is loaded (REMOVE AFTER DEBUGGING)

Method:
GET
Path:
/env-check
File:
settings.js

Returns

200 json - { hasEnv: boolean, dbHost: string (masked), mongoConnected: boolean }

GET /app-update

Returns the in-app update policy so the client can nudge/force users onto a newer build. Values live in a single configs doc (CID: 'AppUpdate') so they can be changed WITHOUT a deploy — important for phased releases: only bump latestVersion/minVersion once the rollout has reached the users you want to move. All fields fall back to safe defaults (disabled) if the doc is missing. Client contract: running < minVersion -> forced (blocking) update minVersion <= running < latest -> soft (dismissable) update nudge running >= latestVersion -> no prompt

Method:
GET
Path:
/app-update
File:
settings.js

Returns

200 enabled, latestVersion, minVersion, message, storeUrl, androidUrl, iosUrl

POST /AddSurvey

Saves a new survey document to the surveys collection.

Method:
POST
Path:
/AddSurvey
File:
survey.js

Returns

200 object - Created survey document

Throws

  • 500

Models Used

POST /AddRating

Saves a new rating to the ratings collection and increments a statsd metric.

Method:
POST
Path:
/AddRating
File:
survey.js

Returns

200 object - Created rating document

Throws

  • 500

Models Used

POST /IncrementLog

Increments a DogStatsD metric based on the Type field in the request body.

Method:
POST
Path:
/IncrementLog
File:
survey.js

Parameters

Name Type Description
Type string

Returns

200 string - "OK"

Throws

  • 500
POST /AIPromptText

Accepts a textual AI prompt request and returns OK (endpoint is currently a placeholder).

Method:
POST
Path:
/AIPromptText
File:
survey.js

Returns

200 string - "OK"

GET /get

Retrieves a tarot card entry by key and type, translating from English if needed.

Method:
GET
Path:
/get
File:
tarot.js

Parameters

Name Type Description
key string, type:string, language:string, reversed:string

Returns

200 Tarot document or translated object with Key, Category, Type, Language, Name, Description

Throws

  • 500

Models Used

POST /addSpread

Saves a new tarot spread document to the database.

Method:
POST
Path:
/addSpread
File:
tarot.js

Parameters

Name Type Description
Group string, Title:string, Cards:string, CardTotal:number, Active:boolean

Returns

200 created TarotSpread document

Throws

  • 500

Models Used

POST /updateSpread/:id

Updates the Active flag of an existing tarot spread by ID.

Method:
POST
Path:
/updateSpread/:id
File:
tarot.js

Parameters

Name Type Description
id string, Active:boolean

Returns

200 string - "OK"

Throws

  • 500

Models Used

GET /createTarotSpreads

Builds a sample tarot spread object in memory (not saved to the database).

Method:
GET
Path:
/createTarotSpreads
File:
tarot.js

Parameters

Name Type Description
none any

Returns

200 sample spread object, not persisted

GET /test2

Simple health-check endpoint.

Method:
GET
Path:
/test2
File:
tarot.js

Returns

200 string - "OK"

GET /test

Simple health-check endpoint.

Method:
GET
Path:
/test
File:
tarot.js

Returns

200 string - "OK"

GET /getTarotSpreads

Retrieves all tarot spread documents, sorted by the Order field ascending.

Method:
GET
Path:
/getTarotSpreads
File:
tarot.js

Parameters

Name Type Description
none any

Returns

200 Array - list of tarot spread documents

Throws

  • 500

Models Used

GET /GetTraits

Provides endpoints to list all trait records in the "Facets" category.

Method:
GET
Path:
/GetTraits
File:
traits.js

Returns

200 Success:boolean, Message:string, Data:array

Throws

  • 500

Models Used

GET /GetTraits/:id

Retrieves a single trait record by its ID.

Method:
GET
Path:
/GetTraits/:id
File:
traits.js

Parameters

Name Type Description
id string

Returns

200 Success:boolean, Message:string, Data:object|string

Throws

  • 500

Models Used

POST /AddTraits

Adds a new trait record using the JSON body provided in the request.

Method:
POST
Path:
/AddTraits
File:
traits.js

Returns

200 Success:boolean, Message:string, Data:object

Throws

  • 500

Models Used

POST /UpdateTraitsByName

Updates a trait's Value by matching Component, ComponentCategory and TraitsCategory fields.

Method:
POST
Path:
/UpdateTraitsByName
File:
traits.js

Parameters

Name Type Description
component string, category:string, traitsCategory:string, newValue:string

Returns

200 message:string, modifiedCount?:number - or 500 { message:string, error:string }

Throws

  • 500

Models Used

PUT /UpdateTraits/:id

Updates a trait by its ID using the JSON body provided.

Method:
PUT
Path:
/UpdateTraits/:id
File:
traits.js

Parameters

Name Type Description
id string

Returns

200 Success:boolean, Message:string, Data:object

Throws

  • 500

Models Used

DELETE /DeleteTraits/:id

Deletes a trait by its ID.

Method:
DELETE
Path:
/DeleteTraits/:id
File:
traits.js

Parameters

Name Type Description
id string

Returns

200 Success:boolean, Message:string, Data:object

Throws

  • 500

Models Used

GET /GetComponentTraits

Retrieves component traits based on query string parameters Component, Category, and TraitsCategory.

Method:
GET
Path:
/GetComponentTraits
File:
traits.js

Parameters

Name Type Description
Component string, Category:string, TraitsCategory:string

Returns

200 Success:boolean, Message:string, Data:array

Throws

  • 500

Models Used

POST /AddComponentTraits

Accepts a request body with component, category, traitsCategory and value fields to add or update a trait.

Method:
POST
Path:
/AddComponentTraits
File:
traits.js

Parameters

Name Type Description
component string, category:string, traitsCategory:string, value:string

Returns

200 Success:boolean, Message:string, Data:object

Throws

  • 500

Models Used

GET /findUser

Finds users by birth date and location and returns a simplified list.

Method:
GET
Path:
/findUser
File:
user.js

Parameters

Name Type Description
day string, month:string, year:string, location:string, key:string

Returns

200 array of {ID, Name, UID, BirthDay, BirthMonth, BirthYear, BirthTime, BirthTown, Lat, Lng, TimeZone, Famous - }

Throws

  • 400 , 403, 500

Models Used

GET /switchAccount

Switches account IDs across profiles and users, and notifies a legacy API.

Method:
GET
Path:
/switchAccount
File:
user.js

Parameters

Name Type Description
key string, oldID:string, newID:string

Returns

200 message:string, profile:{updated:number, skipped:number - , user:{updated:number, skipped:number}, legacyResponse:object|string}

Throws

  • 400 , 403, 500

Models Used

External APIs Called

GET /GetAllUsers

Returns a paginated list of public profiles matching a search query.

Method:
GET
Path:
/GetAllUsers
File:
user.js
Function:
skip

Parameters

Name Type Description
page number, limit:number, uid:string, searchQuery:string

Returns

200 users:array, totalUsers:number, totalPages:number, currentPage:number

Throws

  • 500

Models Used

GET /SearchProfiles

Searches profiles by handle only. Returns no PII — only handle and profileId. Requires the requester to have a registered (non-email) uid. Private profiles are excluded from results.

Method:
GET
Path:
/SearchProfiles
File:
user.js

Parameters

Name Type Description
requesterUid string, searchQuery:string, page:number, limit:number

Returns

200 results: [{ profileId, handle - ], totalResults, totalPages, currentPage }

GET /migratejob

Triggers a background migration job through the migration service.

Method:
GET
Path:
/migratejob
File:
user.js

Parameters

Name Type Description
none any

Returns

200 message:string

Throws

  • 500
POST /start-migration

Starts a migration for a specific user id (uid).

Method:
POST
Path:
/start-migration
File:
user.js

Parameters

Name Type Description
uid string

Returns

200 message:string

Throws

  • 400
POST /deleteUser

Deletes a single user from a profile (soft delete by marking as deleted).

Method:
POST
Path:
/deleteUser
File:
user.js

Parameters

Name Type Description
uid string, profileId:string

Returns

200 message:string, deletedUser:object

Throws

  • 400 , 404, 500

Models Used

POST /erase

Deletes a single user by uid and profileId using post

Method:
POST
Path:
/erase
File:
user.js

Parameters

Name Type Description
uid string, profileId:string

Returns

200 message:string, user:object

Throws

  • 400 , 404

Models Used

DELETE /remove

Deletes a single user by uid and profileId. ( deprecated )

Method:
DELETE
Path:
/remove
File:
user.js

Parameters

Name Type Description
uid string, profileId:string

Returns

200 message:string, user:object

Throws

  • 400 , 404

Models Used

DELETE /removeaccount/:id

Marks a user account and related records as deleted by profile ObjectId.

Method:
DELETE
Path:
/removeaccount/:id
File:
user.js

Parameters

Name Type Description
id string

Returns

200 message:string

Throws

  • 400 , 404, 500

Models Used

DELETE /removeaccount

Deletes a user account and all associated personal data (GDPR compliant). Also calls the legacy RemoveAllData endpoint to purge SQL-side data. Note: Payment records are retained for tax/legal compliance.

Method:
DELETE
Path:
/removeaccount
File:
user.js

Parameters

Name Type Description
uid string, birthday:number, birthmonth:number, birthyear:number

Returns

200 message:string, deletedCollections:array

Throws

  • 400 , 403, 404, 500

Models Used

GET /update-uids-to-lowercase

Converts any non-lowercase user uids to lowercase across the users collection.

Method:
GET
Path:
/update-uids-to-lowercase
File:
user.js

Parameters

Name Type Description
none any

Returns

200 message:string, updatedCount:number

Throws

  • 500

Models Used

GET /user-count

Counts how many user documents exist for a given uid.

Method:
GET
Path:
/user-count
File:
user.js

Parameters

Name Type Description
uid string

Returns

200 uid:string, count:number

Throws

  • 400

Models Used

GET /find-duplicates

Finds duplicate users by profileId and removes non-lowercase duplicates.

Method:
GET
Path:
/find-duplicates
File:
user.js

Parameters

Name Type Description
none any

Returns

200 message:string, deletedIds:array

Throws

  • 500

Models Used

GET /checkpassword/:id

Checks whether a supplied password matches the stored profile password.

Method:
GET
Path:
/checkpassword/:id
File:
user.js

Parameters

Name Type Description
id string, password:string

Returns

200 success:boolean, message:string

Throws

  • 500

Models Used

PUT /setMainUser/:profileId

Sets a user as the main user for their profile. Only one user per uid can be the main user.

Method:
PUT
Path:
/setMainUser/:profileId
File:
user.js

Parameters

Name Type Description
profileId string

Returns

200 message:string, user:object

Throws

  • 400 , 404, 500

Models Used

PUT /edit/:id

Updates a user document identified by profileId with provided body fields (uid/profileId/mainUserId cannot be changed).

Method:
PUT
Path:
/edit/:id
File:
user.js

Parameters

Name Type Description
id string

Returns

200 message:string, user:object

Throws

  • 400 , 404, 500

Models Used

POST /user/Login

Authenticates a user and returns their profileId (obfuscated). Looks up user by uid (email) in profiles collection, validates password, and returns profileId instead of _id to obscure email/uid mapping.

Method:
POST
Path:
/user/Login
File:
user.js

Parameters

Name Type Description
{string} uid - Email/username identifier any
{string} password - User password any

Returns

200 success: true, message: "OK", data: {id: profileId - }

Throws

  • 400 {success: false, message: "InvalidEmail|NotFound|IncorrectPassword"}
  • 500 {success: false, message: "Error message"}

Models Used

POST /adduser

Adds a new user document to the users collection using request body fields.

Method:
POST
Path:
/adduser
File:
user.js

Parameters

Name Type Description
uid string, mainUser:string, name:string, day:number, month:number, year:number, time:string, timeOffset:string, town:string, lat:number, lng:number, noTime:boolean

Returns

200 unknown - 200 savedUser (object)

Throws

  • 500

Models Used

GET /getUsersID/:profileId

Returns user record(s) associated with a given profileId. Replaces connectedusers

Method:
GET
Path:
/getUsersID/:profileId
File:
user.js

Parameters

Name Type Description
profileId string

Returns

200 unknown - 200 array of simplified user objects

Throws

  • 500

Models Used

GET /getUsersID/:profileId

Returns user records associated with a given profileId or uid. First tries to find Profile by profileId to get uid. If not found, assumes input is a uid.

Method:
GET
Path:
/getUsersID/:profileId
File:
user.js

Parameters

Name Type Description
profileId string (can also be uid)

Returns

200 unknown - 200 array of simplified user objects

Throws

  • 500
GET /connectedUsers/:uid

Returns all user records associated with a given uid. DEPRECATED ONLY FOR LEGACY USE

Method:
GET
Path:
/connectedUsers/:uid
File:
user.js

Parameters

Name Type Description
uid string, isFamous:string

Returns

200 unknown - 200 array of simplified user objects

Throws

  • 500

Models Used

GET /handle/available

Quick availability check for a user-chosen handle. Used by the profile editor to give live "available / taken" feedback as the user types.

Method:
GET
Path:
/handle/available
File:
user.js
Function:
handle

Parameters

Name Type Description
handle string (query), uid:string (query, optional — caller's own uid)

Returns

200 handle, valid, available, reason?

Models Used

POST /handle/update

Sets a user-chosen handle. Enforces format + case-insensitive uniqueness.

Method:
POST
Path:
/handle/update
File:
user.js

Parameters

Name Type Description
uid string, handle:string

Returns

200 success:true, handle

Throws

  • 400 invalid format, 404 no profile, 409 taken

Models Used

POST /verifyprofile

Verifies or updates a profile entry and returns the saved profile.

Method:
POST
Path:
/verifyprofile
File:
user.js

Parameters

Name Type Description
uid string, verify:boolean, profileId:string, name:string, handle:string

Returns

200 unknown - 200 updatedProfile (object)

Throws

  • 400 , 500

Models Used

POST /addprofile

DEPRECATED: Adds a profile by fetching details from a legacy API if not present locally.

Method:
POST
Path:
/addprofile
File:
user.js

Parameters

Name Type Description
uid string, profileId:string, profile:string

Returns

200 unknown - 200 profile object or "NOT COMPLETE" / "Select Main User"

Throws

  • 500

Models Used

External APIs Called

GET /log/error

Logs a simple error record using query parameters (uid, msg, url).

Method:
GET
Path:
/log/error
File:
user.js

Parameters

Name Type Description
uid string, msg:string, url:string

Returns

200 unknown - 200 "OK"

Models Used

POST /IncrementLog

Increments a log/error entry using the request body 'Type' field.

Method:
POST
Path:
/IncrementLog
File:
user.js

Parameters

Name Type Description
Type string

Returns

200 unknown - 200 on success or 500 on create error

Models Used

POST /log/posterror

Logs an error using POST body parameters.

Method:
POST
Path:
/log/posterror
File:
user.js

Parameters

Name Type Description
uid string, msg:string, info:string

Returns

200 message:"OK" - or 500

Models Used

GET /find/user

Finds a device by uuid and returns the most used device or "Not Found". DEPRECATED JAN 24.

Method:
GET
Path:
/find/user
File:
user.js

Parameters

Name Type Description
uuid string

Returns

200 unknown - 200 device object or "Not Found"

Models Used

GET /new/start

Increments the metric counter for new user start and returns OK.

Method:
GET
Path:
/new/start
File:
user.js

Parameters

Name Type Description
none any

Returns

200 unknown - 200 "OK"

GET /new/complete

Increments the metric counter for new user completion and returns OK.

Method:
GET
Path:
/new/complete
File:
user.js

Parameters

Name Type Description
none any

Returns

200 unknown - 200 "OK"

GET /store/user

Stores or updates a device session record using query params (uid, uuid, sessions) and request body as update.

Method:
GET
Path:
/store/user
File:
user.js

Parameters

Name Type Description
uid string, uuid:string, sessions:string

Returns

200 unknown - 200 "OK"

Models Used

GET /count/user

Returns the count of non-deleted users and sends a metric; requires a static key '24kk$$5'.

Method:
GET
Path:
/count/user
File:
user.js

Parameters

Name Type Description
key string

Returns

200 userCount:number

Throws

  • 403 , 500

Models Used

GET /count/profile

Returns the count of profiles and sends a metric; requires a static key '24kk$$5'.

Method:
GET
Path:
/count/profile
File:
user.js

Parameters

Name Type Description
key string

Returns

200 profileCount:number

Throws

  • 403 , 500

Models Used

PUT /toggleProfile/:uid

Toggles a profile's privacy flag (isPrivate) for a given uid.

Method:
PUT
Path:
/toggleProfile/:uid
File:
user.js

Parameters

Name Type Description
uid string

Returns

200 success:boolean, message:string, isPrivate:boolean

Throws

  • 404 , 500

Models Used

POST /send-deletion-code

Step 1 — verify credentials + DOB, then email a 6-digit code.

Method:
POST
Path:
/send-deletion-code
File:
user.js
POST /confirm-deletion

Step 2 — verify the code then delete the account.

Method:
POST
Path:
/confirm-deletion
File:
user.js
POST /fcm-token

Saves or updates the FCM device token for a user so Node.js can send push notifications.

Method:
POST
Path:
/fcm-token
File:
user.js

Parameters

Name Type Description
uid string, token:string

Returns

200 success:true - or 400/500

GET /

Returns a simple health-check string indicating the server is running.

Method:
GET
Path:
/
File:
user.js

Returns

200 string

Throws

  • 500

MODELS

Affiliate (affiliates)

Represents an affiliate account used to track referrals and identify partners.

Model:
Affiliate
Collection:
affiliates
File:
Affiliate.js

Schema

Field Type
code String
owner String
email String
status String
created_at Date

Indexes

  • code (unique)

Used By Routes (3)

AffiliateClick (affiliateclicks)

Records individual clicks or installs attributed to an affiliate for tracking conversions.

Model:
AffiliateClick
Collection:
affiliateclicks
File:
Affiliate.js

Schema

Field Type
affiliate ObjectId
ip_address String
user_agent String
device_fingerprint String
device_info Object
type String
status String
meta Object
clicked_at Date

Indexes

  • ip_address+type+clicked_at (compound)

Relations

  • Affiliate (affiliate)
Location (locations)

Stores geographic location details such as name, coordinates, region codes, and population.

Model:
Location
Collection:
locations
File:
Cities.js

Schema

Field Type
Name String
Country String
Lat String
Lng String
RegionCode String
CountryCode String
Province String
FullName String
Population Number
Component (components)

Stores component records with fields like Key, Category, Language and content, and prevents duplicate entries using a unique index.

Model:
Component
Collection:
components
File:
Component.js

Schema

Field Type
Key String
Component String
Category String
Description String
ShortDesc String
Language String
Id String
Phrase String
Image String
DescriptionCount Number
Views Number
AI String
Concept String

Indexes

  • Key+Category+Language+Id (unique)

Used By Routes (7)

Device (devices)

Stores device identifiers, session counts, optional UUIDs, and timestamps for when the record was created.

Model:
Device
Collection:
devices
File:
Device.js

Schema

Field Type
uid String
sessions Number
uuid String
date Date

Used By Routes (2)

Error (errors)

Stores error logs with a user identifier, message, additional info, and a timestamp.

Model:
Error
Collection:
errors
File:
Error.js

Schema

Field Type
uid String
msg String
info String
timestamp Date

Used By Routes (3)

Forecasts (forecasts)

Stores forecasts and horoscope event information for each forecast entry.

Model:
Forecasts
Collection:
forecasts
File:
Forecasts.js

Schema

Field Type
EventID Number
Begins Date
Ends Date
Title String
Sign String
Degree Number
Type String
Description String
Image String
Phrase String
Blurb String
Url String
FullTitle String
SubType String
Report String
PreShadow Date
PostShadow Date
EndDegree Number

Indexes

  • none

Used By Routes (4)

Used By Functions (1)

Friend (friends)

Stores friendship relationships between user profiles and their current status.

Model:
Friend
Collection:
friends
File:
Friend.js

Schema

Field Type
user ObjectId
friend ObjectId
status String
createdAt Date
updatedAt Date

Indexes

  • user+friend (unique)

Relations

  • Profile (user), Profile (friend)
Help (helps)

Stores help articles and their metadata for the application's help pages.

Model:
Help
Collection:
helps
File:
Help.js

Schema

Field Type
HelpId Number
Page String
Section String
Type String
Description String

Used By Routes (5)

Used By Functions (1)

Journal (journals)

Stores journal entries created by users, including metadata and content.

Model:
Journal
Collection:
journals
File:
Journal.js

Schema

Field Type
profileId String
journalId String
created Date
type String
name String
category String
comment String
details String
description String
cards Number

Indexes

  • { profileId: 1, created: -1 }, { journalId: 1 }

Used By Routes (5)

JournalPrompt (journalprompts)

Stores journal prompts linked to astrological events, houses, language, and category.

Model:
JournalPrompt
Collection:
journalprompts
File:
JournalPrompt.js

Schema

Field Type
event String
house String
language String
reflection String
implementation String
ritualMethods String
category String

Indexes

  • event+house+category+language (unique)
Language (languages)

Stores localized language entries with their name, category, type, value and language.

Model:
Language
Collection:
languages
File:
Language.js

Schema

Field Type
Name String
Category String
Type String
Value String
Language String

Used By Routes (8)

Message (messages)

Stores chat message details between users including sender, recipient, content, time and delivery status.

Model:
Message
Collection:
messages
File:
Message.js

Schema

Field Type
FromEmail String
FromUserId String
ToUserId String
Content String
Timestamp Date
Status String

Used By Routes (6)

Used By Functions (3)

Payments (payments)

Stores payment records for users including pricing, timestamps, and platform details.

Model:
Payments
Collection:
payments
File:
Payment.js

Schema

Field Type
uid String
email String
type String
createdAt Date
updatedAt Date
expiredAt Date
price String
priceMicros String
purchaseTime String
currency String
platform String
info String
affiliate_code String

Indexes

  • type+uid (compound, unique)
Paypal (paypals)

Stores PayPal payment and payer information for each transaction.

Model:
Paypal
Collection:
paypals
File:
Paypal.js

Schema

Field Type
item_name String
residence_country String
payment_gross String
payer_id String
payer_email String
first_name String
last_name String
address_name String
address_country String
address_city String
address_state String
address_street String
address_zip String
address_status String
userid String
selectedid String
custom String
createdAt Date
Assigned String
Status String
Return String
Intro String

Used By Routes (11)

Products (products)

Defines the product records stored in the database, including price, images, and metadata for each product.

Model:
Products
Collection:
products
File:
Products.js

Schema

Field Type
Active Boolean
Description String
Discount Number
Image String
Placement Number
Price Number
ProductID Number
Title String
Tag String
Url String
PromoImage String
Text String
ProductType String

Used By Routes (11)

Profile (profiles)

Stores user profile information and securely saves passwords for login.

Model:
Profile
Collection:
profiles
File:
Profile.js

Schema

Field Type
uid String
profileId String
name String
profile String
location String
handle String
password String
dateCreated Date
verified Boolean
dateLastAccessed Date
isPrivate Boolean
isDeleted Boolean
isMigrated Boolean

Indexes

  • uid+profileId (compound, unique)

Used By Routes (8)

Prompts (prompts)

Stores prompt records including component, category, prompt text, job and upscale links for use by the application.

Model:
Prompts
Collection:
prompts
File:
Prompt.js

Schema

Field Type
Component String
Category String
Prompt String
JobID String
JobUrl String
UpscaleID String
UpscaleUrl String
UpscaleNum String
FinalUrl String

Indexes

  • Component+Category (compound, unique)
Ratings (ratings)

Stores user-submitted ratings for specific components within categories.

Model:
Ratings
Collection:
ratings
File:
Rating.js

Schema

Field Type
UserID String
Category String
Component String
Type String
Rating String

Used By Routes (1)

Region (regions)

Stores regional geographic names and identifiers for countries and regions.

Model:
Region
Collection:
regions
File:
Region.js

Schema

Field Type
codeid Number
country String
region String
name2 String
name3 String

Used By Routes (1)

Settings (settings)

Defines a Settings data model that stores a customer identifier (CID), an amount, and a value.

Model:
Settings
Collection:
settings
File:
Settings.js

Schema

Field Type
CID String
Amount Number
Value Number
Stripe (stripes)

Stores Stripe payment configuration and product details used by the application.

Model:
Stripe
Collection:
stripes
File:
Stripe.js

Schema

Field Type
useStripe Number
platform String
paymentMethod String
stripeProducts String
stripeProducts [{id
price Number
link String}]

Indexes

  • none
Survey (surveys)

Stores survey records with a flexible schema so any fields can be saved.

Model:
Survey
Collection:
surveys
File:
Survey.js

Schema

Field Type
dynamic (no fixed fields; strict false)

Indexes

  • none

Used By Routes (1)

Tarot (tarots)

Defines the Tarot card structure stored in MongoDB, describing fields like Key, Name, Type, and whether the card is reversed.

Model:
Tarot
Collection:
tarots
File:
Tarot.js

Schema

Field Type
Key String
Name String
Type String
Category String
Phrase String
Description String
Language String
Reversed Boolean

Used By Routes (1)

Used By Functions (1)

TarotReading (tarotreadings)

Stores tarot reading entries including drawn cards, the user's question, the AI response, timing, and basic metadata.

Model:
TarotReading
Collection:
tarotreadings
File:
TarotReading.js

Schema

Field Type
cards String[]
prompt String
question String
response String
timer Number
createdAt Date
userIp String
TarotSpread (tarotspreads)

Stores tarot spread templates including title, group, cards, and ordering info.

Model:
TarotSpread
Collection:
tarotspreads
File:
TarotSpread.js

Schema

Field Type
Group String
Title String
Cards String
CardTotal Number
Index Number
Order Number
Active Number
Featured String

Indexes

  • none

Used By Routes (3)

Traits (Traits)

Stores personality trait records with category, component, value, language, and rating.

Model:
Traits
Collection:
Traits
File:
Traits.js

Schema

Field Type
TraitsID Number
Component String
ComponentCategory String
TraitsCategory String
Value String
Language String
Rating Number

Indexes

  • none

Used By Routes (9)

User (users)

Stores user birth and account details for each person in the database.

Model:
User
Collection:
users
File:
User.js

Schema

Field Type
uid String
profileId String
name String
day Number
month Number
year Number
time String
timezone String
birthLocation String
lat Number
lng Number
manual Boolean
mainUser Boolean
compatibility String
data String
isDeleted Boolean
mainUserId String
isMigrated Boolean

Indexes

  • uid+profileId (compound, unique, collation: en, strength: 2)

Used By Routes (12)

Views (views)

Records how many times a UI component has been viewed, organized by category and language.

Model:
Views
Collection:
views
File:
Views.js

Schema

Field Type
Component String
Category String
Language String
Views Number

Used By Functions (1)

Views (views)

Exports the Mongoose model so other parts of the application can read and write view counts.

Model:
Views
Collection:
views
File:
Views.js

Used By Functions (1)

Seo (seos)

Stores SEO metadata like title, description and keywords for site components and categories.

Model:
Seo
Collection:
seos
File:
seo.js

Schema

Field Type
Component String
Category String
Title String
Description String
Keywords String
Seo (seos)

Provides the Mongoose model for SEO entries so other files can read and write SEO data.

Model:
Seo
Collection:
seos
File:
seo.js

Schema

Field Type
Component String
Category String
Title String
Description String
Keywords String
Paypal (paypals)

Loads the Paypal Mongoose model used to read and write payment records.

Model:
Paypal
Collection:
paypals
File:
paypal.js

Schema

Field Type
item_name string
Intro string
first_name string
last_name string
_id ObjectId
custom string
createdAt Date
payer_email string
from string
subject string
address_street string
address_city string
address_state string
address_zip string
payment_gross string
og_email string
Assigned string

Used By Routes (11)

Paypal (paypals)

Declares and loads the Paypal model used to read and write payment records.

Model:
Paypal
Collection:
paypals
File:
paypal.js

Schema

Field Type
item_name String
Assigned String
first_name String
last_name String
payer_email String
address_street String
address_city String
address_state String
address_zip String
Intro String
createdAt Date
_id ObjectId

Used By Routes (11)

Config (configs)

Stores configuration entries that track an identifier, an amount, and a numeric value.

Model:
Config
Collection:
configs
File:
settings.js

Schema

Field Type
CID String
Amount Number
Value Number

Used By Routes (1)

Survey (surveys)

Handles survey documents stored in MongoDB; used to create and query surveys.

Model:
Survey
Collection:
surveys
File:
survey.js

Schema

Field Type
fields depend on Survey model (stored in MongoDB) String

Used By Routes (1)

Rating (ratings)

Handles rating documents stored in MongoDB; used to create and query ratings.

Model:
Rating
Collection:
ratings
File:
survey.js

Schema

Field Type
fields depend on Rating model (stored in MongoDB) String

Used By Routes (1)

Component (components)

Manages component metadata stored in MongoDB; used to create and update component documents.

Model:
Component
Collection:
components
File:
survey.js

Schema

Field Type
fields depend on Component model (stored in MongoDB) String

Used By Routes (7)

SEO (seo)

Manages SEO metadata stored in MongoDB; used to create SEO documents for components.

Model:
SEO
Collection:
seo
File:
survey.js

Schema

Field Type
fields depend on SEO model (stored in MongoDB) String
AuraSoma (auraSomas)

Stores AuraSoma bottle details including colors, themes and spiritual information.

Model:
AuraSoma
Collection:
auraSomas
File:
aurasoma.js

Schema

Field Type
bottleName String
plants String
bottleNumber String
colors String
gemsCrystals String
bodyArea String
belongsTo String
relatedPomander String
relatedQuintessence String
mainTheme String
affirmation String
apply String
angelsOfKabbalah String
angelsPrincipalQuality String
description String
dominantCharacteristics String
spiritualLevel String
possibleChallengeAspects String
mentalLevel String
emotionalLevel String

Used By Functions (1)

Message (messages)

Stores user messages and chat content exchanged between users.

Model:
Message
Collection:
messages
File:
messageService.js

Schema

Field Type
FromEmail String
FromUserId String
ToUserId String
Content String
Timestamp Date
Status String

Indexes

  • FromUserId (non-unique), ToUserId (non-unique)

Relations

  • User (FromUserId), User (ToUserId)

Used By Routes (6)

Used By Functions (3)

User (users)

Stores user account information and authentication details.

Model:
User
Collection:
users
File:
messageService.js

Schema

Field Type
_id ObjectId
Email String
Name String
PasswordHash String

Indexes

  • Email (unique)

Relations

  • Message (FromUserId), Message (ToUserId)

Used By Routes (12)

EXTERNAL APIS

api.openai.com (1 endpoint)

Endpoints

POST https://api.openai.com/v1/chat/completions

Configures the OpenAI client used to generate AI-written relocation profiles.

Used By (5)

astromatrix.org (11 endpoints)

Endpoints

POST https://astromatrix.org/API/Astrology/CalculateHoroscopes

Sends chart data to the Astromatrix API to compute horoscope data.

Used By (2)

GET http://astromatrix.org/API/Utility/GetBirthLocations

Looks up birth locations matching a small town name using an external astrology API and returns them.

Used By (1)

GET https://astromatrix.org/API/Utility/GetBirthCityInfo

Fetches detailed city information for a town name from an external astrology API.

Used By (1)

GET http://astromatrix.org/API/Utility/GetRegionCodes

Downloads region code data from an external API and inserts them into the Region collection.

Used By (1)

GET https://astromatrix.org/API/Astrology/GetAllForecasts

Imports all forecasts from an external API into the local database and clears the cache. This route calls an external service to fetch all forecasts, replaces the local forecasts collection, and stores the items.

Used By (1)

GET https://astromatrix.org/Api/notification/SendUserNotification

Saves a new support message and triggers a user notification.

Used By (1)

GET https://astromatrix.org/API/Utility/AddComponentTraits

Sends a GET request to add traits for a specific component to an external astromatrix service.

Used By (1)

GET https://astromatrix.org/API/Utility/HasComponentTraits

Checks whether a component already has traits by querying the astromatrix service.

Used By (1)

GET https://astromatrix.org/API/User/SwitchUserAccount

Switches account IDs across profiles and users, and notifies a legacy API.

Used By (1)

GET https://astromatrix.org/api/user/GetProfile

DEPRECATED: Adds a profile by fetching details from a legacy API if not present locally.

Used By (1)

POST https://astromatrix.org/API/Utility/GetFriends

Migrates users for a single profile UID by calling an external API and saving returned users locally. This function checks if users for the given mainUserId are already migrated, fetches friends from the external API, saves each user into the local users collection, and marks the profile as migrated.

Used By (1)

club.astromatrix.org (1 endpoint)

Endpoints

POST https://club.astromatrix.org/events/metrics/updateMetric

Sends a metric payload to a remote metric ingestion endpoint.

Used By (2)

translation.googleapis.com (1 endpoint)

Endpoints

GET https://translation.googleapis.com/language/translate/v2

Helper that translates a tarot entry into another language and saves the translated entry.

Used By (1)

email.us-west-2.amazonaws.com (1 endpoint)

Endpoints

POST https://email.us-west-2.amazonaws.com

Sends an HTML email via AWS Simple Email Service (SES).

Used By (2)

FUNCTIONS

connectWithRetry [Utility]

Mongoose 5 + useUnifiedTopology does NOT retry a failed INITIAL connect -- it only self-heals after one successful connection. A worker that lost the boot race stayed at readyState 0 for life, buffering every query into a 10s timeout while still taking traffic. Retry instead, jittered so the workers do not all hit server selection at once.

Function:
connectWithRetry
File:
app.js
Type:
Utility
ErrorHandler [Utility]

Mounts messages-related API endpoints under /messages.

Function:
ErrorHandler
File:
app.js
Type:
Utility
ErrorHandler [Utility]

Mounts AI-related API endpoints under /ai.

Function:
ErrorHandler
File:
app.js
Type:
Utility
emailTemplate [Utility]

Connects to MongoDB with the configured host and database.

Function:
emailTemplate
File:
paypal.js
Type:
Utility
emailTemplate [Utility]

Builds a friendly email body and sets sender/subject based on order details. This function prepares the message text for different readers and products.

Function:
emailTemplate
File:
paypal.js
Type:
Utility

Parameters

Name Type Description
obj Object (uses obj.Assigned, obj.item_name, obj.first_name, obj.last_name, obj.payer_email, obj.address_street, obj.address_city, obj.address_state, obj.address_zip, obj.from)

Returns

unknown - string HTML email body

sendEmail [Utility]

Sends an email by calling the external SendAWSEmail utility. This function sends a prepared email object to the email-sending microservice.

Function:
sendEmail
File:
paypal.js
Type:
Utility

Parameters

Name Type Description
obj Object (uses obj.payer_email, obj.from, obj.subject, obj.item_name and emailTemplate output)

Returns

unknown - void

getAsn [Utility]

Looks up ASN and organization for an IP address and caches the result to speed future lookups.

Function:
getAsn
File:
affiliates.js
Type:
Utility

Parameters

Name Type Description
{string} ip - IP address to lookup any

Returns

Promise<{asn:number, org:string, country:string|null - >}

getClientIp [Utility]

Extracts the client's IP address from request headers and connection info, normalizing common proxies.

Function:
getClientIp
File:
affiliates.js
Type:
Utility

Parameters

Name Type Description
{import('express').Request} req - Express request object any

Returns

string - normalized IP address

normalizeIp [Utility]

Cleans and normalizes an IP address string (removes IPv4-mapped prefix, brackets, zone identifiers).

Function:
normalizeIp
File:
affiliates.js
Type:
Utility

Parameters

Name Type Description
{string} ip - raw IP string any

Returns

string - cleaned IP

getIPv6Prefix [Utility]

Returns a short IPv6 prefix (first 4 hextets) useful for coarse matching.

Function:
getIPv6Prefix
File:
affiliates.js
Type:
Utility

Parameters

Name Type Description
{string} ip - IPv6 address any

Returns

string - IPv6 prefix (first 4 segments)

isBot [Utility]

Heuristically determines whether a user-agent string likely belongs to a bot or crawler.

Function:
isBot
File:
affiliates.js
Type:
Utility

Parameters

Name Type Description
{string} ua - user-agent string any

Returns

boolean - true if agent appears to be a bot

prepareCategoryData [Utility]

Combines individual category calculators into a single object for easy access.

Function:
prepareCategoryData
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
planets array Array of planet objects with properties like planet, house, degree, extra.
angles object Object of angle points (asc, mc, ic, dc) with extra metadata.

Returns

unknown - object - Object with wellness, roots, career, love, transformation scoring objects.

grade [Utility]

Converts a numeric score into a human-friendly letter grade and short label.

Function:
grade
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
score number The numeric score to grade.
positive number (optional) Total positive points for polarity context.
negative number (optional) Total negative points for polarity context.

Returns

unknown - string - A short human-readable grade like "A: Excellent" or "D: Challenging".

createScoreObject [Utility]

Creates a fresh score object used by category calculators to collect factors and totals.

Function:
createScoreObject
File:
relocation.js
Type:
Utility

Returns

unknown - object - Score object with positive, negative, net, factor lists, and a grade.

addPositive [Utility]

Records a positive contribution into a score object and notes the reason.

Function:
addPositive
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
scoreObj object Score object returned from createScoreObject.
value number Numeric positive value to add.
reason string Short human-readable reason for the boost.
addNegative [Utility]

Records a negative contribution into a score object and notes the reason.

Function:
addNegative
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
scoreObj object Score object returned from createScoreObject.
value number Numeric negative value to add (should be positive number but is stored negative in context).
reason string Short human-readable reason for the penalty.
finalizeScore [Utility]

Finalizes a score object by applying small boosts/penalties, computing net and grade.

Function:
finalizeScore
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
scoreObj object Score object with collected positives and negatives.

Returns

unknown - object - Mutated score object with net, score, and grade fields computed.

weightCurve [Utility]

Applies a gentle non-linear adjustment to a numeric score to emphasize extremes.

Function:
weightCurve
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
s number The raw net score.

Returns

unknown - number - Adjusted score after curve applied.

scorePlanet [Utility]

Gives a simple numeric weight to a planet based on whether it is considered benefic or malefic.

Function:
scorePlanet
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
planet object Planet object with a "planet" property naming the body.

Returns

unknown - number - Weight value (positive for benefic, negative for malefic, 0 otherwise).

calculateCategoryScores [Utility]

Produces raw category tallies (positive/negative factors) across all planets.

Function:
calculateCategoryScores
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
planets array Array of planet objects with properties planet and house.

Returns

unknown - object - Object with categories wellness, roots, career, love, transformation each containing tallies.

pushScore [Utility]

Helper that pushes a numeric score into a category object and records a readable factor.

Function:
pushScore
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
cat object Category tallies object with positive, negative, factorsPositive, factorsNegative.
score number The score to apply (positive or negative).
factor string Human-readable factor description.
addVirtueBonusFromAngles [Utility]

Adds small "virtue" bonuses to categories when an angle's extra metadata indicates virtue.

Function:
addVirtueBonusFromAngles
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
categoryData object Object with category score objects (wellness, roots, career, love, transformation).
angles object Angle points object with asc, ic, mc, dc which may have .extra.virtue flags.
checkConj [Utility]

Checks if an angle has conjunct planets matching a list and records them as positive/negative on a score object.

Function:
checkConj
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
angle object Angle object that may contain axisConjunct array.
planetList array List of planet names to look for (e.g., ['Jupiter','Venus']).
value number Numeric amount to add if a match is found.
label string Label for the angle used in reason text.
d object Score object (from createScoreObject) to mutate via addPositive/addNegative.
polarity string 'pos' or 'neg' to decide whether to add positive or negative.
prepareWellnessData [Utility]

Builds the wellness score object by scanning planets for placements and conjunctions relevant to health and vitality.

Function:
prepareWellnessData
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
planets array Array of planet objects with properties planet, house, degree, axisConjunct.
angles object Angle objects for asc, mc, ic, dc possibly containing axisConjunct and extra.

Returns

unknown - object - Finalized score object with grade and factors for wellness.

prepareRootsData [Utility]

Builds the roots/home score by scanning for planets in 2nd/4th houses and IC conjunctions.

Function:
prepareRootsData
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
planets array Array of planet objects.
angles object Angle objects potentially containing IC data.

Returns

unknown - object - Finalized score object for roots (home, security).

prepareCareerData [Utility]

Builds the career score by scanning for planets in 10th/6th/2nd houses and MC conjunctions.

Function:
prepareCareerData
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
planets array Array of planet objects.
angles object Angle objects potentially containing MC data.

Returns

unknown - object - Finalized score object for career.

prepareLoveData [Utility]

Builds the love/relationship score by scanning planets in 5th/7th/11th houses and DC conjunctions.

Function:
prepareLoveData
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
planets array Array of planet objects.
angles object Angle objects potentially containing DC data.

Returns

unknown - object - Finalized score object for love and partnerships.

prepareTransformationData [Utility]

Builds the transformation/deep-change score by scanning 8th/12th houses and angle conjunctions.

Function:
prepareTransformationData
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
planets array Array of planet objects.
angles object Angle objects for ic, mc, asc, dc that may trigger transformation.

Returns

unknown - object - Finalized score object for transformation potential.

generatePromptWithExtras [Utility]

Generates a rich prompt (HTML-like) for the AI using location, planets, and computed category data. The prompt includes formatted angles, category summaries, tone guidance, and an action plan request.

Function:
generatePromptWithExtras
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
location string Name of the place being analyzed.
planets array Array of planet objects (used for angle extraction).
categoryData object Scored category objects for wellness, roots, career, love, transformation.
extraData array|string Additional textual data to include (like sabian, HD gates) - optional.

Returns

unknown - string - The assembled prompt to send to the OpenAI API.

getExtra [Utility]

Retrieves extra textual metadata for a single planet or axis, formatted for logging or prompts.

Function:
getExtra
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
planets array Array of planet objects (with possible extra and axisConjunct fields).
planet string Name of the planet or axis to fetch (e.g., "Ascendant", "Sun").

Returns

unknown - string - Human-readable block of text describing the planet/axis, or a not-found message.

withinOrb [Utility]

Determines whether a planet degree lies within a given orb of an axis degree, accounting for wrap-around.

Function:
withinOrb
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
pDegree number The absolute degree of the planet (0-360).
axisDegree number The absolute degree of the axis point (0-360).
orb number Acceptable orb in degrees (default 5).

Returns

unknown - boolean - True if the difference is within the orb, false otherwise.

tagAxisConjunctions [Utility]

Tags planets and axes with nearby axis conjunctions so other routines can react to those close contacts.

Function:
tagAxisConjunctions
File:
relocation.js
Type:
Utility

Parameters

Name Type Description
planets array Array of planet objects, some of which may represent axes like "Ascendant".

Returns

unknown - array - New array of planet objects where each item may include axisConjunct: array|null.

loadPrompt [API Integration]

Main entry: creates a relocation report by calculating scores, assembling a prompt, and calling the OpenAI API. This returns the AI-written relocation profile as text.

Function:
loadPrompt
File:
relocation.js
Type:
API Integration

Parameters

Name Type Description
chart object The input chart object used by reports.calculate to produce planetary positions and metadata.

Returns

unknown - string - Text response from the AI describing relocation considerations for the computed location.

Throws

  • Error - Propagates errors from report calculation or OpenAI API calls.

External APIs Called

calculate [API Integration]

Sends chart data to the Astromatrix API to compute horoscope data.

Function:
calculate
File:
reports.js
Type:
API Integration

Parameters

Name Type Description
chartData object

Returns

object - Raw API response data

Throws

  • Error if the external API call fails

External APIs Called

calculateReport [API Integration]

Runs a monthly horoscope calculation, logs raw transit/forecast lines, and optionally generates a monthly AI reading.

Function:
calculateReport
File:
reports.js
Type:
API Integration

Parameters

Name Type Description
chartData object

Returns

object - Cleaned data or generated monthly reading (if type === "self")

Throws

  • Error if underlying calculation fails

External APIs Called

clean [Utility]

Normalizes raw API result into structured transits, forecasts, natal info, and metadata.

Function:
clean
File:
reports.js
Type:
Utility

Parameters

Name Type Description
result array

Returns

object - { transits:[], forecasts:[], natal:{}, metadata:{} }

cleanTransits [Utility]

Cleans raw transit entries and extracts key fields like planet, house, aspect, dates, and priority.

Function:
cleanTransits
File:
reports.js
Type:
Utility

Parameters

Name Type Description
transits array

Returns

array - Cleaned transit objects

cleanForecasts [Utility]

Cleans raw forecast entries and classifies them as lunations, retrogrades, ingresses, or general transits.

Function:
cleanForecasts
File:
reports.js
Type:
Utility

Parameters

Name Type Description
forecasts array

Returns

array - Cleaned forecast objects

cleanNatal [Utility]

Extracts natal chart points and houses into a consistent structure for later matching.

Function:
cleanNatal
File:
reports.js
Type:
Utility

Parameters

Name Type Description
birthData object

Returns

object - natal { aspects, chakras, facets, points, houses }

calculatePriority [Utility]

Computes a priority score for a transit based on planet, target, house, aspect, and duration.

Function:
calculatePriority
File:
reports.js
Type:
Utility

Parameters

Name Type Description
planet string, targetPlanet:string, house:string, aspect:string, duration:number

Returns

number - priority (higher = more important)

calculateForecastPriority [Utility]

Assigns a priority for forecast events like lunations, retrogrades, and ingress-like items.

Function:
calculateForecastPriority
File:
reports.js
Type:
Utility

Parameters

Name Type Description
type string, retroInfo:object

Returns

number - priority

classifyTerm [Utility]

Classifies an event term length as 'short', 'medium', or 'long' based on duration in days.

Function:
classifyTerm
File:
reports.js
Type:
Utility

Parameters

Name Type Description
duration number

Returns

string - 'short'|'medium'|'long'

aspectTone [Utility]

Maps an aspect name to an overall tone label: harmonious, challenging, or neutral.

Function:
aspectTone
File:
reports.js
Type:
Utility

Parameters

Name Type Description
aspect string

Returns

string - tone

filterByMonth [Utility]

Filters cleaned horoscope data to include only events relevant to a given month and computes facet scores, key dates, and highlight groupings.

Function:
filterByMonth
File:
reports.js
Type:
Utility

Parameters

Name Type Description
data object, year:number, month:number, minPriority:number

Returns

object - filtered result with grouped events, facet scores, facet_tone, key_dates, and summaries

toWeight [Utility]

Converts a priority score into a numeric weight used for summing facet importance.

Function:
toWeight
File:
reports.js
Type:
Utility

Parameters

Name Type Description
item object

Returns

number - weight

addFacetScore [Utility]

Adds a weighted score to a facet's running total.

Function:
addFacetScore
File:
reports.js
Type:
Utility

Parameters

Name Type Description
facetScores object, facet:string, weight:number
bumpFacetTone [Utility]

Increments the harmonious/challenging counters for a facet based on an aspect tone.

Function:
bumpFacetTone
File:
reports.js
Type:
Utility

Parameters

Name Type Description
facet string, tone:string, facetTone:object
addKeyDate [Utility]

Records an event under a specific date if it meets the minimum priority threshold for key dates.

Function:
addKeyDate
File:
reports.js
Type:
Utility

Parameters

Name Type Description
keyDates object, date:string, item:object
logRawTransitForecasts [Utility]

Logs raw transit and forecast entries in a compact, grouped-by-facet format for QA.

Function:
logRawTransitForecasts
File:
reports.js
Type:
Utility

Parameters

Name Type Description
cleaned object
printSummary [Utility]

Prints a human-friendly summary of the filtered data including sections, facets, and weights for debugging.

Function:
printSummary
File:
reports.js
Type:
Utility

Parameters

Name Type Description
data object, year:number, month:number, minPriority:number
buildAIPayload [Utility]

Builds a compact, weighted payload of top facets, highlights, timeline, and forecast notes for AI summarization.

Function:
buildAIPayload
File:
reports.js
Type:
Utility

Parameters

Name Type Description
filteredData object, {year:number, month:number}:object

Returns

object - payload structured for AI input

buildBasePrompt [Utility]

Builds the textual prompt to send to the AI using the month string and structured payload.

Function:
buildBasePrompt
File:
reports.js
Type:
Utility

Parameters

Name Type Description
monthStr string, payload:object

Returns

string - prompt text

callAI [API Integration]

Calls the OpenAI chat completions API using the configured OpenAI client to generate horoscope text.

Function:
callAI
File:
reports.js
Type:
API Integration

Parameters

Name Type Description
prompt string

Returns

string - AI-generated text (or an error placeholder)

External APIs Called

generateMonthlyReading [API Integration]

Runs the complete AI generation pipeline: build payload, log inputs, prompt AI, log output, and return full result for storage or A/B testing.

Function:
generateMonthlyReading
File:
reports.js
Type:
API Integration

Parameters

Name Type Description
filteredData object, {year:number, month:number}:object

Returns

object - { month, ai_input, prompt, result, filteredData }

External APIs Called

categorizeQuestion [Utility]

Categorizes a question by analyzing keywords

Function:
categorizeQuestion
File:
tarotreading.js
Type:
Utility
getRandomTarotCards [Utility]

Draws three random tarot cards using seedrandom for consistency

Function:
getRandomTarotCards
File:
tarotreading.js
Type:
Utility
cleanAndParseJson [Utility]

Cleans and parses JSON response from OpenAI

Function:
cleanAndParseJson
File:
tarotreading.js
Type:
Utility
loadPrompt [Utility]

Load prompt template from file

Function:
loadPrompt
File:
tarotreading.js
Type:
Utility
replaceVariables [Utility]

Replace template variables in prompt

Function:
replaceVariables
File:
tarotreading.js
Type:
Utility
logReading [Utility]

Log reading to monthly log file

Function:
logReading
File:
tarotreading.js
Type:
Utility
getCurrentPromptVersion [Utility]

Get current prompt version from logs

Function:
getCurrentPromptVersion
File:
tarotreading.js
Type:
Utility
getTarotOracleReading [Utility]

Main function to generate a tarot oracle reading

Function:
getTarotOracleReading
File:
tarotreading.js
Type:
Utility

Parameters

Name Type Description
{string} question - The user's question any

Returns

Promise<Object> - Reading result with cards, positions, and interpretation

escapeSingleQuotes [Utility]

Escapes single quotes in a string to make the string safe for embedding in HTML or attributes.

Function:
escapeSingleQuotes
File:
ai.js
Type:
Utility

Parameters

Name Type Description
{string} jsonString - The input string which may contain single quotes. any

Returns

string - The input string with all single quotes replaced by the HTML entity &#39;.

cleanAndParseJson [Utility]

Parses a raw AI response and extracts a JSON object while logging helpful debug information. This function attempts to remove markdown code fences, find the JSON substring, parse it, and validate an expected TarotReading structure.

Function:
cleanAndParseJson
File:
ai.js
Type:
Utility

Parameters

Name Type Description
{string} prompt - The prompt sent to the AI (kept for logging/debug). any
{string} question - The user's question (kept for logging/debug). any
{string} rawResponse - The raw text response returned by the AI that should contain JSON. any

Returns

Object - The parsed JSON object from the AI response.

Throws

  • {Error} When JSON cannot be found, parsed, or does not match the expected structure (e.g., no TarotReading or wrong card count).
tokenise [Utility]

Tokenises an aspect name into sections, treating multi-word bodies (e.g. "Part of Fortune") as single tokens.

Function:
tokenise
File:
astro-naming.js
Type:
Utility

Parameters

Name Type Description
{string} name any

Returns

string[] - tokens

reverseAspectKey [Utility]

Reverses an aspect component name, correctly handling multi-word planet/point names. Strips any leading category prefix (Draconic/Composite/Progressed/Natal) before reversing and re-attaches it afterward. Examples: "Mars Square Uranus" -> "Uranus Square Mars" "North Node Conjunct Part of Fortune" -> "Part of Fortune Conjunct North Node" "Draconic Mars Square Uranus" -> "Draconic Uranus Square Mars"

Function:
reverseAspectKey
File:
astro-naming.js
Type:
Utility

Parameters

Name Type Description
{string} name any

Returns

string

insertNatalBeforeTarget [Utility]

Inserts "Natal" before the second body (the target planet/point) of an aspect, respecting multi-word bodies so the word is never inserted inside a body. This is the canonical Transit Aspect form. "Mars Square Uranus" -> "Mars Square Natal Uranus" "Neptune Opposition Part of Fortune" -> "Neptune Opposition Natal Part of Fortune" "North Node Sextile Jupiter" -> "North Node Sextile Natal Jupiter"

Function:
insertNatalBeforeTarget
File:
astro-naming.js
Type:
Utility

Parameters

Name Type Description
{string} name - Aspect name without "Natal". any

Returns

string

updateTitle [Utility]

Ensures a transit component title includes "Natal" and removes "Transit" for Transit Aspects. Also ensures Draconic/Composite Aspects have the correct prefix on the component name.

Function:
updateTitle
File:
astro-naming.js
Type:
Utility

Parameters

Name Type Description
{string} component - The component title to adjust. any
{string} category - The category name to inspect. any

Returns

string - Adjusted component title.

isValidComponentName [Utility]

Returns true if `name` contains only characters valid in an astrological component key: ASCII letters, spaces, and digits that appear only as part of ordinal-style house tokens (e.g. "1st", "11th" inside "Mars in 11th House"). Rejects anything with apostrophes, parentheses, percent-encoding, SQL injection patterns, or other non-astro punctuation. Should be called AFTER canonicaliseName so casing is already normalised.

Function:
isValidComponentName
File:
astro-naming.js
Type:
Utility

Parameters

Name Type Description
{string} name Canonicalised component name. any

Returns

boolean

isAICreatableCategory [Utility]

True if the on-demand AI creator is allowed to mint components in this category. Expects an ALREADY canonicalised category (call canonicaliseCategory first).

Function:
isAICreatableCategory
File:
astro-naming.js
Type:
Utility

Parameters

Name Type Description
{string} category any

Returns

boolean

articleVariants [Utility]

Name variants differing only by a leading definite article. Tarot card names are stored inconsistently: 15 Major Arcana carry the article ("The Fool", "The Tower") and 19 do not ("Magician", "Empress", "Hierophant", "Death"), and the same split exists in the `tarots` collection. A client asking for "The Magician" therefore matched nothing while "Magician" worked. Matching both ways costs one extra key in an $in and cannot introduce a wrong match — "The X" and "X" are the same card.

Function:
articleVariants
File:
astro-naming.js
Type:
Utility

Parameters

Name Type Description
{string} name any

Returns

string[] - distinct variants to match against, most-specific first

repairWordSplits [Utility]

Rejoins word-split tokens when the joined form is a recognised name. Runs repeatedly so multi-split names collapse fully ("Igu An a" → "Iguan a" → "Iguana").

Function:
repairWordSplits
File:
astro-naming.js
Type:
Utility

Parameters

Name Type Description
{string} s Title-cased name. any

Returns

string

canonicaliseName [Utility]

Normalises a raw component name to its canonical stored form: - normalizeComponentName (abbreviations + Part of Fortune casing) - updateTitle (strips "Transit ", inserts "Natal", adds Draconic/Composite prefix) This is what the AI-write path runs so the stored key always matches what a lookup resolves to.

Function:
canonicaliseName
File:
astro-naming.js
Type:
Utility

Parameters

Name Type Description
{string} name any
{string} category any

Returns

string

run [Utility]

Run a single support task. Designed to be called from an HTTP handler.

Function:
run
File:
autosupport-core.js
Type:
Utility

Parameters

Name Type Description
{object} opts any
{string} opts.mode one of VALID_MODES (e.g. 'write', 'validate') any
{boolean} opts.dry if true, forces dry/preview behaviour any
{number} [opts.limit] optional thread limit any
{function} [opts.log] optional (line string)=>void sink; defaults to console

Returns

Promise<{mode,dry,limit,ok,error? - >}

generateReply [Utility]

Generate a reply for a normalized review.

Function:
generateReply
File:
reviews-common.js
Type:
Utility

Parameters

Name Type Description
{object} review { rating number, text:string }
{object} opts { platform string, replyMax:number }
listTasks [Utility]

List all task names that have a log file, by scanning the logs dir. Lets the viewer auto-discover new tasks without code changes.

Function:
listTasks
File:
runlog.js
Type:
Utility
clearTask [Utility]

Clear (truncate) a single task's log file. Returns true if the file existed.

Function:
clearTask
File:
runlog.js
Type:
Utility
appendRun [Utility]

Append one run record to the task's log file.

Function:
appendRun
File:
runlog.js
Type:
Utility

Parameters

Name Type Description
{string} task e.g. 'support' any
{object} record arbitrary JSON-serialisable run summary any
readRuns [Utility]

Read the most recent N runs for a task, newest first.

Function:
readRuns
File:
runlog.js
Type:
Utility

Parameters

Name Type Description
{string} task any
{number} limit max runs to return (default 20) any
updateLocation [Utility]

Updates a single city document by looking up the province name from the Region collection and saving it.

Function:
updateLocation
File:
cities.js
Type:
Utility

Parameters

Name Type Description
{Object} loc - City document to update any
updateLocations [Utility]

Finds up to 1000 city documents with empty FullName and queues them for updating.

Function:
updateLocations
File:
cities.js
Type:
Utility
doTranslate [Utility]

Translates a component object into the requested language and inserts it into the database.

Function:
doTranslate
File:
component.js
Type:
Utility

Parameters

Name Type Description
{Object} obj - Component object to translate (must include Description). any
{Object} req - Express request object (reads req.query.Language). any
{Object} res - Express response object used to send results or errors. any
addItem [Utility]

Adds a language item to the language collection for non-English entries if missing.

Function:
addItem
File:
component.js
Type:
Utility

Parameters

Name Type Description
{Object} obj - Source component object (uses obj.Language, obj.Key, obj.Category, obj.Component, obj.Phrase). any
{string} type - The type of language entry to add ("Item" or "Phrase"). any
translateItem [Utility]

Translates and stores a language item if not already present for a given language.

Function:
translateItem
File:
component.js
Type:
Utility

Parameters

Name Type Description
{Object} obj - Language item object (expects obj.Value and obj.Type). any
{string} lang - Target language code. any
checkTranslate [Utility]

Iterates English language items of a given type and ensures translations exist for the target language.

Function:
checkTranslate
File:
component.js
Type:
Utility

Parameters

Name Type Description
{string} lang - Target language code. any
{string} type - Type of language items to check (e.g., "Tag"). any
splitCombinedComponent [Utility]

Splits a combined "Planet in Sign in House" component name into its atomic parts. Mirrors the read-side sign+house split logic so generation stays consistent with lookup. Returns null if the name is not a combined sign+house name.

Function:
splitCombinedComponent
File:
component.js
Type:
Utility

Parameters

Name Type Description
{string} name - Component name e.g. "Venus in Aries in 12th House". any

Returns

{ planet:string, signPart:string, housePart:string - | null}

ensureAtomicComponent [Utility]

Generates and stores a single ATOMIC component only if it doesn't already exist with a real description. Never writes combined keys.

Function:
ensureAtomicComponent
File:
component.js
Type:
Utility

Parameters

Name Type Description
{string} name - Atomic component name e.g. "Venus in Aries". any
{string} category - Category for this atomic part. any
createComponentAI [Utility]

Attempts to generate AI content for components that lack meaningful descriptions. For combined "Planet in Sign in House" lookups it generates only the missing ATOMIC parts (the sign part and the house part) and NEVER writes a combined-key doc -- the read path reconstructs combined descriptions from the atomic parts.

Function:
createComponentAI
File:
component.js
Type:
Utility

Parameters

Name Type Description
{Object} obj - Component object (uses obj.Description, obj.Component, obj.Category). any
findComponent [Utility]

Finds a component document by exact or reversed Key to support lookups.

Function:
findComponent
File:
component.js
Type:
Utility

Parameters

Name Type Description
{string} Id - The item Id to search for. any
{string} lang - Language code (e.g., "en"). any
{string} componentName - Component name to search. any
{string} category - Category to constrain search. any

Returns

Promise<Array> - Array of matching component documents.

resolveComponentTraits [Utility]

Resolve a component the way GetComponent does, then return its traits capped the way GetComponent caps the Traits array it embeds. This is the ONE resolution path for traits. Everything that surfaces traits — GetComponent, GetComponentTraits and tarot/get — goes through it, so the three cannot drift: the same card asked for the same way yields the same list. Resolution comes from findComponent, so all of its handling (canonicalisation, reversed aspect keys, category prefixes, the "The Fool"/"Magician" article split) applies here too, and the traits are then read against the name the component is ACTUALLY stored under rather than whatever the caller sent.

Function:
resolveComponentTraits
File:
component.js
Type:
Utility

Parameters

Name Type Description
{string} componentName Raw requested name (canonicalised internally). any
{string} category Raw category (canonicalised internally). any
{string} [lang] Language for the component lookup. Defaults to 'en'. any
{string|number} [Id] Component Id. Defaults to 0. any

Returns

Promise<Array> - capped trait rows; empty when the component does not resolve.

findLatestForecast [Utility]

For Forecasts requested without a valid Id (0 or null), find the most recent matching doc by Key, ignoring Id. Also tries a decan-stripped key for lunar/eclipse events (e.g. "Full Moon in Sagittarius Decan 2" -> "Full Moon in Sagittarius"). "Most recent" = highest Id, then newest _id (ObjectId carries a creation timestamp).

Function:
findLatestForecast
File:
component.js
Type:
Utility

Parameters

Name Type Description
{string} lang - Language code (e.g. "en"). any
{string} componentName - Component/key name to search. any
{string} category - Category to constrain search (expected "Forecasts"). any

Returns

Promise<Object|null> - The most recent matching forecast doc, or null.

updateDescription [Utility]

Removes a specific phrase and everything after it from the description string.

Function:
updateDescription
File:
component.js
Type:
Utility

Parameters

Name Type Description
{Object} obj - Object containing Description field. any
{string} phrase - Phrase indicating where to cut off the description. any

Returns

string - The cleaned description.

handleLanguageSpecificReplacements [Utility]

Adjusts the query for language-specific category and component formatting.

Function:
handleLanguageSpecificReplacements
File:
component.js
Type:
Utility

Parameters

Name Type Description
{Object} query - The request query object (mutated by this function). any
detectCollapseRisk [Utility]

Run BEFORE any AI call. Fast, deterministic, safety-critical.

Function:
detectCollapseRisk
File:
crucible-detection.js
Type:
Utility

Parameters

Name Type Description
{string} query any

Returns

{ detected, state, level, isCrisis, isWithdrawal, isOffering, categories - }

applyOrientSignals [Utility]

Apply signals from orient classifier to profile. Increases confidence based on what was detected.

Function:
applyOrientSignals
File:
crucible-profile.js
Type:
Utility

Parameters

Name Type Description
{Object} profile any
{Object} signals — from orient classifier any

Returns

Object - updated profile

buildContextString [Utility]

Builds a compact context string to inject into classifier and responder prompts. Gracefully degrades when data is missing.

Function:
buildContextString
File:
crucible-profile.js
Type:
Utility
getPrompt [Utility]

Get a prompt by phase name with variable substitution.

Function:
getPrompt
File:
crucible-prompt-loader.js
Type:
Utility

Parameters

Name Type Description
{string} name - Phase name or COLLAPSE_SEVERE / COLLAPSE_EXISTENTIAL / COLLAPSE_MODERATE any
{Object} variables - {{key}} replacements any

Returns

Promise<string>

updateUserState [Utility]

Update state after each interaction

Function:
updateUserState
File:
crucible-state.js
Type:
Utility

Parameters

Name Type Description
{string} userId any
{string} sessionId any
{Object} update any
getSessionContext [Utility]

Build minimal session context for classifier prompt Only behavioral signals — no content

Function:
getSessionContext
File:
crucible-state.js
Type:
Utility

Parameters

Name Type Description
{string} userId any
{string} sessionId any

Returns

Promise<Object>

addDays [Utility]

Adds a number of days to a given date and returns the new date.

Function:
addDays
File:
forecasts.js
Type:
Utility

Parameters

Name Type Description
date Date, days:number

Returns

unknown - Date

getForecast [Data Service]

Fetches forecasts from the database that match the provided date and type. This helper queries the forecasts collection using different filters depending on the requested type.

Function:
getForecast
File:
forecasts.js
Type:
Data Service

Parameters

Name Type Description
date Date, type:string, limit:number

Returns

unknown - Promise<Array>

Models Used

resolveProfileId [Utility]

Resolve a uid string to a Profile ObjectId. Returns null when not found.

Function:
resolveProfileId
File:
friend.js
Type:
Utility
findRecord [Utility]

Find the canonical friend record between two profile ObjectIds regardless of which side initiated the request. Returns null when no record exists.

Function:
findRecord
File:
friend.js
Type:
Utility
getFriendStatus [Utility]

Returns the current connection status between two profile ObjectIds, or null. Exported for use by other routes (e.g. message gating).

Function:
getFriendStatus
File:
friend.js
Type:
Utility
tryTypeQuery [Data Service]

Chooses the appropriate fallback query when page is not provided and returns help entries with non-empty descriptions.

Function:
tryTypeQuery
File:
help.js
Type:
Data Service

Parameters

Name Type Description
section string, type:string

Returns

Array of help objects with non-empty Description

Throws

  • 400

Models Used

findMatchingQuestion [Utility]

Finds a corresponding support question or response object in the astromatrixIssue map.

Function:
findMatchingQuestion
File:
messages.js
Type:
Utility

Parameters

Name Type Description
{string} content - The incoming message content to check against known issues/options. any

Returns

object|null - The matching question/response object or null if none found.

checkRequireLogin [Utility]

Checks whether a given support issue requires the user to be logged in.

Function:
checkRequireLogin
File:
messages.js
Type:
Utility

Parameters

Name Type Description
{string} type - The issue type or message content to evaluate. any

Returns

boolean - True if the issue requires login, otherwise false.

sendAWSEmail [Utility]

Sends an email using AWS SES.

Function:
sendAWSEmail
File:
messages.js
Type:
Utility

Parameters

Name Type Description
{string} to - Recipient email address. any
{string} from - Sender email address. any
{string} subject - Email subject line. any
{string} htmlBody - HTML content of the email. any

Returns

Promise<object> - Returns { success:true, messageId } on success or { success:false, error } on failure.

sendMetric [API Integration]

Sends a metric payload to a remote metric ingestion endpoint.

Function:
sendMetric
File:
metrics.js
Type:
API Integration

Parameters

Name Type Description
name string, type:string, value:number, labels:object, endpoint:string

External APIs Called

ciExact [Utility]

Case-insensitive exact matcher for a uid/email stored in `payments`. Account uids are normalised to lowercase in `users`/`profiles`, but `payments` was written without normalising: 9,782 distinct uids contain uppercase, and 3,264 of those have NO lowercase twin. A `{ uid: uid.toLowerCase() }` lookup therefore cannot see them at all -- 566 of those users hold an ACTIVE record (454 of them lifetime `full_purchase`) and were being shown as free, then told by support that no purchase could be found. Anchored so it stays an exact match, and the input is escaped so an address containing regex metacharacters (e.g. "a+b@x.com") cannot alter the pattern. The collection is small (~47k docs), so the unindexed scan is acceptable here; the durable fix is normalising the stored values -- see scripts/_normalize-payment-uids.js, which must run (and resolve the duplicate uid+type pairs it reports) before these lookups can go back to exact match.

Function:
ciExact
File:
payments.js
Type:
Utility
getConsciousnessLevel [Utility]

Maps a video title to a simple human-readable "consciousness level" label.

Function:
getConsciousnessLevel
File:
products.js
Type:
Utility

Parameters

Name Type Description
title string

Returns

unknown - string

AddComponentTraits [API Integration]

Sends a GET request to add traits for a specific component to an external astromatrix service.

Function:
AddComponentTraits
File:
survey.js
Type:
API Integration

Parameters

Name Type Description
component string, category:string, traitsCategory:string, value:string

External APIs Called

generateAssistantResponse [API Integration]

Generates AI content using OpenAI and updates or creates component and SEO documents depending on the type.

Function:
generateAssistantResponse
File:
survey.js
Type:
API Integration

Parameters

Name Type Description
type string, component:string, category:string, promp:string, temperature:number

Returns

string|null - Assistant response (text) or null

Throws

  • 500

External APIs Called

Models Used

checkComponentTraits [API Integration]

Checks whether a component already has traits by querying the astromatrix service.

Function:
checkComponentTraits
File:
survey.js
Type:
API Integration

Parameters

Name Type Description
component string, category:string, traitcategory:string, callback:function

Returns

unknown - void (calls callback with the response body)

External APIs Called

countWords [Utility]

Counts words in a string by splitting on whitespace.

Function:
countWords
File:
survey.js
Type:
Utility

Parameters

Name Type Description
str string

Returns

unknown - number Number of words in the provided string

generateAI [Utility]

Builds a textual prompt for different AI tasks based on the provided type and inputs. This creates human-friendly instructions used to request AI-generated content.

Function:
generateAI
File:
survey.js
Type:
Utility

Parameters

Name Type Description
type string, title:string, item:string, pre:string, words:string

Returns

unknown - string The prompt text to send to the AI

doTranslate [Data Service]

Translates an English tarot entry into the requested language and saves it. Returns null (never throws) so callers can always safely res.json(response).

Function:
doTranslate
File:
tarot.js
Type:
Data Service

Parameters

Name Type Description
obj object, req.query.language:string, req.query.key:string, res:object

Models Used

attachTraits [Utility]

Look up the traits for a tarot document via the shared component resolver, so tarot/get and GetComponent return the same list for the same card. Never throws — a card is still worth serving if its correspondences cannot be resolved.

Function:
attachTraits
File:
tarot.js
Type:
Utility

Parameters

Name Type Description
{Object} doc A tarot document (needs Key and Category). any

Returns

Promise<Array> - capped trait rows, or [] if none resolve.

limitTraitsPerCategory [Utility]

Cap how many traits of any one TraitsCategory are returned, per schema.xml `serve`.

Function:
limitTraitsPerCategory
File:
traits.js
Type:
Utility
containsZodiacSign [Utility]

Checks whether a given text contains any zodiac sign phrase (like "in Aries").

Function:
containsZodiacSign
File:
traits.js
Type:
Utility

Parameters

Name Type Description
{string} str - The text to check. any

Returns

boolean

removeZodiacSign [Utility]

Removes the first matching zodiac sign phrase from the given text, if present.

Function:
removeZodiacSign
File:
traits.js
Type:
Utility

Parameters

Name Type Description
{string} str - The text to modify. any

Returns

string

switchAspect [Utility]

Swaps the first and third word in a short phrase to try an alternate aspect wording.

Function:
switchAspect
File:
traits.js
Type:
Utility

Parameters

Name Type Description
{string} str - The phrase to switch. any

Returns

string

getComponentTraits [Utility]

Retrieves trait entries that match a component, category, and optional traitsCategory.

Function:
getComponentTraits
File:
traits.js
Type:
Utility

Parameters

Name Type Description
{string|undefined} component - The component to filter by (optional). any
{string} category - The component category to filter by. any
{string|undefined} traitsCategory - The traits category to filter by (optional). any

Returns

Promise<Array> - Array of matching trait documents.

Throws

  • Error
updateComponentTraitsByID [Utility]

Updates the Value of a trait entry given its ID.

Function:
updateComponentTraitsByID
File:
traits.js
Type:
Utility

Parameters

Name Type Description
{string} id - The MongoDB document ID to update. any
{any} value - The new value to set. any

Returns

Promise<{Success:boolean,Message:string,Data:array - >}

updateItemView [Data Service]

Increments the view counter for a given component/category/language, or creates a new record with Views = 1 if none exists.

Function:
updateItemView
File:
views.js
Type:
Data Service

Parameters

Name Type Description
ComponentName string, Category:string, Language:string, Views:number

Returns

unknown - void

Models Used

MODE [Utility]

FLEET USAGE ANALYTICS — one script, several modes. READ-ONLY. node scripts/_analytics.js scan [--fresh] pull raw stats from prod -> local cache <- RUN THIS FIRST node scripts/_analytics.js usage screen popularity, time investment, tiers, co-visits node scripts/_analytics.js deep stickiness, ladder, gaps, segments, thresholds, dropout node scripts/_analytics.js personas person-count personas + what each persona does node scripts/_analytics.js cohort by signup month and last-access recency (needs profiles) node scripts/_analytics.js trend every headline number vs the stored baseline node scripts/_analytics.js all all of the above, in order --json also write scripts/_analytics-<mode>.json --fresh (scan only) ignore an existing cache and re-read prod --baseline=<label> (trend only) compare against an older stored baseline ── CANON ──────────────────────────────────────────────────────────────────── 1. `stats.pagecounts` / `stats.avgs` live on the USER doc — that is one doc per PERSON, not per account. Anything user-facing must roll up by `uid` first, or an astrologer with 400 charts counts 400 times. In this script: screen REACH is always account-level; STICKINESS is person-level on purpose (it measures how magnetic a screen is, not how many humans saw it). 2. `avgs[screen]` is mean SECONDS PER VISIT, not a total. Total time on a screen is pagecounts[s] * avgs[s]. Summing avgs across screens is meaningless. 3. `scan` reads every `users` doc. It does NOT hold one long cursor: a single cursor over 1.2M docs dies on a socket read timeout partway through (measured: ~700k docs, ~4.5min) and you lose the whole pass. Instead it pages by `_id` — each chunk is a short, index-backed seek, so nothing is long-lived enough to drop, it resumes from the last `_id` on a transient error, and there is no COLLSCAN. Do NOT "simplify" this back into one find(). It still caches to disk: scan once, then iterate on reports for free. `node scripts/_dbstat.js ops` shows this script by appName. 4. Only accounts on a recent app build that have synced at least once have stats at all. THIS DATASET SKEWS ENGAGED. Never quote its percentages as install-base numbers — they are "among tracked accounts". The tracked share of the fleet is printed at the top of every run so the skew stays visible. 5. Screen keys are whatever the Flutter app sends, so junk (URLs, one-off routes) turns up; JUNK_KEY drops it. NEW screen keys appearing between runs is normal and is itself a finding — `trend` lists every screen absent from the baseline. 6. Baselines are transcribed from docs/analytics/*.md; BASELINE selects the one `trend` compares against. When you publish a new run, add a BASELINE_<date> constant, point BASELINE at it, and update the docs IN THE SAME COMMIT — otherwise the next person silently compares against stale numbers. Old baselines are kept, not deleted, so --baseline=<label> can still reach back. ─────────────────────────────────────────────────────────────────────────────

Function:
MODE
File:
_analytics.js
Type:
Utility
MODE [Utility]

BYPASS/ENTITLEMENT HEALTH DIAGNOSTIC -- one script, several modes. READ-ONLY except `sweep`, which silently re-grants bypass (no message sent). node scripts/_bypass_health.js rate [days=30] % of paid launches missing the entitlement-sync event (the headline number from the 2026-08-25 investigation, baseline: 54.1%) node scripts/_bypass_health.js complaints [days=30] lost-premium support messages, by day node scripts/_bypass_health.js sweep [days=14] check + silently re-grant bypass for anyone who complained in the window node scripts/_bypass_health.js bursts [days=30] .NET-side simultaneous- failure windows (separate, smaller contributor) ── CANON ──────────────────────────────────────────────────────────────────── Run `rate` after any client release that touches web_view_screen.dart / main.dart's entitlement path -- it's the only direct falsification test for whether a fix actually worked. It should drop toward low single digits, not necessarily to zero (the .NET-side burst contributor, see `bursts`, is a separate thing no client fix removes). `sweep` is a stopgap for the currently-shipped, still-buggy client -- it does not fix anything, it just shortens how long an affected account sits on free. Keep running it until the client fix has actually reached most users (i.e. `rate` has come down AND app-version telemetry shows the new build is dominant), not just until it's merged. See docs/HANDOFF-flutter-bypass-race.md for full context. ─────────────────────────────────────────────────────────────────────────────

Function:
MODE
File:
_bypass_health.js
Type:
Utility
MODE [Utility]

MONGO LOAD DIAGNOSTIC — one script, several modes. READ-ONLY except `kill`. node scripts/_dbstat.js ops [minSecs] in-flight operations, slowest first <- START HERE node scripts/_dbstat.js status serverStatus: connections, opcounters, queues, memory node scripts/_dbstat.js top [limit] per-collection time spent (the `top` command) node scripts/_dbstat.js delta [secs] per-collection time spent IN THE LAST N SECONDS. Prefer this over `top`: `top` is cumulative since mongod start, so a past incident keeps dominating it long after the cause is fixed. node scripts/_dbstat.js watch [secs] sample `ops` every 2s for N secs, tally repeat offenders node scripts/_dbstat.js op <connId> dump ONE op's full command doc (the summary truncates pipelines, so this is how you learn WHICH uid/filter) node scripts/_dbstat.js index [--write] create the indexes from docs/DEV-mongo-slow-query-audit.md (DRY unless --write) node scripts/_dbstat.js kill <ns> <secs> [--write] [--loop] killOp every op on <ns> older than <secs>. DRY unless --write. --loop keeps killing every 5s (emergency valve). ── WHEN TO USE `kill` ─────────────────────────────────────────────────────── It is a TOURNIQUET, not a fix. Killing an op returns an error to that user's request; it does NOT stop the app from immediately issuing the same query again. Use it only to hand CPU back to the rest of the server while a real fix deploys. Killing a read is safe (no partial writes) — this is why the mode is restricted to aggregations/queries and refuses anything that could be mid-write. ───────────────────────────────────────────────────────────────────────────── ── CANON ──────────────────────────────────────────────────────────────────── When mongod pins a CPU it is almost always ONE of three things, in this order: 1. COLLSCAN — a query with no usable index. Look for `planSummary: COLLSCAN` in `ops`. A single scan over `users` (one doc per PROFILE, the biggest collection) will peg a core for many seconds and blocks nothing else visibly. 2. A pile-up — many identical cheap queries, none individually slow. `ops` shows dozens of the same shape; `status` shows activeClients/queues climbing. 3. An index build or an aggregation with allowDiskUse over a large $group. Several of our own scripts (_profiles.js mainuser, _payments.js) do exactly this against prod. CHECK WHETHER A DIAGNOSTIC SCRIPT IS THE THING CAUSING THE LOAD before hunting the app — `ops` prints the client/appName for each op. `secs_running` only appears once an op has been alive >0s, so a flood of fast ops shows as many rows with no secs_running rather than one slow row. Read both shapes. This script itself is cheap: currentOp/serverStatus/top are O(1) admin commands, they do NOT scan data. Safe to run against prod while it is on fire. ─────────────────────────────────────────────────────────────────────────────

Function:
MODE
File:
_dbstat.js
Type:
Utility
ONE [Utility]

VOICE-OF-CUSTOMER DEEP DIVE — maps the issues users raise in support to the actual CONTACTABLE users who raised them, bucketed by issue. Read-only. node scripts/_feedback.js [days] default 45 node scripts/_feedback.js 45 --issue=ads_placement drill one bucket (full quotes) node scripts/_feedback.js 45 --csv write contactable-users.csv node scripts/_feedback.js 120 --ai AI sentiment by week — is the tone complaint receding after a content change, or not? "Contactable" = a registered account (email uid). app-… users have no email and are listed only as a count. Newest message per user wins.

Function:
ONE
File:
_feedback.js
Type:
Utility
MODE [Utility]

SUPPORT INBOX DIAGNOSTIC — one script, several modes. READ-ONLY. node scripts/_inbox.js needsreply [days] threads where the USER spoke last <-- start here node scripts/_inbox.js stuck [days] loops / repeated asks / dead ends node scripts/_inbox.js audit [days] category x handling-state matrix node scripts/_inbox.js feedback [days] what users are actually reporting, clustered + sampled node scripts/_inbox.js health is the pipeline alive? last in/out, backlog by age node scripts/_inbox.js thread <uid> print one full thread + that user's DB state node scripts/_inbox.js reply <uid> <file> [--send] send a reply (DRY unless --send) node scripts/_inbox.js replybatch <json> [--send] send many; JSON = [{uid, text}, ...] ── CANON ──────────────────────────────────────────────────────────────────── A thread needs a reply when the LAST message is from the user. Terminal statuses (Noise / Auto_Closed / Resolved) are excluded -- but note the closing-phrase matcher contains the bare substrings 'fixed' and 'thx', so it wrongly auto-closes real complaints ("needs to be fixed", "fixed stars"). Sanity-check terminal threads. Support sender id is support@astromatrix.org. Replies MUST go via POST club.astromatrix.org/messages/SendMessage (in-app + email). Sending is irreversible -- always dry-preview a batch and get sign-off. ─────────────────────────────────────────────────────────────────────────────

Function:
MODE
File:
_inbox.js
Type:
Utility
loadThreads [Utility]

Build every support thread, newest message last.

Function:
loadThreads
File:
_inbox.js
Type:
Utility
MODE [Utility]

BIRTH-LOCATION INTEGRITY — one script, several modes. READ-ONLY except `repair --write`. node scripts/_locations.js scan [days] how many profiles carry a town but no coordinates, split by failure shape <- START HERE node scripts/_locations.js patterns [days] failure RATE per town format (which string shapes actually break) node scripts/_locations.js samples [days] dump the offending rows node scripts/_locations.js suggest [days] candidates for the rows repair cannot match exactly. PRINTS ONLY -- never writes. node scripts/_locations.js repair [days] [--write] [--tz] [--limit=N] re-resolve coordinates from the town string. DRY unless --write. --tz also re-resolves the timezone (extra paid API calls -- see CANON 4). ── CANON ──────────────────────────────────────────────────────────────────── 1. THE BUG THIS EXISTS FOR. `GetBirthCityInfo?town=X` returns literal `null` -- not an error, not a 404 -- when X is not an EXACT match for a stored `FullName`. The Flutter client does `result.data ?? {}`, so null becomes an empty map, `_parseCoordinate` defaults lat/lng to 0, nothing throws, and the profile saves with a chart computed at 0,0. The user is never told. Confirmed by hand: GetBirthCityInfo?town=London -> null GetBirthCityInfo?town=London, England, United Kingdom -> full record So a town string that came from anywhere OTHER than a live search result is liable to miss. That is why the offenders below are all format oddities, not typos. 2. WHICH FORMATS ACTUALLY BREAK (measured, 7d sample -- do not guess, re-run `patterns`): "Toronto, Ontario, Canada (CA )" padded country code -> ~71% fail "Recife" / "Singapore" bare name, no comma -> ~29% fail "Nantes, , France" empty province -> ~0.5% fail (mostly FINE) The empty-province shape looks broken and is not; it was my first suspect and it was wrong. Trust the measurement. 3. A MISSING TOWN IS NOT THIS BUG. ~8% of new profiles have no coordinates AND no town at all. That is the "I don't know my birth time" path: the wizard skips the location step entirely and saves with a null location by design. Every mode here therefore requires a NON-EMPTY town before counting a row as broken, and treats the literal strings "undefined"/"null" as empty (they are a client stringify bug, counted separately). 4. TIMEZONE IS A SEPARATE, PAID CALL. Some broken rows already hold a CORRECT timezone (e.g. "Eglon, west Virginia" tz=-300) while others hold 0. So coordinates and timezone fail independently, and fixing lat/lng does NOT imply the timezone is wrong. `--tz` is opt-in because it spends TimeZoneDB VIP quota per row and can overwrite a good value with a fresh lookup. Repair coordinates first; only reach for --tz on rows whose tz is 0. 5. REPAIR WRITES EXACT MATCHES ONLY -- IT NEVER GUESSES. Per row it tries, in order: the town verbatim -> the padded country code stripped -> a doubled comma collapsed. Each candidate must come back as a real record from GetBirthCityInfo, which only answers on an exact stored FullName. No match means no write; the row is listed as MANUAL and `suggest` mode will show leads for a human. What it records lands in `_repairNote`. This rule is written in blood. The first version had a fourth step -- search the first comma-token via GetBirthLocations and take the top hit when the result list held one entry -- and on 2026-08-26 it wrote three wrong birthplaces to production before being reverted (backup: scripts/location-repair-backup-2026-08-26.json): "Uniondale, Province of the Western Cape, South Africa" -> Uniondale, NEW YORK "Koln" -> a town in POLAND "Kentucky, Covington" -> NEW MEXICO The one-result check was worthless precisely BECAUSE the query was truncated: dropping the country and region means the right city is never in the list, so a single hit reads as unambiguous while being a different place entirely. 3 of 14 such writes were wrong. A missing coordinate is a visible gap; a wrong one is an invisible wrong chart. If you are tempted to re-add fuzzy matching, put it in `suggest`, never in `repair`. ─────────────────────────────────────────────────────────────────────────────

Function:
MODE
File:
_locations.js
Type:
Utility
classify [Utility]

Classify a town string by the shape that made it fail. Keep in sync with routes/user.js.

Function:
classify
File:
_locations.js
Type:
Utility
candidates [Utility]

The candidate strings we are willing to try, most-trusted first (CANON 5).

Function:
candidates
File:
_locations.js
Type:
Utility
resolve [Utility]

Resolve a town to {lat,lng,fullName} or null. EXACT MATCHES ONLY. An earlier version had a search fallback: take the first comma-token, run it through GetBirthLocations, accept the top hit if the result list had length 1. It wrote three wrong birthplaces to production before being reverted -- "Uniondale, ...South Africa" became Uniondale NEW YORK, "Koln" became a town in Poland, "Kentucky, Covington" became New Mexico. The guard was useless because truncating to the first token DISCARDS the country and region, so the correct city is not in the candidate list at all and a one-result search looks unambiguous while being simply wrong. There is no safe version of "guess from a partial string" for birth data: a wrong birthplace silently produces a wrong chart, which is worse than the missing coordinate it replaces. So the fallback is gone rather than tightened, and anything not matching an exact stored FullName is reported for a human.

Function:
resolve
File:
_locations.js
Type:
Utility
suggestions [Utility]

What search *would* have suggested, shown to a human in `suggest` mode and never written. Kept separate from resolve() on purpose: this is a lead to check by hand, not an answer.

Function:
suggestions
File:
_locations.js
Type:
Utility
birthUnix [Utility]

Birth moment as unix seconds, mirroring the client's _toUnixTime.

Function:
birthUnix
File:
_locations.js
Type:
Utility
MODE [Utility]

PAYMENTS DIAGNOSTIC — one script, several modes. READ-ONLY except `normalize --write`. node scripts/_payments.js trend [days] daily incident table (complaints/telemetry/failures) node scripts/_payments.js telemetry [days] payment log types + failure reasons node scripts/_payments.js followup [days] per-complainant verdict (recovered / still failing) node scripts/_payments.js precedence [days] store said ENTITLED but app showed FREE <-- the real bug class node scripts/_payments.js lookup <emails|file> check specific addresses (payments + errors) — for mailbox triage node scripts/_payments.js web [days] recent Stripe/Web payments — find records filed under a Stripe/Link email that differs from the app login node scripts/_payments.js casing users whose payment record our lookup can't see node scripts/_payments.js export [dir] write the CSVs node scripts/_payments.js normalize [--write] lowercase payments.uid (dry unless --write) ── CANON ──────────────────────────────────────────────────────────────────── Apple/Google in-app billing is ALWAYS the source of truth for entitlement. `payments` is ONLY a mirror for: web purchases, older records, cross-platform lookup. It starts Sep 2023, so an empty result proves NOTHING about a 2019 purchase. Login state must NEVER gate validation: a logged-out user whose store account holds the entitlement must still get premium. If a /syncPayments failure or a logged-out session removes access, that is a CLIENT bug, not missing payment data. Account uids are lowercase everywhere except `payments`, which was written un-normalised -- always join case-insensitively. ─────────────────────────────────────────────────────────────────────────────

Function:
MODE
File:
_payments.js
Type:
Utility
loadPayments [Utility]

Load payments once, indexed by lowercased uid AND email.

Function:
loadPayments
File:
_payments.js
Type:
Utility
complainants [Utility]

Users who raised a purchase issue in the window.

Function:
complainants
File:
_payments.js
Type:
Utility
MODE [Utility]

PROFILE / ACCOUNT DIAGNOSTIC — one script, several modes. READ-ONLY except `restore --write`. node scripts/_profiles.js mainuser [limit] accounts with 0 or >1 main users node scripts/_profiles.js account <uid> one account's profiles + main-user state node scripts/_profiles.js cascade scope of isDeleted-without-deletedAt profiles node scripts/_profiles.js restore [--write] clear the cascade flag (DRY unless --write) ── CANON ──────────────────────────────────────────────────────────────────── `users` = one doc per saved PROFILE. `profiles` = one doc per ACCOUNT. An account must have exactly ONE mainUser. Migration used to set mainUser from the legacy `Famous` flag (celebrity marker, NOT main user), which is why accounts have zero or several. getUsersID heals >1 by clearing all (app then prompts a pick). DELETE PATHS -- these determine what is safe to restore: /deleteUser (live, new app) -> isDeleted + deletedAt <- real user delete /remove (deprecated) -> isDeleted + deletedAt <- real user delete /erase (legacy clients) -> isDeleted, NO deletedAt <- indistinguishable from the cascade bug since 10.7.2 (2026-06-30) So `isDeleted && !deletedAt` is NOT exclusively the bug any more. Restoring it blindly resurrects profiles people deliberately deleted from old app builds. Scope by size: an account with 1-3 flagged profiles looks like a person deleting charts; one with dozens looks like the cascade. Confirm /erase traffic is dead before a broad restore. ─────────────────────────────────────────────────────────────────────────────

Function:
MODE
File:
_profiles.js
Type:
Utility
arg [Utility]

QUARANTINE MANAGEMENT for the immortal-tombstone delete bug. Consolidated multi-mode script; write modes default to DRY, always preview first. node scripts/_quarantine.js add <uid> [--reason="..."] [--source=support|auto] Adds a uid to erase_quarantine with an EMPTY protected set. Use this alone only if you are not restoring anything yet; normally use quarantine-and-restore so the restored ids get protected in one step. node scripts/_quarantine.js list Every quarantined account: when added, why, how many profiles are protected, and how recently each has actually been replayed (pulsed). node scripts/_quarantine.js lift <uid> Removes quarantine entirely (sets liftedAt). Normal handling resumes for every profile on the account, protected or not. node scripts/_quarantine.js restore <uid> [--write] Restores that uid's bug-shaped rows (isDeleted:true, no deletedAt) and adds each restored profileId to the account's protected set. Refuses to run unless the uid is CURRENTLY quarantined -- restoring an unquarantined account is exactly the "gets undone by the next replay" trap this exists to avoid. node scripts/_quarantine.js quarantine-and-restore <uid> [--reason=...] [--write] Does both, in the only safe order: quarantine (empty set) first, then restore (which populates the protected set). Only the restored ids are protected -- the account can still genuinely delete anything else. node scripts/_quarantine.js candidates [--json] The ongoing tracking view: accounts currently holding stuck profiles that are NOT yet quarantined. This is "who needs it" day to day, after the initial bulk pass -- run it periodically to catch new accounts. --json writes a plain array of uids, ready to feed straight into bulk: node scripts/_quarantine.js candidates --json > new.json node scripts/_quarantine.js bulk new.json --write node scripts/_quarantine.js bulk <file.json> [--write] Same as quarantine-and-restore, for every uid in a JSON array file. Generate a one-off candidate list with `node scripts/_stuck-erase-uids.js <hrs> --js`, or the full current set with `candidates --json`. node scripts/_quarantine.js sweep [--days=14] [--write] Classifies each protected profileId as still-pulsing (a device really is still replaying it) or gone quiet (no replay in <days>, since restoredAt if it was never pulsed at all). Quiet ids are safe to drop from protection -- the account can delete them normally again, same as before they were ever stuck. An account whose protected set is fully empty after sweeping is auto-lifted. This is the "classify whether it's pulsing, and if not, safely remove it" loop -- run it periodically (a cron alongside autosupport's, or by hand) rather than leaving accounts quarantined forever on a guess. CANON - Quarantine protects specific PROFILE IDS, not whole accounts. A call against a protected id is always a no-op while quarantined. A call against anything else on the same account gets the ordinary live-profile check, so genuine deletes keep working throughout. - Never restore an account that isn't quarantined. - Source-of-truth is a DB collection, not a code list, specifically so a support ticket can quarantine + restore an account in real time with no deploy in between.

Function:
arg
File:
_quarantine.js
Type:
Utility
scrapeAuraSoma [Data Service]

Scrapes a single Aura-Soma product page and saves its details to the database.

Function:
scrapeAuraSoma
File:
aurasoma.js
Type:
Data Service

Parameters

Name Type Description
url string

Returns

unknown - void

Throws

  • Error

Models Used

descBrokenTag [Utility]

Broken HTML opening tag: tag letter(s) immediately followed by non-space/non-> e.g. <bCareer or <strongText — the ">" was swallowed during AI generation. Two complementary patterns: 1. tag name + uppercase letter before any ">": <bC... or <strongT... 2. tag content without a ">" closure reaching the next closing tag

Function:
descBrokenTag
File:
audit-quality.js
Type:
Utility
descDuped [Utility]

Description paragraph appears twice (generation doubled it).

Function:
descDuped
File:
audit-quality.js
Type:
Utility
descTail [Utility]

Non-whitespace content after the last </p>.

Function:
descTail
File:
audit-quality.js
Type:
Utility
descBadElements [Utility]

Disallowed HTML elements (anything beyond p,b,i,br,ul,ol,li,em,strong,h1-h6).

Function:
descBadElements
File:
audit-quality.js
Type:
Utility
textLen [Utility]

Stripped plain-text length.

Function:
textLen
File:
audit-quality.js
Type:
Utility
main [Utility]

Semantic defects cannot be repaired by string cleanup — the doc must be regenerated.

Function:
main
File:
cleancomponents.js
Type:
Utility
needsModelCleanup [Utility]

True when the copy contains a semantic defect that regeneration (not cleanup) must fix.

Function:
needsModelCleanup
File:
content-rules.js
Type:
Utility
cleanupReason [Utility]

Which rule fired — for logging, so a flagged doc says WHY it was flagged.

Function:
cleanupReason
File:
content-rules.js
Type:
Utility
looksNatalVoice [Utility]

Source text written in natal "you/your" voice with no relational labels — wrong voice for a synastry placement, must be fully rebuilt not echoed.

Function:
looksNatalVoice
File:
content-rules.js
Type:
Utility
cleanElements [Utility]

Strip disallowed elements, keeping their inner content. Returns cleaned HTML or null if unchanged.

Function:
cleanElements
File:
fix-bad-elements.js
Type:
Utility
trimTail [Utility]

Only trim tails that are genuinely garbage: - whitespace / bare <br> - raw text (no structural tags) - PHRASE: / Note: leaks Skip if the tail contains real block-level content (<ul>, <ol>, <h1-6>, etc.) because those are valid description structure that just happens to follow </p>.

Function:
trimTail
File:
fix-desc-tail.js
Type:
Utility
mergeKey [Utility]

Iteratively merge trailing space-splits until stable. Handles double-splits: "Mount a in" → "Mount ain" → "Mountain" "Sabi An" → "Sabian" (capital fragment lowercased)

Function:
mergeKey
File:
fix-key-split.js
Type:
Utility
fixImagePath [Utility]

Update image path: replace the mangled key fragment with the fixed one. E.g. "Transit Aspects/Vest a Sextile Natal Mercury.jpg" → "Transit Aspects/Vesta Sextile Natal Mercury.jpg"

Function:
fixImagePath
File:
fix-key-split.js
Type:
Utility
check [Utility]

A check returns { ok, summary, rows[], detail? }. rows are the offending records.

Function:
check
File:
dbaudit.js
Type:
Utility
ONLY [Utility]

send-support-replies.js — individualized support email replies via Amazon SES. node scripts/support/send-support-replies.js DRY RUN (prints, sends nothing) node scripts/support/send-support-replies.js --send actually send node scripts/support/send-support-replies.js --send --only=user@x.com SAFETY (the July loop bug sent one user 1,176 identical messages): - dry-run unless --send - idempotent: the sent-log (latest-wins) skips any (email, channel) already sent - 600ms between sends POLICY: email is a safety net, not the main support line. Every reply auto-appends the in-app-Support redirect (IN_APP_CLOSE) before the signature — including recovery cases, since a locked-out user can register a new free account and recover in-app. Add new replies to FOLLOWUPS. A second reply to the same person needs a distinct `channel` (e.g. followup2) so the idempotency key differs.

Function:
ONLY
File:
send-support-replies.js
Type:
Utility
arg [Utility]

_fitness.js — OBJECTIVE self-scorer for the personality signature. No hand-rating: a forced-choice LLM judge must pick which of N real bios the (anonymised) signature describes. Accuracy vs 1/N random is the fitness. Decoys are RESAMPLED every round (rotating data → no skew). Run after every rule change. NODE_TLS_REJECT_UNAUTHORIZED=0 node scripts/symbolism/_fitness.js [--n 6] [--rounds 3] [--conc 16] [--limit 0]

Function:
arg
File:
_fitness.js
Type:
Utility
gateBase [Utility]

Base type for a gate: Element/Modality from its sign, Circuit from gate circuitry.

Function:
gateBase
File:
base-types.js
Type:
Utility
gateFromDegree [Utility]

The gate (1-64) occupying an ABSOLUTE ecliptic degree (0 = 0° Aries), via the fixed gate wheel. Inverse of the GATE_SIGN computation -- used to map a Sabian symbol's degree to its I Ching gate.

Function:
gateFromDegree
File:
base-types.js
Type:
Utility
gateLineDegree [Utility]

Midpoint absolute degree of a given gate's line (1-6) -- inverse of gateLineFromDegree. Used to measure degree-proximity between an I Ching hexagram.line and a Sabian degree.

Function:
gateLineDegree
File:
base-types.js
Type:
Utility
gateLineFromDegree [Utility]

The gate AND line (1-6) at an absolute degree. Each gate spans GATE_WIDTH and divides into 6 lines of GATE_WIDTH/6 (0.9375°). Maps a zodiac degree -> hexagram.line.

Function:
gateLineFromDegree
File:
base-types.js
Type:
Utility
centerOf [Utility]

Energetic center for a decomposed part. A gate is EXACT (GATE_CENTER); a bare planet uses the approximate PLANET_CENTER_FALLBACK. Never falls back if a gate exists.

Function:
centerOf
File:
base-types.js
Type:
Utility
channelBase [Utility]

Structural base for a channel: its two gates, the centers it bridges, and its circuit (the shared circuit of its gates, else 'Mixed'). All derived.

Function:
channelBase
File:
base-types.js
Type:
Utility
bodyPartOf [Utility]

Anatomical body region(s) for a part, via its sign (medical astrology).

Function:
bodyPartOf
File:
base-types.js
Type:
Utility
chakraOf [Utility]

Resolve any decomposed part {type,name} to its body-zone chakra, or null.

Function:
chakraOf
File:
base-types.js
Type:
Utility
houseBase [Utility]

Element/Modality for a house, from its natural sign (1st->Aries ... 12th->Pisces).

Function:
houseBase
File:
base-types.js
Type:
Utility
baseOf [Utility]

Resolve any decomposed part {type,name} to its base type, or null if unknown.

Function:
baseOf
File:
base-types.js
Type:
Utility
isAmplifier [Utility]

Is this part an amplifier body (asteroid / Vertex / Part of Fortune)?

Function:
isAmplifier
File:
base-types.js
Type:
Utility
arg [Utility]

Meaning-based classification into the I Ching vocabulary — the constrained-AI pass. For each component, the model picks the 3-5 hexagram THEMES (from the fixed 64) whose meaning best matches. CONSTRAINED (only the 64 fixed buckets -> can't invent mega-concepts) + multi-label. TEST MODE: small sample, measures accuracy + SPREAD across the 64 (does it balance or skew?). No writes. node scripts/symbolism/classify-iching.js --limit 24

Function:
arg
File:
classify-iching.js
Type:
Utility
classifyBody [Utility]

Classify a single decomposed part into {domain, expression} via its base type.

Function:
classifyBody
File:
classify.js
Type:
Utility
contextFor [Utility]

Decide the context flag from the component category (synastry/composite = relationship).

Function:
contextFor
File:
classify.js
Type:
Utility
placementOverride [Utility]

PLACEMENT-level overrides -- depend on the sign/house and classify the whole component (short-circuit). Self context only. First match wins.

Function:
placementOverride
File:
classify.js
Type:
Utility
bodyOverride [Utility]

BODY-level override -- a single body's intrinsic classification, applied to ITS pole only (so in an aspect it does not hijack the whole component). Self context only. Evolution here is EARNED by specific bodies, and (per the headline ranking in classify) only leads when no element pole outranks it.

Function:
bodyOverride
File:
classify.js
Type:
Utility
classify [Utility]

Classify a component into the Matrix taxonomy. LOOKUP-FIRST: if a stored Facet (the existing balanced per-component attribution) is supplied, it IS the expression and decides the domain. Base-type derivation only runs as the fallback for components without a stored Facet.

Function:
classify
File:
classify.js
Type:
Utility

Parameters

Name Type Description
{string} name any
{string} [category] any
{object} [opts] any
{string} [opts.storedFacet] - the component's stored Facets value, if any any
{string} [opts.context] - force 'self' | 'relationship' any

Returns

{context, domain, expression, source, classifications, parts, layer, override?, reason? - }

classifyFromBase [Utility]

Classify directly from a raw Element + Modality (no component name needed). Used for nodes whose base type is known structurally rather than by decomposition -- e.g. Tarot court cards (suit element + rank-as-modality).

Function:
classifyFromBase
File:
classify.js
Type:
Utility

Returns

{context, domain, expression, coordinate - }

classifyGate [Utility]

Classify an I Ching gate (number 1-64) into the Matrix taxonomy. Element + Modality (from the gate's sign) drive domain + expression -- the same law as planets. Circuit (social-function layer) is METADATA only: it is NOT a domain driver (no Evolution override), mirroring the fix that tamed Evolution dominance.

Function:
classifyGate
File:
classify.js
Type:
Utility

Returns

{context, domain, expression, coordinate, gate, sign, circuit, boundary - }

classifyChannel [Utility]

Classify a channel (two gates) -- a COMPOSITE that surfaces BOTH gates' poles, like an aspect. Returns the bridged centers + circuit (structural), the primary coordinate, and `coordinates` = both poles' coordinates (deduped) for the graph.

Function:
classifyChannel
File:
classify.js
Type:
Utility

Returns

{context, gates, key, centers, circuit, coordinate, coordinates, domain, expression - }

deriveClassify [Utility]

Base-type derivation (the fallback path).

Function:
deriveClassify
File:
classify.js
Type:
Utility
arg [Utility]

connect.js — connection/relevance generator (roadmap step 2). For a component, surface the cross-tradition associations that ATTACH to it: other components sharing its concept, scored by relevance, deduplicated by base-archetype root, kept only above a per-type threshold (so the count emerges from the data — no hand-picking). relevance(A,B) = conceptStrength(IDF of shared concept) + 20·Jaccard(archetype hubs) [0..100] IDF: sharing a RARE concept (small pool) is a strong, specific link; sharing a BROAD one is weak. hub overlap = structural corroboration bump / ranking. node scripts/symbolism/connect.js --query "Venus in Leo" [--threshold 65] node scripts/symbolism/connect.js --calibrate [--sample 80] # find the cutoff per target-type

Function:
arg
File:
connect.js
Type:
Utility
arg [Utility]

consolidate.js — tighten the NEW theme-concept set into a good SPREAD (few singletons, no giant outliers), entirely in JSON. Operates ONLY on today's new concepts — old persona values ("The Transformer") are EXCLUDED (those rows need tagging, not merging). Method (controlled, can't collapse): ANCHORS = concepts used >= --floor stay fixed; the rare TAIL (< floor) is absorbed by the LLM into the anchor it's a synonym/variant of, or KEPT if genuinely distinct. Anchors are never merged into each other → no giant pools. Reads _snapshot.json writes _concept-map.json + _snapshot-remapped.json (NO DB writes) NODE_TLS_REJECT_UNAUTHORIZED=0 node scripts/symbolism/consolidate.js [--floor 10] [--batch 40]

Function:
arg
File:
consolidate.js
Type:
Utility
spectrumOf [Utility]

The three-octave arc for a coordinate id, or null. Returns { contraction, expression, radiance } — note `expression` here is the BALANCED octave (the middle band), distinct from the coordinate's own expression slug.

Function:
spectrumOf
File:
growth-spectrum.js
Type:
Utility
buildScaffold [Utility]

Generate the 384-slot scaffold. Each slot carries its OWN distinct concept (HEXAGRAM_LINES) + structural grounding (coordinate/center/circuit/stage). Returns an array of 384 slots.

Function:
buildScaffold
File:
iching-concepts.js
Type:
Utility
conceptGenes [Utility]

Archetypal genes implied by a component's Concept, or [] when it cannot be resolved. Emits ONLY the ×1 archetypal class (fn:/q:/p:). Both identity classes are stripped: pt: — the component is not that planet, it merely resonates with it. sg: — planetAtoms() includes the planet's RULED SIGNS, so an unfiltered projection gave Firefly `sg:Aquarius` purely because its concept mapped to Uranus. sg: carries the same ×3 identity weight as pt: (see FW in relevance-core), so that inference would have outweighed the animal's own `sg:Gemini` — an inferred trait beating a sourced one. What survives (fn:Awakening, q:Ether, p:Fixed for Uranus) is still ample to separate components that were previously identical, without letting a concept assert identity.

Function:
conceptGenes
File:
leaf-roots.js
Type:
Utility

Parameters

Name Type Description
{string} concept any

Returns

string[]

numerologyValue [Utility]

The number a numerology component denotes, or null. Handles the three naming styles present in the data: bare ("22"), prefixed ("Life Path 4", "11 - Master Teacher") and named ("The Builder", "The Seeker") via NUMBER_ARCHETYPE.

Function:
numerologyValue
File:
leaf-roots.js
Type:
Utility

Parameters

Name Type Description
{string} name any

Returns

number|null

structuralRoots [Utility]

The structural decomposition — correspondence tables only, no inference.

Function:
structuralRoots
File:
leaf-roots.js
Type:
Utility
leafRoots [Utility]

Root atoms for a component: its structural decomposition, topped up with concept-derived genes when the structure alone is too thin to score on (see SPARSE_GENE_THRESHOLD). Concept genes are ADDITIVE and never replace structure — a component with real correspondences is unaffected, and one with none at all still gets nothing unless its concept resolves, so this cannot invent a connection out of thin air.

Function:
leafRoots
File:
leaf-roots.js
Type:
Utility

Parameters

Name Type Description
{string} name any
{string} category any
{string} [concept] the component's Concept field; omit to get structure only any

Returns

Set<string> - atom tokens ('fn:Love','q:Fire','#5',...)

arg [Utility]

relate.js — relevance(A, B): a connection % between any two components from BOTH channels. CONCEPT (semantic) : do they share a concept? weighted by the concept's specificity (IDF) ROOT (arithmetic) : how much do their base-archetype gene atoms overlap (IDF coverage) COMBINED : 1 - (1-concept)(1-root) -> connected if EITHER channel fires, boosted if both Scoring lives in relevance-core.js (shared with project.js). This file is the CLI. node scripts/symbolism/relate.js --a "Venus in Leo" --b "Citrine" node scripts/symbolism/relate.js --attrib "Venus in Leo" # roots/lookups/associations, ranked node scripts/symbolism/relate.js --rank "Venus in Leo" --top 15 node scripts/symbolism/relate.js --factors --a "Venus in Leo" --b "The Empress"

Function:
arg
File:
relate.js
Type:
Utility
arg [Utility]

relevance(A, B) prototype — a COMPUTED connection score between any two components, from their shared derivation features (not a hand-tag). Used to decide, per target system, which associations clear a threshold and belong in a component's trait list -- so the COUNT emerges from the data. relevance = 0.75 * coordinate-family + 0.25 * hub overlap coordinate-family: same coordinate 1.0 / same domain .55 / same element .40 / same modality .20 / else 0 (graded near-miss credit) hub overlap: Jaccard of the atoms each routes through (planets/signs) Read-only demo. Usage: node scripts/symbolism/relevance.js --query "Mars Square Saturn" --cat "Planet Aspects" --threshold 60

Function:
arg
File:
relevance.js
Type:
Utility
reload [Utility]

Force a re-read (tests).

Function:
reload
File:
schema.js
Type:
Utility
resolve [Utility]

Most-specific-wins lookup of one field. Order: source NAME -> source KIND -> source "*" -> category attribute -> null.

Function:
resolve
File:
schema.js
Type:
Utility
cutFor [Utility]

Minimum relevance % for a connection to be stored.

Function:
cutFor
File:
schema.js
Type:
Utility

Parameters

Name Type Description
{string} sourceCategory any
{string} targetCategory any
{'root'|'leaf'} sourceKind kind of the SOURCE component any

Returns

number

capFor [Utility]

Max rows STORED per (component, target category). Defaults to `serve`: storing rows nobody is ever shown is pure bloat, and where selection among near-equal scores is arbitrary (totems tie in groups of up to 13) the extra rows are not even a better answer held in reserve — just more arbitrary ones. An explicit `cap` is therefore an exception that has to be argued for, not the norm. Hand-authored categories are UNCAPPED: the engine never writes them, so a cap would be policing editorial content it has no say over — and would report human-written rows as engine violations.

Function:
capFor
File:
schema.js
Type:
Utility
serveFor [Utility]

Max rows RETURNED per category, optionally narrowed by the source category so a structural set (a modality genuinely owns 12 decans) can serve in full while the generic case serves 2.

Function:
serveFor
File:
schema.js
Type:
Utility
hop2For [Utility]

Second-hop discovery rules for a target category: the thresholds a convergent thread must clear to be stored. Returns null when the category is excluded from second-hop discovery.

Function:
hop2For
File:
schema.js
Type:
Utility

Parameters

Name Type Description
{string} targetCategory any

Returns

{cut:number,seeds:number,paths:number,cap:number - |null}

serveMaxFor [Utility]

The largest number of rows a category can ever hold for one component — the composite value where the composite bump applies, otherwise the plain one. The READ path uses this rather than serveFor(), because it sees only stored trait rows and cannot know how many identity seeds the source component had. The WRITER already applied the seed-aware limit, so anything stored is by definition allowed to be served; re-deriving a stricter number at read time would silently drop the second value from exactly the composites that earned it ("Sun Conjunct Moon" losing Water).

Function:
serveMaxFor
File:
schema.js
Type:
Utility

Parameters

Name Type Description
{string} targetCategory any

Returns

number

isGenerated [Utility]

False for hand-authored text categories the engine must never write or delete.

Function:
isGenerated
File:
schema.js
Type:
Utility
reachableFrom [Utility]

True when `sourceCategory` is allowed to reach `targetCategory` at all. Categories without an onlyFrom restriction are reachable from anywhere.

Function:
reachableFrom
File:
schema.js
Type:
Utility

Parameters

Name Type Description
{string} sourceCategory any
{string} targetCategory any

Returns

boolean

requiresGene [Utility]

Gene the SOURCE must carry for this target to be reachable ('decan|gate'), or null.

Function:
requiresGene
File:
schema.js
Type:
Utility
generatedCategories [Utility]

All categories the engine is allowed to write.

Function:
generatedCategories
File:
schema.js
Type:
Utility
protectedCategories [Utility]

All hand-authored categories that must never be touched.

Function:
protectedCategories
File:
schema.js
Type:
Utility
arg [Utility]

split-cutoff.js — enforce each category's CUTOFF (mean + 2σ of its pool sizes) by splitting only the pools above it. No merging. Works on _snapshot-remapped.json; pulls descriptions for just the over-cutoff members; subdivides each big pool until no sub-pool exceeds that category's cutoff. Writes the updated _snapshot-remapped.json. NO DB writes (commit-snapshot.js does that). NODE_TLS_REJECT_UNAUTHORIZED=0 node scripts/symbolism/split-cutoff.js [--passes 4]

Function:
arg
File:
split-cutoff.js
Type:
Utility
canonBody [Utility]

Map a body alias onto its canonical stored name, or null if not a known body.

Function:
canonBody
File:
symbolism-engine.js
Type:
Utility
canonHouse [Utility]

"5th House" / "5th" / "in 5th" -> "5th House" (canonical), else null.

Function:
canonHouse
File:
symbolism-engine.js
Type:
Utility
decompose [Utility]

Decompose a component name into typed atomic parts. Returns [] when the name is not a recognised symbol composition.

Function:
decompose
File:
symbolism-engine.js
Type:
Utility

Parameters

Name Type Description
{string} name any
{string} [category] any

Returns

Array<{type:'planet'|'sign'|'house'|'aspect', name:string - >}

buildSourceIndex [Utility]

Build a fast atom -> traits lookup from raw `traits` docs. Only docs in the four SOURCE_CATEGORIES whose Component is a canonical atom are indexed. Single-value categories keep the first seen value; multi-value categories accumulate a deduped array.

Function:
buildSourceIndex
File:
symbolism-engine.js
Type:
Utility

Parameters

Name Type Description
{Array<{Component,ComponentCategory,TraitsCategory,Value}>} traitsDocs any

Returns

{planet:Map, sign:Map, house:Map, aspect:Map - }

lookup [Utility]

Look up an atom's profile from the index, or null.

Function:
lookup
File:
symbolism-engine.js
Type:
Utility
chakraFor [Utility]

Body-zone Chakra for a component, derived from the sign->chakra graph (base-types) rather than the sparse stored data -- even by construction. Prefers the explicit placement (sign > house), else the primary planet's ruling-sign zone. Returns {value, from} or null.

Function:
chakraFor
File:
symbolism-engine.js
Type:
Utility
centerFor [Utility]

Energetic center (the body-FUNCTION layer that supersedes chakra). Prefers a GATE part -- the exact gate -> center path -- and only falls back to a bare planet's approximate center when no gate is present. Returns {value, label, from, exact} or null. Signs/houses carry no center (they map to a medical body region instead -- see baseTypes.bodyPartOf).

Function:
centerFor
File:
symbolism-engine.js
Type:
Utility
deriveFacetTraced [Utility]

Derive the single Facet from the primary body of a component, with provenance.

Function:
deriveFacetTraced
File:
symbolism-engine.js
Type:
Utility

Returns

{facet:string, from:string - |null}

deriveFacet [Utility]

Derive the single Facet from the primary body of a component.

Function:
deriveFacet
File:
symbolism-engine.js
Type:
Utility
combine [Utility]

Combine atomic parts into a composite trait set.

Function:
combine
File:
symbolism-engine.js
Type:
Utility

Returns

unknown - {{Facets?:string[], Crystals?:string[], Essences?:string[],

explain [Utility]

Like combine(), but returns full provenance so you can SEE what is being connected: every produced value carries the atom (and rule) it came from. Pure inspection helper -- not used by the writer.

Function:
explain
File:
symbolism-engine.js
Type:
Utility

Returns

unknown - {{

triangulate [Utility]
Function:
triangulate
File:
triangulate.js
Type:
Utility

Parameters

Name Type Description
{Array<Bearing>} bearings all evidence pointing at ONE target any
{object} [opts] override DEFAULTS any

Returns

Fix|null

explainFix [Utility]

Glass-box derivation trace for a Fix — the "proof", not an oracle. Returns an array of human-readable lines: header, then one line per origin seed, then its corroborating bearings indented.

Function:
explainFix
File:
triangulate.js
Type:
Utility
triangulateAll [Utility]

Convenience: take a flat list of bearings spanning MANY targets, group by target, score each, and return the Fixes sorted strongest-first.

Function:
triangulateAll
File:
triangulate.js
Type:
Utility
ok [Utility]

triangulate.test.js — regression tests for the triangulation + projection contract. The 8 non-negotiable cases from TRIANGULATION.md §9. Fully DB-free: relate/projection run on a tiny synthetic component set through the shared relevance-core engine. node scripts/symbolism/triangulate.test.js # prints PASS/FAIL, exits 1 on any failure

Function:
ok
File:
triangulate.test.js
Type:
Utility
sendFCM [Utility]

Send a push notification to a single FCM token.

Function:
sendFCM
File:
fcmService.js
Type:
Utility

Parameters

Name Type Description
{string} token - Recipient device FCM token any
{string} title - Notification title any
{string} body - Notification body any
{object} data - Optional key/value data payload (all values must be strings) any

Returns

Promise<{success:boolean, messageId?:string, error?:string, invalid?:boolean - >}

healthz [Utility]
Function:
healthz
File:
healthz.js
Type:
Utility

Parameters

Name Type Description
{string} serviceName Reported in the payload, e.g. 'component'. any

Returns

Function - Express handler.

checkRequireLogin [Utility]

Lists actions that require the user to be logged in before proceeding.

Function:
checkRequireLogin
File:
messageService.js
Type:
Utility
sendAWSEmail [API Integration]

Sends an HTML email via AWS Simple Email Service (SES).

Function:
sendAWSEmail
File:
messageService.js
Type:
API Integration

Parameters

Name Type Description
to string, from:string, subject:string, htmlBody:string

Returns

success:boolean, messageId?:string, error?:object

Throws

  • returns { success:false, error } on failure

External APIs Called

saveMessage [Data Service]

Saves a message to the Message collection and handles support auto-responses.

Function:
saveMessage
File:
messageService.js
Type:
Data Service

Parameters

Name Type Description
FromEmail string, FromUserId:string, ToUserId:string, Content:string, isSupport:boolean

Returns

message:string, data:object - | 200 automated support response object

Throws

  • 500

Models Used

markMessagesAsSeen [Data Service]

Marks all messages from one user to another as "Seen" in the Message collection.

Function:
markMessagesAsSeen
File:
messageService.js
Type:
Data Service

Parameters

Name Type Description
FromUserId string, ToUserId:string

Returns

success:boolean, message:string, data?:object

Throws

  • returns { success:false, message:string, error } on failure

Models Used

sendEmailMessage [API Integration]

Saves a message in MongoDB and sends it as an email to the recipient via AWS SES.

Function:
sendEmailMessage
File:
messageService.js
Type:
API Integration

Parameters

Name Type Description
FromEmail string, FromUserId:string, ToUserId:string, Content:string

Returns

success:boolean, message:string, data?:object, error?:object

Throws

  • returns { success:false, message:'Error sending email message.' } on failure

External APIs Called

Models Used

migrateJob [Utility]

Waits for a given number of milliseconds before continuing.

Function:
migrateJob
File:
migrationService.js
Type:
Utility

Parameters

Name Type Description
ms number

Returns

unknown - Promise<void>

migrateUsers [API Integration]

Migrates users for a single profile UID by calling an external API and saving returned users locally. This function checks if users for the given mainUserId are already migrated, fetches friends from the external API, saves each user into the local users collection, and marks the profile as migrated.

Function:
migrateUsers
File:
migrationService.js
Type:
API Integration

Parameters

Name Type Description
uid string

Returns

unknown - 'ALREADYMIGRATED' | 'MIGRATEDSUCCESS' | undefined Returns 'ALREADYMIGRATED' if users already exist, 'MIGRATEDSUCCESS' on success, or undefined if an error occurred

Throws

  • Error when an unexpected error occurs during the migration process

External APIs Called

Models Used

buildHandleStem [Service Method]

Builds a handle stem from a Big Three object.

Function:
buildHandleStem
File:
profileservice.js
Type:
Service Method

Parameters

Name Type Description
{{ sun {sign,degree}, moon:{sign,degree}, ascendant:{sign,degree} }} big3

Returns

string|null

coerceBig3 [Service Method]

Coerces a stored field (object or JSON string) into a { sun, moon, ascendant } object.

Function:
coerceBig3
File:
profileservice.js
Type:
Service Method

Returns

Object|null

readBig3ForUid [Service Method]

Reads the Big Three for a uid from the User collection. Prefers the main user doc, falls back to any doc with big3. Also checks by profileId (_id) to handle write-timing races.

Function:
readBig3ForUid
File:
profileservice.js
Type:
Service Method

Parameters

Name Type Description
{string} uid any
{string=} profileId any

Returns

Promise<Object|null>

escapeRegex [Service Method]

Escapes a string for safe use inside a RegExp.

Function:
escapeRegex
File:
profileservice.js
Type:
Service Method
validateHandle [Service Method]

Validates a user-chosen handle's format.

Function:
validateHandle
File:
profileservice.js
Type:
Service Method

Parameters

Name Type Description
{string} handle any

Returns

{ valid: boolean, reason?: string - }

isHandleAvailable [Service Method]

Checks whether a handle is free (case-insensitive), ignoring the caller's own profile so re-saving the same handle reads as available.

Function:
isHandleAvailable
File:
profileservice.js
Type:
Service Method

Parameters

Name Type Description
{string} handle any
{string=} ownUid any

Returns

Promise<boolean>

setHandle [Service Method]

Validates, checks uniqueness, then sets a user-chosen handle. Re-checks availability immediately before saving to narrow the race window.

Function:
setHandle
File:
profileservice.js
Type:
Service Method

Parameters

Name Type Description
{string} uid any
{string} handle any

Returns

Promise<{ ok: boolean, status: number, handle?: string, reason?: string - >}

ensureUniqueHandle [Service Method]

Ensures a handle is unique in the profiles collection. Appends an incrementing counter on collision: fierceLion, fierceLion2, ...

Function:
ensureUniqueHandle
File:
profileservice.js
Type:
Service Method

Parameters

Name Type Description
{string} desired any
{string=} ownUid any

Returns

Promise<string>

addOrUpdateProfile [Service Method]

Adds or updates a profile document. Creates if not found, updates otherwise. Assigns a handle exactly once (never overwrites an existing one).

Function:
addOrUpdateProfile
File:
profileservice.js
Type:
Service Method

Parameters

Name Type Description
{Object} profileData any
{string} profileData.uid any
{string=} profileData.profileId any
{boolean=} profileData.verify any
{string=} profileData.name any
{string=} profileData.profile any
{Date=} profileData.dateCreated any
{string=} profileData.handle - client-sent fallback any
{Object=} profileData.big3 - pre-extracted Big Three any

Returns

Promise<Object|undefined>

initSocket [Utility]

Starts a Socket.IO server on the provided HTTP server and manages real-time chat events.

Function:
initSocket
File:
socketService.js
Type:
Utility

Parameters

Name Type Description
{http.Server} server - The HTTP server instance to attach Socket.IO to. any

Returns

SocketIOServer - io - The initialized Socket.IO server instance.

wrappedInit [Utility]

Exports the socket initializer so the main server can enable real-time messaging.

Function:
wrappedInit
File:
socketService.js
Type:
Utility
isPlaceholder [Utility]

Single source of truth for how a connected user's name is displayed. Names are shareable once a connection is accepted, so friends are shown by name rather than @handle. The name to use is the **main user's** name: `profile.name` is a signup-time default ('Anonymous', see profileservice.addOrUpdateProfile) on accounts whose profile row was created before the name was known, and it is never re-synced when a user renames their main user. It is therefore only a fallback. Order: mainUser.name -> profile.name -> @handle -> 'Someone'. Every server-composed name (push notification text, conversation list) must go through here so all surfaces agree.

Function:
isPlaceholder
File:
displayName.js
Type:
Utility
isPlaceholder [Utility]

True when a profile name is a signup placeholder rather than a real name.

Function:
isPlaceholder
File:
displayName.js
Type:
Utility
fromProfile [Utility]

Profile-only fallback, used when no main user record is available.

Function:
fromProfile
File:
displayName.js
Type:
Utility
resolveDisplayNames [Utility]

Resolve display names for many uids in one query.

Function:
resolveDisplayNames
File:
displayName.js
Type:
Utility

Parameters

Name Type Description
{string[]} uids any
{Object<string,Object>} profilesByUid lowercased uid -> profile doc any

Returns

Promise<Object<string,string>> - lowercased uid -> display name

resolveDisplayName [Utility]

Resolve the display name for one profile document (must carry `uid`).

Function:
resolveDisplayName
File:
displayName.js
Type:
Utility

Parameters

Name Type Description
{Object} profileDoc profile with at least uid, name, handle any

Returns

Promise<string>

findUidsByMainUserName [Utility]

Find uids whose **main user** name matches a search term. Used by friend search, which must match the name the app actually displays.

Function:
findUidsByMainUserName
File:
displayName.js
Type:
Utility

Parameters

Name Type Description
{string[]} uids candidate uids any
{string} escapedTerm regex-escaped search term any

Returns

Promise<Set<string>> - set of lowercased matching uids

itemType [Utility]

Normalises a raw shared-item type to the allowlist.

Function:
itemType
File:
metricLabels.js
Type:
Utility

Parameters

Name Type Description
{*} raw - Value from Meta.itemType; may be missing or arbitrary. any

Returns

string - An allowlisted item type, 'unknown' if absent, else 'other'.

messageKind [Utility]

Message body kind.

Function:
messageKind
File:
metricLabels.js
Type:
Utility

Parameters

Name Type Description
{object} message - Message-shaped object with a ContentType field. any

Returns

'text'|'share'

conversationTypeOf [Utility]

Which inbox a message belongs to.

Function:
conversationTypeOf
File:
metricLabels.js
Type:
Utility

Parameters

Name Type Description
{string} toUserId - Recipient user id. any

Returns

'support'|'friend'

DATABASES

astromatrix
Name:
astromatrix
Host:
127.0.0.1:23516
Auth Source:
admin

Used In Files (8)

  • ai.js
  • app.js
  • message.js
  • paypal.js
  • aurasoma.js
  • migrate-friends-sweep.js
  • migrate-passwords.js
  • user.js

CLUSTERS

master (cpuCount workers)
Mode:
master
Workers:
cpuCount

Used In Files (3)

  • ai.js
  • app.js
  • message.js
worker (1 workers)
Mode:
worker
Workers:
1

Used In Files (3)

  • ai.js
  • app.js
  • message.js

SOCKETS

connection, message
Event:
connection, message
File:
message.js
typing, register_user, new_message, disconnect, error, headers, connection_error, connect_error
Event:
typing, register_user, new_message, disconnect, error, headers, connection_error, connect_error
File:
socketService.js
Handler:
initSocket