---
phase: 02-core-crud
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
- src/routes/+page.server.ts
- src/lib/server/db/repository.ts
- src/app.css
autonomous: true
must_haves:
truths:
- "Form actions accept POST requests for create, update, delete, toggleComplete"
- "Repository has getOrdered method returning tasks-first, newest-within-type"
- "Base font size is 16px (1rem) respecting browser settings"
artifacts:
- path: "src/routes/+page.server.ts"
provides: "SvelteKit form actions for CRUD operations"
exports: ["actions", "load"]
- path: "src/lib/server/db/repository.ts"
provides: "Extended repository with getOrdered method"
contains: "getOrdered"
- path: "src/app.css"
provides: "Base styling for accessibility"
contains: "font-size: 100%"
key_links:
- from: "src/routes/+page.server.ts"
to: "src/lib/server/db/repository.ts"
via: "entryRepository import"
pattern: "import.*entryRepository.*from.*repository"
---
Create SvelteKit form actions for all CRUD operations and establish base styling for accessibility.
Purpose: Provides the server-side API that all UI components will use, ensuring progressive enhancement (forms work without JavaScript) and establishing accessible typography.
Output: Form actions (create, update, delete, toggleComplete), extended repository with ordering, base CSS with 16px minimum font.
@/home/tho/.claude/get-shit-done/workflows/execute-plan.md
@/home/tho/.claude/get-shit-done/templates/summary.md
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/02-core-crud/02-CONTEXT.md
@.planning/phases/02-core-crud/02-RESEARCH.md
@src/lib/server/db/repository.ts
@src/lib/server/db/schema.ts
@src/routes/+page.server.ts
Task 1: Extend repository with getOrdered method
src/lib/server/db/repository.ts
Add a `getOrdered` method to EntryRepository interface and SQLiteEntryRepository implementation:
```typescript
getOrdered(options?: { showCompleted?: boolean }): Entry[]
```
Behavior:
- If showCompleted is false (default), exclude entries where status='done'
- Order by: type ASC (task before thought alphabetically), then createdAt DESC (newest first)
- Use drizzle-orm operators: `asc`, `ne` (import from drizzle-orm)
Implementation pattern from research:
```typescript
import { eq, desc, asc, ne } from 'drizzle-orm';
getOrdered(options: { showCompleted?: boolean } = {}): Entry[] {
const { showCompleted = false } = options;
let query = db.select().from(entries);
if (!showCompleted) {
query = query.where(ne(entries.status, 'done'));
}
return query
.orderBy(asc(entries.type), desc(entries.createdAt))
.all();
}
```
Run TypeScript check: `npm run check` passes without errors.
Test manually: Start dev server, database should still work with existing getAll method.
Repository has getOrdered method that filters completed entries and orders tasks-first, newest-within-type
Task 2: Create form actions for CRUD operations
src/routes/+page.server.ts
Replace current page.server.ts with full CRUD form actions. Keep the existing load function but modify to use getOrdered.
Actions to implement:
1. **create**: Accept title (optional), content (required), type (task|thought, default thought)
- Validate content not empty
- Return { success: true, entryId } on success
- Return fail(400, { error, title, content, type }) on validation failure
2. **update**: Accept id (required), plus any of: title, content, type, status
- Return fail(400) if no id
- Return fail(404) if entry not found
- Return { success: true } on success
3. **delete**: Accept id (required)
- Return fail(400) if no id
- Return fail(404) if entry not found
- Return { success: true } on success
4. **toggleComplete**: Accept id (required)
- Toggle status between 'open' and 'done'
- Return fail(400) if no id
- Return { success: true } on success
Import `fail` from '@sveltejs/kit'.
Import `entryRepository` from '$lib/server/db/repository'.
Update load function:
- Use getOrdered() instead of getAll()
- Pass showCompleted: false for now (will be dynamic later)
Run `npm run check` - TypeScript passes.
Test with curl:
```bash
# Create
curl -X POST http://localhost:5173/?/create -d "content=Test entry&type=task"
# Should return redirect (SvelteKit form action behavior)
```
All four form actions (create, update, delete, toggleComplete) exist and handle validation/errors correctly
Task 3: Establish accessible base styling
src/app.css
Update app.css to establish accessible base typography:
```css
@import 'tailwindcss';
/* Ensure minimum 16px base for accessibility (UX-02) */
html {
font-size: 100%; /* 16px default, respects user browser settings */
}
body {
font-size: 1rem; /* 16px minimum */
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Safe area padding for mobile devices with notches */
.safe-bottom {
padding-bottom: env(safe-area-inset-bottom, 0px);
}
/* Utility for adequate touch targets (44x44px minimum per WCAG) */
.touch-target {
min-height: 44px;
min-width: 44px;
}
```
This ensures:
- Base font respects user's browser zoom settings (100% = 16px default)
- All text uses rem, so user scaling works
- Mobile safe areas handled for bottom capture bar
- Touch target utility class available
Start dev server: `npm run dev`
Open in browser, inspect html element - font-size should be 100%.
Inspect body - font-size should be 1rem (16px computed).
Base CSS establishes 16px minimum font, safe area insets, and touch target utility
After all tasks complete:
1. **TypeScript**: `npm run check` passes
2. **Dev server**: `npm run dev` starts without errors
3. **Repository**: getOrdered method exists and returns entries in correct order
4. **Form actions**: All four actions exist in +page.server.ts
5. **CSS**: Base font is 16px (1rem), safe-bottom and touch-target classes defined
- Repository has getOrdered(options?) method with showCompleted filter and tasks-first ordering
- Form actions handle create (with validation), update, delete, and toggleComplete
- Base CSS ensures 16px minimum font and provides mobile-friendly utilities
- TypeScript compilation passes
- All requirements groundwork laid: CORE-01 through CORE-06, UX-02