Hidden from active operations. Permanent deletion is only available in this list.
For internal team use only: plain-language architecture and how information moves. Not customer-facing documentation.
Public site (wpulse.org) + institution portals
│
▼
PHP pages & API (e.g. api/*.php on this server)
│
▼
PostgreSQL, institutions, locations, surveys, responses, sales, backups…
▲
│
Cron jobs (server), reminders, scheduled backups, cleanup scripts
If you are not a developer, these names are just labels for parts of the stack. Short definitions:
.php (e.g. under api/).scripts/ folder.wpulse.org is mostly HTML/PHP on a web server, talking to a PostgreSQL database. Customers use browser-based flows (signup, admin dashboards, survey links). The server saves and reads data through PHP endpoints, not a separate mobile app server for core logic.
A respondent opens a survey link tied to an institution/location/template. The browser submits answers to the backend; PHP validates and writes rows into PostgreSQL (responses and related tables). Aggregates and dashboards read back from the same DB. Anonymity is enforced in how we store and link data, not by hiding the database.
The idea in kid-sized words: We want to stop someone from clicking “submit” ten times on the same survey in one day. We also do not want to keep a notebook of everyone’s private address book. So we use a math blender that turns two clues into two fingerprints. Fingerprints let us say “this looks like the same visitor again” without writing down the original clues.
┌─────────────────────┐ ┌─────────────────────┐
│ Clue A (IP-ish) │ │ Clue B (browser) │
└──────────┬──────────┘ └──────────┬──────────┘
│ │
└───────────┬───────────────┘
▼
┌───────────────────────┐
│ SHA-256 “blender” │ ← one-way math: easy forward,
│ (always same size) │ practically impossible backward
└───────────┬───────────┘
▼
┌───────────────────────┐
│ Two fingerprint codes │ ← saved on the response row
└───────────────────────┘
Why people call it “one-way”: Imagine you blended fruit into a smoothie. You can taste that it’s a smoothie, but you can’t unpour the blender and get the exact same whole fruits back. SHA-256 is like that: we can match “same smoothie again?” but we don’t keep the fruit bowl in the database for this check.
Same computer, different browser? Usually the User-Agent string changes, so user_agent_hash is different even if ip_hash is the same. The duplicate check requires both hashes to match, so we often cannot treat that as the “same device” for this rule, and the person could submit again the same day. That is a known limit of IP+UA fingerprinting (not a full device login).
api/responses.php uses hash('sha256', …) on REMOTE_ADDR and HTTP_USER_AGENT → ip_hash, user_agent_hash. Dedupe query counts responses where survey_id + both hashes + DATE(created_at) = CURRENT_DATE; if > 0, return 429. Stored digests are 64-char hex; index on (survey_id, ip_hash, user_agent_hash, created_at). Not a perfect human ID, shared Wi‑Fi / same browser string / VPN can look like one “device” or shift between days; different browser ⇒ different UA hash ⇒ dedupe key changes, so same-day resubmit may succeed.
On the server (typically cron calling PHP scripts under scripts/). They read/write the database and sometimes send mail. If a job stops, symptoms show up in product behavior (e.g. no trial reminders) or logs, this dashboard summarizes names and intent; the server carries the real schedule.
Tip: For exact script paths and example crontab lines, click Automated jobs above, or inspect scripts/ and server cron on the host.
backups schema (e.g., backups.table_YYYYMMDD).These are the no-login polls from wpulse.org/pulsedrop (Pulsedrop). You can fix typos in the question and choice labels. If a poll already has votes, keep the same number of options (only relabel). Deleting a poll removes all its responses (MFA required if enabled for your account).
| Status | Slug | Topic | Votes | Created | |
|---|---|---|---|---|---|
| Open this section to load polls… | |||||
This is a read-only overview of automation scripts and scheduled jobs configured for Wellness Pulse.
Actual scheduling is done in the server's crontab or database, but this panel summarizes what runs and why.
Sends trial ending / expired reminders to institutions on active trials.
scripts/send_trial_reminders.php0 9 * * * /usr/bin/php /var/www/pulse/scripts/send_trial_reminders.php
Creates monthly, quarterly, and yearly snapshots into the backups schema.
scripts/run_scheduled_backups.php0 0 1 * * php /var/www/pulse/scripts/run_scheduled_backups.php monthly >> /var/log/pulse_backups.log 2>&1 0 0 1 1,4,7,10 * php /var/www/pulse/scripts/run_scheduled_backups.php quarterly >> /var/log/pulse_backups.log 2>&1 0 0 1 1 * php /var/www/pulse/scripts/run_scheduled_backups.php yearly >> /var/log/pulse_backups.log 2>&1
Sends reminder emails to inactive sales reps and can auto‑deactivate long‑inactive accounts.
scripts/sales_rep_motivation.php0 11 * * 4 php /var/www/pulse/scripts/sales_rep_motivation.php >> /var/log/pulse_sales_motivation.log 2>&1
Database function that deletes old API rate‑limit records older than 1 hour.
sql/create_api_tables.sqlcleanup_old_rate_limits()-- Example cron calling PostgreSQL */15 * * * * psql <connection> -c \"SELECT cleanup_old_rate_limits();\"
If you add new automation scripts under scripts/ or new scheduled database jobs, remember to
update this panel so Super Admins always see a complete picture.
This shows all available business types and their associated default survey templates. Each business type gets specific templates tailored to their industry when an institution is created.