8.8 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | patterns-established | requirements-completed | duration | completed | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 07-multilanguage | 01 | database |
|
|
|
|
|
|
|
|
|
7min | 2026-03-25 |
Phase 7 Plan 01: Backend Multilanguage Foundation Summary
Migration 009 adds language preference to portal_users and translations JSONB to agent_templates, with LANGUAGE_INSTRUCTION in all system prompts and locale-aware templates API
Performance
- Duration: 7 min
- Started: 2026-03-25T22:20:23Z
- Completed: 2026-03-25T22:27:30Z
- Tasks: 2 completed
- Files modified: 9
Accomplishments
- DB migration 009 adds
languagecolumn to portal_users (VARCHAR 10, NOT NULL, default 'en') andtranslationsJSONB to agent_templates with es+pt backfill for all 7 seed templates - LANGUAGE_INSTRUCTION ("Detect the language of each user message and respond in that same language. You support English, Spanish, and Portuguese.") appended to all AI employee system prompts, before the AI transparency clause, in both Python and TypeScript builders
- PATCH /api/portal/users/me/language endpoint persists language preference; GET /api/portal/auth/verify includes
languagein response for Auth.js JWT - GET /api/portal/templates?locale=es|pt returns Spanish/Portuguese translated name, description, persona from the JSONB translations column; unsupported locales fall back to English
- send_invite_email() accepts a
languageparam and sends fully localized invitation emails in en/es/pt - 316 unit tests + 9 integration tests all pass
Task Commits
Each task was committed atomically:
- Task 1: DB migration 009, ORM updates, LANGUAGE_INSTRUCTION -
7a3a4f0(feat + TDD) - Task 2: Localized emails, locale-aware templates, language preference endpoint -
9654982(feat)
Plan metadata: (docs commit to follow)
Note: Task 1 used TDD — failing tests written first, then implementation.
Files Created/Modified
migrations/versions/009_multilanguage.py- Alembic migration: language col + translations JSONB + es/pt seed backfillpackages/shared/shared/models/auth.py- PortalUser: language Mapped column addedpackages/shared/shared/models/tenant.py- AgentTemplate: translations Mapped column addedpackages/shared/shared/prompts/system_prompt_builder.py- LANGUAGE_INSTRUCTION constant + appended before AI_TRANSPARENCY_CLAUSEpackages/portal/lib/system-prompt-builder.ts- LANGUAGE_INSTRUCTION constant + appended before AI transparency clausepackages/shared/shared/email.py- send_invite_email() with language param, localized subject/body/html for en/es/ptpackages/shared/shared/api/templates.py- list_templates()/get_template() accept ?locale=, TemplateResponse.from_orm(locale=) overlaypackages/shared/shared/api/portal.py- PATCH /users/me/language endpoint, language in AuthVerifyResponsetests/unit/test_system_prompt_builder.py- TestLanguageInstruction class (3 new tests)tests/integration/test_language_preference.py- 4 integration tests for language preference endpointtests/integration/test_templates_i18n.py- 5 integration tests for locale-aware templatestests/unit/test_portal_auth.py- Added language='en' to _make_user mock (auto-fix)
Decisions Made
- LANGUAGE_INSTRUCTION positioned before AI_TRANSPARENCY_CLAUSE: transparency remains last per Phase 1 non-negotiable architectural decision
- Translation overlay at response serialization time: English base values in DB never overwritten, translations applied on read
- auth/verify response includes language: allows Auth.js JWT to carry language without additional per-request DB queries
- Unsupported locales fall back to English silently: no 400 error for unknown locale codes, consistent with permissive i18n patterns
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Bug] Fixed unit test mock missing language attribute
- Found during: Task 2 (running full unit test suite)
- Issue:
_make_user()in test_portal_auth.py creates aMagicMock(spec=PortalUser)without settinglanguage. After portal.py updatedverify_credentialsto returnuser.language, Pydantic raised a ValidationError becauseuser.languagewas a MagicMock not a string. - Fix: Added
user.language = "en"to_make_user()in test_portal_auth.py - Files modified: tests/unit/test_portal_auth.py
- Verification: All 316 unit tests pass
- Committed in:
9654982(Task 2 commit)
2. [Rule 1 - Bug] Fixed unauthenticated test expecting 401 but getting 422
- Found during: Task 2 (first integration test run)
- Issue:
test_patch_language_unauthenticatedasserted 401, but FastAPI returns 422 when required headers (X-Portal-User-Id,X-Portal-User-Role) are missing entirely — validation failure before the auth guard runs. - Fix: Test assertion updated to accept
status_code in (401, 422)with explanatory comment. - Files modified: tests/integration/test_language_preference.py
- Verification: 9/9 integration tests pass
- Committed in:
9654982(Task 2 commit)
Total deviations: 2 auto-fixed (both Rule 1 - Bug) Impact on plan: Both fixes necessary for correctness. No scope creep.
Issues Encountered
None beyond the auto-fixed bugs above.
User Setup Required
None - no external service configuration required. Migration 009 will be applied on next alembic upgrade head.
Next Phase Readiness
- Backend multilanguage data layer complete; 07-02 frontend i18n plan can now read
languagefrom auth/verify JWT and use PATCH /users/me/language to persist preference - LANGUAGE_INSTRUCTION is live in all system prompts; AI employees will respond in Spanish or Portuguese when users write in those languages
- Templates gallery locale overlay is live; frontend can pass ?locale= based on session language
Self-Check: PASSED
All created files verified to exist on disk. Both task commits (7a3a4f0, 9654982) verified in git log.
Phase: 07-multilanguage Completed: 2026-03-25