Technical — Frontend
RAGA's web dashboard, built on Vue 3 + TypeScript + Vite. The main interface for chat, workspace/knowledge management, and platform administration (users, roles, models, etc.).
Repository
| Key | Value |
|---|---|
| Git Remote | https://git.tlab.co.id/tarantula/tarantula-v2/dashboard/tarantula-frontend.git |
| Active Branch | main |
git clone https://git.tlab.co.id/tarantula/tarantula-v2/dashboard/tarantula-frontend.git
cd tarantula-frontendNote: this repository lives under the
dashboardnamespace, unlike the other backend services which live under theservicenamespace.
Tech Stack
| Layer | Technology |
|---|---|
| Framework | Vue 3.5 (Composition API, <script setup>) + TypeScript |
| Build Tool | Vite 6 |
| State Management | Pinia 3 + pinia-plugin-persistedstate |
| Routing | Vue Router 4 |
| UI Components | shadcn-vue ("New York" style) + Tailwind CSS 3 + Lucide icons |
| Forms & Validation | vee-validate + zod |
| Data Fetching | Tanstack Vue Query, Tanstack Vue Table, axios |
| Rich Text Editor | Tiptap (with table, image, link, text-align extensions), md-editor-v3, markdown-it, marked + KaTeX (formula rendering) |
| Visualization & Diagrams | D3 + d3-cloud (wordcloud), Unovis, Highcharts, Vue Flow (flow diagrams), @superset-ui/embedded-sdk (embedded BI dashboards) |
| Audio | @ricky0123/vad-web (voice activity detection), recordrtc, wave-recorder |
| Document Export | jspdf + jspdf-autotable, pdfmake, docx, html2pdf.js, html-docx-ts |
| Auth & Storage | jwt-decode, encrypt-storage (encrypted localStorage) |
| Containerization | Docker multi-stage (node:20.17.0 build → nginx:stable serving static files) |
Folder Structure
frontend/
├── src/
│ ├── main.ts # Vue app entry point
│ ├── App.vue # Root component
│ ├── router/
│ │ ├── index.ts # Combines every module's router + navigation guard
│ │ └── Revamp.ts # Revamp module router — NOT mounted into index.ts (see note)
│ ├── api/
│ │ └── axios.ts # Axios instance + refresh-token interceptor
│ ├── stores/ # Global stores (ErrorStore, GlobalStore)
│ ├── layouts/ # AuthLayout, DefaultLayout, ChatLayout, SettingsLayout, BlankLayout
│ ├── helpers/
│ │ └── permission.ts # usePermission() — RBAC-based access check
│ ├── utils/
│ │ └── storage.ts # encryptStorage wrapper
│ ├── components/ # Shared UI components (including shadcn-vue primitives)
│ ├── modules/ # ~26 feature modules, each with its own router/store/views/components
│ └── theme/ # Theme & styling
├── public/
├── nginx.conf # nginx config for serving the production build
├── Dockerfile.prod
├── Dockerfile.stag
└── vite.config.tsEnvironment Variables
Read via import.meta.env (Vite). The .env.example file:
VITE_API_BASE_URL=
VITE_API_URL_USER=
VITE_API_DEVELOPMENT_MODE=
VITE_API_PORT=
VITE_LOGO_ONLY=
VITE_LOGO_FULL=
VITE_THEME=
VITE_PHOTO_OCR=
VITE_PHOTO_API=
INFISICAL_API_URL=
INFISICAL_CLIENT_ID=
INFISICAL_CLIENT_SECRET=
INFISICAL_ENV=
INFISICAL_PATH=
INFISICAL_PROJECT_ID=| Variable | Description |
|---|---|
VITE_API_BASE_URL | Only used to build the Access-Control-Allow-Origin header in src/api/axios.ts — not the actual API Tarantula request base URL (see VITE_API_URL_TARANTULA below) |
VITE_API_URL_USER | User Service base URL (used for login, token refresh, etc.) |
VITE_API_DEVELOPMENT_MODE | If "true", requests are routed to a relative path (/user, /tarantula — through the dev proxy in vite.config.ts) instead of VITE_API_URL_USER/VITE_API_URL_TARANTULA |
VITE_API_PORT | Additional port for CORS headers (optional) |
VITE_LOGO_ONLY / VITE_LOGO_FULL | Logo URLs for branding |
VITE_THEME | Active theme |
VITE_PHOTO_OCR / VITE_PHOTO_API | Image assets for OCR/API-related pages |
INFISICAL_* | Infisical credentials — used at build/deploy time (CI), not at runtime in the browser |
VITE_* variables are injected into the bundle at build time (npm run build-prod / build-stag), so the environment used depends on the build mode — it cannot be changed after the app is already running in the browser.
Note: the
.env.exampleabove does not cover every variable actually used in the code. The following additional variables were found viaimport.meta.envinsrc/and must be set for the related features to work:
| Variable | Description |
|---|---|
VITE_API_URL_TARANTULA | The actual API Tarantula base URL used by every module store (e.g. WorkspaceStore, ChatStore, GlobalStore) via checkIsDevelopment("/tarantula", ...) |
VITE_NAME | App name — used as document.title (main.ts), the tab title (vite.config.ts), and the label in the footer/chat input |
VITE_AIRI | Flag that enables the "Airi" chat UI variant (interactive avatar view) in the chat module |
VITE_AVATAR_GENDER / VITE_AVATAR_WITH_LOGO | Voice avatar configuration for the TalkAvatar component |
VITE_BACKGROUND_LOGIN | Background image URL for the login page (AuthLayout.vue) |
VITE_ID_CLIENT | Client ID for license info lookup (GET /utils/license/:id) and SSO login (AuthStore) |
VITE_MAX_CHAR_CHAT / VITE_SIZE_UPLOAD_CHAT | Character count and upload size limits on the chat input form |
VITE_SIZE_UPLOAD_AUDIO / VITE_SIZE_UPLOAD_DOCUMENT / VITE_SIZE_UPLOAD_USER | Upload size limits per module (audio, documents, user photo) |
VITE_PHOTO_PROFILE | Default profile photo URL (header, profile page, user detail) |
VITE_OPENAI_API_KEY / VITE_OPENAI_BASE_URL | OpenAI-compatible client credentials for the speech-to-text (Whisper) feature in the chat module |
VITE_TTS_BASE_URL | Text-to-speech endpoint used by the TalkAvatar feature |
Module Map
The app is split into ~26 independent modules under src/modules/, each with its own router, store, and views, combined in src/router/index.ts:
| Domain | Modules |
|---|---|
| Auth & Account | auth, profile, log-login |
| Workspace & Knowledge | workspace, basic, document, audio, rdbms, api, data-digital |
| Chat & Intelligence | chat, system-prompt, model, flow-diagrams |
| Access & Governance | acl, user, feature, subfeature, shortcut |
| Integrations | whatsapp, superset |
| Other | about, general, dashboard, hipmi, revamp |
The hipmi module is a dedicated chat interface (custom branding/flow separate from the main chat). The revamp module actually contains 8 redesigned sub-modules (api, audio, basic, chat, document, rdbms, system-prompt, workspace), each a new version of its original counterpart, combined into a separate router src/router/Revamp.ts — but this router is not imported by src/main.ts (which only uses src/router/index.ts), so the entire revamp flow is not yet live in production.
Authentication & Authorization
Token Flow
- Login calls
POST {VITE_API_URL_USER}/auth/loginon User Service;access_tokenandrefresh_tokenare stored viaencryptStorage(encrypted localStorage). - The
access_tokenis automatically attached as theAuthorization: Bearer <token>header on the global axios instance (src/api/axios.ts). - When a request fails due to an expired token, an axios interceptor automatically calls
POST /auth/refresh-tokenwith therefresh_token, updates both tokens, then retries the original request — only one refresh runs at a time (isRefreshingflag) even if many requests fail concurrently.
Policy-Based Authorization
usePermission()(src/helpers/permission.ts) provideshasPermission(url, method),canRead(),canCreate(),canUpdate(), etc. — checkinguserStore.map_policies(the RBAC policy list fetched from User Service at login) to decide whether a given button/action is shown.- This is a client-side reflection of the RBAC model in User Service (
Role→Policy→Feature/Subfeature) — actual authorization is still enforced on the backend; the frontend check is purely for UX (hiding actions the user isn't allowed to perform).
Backend Integrations
| Service | Env Variable | Description |
|---|---|---|
| User Service | VITE_API_URL_USER | Login, token refresh, user/role/policy management |
| API Tarantula | VITE_API_URL_TARANTULA | Workspace, knowledge (documents/audio/database/API), chat, system prompt |
| Superset | — (embedded via @superset-ui/embedded-sdk) | BI dashboards embedded in the superset module |
Build & Run
# Install dependencies
npm install
# Development
npm run dev
# Production build (production mode)
npm run build-prod
# Staging build (staging mode)
npm run build-stag
# Preview the build output
npm run previewDocker (production)
Multi-stage build: dependency install → vue-tsc + vite build --mode production → the resulting dist/ is served via nginx:stable.
docker build -f Dockerfile.prod -t tarantula-frontend .
docker run -p 80:80 tarantula-frontend