Platform & admin
Ascendly platform features for super admins (access level 5), HR, and engineering — sign-in policy, operational health, broadcast email, employee onboarding, and access-level reference.
Last updated: July 4, 2026
Sign-in & domains
Google OAuth
All clients (web and desktop) use Continue with Google. After Google returns a profile, the API validates in order:
- Email domain ∈
ALLOWED_EMAIL_DOMAINS(server env) — else403 - Email verified with Google — else
403 - Employee record exists in
tbl_employees(matchgoogle_suborpersonal_data.email_address) — else403
Initial domains: outdoorequipped.com, channelprecision.com. HR must create the employee profile before first sign-in.
Work email on employee create/update
When admins create or edit an employee's work email, the API validates the address domain against the same allowlist (ensure_email_domain_allowed).
Legal pages (public)
| Route | Purpose |
|---|---|
/privacy | Privacy policy |
/terms | Terms of service |
Available without signing in. Desktop opens these in the system browser.
Desktop refresh tokens
Desktop sign-in (POST /v1/auth/google with client: "desktop") returns a refresh token in addition to the JWT. The desktop app stores both in OS-encrypted storage and silently renews via POST /v1/auth/refresh. Sign-out calls POST /v1/auth/logout with the refresh token to revoke it.
Web uses JWT only (no refresh token).
Access levels & permissions
Ascendly uses numeric access levels (1–5) on tbl_employees. Level 5 is super admin; level 1 is a standard employee.
Permissions page (/permissions)
Read-only matrix showing what each level can do across:
| Resource | Actions |
|---|---|
| Employees | view, create, request_create, approve_requests, edit, delete |
| Scorecard | view, submit, edit, delete |
| Organization | view_tree, edit_departments, assign_managers, create_cluster_or_department |
| Tasks | view, create_edit, delete |
| Configurations | view, edit |
| Dashboard | manual_sync |
| Activity logs | view |
API: GET /v1/auth/permissions (current user) · GET /v1/auth/permissions/matrix (full matrix, level 5).
Level 5 users can impersonate another employee for support — impersonation is scoped in audit logs and activity tracking.
System status (/system)
Super admins see operational health at /system.
API: GET /v1/system/status
| Check | What it reports |
|---|---|
| MongoDB | Connection ping |
| BigQuery | Configured, enabled, SELECT 1 probe |
| S3 | Configured, bucket connectivity (ATW proof images) |
| Worker | Heartbeat from tbl_worker_status (keyed by API_ENV); stale after 120s |
| BSC rolling sync | Current period, last rolling sync timestamp, interval |
Overall status is ok or degraded. Worker heartbeats are environment-scoped — local dev (API_ENV=development) and Railway staging/production each show their own worker.
Related pages: System → Notifications (/system/notifications), System → Email (/system/email).
Maintenance mode
Use during deploys, data cutovers, or incidents when most users should not use Ascendly while engineers verify production.
Server configuration
Set on the API service (Railway env or local .env):
| Variable | Default | Purpose |
|---|---|---|
MAINTENANCE_MODE | false | When true, API returns 503 for most routes |
MAINTENANCE_MESSAGE | (built-in default) | Optional custom text shown on the web maintenance page |
MAINTENANCE_BYPASS_EMAILS | (empty) | Comma-separated work emails that may sign in and use the app normally |
Example bypass list: admin@example.com,ops@example.com (matched case-insensitively against the employee profile email).
API behavior
| Path / caller | Behavior |
|---|---|
GET /health | Always allowed |
GET /v1/public/app-status | Always allowed — web/desktop poll this for maintenance state |
POST /v1/auth/google, POST /v1/auth/refresh | Allowed through middleware; handler rejects non-bypass emails with 503 |
| Authenticated requests | Allowed when the JWT user’s email is in MAINTENANCE_BYPASS_EMAILS |
| Everything else | 503 with { maintenance: true, message: "…" } |
The worker process is not blocked (API_ENV=worker skips maintenance middleware).
Web behavior
- Polls
GET /v1/public/app-statuson load and after sign-in. - Non-bypass users are redirected to
/maintenance(full-page message). /login,/auth/callback, and/maintenancestay reachable so bypass users can sign in.- Failed sign-in during maintenance redirects to
/maintenanceinstead of showing raw JSON.
Turn maintenance off (MAINTENANCE_MODE=false) and redeploy when verification is complete.
Admin email compose (/system/email)
Super admins (level 5) can send a broadcast message to selected employees.
| Field | Notes |
|---|---|
| Recipients | Multi-select employees (max per send); quick-add by org group |
| Subject | Required |
| Body | Rich text (plain + HTML) |
| Action URL | Optional deep link in email / in-app |
| Delivery | Email (Gmail delegation), In-app notification, or both |
API: POST /v1/system/email/send
Requires Gmail delegation configured on the API (NOTIFICATION_EMAIL_* env vars). Per-recipient results show email and in-app delivery status. Actions are audit-logged.
Use for company announcements — not for automated scorecard notifications (those use the notification type catalog).
Welcome email (Employees)
On Employees (/employees), admins with create/edit access can select one or more rows and Send Welcome Email.
API: POST /v1/employees/welcome-email with { employee_ids: string[] }
Sends a branded welcome message (email when configured) and can emit an in-app notification. Useful after HR creates a profile so the employee knows they can sign in with Google.
Activity tracking
Ascendly records sign-in time, last active (web) and last active (desktop), and active minutes per client. Managers see split columns on Employees; employees see their own summary on Profile (web) or Home (desktop).
Full rules — visibility, heartbeats, throttling, impersonation, and HR troubleshooting: User activity.
API: GET /v1/employees/activity-export for team CSV export (same scope as the employee list).
Related docs
- Notifications — in-app + email delivery, type catalog
- User activity — last active, active minutes, heartbeat rules
- Desktop app — tray, offline banner, refresh tokens
- API reference — route index
- BigQuery dashboard — sync jobs, worker
- Progress report — shipping status
