asepharyana
970a1cb7f7
docs: bete frontend redesign spec — IMPHNEN deep integration
...
Full 5-layer design document covering:
- Layer 0: Theme tokens & dark mode palette (light + dark CSS vars)
- Layer 1: Shared UI components (Badge, Toast, Skeleton fixes + new primitives)
- Layer 2: Layout & navigation (sidebar expanded, brand bar, tab strip, mobile)
- Layer 3: Feature components (MessageCard, Dashboard, Live panel refinements)
- Layer 4: Polish & micro-interactions (animations, empty states, theme toggle, mascot)
Resolves known issues in DESIGN_TOKENS.md §13 (hardcoded hex colors, z-index,
shimmer mismatch). Adds dark mode support across all components.
2026-07-02 05:40:04 +07:00
asepharyana
bf9d018f7a
fix: skip AI analysis for channel 1508059937031589949
2026-07-02 04:28:33 +07:00
asepharyana
c5a9371e71
fix(infra): nginx upstream DNS staleness — 502 after backend restart
...
- Replace upstream blocks with variable-based proxy_pass + Docker DNS
resolver (127.0.0.11) so nginx resolves hostnames dynamically on
each request instead of caching at startup only.
- Add explicit 'docker compose restart proxy' in CI deploy step
(belt-and-suspenders: also forces nginx restart after deploy).
- Remove no-op sed commands from CI (docker-compose.yml already uses
GitLab registry, no ghcr.io replacements needed).
Root cause: docker compose up -d only recreates containers whose image
changed. When backend container is recreated (new Docker IP), nginx
still caches the old IP → 502 Bad Gateway on /api/*
2026-07-02 04:22:16 +07:00
asepharyana
fa82593a38
fix: switch to node:22-slim, install deps from npm, remove vendor
2026-07-02 04:07:18 +07:00
asepharyana
1495211a61
chore: remove vendor directory
2026-07-02 04:03:32 +07:00
asepharyana
950bc03708
chore: update docker-compose to GitLab registry, remove .gitmodules
2026-07-02 04:03:21 +07:00
asepharyana
edc1a2d1fc
chore: restore .gitlab-ci.yml after revert
2026-07-02 03:57:13 +07:00
asepharyana
7efaf00c93
Revert "feat: migrate frontend to Astro + expand AI moderation + backend admin/runtime config"
...
This reverts commit d59b59a7a7 .
2026-07-02 03:54:44 +07:00
asepharyana
9636087e99
Revert "docs: add Astro migration design spec"
...
This reverts commit e8b1827638 .
2026-07-02 03:54:44 +07:00
asepharyana
6ecff523c7
Revert "docs: add Astro migration implementation plan"
...
This reverts commit 5e40b1ad8c .
2026-07-02 03:54:44 +07:00
asepharyana
bf86fcda8e
Revert "feat: migrate frontend to Astro SSG with design system"
...
This reverts commit 8ad888da28 .
2026-07-02 03:54:44 +07:00
asepharyana
880c68fbab
Revert "ci: migrate from GitHub Actions to GitLab CI/CD"
...
This reverts commit c64dd7c2ee .
2026-07-02 03:54:44 +07:00
asepharyana
26d33dd76b
Revert "ci: simplify GitLab CI — SSH → git pull → docker compose up -d --build"
...
This reverts commit a62c23f1e8 .
2026-07-02 03:54:44 +07:00
asepharyana
3b64a5892f
Revert "ci: switch to debian:stable-slim for SSH compatibility"
...
This reverts commit 0da9839b3a .
2026-07-02 03:54:44 +07:00
asepharyana
10839141d9
Revert "ci: add Docker build + GitLab Container Registry push before deploy"
...
This reverts commit 90b317731b .
2026-07-02 03:54:44 +07:00
asepharyana
9e315a9574
Revert "ci: remove docker tag — shared runners don't have it"
...
This reverts commit 13bba60e3a .
2026-07-02 03:54:44 +07:00
asepharyana
d37cecdb38
Revert "fix(Dockerfile): use node:22-slim for backend (glibc), add linux-headers + nodedir for gateway"
...
This reverts commit 9e8f4377af .
2026-07-02 03:54:44 +07:00
asepharyana
81f541c080
Revert "fix(Dockerfile): switch discord-gateway to node:22-slim for opus compatibility"
...
This reverts commit 51d3e47fe3 .
2026-07-02 03:54:44 +07:00
asepharyana
c408a8d1f7
Revert "fix(Dockerfile): install Rust via rustup for node-crc compatibility"
...
This reverts commit 0200c77fc2 .
2026-07-02 03:54:44 +07:00
asepharyana
ba399e6621
Revert "ci: add GIT_SUBMODULE_STRATEGY for vendor dependencies"
...
This reverts commit 7b106fe562 .
2026-07-02 03:54:44 +07:00
asepharyana
586627319f
Revert "refactor: vendor content as regular files (remove git submodules) so CI builds don't need GitHub auth"
...
This reverts commit 134674d7dd .
2026-07-02 03:54:44 +07:00
asepharyana
24c738dd19
Revert "fix: split LiveShell into Astro layout + individual islands"
...
This reverts commit 6e1757410a .
2026-07-02 03:54:44 +07:00
asepharyana
91e14abbda
Revert "fix: update nginx for Astro SSG — /_astro/ cache, remove SPA fallback"
...
This reverts commit 918e45f9da .
2026-07-02 03:54:44 +07:00
asepharyana
5a10bec67a
Revert "fix: replace Astro.redirect with direct live content at /"
...
This reverts commit 34ac4be6c2 .
2026-07-02 03:54:44 +07:00
asepharyana
34ac4be6c2
fix: replace Astro.redirect with direct live content at /
2026-07-02 03:47:23 +07:00
asepharyana
918e45f9da
fix: update nginx for Astro SSG — /_astro/ cache, remove SPA fallback
2026-07-02 03:42:56 +07:00
asepharyana
6e1757410a
fix: split LiveShell into Astro layout + individual islands
...
- Rewrite live.astro to use Astro Sidebar/Header/Card components
- VoiceControls becomes self-contained (fetches guilds/channels internally)
- Remove LiveShell.tsx (no longer needed)
- Each React island uses appropriate client:load/idle directive
2026-07-02 03:13:54 +07:00
asepharyana
134674d7dd
refactor: vendor content as regular files (remove git submodules) so CI builds don't need GitHub auth
2026-07-02 02:38:04 +07:00
asepharyana
7b106fe562
ci: add GIT_SUBMODULE_STRATEGY for vendor dependencies
2026-07-02 02:33:54 +07:00
asepharyana
0200c77fc2
fix(Dockerfile): install Rust via rustup for node-crc compatibility
2026-07-02 02:29:36 +07:00
asepharyana
51d3e47fe3
fix(Dockerfile): switch discord-gateway to node:22-slim for opus compatibility
2026-07-02 02:26:34 +07:00
asepharyana
9e8f4377af
fix(Dockerfile): use node:22-slim for backend (glibc), add linux-headers + nodedir for gateway
2026-07-02 02:22:09 +07:00
asepharyana
13bba60e3a
ci: remove docker tag — shared runners don't have it
2026-07-02 02:17:54 +07:00
asepharyana
90b317731b
ci: add Docker build + GitLab Container Registry push before deploy
2026-07-02 02:11:46 +07:00
asepharyana
0da9839b3a
ci: switch to debian:stable-slim for SSH compatibility
2026-07-02 01:55:21 +07:00
asepharyana
a62c23f1e8
ci: simplify GitLab CI — SSH → git pull → docker compose up -d --build
...
Remove Docker-in-Docker, registry push/pull, SCP complexity.
Pipeline now just SSHs into VPS and rebuilds from source.
Secrets configured:
VPS_HOST, VPS_USERNAME, VPS_SSH_KEY (file type)
2026-07-02 01:46:52 +07:00
asepharyana
c64dd7c2ee
ci: migrate from GitHub Actions to GitLab CI/CD
...
- Create .gitlab-ci.yml with Docker build + GitLab registry push + VPS deploy
- 4 build jobs (frontend, backend, discord-gateway, proxy) in parallel
- Uses Docker-in-Docker with BuildKit for cached multi-stage builds
- Deploy stage uses SCP for .env + docker-compose, then SSH for orchestration
- Images pushed to registry.gitlab.com/mytheclipse-group/gmw/
GitLab CI/CD secrets configured:
- VPS_HOST: 45.127.35.244
- VPS_USERNAME: root
- VPS_SSH_KEY: (file type - SSH private key)
- ENV_FILE: (env_var type - full .env content)
Remove old .github/workflows/deploy-docker.yml (GitHub Actions)
2026-07-02 01:46:18 +07:00
asepharyana
8ad888da28
feat: migrate frontend to Astro SSG with design system
...
- Replace monolithic React SPA (App.tsx) with 7 Astro pages (+ routing)
- Implement full design system from design/ (OKLCH tokens, Tailwind 4 @theme)
- Add 12 Astro components (Button, Badge, Card, Sidebar, Header, states)
- Add 11 React islands (AuthGuard, MessageFeed, VoiceControls, AudioVisualizer, etc.)
- Add 3 Zustand stores (UI, voice, message state)
- Add CSS architecture: dark/light themes, glassmorphism, fluid typography, animations
- Add 404, login, settings, recordings pages
- Remove 40+ legacy React SPA files
- Add Particles background and MascotChat deferred islands
- Wire WebSocket bridge for real-time messages and voice events
Build: 7 pages in ~900ms
Typecheck: clean (0 errors)
Lint: clean (0 errors)
2026-07-02 01:18:45 +07:00
asepharyana
5e40b1ad8c
docs: add Astro migration implementation plan
2026-07-02 00:41:17 +07:00
asepharyana
e8b1827638
docs: add Astro migration design spec
2026-07-02 00:36:30 +07:00
asepharyana
d59b59a7a7
feat: migrate frontend to Astro + expand AI moderation + backend admin/runtime config
...
Frontend:
- migrate from Vite to Astro (astro.config.mjs, pages/, layouts/)
- add admin panel, settings page, command palette, error boundary
- refactor App.tsx, MascotChatbot, Sidebar, Header, DashboardLayout
- update API client, WebSocket, auth, dashboard features
Backend:
- add admin module and config routes
- refactor middlewares, Redis connection, WebSocket server/bridge
- add runtime config loader
Discord Gateway:
- refactor AI moderation: circuit breaker, concurrency limiter, fallback processor
- add media analysis client, Seaxng search, user profile learner
- add new drizzle migration
Shared:
- extend database schema, add new config fields
2026-07-02 00:02:41 +07:00
MythEclipse
d5c22a3959
fix(discord-gateway): handle forwarded message content via messageSnapshots
...
Two-layer fix for forwarded messages showing as empty/clean:
Layer 1 (messageMetadata.ts): getReferencedMessageContent() now falls
back to message.messageSnapshots Collection when channel.messages.cache
lookup fails. Discord stores forward content in message_snapshots API
field, not in message.content.
Layer 2 (moderationBuilders.ts): buildReferenceXml() now parses msg.
metadata JSON to extract reference.content when DB getMessageById()
fails (cross-server forwards not in local DB).
Previously: forward messages captured with empty parentContent →
LLM saw no reference text → '99% confidence, pesan kosong'.
Now: forward content flows through capture → metadata → analysis.
2026-06-23 23:27:23 +07:00
MythEclipse
ed4a506ca7
refactor: split llmModerationClient.ts + add tests + metrics
...
## Split llmModerationClient.ts (2103 → 3 files)
- **moderationBuilders.ts** (67 lines) — shared: escapeXml, getAnalysisContent, buildReferenceXml
- **mediaAnalysisClient.ts** (656 lines) — vision analysis with multi-layer LRU/DB/phash caching, image/video download, ffmpeg frame extraction, prepareMediaMessage
- **moderationOrchestrator.ts** (998 lines) — callModerationLLM, runTextOnlyBatch, runMediaBatch, runModerationAnalysis, runSimpleTextFallback
- **llmModerationClient.ts** (30 lines) — re-export bridge (backward compat)
No import changes needed — aiAnalysisWorker.ts still imports from llmModerationClient.js.
## Unit tests (backend)
- vitest.config.ts + e2e.test.ts with 9 tests against production:
- health, metrics, dashboard/stats, recordings, config, auth, guilds, negative (404/400)
## Monitoring metrics
- moderationMetrics.ts in backend health module:
- LLM call count/duration/tokens
- Cache hit/miss per layer
- Media analysis count/download duration
- Batch size distribution, errors, SearXNG, auto-delete
2026-06-22 20:38:34 +07:00
MythEclipse
c00b1625fa
chore: add E2E test script for production stack
...
- Tests: health, dashboard/stats, recordings, messages, config, auth, voice guilds, frontend, 404
- Validates JSON fields + HTTP status codes
- Runs against real production (imphnen.asepharyana.my.id)
- Usage: bash scripts/e2e-test.sh [url]
2026-06-22 18:45:45 +07:00
MythEclipse
a3c99a08c3
fix: recordings endpoint 500 — column 'transcription' doesn't exist
...
- SELECT transcription FROM voice_recordings fails because table has no such column
- Removed non-existent transcription from SELECT and interface
- Previous sql.raw() parameter binding also broken — fixed with proper drizzle sql``
2026-06-22 18:22:46 +07:00
MythEclipse
3a282d8467
fix: recordings endpoint 500 — broken SQL parameter binding
...
- Hand-rolled , params with sql.raw() didn't actually bind values
- Drizzle's sql.raw() just inserts literal text — no parameter binding
- Replaced with proper sql`` tagged templates + sql.join() for conditions
- Each filter now correctly binds via drizzle's parameterized query
2026-06-22 17:54:09 +07:00
MythEclipse
ad84d0a1bb
fix: messages with text+media also go into text batch immediately
...
- Previously: text+media message went ONLY to media array → text waited for vision
- Now: text part goes to text batch (immediate LLM analysis), media parallel
- DB update is idempotent — second write to same message_id overwrites
- User sees text moderation results instantly, media follows when ready
2026-06-22 17:45:32 +07:00
MythEclipse
e8286247d6
fix: parallelize text + media LLM analysis instead of sequential
...
- text-only and media analysis now run concurrently via Promise.all
- text no longer blocks on media download + vision analysis
- each path independently saves to DB when its own results are ready
- same batch still uses single context fetch + attachment lookup
2026-06-22 17:42:46 +07:00
MythEclipse
dfabdc85cd
feat: search ALL messages via SearXNG + Redis cache dedup
...
- Remove shouldSearchContent() trigger gate — search runs on all messages
- extractSearchQueries() now extracts from ANY message, not just trigger-matched
- Redis cache (24h TTL) prevents redundant searches for same query
- initSearxngCache() lazy-connects via config.REDIS_URL
- Cache miss→API, hit→skip — fire-and-forget writes
- Both text batch + media path simplified
2026-06-22 12:41:48 +07:00
MythEclipse
84f87104e7
refactor: remove hardcoded lists from prompt, use SearXNG as single source of truth
...
- Remove hardcoded hentai title lists (Boku no Pico, Euphoria, etc.) from prompt
- Remove hardcoded SARA examples from prompt (Kitabonia, etc.)
- Prompt now tells LLM to use <web_searches> as evidence instead of hardcoded knowledge
- Evidence priority: searxng > web_content > media_analysis > internal model
- Code-side triggers in searxngSearch.ts still filter which messages to search
- LLM makes final decision based on search results, not static lists
2026-06-22 12:01:55 +07:00