Unify OpenCode and Codex starter kits

- Add .shared/prompts/ with tool-neutral prompts
- Add .opencode/config/project.md, rules/, skills/ from opencode-kit
- Add .codex/config/project.md from codex-kit
- Copy .shared/prompts/ to both .opencode/prompts/ and .codex/prompts/
- Add features/INDEX.md and features/README.md
- Update README with unified structure

The two original starter kits are now redundant.
This commit is contained in:
Worker Skeletton
2026-05-25 14:11:00 +02:00
parent 2d4dbe48e9
commit 5c9b4333da
38 changed files with 1659 additions and 107 deletions

View File

@@ -1,20 +1,74 @@
# Backend Rules
## PHP
Backend development rules for PHP, databases, and APIs.
- PHP 8+ Syntax
- Prepared Statements für DB Queries
- Input Validation immer auf Server-Seite
- Keine secrets in Code — .env nutzen
## PHP Code
## REST API
- Follow PSR-12 coding standard
- Use strict types: `declare(strict_types=1);`
- Use typed properties and return types
- Maximum function length: ~40 lines
- No code duplication — extract to helper functions
- JSON als Standard-Format
- HTTP Status Codes korrekt nutzen
- GET/POST/etc. semantisch richtig
## API Design
## SQLite
### RESTful Conventions
- Transactions für mehrere Writes
- FOREIGN KEY Constraints aktiviert
- Indexes auf häufige Query-Spalten
| Method | Path | Action |
|--------|------|--------|
| GET | /users | List users |
| GET | /users/{id} | Get single user |
| POST | /users | Create user |
| PUT | /users/{id} | Update user |
| DELETE | /users/{id} | Delete user |
### Response Format
```php
// Success
json_response(['data' => $user, 'status' => 200]);
// Error
json_response(['error' => 'Not found', 'status' => 404]);
// List with pagination
json_response([
'data' => $users,
'total' => $total,
'page' => $page,
'per_page' => $perPage
]);
```
### Status Codes
- `200` OK
- `201` Created
- `204` No Content (successful DELETE)
- `400` Bad Request
- `401` Unauthorized
- `403` Forbidden
- `404` Not Found
- `422` Unprocessable Entity (validation error)
- `500` Internal Server Error
## Validation
- Validate in the controller/action before business logic
- Return `422` with field-specific errors on validation failure
- Never trust user input — validate everything
## Database
- Use PDO with parameterized queries (no string interpolation)
- Use transactions for multi-step operations
- Use indexes on columns used in WHERE/JOIN
- Avoid N+1 queries
- See `database.md` for SQLite/MariaDB/PostgreSQL portability
## Testing
- Unit test business logic in isolation
- Integration test API endpoints
- Test happy path AND error paths
- Mock database in unit tests where practical

View File

@@ -0,0 +1,80 @@
# Database Rules
SQLite for development, MariaDB/PostgreSQL for production. Write portable SQL.
## Development Database
- Use SQLite for local development (zero-config, no server)
- Database file: `database.sqlite` in project root
- Create with: `touch database.sqlite`
## SQL Portability
### Use Standard SQL Only
- `CURRENT_TIMESTAMP` — works on SQLite, MariaDB, PostgreSQL
- `INTEGER PRIMARY KEY` — portable (mapped to SERIAL/BIGSERIAL)
- `TEXT` — portable (avoid VARCHAR length constraints)
- `DATETIME` — portable across all three databases
### Avoid
| Pattern | Why | Alternative |
|---------|-----|-------------|
| `REPLACE INTO` | Deletes then inserts (data loss) | `UPDATE ...; INSERT IF 0 rows affected` |
| `NOW()` | SQLite/MariaDB specific | `CURRENT_TIMESTAMP` |
| `GROUP_CONCAT()` | Not in SQLite | Application-level aggregation |
| `IFNULL()` | SQLite syntax | `COALESCE()` (standard) |
| Database-specific functions | Locks you in | Do it in application code |
### Boolean Fields
SQLite has no BOOLEAN — use INTEGER (0/1):
```sql
CREATE TABLE settings (
dark_mode INTEGER DEFAULT 0,
notifications INTEGER DEFAULT 1
);
```
### String Concatenation
Do string concatenation in PHP, not SQL.
### Upsert Pattern
```php
// Safe upsert (works on all databases)
$affected = $pdo->prepare(
'UPDATE users SET name = ? WHERE id = ?'
)->execute([$name, $id]);
if ($affected === 0) {
$pdo->prepare(
'INSERT INTO users (id, name) VALUES (?, ?)'
)->execute([$id, $name]);
}
```
## Migrations
- Store migrations in `migrations/` directory
- Name format: `001_description.sql`, `002_description.sql`
- Each migration must be idempotent (use `IF NOT EXISTS`)
- Run migrations on every environment
## Indexes
- Index columns used in `WHERE`, `JOIN`, `ORDER BY`
- Composite indexes: put most selective column first
- Don't over-index (write performance cost)
## No N+1 Queries
- Use JOINs or batch queries
- Eager load relationships when needed
## Transactions
Use transactions for any operation that modifies more than one table or row.

View File

@@ -1,17 +1,32 @@
# Frontend Rules
## HTML
Frontend development rules for React, Next.js, Tailwind CSS, and shadcn/ui.
- Semantisches HTML5
- Accessibility beachten (a11y)
## shadcn/ui Components
## CSS
- ALWAYS check `src/components/ui/` first before creating new components
- NEVER recreate a component that already exists in shadcn/ui
- If missing component: `npx shadcn@latest add <component-name>`
- CSS Variables für Theming
- Mobile-First Ansatz
- Keine inline Styles (außer dynamisch)
## Styling
## JS
- Use Tailwind CSS utility classes (never raw CSS)
- Follow existing patterns in the codebase
- Use `clsx` and `tailwind-merge` for conditional classes
- Vanilla JS bevorzugt, kein Framework-Overhead
- ES6+ Syntax
## Component Standards
- All components must be TypeScript (`.tsx`)
- Use proper TypeScript types for props
- Follow existing component patterns
## Testing
- Unit tests co-located next to source files
- Pattern: `ComponentName.test.tsx` next to `ComponentName.tsx`
- Use `@testing-library/react` for React tests
## Lint
- Run `npm run lint` after every change
- Fix lint errors before committing

View File

@@ -1,20 +1,35 @@
# General Rules
## Projekt Start
General development rules for the AI Coding Starter Kit.
Bei einem neuen Projekt:
1. README.md lesen / erstellen
2. AGENTS.md lesen
3. docs/planung/ öffnen und Projektstruktur verstehen
## Feature Tracking
## Naming
- All features MUST be tracked in `features/INDEX.md`
- Feature IDs are sequential: PROJ-1, PROJ-2, etc.
- Never skip IDs or use non-sequential numbering
- Kleinbuchstaben mit Bindestrichen: `mein-projekt`
- Subdomains als Verzeichnisse unter `www/`
- Document-Root immer `public/`
## Git Workflow
## Git Flow
- Commits: `feat(PROJ-X): description`, `fix(PROJ-X): description`
- Never commit secrets, API keys, or credentials
- Always read file before modifying (never assume contents)
1. Branch für Feature: `feature/<name>`
2. Commit oft mit aussagekräftigen Messages
3. Merge via PR oder direkt (bei kleinen Fixes)
## File Structure
- Feature specs: `features/PROJ-X-feature-name.md`
- Tests: co-located next to source (`*.test.ts` next to `*.ts`)
- shadcn/ui components: `src/components/ui/` (NEVER recreate)
## State Management
- State lives in files, not in memory
- Re-read files when context is compacted
- All progress in markdown files (INDEX.md, feature specs)
## Context Recovery
If context is compacted:
1. Re-read relevant feature spec
2. Check `git diff` for uncommitted changes
3. Continue from where you left off
4. Never restart from scratch without checking progress

67
.opencode/rules/php.md Normal file
View File

@@ -0,0 +1,67 @@
# PHP Rules
PHP development rules for portable, maintainable code.
## Code Style
- Follow PSR-12 coding standard
- Use PHP-CS-Fixer or Laravel Pint for formatting
- All new files must have `<?php` opening tag (no short tags `<?`)
- Use typed properties where possible: `private string $name;`
- Use strict types: `declare(strict_types=1);`
## Naming
- Classes: `PascalCase`
- Methods/functions: `camelCase`
- Constants: `SCREAMING_SNAKE_CASE`
- Database tables: `snake_case`
- Columns: `snake_case`
## Functions and Methods
- Maximum function length: ~40 lines
- Maximum parameters: ~4 (use DTOs for more)
- Never use `extract()` — security risk
- Never use `eval()` — security risk
- Never use `global` — use dependency injection
## Type Safety
- Declare return types on all public methods
- Use nullable types intentionally: `?string $name`
- Use `void` return type for methods that don't return
- Prefer `string` over `String`, `int` over `Integer` (lowercase scalar types)
## Error Handling
- Never suppress errors: `@`
- Use exceptions for exceptional cases
- Catch specific exceptions: `catch (InvalidArgumentException $e)`
- Never expose stack traces or internal errors to end users
## SQL and Database
- Use parameterized queries exclusively (never string interpolation)
- Use transactions for multi-step operations
- All SQL must be portable: works on SQLite, MariaDB, PostgreSQL
- See `database.md` for full portability rules
## Composer
- Run `composer validate` before committing `composer.json`
- Lock versions in `composer.lock` (commit it)
- No dev dependencies in production deployment
## Testing
- PHPUnit or Pest for unit/integration tests
- Test one thing per test method
- Use data providers for multiple test cases
- Mock external dependencies (database, APIs)
## Files
- One class per file
- File name matches class name: `UserRepository.php` contains `class UserRepository`
- No code outside of classes/functions (except config/bootstrap)

View File

@@ -1,22 +1,56 @@
# Security Rules
## Generell
Security rules for PHP projects.
- Nie Secrets in Git
- Input immer validieren
- Output immer escapen
## Secrets
## XSS
- NEVER commit secrets, API keys, or credentials
- Use `.env` for local development (gitignored via `.gitignore`)
- Use environment variables for production
- Never log sensitive data (passwords, tokens, personal data)
- Generate secrets with: `openssl_random_pseudo_bytes(32)` or `php -r "echo bin2hex(random_bytes(32));"`
- HTML specialchars() für User-Input in HTML
- Content-Security-Policy Header setzen
## Input Validation
## CSRF
- Validate ALL user input in PHP (never trust `$_GET`, `$_POST`, etc.)
- Use Respect Validation or Laravel Validator
- Sanitize data before database insertion
- Use parameterized queries exclusively (PDO, mysqli with placeholders)
- CSRF Token bei Forms
- SameSite=Cookie
## Output
## SQL Injection
- Escape output with `htmlspecialchars($str, ENT_QUOTES, 'UTF-8')` or framework equivalent
- Set Content-Type headers: `Content-Type: text/html; charset=UTF-8`
- Use CSRF tokens on all state-changing forms
- Prepared Statements immer nutzen
- Nie User-Input direkt in SQL
## Authentication
- Hash passwords with `password_hash()` (bcrypt/argon2) — NEVER MD5 or SHA1
- Use `password_verify()` for comparison
- Implement proper session handling: `session_regenerate_id(true)` on login
- Set secure cookie flags: `session_set_cookie_params(['httponly' => true, 'secure' => true])`
## Security Headers
For production, set these headers:
```
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: default-src 'self'
```
## File Uploads
- Never trust the filename — generate a new one
- Store files outside web root
- Validate MIME type server-side (not just by extension)
- Set file size limits
## Dependencies
- Keep Composer dependencies up to date: `composer outdated`
- Run `composer audit` regularly
- Update known vulnerable packages immediately