Skip to content
Arun K edited this page Jan 7, 2026 · 1 revision

Repository Overview

This is a Vue 3 monorepo for Springtail, a database management platform. It contains two frontend applications and a shared UI package:

  • admin-ui: Administrative interface for managing DB instances, organizations, shards, and users
  • springtail: Customer-facing application for managing accounts, databases, and instances
  • ui-shared: Shared components, utilities, and API client code

Build and Development Commands

Workspace Commands (run from root)

# Install dependencies
pnpm install

# Run a command in a specific workspace
pnpm --filter @springtail/admin-ui <command>
pnpm --filter @springtail/springtail <command>

Admin UI (apps/admin-ui)

cd apps/admin-ui

# Development server (localdev mode with proxied backend)
pnpm dev

# Build for production
pnpm build

# Build for development environment
pnpm build-development

# Type check
pnpm type-check

# Run linter
pnpm lint

# Run unit tests
pnpm test:unit

# Run tests in watch mode
pnpm test:unit --watch

# Generate API types from OpenAPI spec
pnpm build-types  # Requires ../../doc/openapi.json

Springtail UI (apps/springtail)

cd apps/springtail

# Same commands as admin-ui
pnpm dev
pnpm build
pnpm build-development
pnpm type-check
pnpm lint
pnpm test:unit
pnpm build-types  # Requires ../../doc/openapi.json

UI Shared Package (packages/ui-shared)

cd packages/ui-shared

# Generate API types from OpenAPI spec
pnpm build-types  # Requires ../../../doc/openapi.json

Architecture

Monorepo Structure

  • Uses pnpm workspaces for dependency management
  • ui-shared is referenced as workspace:* in both apps
  • TypeScript project references configured via tsconfig.base.json

Frontend Stack

  • Vue 3 with Composition API
  • Vue Router for routing
  • TanStack Query (Vue Query) for server state management and caching
  • Vuelidate for form validation
  • Tailwind CSS for styling
  • Vite for build tooling
  • Vitest with jsdom for unit testing
  • PropelAuth for authentication

API Communication

The application uses a JSON-RPC architecture:

  • RPC client in packages/ui-shared/src/rpc.ts
  • All API calls go through /jsonrpc/v1 endpoint
  • Methods follow pattern: namespace:Method (e.g., dbi:GetDBInstance, user:ListUsers)
  • API wrapper functions in packages/ui-shared/src/api.ts provide typed TanStack Query hooks
  • Request format: {jsonrpc: "2.0", id: number, method: string, params: object}

API Type Generation

  • API types are generated from OpenAPI spec using openapi-typescript-codegen
  • Generated files live in packages/ui-shared/src/models/api/
  • DO NOT manually edit generated API types - they will be overwritten
  • To regenerate types: pnpm build-types (requires OpenAPI spec at ../../doc/openapi.json or ../../../doc/openapi.json)

Authentication Flow

  • PropelAuth handles authentication
  • auth.checkLogin() verifies login and redirects to login page if needed
  • Router guard in main.ts checks auth on each route transition
  • Access tokens are automatically added to RPC requests via Authorization header

State Management

  • TanStack Query for server state (API data, caching, mutations)
  • Query client configured with 5-minute stale time and retry disabled
  • Mutation helpers (acctMutate, userMutate, etc.) auto-invalidate list queries
  • No Pinia/Vuex - server state lives in Query cache

Shared Component Library

The ui-shared package contains reusable components in src/components/:

  • dbinstance/: DB instance-specific components
  • org/: Organization-specific components
  • shared/: Generic UI components (Button, FormInput, FormSelect, Banner, Badge, etc.)

These components follow Tailwind CSS styling conventions and use Vuelidate for validation.

Import Aliases

Both apps use these Vite aliases:

  • @/: Points to app's src/ directory
  • ui-shared/: Points to packages/ui-shared/src/

Environment Configuration

Each app has environment files:

  • .env.localdev: Local development (proxied backend via Vite)
  • .env.development: Development deployment
  • .env.production: Production deployment

Key environment variables:

  • VITE_PROPEL_AUTH_URL: PropelAuth authentication endpoint
  • VITE_API_SERVER_URL: Backend API server URL
  • PROPEL_REDIRECT_URL: Post-login redirect URL

Development Server Setup

  • admin-ui: Runs on port 5174
  • springtail: Default Vite port (usually 5173)
  • Both use Vite proxy to forward /jsonrpc requests to http://localhost:8000 in localdev mode

Testing

  • Unit tests use Vitest with jsdom environment
  • Tests colocated with components (same directory)
  • Run tests with pnpm test:unit or pnpm test:unit --watch

Linting

  • ESLint configured with Vue 3 + TypeScript rules
  • Config in .eslintrc.cjs (per app)
  • Uses @rushstack/eslint-patch for module resolution

Key Patterns

RPC API Calls

Use the typed API wrapper functions from ui-shared/api.ts:

import { useListDBInstances, useGetDBInstance, useCreateDBInstance } from 'ui-shared/api'

// Query hook
const { data, isLoading, error } = useListDBInstances(ref({ limit: 10 }))

// Mutation hook
const createMutation = useCreateDBInstance()
createMutation.mutate(inputData)

Forms with Validation

Use Vuelidate with shared form components:

<FormInput
  v-model="formData.field"
  label="Field Label"
  :validation="v$.field"
  placeholder="Enter value"
/>

Routing Patterns

  • admin-ui: Routes for DB instances, organizations, shards, users
  • springtail: Routes for accounts, databases, organization settings
  • Both use nested routes with child views for detail pages

Important Notes

  • Both apps share identical main.ts setup (Vue Query, router, auth guard, click-away directive)
  • Generated API types should never be manually edited
  • RPC client auto-handles auth tokens and 4xx error redirects
  • Query invalidation is automatic for list queries after mutations
  • All styling uses Tailwind CSS utility classes

Clone this wiki locally