User_last_activity
Last platform activity timestamp per user
| Column Name | Data Type | Constraints |
|---|---|---|
| user_id | uuid | NOT NULL, PK, FK -> users |
| last_active_at | timestamp with time zone | DEFAULT timezone('utc'::text, now()) NOT NULL |
| inserted_at | timestamp with time zone | DEFAULT timezone('utc'::text, now()) NOT NULL |
One row per user. Rows cascade-delete when the user is deleted.
Population: the custom_access_token_hook auth hook stamps the row whenever Supabase Auth issues a JWT, which for an active client is each access-token refresh. A stamp newer than one day short-circuits on the primary key, so the write happens at most once per user per day and no application request pays for it. The hook returns claims unchanged and swallows errors, since a failing Postgres hook would break token issuance.
Enable the hook per project: local Auth is configured in supabase/config.toml; hosted projects select public.custom_access_token_hook under Authentication > Hooks.
System Admin roles receive user_last_activity.read by default. Custom roles do not inherit it until a herd admin grants the ability.
Security Policies (RLS)
RLS enabled. Herd scope: Each active users_roles_per_herd.herd_id of the row's user_id.
| Operation | has_herd_ability ability key | Other paths |
|---|---|---|
| SELECT | user_last_activity.read on a herd the target user currently belongs to | Row owner (user_id = auth.uid()); platform superadmin (every user) |
| INSERT | — | Auth hook or service_role; authenticated holds no write grant |
| UPDATE | — | Auth hook or service_role |
| DELETE | — | service_role |