feat(posts): author_id nel repository + listByAuthor + helper utenti

This commit is contained in:
2026-07-05 21:49:16 +02:00
parent db92fc9c02
commit 6d1e2607ee
3 changed files with 45 additions and 6 deletions
+10
View File
@@ -68,6 +68,16 @@ export function canAccessAdminPath(role: string, pathname: string): boolean {
return true; // blog, upload, logout, showtags: tutti i loggati return true; // blog, upload, logout, showtags: tutti i loggati
} }
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 }[];
}
export function landingFor(role: string): string { export function landingFor(role: string): string {
if (role === 'superuser') return '/admin/content'; if (role === 'superuser') return '/admin/content';
return '/admin'; return '/admin';
+9 -5
View File
@@ -2,21 +2,21 @@ import type Database from 'better-sqlite3';
export interface Post { export interface Post {
id: number; title: string; slug: string; category: string; excerpt: string; id: number; title: string; slug: string; category: string; excerpt: string;
body_html: string; cover: string | null; draft: number; body_html: string; cover: string | null; draft: number; author_id: number | null;
published_at: string | null; created_at: string; updated_at: string; published_at: string | null; created_at: string; updated_at: string;
} }
export interface PostInput { export interface PostInput {
title: string; slug: string; category: string; excerpt: string; title: string; slug: string; category: string; excerpt: string;
body_html: string; cover?: string | null; draft: boolean; body_html: string; cover?: string | null; draft: boolean; author_id?: number | null;
} }
export function createPost(db: Database.Database, input: PostInput): number { export function createPost(db: Database.Database, input: PostInput): number {
const res = db.prepare( const res = db.prepare(
`INSERT INTO posts (title, slug, category, excerpt, body_html, cover, draft, published_at) `INSERT INTO posts (title, slug, category, excerpt, body_html, cover, draft, author_id, published_at)
VALUES (@title, @slug, @category, @excerpt, @body_html, @cover, @draft, VALUES (@title, @slug, @category, @excerpt, @body_html, @cover, @draft, @author_id,
CASE WHEN @draft = 0 THEN datetime('now') ELSE NULL END)` CASE WHEN @draft = 0 THEN datetime('now') ELSE NULL END)`
).run({ ...input, cover: input.cover ?? null, draft: input.draft ? 1 : 0 }); ).run({ ...input, cover: input.cover ?? null, author_id: input.author_id ?? null, draft: input.draft ? 1 : 0 });
return Number(res.lastInsertRowid); return Number(res.lastInsertRowid);
} }
@@ -72,3 +72,7 @@ export function listArchiveMonths(db: Database.Database): { month: string; count
FROM posts WHERE draft = 0 GROUP BY month ORDER BY month DESC` FROM posts WHERE draft = 0 GROUP BY month ORDER BY month DESC`
).all() as { month: string; count: number }[]; ).all() as { month: string; count: number }[];
} }
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[];
}
+26 -1
View File
@@ -3,8 +3,9 @@ import type Database from 'better-sqlite3';
import { createDb } from '../src/lib/db'; import { createDb } from '../src/lib/db';
import { import {
createPost, updatePost, deletePost, getPostById, getPublishedBySlug, createPost, updatePost, deletePost, getPostById, getPublishedBySlug,
listPublished, listAllPosts, listRecent, listArchiveMonths, type PostInput, listPublished, listAllPosts, listRecent, listArchiveMonths, listByAuthor, type PostInput,
} from '../src/lib/posts'; } from '../src/lib/posts';
import { createUser, getUsernameById, listUsers } from '../src/lib/auth';
let db: Database.Database; let db: Database.Database;
beforeEach(() => { db = createDb(':memory:'); }); beforeEach(() => { db = createDb(':memory:'); });
@@ -72,3 +73,27 @@ describe('posts repository', () => {
expect(months[0].month).toMatch(/^\d{4}-\d{2}$/); expect(months[0].month).toMatch(/^\d{4}-\d{2}$/);
}); });
}); });
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);
});
});