docs(01): create phase 1 foundation plans
Phase 01: Foundation - 2 plans in 2 waves - Wave 1: Project setup with SvelteKit + Drizzle schema - Wave 2: Repository layer + verification page - Ready for execution Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
226
.planning/phases/01-foundation/01-01-PLAN.md
Normal file
226
.planning/phases/01-foundation/01-01-PLAN.md
Normal file
@@ -0,0 +1,226 @@
|
||||
---
|
||||
phase: 01-foundation
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- package.json
|
||||
- tsconfig.json
|
||||
- svelte.config.js
|
||||
- vite.config.ts
|
||||
- src/app.css
|
||||
- src/lib/server/db/schema.ts
|
||||
- src/lib/server/db/index.ts
|
||||
- drizzle.config.ts
|
||||
autonomous: true
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "npm run dev starts without errors"
|
||||
- "TypeScript compilation succeeds"
|
||||
- "Tailwind CSS classes are processed"
|
||||
- "Database schema defines unified entries table with type discriminator"
|
||||
artifacts:
|
||||
- path: "package.json"
|
||||
provides: "Project dependencies"
|
||||
contains: "better-sqlite3"
|
||||
- path: "src/lib/server/db/schema.ts"
|
||||
provides: "Drizzle schema with entries table"
|
||||
contains: "entries"
|
||||
- path: "src/lib/server/db/index.ts"
|
||||
provides: "Database connection and initialization"
|
||||
exports: ["db"]
|
||||
key_links:
|
||||
- from: "src/lib/server/db/index.ts"
|
||||
to: "src/lib/server/db/schema.ts"
|
||||
via: "import schema"
|
||||
pattern: "import.*schema"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Create the SvelteKit project with all core dependencies and establish the database schema using Drizzle ORM.
|
||||
|
||||
Purpose: Establishes the foundation for all subsequent development - project structure, tooling, and data model.
|
||||
Output: Working SvelteKit project with Drizzle schema defining the unified entries table.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@/home/tho/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@/home/tho/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/research/STACK.md
|
||||
@.planning/research/ARCHITECTURE.md
|
||||
@.planning/phases/01-foundation/01-CONTEXT.md
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Create SvelteKit project with dependencies</name>
|
||||
<files>
|
||||
package.json
|
||||
tsconfig.json
|
||||
svelte.config.js
|
||||
vite.config.ts
|
||||
src/app.html
|
||||
src/app.css
|
||||
src/routes/+page.svelte
|
||||
</files>
|
||||
<action>
|
||||
Create a new SvelteKit project using `npx sv create` with the following options:
|
||||
- Template: SvelteKit minimal
|
||||
- TypeScript: Yes
|
||||
- Tailwind CSS: Yes (v4 with @tailwindcss/vite)
|
||||
- ESLint + Prettier: Yes
|
||||
|
||||
After project creation, install additional dependencies:
|
||||
```bash
|
||||
npm install better-sqlite3 drizzle-orm nanoid zod
|
||||
npm install -D drizzle-kit @types/better-sqlite3
|
||||
```
|
||||
|
||||
Configure Tailwind in `src/app.css`:
|
||||
```css
|
||||
@import 'tailwindcss';
|
||||
```
|
||||
|
||||
Verify `vite.config.ts` includes Tailwind plugin (sv create should handle this).
|
||||
|
||||
Update `src/routes/+page.svelte` to include a simple Tailwind-styled element to verify CSS processing:
|
||||
```svelte
|
||||
<h1 class="text-2xl font-bold text-blue-600">TaskPlanner</h1>
|
||||
<p class="text-gray-600">Foundation setup complete.</p>
|
||||
```
|
||||
</action>
|
||||
<verify>
|
||||
Run `npm run dev` - server should start on localhost:5173 without errors.
|
||||
Visit the page - should see styled "TaskPlanner" heading.
|
||||
Run `npm run check` - TypeScript should pass.
|
||||
</verify>
|
||||
<done>
|
||||
SvelteKit dev server runs, Tailwind processes classes, all dependencies installed.
|
||||
</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Configure Drizzle schema with entries table</name>
|
||||
<files>
|
||||
src/lib/server/db/schema.ts
|
||||
src/lib/server/db/index.ts
|
||||
drizzle.config.ts
|
||||
</files>
|
||||
<action>
|
||||
Create `src/lib/server/db/schema.ts` with the unified entries table:
|
||||
|
||||
```typescript
|
||||
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
|
||||
|
||||
// Entry types: 'task' (actionable) or 'thought' (reference)
|
||||
export const entries = sqliteTable('entries', {
|
||||
id: text('id').primaryKey(), // nanoid
|
||||
title: text('title'),
|
||||
content: text('content').notNull(),
|
||||
type: text('type', { enum: ['task', 'thought'] }).notNull().default('thought'),
|
||||
status: text('status', { enum: ['open', 'done', 'archived'] }).default('open'), // for tasks
|
||||
pinned: integer('pinned', { mode: 'boolean' }).default(false),
|
||||
dueDate: text('due_date'), // ISO date string, nullable
|
||||
createdAt: text('created_at').notNull().$defaultFn(() => new Date().toISOString()),
|
||||
updatedAt: text('updated_at').notNull().$defaultFn(() => new Date().toISOString()),
|
||||
});
|
||||
|
||||
// Type inference for TypeScript
|
||||
export type Entry = typeof entries.$inferSelect;
|
||||
export type NewEntry = typeof entries.$inferInsert;
|
||||
```
|
||||
|
||||
Create `src/lib/server/db/index.ts` for database connection:
|
||||
|
||||
```typescript
|
||||
import Database from 'better-sqlite3';
|
||||
import { drizzle } from 'drizzle-orm/better-sqlite3';
|
||||
import * as schema from './schema';
|
||||
import { existsSync, mkdirSync } from 'fs';
|
||||
import { dirname } from 'path';
|
||||
|
||||
const DB_PATH = process.env.DATABASE_PATH || './data/taskplaner.db';
|
||||
|
||||
// Ensure data directory exists
|
||||
const dbDir = dirname(DB_PATH);
|
||||
if (!existsSync(dbDir)) {
|
||||
mkdirSync(dbDir, { recursive: true });
|
||||
}
|
||||
|
||||
const sqlite = new Database(DB_PATH);
|
||||
|
||||
// Enable WAL mode for better concurrent read performance
|
||||
sqlite.pragma('journal_mode = WAL');
|
||||
|
||||
export const db = drizzle(sqlite, { schema });
|
||||
|
||||
export { schema };
|
||||
```
|
||||
|
||||
Create `drizzle.config.ts` for migrations:
|
||||
|
||||
```typescript
|
||||
import { defineConfig } from 'drizzle-kit';
|
||||
|
||||
export default defineConfig({
|
||||
schema: './src/lib/server/db/schema.ts',
|
||||
out: './drizzle',
|
||||
dialect: 'sqlite',
|
||||
dbCredentials: {
|
||||
url: process.env.DATABASE_PATH || './data/taskplaner.db',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Add npm scripts to `package.json`:
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"db:migrate": "drizzle-kit migrate",
|
||||
"db:push": "drizzle-kit push",
|
||||
"db:studio": "drizzle-kit studio"
|
||||
}
|
||||
}
|
||||
```
|
||||
</action>
|
||||
<verify>
|
||||
Run `npm run db:push` - should create database file at `./data/taskplaner.db` with entries table.
|
||||
Run `sqlite3 ./data/taskplaner.db ".schema"` - should show entries table with all columns.
|
||||
Import db in a test: create a simple test file that imports and logs `db` without errors.
|
||||
</verify>
|
||||
<done>
|
||||
Drizzle schema defines entries table with id, title, content, type, status, pinned, dueDate, createdAt, updatedAt.
|
||||
Database file created with schema applied. WAL mode enabled.
|
||||
</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
1. `npm run dev` starts without errors
|
||||
2. `npm run check` passes TypeScript validation
|
||||
3. `./data/taskplaner.db` exists after `npm run db:push`
|
||||
4. Database has entries table with correct schema
|
||||
5. Tailwind classes render correctly on the test page
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- SvelteKit project created with TypeScript and Tailwind 4
|
||||
- All dependencies installed (better-sqlite3, drizzle-orm, nanoid, zod)
|
||||
- Drizzle schema defines unified entries table with type discriminator
|
||||
- Database initializes with WAL mode
|
||||
- Dev server starts and serves styled page
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/01-foundation/01-01-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user