summaryrefslogtreecommitdiff
path: root/scripts/add.ts
diff options
context:
space:
mode:
authoryyamashita <yyamashita@mosquit.one>2026-05-10 00:21:04 +0900
committeryyamashita <yyamashita@mosquit.one>2026-05-10 00:21:04 +0900
commit184e6947707ecdf07dfa3a5cbc6e51cf9440e93a (patch)
tree77a75c2225ad7beafecac15ef90d0cc6cfe5871b /scripts/add.ts
parent0e12e7238f48ffc2a5d35dae059c2f00c7250f3b (diff)
Add members table with membership period and note support
Replace band_artists + member_periods with a single members table (id, band_id, artist_id, role, since, until, note, order_index). Each row represents one membership period, so rejoining artists get multiple rows. Existing band_artists data is auto-migrated on startup. Export format bumped to version 3. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'scripts/add.ts')
-rw-r--r--scripts/add.ts26
1 files changed, 13 insertions, 13 deletions
diff --git a/scripts/add.ts b/scripts/add.ts
index ca53dda..947fd28 100644
--- a/scripts/add.ts
+++ b/scripts/add.ts
@@ -12,21 +12,21 @@
* "artists": [{ "name": "...", "links": [{ "label": "Twitter", "url": "..." }] }],
* "bands": [{
* "name": "...", "area": "...", "status": "active",
- * "artists": [{ "name": "...", "role": "Vocal" }],
+ * "members": [{ "name": "...", "role": "Vocal", "since": "2020", "until": "", "note": "" }],
* "links": [{ "label": "Twitter", "url": "..." }]
* }]
* }
*
- * Artist references in bands can use { "id": "<uuid>" } or { "name": "..." } (looked up by name).
+ * Artist references in members can use { "id": "<uuid>" } or { "name": "..." } (looked up by name).
* Artists listed under "artists" are created first so band references by name work.
* Run from the project root so whois.db is found automatically.
*/
import { readFileSync } from "fs";
-import { createArtist, createBand, listArtists, toSlug } from "../app/lib/db.server";
+import { createArtist, createBand, listArtists, toSlug, type MemberInput } from "../app/lib/db.server";
type LinkInput = { label: string; url: string };
-type ArtistRef = { id?: string; name?: string; role?: string | null };
+type MemberRef = { id?: string; name?: string; role?: string | null; since?: string; until?: string; note?: string };
function parseFlags(argv: string[]): Record<string, string> {
const flags: Record<string, string> = {};
@@ -79,7 +79,7 @@ if (command === "artist") {
description: flags.description || null,
status: flags.status || "active",
links: flags.links ? (JSON.parse(flags.links) as LinkInput[]) : [],
- artists: flags.artists ? (JSON.parse(flags.artists) as { id: string; role: string | null }[]) : [],
+ members: flags.members ? (JSON.parse(flags.members) as MemberInput[]) : [],
message: flags.message || "CLI import",
ip_address: "cli",
});
@@ -100,7 +100,7 @@ if (command === "artist") {
const data = JSON.parse(readFileSync(flags.file, "utf-8")) as {
artists?: { name: string; slug?: string; links?: LinkInput[]; message?: string }[];
- bands?: { name: string; slug?: string; area?: string; description?: string; status?: string; links?: LinkInput[]; artists?: ArtistRef[]; message?: string }[];
+ bands?: { name: string; slug?: string; area?: string; description?: string; status?: string; links?: LinkInput[]; members?: MemberRef[]; message?: string }[];
};
// Build name→id map from existing artists, then create new ones
@@ -125,13 +125,13 @@ if (command === "artist") {
const name = b.name?.trim();
if (!name) continue;
const id = crypto.randomUUID();
- const artists = (b.artists ?? [])
- .map((ar) => {
- const artistId = ar.id ?? (ar.name ? nameToId.get(ar.name) : undefined);
- if (!artistId) { console.warn(` Warning: artist not found: "${ar.name}"`); return null; }
- return { id: artistId, role: ar.role ?? null };
+ const members = (b.members ?? [])
+ .map((mr) => {
+ const artistId = mr.id ?? (mr.name ? nameToId.get(mr.name) : undefined);
+ if (!artistId) { console.warn(` Warning: artist not found: "${mr.name}"`); return null; }
+ return { artist_id: artistId, role: mr.role ?? null, since: mr.since ?? "", until: mr.until ?? "", note: mr.note ?? "" };
})
- .filter((x): x is { id: string; role: string | null } => x !== null);
+ .filter((x): x is MemberInput => x !== null);
try {
createBand({
id, slug: b.slug?.trim() || toSlug(name), name,
@@ -139,7 +139,7 @@ if (command === "artist") {
description: b.description || null,
status: b.status || "active",
links: b.links || [],
- artists,
+ members,
message: b.message || "JSON import",
ip_address: "cli",
});