project-nomad/admin/app/validators/curated_collections.ts
Chris Sherwood 68f374e3a8 feat: Add dedicated Wikipedia Selector with smart package management
Adds a standalone Wikipedia selection section that appears prominently in both
the Easy Setup Wizard and Content Explorer. Features include:

- Six Wikipedia package options ranging from Quick Reference (313MB) to Complete
  Wikipedia with Full Media (99.6GB)
- Card-based radio selection UI with clear size indicators
- Smart replacement: downloads new package before deleting old one
- Status tracking: shows Installed, Selected, or Downloading badges
- "No Wikipedia" option for users who want to skip or remove Wikipedia

Technical changes:
- New wikipedia_selections database table and model
- New /api/zim/wikipedia and /api/zim/wikipedia/select endpoints
- WikipediaSelector component with consistent styling
- Integration with existing download queue system
- Callback updates status to 'installed' on successful download
- Wikipedia removed from tiered category system to avoid duplication

UI improvements:
- Added section dividers and icons (AI Models, Wikipedia, Additional Content)
- Consistent spacing between major sections in Easy Setup Wizard
- Content Explorer gets matching Wikipedia section with submit button

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:00:51 -08:00

63 lines
1.8 KiB
TypeScript

import vine from '@vinejs/vine'
export const curatedCollectionResourceValidator = vine.object({
title: vine.string(),
description: vine.string(),
url: vine.string().url(),
size_mb: vine.number().min(0).optional(),
})
export const curatedCollectionValidator = vine.object({
slug: vine.string(),
name: vine.string(),
description: vine.string(),
icon: vine.string(),
language: vine.string().minLength(2).maxLength(5),
resources: vine.array(curatedCollectionResourceValidator).minLength(1),
})
export const curatedCollectionsFileSchema = vine.object({
collections: vine.array(curatedCollectionValidator).minLength(1),
})
/**
* For validating the categories file, which has a different structure than the collections file
* since it includes tiers within each category.
*/
export const curatedCategoriesFileSchema = vine.object({
categories: vine.array(
vine.object({
name: vine.string(),
slug: vine.string(),
icon: vine.string(),
description: vine.string(),
language: vine.string().minLength(2).maxLength(5),
tiers: vine.array(
vine.object({
name: vine.string(),
slug: vine.string(),
description: vine.string(),
recommended: vine.boolean().optional(),
includesTier: vine.string().optional(),
resources: vine.array(curatedCollectionResourceValidator),
})
),
})
),
})
/**
* For validating the Wikipedia options file
*/
export const wikipediaOptionSchema = vine.object({
id: vine.string(),
name: vine.string(),
description: vine.string(),
size_mb: vine.number().min(0),
url: vine.string().url().nullable(),
})
export const wikipediaOptionsFileSchema = vine.object({
options: vine.array(wikipediaOptionSchema).minLength(1),
})