5.4 KiB
5.4 KiB
AGENTS.md
This file contains guidelines for agentic coding assistants working in this repository.
Project Overview
Vue 3 + Vite + Leaflet interactive map visualizing the novel "大唐双龙传" (The Twin of Brothers), showing factions, locations, character routes, and key events across 20 volumes.
Commands
Build & Dev
cd frontend && npm run dev- Start dev server (http://localhost:5173)cd frontend && npm run build- Production build (outputs to ../dist)cd frontend && npm run preview- Preview production build
Testing
No test framework currently configured. Before adding tests, propose the approach (e.g., Vitest for unit tests, Playwright for E2E).
Linting/Typechecking
No linting tools configured. Before adding eslint/prettier, verify compatibility with existing code style.
Code Style Guidelines
Vue 3 & JavaScript
- Use Composition API with
<script setup>syntax - Import only what you need:
import { ref, computed, onMounted } from 'vue' - Use
constfor all variables,letonly when necessary - Separate concerns: state first, then lifecycle hooks, then functions
- Use computed properties for derived state, watchers for side effects
- Function names use camelCase, descriptive:
drawTerritories(),toggleRoute()
Imports
- Group imports: Vue libraries first, then external packages, then local files
- Named imports only, avoid default imports where possible
- Leaflet:
import L from 'leaflet'thenimport 'leaflet/dist/leaflet.css'
File Organization
- Single-file components: template, script, style in that order
- Script sections separated with comment dividers:
// ── 响应式状态 ────────────────────────────────────────────── // ── Leaflet 图层管理 ──────────────────────────────────────── // ── 生命周期 ──────────────────────────────────────────────── // ── 数据加载 ──────────────────────────────────────────────── // ── 地图初始化 ────────────────────────────────────────────── // ── 工具函数 ────────────────────────────────────────────────
Naming Conventions
- Variables: camelCase (
currentVol,mergedLocations,isLoading) - Constants: UPPER_SNAKE_CASE (
layerGroups) - Files: kebab-case (
chapter-panel.vue, not ChapterPanel.vue`) - IDs in JSON: lowercase with underscores (
yuwen_faction,grand_canal) - CSS classes: kebab-case (
.map-container,.legend-item)
CSS & Styling
- Use scoped styles in components
- Dark theme: backgrounds
rgba(20, 20, 40, 0.9), text#e0e0e0 - Accent color:
#c9a96e(gold) for headers and highlights - Absolute positioning for UI overlays (z-index 1000+ for panels)
- Panels use fixed width/height or flexbox for layouts
- Leaflet overrides in global style.css (popup styles)
Data Structure (JSON volumes)
Each volXX.json in /data follows:
{
"volume": "卷X",
"chapters": ["第01章 标题", ...],
"locations": [
{ "id": "unique_id", "name": "Location", "type": "city|town|landmark|waterway",
"lat": 0.0, "lng": 0.0, "description": "..." }
],
"factions": [
{ "id": "unique_id", "name": "Faction", "type": "门阀|朝廷|义军",
"color": "#hex", "leader": "Name", "territory": ["loc_id", ...],
"key_figures": ["Name", ...], "description": "..." }
],
"character_routes": [
{ "character": "Name", "color": "#hex",
"route": [{ "chapter": 1, "location": "loc_id", "event": "..." }] }
],
"key_events": [
{ "chapter": 1, "event": "Description", "location": "loc_id" }
]
}
Error Handling
- Use try/catch for fetch operations
- Log warnings with context:
console.warn('vol01.json load failed:', err) - User-facing loading states:
isLoading.value = true/false - Graceful degradation: missing data should not crash the app
Leaflet Integration
- Initialize map in
onMounted(), store in module-scoped variable - Use layer groups for organized rendering:
territories,locations,routes,events - Clear layers before redrawing:
layerGroups.someLayer.clearLayers() - Custom icons use
L.divIcon()for HTML markers - Dark map tile: CartoDB Dark Matter basemap
Comments & Documentation
- Minimal comments - code should be self-documenting
- Section dividers (as shown above) for organization
- TODO notes for future improvements
- README.md contains project overview and technical architecture
Performance Considerations
- Lazy load data: fetch all volumes in parallel, store in reactive array
- Use computed properties with Map for efficient deduplication
- Debounce heavy operations (map redraws, calculations)
- Limit rendered elements: show only up to
currentVol
Adding New Features
- Check existing data structure in
/data/volXX.json - Follow established code patterns in App.vue
- Use layer groups for new map features
- Update UI panels (legend, chapter-panel, info-panel) consistently
- Ensure responsive state updates with Vue's reactivity system