Admin
A person confirms payments, checks pilots and sends payouts. Work the queues top to bottom.
Queues
Pilots to verify
Oldest first. Open each application, check the documents against the FAA Airmen Inquiry, then verify or ask for more.
Payments to confirm
Search the session id, or the customer email and the amount, in the Stripe Dashboard. Confirm only when the payment shows as succeeded.
Invoices to send
A pilot accepted these jobs, and their package has no Stripe Payment Link, so the customer is waiting for an invoice. Send a Stripe invoice for the price from the Stripe Dashboard, with the job id in the memo. A job leaves this list when the customer reports the payment. If Stripe shows the invoice as paid and the customer has not reported it, click Confirm payment here.
Payouts due
Send the transfer from the Stripe Dashboard, then record the transfer id here. Recording a payout completes the job.
Quotes to set up
The customer accepted a bid. Create the job, then send the Stripe invoice for the customer price from the Stripe Dashboard.
New quote requests
Custom and event requests with no accepted bid yet, oldest first. Verified pilots who cover the address see them on their quote board. No pilot in range means no verified pilot covered the address when the customer asked. Nobody can bid until you recruit one.
Stuck jobs
Jobs that have waited too long at one step. Approve on the customer's behalf, cancel with a note, or close an expired request.
Zeros and waitlist
Bookings from the last 30 days with no pilot in range, and the last 50 waitlist sign-ups by metro. This is where to recruit next.
Refunds
Issue the refund in the Stripe Dashboard first, then record it here so the job shows the right payment status.
Metrics
Daily snapshots
Rows in stats_daily written by Save today's snapshot. Newest first.
Where the numbers live
Every number on this page is computed in the browser from Firestore: jobs, pilots, reviews, waitlist and stats_daily. Traffic, pre-submit drop-off and attribution live only in GA4 and, when a key is set, PostHog.
Pilots
Every pilot account, newest first. Recompute stats after jobs complete. Set the payout account after you create the Stripe Express account for a verified pilot.
Course
The free drone license course. Who asked for the link, who signed in, how far they watched, and who went on to apply to fly.
Link requests
Every request for a sign-in link in the range, counted by person (one per email). These rows are written by each visitor's browser, so a script can add fake ones, and "link sent" is what that browser reported.
Learners
Accounts that first opened the course in the range, and what they have done since. Includes signed-in customers who never asked for a link.
Parts
How far learners in the range got in each part. Finished means playback reached the end of the narration; skipping ahead counts.
By source
Everyone in the range (people who asked and learners), by the campaign or referrer that first brought them to the site. Entry points are in the CSV.
Learner list
Asked but never enrolled
People who asked for a link and have no course record. These addresses are unconfirmed: anyone can type anyone's address into the form. Do not send them marketing. "Link not sent" means the browser reported that Firebase refused the send; the code says why. The privacy policy promises that requests nobody confirmed are deleted after 90 days: press the button once a month.
Where the numbers live
Requests come from course_signups, progress from course_enrollments and pilot applications from pilots, all in Firestore. Landing page visits, sources and form drop-off live only in GA4. So do sign-in links that were opened but did not end in an enrollment: course_link_opened (by link_path) and course_confirm_submitted.
Platform settings
Saved to config/platform. Every page reads it on load.