Enter your username. We'll SMS a reset link to the phone on file.
Enter your phone number. We'll SMS all usernames registered to it.
Checking your reset link…
✅ Password updated successfully.
Set your base location and local timezone.
When enabled, the system automatically turns off Auto Dispatch whenever an admin logs in. As a failsafe, the system will automatically re-enable Auto Dispatch if all admins close their browser.
Used on PDF invoices sent to account customers. Leave blank to omit.
Required for sending invoice PDFs to account customers via email.
Enable/disable receipt options that drivers see at the end of each job.
Generate a PDF invoice for a specific account customer and month. An SMS with the download link is sent automatically.
Fixed info bar above the dispatch calendar. Scrolls right→left in the green used by 'DISPATCH' and 'connected'. Toggles are live-saved to the backend.
Configure automated text messages sent to
customers.
Available Placeholders:
{customer_name}, {phone_number}, {pickup_address}, {dropoff_address}, {pickup_time}, {job_id},
{booking_ref}, {driver_name}, {driver_first_name}, {car_make}, {car_model}, {car_color},
{registration}, {eta_minutes}, {distance_miles}, {manage_link}, {feedback_link}
Texts sent to the assigned driver only for Scheduled / future jobs. Each toggle is independent. Message text is fixed (not template-driven).
"Confirming Job #… on … — pickup … (You have N other upcoming jobs.)"
Only fires when the job was assigned more than 24 h before the pickup time.
1 hour before for local jobs; 2 hours before for long-distance jobs.
SMS the assigned driver when the customer or dispatch changes the booking.
SMS the assigned driver when the booking is cancelled (any source).
Populates {tracking_link} in SMS templates.
Alerts for unallocated jobs (12h/6h before) and ASAP jobs with NO drivers.
SMS admins when a customer books a job due in the next 36 hours. Admin-panel bookings are excluded — this only fires for customer-initiated bookings (web, AI voice, portal, account portal).
Define up to 4 User-Enabled Rates.
Assign rates to specific times.
Define fixed prices for Airports. Pickups get "excludes parking", Dropoffs get +£10.
A job is flagged Out of Area when both pickup and dropoff postcodes have an outward code
that differs from your home postcode. When that triggers, the fare is calculated as
meter fare (A→B at standard SDC rate) + OOA surcharge — where the surcharge is
(shortest dead-mile leg × sliding-scale reduction − in-area allowance)
× per-mile rate below. The meter handles the actual trip; the surcharge covers
the dead mileage. Return-journey estimates are doubled so the customer sees one total.
GL5)
are Out of Area. Ignored when a City-Limit Zone is selected below.
One rate per base tariff slot. The rate applied is chosen by the active tariff (1/2/3/4) at pickup time. Rate 4 is a placeholder for future use.
When the one-way live distance is ≥ the threshold, the fare is calculated as the median (average) of two values:
The result is rounded down to the nearest £5. Airport flat rates always win (unless bypassed below). The OOA surcharge does not apply on long trips — the £/hour component already covers dead mileage. A pickup in the opposite direction of the dropoff naturally inflates the round-trip drive time, so no separate detour surcharge is needed.
Enter pickup + dropoff to preview the long-trip quote (uses the settings above). Useful for phone quotes. Pickup time is optional (defaults to "now" for live-traffic lookup).
When a customer amends an assigned job, the system classifies the change as
minor (silently accepted — the driver keeps the job) or disruptive
(the job is unassigned and re-offered to the bidding pool with a 60-second cooling-off,
exactly like a new job). Admin edits are always minor. See AMEND_RULES.md.
How many drivers you expect to be working to handle future bookings.
When calculating if a new future booking can physically be completed, the system simulates the travel time between existing jobs. Add buffers here to account for delays and ensure the driver has enough time.
Uses Google Maps API with real-time traffic data for more accurate ETA calculations.
Regulated hackney meter rates used by the driver app's in-cab taxi meter. Independent of the dispatch quote tariffs above (which estimate fares for bookings). Verify against your council's published tariff before changing — the meter is a legal instrument. Changes propagate to drivers on their next app reload (or next time they press START on the meter).
Controls how the driver-app taxi meter accrues wait charges on a Wait & Return job between the driver pressing Start Wait (at the way-point) and Continue to Final Destination. Only affects Wait & Return Leg 1 — regular jobs are unchanged.
Generic Meter Timer: the meter keeps using the normal wait_seconds drop logic (Rate 1/2/3) while the vehicle is stationary. Fixed Price Wait Time: the meter switches to a pro-rata accrual of the hourly rate above (e.g. £20/hr = £0.333/min) while stationary during the Start Wait → Continue window, replacing the normal wait drop. Distance charges continue normally once the vehicle moves. Changes apply on the driver's next app reload.
Define geographic zones (named polygons) and derive their postcode
districts. This is a data layer only — no pricing or dispatch logic
consumes it yet (zones_enabled=0).
Loading zones…
No inactive zones.
Stripe card-on-file payments for the consumer portal. This is a 4-layer
sandbox: the master toggle + per-customer beta whitelist below are layers
1 & 2; layer 3 is the card_paid=0 default on every booking;
layer 4 is Stripe test mode (use rk_test_… keys until ready
for live money). All card-payment endpoints return 503 until
the master toggle is ON and the Stripe SDK + keys are configured (Phase 1).
See CARD_PAYMENTS.md for the full plan.
When OFF, all card-payment endpoints return 503 and the portal "pay by card" option stays hidden. Flip ON only after the Stripe SDK + test keys are configured.
One customer ID per line. Only these customers will see the "pay by card" option in the portal (when the master toggle is also ON). Use this to test with your own customer ID + a family member's before widening.
* = all customers. Use only when fully confident in the live flow.
Keys are stored in /etc/systemd/system/taxi.service.d/stripe.conf
(VPS-only, mode 600 — never synced to the workspace). Configure via SSH:
ssh root@159.198.42.250 "nano /etc/systemd/system/taxi.service.d/stripe.conf"
then systemctl daemon-reload && systemctl restart taxi.
The fee is charged to a customer's pre-authorised card when a driver marks a
job as no-show (from "En Route" or "At Pickup" status) OR when a customer
cancels within the timer threshold before pickup. Capped at the pre-authorised
amount, so a low pre-auth will reduce the captured fee. Set the fee to
0 to disable it entirely (releases the pre-auth on no-show instead
of charging it). The timer threshold is shown to the customer in the portal
booking-flow legal blurb.
Stored in company_settings.stripe_no_show_fee_pence +
stripe_no_show_fee_timer_hours. The env var has been removed —
these DB fields are the single source of truth.
Pre-authorise estimate × multiplier on the customer's card at
booking time (a hold, not a charge). Short jobs get the biggest multiplier
so a detour that doubles the meter doesn't hit the capture cap + silently
undercharge. Brackets must be in ascending order with no overlap — the
last bracket is the "no upper cap" band. The capture path auto-releases
any unused hold on completion.
Stored in company_settings.stripe_preauth_brackets (JSON).
Default: ≤£7.50 ×5, £7.51–£15 ×3, £15.01–£30 ×2, >£30 ×1.5.
Cached 60s to avoid hitting the Stripe API on every tab refresh. Auto-refreshes on tab open.
Each driver's commission rate for card-paid jobs. Percentage = % of net (after Stripe fees). Fixed = flat £ per job. Rate is locked at capture time — changing it doesn't affect past ledger entries.
Comma-separated, e.g. GL5, GL10, BS1. Manual adds are preserved on a rebuild only if you re-add them.
Recent login/security events.
| Time | User | Event | IP | Details |
|---|
Track all loyalty earnings and redemptions.
| Date | Customer ID | Job ID | Handled By | Type | Amount | Remaining | Status | Expires |
|---|
All outbound + inbound SMS with delivery receipt (DLR) status. Customer SMS via ClickSend, driver/admin via Traccar.
| Time | ↕ | Provider | Trigger | Phone | Message | Job | DLR | £ |
|---|
Recent ratings and reviews from customers.
| Date | Driver | Customer | Rating | Feedback |
|---|
💳 Card Terminal
Defines when this driver is willing to work. Drives the dispatch map's calendar overlay (Phase 2). Drivers without a matrix are hidden from the calendar until one is set.
Send drivers a one-time link to connect Google / Outlook / Apple Calendar. Job events are pushed automatically once connected.
Non-Anytime drivers we send overflow / closure work to. Assigning a job to one of these sends an SMS with a link to a one-job driver page (no app install needed).
| Name | Phone | Company | Vehicle | Notes | Bid SMS | Last used | Actions |
|---|
Editing the text automatically bumps the version — every external driver will need to re-accept on their next visit. The agreement is shown as a splash screen before they can see jobs.
Configure business hours for the AI phone system. Calls outside operating hours will trigger a callback to the team.
| Day | Active | Open | Close |
|---|---|---|---|
| Monday | |||
| Tuesday | |||
| Wednesday | |||
| Thursday | |||
| Friday | |||
| Saturday | |||
| Sunday |
When a driver is online during closed hours, allow bookings within a time window.
Company-wide full-day closures (annual leave, bank holidays, Christmas shutdown). Bookings with a pickup date inside an active closure are blocked on all channels (webform, portal, AI voice). Existing bookings are honoured — cancel them manually if needed. Inbound calls still ring the team; only the AI's booking flow changes. Closures inherit the Driver Override setting above (a driver online during a closure can still take ASAP bookings within the override window). Closure rows save immediately — no need to click SAVE SCHEDULE.
| Start | Last Closed | Reason | Reopens | Actions |
|---|
Search all jobs including rejected and cancelled bookings.
| ID / Date | Customer | Route | Status | Source | Price | Actions |
|---|---|---|---|---|---|---|
| Enter search criteria above... | ||||||
Generate monthly job reports for driver account reconciliation.
| Job ID | Date | Pickup | Dropoff | Price | Driver Fees | Account |
|---|
Manage admin access and alerts.
| Username | Role | Phone (Alerts) | Last Login | Action |
|---|
Drivers bid on unassigned jobs from the driver app. An independent 30-day-rolling fareshare algorithm (jobs 50% / efficiency 30% / miles 20%) picks the winner when each bidding window closes. ASAP jobs race round-robin via "first-click-wins". Disabled by default.
Weights should sum to 1.0. The algorithm normalizes defensively if they don't.
How long a scheduled job stays open for bidding before the fareshare winner is picked. The window tier is chosen by time-to-pickup. ASAP jobs have no fixed window (first-click-wins).
Loading…
Automatically create standing bookings (school runs, regular hospital appointments, weekly commutes). A nightly background loop (just after 04:00) spawns each rule's upcoming occurrences 7 days ahead of pickup, priced at that occurrence's own tariff, and sends them through the normal dispatch + bidding flow.
Loading…
The nightly loop runs just after 04:00. Use the button below to run it immediately (useful right after creating a rule so the upcoming occurrences appear without waiting for the next tick).
Loading…
Download a snapshot of the database or restore from a previous backup.
Creates a Zip file containing taxi_dispatch.db.
Upload a backup Zip file to restore the system
state.
WARNING: This will overwrite current data!
Drag blocks to reorder, toggle to show/hide, and click a block to change its style.
☰ Drag to reorder | Toggle to show/hide | Click block for style options
Only change these if your printer hardware behaves differently from a standard 58 mm thermal printer.
Status and configuration for the third-party services the app uses.
Secrets are shown as ••••••••last4.
Saving the AI knowledge base restarts the AI voice service.
This text is loaded into the Gemini AI voice agent's system instruction as
BUSINESS INFORMATION. Editing it changes how the AI answers questions
about the business. Saving writes /var/www/taxi-ai/knowledge.txt atomically
and restarts taxi_ai.service so the new text takes effect.
An AI chat assistant embedded in the admin panel. Helps dispatchers with
job lookups, status explanations, and dispatch procedures. Reads the
dispatch_rules.txt knowledge base below. PII-safe — never sees
customer names, phone numbers, or addresses. Enable it, then use the
floating chat button (bottom-right) to ask questions.
Controls the agent's role, tone, and behaviour. This is the system instruction sent to Gemini on every question. If left blank, a sensible default (concise dispatch helper, no PII access, cites knowledge base sections) is used. Edit this to change the assistant's personality, add custom rules, or restrict its scope. Changes take effect on the next question — no service restart needed.
Tip: include the line "You are Mini-Me, …" to set the agent's identity. Mention tone (e.g. "friendly and concise"), scope (e.g. "only answer dispatch-related questions"), and any hard rules (e.g. "never suggest cancelling a job without checking with the operator").
Operator-editable knowledge base. The assistant reads this on every question
and uses ## headings to find relevant sections. Expand it over time —
the richer the file, the better the answers. No service restart needed (read fresh
on each /ask call).
Data protection register, retention schedule, DPIA, DPA register, privacy notices, and (Phase 2-3) SAR extraction, erasure, breach incident register, DSAR queue. Admin-only — standard dispatchers do not see this tab.
Hardcoded retention periods per data category. Mirrors GDPR_COMPLIANCE.md §5.1
+ purge_old_data(). The daily 03:30 UTC cron runs the purge.
Loading…
Last purge timestamp, next scheduled run, per-table row counts + purge-eligible counts. The "Run purge now" button triggers a manual purge in the background (can take 10-30s on a large DB).
Loading…
Data Protection Impact Assessment for driver GPS tracking + Twilio call recording.
Draft pending operator + DPO sign-off. Reads from
compliance/DPIA_GPS_CALL_RECORDING.md on each request.
Loading…
List of sub-processors + their Data Processing Agreement status. Reads from
compliance/DPA_REGISTER.md. DPA PDFs in compliance/dpas/ are downloadable.
Loading…
Links to the live customer/driver privacy notices, cookie policy, terms of service, and accessibility statement. These are the public-facing legal pages served at clean URLs.
Loading…
Generate a Subject Access Request bundle (ZIP) containing all personal data for a customer or driver.
Wraps sar_extract.py. Dry-run prints what would be extracted without writing a ZIP.
Every extraction is audit-logged.
Loading…
Execute GDPR Art. 17 right-to-erasure for a customer. Two-step process: dry-run preview (mints a
single-use confirm token), then execution (requires typing ERASE). Wraps erasure_execute.py.
Generates an erasure certificate JSON on execution.
Loading…
Trigger a manual retention purge (deletes/anonymises data older than the cutoffs above). The daily 03:30 UTC cron runs this automatically; this button lets you run it on-demand.
Loading…
Tails the Content Security Policy violation log (last 200 lines). Useful for triaging CSP reports before switching from Report-Only to enforcement. Clear the log after triage.
Loading…
Reads the latest pip-audit report from /var/log/taxi-app/pip-audit-latest.json
(written by a cron job). Shows vulnerable packages, CVEs, and fix versions.
Loading…
Breach incident register, DSAR request queue (Art. 12/15), consent ledger (Art. 7), + sub-processor change-log (Art. 28). New backend+UI for genuine GDPR gaps.
https://anytimetaxi.co.uk/api/clicksend/dlr?token=WEBHOOK_TOKEN
CLICKSEND_WEBHOOK_TOKEN env var (systemd drop-in). Without a token in the URL, the webhook returns 401.
All PDF invoices produced by the monthly generator. Click Download to open the PDF, Resend SMS to push the link again, or Regenerate to overwrite with fresh data.
| Invoice # | Account | Period | Mode | Total | Generated | SMS | Actions | |
|---|---|---|---|---|---|---|---|---|
| Loading… | ||||||||
Manage all customers, edit details, and view their booking history.
| ID | Name | Phone | Email / Address | Jobs | Badges | Actions |
|---|---|---|---|---|---|---|
| Loading... | ||||||
Gamified loyalty rewards (replaces the flat-rate 10% earn when enabled).
Each fare bracket has 4 prize amounts. Fares above the highest bracket cap go into premium.
| Bracket | Max Fare (£) | Prize 1 (lowest) | Prize 2 | Prize 3 | Prize 4 (highest) |
|---|
Relative odds of picking each prize tier. They don't need to sum to 100, but should be balanced.
Customers see one game per spin, rotated so they never see the same game twice in a row. At least one must be enabled.
Variables: {play_link}, {customer_name}. Optional: {opt_out_link}, {terms_link} — both are already shown in the play page footer, so you usually do not need them in the SMS body.
/loyalty-terms.html page (3L-5).Send a one-off welcome reward to a customer (e.g. for a bulk-invite campaign, or to test the flow). Refused for customers who have opted out or who have already played their onboarding spin.
Inspect issued tokens for support / debugging.
| Created | Token | Customer | Type | Bracket | Prize | Game | Status | SMS Sent | Expires |
|---|---|---|---|---|---|---|---|---|---|
| Click "Apply Filter" to load. | |||||||||
Super Admin tool: look up any job by ID and edit all fields directly. Changing the flight number will automatically unsubscribe the old flight and subscribe the new one.
| Field | Value |
|---|
Live operational metrics. Pick a category from the dropdown to view its dashboard. All revenue figures use completed-jobs pricing; date windows are UTC to match the database.
Select Driver (Online/Busy/Offline):
Editing user:
Enter new password for user :
Mint a 30-day single-use invite link and text it to the candidate. They'll verify their email, fill the form, and the application will appear in the bell queue for review.
Select one of your top 20 customers, or search by name or number:
Loading customers...
Select a frequent trip for :
Loading trips...
Invalid email format
| Date | Pickup | Dropoff | Price | Status |
|---|
Loading conversation…
The system found the following customers with highly similar names and phone numbers. Click 'Merge Group' to consolidate their history into the Primary profile.
Scanning database...
Looking up caller…
Loading…
Send a one-time setup link to the driver's phone, or manage their existing connections.
No statements yet.