This document covers development setup, architecture, and testing for the Solitude Interface project.
- Astro - Static site generator
- React - UI components
- TypeScript - Type safety
- TailwindCSS - Styling
- Ghost Content API - Headless CMS
- Vitest - Testing framework
- pnpm - Package manager
This project uses pnpm.
corepack enable pnpm
pnpm -vIf
corepackis not available, install pnpm globally:npm i -g pnpm
pnpm installIf you ever see a warning like “Ignored build scripts …”, run:
pnpm approve-buildsand allow trusted dependencies (e.g.
esbuild,sharp).
src/
├── api/ # Ghost API integration
│ ├── adapters/ # Data transformers
│ ├── clients/ # API clients
│ ├── config/ # Environment configuration
│ ├── ghost/ # Ghost-specific APIs
│ ├── utils/ # Utilities (cache, error handlers)
│ └── __tests__/ # API tests
├── components/ # UI components
│ ├── common/ # Shared components
│ ├── home/ # Homepage components
│ ├── i18n/ # Internationalization components
│ ├── layout/ # Layout components (navbar, dock)
│ ├── pages/ # Page-specific components
│ └── posts/ # Post display components
├── layouts/ # Astro layouts
├── lib/ # Core libraries (i18n)
├── pages/ # Astro pages
├── stores/ # State management (Jotai)
├── styles/ # Global styles
└── types/ # TypeScript types
| Command | Action |
|---|---|
pnpm install |
Install dependencies |
pnpm dev |
Start local dev server at localhost:4321 |
pnpm build |
Build production site to ./dist/ |
pnpm preview |
Preview build locally before deploying |
pnpm astro sync |
Generate Astro type definitions |
pnpm astro check |
Typecheck and validate Astro project |
pnpm format |
Format code with Prettier (writes changes) |
pnpm format:check |
Check formatting with Prettier (no changes) |
pnpm test |
Run tests in watch mode |
pnpm test:run |
Run all tests once (CI-friendly) |
pnpm test:unit |
Run unit tests only (fast, with mocks) |
pnpm test:integration |
Run integration tests (real API calls) |
pnpm test:coverage |
Run tests with coverage report |
pnpm test:ui |
Open Vitest UI for interactive testing |
This project includes two types of tests:
- Unit Tests: Fast tests using mock data, no external dependencies
- Integration Tests: Tests using real Ghost API to verify actual behavior
# Watch mode - runs tests on file changes
pnpm test
# Run only unit tests (fast, no API needed)
pnpm test:unit
# Run only integration tests (requires .env configuration)
pnpm test:integration
# Run all tests once (CI-friendly)
pnpm test:run| Feature | Unit Tests | Integration Tests |
|---|---|---|
| Speed | ⚡ Fast (< 1s) | 🐌 Slower (10-30s) |
| Dependencies | ✅ None | |
| API Calls | ❌ Mocked | ✅ Real Ghost API |
| Use Case | Daily development | Pre-commit / CI verification |
| Command | pnpm test:unit |
pnpm test:integration |
# Watch mode - runs tests on file changes
pnpm test
# Run all tests once
pnpm test:run
# Alias: run all tests once
pnpm test:all
# Run unit tests only
pnpm test:unit
# Run integration tests only
pnpm test:integration
# Generate coverage report
pnpm test:coverage
# Open interactive UI
pnpm test:ui- Ghost adapter logic (URL transformations, tag extraction)
- Cloudflare Zero Trust adapter
- Cache utilities
- Error handlers
- API client structure
- Real Ghost API connection
- Fetching posts and site information
- Data structure validation
- URL adaptation and transformation
- Tag extraction and categorization
- Cache performance (first call = API, second call = cache)
- Error handling with actual endpoints
src/api/__tests__/
├── setup.ts # Unit test setup (mocks env vars)
├── setup.integration.ts # Integration test setup (uses real env vars)
├── adapters/
│ ├── ghost.test.ts # Unit: Ghost adapter
│ └── cloudflare.test.ts # Unit: Cloudflare adapter
├── clients/
│ ├── ghost.test.ts # Unit: Ghost API client
│ └── ghost.integration.test.ts # Integration: Real API calls
├── ghost/
│ ├── posts.test.ts # Unit: Posts API
│ ├── posts.integration.test.ts # Integration: Real post data
│ ├── settings.test.ts # Unit: Settings API
│ └── settings.integration.test.ts # Integration: Real site info
└── utils/
├── cache.test.ts # Unit: Cache utilities
└── errorHandlers.test.ts # Unit: Error handlers
Naming Convention:
- Unit tests:
*.test.ts - Integration tests:
*.integration.test.ts
The following code in src/api/adapters/ghost.ts handles tag extraction:
const TAG_PREFIXES = {
TYPE: 'type-',
CATEGORY: 'category-',
SERIES: 'series-',
} as const;The i18n system in src/lib/i18n.ts handles language tags:
const LANG_TAG_PREFIX = 'hash-lang-'; // Ghost converts #lang-xx to hash-lang-xx
const I18N_TAG_PREFIX = 'hash-i18n-'; // Ghost converts #i18n-xx to hash-i18n-xxDefault language is set in src/lib/i18n.ts:
export const DEFAULT_LOCALE: Locale = 'zh';To change the default, modify this value and update astro.config.mjs:
i18n: {
locales: ['zh', 'en', 'ja'],
defaultLocale: 'zh', // Change this
}