Dịch headings, section titles, và thuật ngữ chính trong 15 file
markdown (.claude/agents/ và .claude/*.md) sang tiếng Việt có dấu.
Giữ nguyên format markdown, code blocks, tên kỹ thuật và commands.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: Lucide JS replaces <i data-lucide> with <svg>, breaking
Blazor's virtual DOM diffing (insertBefore/removeChild on null).
23 components + 2 MutationObservers were calling lucide.createIcons()
concurrently, amplifying the race condition.
Changes:
- Remove all 23 direct lucide.createIcons() JS interop calls from
layouts and components (AdminLayout, AuthLayout, StaffLayout, etc.)
- Replace dual MutationObserver with single requestIdleCallback poller
that only runs when browser is idle (after Blazor finishes rendering)
- Auto-suppress Blazor error banner for known harmless Lucide DOM
mismatch errors (insertBefore/removeChild on null)
- Change login NavigateTo from forceLoad:true to forceLoad:false
to avoid full WASM runtime reload after successful login
- Simplify launch.json to pos-web only for Claude Code preview
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Configure all 24 services to connect to remote staging PostgreSQL
(212.28.186.239:30992) and MinIO (minio.techbi.org) while running
Redis and RabbitMQ locally on non-standard ports (16379, 25672)
to avoid conflicts with other projects.
- Add .env.remote with hybrid connection strings
- Add docker-compose.dev.yml (lightweight Redis + RabbitMQ only)
- Add scripts/dev/start-dev.sh for one-command infra startup
- Update all appsettings.Development.json with remote DB + timeout
- Add .claude/launch.json for Claude Code preview (pos-web only)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Known Issues & Gotchas section to CLAUDE.md covering role PascalCase
requirement, EF migration enforcement, and browser token cache behavior.
Update Tech Lead review checklist and naming conventions accordingly.
Include local development setup investigation and quick reference docs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
OnboardingBusiness.razor was only navigating to the next step without
calling the merchant registration API, so no merchant record was ever
created in the database. This caused settings page updates to fail with
"Merchant not found" and the SuperAdmin panel to show zero merchants.
- Inject MerchantApiService and call RegisterMerchantAsync on "Tiếp tục"
- Remove hardcoded demo data from onboarding form fields
- Add fallback in AdminSettings SaveMerchant to auto-register if PUT fails
- Add BFF POST /api/bff/account/register-merchant endpoint
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Redis StatefulSet pod uses label app=redis but allow-redis-replication
only listed redis-master/redis-replica/redis-sentinel. Sentinel could
not reach redis-0, causing infinite wait loop and CrashLoopBackOff.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Services in K8s use `Jwt__Authority=http://iam-service:8080` (internal)
but RequireHttpsMetadata was hardcoded to `!IsDevelopment()` which
crashes in Staging with "The MetadataAddress or Authority must use HTTPS".
Fix: Read RequireHttpsMetadata from config + auto-detect HTTP authority.
Affected: merchant-service, ads-billing, ads-serving, ads-tracking.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Critical fixes applied to staging K8s manifests:
1. NetworkPolicy: Add allow-inter-service-ingress (services can receive
requests from each other - fixes promotion→wallet health check timeout)
2. NetworkPolicy: Add allow-app-to-neon-egress (explicit DB access rule)
3. NetworkPolicy: Add ingress-nginx namespace to allow-traefik-ingress
4. Resources: Reduce CPU requests 250m→100m (cluster was at 99%)
5. IAM Service: Add signing certificate volume mount (required for
IdentityServer in non-Development environments)
Without #1, any service calling another service via HTTP would timeout
because default-deny-all blocks all ingress and only egress was allowed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Kaniko git:// context doesn't support HTTPS auth well.
Use alpine/git initContainer to clone repo into emptyDir,
then Kaniko builds from local /workspace/repo/{service} path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Touch all Dockerfiles to force Gitea Actions to detect changes
and build all 25 backend services + 1 frontend via Kaniko → Harbor.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Scale all 26 services from 2→1 replicas (fit 8.4 available cores)
- HPA min 2→1, max 4→2 for staging
- Rewrite Gitea Actions: batch parallel Kaniko builds (5 per batch)
- Secure credentials via secrets (REPO_PASSWORD, HARBOR_*)
- Kaniko clones from Gitea (already mirrored from GitHub)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>