Documentation/Reference apps/Lumen is an open-source clinic booking app with a Google Calendar step
Lumen is an open-source clinic booking app with a Google Calendar step
Lumen is an open-source clinic appointment booking app. Patients book visits and staff run the schedule. Source on GitHub, live demo at lumen.supero.live.
- apps
- healthcare
- workflows
- google-calendar
- field-level-access
Overview
Lumen is an open-source clinic appointment booking app in which creating an appointment row is enough to start the patient's email and the clinic's calendar event.
Three of the 19 apps in the supero-apps repo list
google_calendar among their services. Lumen, a multi-specialty clinic app, is the only one whose code calls it. Its code is the lumen folder of that repo. The call is the second step of a workflow in setup.py:python
{"id": "calendar", "type": "service_call", "service": "google_calendar", "operation": "create_event", "on_error": "continue",
"input_map": {"summary": "Lumen Health — {{input.patient_name}} with {{input.provider_name}}",
"start_time": "{{input.start_time}}", "end_time": "{{input.end_time}}",
"timezone": "America/New_York",
"description": "Visit reason: {{input.reason}}. Patient: {{input.patient_name}} ({{input.patient_email}}). Provider: {{input.provider_name}}."}},Nobody presses a button for this.
What `@create:lumen:appointment` sets off
The patient fills in the booking form in ui/app.js and the front end makes one call,
client.createObject('appointment', rec), with appt_state set to requested. The client does nothing else. An entry in EVENT_BINDINGS ties the event @create:lumen:appointment to the workflow appointment_confirmation, version 1.1.0, and maps six fields of the new record into its input. Step one sends an email. Step two is the calendar event above, carrying the visit reason and both names in its description. Both are marked on_error: continue. Credentials for a service like Google Calendar are set in the admin panel, never in the code, so a copy with no calendar connected still books the visit and simply skips past that step.If you build software for clinics, that binding is the part to copy. The booking screen stays a plain form, and what happens after a booking lives in a Python list beside the seed data, so that when the front desk asks whether it can also text the patient you add a step to a list and leave the screen alone. Lumen has that step already. Its second workflow,
appointment_reminder, sends an email and an SMS and then stamps reminded_at on the appointment. No event is bound to it. Staff run it from the schedule with a Send reminder button.Three fields missing from the patient's copy
Lumen has two roles.
tenant_admin is the front desk and the providers. tenant_user is the patient. Each starts from default_access="none" with one rule per entity, so anything a role can touch is written down as five rules. This is the patient's rule for appointments:python
PolicyRule(entity="appointment", can_read=True, can_create=True, can_update=True,
filter_field="owner_username", filter_match="$user.name",
hidden_fields=["clinical_notes", "diagnosis", "internal_billing_code"]),The
filter_field pair is policy-based row scoping: a patient reads only the appointments whose owner_username matches their own login. The last argument works on columns. For a tenant_user those three fields are absent from the response body, removed server-side. The staff rule for the same entity has no hidden_fields, so the staff console in the same app.js renders a "Clinical (staff only)" panel with the notes, the diagnosis and the billing code.The seed data lets you watch it happen. The demo patient, Daniel Brooks, has five appointments, and two of them are completed visits that carry clinical notes, a diagnosis such as "Benign melanocytic nevus (D22.5)" and a billing code such as
99395. On a freshly seeded copy the patient's portal lists all five, and for the front desk those two visits open with the clinical panel filled in.The login screen names both demo accounts.
Lumen models the shape of that access control. It is a reference app and carries no certification, and its README tells you in the first lines to keep real patient data out of it.
Consent is a `doc_state` and a timestamp
schemas.py defines five schemas (one per kind of record) with 54 attributes between them:
Provider, ClinicService, Patient, Appointment, Document. The first two are listed in PUBLIC_SCHEMAS, so the landing page can show eight seeded providers and eight services to a visitor who has not signed in. Appointment declares a validation called end-after-start with severity error.Document is how Lumen handles consent forms. A document has a doc_state of pending, signed or completed, and the patient's Sign button updates the row to signed and writes signed_at. Nothing more. One of the four seeded documents is still pending, the new-patient intake consent, so on a fresh seed the button is there to press.The booking page also has a symptom helper. It sends the patient's description and the list of services to
services.ai.complete and asks for one suggestion, and when that call returns nothing a keyword map in app.js picks a specialty instead. The whole front end is React in one file of 545 lines, and it runs with no build step.Clone the clinic booking app and pick a domain name
bash
git clone https://github.com/supero-platform/supero-apps.git
cd supero-apps/apps/healthcare/lumen
cp .env.example .env # set SUPERO_DOMAIN (any free name) + SUPERO_PASSWORD
./run.shFour commands. No Supero account is needed, since
run.sh registers whatever domain you put in .env, and you should have it running in about two minutes at http://localhost:5663. The app refuses to start until SUPERO_PASSWORD is set.The code in the lumen folder is MIT. The platform it talks to is a hosted service, and that part is closed.
To look before you clone, sign in at lumen.supero.live with either demo account, then replace the eight entries in
SPECIALTIES with your clinic's own.When you would sooner begin from an empty project than from Lumen, that starts at supero.dev.
On this page