Files
Adriano b913a2bf90 registri dei piani in git (AI-OS#309)
Refs gitea:Adriano/AI-OS#310

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-06 10:36:26 +02:00

3.9 KiB

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):

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:

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:

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:

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
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"