Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
66ca1bc
change: demogrpahic data schema change.
CDevmina Apr 26, 2025
50db45f
feat: Refactor User demographic data handling to use a new Demographi…
CDevmina Apr 26, 2025
351171c
feat: Enhance UserRegistrationForm and UserPreferencesPage with count…
CDevmina Apr 26, 2025
0800c2b
feat: Update demographic inference functions to accept userData docum…
CDevmina Apr 26, 2025
857817d
feat: Enhance demographic data handling with user-provided fields and…
CDevmina Apr 26, 2025
a72f71a
feat: Implement hybrid demographic inference with enhanced keyword an…
CDevmina Apr 26, 2025
6d89ade
Refactor code structure for improved readability and maintainability
CDevmina Apr 26, 2025
6930423
fix: Align demographic cards to the top in UserPreferencesPage
CDevmina Apr 26, 2025
1c26568
Revert "fix: Align demographic cards to the top in UserPreferencesPage"
CDevmina Apr 26, 2025
2af5fbb
Revert "Refactor code structure for improved readability and maintain…
CDevmina Apr 26, 2025
0b6e0a4
feat: Enhance demographic data handling by adding user-provided field…
CDevmina Apr 26, 2025
e69b9a0
feat: Expand demographic form to include additional fields and improv…
CDevmina Apr 26, 2025
c033855
feat: Add allowInference field to privacy settings and update related…
CDevmina Apr 26, 2025
b23c71b
feat: Update UserPreferencesPage to enhance demographic data handling…
CDevmina Apr 26, 2025
d01ef83
style: Improve layout structure by wrapping cards in a grid and updat…
CDevmina Apr 26, 2025
bac3c5b
feat: Refactor privacy settings in User interface and add UserProfile…
CDevmina Apr 26, 2025
19a81cd
feat: Integrate allowInference field into privacy settings and update…
CDevmina Apr 26, 2025
189af4e
Revert "feat: Add UserProfilePage route for user profile management"
CDevmina Apr 26, 2025
b177bc9
feat: Add allowInference field to privacy settings and update related…
CDevmina Apr 26, 2025
31c258a
feat: Add allowInference field to data sharing consent schema in Open…
CDevmina Apr 27, 2025
e5c73dc
feat: Enhance UserRegistrationForm with inference popover and update …
CDevmina Apr 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
248 changes: 179 additions & 69 deletions api-service/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -897,46 +897,10 @@ components:
phone:
type: string
pattern: ^\+?[\d\s-]+$
gender:
type: string
nullable: true
description: User gender identity (e.g., 'male', 'female', 'non-binary', 'prefer_not_to_say')
example: "female"
incomeBracket:
type: string
nullable: true
description: User income bracket category (e.g., '<25k', '25k-50k', '50k-100k', '100k-200k', '>200k', 'prefer_not_to_say')
example: "50k-100k"
country:
type: string
nullable: true
description: User country of residence (ISO 3166-1 alpha-2 code)
example: "US"
age:
type: integer
format: int32
nullable: true
description: User age
example: 35
privacySettings:
type: object
properties:
dataSharingConsent:
type: boolean
default: false
anonymizeData:
type: boolean
default: false
optInStores:
type: array
items:
type: string
description: List of store IDs user has opted into
optOutStores:
type: array
items:
type: string
description: List of store IDs user has opted out from
$ref: "#/components/schemas/PrivacySettings"
demographicData:
$ref: "#/components/schemas/DemographicData"
createdAt:
type: string
format: date-time
Expand All @@ -946,6 +910,19 @@ components:
format: date-time
readOnly: true

PrivacySettings:
type: object
properties:
dataSharingConsent:
type: boolean
description: User consent to share aggregated/anonymized data.
allowInference:
type: boolean
description: Allow Tapiro to infer demographic data based on user activity.
default: true
required:
- dataSharingConsent

Store:
type: object
required:
Expand Down Expand Up @@ -1006,6 +983,9 @@ components:
dataSharingConsent:
type: boolean
description: User's consent for data sharing
allowInference:
type: boolean
description: Allow Tapiro to infer demographic data (defaults to true if omitted).
gender:
type: string
nullable: true
Expand Down Expand Up @@ -1057,45 +1037,75 @@ components:
phone:
type: string
description: User's phone number (E.164 format recommended)
pattern: '^\+?[\d\s-]+$'
preferences:
type: array
description: User interest preferences with taxonomy categorization
items:
$ref: "#/components/schemas/PreferenceItem"
privacySettings:
$ref: "#/components/schemas/PrivacySettings"
demographicData:
type: object
description: Updatable user-provided demographic information. Setting a value here implies verification and may clear inferred values.
properties:
dataSharingConsent:
type: boolean
anonymizeData:
gender:
type: string
nullable: true
description: "User-provided gender identity"
enum: [male, female, non-binary, prefer_not_to_say, null]
incomeBracket:
type: string
nullable: true
description: "User-provided income bracket category"
enum:
[
"<25k",
"25k-50k",
"50k-100k",
"100k-200k",
">200k",
"prefer_not_to_say",
null,
]
country:
type: string
nullable: true
description: "User-provided country of residence (e.g., ISO 3166-1 alpha-2 code)"
age:
type: integer
format: int32
nullable: true
description: "User-provided age. Setting this clears the inferred age bracket."
minimum: 0
hasKids:
type: boolean
optInStores:
type: array
items:
type: string
description: List of store IDs the user has opted into sharing data with
optOutStores:
type: array
items:
type: string
description: List of store IDs the user has opted out of sharing data with
gender:
type: string
nullable: true
description: User gender identity
incomeBracket:
type: string
nullable: true
description: User income bracket category
country:
type: string
nullable: true
description: User country of residence (ISO 3166-1 alpha-2 code)
age:
type: integer
format: int32
nullable: true
description: User age
nullable: true
description: "User-provided: Does the user have children?"
relationshipStatus:
type: string
nullable: true
description: "User-provided: User relationship status"
enum: [single, relationship, married, prefer_not_to_say, null]
employmentStatus:
type: string
nullable: true
description: "User-provided: User employment status"
enum: [employed, unemployed, student, prefer_not_to_say, null]
educationLevel:
type: string
nullable: true
description: "User-provided: User education level"
enum:
[
high_school,
bachelors,
masters,
doctorate,
prefer_not_to_say,
null,
]
# REMOVED verification flags from update payload

ApiKey:
type: object
Expand Down Expand Up @@ -1571,6 +1581,106 @@ components:
version:
type: string

DemographicData:
type: object
description: User-provided and inferred demographic information
properties:
# --- User-Provided ---
gender:
type: string
nullable: true
description: "User-provided gender identity"
enum: [male, female, non-binary, prefer_not_to_say, null]
example: "female"
incomeBracket:
type: string
nullable: true
description: "User-provided income bracket category"
enum:
[
"<25k",
"25k-50k",
"50k-100k",
"100k-200k",
">200k",
"prefer_not_to_say",
null,
]
example: "50k-100k"
country:
type: string
nullable: true
description: "User-provided country of residence (e.g., ISO 3166-1 alpha-2 code)"
example: "US"
age:
type: integer
format: int32
nullable: true
description: "User-provided age"
example: 35
minimum: 0
hasKids: # NEW User-provided
type: boolean
nullable: true
description: "User-provided: Does the user have children?"
example: true
relationshipStatus: # NEW User-provided
type: string
nullable: true
description: "User-provided: User relationship status"
enum: [single, relationship, married, prefer_not_to_say, null]
example: "married"
employmentStatus: # NEW User-provided
type: string
nullable: true
description: "User-provided: User employment status"
enum: [employed, unemployed, student, prefer_not_to_say, null]
example: "employed"
educationLevel: # NEW User-provided
type: string
nullable: true
description: "User-provided: User education level"
enum:
[
high_school,
bachelors,
masters,
doctorate,
prefer_not_to_say,
null,
]
example: "bachelors"
# --- Inferred (Read-Only in responses, not updatable directly) ---
inferredHasKids:
type: boolean
nullable: true
readOnly: true
description: "Inferred: Does the user likely have children? (null if unknown or user provided)"
inferredRelationshipStatus:
type: string
nullable: true
readOnly: true
description: "Inferred: User relationship status (null if unknown or user provided)"
enum: [single, relationship, married, null]
inferredEmploymentStatus:
type: string
nullable: true
readOnly: true
description: "Inferred: User employment status (null if unknown or user provided)"
enum: [employed, unemployed, student, null]
inferredEducationLevel:
type: string
nullable: true
readOnly: true
description: "Inferred: User education level (null if unknown or user provided)"
enum: [high_school, bachelors, masters, doctorate, null]
inferredGender:
type: string
nullable: true
readOnly: true
description: "Inferred: User gender identity (null if unknown or user provided)"
enum: [male, female, non-binary, null]

RecentUserDataEntry:
type: object
properties:
Expand Down
32 changes: 27 additions & 5 deletions api-service/service/AuthenticationService.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ const { CACHE_TTL, CACHE_KEYS } = require('../utils/cacheConfig');
exports.registerUser = async function (req, body) {
try {
const db = getDB();
// Destructure new demographic fields
// Destructure new demographic fields AND allowInference
const {
preferences,
dataSharingConsent,
allowInference, // <-- Add allowInference
gender,
incomeBracket,
country,
Expand Down Expand Up @@ -100,14 +101,35 @@ exports.registerUser = async function (req, body) {
username: userData.username || userData.nickname || userData.sub,
email: userData.email,
phone: userData.phone_number || null,
gender: gender || null, // Add new fields, defaulting to null if not provided
incomeBracket: incomeBracket || null,
country: country || null,
age: age || null,
demographicData: {
// User provided (initialize as null unless provided in registration body)
gender: gender || null,
incomeBracket: incomeBracket || null,
country: country || null,
age: age || null,
hasKids: null, // NEW user-provided, init null
relationshipStatus: null, // NEW user-provided, init null
employmentStatus: null, // NEW user-provided, init null
educationLevel: null, // NEW user-provided, init null
// Inferred (initialize as null)
inferredHasKids: null,
// REMOVED hasKidsIsVerified
inferredRelationshipStatus: null,
// REMOVED relationshipStatusIsVerified
inferredEmploymentStatus: null,
// REMOVED employmentStatusIsVerified
inferredEducationLevel: null,
// REMOVED educationLevelIsVerified
// REMOVED inferredAgeBracket
// REMOVED ageBracketIsVerified
inferredGender: null,
// REMOVED genderIsVerified
},
preferences: preferences || [],
privacySettings: {
dataSharingConsent,
anonymizeData: false,
allowInference: allowInference !== undefined ? allowInference : true, // <-- Set allowInference, default true
optInStores: [],
optOutStores: [],
},
Expand Down
Loading
Loading