2af477397e
I hope that coding results will be better and more consistent
176 lines
5.7 KiB
Markdown
176 lines
5.7 KiB
Markdown
# Bamort Development Instructions
|
|
|
|
Bamort is a role-playing game character management system (MOAM replacement) with a Go backend and Vue.js frontend.
|
|
|
|
## Project Overview
|
|
|
|
- **Repository**: github.com:Bardioc26/bamort.git
|
|
- **Architecture**: Monorepo with separate backend/frontend in Docker containers
|
|
- **Backend**: Go 1.25 + Gin framework + GORM + MariaDB
|
|
- **Frontend**: Vue 3 + Vite + i18n
|
|
- **Development**: Docker Compose with live-reload (Air for Go, Vite HMR for Vue)
|
|
|
|
## Backend Architecture (`backend/`)
|
|
|
|
### Module Structure
|
|
Each domain module follows this pattern (e.g., `character/`, `pdfrender/`, `equipment/`):
|
|
```
|
|
module/
|
|
handlers.go # HTTP handlers (Gin controllers)
|
|
routes.go # Route registration: RegisterRoutes(r *gin.RouterGroup)
|
|
*_test.go # Tests with setupTestEnvironment(t)
|
|
```
|
|
|
|
**Key conventions:**
|
|
- **Entry point**: `cmd/main.go` registers all modules via `RegisterRoutes(protected)`
|
|
- **Models**: `models/` contains GORM entities (e.g., `Char`, `SkFertigkeit`, `EqWaffe`)
|
|
- **Database**: Shared `database.DB` instance, use `models.MigrateStructure(db)` for migrations
|
|
- **Configuration**: `config.Cfg` loaded from env vars (see `config/config.go`)
|
|
- `TEMPLATES_DIR` for PDF templates (default: `./templates`)
|
|
- `ENVIRONMENT=test|development|production`
|
|
- `DATABASE_TYPE=mysql|sqlite`
|
|
|
|
### Testing Requirements
|
|
- **NEVER** create test files with `main()` functions
|
|
- **ALWAYS** use `_test.go` suffix
|
|
- **ALWAYS** call `setupTestEnvironment(t)` at start of each test:
|
|
```go
|
|
func setupTestEnvironment(t *testing.T) {
|
|
original := os.Getenv("ENVIRONMENT")
|
|
os.Setenv("ENVIRONMENT", "test")
|
|
t.Cleanup(func() { /* restore */ })
|
|
}
|
|
```
|
|
- Use `testutils.SetupTestDB()` for database tests (creates SQLite test DB)
|
|
- Test character ID 18 (Fanjo Vetrani) exists in test database
|
|
|
|
### API Patterns
|
|
- Protected routes under `/api` prefix require JWT authentication
|
|
- Use `respondWithError(c, status, message)` for error responses
|
|
- Route registration example:
|
|
```go
|
|
func RegisterRoutes(r *gin.RouterGroup) {
|
|
group := r.Group("/module")
|
|
group.GET("/list", ListHandler)
|
|
group.POST("/create", CreateHandler)
|
|
}
|
|
```
|
|
|
|
## Frontend Architecture (`frontend/`)
|
|
|
|
### Component Structure
|
|
- **Views**: `src/views/` - Page-level components (CharacterView, DashboardView)
|
|
- **Components**: `src/components/` - Reusable components (CharacterDetails, SkillView)
|
|
- **Utils**: `src/utils/api.js` - Axios instance with JWT interceptor
|
|
- **Locales**: `src/locales/de` and `src/locales/en` - i18n translations (JS objects, not JSON)
|
|
- **Store**: Pinia stores in `src/stores/`
|
|
|
|
### API Communication
|
|
- Use `API.get()`, `API.post()` from `utils/api.js` (auto-adds auth headers)
|
|
- Base URL: `import.meta.env.VITE_API_URL` (defaults to `http://localhost:8180`)
|
|
- Example:
|
|
```js
|
|
const response = await API.get(`/api/characters/${this.id}`)
|
|
```
|
|
|
|
### Translation Pattern
|
|
Add to both `locales/de` and `locales/en`:
|
|
```js
|
|
export default {
|
|
export: {
|
|
selectTemplate: 'Vorlage wählen', // DE
|
|
exportPDF: 'PDF Export'
|
|
}
|
|
}
|
|
```
|
|
|
|
## Docker Development Workflow
|
|
|
|
### Verify Containers
|
|
```bash
|
|
docker ps | grep bamort-backend-dev # Must be running before testing
|
|
```
|
|
|
|
### Container Names & Ports
|
|
- `bamort-backend-dev`: Go API at http://localhost:8180 (Air live-reload)
|
|
- `bamort-frontend-dev`: Vue at http://localhost:5173 (Vite HMR)
|
|
- `bamort-mariadb-dev`: MariaDB at localhost:3306
|
|
- `bamort-phpmyadmin-dev`: http://localhost:8082
|
|
|
|
### Rebuild After Dockerfile Changes
|
|
```bash
|
|
cd /data/dev/bamort
|
|
docker-compose -f docker/docker-compose.dev.yml build bamort-backend-dev
|
|
docker-compose -f docker/docker-compose.dev.yml up -d bamort-backend-dev
|
|
```
|
|
|
|
### View Logs
|
|
```bash
|
|
docker logs bamort-backend-dev --tail=50
|
|
docker logs bamort-frontend-dev --tail=20
|
|
```
|
|
|
|
## Testing Commands
|
|
|
|
### Backend Tests
|
|
```bash
|
|
cd /data/dev/bamort/backend
|
|
go test -v ./pdfrender/ -run TestExportCharacterToPDF
|
|
go test -v ./character/
|
|
```
|
|
|
|
### Frontend
|
|
- HMR auto-reloads on file save
|
|
- Check browser console and `docker logs bamort-frontend-dev`
|
|
|
|
## PDF Rendering Module (`pdfrender/`)
|
|
|
|
- Uses `chromedp` for HTML→PDF (requires Chromium in Docker)
|
|
- Templates in `templates/Default_A4_Quer/` (page1_stats.html, page2_play.html, etc.)
|
|
- Continuation pages auto-generated for overflow (page1.2_stats.html pattern)
|
|
- Test with character ID 18: generates 4 pages + continuations if needed
|
|
- Template capacity defined in HTML comments: `<!-- MaxItems: 58 -->`
|
|
|
|
## Common Patterns
|
|
|
|
### Error Handling (Backend)
|
|
```go
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
```
|
|
|
|
### Modal Dialogs (Frontend)
|
|
```vue
|
|
<div v-if="showDialog" class="modal-overlay" @click.self="showDialog = false">
|
|
<div class="modal-content"><!-- content --></div>
|
|
</div>
|
|
```
|
|
|
|
### Popup Blocker Workaround
|
|
Open window **synchronously** before async calls:
|
|
```js
|
|
const newWindow = window.open('', '_blank')
|
|
// ... then await API call ...
|
|
newWindow.location.href = url
|
|
```
|
|
|
|
## Critical Rules
|
|
|
|
1. **NEVER** write example/demo code - only production code
|
|
2. **NEVER** create test files with `main()` - use `_test.go`
|
|
3. **ALWAYS** check `docker ps` before assuming containers are running
|
|
4. **ALWAYS** use TDD: write failing test first, then implement
|
|
5. **ALWAYS** use KISS principle: simplest solution that works
|
|
6. **ALWAYS** add translations to both DE and EN locales
|
|
7. **ALWAYS** use global CSS definition to ensure consistent style
|
|
|
|
## File-Specific Instructions
|
|
|
|
Load additional instructions for specific file types:
|
|
- Go files: See `.github/instructions/go.instructions.md`
|
|
- Vue files: See `.github/instructions/vue.instructions.md`
|
|
- js files: See `.github/instructions/js.instructions.md`
|
|
- css files: See `.github/instructions/css.instructions.md`
|