-
-
Notifications
You must be signed in to change notification settings - Fork 260
Improve bit resx translator (#11801) #11802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThe ResxTranslator now processes translations in parallel batches of 100 items using configurable parallelism options. The translation flow replaces tool-based routing with JSON-based batch requests to a ChatClient, returning structured translation responses. Additionally, localization strings across email, app, and identity resources are updated in 8+ languages for consistency and clarity. Changes
Sequence DiagramsequenceDiagram
actor Translator
participant Batch as Batch Processor
participant ChatClient
participant Response as TranslationBatchResponse
rect rgb(220, 240, 250)
Note over Translator,Response: Parallel Batch Translation Flow
Translator->>Batch: Iterate notTranslatedKeyValues in batches (100 items)
activate Batch
Batch->>Batch: Construct JSON payload<br/>from batch keys
Batch->>ChatClient: GetResponseAsync(batch JSON,<br/>ChatOptions with JSON schema)
deactivate Batch
activate ChatClient
ChatClient->>Response: Parse response
deactivate ChatClient
activate Response
Response->>Response: Deserialize Translations[]
deactivate Response
Response->>Batch: Return TranslationBatchResponse
activate Batch
Batch->>Batch: Map translations to batch keys<br/>(index bounds check)
Batch->>Batch: Log input/output token usage
Batch->>Translator: Update batch translations
deactivate Batch
end
rect rgb(240, 255, 240)
Note over Translator: Repeat for next batch
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20–25 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (11)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.es.resx (5)
121-126: Confirmation email subject & subtitle read well; minor optional tone tweak
- Subject and subtitle are grammatically correct and preserve the
{0}placeholder safely.- If
{0}is the email address, consider optionally clarifying: e.g.,has registrado {0} como dirección de correo electrónico en tu cuenta de Boilerplatefor slightly more explicit wording.
151-152: Consider localizing “OTP” term for non‑technical users
- Technically correct, but
OTPalone may be unclear for some Spanish‑speaking users.- Optional: use something like
Código de un solo uso (OTP)orCódigo OTPto give a clearer cue in the subject.
175-183: 2FA token wording OK; consider less technical phrasing (optional)
- Subject and message are understandable and keep the security meaning.
- Optional UX improvement: replace
token 2FAwith something likecódigo de verificación en dos pasosorcódigo 2FAto be more user‑facing, especially outside technical audiences.
184-192: Elevated access token text is correct; small style refinement possible
- “Token de acceso elevado” and the body line are grammatically correct and accurate.
- Optional: you could consider
token de acceso con privilegios elevadosortoken de acceso avanzadoif you want to be a bit more explicit, but current wording is acceptable.
196-198: DefaultFromName string is acceptable; check branding consistency
App Boilerplateis understandable, but you may want to align with how the product name appears elsewhere (e.g.,Boilerplate AppvsAplicación Boilerplate).- If other locales use a specific pattern, mirror that here for consistency.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.sv.resx (2)
148-150: Tighten link phrasing for more natural Swedish
"Eller du kan klicka på länken nedan …"is understandable but slightly clunky;"Eller klicka på länken nedan …"matches the style used in the confirmation email and reads more idiomatically.Example tweak:
- <value>Eller du kan klicka på länken nedan för att försöka återställa ditt lösenord.</value> + <value>Eller klicka på länken nedan för att återställa ditt lösenord.</value> - <value>Eller du kan klicka på länken nedan för att logga in.</value> + <value>Eller klicka på länken nedan för att logga in.</value>Also applies to: 166-168
151-165: Consider less technical wording than “OTP”/“token” for end usersFor Swedish end users, terms like
OTP,2FA-tokenandåtkomsttokenare fairly technical. If you want a more user-friendly tone, consider alternatives such as:
engångskod/engångslösenordinstead ofOTPsäkerhetskodorinloggningskodinstead of2FA-tokenkod för förhöjd åtkomstinstead offörhöjd åtkomsttokenNot a blocker, but harmonizing with
"Kopiera denna kod och använd den i appen."could make the UX clearer.Also applies to: 175-183, 190-195
src/Templates/Boilerplate/Bit.Boilerplate/Bit.ResxTranslator.json (1)
39-43: ParallelOptions JSON matches the new settings propertyThe new top‑level
"ParallelOptions"object with"MaxDegreeOfParallelism": 4aligns with theParallelOptionsproperty added toResxTranslatorSettings. This should bind cleanly and let you tune translation parallelism via config.Consider documenting acceptable values (e.g.,
-1for “unbounded”, positive integers only) in the README so misconfiguration doesn’t cause runtime issues.src/ResxTranslator/Bit.ResxTranslator/Services/Translator.cs (3)
72-87: Potential null handling and index mismatch concern.The code checks
response.Result?.Translations != nullbut doesn't handle the case where the AI returns fewer translations than expected. Ifresponse.Result.Translations.Length < batch.Count, some entries would be silently skipped without logging.Consider adding a warning log when translation counts don't match:
if (response.Result?.Translations != null) { + if (response.Result.Translations.Length != batch.Count) + { + logger.LogWarning("Expected {Expected} translations but received {Received} for batch {BatchIndex}.", + batch.Count, response.Result.Translations.Length, batchIndex + 1); + } foreach ((string translate, int index) in response.Result.Translations.Select((translate, index) => (translate, index)))
200-204: Consider addinginitaccessor and usingIReadOnlyList<string>for immutability.The
Translationsproperty uses a mutable array withset. For a response DTO, consider usinginitand an immutable collection type:public record TranslationBatchResponse { - public required string[] Translations { get; set; } + public required string[] Translations { get; init; } }
41-46: Batch creation can be simplified usingChunk..NET 6+ provides
Chunk()for cleaner batch creation:-const int batchSize = 100; -var batches = notTranslatedKeyValues - .Select((kvp, index) => new { kvp, index }) - .GroupBy(x => x.index / batchSize) - .Select(g => g.Select(x => x.kvp).ToDictionary(kvp => kvp.Key, kvp => kvp.Value)) - .ToList(); +const int batchSize = 100; +var batches = notTranslatedKeyValues + .Chunk(batchSize) + .Select(chunk => chunk.ToDictionary(kvp => kvp.Key, kvp => kvp.Value)) + .ToList();
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
📒 Files selected for processing (27)
src/ResxTranslator/Bit.ResxTranslator/Models/ResxTranslatorSettings.cs(1 hunks)src/ResxTranslator/Bit.ResxTranslator/Services/Translator.cs(4 hunks)src/Templates/Boilerplate/Bit.Boilerplate/Bit.ResxTranslator.json(1 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.ar.resx(4 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.de.resx(8 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.es.resx(5 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.fr.resx(3 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.hi.resx(3 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.nl.resx(3 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.sv.resx(6 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.zh.resx(4 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.ar.resx(22 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.de.resx(32 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.es.resx(44 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.fr.resx(32 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.hi.resx(39 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.nl.resx(44 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.sv.resx(27 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.zh.resx(32 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.ar.resx(3 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.de.resx(2 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.es.resx(2 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.fr.resx(2 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.hi.resx(2 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.nl.resx(2 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.sv.resx(3 hunks)src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.zh.resx(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/ResxTranslator/Bit.ResxTranslator/Services/Translator.cs (1)
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/SignalR/AppChatbot.cs (1)
ChatOptions(152-173)
🪛 GitHub Check: build Bit.ResxTranslator
src/ResxTranslator/Bit.ResxTranslator/Services/Translator.cs
[warning] 59-59:
Using member 'System.Text.Json.JsonSerializer.Serialize(TValue, JsonSerializerOptions)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.
[warning] 59-59:
Using member 'System.Text.Json.JsonSerializer.Serialize(TValue, JsonSerializerOptions)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.
[warning] 57-57:
Using member 'Microsoft.Extensions.Configuration.ConfigurationBinder.Bind(IConfiguration, Object)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. Binding strongly typed objects to configuration values requires generating dynamic code at runtime, for example instantiating generic types.
[warning] 57-57:
Using member 'Microsoft.Extensions.Configuration.ConfigurationBinder.Bind(IConfiguration, Object)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Cannot statically analyze the type of instance so its members may be trimmed.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build Bit.Templates
🔇 Additional comments (26)
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.es.resx (1)
129-132: Spanish email messages read naturally and are consistentThe updated phrases using “correo electrónico” are grammatically correct, clearer than the previous “correo”, and consistent with the rest of the resource file and similar identity messages.
Also applies to: 141-144
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.nl.resx (2)
165-184: LGTM! Consistent terminology improves UX.The update from "ten minste" to "minstens" across all password requirement messages is a good improvement. "Minstens" is more commonly used in modern Dutch and provides consistent terminology across related error messages.
197-200: LGTM! Translation quality improved.The UserLockoutNotEnabled message now uses natural, idiomatic Dutch phrasing. The translation accurately conveys the meaning while maintaining proper Dutch grammar and terminology.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.es.resx (2)
133-144: Reset password strings are clear and user‑friendly
- Subject line is correct and natural (“Restablece tu contraseña”).
- Body text “Si no eres tú…” is idiomatic and slightly more neutral than past‑tense alternatives; no issues.
169-174: App name and welcome line are consistent with branding
Boilerplateand¡Bienvenido a Boilerplate!are straightforward and consistent with the new app identity.- No placeholder issues or grammatical problems.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.sv.resx (2)
121-135: Subjects and placeholders look consistent and correctThe updated subjects read naturally in Swedish, consistently follow the
Boilerplate {0} - …pattern, and preserve the{0}placeholder. No issues from a localization or formatting perspective.Also applies to: 151-153, 175-177, 184-186
169-174: Branding strings are consistent
AppName, welcome text, andDefaultFromNameconsistently use “Boilerplate” / “Boilerplate-appen” and look appropriate for sender display and in-message branding.Also applies to: 196-198
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.zh.resx (1)
128-128: Chinese translation refinements look structurally sound.The updated Chinese translations maintain proper placeholder formatting and XML structure. Since these appear to be generated by the improved batch translation workflow, consider having a native Chinese speaker validate the linguistic accuracy and cultural appropriateness of the refined strings.
Also applies to: 143-143, 149-149, 158-158, 167-167, 173-173
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.nl.resx (1)
143-143: Dutch translation updates are structurally correct.The refined Dutch strings maintain proper XML formatting. As these translations were likely generated through the improved batch translation process, native Dutch speaker validation would ensure optimal linguistic quality.
Also applies to: 161-161, 185-185, 191-191
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.de.resx (1)
122-122: German translation improvements include typographic enhancements.The updates improve German typography (hyphen to en dash) and refine conditional phrasing. These appear to be generated by the enhanced translation workflow. Consider native German speaker validation for linguistic accuracy.
Also applies to: 134-134, 143-143, 152-152, 161-161, 176-176, 185-185, 197-197
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.de.resx (1)
178-178: German identity string refinements are structurally sound.Minor grammatical improvements to identity error messages. As these were generated through the batch translation process, native validation would ensure optimal phrasing.
Also applies to: 186-186, 198-198
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.zh.resx (1)
166-166: Chinese identity strings updated consistently.Password requirement messages have been refined in Chinese. These batch-translated updates maintain structural integrity. Native speaker validation recommended for linguistic accuracy.
Also applies to: 170-170, 178-178, 182-182
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.fr.resx (1)
126-126: French identity strings improved with proper typography.Excellent application of French typographic standards using guillemets (« ») for quotes and refined phrasing throughout. These batch-generated improvements significantly enhance French localization quality. Native speaker validation would confirm linguistic excellence.
Also applies to: 130-130, 134-134, 138-138, 142-142, 146-146, 154-154, 158-158, 166-166, 170-170, 178-178, 194-194, 202-202
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.fr.resx (1)
261-261: Comprehensive French localization improvements.Extensive and systematic refinements to French app strings demonstrating the effectiveness of the batch translation workflow. Updates include typographic standardization, phrasing improvements, and consistency enhancements across the entire resource file. The scope and consistency of these changes reflect successful automated translation processing. Native French speaker review would validate the linguistic quality of these improvements.
Also applies to: 268-268, 279-285, 312-312, 325-325, 361-364, 382-382, 400-409, 424-427, 493-493, 517-517, 670-670, 682-682, 700-700, 730-730, 745-748, 772-775, 787-787, 856-856, 868-868, 883-889, 898-907, 937-940, 1011-1014, 1026-1029, 1059-1059, 1091-1094, 1146-1165, 1170-1182, 1231-1231, 1280-1280, 1311-1311, 1341-1344, 1362-1362
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.sv.resx (1)
122-122: Swedish identity strings refined for consistency.Grammar and terminology improvements throughout Swedish identity messages. These batch-processed translations maintain proper structure and formatting. Native Swedish speaker validation recommended to confirm linguistic quality.
Also applies to: 130-130, 134-134, 138-138, 142-142, 146-146, 154-154, 158-158, 170-170, 174-174, 178-178, 198-198
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.zh.resx (1)
239-241: Batch session limit message looks structurally correctThe multi-line
PrivilegedDeviceLimitMessagepreserves both{0}and{1}placeholders and matches the semantics used in other locales. No structural issues from the translation side here.src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.fr.resx (1)
172-192: French email texts and 2FA/elevated access messages look consistentThe updated welcome, 2FA, and elevated‑access messages are idiomatic French and preserve placeholders
{0}where used. No structural or formatting issues detected.src/ResxTranslator/Bit.ResxTranslator/Models/ResxTranslatorSettings.cs (1)
17-18: ParallelOptions property is wired sensibly; consider validating degree of parallelismAdding
public ParallelOptions ParallelOptions { get; set; } = new() { MaxDegreeOfParallelism = 4 };fits well with the new JSON
"ParallelOptions"section and gives a reasonable default. To guard against misconfig (e.g.,0or invalid negatives), you may want to validateParallelOptions.MaxDegreeOfParallelismon startup and normalize to-1or a minimum of1.src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.ar.resx (1)
161-207: Arabic identity error strings improved without breaking placeholdersThe updated messages for password mismatch, minimum length, existing password, and required unique chars read more naturally in Arabic and still preserve
{0}where required. No functional issues spotted.src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.es.resx (1)
1-1366: Spanish localization updates look appropriate.The translations adopt consistent formal "usted" usage and include grammar/punctuation refinements. Placeholders like
{0},{1}are correctly preserved throughout.src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/IdentityStrings.hi.resx (1)
121-208: Hindi identity string updates look appropriate.The terminology refinements (e.g., standardizing character references and password-related terms) improve consistency across the identity-related messages.
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.hi.resx (1)
1-1367: Hindi app string updates look appropriate.The updates standardize terminology (OTP, 2FA), improve grammar consistency, and maintain proper placeholder formatting throughout.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.ar.resx (1)
121-198: Arabic email string updates look appropriate.The consistent application of the definite article "ال" improves grammatical correctness, and all placeholders are preserved correctly.
src/Templates/Boilerplate/Bit.Boilerplate/src/Shared/Resources/AppStrings.de.resx (1)
1-1367: German app string updates look appropriate.The translations include grammar corrections and phrasing refinements while maintaining proper placeholder formatting.
src/Templates/Boilerplate/Bit.Boilerplate/src/Server/Boilerplate.Server.Api/Resources/EmailStrings.hi.resx (1)
121-198: Hindi email string updates look appropriate.The updates standardize OTP terminology and improve action phrasing consistency while preserving placeholders correctly.
src/ResxTranslator/Bit.ResxTranslator/Services/Translator.cs (1)
52-58: Configuration section mismatch and AOT compatibility concerns require verification.The review flags a potential mismatch between
"ChatOptions"(used at line 57 in Translator.cs) and"AI:ChatOptions"(allegedly used in AppChatbot.cs line 169). This should be verified to confirm whether the sections should be consistent or if this difference is intentional.Additionally, static analysis warnings about AOT/trimming compatibility with
JsonSerializer.Serialize(line 59) andconfiguration.Bind(line 57) should be investigated. If these warnings are present, consider implementing source generation for JSON serialization and reviewing configuration binding patterns to ensure AOT compatibility.
closes #11801
1- Add support to configure parallel options
2- Translate resx entries in batched by each 100 items
3- Improved performance by optimizing AI call
Summary by CodeRabbit
Release Notes
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.