### Task 4: Repository posts — autore e liste per autore **Files:** - Modify: `src/lib/posts.ts` - Modify: `src/lib/auth.ts` (helper utenti riusati anche dal blog e dalla gestione utenti) - Test: `tests/posts.test.ts` **Interfaces:** - Produces: - `interface Post` con `author_id: number | null` - `interface PostInput` con `author_id?: number | null` - `createPost(db, input)` scrive `author_id` - `listByAuthor(db, authorId: number): Post[]` - in `auth.ts`: `getUsernameById(db, id: number): string | null`, `listUsers(db): { id: number; username: string; role: string }[]` - [ ] **Step 1: Scrivi i test del repository** Aggiungi in `tests/posts.test.ts` (in coda, riusando `db`/`base`): ```typescript import { listByAuthor } from '../src/lib/posts'; import { createUser, getUsernameById, listUsers } from '../src/lib/auth'; describe('autore articoli', () => { it('createPost salva author_id e listByAuthor filtra', () => { const aliceId = createUser(db, 'alice', 'segreta123', 'user'); const bobId = createUser(db, 'bob', 'segreta123', 'user'); createPost(db, { ...base, slug: 'a1', author_id: aliceId }); createPost(db, { ...base, slug: 'a2', author_id: aliceId }); createPost(db, { ...base, slug: 'b1', author_id: bobId }); expect(listByAuthor(db, aliceId).length).toBe(2); expect(listByAuthor(db, bobId).length).toBe(1); }); it('post senza author_id ha author_id null', () => { const id = createPost(db, { ...base, slug: 'orfano' }); expect(getPostById(db, id)!.author_id).toBeNull(); }); it('getUsernameById e listUsers', () => { const id = createUser(db, 'carla', 'segreta123', 'superuser'); expect(getUsernameById(db, id)).toBe('carla'); expect(getUsernameById(db, 99999)).toBeNull(); expect(listUsers(db).some((u) => u.username === 'carla' && u.role === 'superuser')).toBe(true); }); }); ``` - [ ] **Step 2: Esegui e verifica il fallimento** Run: `npm test -- tests/posts.test.ts` Expected: FAIL — `listByAuthor`/`getUsernameById`/`listUsers` non esistono, `author_id` non nell'input. - [ ] **Step 3: Aggiorna `posts.ts`** Nell'`interface Post` aggiungi `author_id: number | null;`. Nell'`interface PostInput` aggiungi `author_id?: number | null;`. Sostituisci `createPost`: ```typescript export function createPost(db: Database.Database, input: PostInput): number { const res = db.prepare( `INSERT INTO posts (title, slug, category, excerpt, body_html, cover, draft, author_id, published_at) VALUES (@title, @slug, @category, @excerpt, @body_html, @cover, @draft, @author_id, CASE WHEN @draft = 0 THEN datetime('now') ELSE NULL END)` ).run({ ...input, cover: input.cover ?? null, author_id: input.author_id ?? null, draft: input.draft ? 1 : 0 }); return Number(res.lastInsertRowid); } ``` `updatePost` resta invariato (non tocca `author_id`: l'autore non cambia in modifica). Aggiungi in fondo: ```typescript export function listByAuthor(db: Database.Database, authorId: number): Post[] { return db.prepare('SELECT * FROM posts WHERE author_id = ? ORDER BY updated_at DESC').all(authorId) as Post[]; } ``` - [ ] **Step 4: Aggiungi gli helper utenti in `auth.ts`** In `src/lib/auth.ts` aggiungi: ```typescript export function getUsernameById(db: Database.Database, id: number): string | null { const row = db.prepare('SELECT username FROM users WHERE id = ?').get(id) as { username: string } | undefined; return row?.username ?? null; } export function listUsers(db: Database.Database): { id: number; username: string; role: string }[] { return db.prepare('SELECT id, username, role FROM users ORDER BY username').all() as { id: number; username: string; role: string }[]; } ``` - [ ] **Step 5: Esegui e verifica il successo** Run: `npm test -- tests/posts.test.ts` Expected: PASS. - [ ] **Step 6: Commit** ```bash git add src/lib/posts.ts src/lib/auth.ts tests/posts.test.ts git commit -m "feat(posts): author_id nel repository + listByAuthor + helper utenti" ``` ---