fix(screenshots): improve seed data content and remove attachments

- Remove image attachments and attachments screenshot
- Remove pinned note for cleaner hero grid
- Enrich note content with markdown (headings, bold, italic, blockquotes, lists)
- Replace "Ancient Flute" with "Coding Playlists" (ties to Navidrome)
- Shorten titles, remove content that repeats title
- Remove hashtags from checklist notes (rendered as items)
- Use bretzel persona "Salzig Bretzel" for collaborator
- Update services: Crumbs, 42, Dokploy, Outline, Navidrome, RetroAssembly, Umami

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Frederic Cabassut
2026-03-20 22:32:16 +01:00
committed by Fred Cabassut
co-authored by Claude Opus 4.6
parent 1d60cca2de
commit 6f496cbd87
13 changed files with 110 additions and 132 deletions
+1 -11
View File
@@ -72,17 +72,7 @@ export async function captureDesktop(page: Page): Promise<void> {
await page.getByTestId('close-editor-btn').click();
await waitForApp(page);
// D6: Attachments — open "Bretzel Ingredients" (has featured bretzel image)
await noteCard(page, 'Bretzel Ingredients').click();
await page.waitForSelector('[data-testid="note-editor"]');
await page.getByTestId('image-toggle').click();
await page.waitForSelector('[data-testid="image-upload"]');
await waitForApp(page);
await screenshot(page, 'screenshot-attachments.png');
await page.getByTestId('close-editor-btn').click();
await waitForApp(page);
// D7: API/MCP settings
// D6: API/MCP settings
await page.goto(`${BASE_URL}/settings/mcp`);
await waitForApp(page);
await screenshot(page, 'screenshot-api.png');
+3 -3
View File
@@ -12,7 +12,7 @@ export const ADMIN = {
};
export const COLLABORATOR = {
email: 'alice@bretzel.app',
displayName: 'Alice Chen',
password: 'alice2026!!'
email: 'salzig@bretzel.app',
displayName: 'Salzig Bretzel',
password: 'salzig2026!!'
};
+106 -114
View File
@@ -1,5 +1,4 @@
import type { Page } from '@playwright/test';
import { generateBretzelPng, generateSaltShakerPng } from './bretzel-pixel';
import { BASE_URL, ADMIN, COLLABORATOR } from './constants';
type HttpMethod = 'post' | 'patch' | 'get' | 'delete';
@@ -16,34 +15,6 @@ async function api(page: Page, method: HttpMethod, path: string, data?: unknown)
return text ? JSON.parse(text) : {};
}
async function uploadAttachment(
page: Page,
noteId: string,
filename: string,
pngBuffer: Buffer,
featured: boolean
): Promise<void> {
const res = await page.request.post(`${BASE_URL}/api/notes/${noteId}/attachments`, {
headers: { Origin: BASE_URL },
multipart: {
file: {
name: filename,
mimeType: 'image/png',
buffer: pngBuffer
}
}
});
if (!res.ok()) {
throw new Error(`Upload ${filename} failed: ${res.status()} ${await res.text()}`);
}
if (featured) {
const attachment = await res.json();
await api(page, 'patch', `/api/notes/${noteId}/attachments?attachmentId=${attachment.id}`, {
featured: true
});
}
}
interface NoteData {
key: string;
title: string;
@@ -59,83 +30,104 @@ function getNotesData(): NoteData[] {
return [
{
key: 'bakingcode',
title: 'Baking code for the...',
content: `A developer's checklist where code meets dough.
- [x] Set up CI/CD pipeline
- [x] Write the CRDT sync logic
- [ ] Bake the docker image
title: 'Crumbs v0.23 Release',
content: `- [x] CRDT sync logic
- [x] MCP server integration
- [ ] Bake the Docker image
- [ ] Deploy to the homelab
- [ ] Celebrate with a bretzel
#dev #bretzel`,
- [ ] Celebrate with a bretzel`,
color: 'clay',
checklistMode: true
},
{
key: 'flute',
title: 'Ancient Flute Harmonica Discovered',
content: `Archaeologists found a 40,000-year-old flute carved from vulture bone.
key: 'coding-music',
title: 'Coding Playlists',
content: `Curated on **Navidrome** for maximum focus.
The oldest known musical instrument.
Imagine the first song ever played.
### Late Night Focus
#reading`,
1. *Tycho* — Dive (ambient electronic)
2. *Boards of Canada* — Music Has the Right to Children
3. *Nujabes* — Modal Soul
4. *C418* — Minecraft Volume Alpha
### Saturday Baking
For slow mornings in the kitchen:
1. *Khruangbin* — Con Todo El Mundo
2. *Tatsuro Yamashita* — For You
#music #personal`,
color: 'chalk'
},
{
key: 'weekend',
title: 'Weekend Plans',
content: `Saturday:
- Farmer's market (get sourdough starter)
content: `### Saturday
- Farmer's market — get sourdough starter
- Fix the Dokploy SSL cert renewal
- Bake a batch of bretzels
Sunday:
- Retro gaming marathon
### Sunday
- Retro gaming marathon on *RetroAssembly*
- Update the self-hosting stack
- Plan next trip on 42
- Plan next trip on **42**
> A weekend well spent brings a week of content.
#personal #weekend`,
color: 'mint'
},
{
key: 'manifesto',
title: 'The Best Software Is the Software You Own',
content: `Self-host everything. Trust no cloud.
title: 'Own Your Software',
content: `## The Rules
The best software is the software you own.
Your data. Your server. Your rules.
1. **Self-host everything.** Trust no cloud.
2. **Own your data.** Your server, your rules.
3. **Keep it simple.** If it needs a PhD to deploy, it's wrong.
4. **SQLite > Postgres** for single-user apps. Fight me.
If it can't run on your hardware, it's not really yours.
> If it can't run on your hardware, it's not really yours.
#personal #bretzel`,
Seven services, one VPS, *zero* vendor lock-in.
#personal #selfhosting`,
color: 'coral'
},
{
key: 'retro',
title: 'Back to Retro Gaming',
content: `Games to replay this summer:
content: `Games running on **RetroAssembly** this summer:
Chrono Trigger (SNES) — best RPG ever made
The Legend of Zelda: Link's Awakening (GB)
Castlevania: Symphony of the Night (PS1)
Advance Wars (GBA)
Final Fantasy Tactics (PS1)
- **Chrono Trigger** (SNES) — best RPG ever made
- **Link's Awakening** (GB) — pure portable magic
- **Symphony of the Night** (PS1) — the *definitive* Metroidvania
- **Advance Wars** (GBA) — turn-based perfection
- **Final Fantasy Tactics** (PS1) — political intrigue + job system
The pixel art era was peak game design.
> The pixel art era was peak game design.
#reading #personal`,
#gaming #retro`,
color: 'peach'
},
{
key: 'selfhosting',
title: 'Self-Hosting Stack',
content: `Current homelab setup:
content: `All services running behind **Caddy** reverse proxy on a single Hetzner VPS.
**Crumbs** — notes (obviously)
**Vaultwarden** — passwords
**Nextcloud** — files & calendar
### Core Services
- **Crumbs** — notes *(obviously)*
- **Dokploy** — deployment platform
- **Outline** — team wiki
### Monitoring
> Everything that can break *will* break at 3 AM on a Sunday.
Just getting started. More to come.
@@ -145,19 +137,14 @@ Just getting started. More to come.
{
key: 'bretzel',
title: 'Bretzel Ingredients',
content: `The perfect Alsatian bretzel recipe:
- [x] 500g bread flour
content: `- [x] 500g bread flour
- [x] 300ml warm water
- [x] 10g salt
- [ ] 7g dry yeast
- [ ] 30g butter (softened)
- [ ] Baking soda for the bath
- [ ] Coarse salt for topping
#baking #bretzel`,
- [ ] Coarse salt for topping`,
color: 'sand',
pinned: true,
checklistMode: true
}
];
@@ -165,47 +152,64 @@ Just getting started. More to come.
function getVersionHistoryContents(): string[] {
return [
// Version 2: Add Dokploy + Outline
`Current homelab setup:
// Version 2: Add Navidrome + RetroAssembly
`All services running behind **Caddy** reverse proxy on a single Hetzner VPS.
**Crumbs** — notes (obviously)
**Dokploy** — deployment platform
**Outline** — team wiki
**Vaultwarden** — passwords
**Nextcloud** — files & calendar
### Core Services
- **Crumbs** — notes *(obviously)*
- **Dokploy** — deployment platform
- **Outline** — team wiki
- **Navidrome** — music streaming
- **RetroAssembly** — retro game emulation
### Monitoring
> Everything that can break *will* break at 3 AM on a Sunday.
Growing the stack.
#homelab #devops`,
// Version 3: Add Navidrome + Plausible
`Current homelab setup:
// Version 3: Add 42 + Umami
`All services running behind **Caddy** reverse proxy on a single Hetzner VPS.
**Crumbs** — notes (obviously)
**Dokploy** — deployment platform
**Outline** — team wiki
**Navidrome** — music streaming
**Vaultwarden** — passwords
**Nextcloud** — files & calendar
**Plausible** — analytics
### Core Services
- **Crumbs** — notes *(obviously)*
- **42** — holiday budget tracking
- **Dokploy** — deployment platform
- **Outline** — team wiki
- **Navidrome** — music streaming
- **RetroAssembly** — retro game emulation
- **Umami** — privacy-first analytics
### Monitoring
> Everything that can break *will* break at 3 AM on a Sunday.
The stack is getting serious.
#homelab #devops`,
// Version 4: Add 42, final version
`Current homelab setup:
// Version 4: Final version
`All services running behind **Caddy** reverse proxy on a single Hetzner VPS.
**Crumbs** — notes (obviously)
**42** — holiday budget tracking
**Dokploy** — deployment platform
**Outline** — team wiki
**Navidrome** — music streaming
**Vaultwarden** — passwords
**Nextcloud** — files & calendar
**Plausible** — analytics
### Core Services
Everything below daily reverse proxy.
- **Crumbs** — notes *(obviously)*
- **42** — holiday budget tracking
- **Dokploy** — deployment platform
- **Outline** — team wiki
- **Navidrome** — music streaming
- **RetroAssembly** — retro game emulation
- **Umami** — privacy-first analytics
### Monitoring
> Everything that can break *will* break at 3 AM on a Sunday.
Everything below daily reverse proxy. The dream stack is *almost* complete.
#homelab #devops`
];
@@ -260,19 +264,7 @@ export async function seed(page: Page): Promise<void> {
console.log(` version ${i + 2} created for "Self-Hosting Stack"`);
}
// 6. Upload pixel-art images to "Bretzel Ingredients"
await uploadAttachment(page, noteIds['bretzel'], 'bretzel.png', generateBretzelPng(), true);
console.log(' uploaded bretzel.png (featured)');
await uploadAttachment(
page,
noteIds['bretzel'],
'salt-shaker.png',
generateSaltShakerPng(),
false
);
console.log(' uploaded salt-shaker.png');
// 7. Create API keys
// 6. Create API keys
await api(page, 'post', '/api/settings/api-keys', { name: 'Claude Code' });
await api(page, 'post', '/api/settings/api-keys', { name: 'N8N' });
console.log(' API keys created');