Skip to content

Commit 14c3887

Browse files
committed
Add exercise field to profiles; update filters, components, and database schema
1 parent 37e8a42 commit 14c3887

22 files changed

Lines changed: 230 additions & 37 deletions

CLAUDE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ Database:
6363
yarn --cwd=backend/api regen-types-dev # rebuild common/src/supabase/schema.ts
6464
```
6565

66+
Every new migration must also be appended to `backend/supabase/migration.sql` (`\i
67+
backend/supabase/migrations/<file>.sql`, before the closing `COMMIT;`) — that ordered list is what rebuilds
68+
the schema from scratch.
69+
6670
## Adding an API endpoint (3 files across 2 packages)
6771

6872
1. **Schema** — add entry (method, `authed`, Zod `props`, `returns`) in `common/src/api/schema.ts`.

backend/api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@compass/api",
3-
"version": "1.56.0",
3+
"version": "1.57.0",
44
"private": true,
55
"description": "Backend API endpoints",
66
"main": "src/serve.ts",

backend/api/src/get-profiles.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {type APIHandler} from 'api/helpers/endpoint'
44
import {
55
DIET_CHOICES,
66
EDUCATION_CHOICES,
7+
EXERCISE_CHOICES,
78
GENDERS,
89
LANGUAGE_CHOICES,
910
MBTI_CHOICES,
@@ -88,6 +89,7 @@ export type profileQueryType = {
8889
wants_kids_strength?: number | undefined
8990
has_kids?: number | undefined
9091
is_smoker?: boolean | undefined
92+
exercise?: string[] | undefined
9193
shortBio?: boolean | undefined
9294
psychedelics?: string[] | undefined
9395
cannabis?: string[] | undefined
@@ -147,6 +149,7 @@ const choiceFields = [
147149
{field: 'gender', choices: GENDERS},
148150
{field: 'education_level', choices: EDUCATION_CHOICES},
149151
{field: 'mbti', choices: MBTI_CHOICES},
152+
{field: 'exercise', choices: EXERCISE_CHOICES},
150153
]
151154

152155
// Define array choice fields to search
@@ -290,6 +293,7 @@ export const loadProfiles = async (props: profileQueryType, db?: SupabaseDirectC
290293
causes,
291294
work,
292295
is_smoker,
296+
exercise,
293297
shortBio,
294298
psychedelics,
295299
cannabis,
@@ -629,6 +633,8 @@ export const loadProfiles = async (props: profileQueryType, db?: SupabaseDirectC
629633
{is_smoker},
630634
),
631635

636+
exercise?.length && where(`exercise = ANY($(exercise))`, {exercise}),
637+
632638
psychedelics?.length &&
633639
where(
634640
(psychedelics.includes('never_not_interested') ? 'psychedelics IS NULL OR ' : '') +

backend/api/src/llm-extract-profile.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
CANNABIS_CHOICES,
77
DIET_CHOICES,
88
EDUCATION_CHOICES,
9+
EXERCISE_CHOICES,
910
GENDERS,
1011
LANGUAGE_CHOICES,
1112
MBTI_CHOICES,
@@ -113,6 +114,7 @@ async function validateProfileFields(
113114
'gender',
114115
'education_level',
115116
'mbti',
117+
'exercise',
116118
'psychedelics',
117119
'cannabis',
118120
'headline',
@@ -467,6 +469,7 @@ export async function callLLM(
467469
relationship_status: Object.values(RELATIONSHIP_STATUS_CHOICES),
468470
cannabis: Object.values(CANNABIS_CHOICES),
469471
education_level: Object.values(EDUCATION_CHOICES),
472+
exercise: Object.values(EXERCISE_CHOICES),
470473
gender: Object.values(GENDERS),
471474
mbti: Object.values(MBTI_CHOICES),
472475
psychedelics: Object.values(PSYCHEDELICS_CHOICES),
@@ -511,6 +514,7 @@ export async function callLLM(
511514
'Number 0–4. How strongly they want kids (0 = definitely not, 4 = definitely yes).',
512515
diet: `Array. Any of: ${validChoices.diet?.join(', ')}`,
513516
ethnicity: `Array. Any of: ${validChoices.ethnicity?.join(', ')}`,
517+
exercise: `String. One of: ${validChoices.exercise?.join(', ')}. How often they exercise, only if explicitly stated.`,
514518

515519
// Substances
516520
psychedelics: `String. One of: ${validChoices.psychedelics?.join(', ')}. Usage frequency of psychedelics/plant medicine, only if explicitly stated.`,

backend/supabase/CLAUDE.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,18 @@ Apply them with `./scripts/migrate.sh backend/supabase/migrations/<file>.sql` (s
77
[`../../supabase/CLAUDE.md`](../../supabase/CLAUDE.md)). The `supabase/migrations/` folder at the repo root
88
is generated/derived and gitignored — don't add migrations there.
99

10+
**Every new migration must also be appended to [`migration.sql`](migration.sql)** as
11+
`\i backend/supabase/migrations/<file>.sql`, just before the closing `COMMIT;`. That file is the ordered
12+
list used to rebuild the schema from scratch — a migration missing from it silently never runs on a fresh
13+
database. Creating the migration file is not done until the line is added.
14+
1015
## Layout
1116

1217
```
1318
backend/supabase/
1419
├── makefile Regen type / schema targets
1520
├── migrations/ Active migrations — YYYYMMDD_<name>.sql, applied in filename order (source of truth)
16-
├── migration.sql One-off SQL helpers
21+
├── migration.sql Ordered \i list of every table file + migration — rebuilds the schema from scratch
1722
├── users.sql, profiles.sql, ... Reference shapes — one file per table
1823
├── functions.sql, functions_others.sql Postgres functions
1924
├── extensions.sql Postgres extensions
@@ -35,8 +40,9 @@ These targets are also exposed as `yarn --cwd=backend/api regen-types-dev` / `re
3540
## Conventions
3641

3742
- SQL is lowercase by convention across the codebase.
38-
- Adding a new table: create a new migration in [`migrations/`](migrations/), apply it (see
39-
`../../supabase/CLAUDE.md`), then run `make regen-types-dev` so the types in `common/` pick it up.
43+
- Adding a new table or column: create a new migration in [`migrations/`](migrations/), add its `\i` line to
44+
[`migration.sql`](migration.sql), apply it (see `../../supabase/CLAUDE.md`), then run `make regen-types-dev`
45+
so the types in `common/` pick it up.
4046
- Don't hand-edit `common/src/supabase/schema.ts` — it gets overwritten by `regen-types`.
4147

4248
## Related docs

backend/supabase/migration.sql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ BEGIN;
5656
\i backend/supabase/email_unsubscribe_tokens.sql
5757
\i backend/supabase/migrations/20260524_add_orientation_to_profiles.sql
5858
\i backend/supabase/migrations/20260709_add_last_checked_at_to_bookmarked_searches.sql
59-
\i backend/supabase/migrations/20260724_add_neurotype_to_profiles.sql
6059
\i backend/supabase/migrations/20260724_add_accessibility_notes_to_profiles.sql
60+
\i backend/supabase/migrations/20260724_add_neurotype_to_profiles.sql
6161
\i backend/supabase/migrations/20260728_add_ban_reason_to_users.sql
62+
\i backend/supabase/migrations/20260730_cap_profiles_users_reads.sql
63+
\i backend/supabase/migrations/20260731_add_exercise_to_profiles.sql
64+
\i backend/supabase/migrations/20260731_lock_activity_stars_compat.sql
6265
COMMIT;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- Add exercise frequency to profiles
2+
-- Created: 2026-07-31
3+
--
4+
-- Scalar single-select (see EXERCISE_CHOICES in common/src/choices.ts): 'rarely' | 'sometimes' | 'often'.
5+
-- NULL means "not answered" — there is deliberately no "prefer not to say" choice.
6+
7+
ALTER TABLE profiles
8+
ADD COLUMN IF NOT EXISTS exercise TEXT;
9+
10+
CREATE INDEX IF NOT EXISTS profiles_exercise_idx ON profiles (exercise);

common/messages/de.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@
405405
"filter.age.years": "Jahre",
406406
"filter.any": "Alle",
407407
"filter.any_cannabis": "Cannabis",
408+
"filter.any_exercise": "Sport",
408409
"filter.any_causes": "Moralische Anliegen",
409410
"filter.any_diet": "Ernährung",
410411
"filter.any_drinks": "Getränke",
@@ -448,6 +449,7 @@
448449
"filter.label.cannabis": "Cannabis",
449450
"filter.label.cannabis_intention": "Cannabis (Absicht)",
450451
"filter.label.diet": "Ernährung",
452+
"filter.label.exercise": "Sport",
451453
"filter.label.drinks": "Getränke",
452454
"filter.label.education_levels": "Bildung",
453455
"filter.label.has_kids": "Kinder",
@@ -886,6 +888,10 @@
886888
"profile.connection.default": "Verbindung",
887889
"profile.connection_goals": "Verbindungsziele",
888890
"profile.diet": "Ernährung",
891+
"profile.exercise": "Sport",
892+
"profile.exercise.rarely": "Einmal pro Woche oder weniger",
893+
"profile.exercise.sometimes": "2–4 Mal pro Woche",
894+
"profile.exercise.often": "5+ Mal pro Woche",
889895
"profile.diet.keto": "Ketogen",
890896
"profile.diet.omnivore": "Omnivor",
891897
"profile.diet.other": "Andere",
@@ -1160,6 +1166,7 @@
11601166
"profile.optional.category.family": "Familie",
11611167
"profile.optional.category.interested_in": "Wen ich suche",
11621168
"profile.optional.category.morality": "Moral",
1169+
"profile.optional.category.lifestyle": "Lebensstil",
11631170
"profile.optional.category.personal_info": "Persönliche Informationen",
11641171
"profile.optional.category.photos": "Fotos",
11651172
"profile.optional.category.psychology": "Psychologie",
@@ -1172,6 +1179,7 @@
11721179
"profile.optional.connection_type": "Beziehungsart",
11731180
"profile.optional.details": "Details",
11741181
"profile.optional.diet": "Ernährungsweise",
1182+
"profile.optional.exercise": "Sport",
11751183
"profile.optional.drinks_per_month": "Alkoholische Getränke pro Monat",
11761184
"profile.optional.education_level": "Höchster Bildungsabschluss",
11771185
"profile.optional.error.invalid_fields": "Einige Felder sind nicht korrekt...",

common/messages/fr.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@
405405
"filter.age.years": "ans",
406406
"filter.any": "Tous",
407407
"filter.any_cannabis": "Cannabis",
408+
"filter.any_exercise": "Activité physique",
408409
"filter.any_causes": "Causes morales",
409410
"filter.any_diet": "Régime alimentaire",
410411
"filter.any_drinks": "Boissons",
@@ -448,6 +449,7 @@
448449
"filter.label.cannabis": "Cannabis",
449450
"filter.label.cannabis_intention": "Cannabis (intentions)",
450451
"filter.label.diet": "Régime",
452+
"filter.label.exercise": "Activité physique",
451453
"filter.label.drinks": "Boissons",
452454
"filter.label.education_levels": "Éducation",
453455
"filter.label.has_kids": "Enfants",
@@ -885,6 +887,10 @@
885887
"profile.connection.default": "une relation",
886888
"profile.connection_goals": "Objectifs de relation",
887889
"profile.diet": "Régime alimentaire",
890+
"profile.exercise": "Activité physique",
891+
"profile.exercise.rarely": "Une fois par semaine ou moins",
892+
"profile.exercise.sometimes": "2 à 4 fois par semaine",
893+
"profile.exercise.often": "5 fois ou plus par semaine",
888894
"profile.diet.keto": "Cétogène",
889895
"profile.diet.omnivore": "Omnivore",
890896
"profile.diet.other": "Autre",
@@ -1159,6 +1165,7 @@
11591165
"profile.optional.category.family": "Famille",
11601166
"profile.optional.category.interested_in": "Ce que je recherche",
11611167
"profile.optional.category.morality": "Moralité",
1168+
"profile.optional.category.lifestyle": "Mode de vie",
11621169
"profile.optional.category.personal_info": "Infos personnelles",
11631170
"profile.optional.category.photos": "Photos",
11641171
"profile.optional.category.psychology": "Psychologie",
@@ -1171,6 +1178,7 @@
11711178
"profile.optional.connection_type": "Type de relation",
11721179
"profile.optional.details": "Détails",
11731180
"profile.optional.diet": "Régime alimentaire",
1181+
"profile.optional.exercise": "Activité physique",
11741182
"profile.optional.drinks_per_month": "Boissons alcoolisées consommées par mois",
11751183
"profile.optional.education_level": "Niveau d'études le plus élevé",
11761184
"profile.optional.error.invalid_fields": "Certains champs sont incorrects...",

common/src/api/schema.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,7 @@ export const API = (_apiTypeCheck = {
788788
wants_kids_strength: z.coerce.number().optional(),
789789
has_kids: z.coerce.number().optional(),
790790
is_smoker: zBoolean.optional().optional(),
791+
exercise: arraybeSchema.optional(),
791792
psychedelics: arraybeSchema.optional(),
792793
cannabis: arraybeSchema.optional(),
793794
psychedelics_intention: arraybeSchema.optional(),

0 commit comments

Comments
 (0)