Skip to content

Commit ab6e4a2

Browse files
assassin808claude
andcommitted
feat: add contributor institution field across docs, data, and website
Add institution to contributor schema in study index.json files, build script, website display, upload form, and contribution docs. Defaults to "Independent Researcher" if left blank. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 549d486 commit ab6e4a2

File tree

10 files changed

+62
-13
lines changed

10 files changed

+62
-13
lines changed

co_website/app/api/contribute/upload/route.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ export async function POST(request: NextRequest) {
139139
const formData = await request.formData();
140140
const file = formData.get("file") as File | null;
141141
const contributorGithub = normalizeGithub(String(formData.get("contributor_github") || ""));
142+
const contributorName = String(formData.get("contributor_name") || "").trim();
143+
const contributorInstitution = String(formData.get("contributor_institution") || "Independent Researcher").trim();
142144
if (!file || !(file instanceof File)) {
143145
return NextResponse.json({ success: false, errors: ["No file provided."] }, { status: 400 });
144146
}
@@ -223,7 +225,7 @@ export async function POST(request: NextRequest) {
223225
authors: Array.isArray(meta.authors) ? meta.authors : [],
224226
year: typeof meta.year === "number" ? meta.year : null,
225227
description: typeof meta.summary === "string" ? meta.summary : typeof meta.abstract === "string" ? meta.abstract : "",
226-
contributors: [{ github: contributorGithub }],
228+
contributors: [{ name: contributorName || undefined, github: contributorGithub, institution: contributorInstitution }],
227229
};
228230
pathToContent.set(
229231
`studies/${studyId}/index.json`,

co_website/app/studies/[studyId]/page.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export async function generateStaticParams() {
1515
}
1616
}
1717

18-
type Contributor = { name: string; github?: string };
18+
type Contributor = { name: string; github?: string; institution?: string };
1919
type StudyEntry = {
2020
study_id: string;
2121
title: string;
@@ -93,7 +93,7 @@ export default async function StudyDetailPage({
9393
<h2 className="text-xl font-semibold text-gray-900 font-serif mb-4">Contributors</h2>
9494
<ul className="flex flex-wrap gap-3">
9595
{study.contributors.map((c) => (
96-
<li key={c.name}>
96+
<li key={c.name} className="flex items-baseline gap-1">
9797
{c.github ? (
9898
<a
9999
href={c.github}
@@ -106,6 +106,9 @@ export default async function StudyDetailPage({
106106
) : (
107107
<span className="text-gray-600">{c.name}</span>
108108
)}
109+
{c.institution && (
110+
<span className="text-sm text-gray-400">({c.institution})</span>
111+
)}
109112
</li>
110113
))}
111114
</ul>

co_website/app/studies/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { promises as fs } from "fs";
22
import path from "path";
33
import Link from "next/link";
44

5-
type Contributor = { name: string; github?: string };
5+
type Contributor = { name: string; github?: string; institution?: string };
66
type StudySummary = {
77
study_id: string;
88
title: string;

co_website/components/ContributeUploadForm.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ type Result = { success: true; pr_url: string } | { success: false; errors: stri
77
export default function ContributeUploadForm() {
88
const [file, setFile] = useState<File | null>(null);
99
const [contributorGithub, setContributorGithub] = useState("");
10+
const [contributorName, setContributorName] = useState("");
11+
const [contributorInstitution, setContributorInstitution] = useState("");
1012
const [dragActive, setDragActive] = useState(false);
1113
const [loading, setLoading] = useState(false);
1214
const [result, setResult] = useState<Result | null>(null);
@@ -48,6 +50,8 @@ export default function ContributeUploadForm() {
4850
const formData = new FormData();
4951
formData.append("file", file);
5052
formData.append("contributor_github", contributorGithub.trim());
53+
formData.append("contributor_name", contributorName.trim());
54+
formData.append("contributor_institution", contributorInstitution.trim() || "Independent Researcher");
5155
try {
5256
const res = await fetch("/api/contribute/upload", {
5357
method: "POST",
@@ -62,11 +66,19 @@ export default function ContributeUploadForm() {
6266
setLoading(false);
6367
}
6468
},
65-
[file, contributorGithub]
69+
[file, contributorGithub, contributorName, contributorInstitution]
6670
);
6771

6872
return (
6973
<form onSubmit={handleSubmit} className="space-y-4">
74+
<input
75+
type="text"
76+
value={contributorName}
77+
onChange={(e) => setContributorName(e.target.value)}
78+
placeholder="Your name (required)"
79+
className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm text-gray-900 placeholder:text-gray-400 focus:border-cyan-500 focus:outline-none"
80+
required
81+
/>
7082
<input
7183
type="text"
7284
value={contributorGithub}
@@ -75,6 +87,13 @@ export default function ContributeUploadForm() {
7587
className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm text-gray-900 placeholder:text-gray-400 focus:border-cyan-500 focus:outline-none"
7688
required
7789
/>
90+
<input
91+
type="text"
92+
value={contributorInstitution}
93+
onChange={(e) => setContributorInstitution(e.target.value)}
94+
placeholder="Institution (leave blank for Independent Researcher)"
95+
className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm text-gray-900 placeholder:text-gray-400 focus:border-cyan-500 focus:outline-none"
96+
/>
7897
<div
7998
onDragEnter={handleDrag}
8099
onDragLeave={handleDrag}

co_website/data/studies_index.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@
146146
"contributors": [
147147
{
148148
"name": "Guankai Zhai",
149-
"github": "https://github.com/zgk2003"
149+
"github": "https://github.com/zgk2003",
150+
"institution": "Stanford University"
150151
}
151152
]
152153
},
@@ -163,7 +164,8 @@
163164
"contributors": [
164165
{
165166
"name": "Yuanjun Feng",
166-
"github": "https://github.com/diana3135"
167+
"github": "https://github.com/diana3135",
168+
"institution": "University of Lausanne"
167169
}
168170
]
169171
}

docs/build_study_files.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,13 @@ This file lives at the root of your study directory. The website reads it for th
2626

2727
**Required fields:** `title` (string), `authors` (string[]), `year` (number | null), `description` (string) — all non-empty.
2828

29-
**Optional:** `contributors` — array of `{"name": "...", "github": "..."}` so you get credit on the site.
29+
**Optional:** `contributors` — array of objects so you get credit on the site.
30+
31+
| Field | Required | Description |
32+
|-------|----------|-------------|
33+
| `name` | Yes | Your full name |
34+
| `github` | No | Your GitHub profile URL |
35+
| `institution` | No | Your university or organization. Use `"Independent Researcher"` if unaffiliated |
3036

3137
```json
3238
{
@@ -35,7 +41,11 @@ This file lives at the root of your study directory. The website reads it for th
3541
"year": 1977,
3642
"description": "People overestimate how many others share their beliefs and behaviors.",
3743
"contributors": [
38-
{ "name": "Your Name", "github": "https://github.com/your-username" }
44+
{
45+
"name": "Your Name",
46+
"github": "https://github.com/your-username",
47+
"institution": "Stanford University"
48+
}
3949
]
4050
}
4151
```

docs/submit_study.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,20 @@ git push origin contrib-yourgithubid-013
3434

3535
Head to GitHub and open a **Pull Request** targeting the `dev` branch. Include a brief description of the study and any notes for reviewers.
3636

37-
Make sure your `index.json` includes a `contributors` field with your name and GitHub link — CI will verify this matches your GitHub account:
37+
Make sure your `index.json` includes a `contributors` field with your name, GitHub link, and institution — CI will verify your GitHub ID matches the PR author:
3838

3939
```json
4040
"contributors": [
41-
{ "name": "Your Name", "github": "https://github.com/your-username" }
41+
{
42+
"name": "Your Name",
43+
"github": "https://github.com/your-username",
44+
"institution": "Stanford University"
45+
}
4246
]
4347
```
4448

49+
If you are not affiliated with a university or organization, use `"Independent Researcher"` as your institution.
50+
4551
### What happens after you hit "Create PR"
4652

4753
- **CI** runs `verify_study.sh` and `build_studies_index.py` automatically. It also checks that the `contributors` GitHub ID in your `index.json` matches the PR author.

scripts/build_studies_index.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ def build_index() -> list[dict]:
5757
if c.get("github"):
5858
gh = str(c["github"]).strip()
5959
nc["github"] = gh if gh.startswith("http") else f"https://github.com/{gh.lstrip('/')}"
60+
if c.get("institution"):
61+
nc["institution"] = c["institution"]
6062
contributors.append(nc)
6163
entry = {
6264
"study_id": study_dir.name,

studies/study_013/index.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"contributors": [
1111
{
1212
"name": "Guankai Zhai",
13-
"github": "https://github.com/zgk2003"
13+
"github": "https://github.com/zgk2003",
14+
"institution": "Stanford University"
1415
}
1516
]
1617
}

studies/study_014/index.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
"year": 2011,
99
"description": "This study investigates how auctioneers set reserve prices in second-price sealed-bid auctions. A well-established theoretical result, assuming risk neutrality of the seller, is that the optimal reserve price should not depend on the number of participating bidders. In a set of controlled laboratory experiments, it is found that seller behavior often deviates from the theoretical benchmarks: sellers systematically increase their reserve prices as the number of bidders grows, contrary to standard auction theory.",
1010
"contributors": [
11-
{ "name": "Yuanjun Feng", "github": "https://github.com/diana3135" }
11+
{
12+
"name": "Yuanjun Feng",
13+
"github": "https://github.com/diana3135",
14+
"institution": "University of Lausanne"
15+
}
1216
]
1317
}

0 commit comments

Comments
 (0)