···2525 Description *string `json:"description,omitempty" cborgen:"description,omitempty"`
2626 // duration: Duration of the study session in seconds.
2727 Duration int64 `json:"duration" cborgen:"duration"`
2828- // languageCode: An ISO 639-1 two-letter language code (e.g., 'en', 'es', 'ko').
2828+ // languageCode: An ISO 639-1, 639-2, or 639-3 language code (2–3 characters, e.g., 'en', 'eng', 'asl').
2929 LanguageCode string `json:"languageCode" cborgen:"languageCode"`
3030 // predefinedActivityName: A key used to lookup activity type details.
3131 PredefinedActivityName *string `json:"predefinedActivityName,omitempty" cborgen:"predefinedActivityName,omitempty"`
···117117 var languages []domain.Language
118118 for idx, languageString := range record.Languages {
119119 if idx < domain.MaxLanguages {
120120- language, ok := database.Languages[domain.LanguageCode(languageString)]
120120+ language, ok := database.LookupLanguage(domain.LanguageCode(languageString))
121121 if !ok {
122122 return fmt.Errorf("failed to find language '%s'", languageString)
123123 }
···196196 }
197197198198 languageCode := record.LanguageCode
199199- language, ok := database.Languages[domain.LanguageCode(languageCode)]
199199+ language, ok := database.LookupLanguage(domain.LanguageCode(languageCode))
200200 if !ok {
201201 return fmt.Errorf("failed to find language '%s'", languageCode)
202202 }
···9494 return nil, fmt.Errorf("failed to scan language code: %w", err)
9595 }
96969797- language, ok := Languages[domain.LanguageCode(langCode)]
9797+ language, ok := LookupLanguage(domain.LanguageCode(langCode))
9898 if !ok {
9999- log.Printf("language code '%s' found in db but not in global map", langCode)
9999+ log.Printf("language code '%s' found in db but not recognised", langCode)
100100 continue
101101 }
102102 languages = append(languages, language)
···163163 }
164164165165 for _, l := range profile.Languages {
166166- if len(l.Code) != 2 {
166166+ if len(l.Code) < 2 || len(l.Code) > 3 {
167167 return ErrProfileInvalidLanguageCode
168168 }
169169 }
···224224 return nil, fmt.Errorf("failed to scan profile language: %w", err)
225225 }
226226 if p, ok := profileMap[did]; ok {
227227- if lang, langOK := Languages[domain.LanguageCode(langCode)]; langOK {
227227+ if lang, langOK := LookupLanguage(domain.LanguageCode(langCode)); langOK {
228228 p.Languages = append(p.Languages, lang)
229229 profileMap[did] = p
230230 }
···11package domain
2233-// An ISO 639-1 two-letter language code (e.g., 'en', 'es', 'ko')
33+// An ISO 639-1, 639-2, or 639-3 language code (e.g., 'en', 'eng', 'asl')
44type LanguageCode string
5566type Language struct {
77 Code LanguageCode
88- // The common name, typically in English.
88+ // The common name in English.
99 Name string
1010 // The name in its own language (e.g., "日本語").
1111 NativeName *string
1212- // An emoji.
1313- Flag string
1412}