3.7 KiB
name, description, user-invocable, argument-hint
| name | description | user-invocable | argument-hint |
|---|---|---|---|
| prod-db | Look up data in Cleo production read replicas (Postgres, IAM auth, read-only). Use when the user asks to look up, find, or check something in prod / the prod DB, e.g. a user id, family id, guide id, or other record IDs for a given user. Returns IDs and metadata only, never PII/PHI. | true | [question about prod data] |
prod-db
Query prod read replicas through one script. Never call psql or aws rds directly.
~/.config/claude/skills/prod-db/prod-query.sh <alias> "<select sql>"
~/.config/claude/skills/prod-db/prod-query.sh <alias> --tables
~/.config/claude/skills/prod-db/prod-query.sh <alias> --columns <table>
The script connects to the cluster-ro endpoints as reader, forces read-only sessions with a 30s statement timeout, and caps output at 200 rows. If it reports no SSO session, ask the user to run ! aws sso login --profile prod-mono-reader.
PII/PHI rules (org policy: never put PII/PHI into Claude)
- SELECT only IDs, foreign keys, UUIDs, timestamps, statuses, flags and counts.
- Never select names, emails, phones, DOB, addresses, notes, message bodies, health data, or Kratos
traits. NeverSELECT *. - A value the user gives you (an email) may appear only in a
WHEREclause. Do not repeat it in your output; refer to "the user". - The script blocks
*, non-SELECT statements, and result columns whose names look sensitive (it prints only the offending column names). Aliasing a sensitive column to dodge this is forbidden. If the user needs a PII field, tell them to look it up in Postico. - Report results as IDs only.
Workflow
- Pick the alias. Run
--tables/--columns <table>(schema only) before writing SQL for an unfamiliar table. - Write a narrow SELECT with explicit columns and a
LIMIT. - Summarize the IDs. Don't paste raw output beyond what's needed.
Aliases
backend (backenddb), guides, kratos, userflow (userpreferencesdb), scheduling (schedulingdb), messaging (messagingdb), eligibility (eligibilitydb), entitlements (entitlementsdb), benefits (benefitsdb), assessments (assessmentsdb), engagement (engagementdb), tagging (taggingdb), supportplan (supportplandb), integrations, content (thegoodcontentdb), retool.
Schema notes
backend (Django app lucy_web, public schema):
auth_user(id, email)is the user.lucy_web_family(id, employee_user_id, partner_user_id)links a user to a family, as employee or partner.lucy_web_childfamilypackage(id, family_id, child_id, guide_id, guide_assigned_on)links a family to its guide. The current guide is the row with the highestidfor the family (seeFamily.lucy_guideinservices/cleo-backend/lucy_web/models/family.py).lucy_web_lucyguide(id, uuid, user_id, is_active)is the guide.user_idis the guide's ownauth_userrow. Do not select the guide's name or email.- Caregiver users are linked through the caregiver childfamilypackage models, which this query does not cover.
guides: tables store a numeric guide_id equal to lucy_web_lucyguide.id. It does not own the user-to-guide assignment.
kratos: identities(id uuid, traits jsonb). The Kratos id is not known to equal backend auth_user.id. Bridge on email, inside WHERE only. Unverified for this deployment.
Example: user id and guide id for an email
select u.id as user_id, f.id as family_id,
g.id as guide_id, g.uuid as guide_uuid, cfp.guide_assigned_on
from auth_user u
join lucy_web_family f on f.employee_user_id = u.id or f.partner_user_id = u.id
join lucy_web_childfamilypackage cfp on cfp.family_id = f.id
join lucy_web_lucyguide g on g.id = cfp.guide_id
where lower(u.email) = lower('<email>')
order by cfp.id desc
limit 5
Run it with alias backend.