unboundedpress/AGENTS.md

159 lines
4.4 KiB
Markdown
Raw Normal View History

# Agent Guidelines for Unboundedpress Dev
## Project Overview
This repository contains two main projects:
- **`portfolio-nuxt/`** - Primary Nuxt 3 application (Vue 3, TypeScript, Tailwind CSS, Pinia)
- **`portfolio/`** - Legacy Express.js application (plain JavaScript)
The Nuxt project is the main focus for development.
## Build Commands
### portfolio-nuxt (Primary Project)
```bash
cd portfolio-nuxt
npm install # Install dependencies
npm run dev # Development server
npm run build # Build for production
npm run generate # Generate static site
npm run preview # Preview production build
```
### portfolio (Legacy Project)
```bash
cd portfolio/src
npm run serve # Development with nodemon
npm run format # Format code
```
### Running a Single Test
**No test framework is currently configured.** If you add tests:
- For Nuxt: Use Vitest
- Run a single test: `npx vitest run --testNamePattern="test name"`
## Code Style Guidelines
### General Principles
- Use TypeScript in Vue components (`.vue` with `<script setup lang="ts">`)
- Use JavaScript (`.js`) in Pinia stores under `stores/`
- Follow Vue 3 Composition API with `<script setup>`
- Use Tailwind CSS classes for styling
### TypeScript Conventions
- Use `defineProps` and `defineEmits` with type-based syntax
- Use `withDefaults` for optional props with default values
- Prefer `ref` and `reactive` from Vue
- Use `toRefs` when destructuring props
```typescript
const props = withDefaults(
defineProps<{
modelValue?: boolean
persistent?: boolean
}>(),
{
modelValue: false,
persistent: false,
},
)
const emit = defineEmits<{
(e: 'update:modelValue', value: boolean): void
}>()
```
### Vue Component Structure
1. `<script setup lang="ts">` - Logic (imports, props, emits, composables)
2. `<template>` - Template with slots
3. `<style>` - Scoped styles (if needed, Tailwind preferred)
### Imports
- Use `@/` alias for imports (configured in Nuxt)
- Import Vue core: `import { ref, watch } from 'vue'`
- Import from stores: `import { useModalStore } from '@/stores/ModalStore'`
- Import icons: `import Icon from 'nuxt-icon'` or `<Icon name="..." />` in template
### File Naming
- Vue components: PascalCase (e.g., `IconButton.vue`, `Modal.vue`)
- Component folders: PascalCase with index.vue (e.g., `components/Modal/`)
- Stores: PascalCase with Store suffix (e.g., `AudioPlayerStore.js`, `ModalStore.js`)
- Pages: kebab-case (e.g., `index.vue`, `about-us.vue`)
### Tailwind CSS
- Use utility classes for all styling
- Follow existing patterns in components (see `components/Modal/Modal.vue`)
- Use `bg-`, `text-`, `p-`, `m-`, `flex-`, `grid-` prefixes
### State Management (Pinia)
- Create stores in `stores/` directory
- Use JavaScript (`.js`) for stores
- Follow the pattern in `stores/ModalStore.js`:
```javascript
import { defineStore } from "pinia"
export const useModalStore = defineStore("ModalStore", {
state: () => ({ key: "value" }),
actions: {
setKey(value) {
this.key = value
}
}
})
```
### API Data Fetching
- Use Nuxt's `useFetch` and `useAsyncData` composables
- Transform data in the `transform` option
```typescript
const { data: works } = await useFetch('https://unboundedpress.org/api/works', {
transform: (works) => {
// transformation logic
return transformedData
}
})
```
### Error Handling
- Handle null/undefined values in templates with `v-if` guards
- Use optional chaining (`?.`) when accessing nested properties
- Validate URLs before using them (see pattern in `pages/index.vue`)
### Head Management
Use `useHead` for SEO metadata:
```typescript
useHead({
titleTemplate: 'Site Title - %s'
})
```
### Transition and Animation
- Use Vue's built-in `<Transition>` and `<TransitionRoot>` components
- Use Headless UI for complex components (already installed)
## Additional Conventions
### Composables
- Place reusable logic in `composables/` directory
- Use the `use` prefix (e.g., `useModal`)
### Server Routes
- Place API routes in `server/api/` directory
- Use `.ts` files for TypeScript routes
### Image Handling
- Use `<NuxtImg>` component for optimized images
- Configure domains in `nuxt.config.ts` under `image.domains`
## Environment Variables
- Use `.env` files for local development
- Template available in `.env_template`
- Never commit secrets to version control
## Docker
- `Dockerfile` provided for deployment
- Multi-stage build available in `Dockerfile_upgrade`