Skip to content

Commit 4411d7f

Browse files
committed
create Language.usesAIAssistance field
1 parent 3e38da2 commit 4411d7f

File tree

6 files changed

+67
-0
lines changed

6 files changed

+67
-0
lines changed

dbschema/language.gel

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ module default {
5757
constraint regexp(r'^[0-9]{5}$');
5858
}
5959

60+
property usesAIAssistance := exists (
61+
select .engagements
62+
filter .usingAIAssistedTranslation not in {
63+
Engagement::AIAssistedTranslation.None,
64+
Engagement::AIAssistedTranslation.Unknown
65+
}
66+
);
67+
6068
property population := .populationOverride ?? .ethnologue.population;
6169
populationOverride: population;
6270

dbschema/migrations/00020-m1cpuxn.edgeql

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/language/dto/language.dto.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,17 @@ export class Language extends Interfaces {
184184
})
185185
readonly presetInventory: SecuredBoolean;
186186

187+
@Calculated()
188+
@Field({
189+
description: stripIndent`
190+
Whether any engagement for this language is using AI-assisted translation.
191+
192+
This is true if any engagement's "usingAIAssistedTranslation" property is not "None" or "Unknown".
193+
Used to track and filter languages that have AI assistance in their translation process.
194+
`,
195+
})
196+
readonly usesAIAssistance: SecuredBoolean;
197+
187198
// Not returned, only used to cache the sensitivity for determining permissions
188199
readonly effectiveSensitivity: Sensitivity;
189200
}

src/components/language/dto/list-language.dto.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ export abstract class LanguageFilters {
4747
})
4848
readonly presetInventory?: boolean;
4949

50+
@OptionalField({
51+
description:
52+
'Only languages that have an AI-assisted translation engagement',
53+
})
54+
readonly usesAIAssistance?: boolean;
55+
5056
@OptionalField({
5157
description:
5258
'Only languages that are pinned/unpinned by the requesting user',

src/components/language/language.gel.repository.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export class LanguageGelRepository
1515
sensitivity: lang.ownSensitivity,
1616
effectiveSensitivity: lang.sensitivity,
1717
presetInventory: e.bool(false), // Not implemented going forward
18+
usesAIAssistance: lang.usesAIAssistance,
1819
}),
1920
omit: ['create'],
2021
})

src/components/language/language.repository.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ export class LanguageRepository extends DtoRepository<
209209
])
210210
.apply(matchProps({ nodeName: 'eth', outputVar: 'ethProps' }))
211211
.apply(isPresetInventory)
212+
.apply(usingAIAssistance)
212213
.optionalMatch([
213214
node('node'),
214215
relation('in', '', 'language', ACTIVE),
@@ -222,6 +223,7 @@ export class LanguageRepository extends DtoRepository<
222223
ethnologue: 'ethProps',
223224
pinned,
224225
presetInventory: 'presetInventory',
226+
usesAIAssistance: 'usesAIAssistance',
225227
firstScriptureEngagement: 'firstScriptureEngagement { .id }',
226228
scope: 'scopedRoles',
227229
changeset: 'changeset.id',
@@ -339,6 +341,10 @@ export const languageFilters = filter.define(() => LanguageFilters, {
339341
const condition = equals('true', true);
340342
return { presetInventory: value ? condition : not(condition) };
341343
},
344+
usesAIAssistance: ({ value, query }) => {
345+
query.apply(usingAIAssistance).with(['node', 'usesAIAssistance']);
346+
return { usesAIAssistance: value };
347+
},
342348
});
343349

344350
const ethnologueFilters = filter.define(() => EthnologueLanguageFilters, {
@@ -374,6 +380,25 @@ const isPresetInventory = (query: Query) =>
374380
),
375381
);
376382

383+
const usingAIAssistance = (query: Query) =>
384+
query.subQuery('node', (sub) =>
385+
sub
386+
.optionalMatch([
387+
node('node'),
388+
relation('in', '', 'language', ACTIVE),
389+
node('eng', 'LanguageEngagement'),
390+
])
391+
.optionalMatch([
392+
node('eng'),
393+
relation('out', '', 'usingAIAssistedTranslation', ACTIVE),
394+
node('prop', 'Property'),
395+
])
396+
.with([
397+
`any(val in collect(prop.value) WHERE val IS NOT NULL AND val <> 'None' AND val <> 'Unknown') as usesAIAssistance`,
398+
])
399+
.return(['usesAIAssistance']),
400+
);
401+
377402
export const languageSorters = defineSorters(Language, {
378403
// eslint-disable-next-line @typescript-eslint/naming-convention
379404
'ethnologue.*': (query, input) =>
@@ -405,6 +430,11 @@ export const languageSorters = defineSorters(Language, {
405430
.return<{ sortValue: unknown }>(
406431
coalesce('override.value', 'canonical.value').as('sortValue'),
407432
),
433+
usesAIAssistance: (query) =>
434+
query
435+
.apply(usingAIAssistance)
436+
.with(['node', 'usesAIAssistance as sortValue'])
437+
.return<{ sortValue: unknown }>('sortValue'),
408438
});
409439

410440
const ethnologueSorters = defineSorters(EthnologueLanguage, {});

0 commit comments

Comments
 (0)