You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The repo ships with a single example project (src/content/projects/example-project/) and a single example webring member (src/content/webring/example-member.json). That's enough to show the shape, but not enough to develop or demo against — and the upcoming filter and search features need a realistic spread of values to actually be testable. This ticket adds 8 new project entries and 6 new webring members that are clearly fictional but cover a wide range of field values.
The most important thing here is variety. Filter and search (built in separate tickets) read project domains, year, tech, builtBy names, title, and description. If every seed entry has the same domains/year/tech, those features can't be exercised. So deliberately spread the discriminating fields across the entries (details in the plan).
Keep every human-readable value an obvious placeholder — "Example Project 1", "Example Student 2", https://example.com/... — and use no real student names. Field values like year, domains, tech, and inRing should be a realistic mix, not the same value repeated.
Files you'll edit:
src/content/projects/<slug>/index.md + a cover image — 8 new folders
src/content/webring/<name>.json — 6 new files
Don't edit:
src/content.config.ts — entries must conform to the existing schema, not change it. (Match the fields exactly; the build validates them.) You should look at this file for reference, but it shouldn't need edits.
8 project folders. Each project is a folder under src/content/projects/ containing index.md (frontmatter + a short markdown body) and a co-located cover image. Frontmatter must match the existing example's shape:
---
title: 'Example Project 1'description: 'A short, distinct description — search reads this, so make each one different.'builtBy:
- name: 'Example Student 1'url: 'https://example.com/student-1'tech: ['TypeScript', 'Astro', 'PostgreSQL']year: 2024domains: ['web', 'cybersecurity']github: 'https://github.com/example/example-project-1'deploy: 'https://example-1.example.com'cover: './cover.png'
---
Add a couple of paragraphs of placeholder body text under the frontmatter (the detail page renders it).
Spread the values across the 8 entries — this is the point of the ticket:
domains: it's an array (one or more). Cover the full enum across the set — web, mobile, ai-ml, cybersecurity, game-dev, hardware, systems, infrastructure — and make some entries single-domain and some multi-domain (e.g. ['web', 'cybersecurity']), so the filter's multi-domain matching gets exercised.
year: use a range (e.g. 2021–2025), with at least two entries sharing a year so a year filter returns more than one.
tech: different stacks per project, but let a few share a common item (e.g. several include TypeScript or Python) so a tech search matches multiple cards.
builtBy: mix single-author and multi-author (2–3 people) entries; give some authors a url and leave some without (the url is optional).
deploy: include it on some, omit it on others (it's optional — e.g. a CLI/library has no live site).
Cover images — generated placeholders. Each folder needs its own cover so the cards are visually distinguishable. Generate simple placeholders rather than sourcing real screenshots: a solid Carleton-red (#ef1a1a) or off-white (#f6f5f3) background with the project title centered, exported around 1600×900 (16:9) as a small PNG. Don't reuse one shared image for all eight — varied covers make the grid read like real content. Keep file sizes modest.
Any method works (a quick design-tool export, an online placeholder generator). One easy option is an ImageMagick one-liner (install it here; the command is magick on v7, convert on older v6):
magick -size 1600x900 xc:'#ef1a1a' \
-gravity center -fill white -pointsize 72 \
-annotate 0 'Example Project 1' \
cover.png
Swap the color/title per project. Note -annotate doesn't word-wrap, so keep titles short (or use caption: if you want wrapping).
6 webring members. Each is a JSON file under src/content/webring/, matching the existing example-member.json shape:
Spread the values: a range of grad years, and a mix of inRing: true and inRing: false (the ring graph and generated ring data only include inRing: true, so having some false members proves that filtering works). If the member schema has gained optional fields (e.g. social links) by the time you pick this up, vary those too — include them on some members and omit them on others. Use placeholder names/URLs only.
Validate. Run pnpm check and pnpm build — invalid frontmatter (bad domains value, missing required field, malformed URL) fails here, which is exactly the PR-validation contract. Then pnpm dev and eyeball the gallery and webring directory: distinct covers, varied years/domains/tech, and a couple of members not in the ring.
✅ Acceptance Criteria
8 new project entries exist, each with index.md + its own placeholder cover image, all conforming to the existing schema.
Project domains covers the full enum across the set, with a mix of single- and multi-domain entries; year, tech, and builtBy (single vs multi-author, with/without url) are varied; deploy is present on some and omitted on others.
6 new webring members exist with a range of grad years and a mix of inRing: true/false.
All human-readable values are obvious placeholders (Example Project N / Example Student N / example.com); no real student names.
Covers are distinct per project (not one shared image) and roughly 16:9.
content.config.ts, components, and pages are untouched.
pnpm format:check, pnpm check, and pnpm build all pass.
🧠 Context
The repo ships with a single example project (
src/content/projects/example-project/) and a single example webring member (src/content/webring/example-member.json). That's enough to show the shape, but not enough to develop or demo against — and the upcoming filter and search features need a realistic spread of values to actually be testable. This ticket adds 8 new project entries and 6 new webring members that are clearly fictional but cover a wide range of field values.The most important thing here is variety. Filter and search (built in separate tickets) read project
domains,year,tech,builtBynames,title, anddescription. If every seed entry has the same domains/year/tech, those features can't be exercised. So deliberately spread the discriminating fields across the entries (details in the plan).Keep every human-readable value an obvious placeholder — "Example Project 1", "Example Student 2",
https://example.com/...— and use no real student names. Field values like year, domains, tech, and inRing should be a realistic mix, not the same value repeated.Files you'll edit:
src/content/projects/<slug>/index.md+ a cover image — 8 new folderssrc/content/webring/<name>.json— 6 new filesDon't edit:
src/content.config.ts— entries must conform to the existing schema, not change it. (Match the fields exactly; the build validates them.) You should look at this file for reference, but it shouldn't need edits.example-project/example-memberentries — leave them; you're adding alongside.🛠️ Implementation Plan
8 project folders. Each project is a folder under
src/content/projects/containingindex.md(frontmatter + a short markdown body) and a co-located cover image. Frontmatter must match the existing example's shape:Add a couple of paragraphs of placeholder body text under the frontmatter (the detail page renders it).
Spread the values across the 8 entries — this is the point of the ticket:
domains: it's an array (one or more). Cover the full enum across the set —web,mobile,ai-ml,cybersecurity,game-dev,hardware,systems,infrastructure— and make some entries single-domain and some multi-domain (e.g.['web', 'cybersecurity']), so the filter's multi-domain matching gets exercised.year: use a range (e.g. 2021–2025), with at least two entries sharing a year so a year filter returns more than one.tech: different stacks per project, but let a few share a common item (e.g. several includeTypeScriptorPython) so a tech search matches multiple cards.builtBy: mix single-author and multi-author (2–3 people) entries; give some authors aurland leave some without (theurlis optional).deploy: include it on some, omit it on others (it's optional — e.g. a CLI/library has no live site).Cover images — generated placeholders. Each folder needs its own cover so the cards are visually distinguishable. Generate simple placeholders rather than sourcing real screenshots: a solid Carleton-red (
#ef1a1a) or off-white (#f6f5f3) background with the project title centered, exported around 1600×900 (16:9) as a small PNG. Don't reuse one shared image for all eight — varied covers make the grid read like real content. Keep file sizes modest.Any method works (a quick design-tool export, an online placeholder generator). One easy option is an ImageMagick one-liner (install it here; the command is
magickon v7,converton older v6):Swap the color/title per project. Note
-annotatedoesn't word-wrap, so keep titles short (or usecaption:if you want wrapping).6 webring members. Each is a JSON file under
src/content/webring/, matching the existingexample-member.jsonshape:{ "name": "Example Student 1", "url": "https://example.com/student-1", "year": 2024, "inRing": true }Spread the values: a range of grad
years, and a mix ofinRing: trueandinRing: false(the ring graph and generated ring data only includeinRing: true, so having somefalsemembers proves that filtering works). If the member schema has gained optional fields (e.g. social links) by the time you pick this up, vary those too — include them on some members and omit them on others. Use placeholder names/URLs only.Validate. Run
pnpm checkandpnpm build— invalid frontmatter (baddomainsvalue, missing required field, malformed URL) fails here, which is exactly the PR-validation contract. Thenpnpm devand eyeball the gallery and webring directory: distinct covers, varied years/domains/tech, and a couple of members not in the ring.✅ Acceptance Criteria
index.md+ its own placeholder cover image, all conforming to the existing schema.domainscovers the full enum across the set, with a mix of single- and multi-domain entries;year,tech, andbuiltBy(single vs multi-author, with/withouturl) are varied;deployis present on some and omitted on others.inRing: true/false.content.config.ts, components, and pages are untouched.pnpm format:check,pnpm check, andpnpm buildall pass.