Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c93aace56b | |||
| 9d530dd4d3 |
@@ -0,0 +1,136 @@
|
||||
# Nextcraft — ARCHITECTURE.md
|
||||
|
||||
## Overview
|
||||
|
||||
Nextcraft v0.1 is a high-fidelity UI/UX prototype built as a TypeScript monorepo using pnpm workspaces and turborepo. The prototype consists of a single Next.js application with route groups for each surface (Learner, Marketplace, Employer Dashboard, Admin), backed by a shared component library, typed mock data layer, and shared types package.
|
||||
|
||||
**No backend, no database, no authentication logic.** All data is static/mock. The architecture is designed to be replaced piece-by-piece with real backend services in future milestones.
|
||||
|
||||
### Confirmed Technology Stack (Research Findings)
|
||||
|
||||
| Technology | Version | Purpose |
|
||||
|------------|---------|---------|
|
||||
| Node.js | v24.15.0 | Runtime |
|
||||
| pnpm | 12.3.4 | Package manager + workspaces |
|
||||
| turborepo | latest | Build orchestration |
|
||||
| Next.js | latest (App Router) | Web application framework |
|
||||
| React | 19+ | UI library |
|
||||
| TypeScript | 5.x | Type system |
|
||||
| Tailwind CSS | v4 | Utility-first CSS framework |
|
||||
| lucide-react | latest | Icon system |
|
||||
| recharts | latest | Charts for employer/admin dashboards |
|
||||
| @xyflow/react (react-flow) | latest | Competency graph viewer in admin surface |
|
||||
| Inter font | via next/font | Typography |
|
||||
| ESLint | via Next.js | Linting |
|
||||
| Prettier | latest | Code formatting |
|
||||
|
||||
### Architecture Decisions from Research
|
||||
|
||||
1. **Next.js App Router with route groups** — `(learner)`, `(marketplace)`, `(employer)`, `(admin)` provide clean URL separation without affecting paths
|
||||
2. **Tailwind CSS v4** — Configured via `@theme` in CSS, no `tailwind.config.js` needed (v4 paradigm shift). Dark mode via `class` strategy.
|
||||
3. **Server components by default** — All pages are server components. Client components only for interactive elements (filters, search, chat, graph viewer, dark mode toggle)
|
||||
4. **Mock data as ES modules** — Typed TS files exported from `packages/mock-data`. No JSON files — all mock data is programmatically generated for richer structure.
|
||||
5. **react-flow (@xyflow/react)** — Confirmed for competency graph viewer. Provides interactive node/edge rendering with built-in controls.
|
||||
6. **recharts** — Confirmed for analytics dashboards. Responsive, composable, integrates well with React server components.
|
||||
7. **pnpm workspaces** — `apps/web` + `packages/ui` + `packages/mock-data` + `packages/types`. Shared deps hoisted.
|
||||
|
||||
---
|
||||
|
||||
## Components
|
||||
|
||||
### apps/web — Next.js Application
|
||||
|
||||
| Component | Description | Boundaries | Depends On |
|
||||
|-----------|-------------|------------|------------|
|
||||
| `app/(learner)/` | Learner surface route group: landing, catalog, competency stack, dashboard, byte viewer, sandbox mockup, assessment mockup | Learner-only routes and layouts | packages/ui, packages/mock-data, packages/types |
|
||||
| `app/(marketplace)/` | Marketplace surface route group: job board, job detail, employer profile, search/filter, pricing | Marketplace-only routes and layouts | packages/ui, packages/mock-data, packages/types |
|
||||
| `app/(employer)/` | Employer dashboard route group: overview, talent search, candidate profile, posting management | Employer-only routes and layouts | packages/ui, packages/mock-data, packages/types |
|
||||
| `app/(admin)/` | Admin surface route group: overview, learner management, competency graph viewer, moderation | Admin-only routes and layouts | packages/ui, packages/mock-data, packages/types |
|
||||
| `app/layout.tsx` | Root layout: theme provider, navigation shell, responsive container | All routes | packages/ui |
|
||||
| `components/` | Surface-specific components (not shared across surfaces) | Per-surface only | packages/ui |
|
||||
|
||||
### packages/ui — Shared Component Library
|
||||
|
||||
| Component | Description | Boundaries | Depends On |
|
||||
|-----------|-------------|------------|------------|
|
||||
| `design-tokens/` | CSS custom properties: color palette, typography scale, spacing system, breakpoints, shadows, radii | Foundation layer — no dependencies | None |
|
||||
| `primitives/` | Button, Input, Card, Badge, Avatar, Dialog, Tabs, Progress, Tooltip, Skeleton, Toast | Atomic UI components | design-tokens |
|
||||
| `composites/` | Navigation, Table, SearchBar, FilterPanel, ChatInterface, GraphViewer, ArtifactCard, CompetencyBadge, JobCard, CandidateCard, MetricCard | Composite components built from primitives | primitives, packages/types |
|
||||
| `layouts/` | Container, Grid, Sidebar, SplitPanel, DashboardLayout | Layout components | primitives, design-tokens |
|
||||
| `theme/` | Theme provider, CSS variable overrides per surface (learner, marketplace, employer, admin) | Theme context | design-tokens |
|
||||
|
||||
### packages/mock-data — Mock Data Layer
|
||||
|
||||
| Component | Description | Boundaries | Depends On |
|
||||
|-----------|-------------|------------|------------|
|
||||
| `competency-stacks.ts` | 5 competency stacks (AI Orchestration Engineer, AI Safety & Governance, Human-AI Product Designer, AI-Augmented Field Operator, Computational Sciences), each with 12-18 competencies | Typed mock data | packages/types |
|
||||
| `jobs.ts` | 20+ mock AI-era job listings with skills, seniority, salary, match scores | Typed mock data | packages/types |
|
||||
| `candidates.ts` | 15+ mock candidate profiles with artifacts, process traces, defense scores, microcredentials | Typed mock data | packages/types |
|
||||
| `employers.ts` | 10+ mock employer profiles with logos, descriptions, open positions | Typed mock data | packages/types |
|
||||
| `learner-progress.ts` | Mock learner progress data: active competencies, completion percentages, recent artifacts | Typed mock data | packages/types |
|
||||
| `ai-tutor-responses.ts` | Pre-scripted AI tutor chat responses for Coach and Tutor agent mockups | Typed mock data | packages/types |
|
||||
|
||||
### packages/types — Shared Types
|
||||
|
||||
| Component | Description | Boundaries | Depends On |
|
||||
|-----------|-------------|------------|------------|
|
||||
| `domain.ts` | Competency, CompetencyStack, Microcredential, Artifact, ProcessTrace, OralDefense, AssessmentRubric | Domain types | None |
|
||||
| `marketplace.ts` | Job, Employer, Candidate, JobPosting, TalentMatch, SearchFilter | Marketplace types | None |
|
||||
| `user.ts` | Learner, Admin, EmployerUser, AgeGroup, Role | User types | None |
|
||||
| `ui.ts` | Component props, theme config, breakpoint definitions | UI types | None |
|
||||
|
||||
---
|
||||
|
||||
## Data Flow
|
||||
|
||||
```
|
||||
[Mock Data Layer] ──typed──> [Shared Types] <──typed──> [UI Components]
|
||||
│ │
|
||||
│ │
|
||||
▼ ▼
|
||||
[Next.js Route Groups] [Surface Components]
|
||||
(learner)/ (marketplace)/ (employer)/ (admin)/
|
||||
│ │ │ │
|
||||
└──────────────────┴─────────────────┴───────────────┘
|
||||
│
|
||||
▼
|
||||
[Root Layout + Theme Provider]
|
||||
│
|
||||
▼
|
||||
[Responsive Navigation Shell]
|
||||
```
|
||||
|
||||
All data flows from the mock data layer through typed imports into Next.js route handlers / server components, which pass data as props to UI components. No client-side data fetching, no API routes, no server actions in v0.1.
|
||||
|
||||
---
|
||||
|
||||
## Build Order
|
||||
|
||||
1. **Monorepo scaffolding** — pnpm-workspace.yaml, turbo.json, tsconfig.json, package.json, Next.js app initialization
|
||||
2. **Shared types** — packages/types with all domain, marketplace, user, and UI type definitions
|
||||
3. **Mock data layer** — packages/mock-data with typed mock data for all surfaces
|
||||
4. **Design tokens** — packages/ui/design-tokens with CSS custom properties
|
||||
5. **UI primitives** — Button, Input, Card, Badge, Avatar, Dialog, Tabs, Progress, Tooltip, Skeleton, Toast
|
||||
6. **Root layout + navigation shell** — Root layout with theme provider, responsive navigation, role switcher
|
||||
7. **UI composites** — Navigation, Table, SearchBar, FilterPanel, ChatInterface, GraphViewer, ArtifactCard, CompetencyBadge, JobCard, CandidateCard, MetricCard
|
||||
8. **Learner surface routes** — Landing, catalog, competency stack, dashboard, byte viewer, sandbox mockup, assessment mockup
|
||||
9. **Marketplace surface routes** — Job board, job detail, employer profile, search/filter, pricing
|
||||
10. **Employer dashboard routes** — Overview, talent search, candidate profile, posting management
|
||||
11. **Admin surface routes** — Overview, learner management, competency graph viewer, moderation
|
||||
12. **Polish + integration** — Cross-surface navigation, responsive QA, visual consistency, Storybook
|
||||
|
||||
---
|
||||
|
||||
## Future Architecture (Post-v0.1, for reference)
|
||||
|
||||
The v0.1 prototype is designed to be replaced piece-by-piece with real backend services:
|
||||
|
||||
- **Mock data → PostgreSQL + Drizzle ORM** — mock data files replaced with database queries via repository layer
|
||||
- **Static routes → Fastify API + Next.js SSR** — API routes replaced with Fastify backend services
|
||||
- **Mock AI tutor → Python FastAPI AI services** — Chat interface mockup replaced with real AI agent microservices
|
||||
- **Mock assessment → Assessment engine** — Assessment mockup replaced with process-trace grading + oral defense engine
|
||||
- **No auth → Identity verification + age-gating** — Registration flow mockup replaced with real KYC and age verification
|
||||
- **No search → Semantic vector search (pgvector)** — Filter UI replaced with vector similarity search
|
||||
- **No payments → Payment processing** — Pricing page replaced with real subscription/payment flows
|
||||
|
||||
The monorepo structure (apps/web + packages/*) is designed to accommodate additional apps (e.g., apps/api, apps/ai-service) in future milestones without restructuring.
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"phase": 1,
|
||||
"stage": "execute",
|
||||
"milestone": "v0.1",
|
||||
"phase_role": "execution",
|
||||
"attempts": 0,
|
||||
"updated_at": "2026-09-10T21:34:00Z"
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
# Nextcraft — PERSONAS.md
|
||||
|
||||
## Persona Roster
|
||||
|
||||
### lead-developer
|
||||
```yaml
|
||||
active: true
|
||||
phase_specific: false
|
||||
reason: Coordinates task decomposition across surfaces, resolves conflicts between frontend and data personas
|
||||
domain: coordination
|
||||
frameworks:
|
||||
- next.js
|
||||
- turborepo
|
||||
- pnpm
|
||||
constraints:
|
||||
- pragmatic
|
||||
- battle-tested defaults
|
||||
- monorepo-architecture
|
||||
territory:
|
||||
- "**/package.json"
|
||||
- "**/turbo.json"
|
||||
- "**/pnpm-workspace.yaml"
|
||||
- "**/tsconfig.json"
|
||||
```
|
||||
|
||||
### frontend-engineer
|
||||
```yaml
|
||||
active: true
|
||||
phase_specific: false
|
||||
reason: Primary persona for v0.1 — all 28 REQ-IDs are UI/frontend work. Owns all page components, layouts, and surface-specific UI.
|
||||
domain: frontend
|
||||
frameworks:
|
||||
- react
|
||||
- next.js
|
||||
- tailwindcss
|
||||
- lucide-react
|
||||
- recharts
|
||||
- react-flow
|
||||
constraints:
|
||||
- component-first
|
||||
- server-components-default
|
||||
- minimal-client-js
|
||||
- mock-data-only
|
||||
- responsive-all-breakpoints
|
||||
- dark-mode-support
|
||||
territory:
|
||||
- "apps/web/**"
|
||||
- "packages/ui/**"
|
||||
- "packages/mock-data/**"
|
||||
- "packages/types/**"
|
||||
```
|
||||
|
||||
### data-engineer
|
||||
```yaml
|
||||
active: true
|
||||
phase_specific: false
|
||||
reason: Owns mock data layer schema and typed definitions. No real database in v0.1, but data structures must be well-typed for future migration.
|
||||
domain: data
|
||||
frameworks:
|
||||
- typescript
|
||||
constraints:
|
||||
- schema-first
|
||||
- type-safe
|
||||
- migration-ready
|
||||
- mock-data-only
|
||||
territory:
|
||||
- "packages/types/**"
|
||||
- "packages/mock-data/**"
|
||||
```
|
||||
|
||||
### backend-engineer
|
||||
```yaml
|
||||
active: false
|
||||
phase_specific: false
|
||||
reason: No backend in v0.1. All data is mock/static. Backend persona deactivated until v0.2+ when API services are needed.
|
||||
domain: backend
|
||||
frameworks: []
|
||||
constraints: []
|
||||
territory: []
|
||||
```
|
||||
|
||||
### security-auditor
|
||||
```yaml
|
||||
active: false
|
||||
phase_specific: false
|
||||
reason: No auth, no API, no real data in v0.1. Security review handled by verifier's STRIDE analysis layer. No dedicated security persona needed for UI prototype.
|
||||
domain: security
|
||||
frameworks: []
|
||||
constraints: []
|
||||
territory: []
|
||||
```
|
||||
|
||||
## Custom Personas
|
||||
|
||||
### design-system-engineer
|
||||
```yaml
|
||||
active: true
|
||||
phase_specific: false
|
||||
reason: Custom persona for v0.1 — owns the shared component library, design tokens, and visual consistency. Combines frontend expertise with design system ownership.
|
||||
domain: frontend
|
||||
frameworks:
|
||||
- tailwindcss
|
||||
- storybook
|
||||
- lucide-react
|
||||
constraints:
|
||||
- design-token-driven
|
||||
- wcag-aa-contrast
|
||||
- dark-mode-required
|
||||
- consistent-across-surfaces
|
||||
territory:
|
||||
- "packages/ui/**"
|
||||
```
|
||||
|
||||
## Phase-Specific Personas
|
||||
|
||||
None for v0.1. All active personas span the entire milestone.
|
||||
|
||||
## Territory Conflict Resolution
|
||||
|
||||
| Conflict | Resolution |
|
||||
|----------|-----------|
|
||||
| frontend-engineer vs data-engineer (packages/types, packages/mock-data) | data-engineer owns type definitions and mock data schema; frontend-engineer consumes them. If changes needed, data-engineer updates types first. |
|
||||
| frontend-engineer vs design-system-engineer (packages/ui) | design-system-engineer owns design tokens and primitive components; frontend-engineer owns composite components and page-level UI. |
|
||||
| lead-developer vs any | lead-developer coordinates only, does not directly modify code files. |
|
||||
@@ -0,0 +1,398 @@
|
||||
# Nextcraft v0.1 — PLAN.md
|
||||
|
||||
## Overview
|
||||
|
||||
This plan covers execution phases 1-6 of milestone v0.1 (UI/UX Prototype). Each phase is a vertical slice that produces a demoable milestone. Phases are ordered by dependency — later phases build on earlier ones.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Project Scaffolding
|
||||
|
||||
**Requirements:** REQ-001, REQ-002, REQ-003, REQ-004, REQ-005
|
||||
**Persona:** design-system-engineer (Wave 1), data-engineer (Wave 1), frontend-engineer (Wave 2)
|
||||
**Goal:** Monorepo builds, dev server starts, component library has all primitives, mock data typed, routing works
|
||||
|
||||
### Wave 1: Foundation (parallel — no shared file conflicts)
|
||||
|
||||
#### Task 1-1-01: Monorepo scaffolding
|
||||
- **Persona:** design-system-engineer
|
||||
- **Files:** `package.json`, `pnpm-workspace.yaml`, `turbo.json`, `tsconfig.json`, `.npmrc`
|
||||
- **Action:** Create root monorepo config. pnpm workspaces pointing to `apps/*` and `packages/*`. Turborepo with build/dev/lint/typecheck pipelines. Root tsconfig with path aliases.
|
||||
- **Verify:** `pnpm install` succeeds; workspace packages detected
|
||||
- **Done:** `pnpm list -r` shows all workspace packages
|
||||
|
||||
#### Task 1-1-02: Shared types package
|
||||
- **Persona:** data-engineer
|
||||
- **Files:** `packages/types/package.json`, `packages/types/tsconfig.json`, `packages/types/domain.ts`, `packages/types/marketplace.ts`, `packages/types/user.ts`, `packages/types/ui.ts`, `packages/types/index.ts`
|
||||
- **Action:** Create all shared TypeScript type definitions: Competency, CompetencyStack, Microcredential, Artifact, ProcessTrace, OralDefense, AssessmentRubric, Job, Employer, Candidate, JobPosting, TalentMatch, SearchFilter, Learner, Admin, EmployerUser, AgeGroup, Role, plus UI types (ComponentProps, ThemeConfig, Breakpoint).
|
||||
- **Verify:** `pnpm typecheck` passes in packages/types
|
||||
- **Done:** All types exported from index.ts; no type errors
|
||||
|
||||
#### Task 1-1-03: Mock data package
|
||||
- **Persona:** data-engineer
|
||||
- **Files:** `packages/mock-data/package.json`, `packages/mock-data/tsconfig.json`, `packages/mock-data/competency-stacks.ts`, `packages/mock-data/jobs.ts`, `packages/mock-data/candidates.ts`, `packages/mock-data/employers.ts`, `packages/mock-data/learner-progress.ts`, `packages/mock-data/ai-tutor-responses.ts`, `packages/mock-data/index.ts`
|
||||
- **Action:** Create typed mock data: 5 competency stacks (AI Orchestration Engineer with 15 competencies, AI Safety & Governance with 14, Human-AI Product Designer with 13, AI-Augmented Field Operator with 12, Computational Sciences with 16). 20+ mock jobs. 15+ mock candidates. 10+ mock employers. Mock learner progress. Pre-scripted AI tutor responses.
|
||||
- **Verify:** All mock data matches types from packages/types; `pnpm typecheck` passes
|
||||
- **Done:** All mock data exported from index.ts; types match
|
||||
|
||||
### Wave 2: UI Foundation (depends on Wave 1)
|
||||
|
||||
#### Task 1-2-01: Next.js app initialization
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/package.json`, `apps/web/tsconfig.json`, `apps/web/next.config.ts`, `apps/web/app/layout.tsx`, `apps/web/app/page.tsx`, `apps/web/app/globals.css`
|
||||
- **Action:** Initialize Next.js app with App Router, TypeScript, Tailwind CSS v4. Configure Inter font via next/font. Set up path aliases to packages. Create root layout with theme provider. Create placeholder home page.
|
||||
- **Verify:** `pnpm dev` starts; `pnpm build` succeeds; page renders at localhost:3000
|
||||
- **Done:** Next.js app runs with Tailwind CSS and Inter font
|
||||
|
||||
#### Task 1-2-02: Design tokens and Tailwind config
|
||||
- **Persona:** design-system-engineer
|
||||
- **Files:** `packages/ui/package.json`, `packages/ui/tsconfig.json`, `packages/ui/src/index.ts`, `packages/ui/src/tokens/index.ts`, `apps/web/app/globals.css` (update)
|
||||
- **Action:** Create packages/ui package. Define design tokens as TypeScript constants and CSS custom properties: color palette (indigo/violet primary, emerald accent, slate neutral, dark mode variants), typography scale (12px-48px), spacing system (4px base), breakpoints (375px, 768px, 1280px), shadows, radii. Configure Tailwind v4 `@theme` with custom colors.
|
||||
- **Verify:** Design tokens importable from packages/ui; Tailwind classes work with custom colors
|
||||
- **Done:** `import { tokens } from '@nextcraft/ui'` works; `bg-primary-500` class works
|
||||
|
||||
#### Task 1-2-03: UI primitives
|
||||
- **Persona:** design-system-engineer
|
||||
- **Files:** `packages/ui/src/primitives/button.tsx`, `packages/ui/src/primitives/input.tsx`, `packages/ui/src/primitives/card.tsx`, `packages/ui/src/primitives/badge.tsx`, `packages/ui/src/primitives/avatar.tsx`, `packages/ui/src/primitives/dialog.tsx`, `packages/ui/src/primitives/tabs.tsx`, `packages/ui/src/primitives/progress.tsx`, `packages/ui/src/primitives/tooltip.tsx`, `packages/ui/src/primitives/skeleton.tsx`, `packages/ui/src/primitives/toast.tsx`, `packages/ui/src/primitives/index.ts`
|
||||
- **Action:** Create all 12 primitive components. Each is a React component with TypeScript props, Tailwind styling, forwardRef, and size variants. Button (primary, secondary, ghost, destructive). Input (text, search, with label). Card (with header, body, footer slots). Badge (default, success, warning, error). Avatar (with image, fallback, sizes). Dialog (modal, with overlay). Tabs (horizontal, with active indicator). Progress (linear, circular). Tooltip (on hover). Skeleton (shimmer). Toast (with variants).
|
||||
- **Verify:** All primitives importable; each renders without error; variants work
|
||||
- **Done:** 12 primitives exported from packages/ui
|
||||
|
||||
#### Task 1-2-04: Layout components
|
||||
- **Persona:** design-system-engineer
|
||||
- **Files:** `packages/ui/src/layouts/container.tsx`, `packages/ui/src/layouts/grid.tsx`, `packages/ui/src/layouts/sidebar.tsx`, `packages/ui/src/layouts/split-panel.tsx`, `packages/ui/src/layouts/dashboard-layout.tsx`, `packages/ui/src/layouts/index.ts`
|
||||
- **Action:** Create layout components. Container (max-width variants: sm, md, lg, xl, full). Grid (responsive cols prop). Sidebar (collapsible, with nav items). SplitPanel (resizable divider). DashboardLayout (sidebar + main content area).
|
||||
- **Verify:** Layout components render; responsive breakpoints work
|
||||
- **Done:** 5 layout components exported
|
||||
|
||||
#### Task 1-2-05: Root layout + navigation shell
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/layout.tsx` (update), `apps/web/components/navigation-shell.tsx`, `apps/web/components/role-switcher.tsx`, `apps/web/components/header.tsx`, `apps/web/components/footer.tsx`
|
||||
- **Action:** Update root layout with theme provider (dark mode toggle), Inter font, responsive navigation shell. Create role switcher (learner/employer/admin toggle in header). Create header with logo, nav links, role switcher, dark mode toggle. Create footer with links.
|
||||
- **Verify:** Dark mode toggle works; role switcher navigates between surfaces; responsive at 375px/768px/1280px
|
||||
- **Done:** Navigation shell renders on all pages; role switcher functional
|
||||
|
||||
#### Task 1-2-06: Route groups with placeholder pages
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(learner)/page.tsx`, `apps/web/app/(learner)/layout.tsx`, `apps/web/app/(marketplace)/page.tsx`, `apps/web/app/(marketplace)/layout.tsx`, `apps/web/app/(employer)/page.tsx`, `apps/web/app/(employer)/layout.tsx`, `apps/web/app/(admin)/page.tsx`, `apps/web/app/(admin)/layout.tsx`
|
||||
- **Action:** Create route groups with layouts for each surface. Each layout has surface-specific navigation. Placeholder pages with surface name and brief description.
|
||||
- **Verify:** Navigation to / (learner), /marketplace, /employer, /admin works
|
||||
- **Done:** 4 route groups with layouts and placeholder pages
|
||||
|
||||
### Must-Haves (Phase 1)
|
||||
- [ ] `pnpm install` succeeds
|
||||
- [ ] `pnpm dev` starts Next.js dev server
|
||||
- [ ] `pnpm build` succeeds
|
||||
- [ ] `pnpm typecheck` passes
|
||||
- [ ] 12 UI primitives importable from `@nextcraft/ui`
|
||||
- [ ] Mock data typed and importable from `@nextcraft/mock-data`
|
||||
- [ ] Types importable from `@nextcraft/types`
|
||||
- [ ] 4 route groups with layouts
|
||||
- [ ] Dark mode toggle works
|
||||
- [ ] Role switcher navigates between surfaces
|
||||
- [ ] Responsive at 375px, 768px, 1280px
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Learner Surface UI
|
||||
|
||||
**Requirements:** REQ-006, REQ-007, REQ-008, REQ-009, REQ-010, REQ-011, REQ-012
|
||||
**Persona:** frontend-engineer
|
||||
**Goal:** All 7 learner pages render with mock data; navigation works; responsive
|
||||
|
||||
### Wave 1: Core learner pages
|
||||
|
||||
#### Task 2-1-01: Landing page
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(learner)/page.tsx`, `apps/web/components/learner/hero.tsx`, `apps/web/components/learner/how-it-works.tsx`, `apps/web/components/learner/program-highlights.tsx`, `apps/web/components/learner/testimonials.tsx`
|
||||
- **Action:** Build landing page with hero section (headline, subheadline, CTA buttons), how-it-works section (Byte→Build→Demonstrate→Defend visual flow), program highlights (3-4 featured competency stacks), testimonials mockup (3 cards with avatar, quote, name, role), CTA to program catalog.
|
||||
- **Verify:** Landing page renders with all sections; CTA links to /catalog
|
||||
- **Done:** Landing page complete
|
||||
|
||||
#### Task 2-1-02: Program catalog
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(learner)/catalog/page.tsx`, `apps/web/components/learner/stack-card.tsx`
|
||||
- **Action:** Build program catalog page. Grid of 5 competency stack cards. Each card: stack name, role description, competency count, estimated duration, microcredential count, "Explore" button linking to stack detail.
|
||||
- **Verify:** 5 stack cards render with mock data; clicking "Explore" navigates to stack detail
|
||||
- **Done:** Catalog page complete
|
||||
|
||||
#### Task 2-1-03: Competency stack view
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(learner)/catalog/[stackId]/page.tsx`, `apps/web/components/learner/competency-list.tsx`, `apps/web/components/learner/competency-item.tsx`, `apps/web/components/learner/microcredential-badge.tsx`
|
||||
- **Action:** Build competency stack detail page. Header with stack name, role, description. List of 12-18 competencies. Each competency: name, description, status (locked/available/in-progress/mastered), microcredential badge, progress bar. Clicking a competency navigates to byte tutorial viewer.
|
||||
- **Verify:** Competencies render with correct status indicators; microcredential badges display
|
||||
- **Done:** Stack detail page complete
|
||||
|
||||
#### Task 2-1-04: Learner dashboard
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(learner)/dashboard/page.tsx`, `apps/web/components/learner/dashboard/active-competencies.tsx`, `apps/web/components/learner/dashboard/progress-graph.tsx`, `apps/web/components/learner/dashboard/recent-artifacts.tsx`, `apps/web/components/learner/dashboard/upcoming-defenses.tsx`, `apps/web/components/learner/dashboard/ai-tutor-chat.tsx`, `apps/web/components/learner/dashboard/milestone-tracker.tsx`
|
||||
- **Action:** Build learner dashboard. Active competencies panel (current stack, progress). Progress graph (recharts area chart showing mastery over time). Recent artifacts (cards with artifact name, type, date). Upcoming defenses (list with competency name, date, status). AI tutor chat mockup (chat interface with pre-scripted responses, message input). Milestone tracker (progress through stack).
|
||||
- **Verify:** Dashboard renders all panels; AI tutor chat displays scripted responses on "send"
|
||||
- **Done:** Dashboard complete
|
||||
|
||||
### Wave 2: Detail views
|
||||
|
||||
#### Task 2-2-01: Byte tutorial viewer
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(learner)/learn/[competencyId]/page.tsx`, `apps/web/components/learner/byte-viewer/concept-panel.tsx`, `apps/web/components/learner/byte-viewer/worked-example.tsx`, `apps/web/components/learner/byte-viewer/viewer-tabs.tsx`
|
||||
- **Action:** Build byte tutorial viewer. Layout: left panel (concept text, 3-7 minute read), right panel (worked example with code/design/simulation viewer mockup). Tabbed viewer (code, design, simulation). Navigation to build sandbox.
|
||||
- **Verify:** Tutorial viewer renders with concept and example panels; tabs switch
|
||||
- **Done:** Byte tutorial viewer complete
|
||||
|
||||
#### Task 2-2-02: Build sandbox mockup
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(learner)/build/[competencyId]/page.tsx`, `apps/web/components/learner/sandbox/toolbar.tsx`, `apps/web/components/learner/sandbox/file-explorer.tsx`, `apps/web/components/learner/sandbox/editor-area.tsx`, `apps/web/components/learner/sandbox/telemetry-sidebar.tsx`
|
||||
- **Action:** Build sandbox mockup IDE UI. Layout: top toolbar (run, save, submit buttons), left sidebar (file explorer tree), center (code editor area with syntax-highlighted mock code), right sidebar (telemetry — process capture indicators showing commits, keystrokes, time spent). No real code execution.
|
||||
- **Verify:** Sandbox UI renders with all panels; toolbar buttons are interactive (non-functional)
|
||||
- **Done:** Build sandbox mockup complete
|
||||
|
||||
#### Task 2-2-03: Assessment/defense mockup
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(learner)/defend/[competencyId]/page.tsx`, `apps/web/components/learner/assessment/rubric-display.tsx`, `apps/web/components/learner/assessment/ai-reviewer-panel.tsx`, `apps/web/components/learner/assessment/oral-defense.tsx`, `apps/web/components/learner/assessment/process-trace.tsx`, `apps/web/components/learner/assessment/artifact-viewer.tsx`
|
||||
- **Action:** Build assessment/defense mockup. Layout: top (artifact viewer — submitted work preview), left (rubric display — competency criteria with checkmarks), right (AI reviewer panel — assessment results), bottom (oral defense interface — mic button mockup, waveform animation, transcript area). Process trace timeline (showing build steps with timestamps).
|
||||
- **Verify:** Assessment mockup renders all panels; mic button has hover state; timeline displays mock events
|
||||
- **Done:** Assessment/defense mockup complete
|
||||
|
||||
### Must-Haves (Phase 2)
|
||||
- [ ] Landing page renders with hero, how-it-works, highlights, testimonials, CTA
|
||||
- [ ] Program catalog shows 5 competency stack cards
|
||||
- [ ] Competency stack view shows 12-18 competencies with status and badges
|
||||
- [ ] Learner dashboard shows all 6 panels including AI tutor chat mockup
|
||||
- [ ] Byte tutorial viewer renders with concept and worked example panels
|
||||
- [ ] Build sandbox mockup renders with toolbar, file explorer, editor, telemetry
|
||||
- [ ] Assessment mockup renders with rubric, AI reviewer, oral defense, process trace
|
||||
- [ ] All pages responsive at 375px, 768px, 1280px
|
||||
- [ ] Navigation between all learner pages works
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Marketplace Surface UI
|
||||
|
||||
**Requirements:** REQ-013, REQ-014, REQ-015, REQ-016, REQ-017
|
||||
**Persona:** frontend-engineer
|
||||
**Goal:** All 5 marketplace pages render with mock data; search/filter interactive
|
||||
|
||||
### Wave 1: Job board + search
|
||||
|
||||
#### Task 3-1-01: Job board listing
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(marketplace)/page.tsx`, `apps/web/components/marketplace/job-card.tsx`, `apps/web/components/marketplace/job-listing-grid.tsx`
|
||||
- **Action:** Build job board listing page. Layout: left sidebar (filters), main area (grid of job cards). Each job card: job title, company name, logo, location, remote badge, salary range, match score (percentage badge), required skills (tag chips), posted date. 20+ mock job listings.
|
||||
- **Verify:** 20+ job cards render; match scores display; skill tags show
|
||||
- **Done:** Job board listing complete
|
||||
|
||||
#### Task 3-1-02: Search/filter UI
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/components/marketplace/filter-sidebar.tsx`, `apps/web/components/marketplace/search-bar.tsx`, `apps/web/components/marketplace/saved-searches.tsx`
|
||||
- **Action:** Build filter sidebar. Semantic search bar at top (with icon, placeholder text). Filters: skills (multi-select chips), seniority (dropdown), location (text input), remote toggle, salary range (min/max inputs). Saved searches mockup section. Client-side filtering of mock jobs using useState.
|
||||
- **Verify:** Typing in search filters jobs; selecting skill filters jobs; toggling remote filters jobs
|
||||
- **Done:** Search/filter UI functional with client-side filtering
|
||||
|
||||
### Wave 2: Detail pages
|
||||
|
||||
#### Task 3-2-01: Job detail page
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(marketplace)/jobs/[jobId]/page.tsx`, `apps/web/components/marketplace/job-detail.tsx`, `apps/web/components/marketplace/skills-breakdown.tsx`, `apps/web/components/marketplace/related-jobs.tsx`
|
||||
- **Action:** Build job detail page. Layout: header (job title, company, location, salary, apply button), body (full description, required competencies list, AI-matched skills breakdown with match percentages), sidebar (employer info card, related jobs list).
|
||||
- **Verify:** Job detail renders with all sections; apply button is interactive (non-functional)
|
||||
- **Done:** Job detail page complete
|
||||
|
||||
#### Task 3-2-02: Employer profile
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(marketplace)/employers/[employerId]/page.tsx`, `apps/web/components/marketplace/employer-header.tsx`, `apps/web/components/marketplace/employer-openings.tsx`, `apps/web/components/marketplace/employer-culture.tsx`
|
||||
- **Action:** Build employer profile page. Header: logo, company name, tagline, industry, size, location, social links. Body: about section, culture section (mock photos grid), open positions list (job cards).
|
||||
- **Verify:** Employer profile renders with all sections; social links are clickable (mock URLs)
|
||||
- **Done:** Employer profile complete
|
||||
|
||||
#### Task 3-2-03: Pricing page
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(marketplace)/pricing/page.tsx`, `apps/web/components/marketplace/pricing-card.tsx`, `apps/web/components/marketplace/feature-comparison.tsx`
|
||||
- **Action:** Build pricing page. Three pricing cards: Job Posting (single — $49, bundle — $399 for 10, enterprise — custom). Talent Access plans (starter, pro, enterprise). Feature comparison table. CTA buttons on each plan.
|
||||
- **Verify:** Pricing page renders with 3 tiers and comparison table; responsive
|
||||
- **Done:** Pricing page complete
|
||||
|
||||
### Must-Haves (Phase 3)
|
||||
- [ ] Job board shows 20+ mock job listings with match scores
|
||||
- [ ] Search bar filters jobs client-side
|
||||
- [ ] Filter sidebar filters by skills, seniority, remote, salary
|
||||
- [ ] Job detail page shows full description, competencies, skills breakdown
|
||||
- [ ] Employer profile shows company info, culture, open positions
|
||||
- [ ] Pricing page shows 3 tiers with feature comparison
|
||||
- [ ] All pages responsive at 375px, 768px, 1280px
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Employer Dashboard UI
|
||||
|
||||
**Requirements:** REQ-018, REQ-019, REQ-020, REQ-021
|
||||
**Persona:** frontend-engineer
|
||||
**Goal:** All 4 employer dashboard pages render with mock data; charts display
|
||||
|
||||
### Wave 1: Dashboard + talent search
|
||||
|
||||
#### Task 4-1-01: Employer dashboard overview
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(employer)/page.tsx`, `apps/web/components/employer/overview/metric-cards.tsx`, `apps/web/components/employer/overview/applicant-pipeline.tsx`, `apps/web/components/employer/overview/talent-matches.tsx`, `apps/web/components/employer/overview/analytics-charts.tsx`
|
||||
- **Action:** Build employer dashboard overview. Top row: 4 metric cards (active postings, total applicants, talent matches, placement rate). Middle: applicant pipeline (kanban-style columns: applied, screening, interview, offer, hired). Right: talent matches (list of matched candidates with match score). Bottom: analytics charts (recharts — bar chart for postings over time, donut chart for applicant sources, line chart for placement trends).
|
||||
- **Verify:** Dashboard renders with metric cards, pipeline, matches, and 3 chart types
|
||||
- **Done:** Employer dashboard overview complete
|
||||
|
||||
#### Task 4-1-02: Talent search
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(employer)/talent/page.tsx`, `apps/web/components/employer/talent/candidate-card.tsx`, `apps/web/components/employer/talent/talent-filters.tsx`
|
||||
- **Action:** Build talent search page. Layout: top (search bar + AI-matched filters), main (grid of candidate cards). Each candidate card: avatar, name, headline (competency stack + level), microcredential badges (top 3), artifact count, defense score, match percentage, "View Profile" button. 15+ mock candidates. Client-side filtering.
|
||||
- **Verify:** 15+ candidate cards render; filters work client-side; clicking "View Profile" navigates to candidate profile
|
||||
- **Done:** Talent search complete
|
||||
|
||||
### Wave 2: Detail + management
|
||||
|
||||
#### Task 4-2-01: Candidate profile view
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(employer)/talent/[candidateId]/page.tsx`, `apps/web/components/employer/talent-profile/artifact-gallery.tsx`, `apps/web/components/employer/talent-profile/process-trace-summary.tsx`, `apps/web/components/employer/talent-profile/defense-transcripts.tsx`, `apps/web/components/employer/talent-profile/competency-mini-graph.tsx`, `apps/web/components/employer/talent-profile/microcredential-verification.tsx`
|
||||
- **Action:** Build candidate profile view. Header: avatar, name, headline, match score, contact button. Body sections: artifact gallery (grid of project artifacts with thumbnails), process trace summary (timeline of build steps), oral defense transcripts (accordion of defense sessions with Q&A), competency mini-graph (react-flow visualization of candidate's competencies), microcredential verification (list of earned credentials with verification badges).
|
||||
- **Verify:** All profile sections render; defense transcripts accordion expands; mini-graph renders
|
||||
- **Done:** Candidate profile complete
|
||||
|
||||
#### Task 4-2-02: Posting management
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(employer)/postings/page.tsx`, `apps/web/components/employer/postings/posting-list.tsx`, `apps/web/components/employer/postings/posting-form.tsx`, `apps/web/components/employer/postings/applicant-list.tsx`
|
||||
- **Action:** Build posting management page. Layout: left (list of job postings with status badges: active, draft, expired), right (selected posting detail or create/edit form). Form fields: title, description, required competencies (multi-select), seniority, salary range, location, remote toggle. Applicant list per posting (table with name, applied date, status, match score). "Create New Posting" button opens form.
|
||||
- **Verify:** Posting list renders; form is interactive (inputs work, non-functional submit); applicant list displays
|
||||
- **Done:** Posting management complete
|
||||
|
||||
### Must-Haves (Phase 4)
|
||||
- [ ] Dashboard overview shows 4 metric cards, applicant pipeline, 3 charts
|
||||
- [ ] Talent search shows 15+ candidate cards with filters
|
||||
- [ ] Candidate profile shows artifact gallery, process trace, defense transcripts, mini-graph, credentials
|
||||
- [ ] Posting management shows posting list, create/edit form, applicant list
|
||||
- [ ] All pages responsive at 375px, 768px, 1280px
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Admin Surface UI
|
||||
|
||||
**Requirements:** REQ-022, REQ-023, REQ-024, REQ-025
|
||||
**Persona:** frontend-engineer
|
||||
**Goal:** All 4 admin pages render; competency graph viewer interactive
|
||||
|
||||
### Wave 1: Overview + learner management
|
||||
|
||||
#### Task 5-1-01: Admin overview
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(admin)/page.tsx`, `apps/web/components/admin/overview/platform-metrics.tsx`, `apps/web/components/admin/overview/activity-feed.tsx`, `apps/web/components/admin/overview/system-health.tsx`
|
||||
- **Action:** Build admin overview. Top: platform metric cards (total learners, total employers, placements, completion rate, NPS). Middle: activity feed (timeline of recent platform events — new registrations, completions, job postings, placements). Right: system health mockup (status indicators for services, uptime bars, error rates).
|
||||
- **Verify:** Admin overview renders with metrics, activity feed, system health
|
||||
- **Done:** Admin overview complete
|
||||
|
||||
#### Task 5-1-02: Learner management
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(admin)/learners/page.tsx`, `apps/web/components/admin/learners/learner-table.tsx`, `apps/web/components/admin/learners/learner-detail.tsx`
|
||||
- **Action:** Build learner management page. Layout: searchable learner table (columns: name, email, stack, progress %, status, joined date). Search and filter (by stack, status). Clicking a learner opens detail panel (progress tracking, competency completion, credential issuance log, recent activity).
|
||||
- **Verify:** Learner table renders with mock data; search filters; detail panel opens on click
|
||||
- **Done:** Learner management complete
|
||||
|
||||
### Wave 2: Graph viewer + moderation
|
||||
|
||||
#### Task 5-2-01: Competency graph viewer
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(admin)/graph/page.tsx`, `apps/web/components/admin/graph/competency-graph.tsx`, `apps/web/components/admin/graph/node-detail.tsx`
|
||||
- **Action:** Build competency graph viewer using @xyflow/react. Interactive node/edge graph showing competency stacks and their relationships. Nodes: competency stacks (colored by category) and individual competencies. Edges: prerequisite relationships. Node click opens detail panel (competency name, description, stack, prerequisites, learners mastering it). Controls: zoom, pan, fit-to-screen. Mock graph data.
|
||||
- **Verify:** Graph renders with nodes and edges; nodes are clickable; detail panel opens; zoom/pan works
|
||||
- **Done:** Competency graph viewer complete
|
||||
|
||||
#### Task 5-2-02: Marketplace moderation
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/app/(admin)/moderation/page.tsx`, `apps/web/components/admin/moderation/review-queue.tsx`, `apps/web/components/admin/moderation/verification-queue.tsx`, `apps/web/components/admin/moderation/flagged-content.tsx`
|
||||
- **Action:** Build marketplace moderation page. Three tabs: Job Posting Review (queue of pending job postings with approve/reject buttons), Employer Verification (queue of employers awaiting identity verification), Flagged Content (list of reported content with reason, reporter, actions). All buttons non-functional but interactive (hover states, click feedback).
|
||||
- **Verify:** Moderation page renders with 3 tabs; queues display mock items; tab switching works
|
||||
- **Done:** Marketplace moderation complete
|
||||
|
||||
### Must-Haves (Phase 5)
|
||||
- [ ] Admin overview shows platform metrics, activity feed, system health
|
||||
- [ ] Learner management shows searchable table with detail panel
|
||||
- [ ] Competency graph viewer renders interactive graph with clickable nodes
|
||||
- [ ] Marketplace moderation shows 3 tabbed queues
|
||||
- [ ] All pages responsive at 375px, 768px, 1280px
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Polish + Integration
|
||||
|
||||
**Requirements:** REQ-026, REQ-027, REQ-028
|
||||
**Persona:** frontend-engineer, design-system-engineer
|
||||
**Goal:** Cross-surface consistency, dark mode everywhere, Storybook
|
||||
|
||||
### Wave 1: Navigation + consistency
|
||||
|
||||
#### Task 6-1-01: Cross-surface navigation polish
|
||||
- **Persona:** frontend-engineer
|
||||
- **Files:** `apps/web/components/navigation-shell.tsx` (update), `apps/web/components/role-switcher.tsx` (update), `apps/web/components/breadcrumbs.tsx`
|
||||
- **Action:** Polish cross-surface navigation. Role switcher dropdown with surface-specific sub-navigation. Breadcrumbs on all pages showing current location. Consistent header/footer across all 4 surfaces. Active nav link highlighting.
|
||||
- **Verify:** Breadcrumbs show on all pages; role switcher dropdown works; active links highlighted
|
||||
- **Done:** Cross-surface navigation polished
|
||||
|
||||
#### Task 6-1-02: Visual consistency audit
|
||||
- **Persona:** design-system-engineer
|
||||
- **Files:** `apps/web/app/globals.css` (update), `packages/ui/src/tokens/index.ts` (update if needed)
|
||||
- **Action:** Audit all surfaces for visual consistency. Check: typography scale (all text uses design tokens), color palette (no hardcoded colors), spacing system (all margins/padding use design tokens), dark mode (all pages support dark mode toggle), WCAG AA contrast (all text meets 4.5:1 ratio). Fix any inconsistencies found.
|
||||
- **Verify:** No hardcoded colors; dark mode works on all pages; contrast check passes
|
||||
- **Done:** Visual consistency audit complete
|
||||
|
||||
### Wave 2: Storybook
|
||||
|
||||
#### Task 6-2-01: Storybook setup
|
||||
- **Persona:** design-system-engineer
|
||||
- **Files:** `apps/web/.storybook/main.ts`, `apps/web/.storybook/preview.ts`, `packages/ui/src/primitives/*.stories.tsx` (one per primitive)
|
||||
- **Action:** Set up Storybook for the component library. Configure for Next.js + Tailwind. Create stories for all 12 primitives and key composites (JobCard, CandidateCard, CompetencyBadge, MetricCard). Each story: default, variants, sizes, dark mode.
|
||||
- **Verify:** `pnpm storybook` starts; all primitive stories render; dark mode toggle in Storybook
|
||||
- **Done:** Storybook documents all primitives + key composites
|
||||
|
||||
### Must-Haves (Phase 6)
|
||||
- [ ] Breadcrumbs on all pages
|
||||
- [ ] Role switcher dropdown with surface-specific nav
|
||||
- [ ] Active nav link highlighting
|
||||
- [ ] No hardcoded colors — all from design tokens
|
||||
- [ ] Dark mode works on all 4 surfaces
|
||||
- [ ] WCAG AA contrast passes
|
||||
- [ ] Storybook runs with all primitive stories
|
||||
|
||||
---
|
||||
|
||||
## MVP/UX Sections
|
||||
|
||||
### User-Facing Surface
|
||||
The primary user-facing surface is the **Nextcraft web application** at `localhost:3000` (dev) with 4 route groups:
|
||||
- `/` — Learner surface (landing, catalog, dashboard, learn, build, defend)
|
||||
- `/marketplace` — Marketplace surface (jobs, employers, pricing)
|
||||
- `/employer` — Employer dashboard (overview, talent, postings)
|
||||
- `/admin` — Admin surface (overview, learners, graph, moderation)
|
||||
|
||||
### Happy Path
|
||||
1. User visits landing page → sees hero, how-it-works (Byte→Build→Demonstrate→Defend), program highlights
|
||||
2. User clicks "Explore Programs" → program catalog shows 5 competency stacks
|
||||
3. User clicks "AI Orchestration Engineer" → competency stack view shows 15 competencies
|
||||
4. User clicks a competency → byte tutorial viewer shows concept + worked example
|
||||
5. User clicks "Start Building" → build sandbox mockup shows IDE UI with telemetry
|
||||
6. User clicks "Submit for Assessment" → assessment/defense mockup shows rubric, AI reviewer, oral defense interface
|
||||
7. User navigates to marketplace → job board shows AI-era job listings with match scores
|
||||
8. User searches/filters jobs → results update client-side
|
||||
9. User clicks a job → job detail page shows full description, required competencies, employer info
|
||||
10. User switches to employer dashboard → overview shows metrics, pipeline, charts
|
||||
11. User searches talent → candidate cards with microcredentials, defense scores
|
||||
12. User clicks a candidate → profile shows artifact gallery, process trace, defense transcripts
|
||||
13. User switches to admin → overview shows platform metrics, activity feed
|
||||
14. User opens competency graph viewer → interactive graph with clickable nodes
|
||||
|
||||
### UX Acceptance Criteria
|
||||
1. All 4 surfaces are accessible via the role switcher in the header
|
||||
2. Navigation is consistent across all surfaces (same header, footer, breadcrumb pattern)
|
||||
3. All pages are responsive at 375px (mobile), 768px (tablet), 1280px (desktop)
|
||||
4. Dark mode toggle works on all surfaces
|
||||
5. All interactive elements have hover states and click feedback
|
||||
6. Form inputs are non-functional but visually complete (placeholders, labels, validation states)
|
||||
7. Mock data is realistic and typed — no "lorem ipsum" or placeholder text
|
||||
8. All charts render correctly (recharts) with mock data
|
||||
9. Competency graph viewer is interactive (zoom, pan, click nodes)
|
||||
10. AI tutor chat displays pre-scripted responses on message "send"
|
||||
11. No console errors on any page
|
||||
12. `pnpm build` succeeds without warnings
|
||||
@@ -0,0 +1,102 @@
|
||||
# Nextcraft — PROJECT.md
|
||||
|
||||
## What This Is
|
||||
|
||||
Nextcraft is an AI-native outcome school where graduates prove what they can build — not what they can write. It credentials verifiable skill for a post-AI labor market, rejects legacy degree structures, and trains the workforce of tomorrow through hands-on competency stacks assessed entirely by AI tutors. The marketplace is the symbiotic second surface: employers meet AI-credentialed talent through an automated, algorithmically-matched job board that runs without human headcount.
|
||||
|
||||
**Single guiding outcome:** ≥1,000 learners placed in AI-orchestration roles via the Nextcraft marketplace within 36 months of launch, verified by CIRR-style third-party audit.
|
||||
|
||||
---
|
||||
|
||||
## Current Milestone: v0.1 — UI/UX Prototype
|
||||
|
||||
**Scope:** High-fidelity interactive prototype of all four Nextcraft surfaces with realistic mock data, navigation flows, responsive layouts, and a shared component library. No backend, no business logic, no database — everything static/mocked.
|
||||
|
||||
**Constraint:** MAJOR 0 until MVP is released. No business logic until the first milestone prototype is agreed upon by the founder.
|
||||
|
||||
**Tech stack:** TypeScript monorepo (pnpm/turborepo) with Next.js for all web surfaces. Python FastAPI AI services planned for later milestones (not in v0.1).
|
||||
|
||||
---
|
||||
|
||||
## Requirements (Validated)
|
||||
|
||||
The following requirements have been validated during specification and are locked for milestone v0.1:
|
||||
|
||||
1. Learner surface UI — landing page, program catalog, competency stack view, learner dashboard, byte tutorial viewer, build sandbox mockup, assessment/defense mockup
|
||||
2. Marketplace surface UI — job board listing, job detail page, employer profile, search/filter UI, job posting packages pricing page
|
||||
3. Employer dashboard UI — overview, talent search, candidate profile view, posting management
|
||||
4. Admin surface UI — overview, learner management, competency graph viewer, marketplace moderation
|
||||
5. Shared component library — design system, reusable UI primitives, surface-specific theming
|
||||
6. Responsive layout system — mobile, tablet, desktop breakpoints
|
||||
7. Mock data layer — typed, realistic data reflecting the vision (competency stacks, job listings, candidate profiles)
|
||||
8. Navigation/routing — cross-surface navigation, role-based route groups
|
||||
|
||||
## Requirements (Active — Future Milestones)
|
||||
|
||||
The following are deferred beyond v0.1 and will be activated in subsequent milestones:
|
||||
|
||||
- AI tutor agent architecture (Coach, Tutor, Lab, Assessor, Proctor, Mentor)
|
||||
- Competency graph engine and adaptive pathways
|
||||
- Assessment engine (process-trace grading, oral defense, per-learner variant tasks)
|
||||
- Sandbox fabric (sandboxed IDE, design tool, simulation)
|
||||
- Identity verification and age-gating logic (16+/18+)
|
||||
- Marketplace job aggregation pipeline (3M+ jobs from 120K companies)
|
||||
- AI-powered tagging, semantic vector search, company enrichment
|
||||
- AI resume parsing and job matching
|
||||
- SEO-optimized programmatic pages
|
||||
- Payment processing and subscription management
|
||||
- Human tutor marketplace (third-party course creation)
|
||||
- B2B employer network functionality
|
||||
- CIRR-style placement tracking and audit
|
||||
|
||||
## Requirements (Out of Scope — Per Vision Doctrine)
|
||||
|
||||
- Traditional accreditation — not sought, not pursued, not revisited
|
||||
- Under-16 learners — excluded; AI school floor is 16+
|
||||
- Marketplace for under-18 — excluded; marketplace is 18+ with verified identity
|
||||
- Human tutors in the core school — excluded; humans exist only in the open marketplace
|
||||
- Graded written exams without process trace — excluded
|
||||
- Legacy job titles in curriculum — excluded
|
||||
- Junk advertising — excluded
|
||||
|
||||
---
|
||||
|
||||
## Constraints
|
||||
|
||||
1. **MAJOR 0 until MVP** — all versions remain v0.x until the MVP is released and agreed upon by the founder
|
||||
2. **No business logic in v0.1** — pure UI/UX prototype with mock data only
|
||||
3. **High-fidelity interactive** — clickable navigation, realistic content, hover states, form inputs (non-functional), responsive breakpoints, loading states (mock)
|
||||
4. **All data mocked** — no real API calls, no database, no authentication logic
|
||||
5. **Shared design system** — all 4 surfaces use a unified component library with surface-specific theming via CSS variables
|
||||
6. **TypeScript monorepo** — pnpm workspaces + turborepo for build orchestration
|
||||
7. **Next.js App Router** — route groups for each surface: (learner), (marketplace), (employer), (admin)
|
||||
8. **Solo founder constraint** — Phase 1 is build-only with no headcount; the prototype must be producible by a solo developer with AI assistance
|
||||
9. **No traditional accreditation** — proprietary credential replaces degrees
|
||||
10. **AI-first architecture** — AI tutors are the primary human-facing layer (in future milestones)
|
||||
|
||||
---
|
||||
|
||||
## Key Decisions
|
||||
|
||||
| ID | Decision | Rationale | Outcome |
|
||||
|----|----------|-----------|---------|
|
||||
| D-001 | Milestone v0.1 = UI/UX prototype only, no business logic | Founder directive: validate UX before building backend. Prototype must be agreed upon before proceeding to business logic. | Scope locked to frontend surfaces with mock data |
|
||||
| D-002 | MAJOR 0 until MVP released | Founder directive: remain on v0.x until MVP is validated. Signals pre-release status. | All tags are v0.x.y until MVP agreement |
|
||||
| D-003 | TypeScript monorepo (pnpm/turborepo) + Next.js | Unified codebase for all 4 surfaces. Shared component library, types, mock data. Next.js App Router for route-based surface separation. Python AI services deferred to later milestones. | Monorepo structure with apps/web + packages/* |
|
||||
| D-004 | All 4 surfaces in v0.1 (Learner, Marketplace, Employer, Admin) | Founder selected all 4 surfaces for the prototype. Complete product visualization before any backend work. | 24 REQ-IDs covering all surfaces + shared infrastructure |
|
||||
| D-005 | High-fidelity interactive prototype | Founder selected high-fidelity over wireframes. Realistic mock data, navigation flows, responsive layouts, component library. No backend calls. | Clickable prototype with realistic content |
|
||||
| D-006 | Release forge = Gitea @ git.cloudinit.dev, owner=coreci, repo=nextcraft | Founder-provided Gitea instance for release management. Token stored in .ciagent/.env.secrets. | Ship workflow creates tags + releases on Gitea |
|
||||
| D-007 | Full autonomy for CIAgent pipeline | Founder selected full autonomy. No HITL after clarify. Auto-decide above confidence 0.60. Escalation hooks: deploy, delete_data, merge_to_main. | Rapid autonomous building with kill criteria |
|
||||
| D-008 | Shared component library in packages/ui/ | All surfaces share a unified design system with surface-specific theming via CSS variables. Promotes consistency and reduces duplication. | packages/ui, packages/mock-data, packages/types |
|
||||
| D-009 | AI tutor UI as chat interface mockup with pre-scripted responses | The learner surface includes an AI tutor chat UI mockup. No real AI backend — pre-scripted responses simulate the Coach and Tutor agents. | Mockup only in v0.1, real agents in future milestone |
|
||||
| D-010 | Age-gating represented as visual registration flow mockup | 16+/18+ age-gating shown as a UI flow with age verification step. No actual verification logic. | Visual mockup only |
|
||||
| D-011 | Competency graph viewer as interactive static visualization | Admin surface includes a competency graph viewer using react-flow or similar. Mock competency nodes and edges. No real graph data. | Static graph with mock data |
|
||||
| D-012 | Tech stack: TS monorepo + Python AI services (future) | v0.1 uses TS only. Python FastAPI microservices planned for AI tutor agents and assessment engine in later milestones. | v0.1: TS only. Future: TS + Python |
|
||||
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
Nextcraft is being built by a solo founder using the CIAgent v0.7.0 autonomous pipeline. The vision document defines a 36-month, 3-phase roadmap to ≥1,000 placements. The first CIAgent milestone (v0.1) is intentionally scoped to UI/UX only — validating the product vision through interactive prototypes before any backend or business logic investment.
|
||||
|
||||
The four surfaces (Learner, Marketplace, Employer Dashboard, Admin) map directly to the four audiences in the vision: learners, employers, marketplace operators, and platform administrators. The prototype will demonstrate the complete user journey across all surfaces with realistic mock data reflecting the AI-era competency stacks, AI-orchestration job listings, and artifact+process trace+oral defense credential model.
|
||||
@@ -0,0 +1,154 @@
|
||||
# Nextcraft — REQUIREMENTS.md
|
||||
|
||||
## v0.1 Requirements (UI/UX Prototype)
|
||||
|
||||
### Infrastructure
|
||||
|
||||
| ID | Description | Priority | Phase | Status |
|
||||
|----|-------------|----------|-------|--------|
|
||||
| REQ-001 | Monorepo scaffolding: pnpm workspaces, turborepo, Next.js app, TypeScript config, ESLint, Prettier | critical | 1 | pending |
|
||||
| REQ-002 | Shared component library: design tokens, Button, Input, Card, Badge, Avatar, Dialog, Navigation, Table, Tabs, Progress, Tooltip, Skeleton, Toast | critical | 1 | pending |
|
||||
| REQ-003 | Mock data layer: typed mock data for competency stacks, job listings, candidate profiles, employers, learner progress | critical | 1 | pending |
|
||||
| REQ-004 | Routing and navigation: App Router route groups for (learner), (marketplace), (employer), (admin); shared layout components; cross-surface navigation | critical | 1 | pending |
|
||||
| REQ-005 | Responsive layout system: mobile, tablet, desktop breakpoints; container components; grid system | high | 1 | pending |
|
||||
|
||||
### Learner Surface
|
||||
|
||||
| ID | Description | Priority | Phase | Status |
|
||||
|----|-------------|----------|-------|--------|
|
||||
| REQ-006 | Landing page: hero, value proposition, program highlights, how-it-works (Byte→Build→Demonstrate→Defend), testimonials mockup, CTA to program catalog | critical | 2 | pending |
|
||||
| REQ-007 | Program catalog: grid of competency stacks (AI Orchestration Engineer, AI Safety & Governance Lead, Human-AI Product Designer, AI-Augmented Field Operator, Computational Sciences Practitioner); stack cards with role descriptions | critical | 2 | pending |
|
||||
| REQ-008 | Competency stack view: selected stack detail with 12-18 competencies listed, progress indicators, microcredential badges, mastery status | critical | 2 | pending |
|
||||
| REQ-009 | Learner dashboard: active competencies, progress graph, recent artifacts, upcoming defenses, AI tutor chat mockup, milestone tracker | critical | 2 | pending |
|
||||
| REQ-010 | Byte tutorial viewer: 3-7 minute micro-tutorial layout with concept panel, worked example panel, code/design/simulation viewer mockup | high | 2 | pending |
|
||||
| REQ-011 | Build sandbox mockup: sandboxed IDE/design tool/simulation UI mockup with toolbar, file explorer, editor area, telemetry sidebar (process capture indicators) | high | 2 | pending |
|
||||
| REQ-012 | Assessment/defense mockup: rubric display, AI reviewer panel, oral defense interface (voice/mic mockup), process trace timeline, artifact viewer | high | 2 | pending |
|
||||
|
||||
### Marketplace Surface
|
||||
|
||||
| ID | Description | Priority | Phase | Status |
|
||||
|----|-------------|----------|-------|--------|
|
||||
| REQ-013 | Job board listing: searchable grid of AI-era job listings, filter sidebar (skills, seniority, location, salary), result cards with match score | critical | 3 | pending |
|
||||
| REQ-014 | Job detail page: full job description, required competencies, employer info, application CTA, related jobs, AI-matched skills breakdown | critical | 3 | pending |
|
||||
| REQ-015 | Employer profile: company overview, logo, description, social links, open positions, company culture mockup | high | 3 | pending |
|
||||
| REQ-016 | Search/filter UI: semantic search bar, skill tags, category filters, seniority filter, remote/on-site toggle, saved searches mockup | critical | 3 | pending |
|
||||
| REQ-017 | Pricing page: job posting packages (single, bundle, enterprise), talent access plans, subscription tiers, feature comparison table | high | 3 | pending |
|
||||
|
||||
### Employer Dashboard
|
||||
|
||||
| ID | Description | Priority | Phase | Status |
|
||||
|----|-------------|----------|-------|--------|
|
||||
| REQ-018 | Employer dashboard overview: active postings, applicant pipeline, talent matches, analytics mockup (charts, placement stats) | critical | 4 | pending |
|
||||
| REQ-019 | Talent search: searchable candidate database with AI-matched filters, candidate cards showing competency stack, microcredentials, artifact count, defense score | critical | 4 | pending |
|
||||
| REQ-020 | Candidate profile view: full candidate profile with artifact gallery, process trace summary, oral defense transcripts, competency graph, microcredential verification | high | 4 | pending |
|
||||
| REQ-021 | Posting management: create/edit/delete job postings, posting status tracking, applicant list per posting, interview pipeline mockup | high | 4 | pending |
|
||||
|
||||
### Admin Surface
|
||||
|
||||
| ID | Description | Priority | Phase | Status |
|
||||
|----|-------------|----------|-------|--------|
|
||||
| REQ-022 | Admin overview: platform metrics (learners, employers, placements, completion rate, NPS), recent activity feed, system health mockup | critical | 5 | pending |
|
||||
| REQ-023 | Learner management: searchable learner table, learner detail view, progress tracking, competency completion status, credential issuance log | high | 5 | pending |
|
||||
| REQ-024 | Competency graph viewer: interactive visualization of competency stacks and their relationships, node/edge graph using react-flow, stack details on node click | high | 5 | pending |
|
||||
| REQ-025 | Marketplace moderation: job posting review queue, employer verification queue, flagged content, content moderation tools mockup | high | 5 | pending |
|
||||
|
||||
### Polish & Integration
|
||||
|
||||
| ID | Description | Priority | Phase | Status |
|
||||
|----|-------------|----------|-------|--------|
|
||||
| REQ-026 | Cross-surface navigation: role switcher (learner/employer/admin), breadcrumbs, consistent header/footer across all surfaces | critical | 6 | pending |
|
||||
| REQ-027 | Visual consistency audit: typography scale, color palette, spacing system, dark mode toggle, accessibility baseline (WCAG AA contrast) | high | 6 | pending |
|
||||
| REQ-028 | Component library finalization: Storybook setup, component documentation, prop tables, usage examples | medium | 6 | pending |
|
||||
|
||||
---
|
||||
|
||||
## v2 Requirements (Future Milestones — Deferred)
|
||||
|
||||
### AI Tutor Architecture
|
||||
|
||||
| ID | Description | Priority | Milestone | Status |
|
||||
|----|-------------|----------|-----------|--------|
|
||||
| REQ-F-001 | Coach agent: pacing, motivation, retrieval practice | high | v0.2+ | deferred |
|
||||
| REQ-F-002 | Tutor agent: concept delivery, Socratic questioning | high | v0.2+ | deferred |
|
||||
| REQ-F-003 | Lab agent: sandbox execution, in-flow feedback | high | v0.2+ | deferred |
|
||||
| REQ-F-004 | Assessor agent: rubric application to artifacts and defenses | high | v0.2+ | deferred |
|
||||
| REQ-F-005 | Proctor agent: identity, attention, integrity signals | high | v0.2+ | deferred |
|
||||
| REQ-F-006 | Mentor agent: long-horizon career narrative | medium | v0.2+ | deferred |
|
||||
|
||||
### Assessment Engine
|
||||
|
||||
| ID | Description | Priority | Milestone | Status |
|
||||
|----|-------------|----------|-----------|--------|
|
||||
| REQ-F-007 | Process-trace grading engine | high | v0.3+ | deferred |
|
||||
| REQ-F-008 | Per-learner variant task generation | high | v0.3+ | deferred |
|
||||
| REQ-F-009 | Oral/voice defense with AI examiner | high | v0.3+ | deferred |
|
||||
| REQ-F-010 | Live in-environment build with telemetry | high | v0.3+ | deferred |
|
||||
|
||||
### Marketplace Engine
|
||||
|
||||
| ID | Description | Priority | Milestone | Status |
|
||||
|----|-------------|----------|-----------|--------|
|
||||
| REQ-F-011 | AI job aggregation pipeline (3M+ jobs from 120K companies) | high | v0.4+ | deferred |
|
||||
| REQ-F-012 | AI-powered tagging (skills, categories, seniority) | high | v0.4+ | deferred |
|
||||
| REQ-F-013 | Semantic vector search for role matching | high | v0.4+ | deferred |
|
||||
| REQ-F-014 | AI company enrichment (logos, descriptions, social links) | medium | v0.4+ | deferred |
|
||||
| REQ-F-015 | AI resume parsing (profile auto-fill) | medium | v0.4+ | deferred |
|
||||
| REQ-F-016 | SEO-optimized programmatic pages | medium | v0.4+ | deferred |
|
||||
|
||||
### Platform Infrastructure
|
||||
|
||||
| ID | Description | Priority | Milestone | Status |
|
||||
|----|-------------|----------|-----------|--------|
|
||||
| REQ-F-017 | Identity verification and age-gating (16+/18+) | high | v0.2+ | deferred |
|
||||
| REQ-F-018 | Payment processing and subscription management | high | v0.3+ | deferred |
|
||||
| REQ-F-019 | Human tutor marketplace (third-party courses) | medium | v0.4+ | deferred |
|
||||
| REQ-F-020 | CIRR-style placement tracking and audit | medium | v0.5+ | deferred |
|
||||
|
||||
---
|
||||
|
||||
## Out of Scope (Per Vision Doctrine)
|
||||
|
||||
| Feature | Reason |
|
||||
|---------|--------|
|
||||
| Traditional accreditation | Not sought, not pursued, not revisited (Principle 4) |
|
||||
| Under-16 learners | COPPA avoidance; AI school floor is 16+ |
|
||||
| Marketplace for under-18 | Marketplace restricted to 18+ with verified identity |
|
||||
| Human tutors in core school | Humans exist only in open marketplace as third-party sellers |
|
||||
| Graded written exams without process trace | Trivially solvable by frontier AI; process-trace + oral defense more valid |
|
||||
| Legacy job titles in curriculum | Programs train for AI-era roles, not obsolete ones |
|
||||
| Junk advertising | Ad quality enforced algorithmically; relevant ads only |
|
||||
|
||||
---
|
||||
|
||||
## Traceability Matrix
|
||||
|
||||
| Requirement | Phase | Status |
|
||||
|-------------|-------|--------|
|
||||
| REQ-001 | 1 | pending |
|
||||
| REQ-002 | 1 | pending |
|
||||
| REQ-003 | 1 | pending |
|
||||
| REQ-004 | 1 | pending |
|
||||
| REQ-005 | 1 | pending |
|
||||
| REQ-006 | 2 | pending |
|
||||
| REQ-007 | 2 | pending |
|
||||
| REQ-008 | 2 | pending |
|
||||
| REQ-009 | 2 | pending |
|
||||
| REQ-010 | 2 | pending |
|
||||
| REQ-011 | 2 | pending |
|
||||
| REQ-012 | 2 | pending |
|
||||
| REQ-013 | 3 | pending |
|
||||
| REQ-014 | 3 | pending |
|
||||
| REQ-015 | 3 | pending |
|
||||
| REQ-016 | 3 | pending |
|
||||
| REQ-017 | 3 | pending |
|
||||
| REQ-018 | 4 | pending |
|
||||
| REQ-019 | 4 | pending |
|
||||
| REQ-020 | 4 | pending |
|
||||
| REQ-021 | 4 | pending |
|
||||
| REQ-022 | 5 | pending |
|
||||
| REQ-023 | 5 | pending |
|
||||
| REQ-024 | 5 | pending |
|
||||
| REQ-025 | 5 | pending |
|
||||
| REQ-026 | 6 | pending |
|
||||
| REQ-027 | 6 | pending |
|
||||
| REQ-028 | 6 | pending |
|
||||
@@ -0,0 +1,192 @@
|
||||
# Nextcraft — ROADMAP.md
|
||||
|
||||
## Overview
|
||||
|
||||
**Milestone v0.1** — UI/UX Prototype: High-fidelity interactive prototype of all four Nextcraft surfaces (Learner, Marketplace, Employer Dashboard, Admin) with realistic mock data, shared component library, responsive layouts, and navigation flows. No backend, no business logic.
|
||||
|
||||
**Milestone type:** Feature (includes new UI features)
|
||||
**Tag line:** v0.0.x (patches on the v0.0 line; milestone release as v0.1.0)
|
||||
**Branch:** milestone/v0.1-nextcraft-ui-prototype
|
||||
|
||||
---
|
||||
|
||||
## Phase List
|
||||
|
||||
| # | Name | Status | Depends On | Requirements | Success Criteria |
|
||||
|---|------|--------|------------|--------------|------------------|
|
||||
| 0 | Pre-execution | in_progress | — | — | Specification, clarify, research, plan complete; .ciagent/ files created |
|
||||
| 1 | Project scaffolding | not_started | 0 | REQ-001, REQ-002, REQ-003, REQ-004, REQ-005 | Monorepo builds; dev server starts; component library has all primitives; mock data typed; routing works between route groups |
|
||||
| 2 | Learner surface UI | not_started | 1 | REQ-006, REQ-007, REQ-008, REQ-009, REQ-010, REQ-011, REQ-012 | All 7 learner pages render with mock data; navigation between pages works; responsive at mobile/tablet/desktop |
|
||||
| 3 | Marketplace surface UI | not_started | 1 | REQ-013, REQ-014, REQ-015, REQ-016, REQ-017 | All 5 marketplace pages render with mock data; search/filter UI interactive (client-side); job board listing displays mock jobs |
|
||||
| 4 | Employer dashboard UI | not_started | 1 | REQ-018, REQ-019, REQ-020, REQ-021 | All 4 employer pages render with mock data; talent search displays mock candidates; candidate profile shows artifact gallery + process trace |
|
||||
| 5 | Admin surface UI | not_started | 1 | REQ-022, REQ-023, REQ-024, REQ-025 | All 4 admin pages render with mock data; competency graph viewer renders interactive graph; moderation queue displays mock flagged content |
|
||||
| 6 | Polish + integration | not_started | 2, 3, 4, 5 | REQ-026, REQ-027, REQ-028 | Cross-surface navigation works; visual consistency audit passes; dark mode toggle functional; Storybook documents all components |
|
||||
| 7 | Final review + ship | not_started | 6 | — | Code review clean; audit passes; milestone tagged v0.1.0; release created on Gitea |
|
||||
|
||||
---
|
||||
|
||||
## Phase Details
|
||||
|
||||
### Phase 0: Pre-execution
|
||||
|
||||
**Goal:** Establish project specification, clarify ambiguities, research tech stack, create detailed plans.
|
||||
|
||||
**Stages:** SPECIFY → CLARIFY → RESEARCH → PLAN → (GRILL optional) → SHIP
|
||||
|
||||
**Deliverables:**
|
||||
- .ciagent/config.json
|
||||
- .ciagent/PROJECT.md
|
||||
- .ciagent/REQUIREMENTS.md
|
||||
- .ciagent/ARCHITECTURE.md
|
||||
- .ciagent/ROADMAP.md
|
||||
- .ciagent/CHECKPOINT.json
|
||||
|
||||
**Success criteria:** All .ciagent/ files created; initial commit with ---ci--- block; phase 0 shipped as v0.0.1.
|
||||
|
||||
---
|
||||
|
||||
### Phase 1: Project Scaffolding
|
||||
|
||||
**Goal:** Set up the monorepo, component library, mock data layer, routing, and responsive system.
|
||||
|
||||
**Requirements:** REQ-001, REQ-002, REQ-003, REQ-004, REQ-005
|
||||
|
||||
**Key deliverables:**
|
||||
- pnpm-workspace.yaml + turbo.json + root package.json
|
||||
- apps/web Next.js app with App Router
|
||||
- packages/ui with design tokens + all primitives (Button, Input, Card, Badge, Avatar, Dialog, Tabs, Progress, Tooltip, Skeleton, Toast)
|
||||
- packages/mock-data with typed mock data for all domains
|
||||
- packages/types with shared TypeScript type definitions
|
||||
- Route groups: (learner), (marketplace), (employer), (admin)
|
||||
- Responsive layout system with breakpoints
|
||||
- Root layout with theme provider
|
||||
|
||||
**Success criteria:**
|
||||
- `pnpm dev` starts the Next.js dev server
|
||||
- `pnpm build` succeeds without errors
|
||||
- `pnpm typecheck` passes
|
||||
- All primitive components exist and are importable
|
||||
- Mock data is typed and importable
|
||||
- Navigation between route groups works (even if pages are placeholders)
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: Learner Surface UI
|
||||
|
||||
**Goal:** Build all 7 learner surface pages with realistic mock data and interactive elements.
|
||||
|
||||
**Requirements:** REQ-006, REQ-007, REQ-008, REQ-009, REQ-010, REQ-011, REQ-012
|
||||
|
||||
**Key deliverables:**
|
||||
- Landing page: hero, value proposition, Byte→Build→Demonstrate→Defend flow, testimonials, CTA
|
||||
- Program catalog: 5 competency stack cards with role descriptions
|
||||
- Competency stack view: selected stack with 12-18 competencies, progress indicators, microcredential badges
|
||||
- Learner dashboard: active competencies, progress graph, recent artifacts, AI tutor chat mockup, milestones
|
||||
- Byte tutorial viewer: concept panel, worked example, code/design viewer mockup
|
||||
- Build sandbox mockup: IDE UI with toolbar, file explorer, editor area, telemetry sidebar
|
||||
- Assessment/defense mockup: rubric display, AI reviewer panel, oral defense interface, process trace timeline
|
||||
|
||||
**Success criteria:**
|
||||
- All 7 pages render with mock data
|
||||
- Navigation between pages works
|
||||
- AI tutor chat mockup displays pre-scripted responses
|
||||
- Responsive at mobile (375px), tablet (768px), desktop (1280px)
|
||||
- Hover states and interactive elements functional
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: Marketplace Surface UI
|
||||
|
||||
**Goal:** Build all 5 marketplace surface pages with job listings, search, and pricing.
|
||||
|
||||
**Requirements:** REQ-013, REQ-014, REQ-015, REQ-016, REQ-017
|
||||
|
||||
**Key deliverables:**
|
||||
- Job board listing: searchable grid of mock AI-era jobs, filter sidebar, match score cards
|
||||
- Job detail page: full description, required competencies, employer info, AI-matched skills
|
||||
- Employer profile: company overview, logo, open positions, culture mockup
|
||||
- Search/filter UI: semantic search bar, skill tags, filters (seniority, remote, salary), saved searches
|
||||
- Pricing page: job posting packages, talent access plans, feature comparison table
|
||||
|
||||
**Success criteria:**
|
||||
- All 5 pages render with mock data
|
||||
- Filter sidebar interactive (client-side filtering of mock jobs)
|
||||
- Job cards display match scores and skill tags
|
||||
- Pricing table is responsive and readable
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: Employer Dashboard UI
|
||||
|
||||
**Goal:** Build all 4 employer dashboard pages for talent search and posting management.
|
||||
|
||||
**Requirements:** REQ-018, REQ-019, REQ-020, REQ-021
|
||||
|
||||
**Key deliverables:**
|
||||
- Dashboard overview: active postings, applicant pipeline, talent matches, analytics charts
|
||||
- Talent search: searchable candidate database with AI-matched filters, candidate cards
|
||||
- Candidate profile: artifact gallery, process trace summary, defense transcripts, competency graph, microcredentials
|
||||
- Posting management: create/edit/delete job postings, status tracking, applicant list, interview pipeline
|
||||
|
||||
**Success criteria:**
|
||||
- All 4 pages render with mock data
|
||||
- Analytics charts display mock metrics (bar/line/donut charts)
|
||||
- Candidate cards show competency stacks, microcredentials, defense scores
|
||||
- Posting management form inputs are interactive (non-functional submit)
|
||||
|
||||
---
|
||||
|
||||
### Phase 5: Admin Surface UI
|
||||
|
||||
**Goal:** Build all 4 admin surface pages including the interactive competency graph viewer.
|
||||
|
||||
**Requirements:** REQ-022, REQ-023, REQ-024, REQ-025
|
||||
|
||||
**Key deliverables:**
|
||||
- Admin overview: platform metrics (learners, employers, placements, completion rate, NPS), activity feed, system health
|
||||
- Learner management: searchable learner table, detail view, progress tracking, credential log
|
||||
- Competency graph viewer: interactive node/edge graph using react-flow, competency stack nodes, dependency edges
|
||||
- Marketplace moderation: job posting review queue, employer verification queue, flagged content, moderation tools
|
||||
|
||||
**Success criteria:**
|
||||
- All 4 pages render with mock data
|
||||
- Competency graph viewer renders an interactive graph with clickable nodes
|
||||
- Admin table supports sorting and filtering (client-side, mock data)
|
||||
- Moderation queue displays mock flagged items with approve/reject buttons (non-functional)
|
||||
|
||||
---
|
||||
|
||||
### Phase 6: Polish + Integration
|
||||
|
||||
**Goal:** Ensure cross-surface consistency, responsive quality, and component library documentation.
|
||||
|
||||
**Requirements:** REQ-026, REQ-027, REQ-028
|
||||
|
||||
**Key deliverables:**
|
||||
- Cross-surface navigation: role switcher (learner/employer/admin), breadcrumbs, consistent header/footer
|
||||
- Visual consistency: typography scale, color palette, spacing system, dark mode toggle, WCAG AA contrast
|
||||
- Storybook: component documentation, prop tables, usage examples for all primitives and composites
|
||||
|
||||
**Success criteria:**
|
||||
- Role switcher navigates between surfaces
|
||||
- Dark mode toggle works across all surfaces
|
||||
- All pages pass WCAG AA contrast checks
|
||||
- Storybook runs and documents all components
|
||||
- No visual inconsistencies between surfaces
|
||||
|
||||
---
|
||||
|
||||
### Phase 7: Final Review + Ship
|
||||
|
||||
**Goal:** Code review, audit, milestone release.
|
||||
|
||||
**Key deliverables:**
|
||||
- Multi-persona code review (correctness, testing, security, performance, maintainability)
|
||||
- Project health audit (reconstruction test, .ciagent/ file discipline, branch hygiene, commit discipline)
|
||||
- Milestone ship: merge milestone → main, tag v0.1.0, create Gitea release
|
||||
|
||||
**Success criteria:**
|
||||
- Code review: P0 fixes applied, P1+ documented
|
||||
- Audit: all checks pass, project state reconstructable from git log
|
||||
- Ship: v0.1.0 tagged, milestone branch merged to main, Gitea release created
|
||||
- All 28 requirements marked complete
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"version": "0.7.0",
|
||||
"autonomy": {
|
||||
"level": "full",
|
||||
"decision_confidence_threshold": 0.6,
|
||||
"escalation_hooks": ["deploy", "delete_data", "merge_to_main"],
|
||||
"max_revision_iterations": 3,
|
||||
"clarify_budget": 10
|
||||
},
|
||||
"release": {
|
||||
"forge": "gitea",
|
||||
"base_url": "https://git.cloudinit.dev",
|
||||
"owner": "coreci",
|
||||
"repo": "nextcraft"
|
||||
},
|
||||
"secrets": {
|
||||
"scopes": ["gitea"],
|
||||
"env_files": [".env", ".env.secrets", ".env.*"]
|
||||
},
|
||||
"ship": {
|
||||
"per_phase": true,
|
||||
"allow_skip": false,
|
||||
"release_blocking": false,
|
||||
"max_release_retries": 3
|
||||
},
|
||||
"verification": {
|
||||
"bdd_default": false
|
||||
},
|
||||
"personas": {
|
||||
"enabled": true,
|
||||
"territory_enforcement": "warn"
|
||||
},
|
||||
"parallelization": {
|
||||
"enabled": false,
|
||||
"max_concurrent_agents": 1
|
||||
},
|
||||
"ideation": {
|
||||
"max_ideas": 20,
|
||||
"categories": ["security", "quality", "architecture", "coverage", "improvement", "spec", "chaos", "bdd"]
|
||||
},
|
||||
"security": {
|
||||
"bash_allowlist": {
|
||||
"blocked_env_vars": ["GITEA_TOKEN", "GITHUB_TOKEN", "GITLAB_TOKEN"]
|
||||
}
|
||||
},
|
||||
"projects": [],
|
||||
"active_project": null,
|
||||
"milestone": {
|
||||
"version": "v0.1",
|
||||
"name": "nextcraft-ui-prototype",
|
||||
"type": "feature",
|
||||
"branch": "milestone/v0.1-nextcraft-ui-prototype"
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
# Environment files — never commit credentials
|
||||
.env
|
||||
.env.secrets
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# CIAgent secrets
|
||||
.ciagent/.env.secrets
|
||||
|
||||
# Dependencies
|
||||
node_modules/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
venv/
|
||||
|
||||
# Build artifacts
|
||||
dist/
|
||||
build/
|
||||
.next/
|
||||
.turbo/
|
||||
*.tsbuildinfo
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Test coverage
|
||||
coverage/
|
||||
.nyc_output/
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Card, CardBody, Badge } from '@nextcraft/ui';
|
||||
|
||||
export default function AdminHome() {
|
||||
return (
|
||||
<Card>
|
||||
<CardBody className="flex flex-col gap-3">
|
||||
<Badge variant="error">Admin surface</Badge>
|
||||
<h1 className="text-2xl font-bold text-slate-900 dark:text-slate-100">Admin overview</h1>
|
||||
<p className="text-slate-600 dark:text-slate-400">
|
||||
Placeholder — cohort oversight, content governance, and system health arrive in Phase 5.
|
||||
</p>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Shield } from 'lucide-react';
|
||||
|
||||
const LINKS = [
|
||||
{ label: 'Overview', href: '/admin' },
|
||||
{ label: 'Cohorts', href: '/admin/cohorts' },
|
||||
{ label: 'Content', href: '/admin/content' },
|
||||
];
|
||||
|
||||
export default function AdminLayout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<div className="mx-auto flex max-w-7xl gap-6 px-4 py-8 sm:px-6">
|
||||
<aside className="hidden w-56 shrink-0 md:block">
|
||||
<div className="mb-4 flex items-center gap-2 text-sm font-semibold text-slate-500 dark:text-slate-400">
|
||||
<Shield className="h-4 w-4 text-rose-600" />
|
||||
Admin surface
|
||||
</div>
|
||||
<nav className="flex flex-col gap-1">
|
||||
{LINKS.map((l) => (
|
||||
<Link
|
||||
key={l.href}
|
||||
href={l.href}
|
||||
className="rounded-md px-3 py-2 text-sm font-medium text-slate-700 hover:bg-slate-100 dark:text-slate-200 dark:hover:bg-slate-800"
|
||||
>
|
||||
{l.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
</aside>
|
||||
<div className="flex-1">{children}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Card, CardBody, Badge } from '@nextcraft/ui';
|
||||
|
||||
export default function EmployerHome() {
|
||||
return (
|
||||
<Card>
|
||||
<CardBody className="flex flex-col gap-3">
|
||||
<Badge variant="info">Employer surface</Badge>
|
||||
<h1 className="text-2xl font-bold text-slate-900 dark:text-slate-100">Employer overview</h1>
|
||||
<p className="text-slate-600 dark:text-slate-400">
|
||||
Placeholder — talent pipelines, job posts, and evidence-based candidate views arrive in Phase 4.
|
||||
</p>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Building2 } from 'lucide-react';
|
||||
|
||||
const LINKS = [
|
||||
{ label: 'Overview', href: '/employer' },
|
||||
{ label: 'Talent pipeline', href: '/employer/pipeline' },
|
||||
{ label: 'Jobs', href: '/employer/jobs' },
|
||||
];
|
||||
|
||||
export default function EmployerLayout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<div className="mx-auto flex max-w-7xl gap-6 px-4 py-8 sm:px-6">
|
||||
<aside className="hidden w-56 shrink-0 md:block">
|
||||
<div className="mb-4 flex items-center gap-2 text-sm font-semibold text-slate-500 dark:text-slate-400">
|
||||
<Building2 className="h-4 w-4 text-primary-600" />
|
||||
Employer surface
|
||||
</div>
|
||||
<nav className="flex flex-col gap-1">
|
||||
{LINKS.map((l) => (
|
||||
<Link
|
||||
key={l.href}
|
||||
href={l.href}
|
||||
className="rounded-md px-3 py-2 text-sm font-medium text-slate-700 hover:bg-slate-100 dark:text-slate-200 dark:hover:bg-slate-800"
|
||||
>
|
||||
{l.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
</aside>
|
||||
<div className="flex-1">{children}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Card, CardBody, Badge } from '@nextcraft/ui';
|
||||
|
||||
export default function CatalogPage() {
|
||||
return (
|
||||
<Card>
|
||||
<CardBody className="flex flex-col gap-3">
|
||||
<Badge variant="info">Learner · Catalog</Badge>
|
||||
<h1 className="text-2xl font-bold text-slate-900 dark:text-slate-100">Competency catalog</h1>
|
||||
<p className="text-slate-600 dark:text-slate-400">
|
||||
Placeholder — competency stacks, prerequisites, and enrollment arrive in Phase 2.
|
||||
</p>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Card, CardBody, Badge } from '@nextcraft/ui';
|
||||
|
||||
export default function DashboardPage() {
|
||||
return (
|
||||
<Card>
|
||||
<CardBody className="flex flex-col gap-3">
|
||||
<Badge variant="info">Learner · Dashboard</Badge>
|
||||
<h1 className="text-2xl font-bold text-slate-900 dark:text-slate-100">Dashboard</h1>
|
||||
<p className="text-slate-600 dark:text-slate-400">
|
||||
Placeholder — progress, upcoming defenses, and AI tutor prompts arrive in Phase 2.
|
||||
</p>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { GraduationCap } from 'lucide-react';
|
||||
|
||||
const LINKS = [
|
||||
{ label: 'Dashboard', href: '/dashboard' },
|
||||
{ label: 'Catalog', href: '/catalog' },
|
||||
{ label: 'AI Tutor', href: '/tutor' },
|
||||
{ label: 'Defenses', href: '/defenses' },
|
||||
];
|
||||
|
||||
export default function LearnerLayout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<div className="mx-auto flex max-w-7xl gap-6 px-4 py-8 sm:px-6">
|
||||
<aside className="hidden w-56 shrink-0 md:block">
|
||||
<div className="mb-4 flex items-center gap-2 text-sm font-semibold text-slate-500 dark:text-slate-400">
|
||||
<GraduationCap className="h-4 w-4 text-primary-600" />
|
||||
Learner surface
|
||||
</div>
|
||||
<nav className="flex flex-col gap-1">
|
||||
{LINKS.map((l) => (
|
||||
<Link
|
||||
key={l.href}
|
||||
href={l.href}
|
||||
className="rounded-md px-3 py-2 text-sm font-medium text-slate-700 hover:bg-slate-100 dark:text-slate-200 dark:hover:bg-slate-800"
|
||||
>
|
||||
{l.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
</aside>
|
||||
<div className="flex-1">{children}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import Link from 'next/link';
|
||||
import { ArrowRight, GraduationCap, ShoppingBag, Building2, Shield } from 'lucide-react';
|
||||
import { Button, Card, CardBody, Badge } from '@nextcraft/ui';
|
||||
|
||||
const SURFACES = [
|
||||
{
|
||||
href: '/dashboard',
|
||||
title: 'Learner',
|
||||
description: 'Competency stacks, microcredentials, AI tutors, oral defenses.',
|
||||
icon: GraduationCap,
|
||||
color: 'text-primary-600',
|
||||
},
|
||||
{
|
||||
href: '/marketplace',
|
||||
title: 'Marketplace',
|
||||
description: 'AI-era job board matching verified competencies to roles.',
|
||||
icon: ShoppingBag,
|
||||
color: 'text-accent-600',
|
||||
},
|
||||
{
|
||||
href: '/employer',
|
||||
title: 'Employer',
|
||||
description: 'Talent pipelines, evidence-based hiring, culture pages.',
|
||||
icon: Building2,
|
||||
color: 'text-primary-600',
|
||||
},
|
||||
{
|
||||
href: '/admin',
|
||||
title: 'Admin',
|
||||
description: 'Cohort oversight, content governance, system health.',
|
||||
icon: Shield,
|
||||
color: 'text-rose-600',
|
||||
},
|
||||
];
|
||||
|
||||
export default function LearnerHome() {
|
||||
return (
|
||||
<div className="flex flex-col gap-12">
|
||||
<section className="flex flex-col items-start gap-6">
|
||||
<Badge variant="info">v0.1 · UI/UX Prototype</Badge>
|
||||
<h1 className="max-w-3xl text-4xl font-bold tracking-tight text-slate-900 sm:text-5xl dark:text-slate-50">
|
||||
Prove what you can build, not what you can write.
|
||||
</h1>
|
||||
<p className="max-w-2xl text-lg text-slate-600 dark:text-slate-300">
|
||||
Nextcraft is an AI-native outcome school and talent marketplace. Learners earn
|
||||
microcredentials backed by artifacts, process traces, and oral defenses — and employers
|
||||
hire on evidence, not résumés.
|
||||
</p>
|
||||
<div className="flex items-center gap-3">
|
||||
<Link href="/dashboard">
|
||||
<Button size="lg" iconRight={<ArrowRight className="h-4 w-4" />}>
|
||||
Enter the learner surface
|
||||
</Button>
|
||||
</Link>
|
||||
<Link href="/marketplace">
|
||||
<Button variant="outline" size="lg">
|
||||
Browse the marketplace
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{SURFACES.map((s) => (
|
||||
<Link key={s.href} href={s.href}>
|
||||
<Card className="h-full transition-shadow hover:shadow-md">
|
||||
<CardBody className="flex flex-col gap-3">
|
||||
<s.icon className={`h-6 w-6 ${s.color}`} />
|
||||
<h3 className="text-base font-semibold text-slate-900 dark:text-slate-100">{s.title}</h3>
|
||||
<p className="text-sm text-slate-600 dark:text-slate-400">{s.description}</p>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Link>
|
||||
))}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { ShoppingBag } from 'lucide-react';
|
||||
|
||||
const LINKS = [
|
||||
{ label: 'Job board', href: '/marketplace' },
|
||||
{ label: 'Pricing', href: '/marketplace/pricing' },
|
||||
];
|
||||
|
||||
export default function MarketplaceLayout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<div className="mx-auto flex max-w-7xl gap-6 px-4 py-8 sm:px-6">
|
||||
<aside className="hidden w-56 shrink-0 md:block">
|
||||
<div className="mb-4 flex items-center gap-2 text-sm font-semibold text-slate-500 dark:text-slate-400">
|
||||
<ShoppingBag className="h-4 w-4 text-accent-600" />
|
||||
Marketplace surface
|
||||
</div>
|
||||
<nav className="flex flex-col gap-1">
|
||||
{LINKS.map((l) => (
|
||||
<Link
|
||||
key={l.href}
|
||||
href={l.href}
|
||||
className="rounded-md px-3 py-2 text-sm font-medium text-slate-700 hover:bg-slate-100 dark:text-slate-200 dark:hover:bg-slate-800"
|
||||
>
|
||||
{l.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
</aside>
|
||||
<div className="flex-1">{children}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Card, CardBody, Badge } from '@nextcraft/ui';
|
||||
|
||||
export default function MarketplaceHome() {
|
||||
return (
|
||||
<Card>
|
||||
<CardBody className="flex flex-col gap-3">
|
||||
<Badge variant="success">Marketplace surface</Badge>
|
||||
<h1 className="text-2xl font-bold text-slate-900 dark:text-slate-100">AI-era job board</h1>
|
||||
<p className="text-slate-600 dark:text-slate-400">
|
||||
Placeholder — job listings, filters, and match scores arrive in Phase 3.
|
||||
</p>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Card, CardBody, Badge } from '@nextcraft/ui';
|
||||
|
||||
export default function PricingPage() {
|
||||
return (
|
||||
<Card>
|
||||
<CardBody className="flex flex-col gap-3">
|
||||
<Badge variant="success">Marketplace · Pricing</Badge>
|
||||
<h1 className="text-2xl font-bold text-slate-900 dark:text-slate-100">Pricing</h1>
|
||||
<p className="text-slate-600 dark:text-slate-400">
|
||||
Placeholder — employer subscription tiers arrive in a later phase.
|
||||
</p>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
@theme {
|
||||
--font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
|
||||
|
||||
--color-primary-50: #eef2ff;
|
||||
--color-primary-100: #e0e7ff;
|
||||
--color-primary-200: #c7d2fe;
|
||||
--color-primary-300: #a5b4fc;
|
||||
--color-primary-400: #818cf8;
|
||||
--color-primary-500: #6366f1;
|
||||
--color-primary-600: #4f46e5;
|
||||
--color-primary-700: #4338ca;
|
||||
--color-primary-800: #3730a3;
|
||||
--color-primary-900: #312e81;
|
||||
--color-primary-950: #1e1b4b;
|
||||
|
||||
--color-accent-50: #ecfdf5;
|
||||
--color-accent-100: #d1fae5;
|
||||
--color-accent-200: #a7f3d0;
|
||||
--color-accent-300: #6ee7b7;
|
||||
--color-accent-400: #34d399;
|
||||
--color-accent-500: #10b981;
|
||||
--color-accent-600: #059669;
|
||||
--color-accent-700: #047857;
|
||||
--color-accent-800: #065f46;
|
||||
--color-accent-900: #064e3b;
|
||||
--color-accent-950: #022c22;
|
||||
|
||||
--radius-sm: 4px;
|
||||
--radius-md: 8px;
|
||||
--radius-lg: 12px;
|
||||
--radius-xl: 16px;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
html {
|
||||
font-family: var(--font-sans);
|
||||
color-scheme: light;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-white text-slate-900 antialiased;
|
||||
}
|
||||
|
||||
html.dark body {
|
||||
@apply bg-slate-950 text-slate-100;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import type { Metadata } from 'next';
|
||||
import { Inter } from 'next/font/google';
|
||||
import './globals.css';
|
||||
import { ThemeProvider } from '../components/theme-provider';
|
||||
import { NavigationShell } from '../components/navigation-shell';
|
||||
|
||||
const inter = Inter({ subsets: ['latin'], variable: '--font-sans', display: 'swap' });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Nextcraft — AI-native outcome school',
|
||||
description:
|
||||
'Prove what you can build, not what you can write. Nextcraft is an AI-native outcome school and talent marketplace prototype.',
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<html lang="en" className={inter.variable} suppressHydrationWarning>
|
||||
<body className="font-sans">
|
||||
<ThemeProvider>
|
||||
<NavigationShell>{children}</NavigationShell>
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
'use client';
|
||||
|
||||
import { Moon, Sun } from 'lucide-react';
|
||||
import { Button } from '@nextcraft/ui';
|
||||
import { useTheme } from './theme-provider';
|
||||
|
||||
export function DarkModeToggle() {
|
||||
const { mode, toggle } = useTheme();
|
||||
return (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={toggle}
|
||||
aria-label={mode === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'}
|
||||
icon={mode === 'dark' ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}
|
||||
>
|
||||
<span className="sr-only">Toggle theme</span>
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import Link from 'next/link';
|
||||
|
||||
const FOOTER_LINKS = [
|
||||
{ label: 'Learner', href: '/' },
|
||||
{ label: 'Marketplace', href: '/marketplace' },
|
||||
{ label: 'Employer', href: '/employer' },
|
||||
{ label: 'Admin', href: '/admin' },
|
||||
];
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
<footer className="border-t border-slate-200 bg-white py-6 dark:border-slate-800 dark:bg-slate-950">
|
||||
<div className="mx-auto flex max-w-7xl flex-col items-center justify-between gap-3 px-4 text-sm text-slate-500 sm:flex-row sm:px-6 dark:text-slate-400">
|
||||
<p>Nextcraft v0.1 — UI/UX Prototype</p>
|
||||
<nav className="flex items-center gap-4">
|
||||
{FOOTER_LINKS.map((l) => (
|
||||
<Link key={l.href} href={l.href} className="hover:text-slate-900 dark:hover:text-slate-100">
|
||||
{l.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import Link from 'next/link';
|
||||
import { Workflow } from 'lucide-react';
|
||||
import { DarkModeToggle } from './dark-mode-toggle';
|
||||
import { RoleSwitcher } from './role-switcher';
|
||||
|
||||
const NAV_LINKS = [
|
||||
{ label: 'Learner', href: '/' },
|
||||
{ label: 'Marketplace', href: '/marketplace' },
|
||||
{ label: 'Employer', href: '/employer' },
|
||||
{ label: 'Admin', href: '/admin' },
|
||||
];
|
||||
|
||||
export function Header() {
|
||||
return (
|
||||
<header className="sticky top-0 z-30 border-b border-slate-200 bg-white/80 backdrop-blur dark:border-slate-800 dark:bg-slate-950/80">
|
||||
<div className="mx-auto flex h-14 max-w-7xl items-center gap-4 px-4 sm:px-6">
|
||||
<Link href="/" className="flex items-center gap-2 font-semibold">
|
||||
<span className="flex h-8 w-8 items-center justify-center rounded-md bg-primary-600 text-white">
|
||||
<Workflow className="h-4 w-4" />
|
||||
</span>
|
||||
<span className="text-slate-900 dark:text-slate-100">Nextcraft</span>
|
||||
</Link>
|
||||
|
||||
<nav className="ml-4 hidden items-center gap-1 md:flex">
|
||||
{NAV_LINKS.map((l) => (
|
||||
<Link
|
||||
key={l.href}
|
||||
href={l.href}
|
||||
className="rounded-md px-3 py-1.5 text-sm font-medium text-slate-600 hover:bg-slate-100 hover:text-slate-900 dark:text-slate-300 dark:hover:bg-slate-800 dark:hover:text-slate-100"
|
||||
>
|
||||
{l.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<div className="ml-auto flex items-center gap-2">
|
||||
<RoleSwitcher />
|
||||
<DarkModeToggle />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import { Header } from './header';
|
||||
import { Footer } from './footer';
|
||||
|
||||
export function NavigationShell({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col">
|
||||
<Header />
|
||||
<main className="flex-1">{children}</main>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { ChevronDown, GraduationCap, ShoppingBag, Building2, Shield } from 'lucide-react';
|
||||
import type { RoleSurface } from '@nextcraft/types';
|
||||
import { Button } from '@nextcraft/ui';
|
||||
|
||||
const SURFACES: { value: RoleSurface; label: string; href: string; icon: typeof GraduationCap }[] = [
|
||||
{ value: 'learner', label: 'Learner', href: '/', icon: GraduationCap },
|
||||
{ value: 'marketplace', label: 'Marketplace', href: '/marketplace', icon: ShoppingBag },
|
||||
{ value: 'employer', label: 'Employer', href: '/employer', icon: Building2 },
|
||||
{ value: 'admin', label: 'Admin', href: '/admin', icon: Shield },
|
||||
];
|
||||
|
||||
export function RoleSwitcher() {
|
||||
const router = useRouter();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setOpen((v) => !v)}
|
||||
iconRight={<ChevronDown className="h-3.5 w-3.5" />}
|
||||
>
|
||||
Switch surface
|
||||
</Button>
|
||||
{open && (
|
||||
<>
|
||||
<div className="fixed inset-0 z-10" onClick={() => setOpen(false)} aria-hidden />
|
||||
<div className="absolute right-0 z-20 mt-2 w-44 rounded-md border border-slate-200 bg-white py-1 shadow-lg dark:border-slate-800 dark:bg-slate-900">
|
||||
{SURFACES.map((s) => (
|
||||
<button
|
||||
key={s.value}
|
||||
onClick={() => {
|
||||
setOpen(false);
|
||||
router.push(s.href);
|
||||
}}
|
||||
className="flex w-full items-center gap-2 px-3 py-2 text-sm text-slate-700 hover:bg-slate-100 dark:text-slate-200 dark:hover:bg-slate-800"
|
||||
>
|
||||
<s.icon className="h-4 w-4 text-slate-500" />
|
||||
{s.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
'use client';
|
||||
|
||||
import { createContext, useCallback, useContext, useEffect, useMemo, useState, type ReactNode } from 'react';
|
||||
import type { ThemeMode } from '@nextcraft/types';
|
||||
|
||||
interface ThemeContextValue {
|
||||
mode: ThemeMode;
|
||||
toggle: () => void;
|
||||
setMode: (mode: ThemeMode) => void;
|
||||
}
|
||||
|
||||
const ThemeContext = createContext<ThemeContextValue | null>(null);
|
||||
|
||||
export function ThemeProvider({ children }: { children: ReactNode }) {
|
||||
const [mode, setModeState] = useState<ThemeMode>('light');
|
||||
|
||||
useEffect(() => {
|
||||
const stored = typeof window !== 'undefined' ? window.localStorage.getItem('nextcraft-theme') : null;
|
||||
const prefersDark =
|
||||
typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const initial: ThemeMode = stored === 'dark' || stored === 'light' ? stored : prefersDark ? 'dark' : 'light';
|
||||
setModeState(initial);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const root = document.documentElement;
|
||||
if (mode === 'dark') root.classList.add('dark');
|
||||
else root.classList.remove('dark');
|
||||
window.localStorage.setItem('nextcraft-theme', mode);
|
||||
}, [mode]);
|
||||
|
||||
const setMode = useCallback((m: ThemeMode) => setModeState(m), []);
|
||||
const toggle = useCallback(() => setModeState((m) => (m === 'dark' ? 'light' : 'dark')), []);
|
||||
|
||||
const value = useMemo(() => ({ mode, toggle, setMode }), [mode, toggle, setMode]);
|
||||
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
|
||||
}
|
||||
|
||||
export function useTheme(): ThemeContextValue {
|
||||
const ctx = useContext(ThemeContext);
|
||||
if (!ctx) throw new Error('useTheme must be used within ThemeProvider');
|
||||
return ctx;
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
declare module '*.css' {
|
||||
const content: Record<string, string>;
|
||||
export default content;
|
||||
}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
/// <reference path="./.next/types/routes.d.ts" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { NextConfig } from 'next';
|
||||
|
||||
const config: NextConfig = {
|
||||
transpilePackages: ['@nextcraft/ui', '@nextcraft/types', '@nextcraft/mock-data'],
|
||||
reactStrictMode: true,
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "web",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nextcraft/mock-data": "workspace:*",
|
||||
"@nextcraft/types": "workspace:*",
|
||||
"@nextcraft/ui": "workspace:*",
|
||||
"@xyflow/react": "^12.3.5",
|
||||
"lucide-react": "^0.468.0",
|
||||
"next": "^15.1.3",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"recharts": "^2.15.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.0.0",
|
||||
"@types/node": "20.17.6",
|
||||
"@types/react": "^19.0.0",
|
||||
"@types/react-dom": "^19.0.0",
|
||||
"tailwindcss": "^4.0.0",
|
||||
"typescript": "^5.7.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
const config = {
|
||||
plugins: {
|
||||
'@tailwindcss/postcss': {},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"plugins": [{ "name": "next" }],
|
||||
"jsx": "preserve",
|
||||
"moduleResolution": "bundler",
|
||||
"allowJs": true,
|
||||
"noEmit": true,
|
||||
"incremental": true,
|
||||
"paths": {
|
||||
"@/*": ["./*"],
|
||||
"@nextcraft/ui": ["../../packages/ui/src/index.ts"],
|
||||
"@nextcraft/ui/*": ["../../packages/ui/src/*"],
|
||||
"@nextcraft/types": ["../../packages/types/index.ts"],
|
||||
"@nextcraft/types/*": ["../../packages/types/*"],
|
||||
"@nextcraft/mock-data": ["../../packages/mock-data/index.ts"],
|
||||
"@nextcraft/mock-data/*": ["../../packages/mock-data/*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "nextcraft",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@12.3.4",
|
||||
"scripts": {
|
||||
"dev": "turbo dev",
|
||||
"build": "turbo build",
|
||||
"lint": "turbo lint",
|
||||
"typecheck": "turbo typecheck",
|
||||
"clean": "turbo clean && rm -rf node_modules"
|
||||
},
|
||||
"devDependencies": {
|
||||
"turbo": "^2.3.3",
|
||||
"typescript": "^5.7.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Pre-scripted AI tutor responses for the prototype.
|
||||
* Each pair has a Coach (motivational, pacing) and Tutor (concept, Socratic)
|
||||
* variant keyed by intent.
|
||||
*/
|
||||
|
||||
export interface TutorResponse {
|
||||
id: string;
|
||||
intent: string;
|
||||
agent: 'coach' | 'tutor';
|
||||
message: string;
|
||||
suggestedActions?: string[];
|
||||
}
|
||||
|
||||
export const aiTutorResponses: TutorResponse[] = [
|
||||
{
|
||||
id: 'resp-001',
|
||||
intent: 'stuck-on-concept',
|
||||
agent: 'coach',
|
||||
message:
|
||||
"I can see you've hit a wall on RAG Pipeline Design — that's the most common sticking point in this stack. Take a 5-minute break, then come back and let's try a smaller chunk. You've already mastered Tool Use, so the retrieval pieces will click faster than you expect.",
|
||||
suggestedActions: ['Take a break', 'Review a worked example', 'Break it into smaller steps'],
|
||||
},
|
||||
{
|
||||
id: 'resp-002',
|
||||
intent: 'stuck-on-concept',
|
||||
agent: 'tutor',
|
||||
message:
|
||||
"Let's build intuition first. RAG is a two-stage retrieval pipeline: (1) given a query, find the most relevant passages from a corpus, and (2) feed those passages into the model as context so its answer is grounded. Socratic question: why might a lexical search (like BM25) struggle with a query phrased very differently from the document text?",
|
||||
suggestedActions: ['Show me a worked example', 'Compare BM25 vs embeddings', 'Try a practice problem'],
|
||||
},
|
||||
{
|
||||
id: 'resp-003',
|
||||
intent: 'request-pacing',
|
||||
agent: 'coach',
|
||||
message:
|
||||
"You're 62% through the AI Orchestration stack and ahead of your original pace by nine days. Your next two defenses are scheduled in 11 days. I recommend a 3-day sprint on Multi-Agent Communication, then one light day before the defense prep.",
|
||||
suggestedActions: ['Show my weekly plan', 'Schedule a lighter day', 'Adjust pace'],
|
||||
},
|
||||
{
|
||||
id: 'resp-004',
|
||||
intent: 'request-pacing',
|
||||
agent: 'tutor',
|
||||
message:
|
||||
'Here is a suggested sequence: complete the Multi-Agent Communication module in 3 sessions of 45 minutes, then the Memory Systems primer in 2 sessions. After that, one full session for defense rehearsal. This matches the cognitive load profile of learners who succeeded before you.',
|
||||
suggestedActions: ['Lock in this plan', 'Adjust session length', 'See alternatives'],
|
||||
},
|
||||
{
|
||||
id: 'resp-005',
|
||||
intent: 'celebrate-milestone',
|
||||
agent: 'coach',
|
||||
message:
|
||||
"Huge milestone — you just earned your Tool Use & Function Calling microcredential with a 91. That's above the cohort median. You now have three of the five core orchestration credentials. Two more and you qualify for the stack endorsement.",
|
||||
suggestedActions: ['See path to endorsement', 'Share with employer partners', 'Pick the next competency'],
|
||||
},
|
||||
{
|
||||
id: 'resp-006',
|
||||
intent: 'celebrate-milestone',
|
||||
agent: 'tutor',
|
||||
message:
|
||||
'Your artifact for this competency showed clean handling of structured outputs and graceful fallback when the model returned malformed JSON. For your next competency, I recommend exploring how tool-use composes with multi-agent communication — that will set you up for the stack endorsement.',
|
||||
suggestedActions: ['Start Multi-Agent Communication', 'Review a harder artifact example', 'Read a case study'],
|
||||
},
|
||||
{
|
||||
id: 'resp-007',
|
||||
intent: 'explain-socratic',
|
||||
agent: 'tutor',
|
||||
message:
|
||||
"Think about agent memory as three layers: short-term context (the current conversation window), episodic memory (records of past agent runs you can replay), and long-term semantic memory (consolidated knowledge you distill over time). Question: if an agent handles 10,000 sessions a day, which layer would you consolidate into long-term memory, and how often?",
|
||||
suggestedActions: ['I have an answer', 'Give me a hint', 'Show a worked example'],
|
||||
},
|
||||
{
|
||||
id: 'resp-008',
|
||||
intent: 'defense-prep',
|
||||
agent: 'coach',
|
||||
message:
|
||||
"Your oral defense for Multi-Agent Communication is in 11 days. You are well prepared — your process trace shows 14 distinct practice runs. Let's spend one session rehearsing the edge-case questions, then a mock defense with me acting as the panel.",
|
||||
suggestedActions: ['Start mock defense', 'Review edge-case questions', 'See my process trace'],
|
||||
},
|
||||
{
|
||||
id: 'resp-009',
|
||||
intent: 'defense-prep',
|
||||
agent: 'tutor',
|
||||
message:
|
||||
"In a defense you'll be asked to explain your design trade-offs, not just your code. Be ready to answer: why did you choose a blackboard architecture over direct message passing? What failure mode did you observe under load, and how did you mitigate it? Let's rehearse one question now.",
|
||||
suggestedActions: ['Rehearse question 1', 'Rehearse question 2', 'See scoring rubric'],
|
||||
},
|
||||
{
|
||||
id: 'resp-010',
|
||||
intent: 'career-guidance',
|
||||
agent: 'coach',
|
||||
message:
|
||||
"Based on your competencies and artifacts, you match strongly to AI Orchestration Engineer roles (96%) and Agent Reliability Engineer roles (90%). Two employers are actively hiring for these profiles. Want me to show you the matching jobs and the remaining competencies they require?",
|
||||
suggestedActions: ['Show matching jobs', 'See competency gaps', 'Build a targeted plan'],
|
||||
},
|
||||
{
|
||||
id: 'resp-011',
|
||||
intent: 'career-guidance',
|
||||
agent: 'tutor',
|
||||
message:
|
||||
'Your portfolio demonstrates multi-agent systems and evaluation, which are the two most-cited skills in senior orchestration postings. The gap to a Staff-level role is observability and cost optimization. I recommend the Agent Reliability Engineer competencies as your next sprint.',
|
||||
suggestedActions: ['Start reliability sprint', 'See a staff-level job', 'Compare skill gaps'],
|
||||
},
|
||||
{
|
||||
id: 'resp-012',
|
||||
intent: 'check-understanding',
|
||||
agent: 'tutor',
|
||||
message:
|
||||
'Quick check: in a plan-and-execute agent, what is the advantage of re-planning after each tool call rather than executing the full plan from the start? Take your time — there is no penalty for thinking.',
|
||||
suggestedActions: ['I have an answer', 'Give me a hint', 'Skip this check'],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,184 @@
|
||||
import type { Candidate } from '@nextcraft/types';
|
||||
|
||||
export const candidates: Candidate[] = [
|
||||
{
|
||||
id: 'cand-001',
|
||||
name: 'Maya Okonkwo',
|
||||
avatar: 'https://i.pravatar.cc/150?img=1',
|
||||
headline: 'AI Orchestration Engineer · Multi-agent systems, RAG, evaluation',
|
||||
competencyStackId: 'stack-orchestration',
|
||||
microcredentials: 11,
|
||||
artifactCount: 12,
|
||||
defenseScore: 92,
|
||||
matchScore: 96,
|
||||
bio: 'Shipped two production agent systems handling 4M+ queries/week. Evidence portfolio includes a multi-agent research assistant with full eval harness.',
|
||||
},
|
||||
{
|
||||
id: 'cand-002',
|
||||
name: 'Devon Park',
|
||||
avatar: 'https://i.pravatar.cc/150?img=2',
|
||||
headline: 'AI Safety Researcher · Alignment, red teaming, interpretability',
|
||||
competencyStackId: 'stack-safety',
|
||||
microcredentials: 10,
|
||||
artifactCount: 9,
|
||||
defenseScore: 90,
|
||||
matchScore: 91,
|
||||
bio: 'Published two workshop papers on jailbreak robustness. Runs an automated red-team suite with 1,200+ probes across three model families.',
|
||||
},
|
||||
{
|
||||
id: 'cand-003',
|
||||
name: 'Priya Iyer',
|
||||
avatar: 'https://i.pravatar.cc/150?img=3',
|
||||
headline: 'Human-AI Product Designer · Agentic UX, trust calibration',
|
||||
competencyStackId: 'stack-designer',
|
||||
microcredentials: 9,
|
||||
artifactCount: 11,
|
||||
defenseScore: 88,
|
||||
matchScore: 89,
|
||||
bio: 'Designed the transparency system for an assistant with 2M MAU. Portfolio includes a full human-in-the-loop review pattern library.',
|
||||
},
|
||||
{
|
||||
id: 'cand-004',
|
||||
name: 'Tomás Vega',
|
||||
avatar: 'https://i.pravatar.cc/150?img=4',
|
||||
headline: 'LLM Application Developer · RAG, function calling, streaming',
|
||||
competencyStackId: 'stack-orchestration',
|
||||
microcredentials: 12,
|
||||
artifactCount: 10,
|
||||
defenseScore: 87,
|
||||
matchScore: 93,
|
||||
bio: 'Built a document-grounded Q&A product from zero to 50K daily actives. Specializes in retrieval quality and output validation.',
|
||||
},
|
||||
{
|
||||
id: 'cand-005',
|
||||
name: 'Hana Lindqvist',
|
||||
avatar: 'https://i.pravatar.cc/150?img=5',
|
||||
headline: 'Computational Biologist · Drug discovery, ML pipelines',
|
||||
competencyStackId: 'stack-science',
|
||||
microcredentials: 13,
|
||||
artifactCount: 8,
|
||||
defenseScore: 91,
|
||||
matchScore: 88,
|
||||
bio: 'Active-learning pipeline nominated for a phenotype-prediction benchmark. Reproducible workflows with Snakemake and containerized HPC jobs.',
|
||||
},
|
||||
{
|
||||
id: 'cand-006',
|
||||
name: 'Marcus Bell',
|
||||
avatar: 'https://i.pravatar.cc/150?img=6',
|
||||
headline: 'Robotics Operations Specialist · Vision systems, field AI',
|
||||
competencyStackId: 'stack-operator',
|
||||
microcredentials: 8,
|
||||
artifactCount: 7,
|
||||
defenseScore: 84,
|
||||
matchScore: 78,
|
||||
bio: 'Five years on a warehouse robotics fleet. Built an anomaly-triage dashboard that cut false-positive escalations by 40%.',
|
||||
},
|
||||
{
|
||||
id: 'cand-007',
|
||||
name: 'Sofia Marchetti',
|
||||
avatar: 'https://i.pravatar.cc/150?img=7',
|
||||
headline: 'AI Governance Lead · NIST AI RMF, audit, model cards',
|
||||
competencyStackId: 'stack-safety',
|
||||
microcredentials: 11,
|
||||
artifactCount: 6,
|
||||
defenseScore: 89,
|
||||
matchScore: 85,
|
||||
bio: 'Stood up AI governance at a 5,000-person org. Authored 14 model cards and a risk register covering 30+ deployed systems.',
|
||||
},
|
||||
{
|
||||
id: 'cand-008',
|
||||
name: 'Liam Chen',
|
||||
avatar: 'https://i.pravatar.cc/150?img=8',
|
||||
headline: 'Agent Reliability Engineer · Observability, tracing, SRE',
|
||||
competencyStackId: 'stack-orchestration',
|
||||
microcredentials: 10,
|
||||
artifactCount: 9,
|
||||
defenseScore: 86,
|
||||
matchScore: 90,
|
||||
bio: 'Owns tracing for an agent platform serving 200+ internal teams. Built a token-cost alerting system that saved $1.2M/year.',
|
||||
},
|
||||
{
|
||||
id: 'cand-009',
|
||||
name: 'Amara Diallo',
|
||||
avatar: 'https://i.pravatar.cc/150?img=9',
|
||||
headline: 'Climate ML Scientist · Forecasting, data assimilation, PINNs',
|
||||
competencyStackId: 'stack-science',
|
||||
microcredentials: 12,
|
||||
artifactCount: 8,
|
||||
defenseScore: 90,
|
||||
matchScore: 84,
|
||||
bio: 'Downscaled GCM output for a regional energy grid operator. Physics-informed model improved 72-hour wind forecasts by 18%.',
|
||||
},
|
||||
{
|
||||
id: 'cand-010',
|
||||
name: 'Ethan Whitfield',
|
||||
avatar: 'https://i.pravatar.cc/150?img=10',
|
||||
headline: 'AI Product Manager · Roadmapping, AI UX, metrics',
|
||||
competencyStackId: 'stack-designer',
|
||||
microcredentials: 9,
|
||||
artifactCount: 5,
|
||||
defenseScore: 82,
|
||||
matchScore: 80,
|
||||
bio: 'Shipped an agentic coding assistant to 30K developers. Defined the success metrics and evaluation framework for the v1 launch.',
|
||||
},
|
||||
{
|
||||
id: 'cand-011',
|
||||
name: 'Yuki Tanaka',
|
||||
avatar: 'https://i.pravatar.cc/150?img=11',
|
||||
headline: 'Evaluation Engineer · LLM-as-judge, regression suites',
|
||||
competencyStackId: 'stack-orchestration',
|
||||
microcredentials: 10,
|
||||
artifactCount: 8,
|
||||
defenseScore: 85,
|
||||
matchScore: 86,
|
||||
bio: 'Built an eval platform that runs 50K+ judged samples per model release. Calibrated LLM-as-judge against human panels to 0.87 agreement.',
|
||||
},
|
||||
{
|
||||
id: 'cand-012',
|
||||
name: 'Olu Adeyemi',
|
||||
avatar: 'https://i.pravatar.cc/150?img=12',
|
||||
headline: 'Conversation Designer · Dialogue flows, persona systems',
|
||||
competencyStackId: 'stack-designer',
|
||||
microcredentials: 8,
|
||||
artifactCount: 7,
|
||||
defenseScore: 83,
|
||||
matchScore: 77,
|
||||
bio: 'Designed repair flows that reduced user frustration escalations by 35%. Authored a persona consistency framework now used company-wide.',
|
||||
},
|
||||
{
|
||||
id: 'cand-013',
|
||||
name: 'Nadia Petrova',
|
||||
avatar: 'https://i.pravatar.cc/150?img=13',
|
||||
headline: 'Materials ML Engineer · Property prediction, active learning',
|
||||
competencyStackId: 'stack-science',
|
||||
microcredentials: 11,
|
||||
artifactCount: 9,
|
||||
defenseScore: 88,
|
||||
matchScore: 82,
|
||||
bio: 'Active-learning loop identified three experimentally-validated novel alloys. Maintains an open-source DFT active-learning toolkit.',
|
||||
},
|
||||
{
|
||||
id: 'cand-014',
|
||||
name: 'Rafael Costa',
|
||||
avatar: 'https://i.pravatar.cc/150?img=14',
|
||||
headline: 'Edge AI Engineer · Quantization, TensorRT, field deployment',
|
||||
competencyStackId: 'stack-operator',
|
||||
microcredentials: 9,
|
||||
artifactCount: 8,
|
||||
defenseScore: 84,
|
||||
matchScore: 83,
|
||||
bio: 'Quantized a vision model from 240MB to 11MB with <1% accuracy loss. Deployed to 3,000+ edge devices with OTA model updates.',
|
||||
},
|
||||
{
|
||||
id: 'cand-015',
|
||||
name: 'Ingrid Solberg',
|
||||
avatar: 'https://i.pravatar.cc/150?img=15',
|
||||
headline: 'AI Red Team Lead · Adversarial testing, disclosure, policy',
|
||||
competencyStackId: 'stack-safety',
|
||||
microcredentials: 10,
|
||||
artifactCount: 7,
|
||||
defenseScore: 87,
|
||||
matchScore: 88,
|
||||
bio: 'Led red-teaming for two frontier model releases. Coordinated three coordinated disclosures with partner labs.',
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,167 @@
|
||||
import type { CompetencyStack, Competency } from '@nextcraft/types';
|
||||
|
||||
let idCounter = 0;
|
||||
const cid = (prefix: string) => `${prefix}-c${(++idCounter).toString().padStart(3, '0')}`;
|
||||
|
||||
function makeCompetency(
|
||||
stackId: string,
|
||||
name: string,
|
||||
description: string,
|
||||
status: Competency['status'],
|
||||
prerequisites: string[] = [],
|
||||
): Competency {
|
||||
return {
|
||||
id: cid(stackId),
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
stackId,
|
||||
prerequisites,
|
||||
microcredentialId: status === 'mastered' ? `mc-${cid(stackId)}` : null,
|
||||
};
|
||||
}
|
||||
|
||||
// --- Stack 1: AI Orchestration Engineer (15 competencies) ---
|
||||
const orchestrationComps: Competency[] = [
|
||||
makeCompetency('stack-orchestration', 'Agent Architecture Patterns', 'ReAct, plan-and-execute, reflexion, and reflexion-based agent topologies.', 'mastered'),
|
||||
makeCompetency('stack-orchestration', 'Multi-Agent Communication', 'Message passing, shared memory blackboards, and inter-agent protocol design.', 'in_progress', ['stack-orchestration-c001']),
|
||||
makeCompetency('stack-orchestration', 'Tool Use & Function Calling', 'Defining tool schemas, binding tools to models, and handling structured outputs.', 'mastered'),
|
||||
makeCompetency('stack-orchestration', 'Prompt Engineering Fundamentals', 'Few-shot, chain-of-thought, and instruction tuning for reliable model behavior.', 'mastered'),
|
||||
makeCompetency('stack-orchestration', 'RAG Pipeline Design', 'Chunking strategies, hybrid retrieval, reranking, and context window management.', 'in_progress'),
|
||||
makeCompetency('stack-orchestration', 'Vector Databases & Embeddings', 'Embedding model selection, indexing (HNSW, IVF), and metadata filtering.', 'available', ['stack-orchestration-c005']),
|
||||
makeCompetency('stack-orchestration', 'LLM Evaluation & Metrics', 'LLM-as-judge, human eval panels, regression suites, and drift detection.', 'available'),
|
||||
makeCompetency('stack-orchestration', 'Guardrails & Output Validation', 'Schema validation, safety classifiers, and fallback response strategies.', 'available', ['stack-orchestration-c003']),
|
||||
makeCompetency('stack-orchestration', 'Agent Memory Systems', 'Short-term context, episodic memory, and long-term knowledge consolidation.', 'locked', ['stack-orchestration-c002', 'stack-orchestration-c006']),
|
||||
makeCompetency('stack-orchestration', 'Workflow Orchestration', 'DAG-based pipelines, conditional branching, and human-in-the-loop checkpoints.', 'locked', ['stack-orchestration-c001']),
|
||||
makeCompetency('stack-orchestration', 'Model Routing & Cascading', 'Cost-aware routing, small-to-large cascades, and fallback model strategies.', 'locked', ['stack-orchestration-c008']),
|
||||
makeCompetency('stack-orchestration', 'Streaming & Incremental Output', 'Token streaming, partial JSON parsing, and progressive UI rendering.', 'available'),
|
||||
makeCompetency('stack-orchestration', 'Observability for Agents', 'Tracing spans, token cost tracking, and latency profiling across agent calls.', 'available'),
|
||||
makeCompetency('stack-orchestration', 'Cost Optimization Strategies', 'Caching, prompt compression, and batch inference for production cost control.', 'locked', ['stack-orchestration-c011']),
|
||||
makeCompetency('stack-orchestration', 'Production Deployment Patterns', 'Blue-green deploys, shadow traffic, and rollback for agent workloads.', 'locked', ['stack-orchestration-c010']),
|
||||
];
|
||||
|
||||
// --- Stack 2: AI Safety & Governance Lead (14 competencies) ---
|
||||
const safetyComps: Competency[] = [
|
||||
makeCompetency('stack-safety', 'Alignment Fundamentals', 'RLHF, DPO, and constitutional AI approaches to value alignment.', 'in_progress'),
|
||||
makeCompetency('stack-safety', 'Red Teaming Methodologies', 'Adversarial prompting, automated red-team suites, and vulnerability disclosure.', 'available'),
|
||||
makeCompetency('stack-safety', 'Model Card Authoring', 'Documenting capabilities, limitations, intended use, and known failure modes.', 'mastered'),
|
||||
makeCompetency('stack-safety', 'Bias Auditing', 'Disparate impact testing across demographics and protected attributes.', 'in_progress', ['stack-safety-c003']),
|
||||
makeCompetency('stack-safety', 'AI Policy Frameworks', 'NIST AI RMF, EU AI Act, and ISO/IEC 42001 compliance mapping.', 'available'),
|
||||
makeCompetency('stack-safety', 'Risk Taxonomy & Classification', 'Harm severity scales, likelihood scoring, and risk register maintenance.', 'available', ['stack-safety-c005']),
|
||||
makeCompetency('stack-safety', 'Interpretability Techniques', 'Attention probing, activation patching, and circuit analysis.', 'locked', ['stack-safety-c001']),
|
||||
makeCompetency('stack-safety', 'Incident Response for AI', 'Detection, containment, root-cause analysis, and postmortem for AI failures.', 'locked', ['stack-safety-c006']),
|
||||
makeCompetency('stack-safety', 'Data Provenance & Lineage', 'Training data tracking, consent management, and deletion workflows.', 'available'),
|
||||
makeCompetency('stack-safety', 'Jailbreak & Prompt Injection Defense', 'Input sanitization, instruction hierarchy, and indirect injection mitigation.', 'available', ['stack-safety-c002']),
|
||||
makeCompetency('stack-safety', 'Model Monitoring in Production', 'Drift detection, output distribution tracking, and alerting thresholds.', 'locked', ['stack-safety-c008']),
|
||||
makeCompetency('stack-safety', 'Privacy-Preserving ML', 'Differential privacy, federated learning, and synthetic data generation.', 'locked', ['stack-safety-c009']),
|
||||
makeCompetency('stack-safety', 'Governance Documentation', 'Audit trails, decision logs, and accountability matrices for AI systems.', 'available'),
|
||||
makeCompetency('stack-safety', 'Stakeholder Communication', 'Translating technical risk findings for executives, regulators, and users.', 'available', ['stack-safety-c013']),
|
||||
];
|
||||
|
||||
// --- Stack 3: Human-AI Product Designer (13 competencies) ---
|
||||
const designerComps: Competency[] = [
|
||||
makeCompetency('stack-designer', 'Agentic Interaction Patterns', 'Designing for delegating, interrupting, and reviewing autonomous agents.', 'in_progress'),
|
||||
makeCompetency('stack-designer', 'Conversational UX', 'Multi-turn dialogue design, intent modeling, and repair flows.', 'mastered'),
|
||||
makeCompetency('stack-designer', 'AI Transparency Patterns', 'Confidence indicators, source attribution, and model limitation disclosure.', 'in_progress', ['stack-designer-c002']),
|
||||
makeCompetency('stack-designer', 'Human-in-the-Loop Design', 'Approval gates, escalation paths, and override affordances.', 'available', ['stack-designer-c001']),
|
||||
makeCompetency('stack-designer', 'Prompt UX', 'Designing prompt composition surfaces, suggestions, and templates.', 'available'),
|
||||
makeCompetency('stack-designer', 'Failure & Fallback Design', 'Graceful degradation, error states, and recovery flows for AI features.', 'available', ['stack-designer-c003']),
|
||||
makeCompetency('stack-designer', 'Multimodal Interface Design', 'Voice + touch + visual coordination across modalities.', 'locked', ['stack-designer-c002']),
|
||||
makeCompetency('stack-designer', 'Trust & Calibration', 'User mental model alignment, expectation setting, and over-trust mitigation.', 'available', ['stack-designer-c003']),
|
||||
makeCompetency('stack-designer', 'Accessibility for AI Interfaces', 'Screen-reader-friendly AI output, cognitive load, and reading-level tuning.', 'available'),
|
||||
makeCompetency('stack-designer', 'Persona & Tone Systems', 'Character design for AI assistants, consistency, and contextual adaptation.', 'available', ['stack-designer-c005']),
|
||||
makeCompetency('stack-designer', 'Evaluation of AI UX', 'Task success, satisfaction, and reliance metrics for AI-assisted workflows.', 'locked', ['stack-designer-c008']),
|
||||
makeCompetency('stack-designer', 'Onboarding to Agentic Systems', 'Progressive disclosure, first-run experience, and capability scaffolding.', 'available', ['stack-designer-c004']),
|
||||
makeCompetency('stack-designer', 'AI Ethics in Product Design', 'Consent, dark-pattern avoidance, and dignity-preserving automation.', 'available', ['stack-designer-c009']),
|
||||
];
|
||||
|
||||
// --- Stack 4: AI-Augmented Field Operator (12 competencies) ---
|
||||
const operatorComps: Competency[] = [
|
||||
makeCompetency('stack-operator', 'AI Co-Pilot Operation', 'Interacting with voice and tablet-based AI assistants in field conditions.', 'in_progress'),
|
||||
makeCompetency('stack-operator', 'Robotics Safety Protocols', 'Lockout/tagout, collision avoidance, and emergency stop procedures.', 'mastered'),
|
||||
makeCompetency('stack-operator', 'Predictive Maintenance Alerts', 'Interpreting ML-based anomaly scores and scheduling interventions.', 'available', ['stack-operator-c002']),
|
||||
makeCompetency('stack-operator', 'Computer Vision Inspection', 'Operating vision-based quality control stations and tuning thresholds.', 'available'),
|
||||
makeCompetency('stack-operator', 'Sensor Data Interpretation', 'Reading IoT telemetry dashboards and recognizing fault signatures.', 'in_progress', ['stack-operator-c003']),
|
||||
makeCompetency('stack-operator', 'Digital Twin Fundamentals', 'Navigating virtual replicas of physical assets for simulation and planning.', 'locked', ['stack-operator-c005']),
|
||||
makeCompetency('stack-operator', 'Augmented Reality Overlays', 'Using AR headsets for guided assembly, annotation, and remote assistance.', 'available'),
|
||||
makeCompetency('stack-operator', 'Edge Model Deployment', 'Pushing model updates to on-device inference hardware in the field.', 'locked', ['stack-operator-c006']),
|
||||
makeCompetency('stack-operator', 'Calibration & Drift Correction', 'Maintaining sensor accuracy and recognizing model drift in production.', 'available', ['stack-operator-c004']),
|
||||
makeCompetency('stack-operator', 'Field Data Collection', 'Structured annotation, labeling workflows, and high-quality dataset capture.', 'available'),
|
||||
makeCompetency('stack-operator', 'Autonomous System Supervision', 'Monitoring fleets of semi-autonomous units and intervening on exceptions.', 'locked', ['stack-operator-c001']),
|
||||
makeCompetency('stack-operator', 'Safety-Critical Decision Making', 'Knowing when to override AI recommendations and escalate to humans.', 'available', ['stack-operator-c002']),
|
||||
];
|
||||
|
||||
// --- Stack 5: Computational Sciences Practitioner (16 competencies) ---
|
||||
const scienceComps: Competency[] = [
|
||||
makeCompetency('stack-science', 'Scientific Computing with Python', 'NumPy, SciPy, pandas, and Jupyter workflows for research-grade analysis.', 'mastered'),
|
||||
makeCompetency('stack-science', 'ML for Scientific Discovery', 'Surrogate models, property prediction, and active learning loops.', 'in_progress', ['stack-science-c001']),
|
||||
makeCompetency('stack-science', 'Molecular & Materials Simulation', 'DFT, molecular dynamics, and ML potentials for materials screening.', 'available'),
|
||||
makeCompetency('stack-science', 'Climate Modeling Fundamentals', 'GCM structure, downscaling, and emissions scenario interpretation.', 'available'),
|
||||
makeCompetency('stack-science', 'Bioinformatics Pipelines', 'Sequence alignment, variant calling, and differential expression analysis.', 'in_progress'),
|
||||
makeCompetency('stack-science', 'High-Performance Computing', 'MPI, OpenMP, GPU offloading, and job scheduling on HPC clusters.', 'available', ['stack-science-c001']),
|
||||
makeCompetency('stack-science', 'Scientific Data Visualization', 'Matplotlib, Plotly, ParaView, and domain-specific plotting conventions.', 'mastered'),
|
||||
makeCompetency('stack-science', 'Reproducible Research Practices', 'Containerization, workflow managers (Snakemake, Nextflow), and DOIs.', 'available', ['stack-science-c006']),
|
||||
makeCompetency('stack-science', 'Statistical Inference', 'Bayesian methods, hypothesis testing, and uncertainty quantification.', 'available'),
|
||||
makeCompetency('stack-science', 'Physics-Informed Neural Networks', 'Embedding governing equations as constraints in ML models.', 'locked', ['stack-science-c002']),
|
||||
makeCompetency('stack-science', 'Generative Models for Science', 'Diffusion models for molecule generation and protein structure sampling.', 'locked', ['stack-science-c010']),
|
||||
makeCompetency('stack-science', 'Causal Inference Methods', 'Do-calculus, instrumental variables, and counterfactual reasoning.', 'available', ['stack-science-c009']),
|
||||
makeCompetency('stack-science', 'Experiment Design', 'DOE, factorial designs, and sample-size planning for costly experiments.', 'available'),
|
||||
makeCompetency('stack-science', 'Data Assimilation', 'EnKF, 4D-Var, and real-time integration of observations into models.', 'locked', ['stack-science-c004']),
|
||||
makeCompetency('stack-science', 'Scientific Writing with AI', 'Literature review automation, manuscript drafting assistance, and citation tools.', 'available'),
|
||||
makeCompetency('stack-science', 'Open Science & FAIR Data', 'Findable, accessible, interoperable, reusable data stewardship.', 'available', ['stack-science-c008']),
|
||||
];
|
||||
|
||||
export const competencyStacks: CompetencyStack[] = [
|
||||
{
|
||||
id: 'stack-orchestration',
|
||||
name: 'AI Orchestration Engineer',
|
||||
targetRoles: 'Agent design, multi-agent systems, AI workflow automation',
|
||||
description:
|
||||
'Design and operate systems of cooperating AI agents. Master tool use, retrieval, memory, evaluation, and production deployment of agentic workflows.',
|
||||
competencies: orchestrationComps,
|
||||
color: 'indigo',
|
||||
icon: 'Workflow',
|
||||
},
|
||||
{
|
||||
id: 'stack-safety',
|
||||
name: 'AI Safety & Governance Lead',
|
||||
targetRoles: 'Alignment, audit, policy, risk',
|
||||
description:
|
||||
'Ensure AI systems are aligned, auditable, and compliant. Lead red-teaming, bias audits, incident response, and governance documentation.',
|
||||
competencies: safetyComps,
|
||||
color: 'rose',
|
||||
icon: 'ShieldCheck',
|
||||
},
|
||||
{
|
||||
id: 'stack-designer',
|
||||
name: 'Human-AI Product Designer',
|
||||
targetRoles: 'UX for agentic systems, AI interaction design',
|
||||
description:
|
||||
'Design interfaces where humans and AI agents collaborate. Master transparency, trust calibration, failure design, and agentic interaction patterns.',
|
||||
competencies: designerComps,
|
||||
color: 'violet',
|
||||
icon: 'Sparkles',
|
||||
},
|
||||
{
|
||||
id: 'stack-operator',
|
||||
name: 'AI-Augmented Field Operator',
|
||||
targetRoles: 'Skilled trades + AI co-pilots, robotics operations',
|
||||
description:
|
||||
'Operate AI-augmented equipment in the field. Pair skilled trades with AI co-pilots, robotics supervision, predictive maintenance, and AR-guided workflows.',
|
||||
competencies: operatorComps,
|
||||
color: 'emerald',
|
||||
icon: 'Wrench',
|
||||
},
|
||||
{
|
||||
id: 'stack-science',
|
||||
name: 'Computational Sciences Practitioner',
|
||||
targetRoles: 'Bio, materials, climate + AI',
|
||||
description:
|
||||
'Apply ML to scientific discovery in biology, materials, and climate. Master scientific computing, simulation, PINNs, and reproducible research.',
|
||||
competencies: scienceComps,
|
||||
color: 'cyan',
|
||||
icon: 'Atom',
|
||||
},
|
||||
];
|
||||
|
||||
export const allCompetencies: Competency[] = competencyStacks.flatMap((s) => s.competencies);
|
||||
@@ -0,0 +1,134 @@
|
||||
import type { Employer } from '@nextcraft/types';
|
||||
|
||||
export const employers: Employer[] = [
|
||||
{
|
||||
id: 'emp-openai',
|
||||
name: 'OpenAI Labs',
|
||||
logo: 'https://placehold.co/80x80/indigo/white?text=OA',
|
||||
description:
|
||||
'Mock employer building frontier AI systems. We build and deploy large language models and agentic tools used by millions of developers and consumers.',
|
||||
industry: 'Artificial Intelligence',
|
||||
size: '2,000+',
|
||||
location: 'San Francisco, CA',
|
||||
website: 'https://example.com/openai',
|
||||
socialLinks: { twitter: 'https://example.com/openai/x', linkedin: 'https://example.com/openai/li' },
|
||||
culture: 'Research-driven, shipping-paced, safety-conscious. We pair frontier research with product rigor.',
|
||||
},
|
||||
{
|
||||
id: 'emp-anthropic',
|
||||
name: 'Anthropic Research',
|
||||
logo: 'https://placehold.co/80x80/amber/white?text=AN',
|
||||
description:
|
||||
'Mock employer focused on AI safety and alignment. We build reliable, interpretable, and steerable AI systems.',
|
||||
industry: 'AI Safety',
|
||||
size: '1,000+',
|
||||
location: 'San Francisco, CA',
|
||||
website: 'https://example.com/anthropic',
|
||||
socialLinks: { twitter: 'https://example.com/anthropic/x', linkedin: 'https://example.com/anthropic/li' },
|
||||
culture: 'Safety-first, evidence-based, calm-paced. We value thoroughness over speed when stakes are high.',
|
||||
},
|
||||
{
|
||||
id: 'emp-huggingface',
|
||||
name: 'Hugging Face',
|
||||
logo: 'https://placehold.co/80x80/yellow/black?text=HF',
|
||||
description:
|
||||
'Mock employer building the open-source AI community. We host models, datasets, and demos for the global ML community.',
|
||||
industry: 'Open Source AI',
|
||||
size: '500+',
|
||||
location: 'New York, NY',
|
||||
website: 'https://example.com/hf',
|
||||
socialLinks: { twitter: 'https://example.com/hf/x', linkedin: 'https://example.com/hf/li' },
|
||||
culture: 'Community-first, open-by-default, remote-friendly. We ship in the open with thousands of contributors.',
|
||||
},
|
||||
{
|
||||
id: 'emp-scaleai',
|
||||
name: 'Scale AI',
|
||||
logo: 'https://placehold.co/80x80/violet/white?text=SC',
|
||||
description:
|
||||
'Mock employer providing data and evaluation infrastructure for frontier AI. We power the RLHF and eval pipelines behind many model releases.',
|
||||
industry: 'AI Infrastructure',
|
||||
size: '1,500+',
|
||||
location: 'San Francisco, CA',
|
||||
website: 'https://example.com/scale',
|
||||
socialLinks: { twitter: 'https://example.com/scale/x', linkedin: 'https://example.com/scale/li' },
|
||||
culture: 'Infrastructure-minded, quality-obsessed, enterprise-aware. We bridge research and production data.',
|
||||
},
|
||||
{
|
||||
id: 'emp-perplexity',
|
||||
name: 'Perplexity',
|
||||
logo: 'https://placehold.co/80x80/teal/white?text=PX',
|
||||
description:
|
||||
'Mock employer building an AI-powered answer engine. We combine retrieval, generation, and citations for trustworthy answers.',
|
||||
industry: 'AI Search',
|
||||
size: '300+',
|
||||
location: 'San Francisco, CA',
|
||||
website: 'https://example.com/perplexity',
|
||||
socialLinks: { twitter: 'https://example.com/perplexity/x', linkedin: 'https://example.com/perplexity/li' },
|
||||
culture: 'Answer-focused, fast-iterating, citation-proud. We treat groundedness as a product feature.',
|
||||
},
|
||||
{
|
||||
id: 'emp-cohere',
|
||||
name: 'Cohere',
|
||||
logo: 'https://placehold.co/80x80/pink/white?text=CO',
|
||||
description:
|
||||
'Mock employer building enterprise-grade language models. We specialize in retrieval, multilinguality, and data privacy for regulated industries.',
|
||||
industry: 'Enterprise LLMs',
|
||||
size: '400+',
|
||||
location: 'Toronto, Canada',
|
||||
website: 'https://example.com/cohere',
|
||||
socialLinks: { twitter: 'https://example.com/cohere/x', linkedin: 'https://example.com/cohere/li' },
|
||||
culture: 'Enterprise-aware, research-active, multilingual. We ship models that work in 100+ languages.',
|
||||
},
|
||||
{
|
||||
id: 'emp-mistral',
|
||||
name: 'Mistral AI',
|
||||
logo: 'https://placehold.co/80x80/red/white?text=MI',
|
||||
description:
|
||||
'Mock employer building open-weight frontier models in Europe. We push efficiency and openness in large language models.',
|
||||
industry: 'Open-Weight LLMs',
|
||||
size: '200+',
|
||||
location: 'Paris, France',
|
||||
website: 'https://example.com/mistral',
|
||||
socialLinks: { twitter: 'https://example.com/mistral/x', linkedin: 'https://example.com/mistral/li' },
|
||||
culture: 'European-rooted, efficiency-driven, open-weight-proud. We ship small models that punch above their size.',
|
||||
},
|
||||
{
|
||||
id: 'emp-replicate',
|
||||
name: 'Replicate',
|
||||
logo: 'https://placehold.co/80x80/orange/white?text=RE',
|
||||
description:
|
||||
'Mock employer making ML deployment delightful. We host, serve, and scale models with a few lines of code.',
|
||||
industry: 'ML Deployment',
|
||||
size: '150+',
|
||||
location: 'San Francisco, CA',
|
||||
website: 'https://example.com/replicate',
|
||||
socialLinks: { twitter: 'https://example.com/replicate/x', linkedin: 'https://example.com/replicate/li' },
|
||||
culture: 'Developer-experience-obsessed, pragmatic, remote-friendly. We make shipping models feel like shipping software.',
|
||||
},
|
||||
{
|
||||
id: 'emp-pinecone',
|
||||
name: 'Pinecone',
|
||||
logo: 'https://placehold.co/80x80/green/white?text=PC',
|
||||
description:
|
||||
'Mock employer building the vector database for AI applications. We power retrieval for thousands of production RAG systems.',
|
||||
industry: 'Vector Databases',
|
||||
size: '300+',
|
||||
location: 'New York, NY',
|
||||
website: 'https://example.com/pinecone',
|
||||
socialLinks: { twitter: 'https://example.com/pinecone/x', linkedin: 'https://example.com/pinecone/li' },
|
||||
culture: 'Infra-focused, latency-obsessed, distributed-first. We treat retrieval as the heart of grounded AI.',
|
||||
},
|
||||
{
|
||||
id: 'emp-langchain',
|
||||
name: 'LangChain',
|
||||
logo: 'https://placehold.co/80x80/blue/white?text=LC',
|
||||
description:
|
||||
'Mock employer building the orchestration layer for LLM applications. We provide frameworks for agents, retrieval, and evaluation.',
|
||||
industry: 'AI Orchestration',
|
||||
size: '200+',
|
||||
location: 'San Francisco, CA',
|
||||
website: 'https://example.com/langchain',
|
||||
socialLinks: { twitter: 'https://example.com/langchain/x', linkedin: 'https://example.com/langchain/li' },
|
||||
culture: 'Framework-minded, community-driven, abstractions-first. We build primitives others compose into products.',
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,13 @@
|
||||
export { competencyStacks, allCompetencies } from './competency-stacks';
|
||||
export { jobs } from './jobs';
|
||||
export { candidates } from './candidates';
|
||||
export { employers } from './employers';
|
||||
export {
|
||||
primaryLearner,
|
||||
learnerMicrocredentials,
|
||||
learnerArtifacts,
|
||||
upcomingDefenses,
|
||||
learnerSummary,
|
||||
} from './learner-progress';
|
||||
export { aiTutorResponses } from './ai-tutor-responses';
|
||||
export type { TutorResponse } from './ai-tutor-responses';
|
||||
@@ -0,0 +1,324 @@
|
||||
import type { Job } from '@nextcraft/types';
|
||||
|
||||
export const jobs: Job[] = [
|
||||
{
|
||||
id: 'job-001',
|
||||
title: 'AI Orchestration Engineer',
|
||||
employerId: 'emp-langchain',
|
||||
description:
|
||||
'Design and operate multi-agent systems that automate complex knowledge workflows. You will own agent topology, tool integration, and evaluation harnesses for production deployments serving millions of queries.',
|
||||
requiredCompetencies: ['stack-orchestration-c001', 'stack-orchestration-c002', 'stack-orchestration-c005'],
|
||||
skills: ['LangGraph', 'Multi-agent systems', 'RAG', 'Python', 'Evaluation'],
|
||||
seniority: 'senior',
|
||||
location: 'San Francisco, CA',
|
||||
remote: true,
|
||||
salaryMin: 160000,
|
||||
salaryMax: 240000,
|
||||
matchScore: 96,
|
||||
postedAt: '2026-08-21T10:00:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-002',
|
||||
title: 'LLM Application Developer',
|
||||
employerId: 'emp-openai',
|
||||
description:
|
||||
'Build delightful LLM-powered features end-to-end. You will work on retrieval, function calling, streaming UX, and robust output validation for consumer-facing products.',
|
||||
requiredCompetencies: ['stack-orchestration-c003', 'stack-orchestration-c004', 'stack-orchestration-c005'],
|
||||
skills: ['Python', 'TypeScript', 'RAG', 'Function calling', 'Streaming'],
|
||||
seniority: 'mid',
|
||||
location: 'San Francisco, CA',
|
||||
remote: true,
|
||||
salaryMin: 140000,
|
||||
salaryMax: 210000,
|
||||
matchScore: 92,
|
||||
postedAt: '2026-08-28T09:30:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-003',
|
||||
title: 'AI Safety Researcher',
|
||||
employerId: 'emp-anthropic',
|
||||
description:
|
||||
'Research alignment, interpretability, and robustness of frontier models. Design experiments, run evaluations, and publish findings that improve the safety of deployed AI systems.',
|
||||
requiredCompetencies: ['stack-safety-c001', 'stack-safety-c007', 'stack-safety-c002'],
|
||||
skills: ['Alignment', 'Interpretability', 'Red teaming', 'Python', 'Research'],
|
||||
seniority: 'senior',
|
||||
location: 'San Francisco, CA',
|
||||
remote: false,
|
||||
salaryMin: 180000,
|
||||
salaryMax: 280000,
|
||||
matchScore: 88,
|
||||
postedAt: '2026-08-15T12:00:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-004',
|
||||
title: 'Prompt Engineer',
|
||||
employerId: 'emp-perplexity',
|
||||
description:
|
||||
'Craft, test, and ship prompt strategies that power answer-engine features. Own prompt libraries, regression suites, and A/B experiments across product surfaces.',
|
||||
requiredCompetencies: ['stack-orchestration-c004', 'stack-orchestration-c001'],
|
||||
skills: ['Prompt engineering', 'Evaluation', 'A/B testing', 'Python'],
|
||||
seniority: 'mid',
|
||||
location: 'Remote',
|
||||
remote: true,
|
||||
salaryMin: 110000,
|
||||
salaryMax: 175000,
|
||||
matchScore: 84,
|
||||
postedAt: '2026-09-02T14:15:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-005',
|
||||
title: 'AI Product Manager',
|
||||
employerId: 'emp-huggingface',
|
||||
description:
|
||||
'Own the roadmap for AI-powered developer tools. Translate model capabilities into customer value, define success metrics, and ship agentic features with engineering.',
|
||||
requiredCompetencies: ['stack-designer-c001', 'stack-orchestration-c001'],
|
||||
skills: ['Product strategy', 'AI UX', 'Roadmapping', 'Stakeholder mgmt'],
|
||||
seniority: 'senior',
|
||||
location: 'New York, NY',
|
||||
remote: true,
|
||||
salaryMin: 150000,
|
||||
salaryMax: 220000,
|
||||
matchScore: 78,
|
||||
postedAt: '2026-08-30T08:00:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-006',
|
||||
title: 'RAG Infrastructure Engineer',
|
||||
employerId: 'emp-pinecone',
|
||||
description:
|
||||
'Build the retrieval substrate behind knowledge-grounded AI. Optimize indexing, query latency, and hybrid retrieval across billion-vector workloads.',
|
||||
requiredCompetencies: ['stack-orchestration-c005', 'stack-orchestration-c006'],
|
||||
skills: ['Vector databases', 'Embeddings', 'Go', 'Distributed systems'],
|
||||
seniority: 'mid',
|
||||
location: 'Remote',
|
||||
remote: true,
|
||||
salaryMin: 130000,
|
||||
salaryMax: 200000,
|
||||
matchScore: 81,
|
||||
postedAt: '2026-09-05T11:00:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-007',
|
||||
title: 'AI Governance Lead',
|
||||
employerId: 'emp-scaleai',
|
||||
description:
|
||||
'Stand up the AI governance program for enterprise customers. Map controls to NIST AI RMF and EU AI Act, run audits, and author model cards at scale.',
|
||||
requiredCompetencies: ['stack-safety-c005', 'stack-safety-c003', 'stack-safety-c013'],
|
||||
skills: ['AI policy', 'NIST AI RMF', 'Audit', 'Documentation'],
|
||||
seniority: 'staff',
|
||||
location: 'San Francisco, CA',
|
||||
remote: true,
|
||||
salaryMin: 170000,
|
||||
salaryMax: 230000,
|
||||
matchScore: 74,
|
||||
postedAt: '2026-08-18T16:45:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-008',
|
||||
title: 'Human-AI Interaction Designer',
|
||||
employerId: 'emp-anthropic',
|
||||
description:
|
||||
'Design how users collaborate with Claude across products. Own transparency patterns, trust calibration, and agentic interaction for assistant surfaces.',
|
||||
requiredCompetencies: ['stack-designer-c001', 'stack-designer-c003', 'stack-designer-c008'],
|
||||
skills: ['Figma', 'AI UX', 'Prototyping', 'User research'],
|
||||
seniority: 'mid',
|
||||
location: 'San Francisco, CA',
|
||||
remote: true,
|
||||
salaryMin: 125000,
|
||||
salaryMax: 190000,
|
||||
matchScore: 86,
|
||||
postedAt: '2026-08-25T10:30:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-009',
|
||||
title: 'Evaluation Engineer',
|
||||
employerId: 'emp-cohere',
|
||||
description:
|
||||
'Build and operate the eval platform for LLM-powered products. Design LLM-as-judge pipelines, regression suites, and human-eval panels for production models.',
|
||||
requiredCompetencies: ['stack-orchestration-c007', 'stack-safety-c002'],
|
||||
skills: ['LLM evaluation', 'Python', 'Statistics', 'Data labeling'],
|
||||
seniority: 'mid',
|
||||
location: 'Toronto, Canada',
|
||||
remote: true,
|
||||
salaryMin: 120000,
|
||||
salaryMax: 180000,
|
||||
matchScore: 79,
|
||||
postedAt: '2026-09-01T13:20:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-010',
|
||||
title: 'Robotics Operations Specialist',
|
||||
employerId: 'emp-replicate',
|
||||
description:
|
||||
'Supervise a fleet of AI-augmented robotic units in a warehouse environment. Interpret anomaly alerts, perform calibrations, and intervene on exceptions.',
|
||||
requiredCompetencies: ['stack-operator-c002', 'stack-operator-c011', 'stack-operator-c003'],
|
||||
skills: ['Robotics', 'Safety protocols', 'IoT', 'Predictive maintenance'],
|
||||
seniority: 'entry',
|
||||
location: 'Austin, TX',
|
||||
remote: false,
|
||||
salaryMin: 80000,
|
||||
salaryMax: 115000,
|
||||
matchScore: 71,
|
||||
postedAt: '2026-08-22T09:00:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-011',
|
||||
title: 'Computational Biologist',
|
||||
employerId: 'emp-recursion',
|
||||
description:
|
||||
'Apply ML to drug discovery. Build pipelines for phenotype prediction, active learning on assay data, and molecular generation for novel targets.',
|
||||
requiredCompetencies: ['stack-science-c005', 'stack-science-c002', 'stack-science-c011'],
|
||||
skills: ['Bioinformatics', 'Python', 'PyTorch', 'Drug discovery'],
|
||||
seniority: 'senior',
|
||||
location: 'Boston, MA',
|
||||
remote: true,
|
||||
salaryMin: 145000,
|
||||
salaryMax: 215000,
|
||||
matchScore: 83,
|
||||
postedAt: '2026-08-12T15:00:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-012',
|
||||
title: 'Climate ML Scientist',
|
||||
employerId: 'emp-deepmind',
|
||||
description:
|
||||
'Develop ML models for climate forecasting and energy grid optimization. Work with earth system scientists to downscale GCM output and quantify uncertainty.',
|
||||
requiredCompetencies: ['stack-science-c004', 'stack-science-c014', 'stack-science-c010'],
|
||||
skills: ['Climate modeling', 'PyTorch', 'Data assimilation', 'PINNs'],
|
||||
seniority: 'senior',
|
||||
location: 'London, UK',
|
||||
remote: true,
|
||||
salaryMin: 135000,
|
||||
salaryMax: 200000,
|
||||
matchScore: 77,
|
||||
postedAt: '2026-08-27T11:45:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-013',
|
||||
title: 'Agent Reliability Engineer',
|
||||
employerId: 'emp-langchain',
|
||||
description:
|
||||
'Own observability and reliability for production agent workloads. Build tracing, alerting, and rollback systems for multi-step agent pipelines.',
|
||||
requiredCompetencies: ['stack-orchestration-c013', 'stack-orchestration-c015', 'stack-orchestration-c008'],
|
||||
skills: ['Observability', 'Python', 'SRE', 'Distributed tracing'],
|
||||
seniority: 'mid',
|
||||
location: 'Remote',
|
||||
remote: true,
|
||||
salaryMin: 140000,
|
||||
salaryMax: 205000,
|
||||
matchScore: 90,
|
||||
postedAt: '2026-09-04T09:00:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-014',
|
||||
title: 'AI Red Team Lead',
|
||||
employerId: 'emp-mistral',
|
||||
description:
|
||||
'Lead adversarial testing of frontier and open-weight models. Build automated red-team suites, track vulnerabilities, and coordinate disclosure.',
|
||||
requiredCompetencies: ['stack-safety-c002', 'stack-safety-c010', 'stack-safety-c001'],
|
||||
skills: ['Red teaming', 'Prompt injection', 'Python', 'Leadership'],
|
||||
seniority: 'staff',
|
||||
location: 'Paris, France',
|
||||
remote: true,
|
||||
salaryMin: 160000,
|
||||
salaryMax: 230000,
|
||||
matchScore: 85,
|
||||
postedAt: '2026-08-19T10:30:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-015',
|
||||
title: 'Conversation Designer',
|
||||
employerId: 'emp-huggingface',
|
||||
description:
|
||||
'Design dialogue flows, personas, and repair strategies for AI assistants across open-source products. Partner with ML engineers to align tone with model behavior.',
|
||||
requiredCompetencies: ['stack-designer-c002', 'stack-designer-c010', 'stack-designer-c011'],
|
||||
skills: ['Conversation design', 'Figma', 'Voice UX', 'Prototyping'],
|
||||
seniority: 'mid',
|
||||
location: 'Remote',
|
||||
remote: true,
|
||||
salaryMin: 105000,
|
||||
salaryMax: 160000,
|
||||
matchScore: 73,
|
||||
postedAt: '2026-08-29T14:00:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-016',
|
||||
title: 'Field AI Technician',
|
||||
employerId: 'emp-anduril',
|
||||
description:
|
||||
'Deploy and maintain AI vision systems on defense hardware in the field. Calibrate sensors, interpret model alerts, and escalate edge cases to engineering.',
|
||||
requiredCompetencies: ['stack-operator-c004', 'stack-operator-c009', 'stack-operator-c001'],
|
||||
skills: ['Computer vision', 'Sensor calibration', 'Field ops', 'Python'],
|
||||
seniority: 'entry',
|
||||
location: 'Costa Mesa, CA',
|
||||
remote: false,
|
||||
salaryMin: 90000,
|
||||
salaryMax: 130000,
|
||||
matchScore: 68,
|
||||
postedAt: '2026-08-14T08:30:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-017',
|
||||
title: 'Materials ML Engineer',
|
||||
employerId: 'emp-deepmind',
|
||||
description:
|
||||
'Discover novel materials with ML. Train property-prediction models, run active-learning loops over DFT calculations, and validate candidates experimentally.',
|
||||
requiredCompetencies: ['stack-science-c003', 'stack-science-c002', 'stack-science-c006'],
|
||||
skills: ['Materials science', 'PyTorch', 'DFT', 'Active learning'],
|
||||
seniority: 'senior',
|
||||
location: 'London, UK',
|
||||
remote: true,
|
||||
salaryMin: 140000,
|
||||
salaryMax: 210000,
|
||||
matchScore: 80,
|
||||
postedAt: '2026-08-26T12:15:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-018',
|
||||
title: 'AI Trust & Safety Analyst',
|
||||
employerId: 'emp-openai',
|
||||
description:
|
||||
'Investigate misuse patterns, triage safety incidents, and improve policy enforcement for consumer AI products. Author postmortems and recommend mitigations.',
|
||||
requiredCompetencies: ['stack-safety-c008', 'stack-safety-c006', 'stack-safety-c002'],
|
||||
skills: ['Trust & safety', 'Incident response', 'Policy', 'Investigation'],
|
||||
seniority: 'mid',
|
||||
location: 'San Francisco, CA',
|
||||
remote: true,
|
||||
salaryMin: 115000,
|
||||
salaryMax: 170000,
|
||||
matchScore: 76,
|
||||
postedAt: '2026-09-03T10:45:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-019',
|
||||
title: 'Edge AI Engineer',
|
||||
employerId: 'emp-replicate',
|
||||
description:
|
||||
'Optimize and deploy models to edge hardware. Quantize, distill, and compile models for low-latency inference on field devices with constrained budgets.',
|
||||
requiredCompetencies: ['stack-operator-c008', 'stack-orchestration-c012', 'stack-orchestration-c014'],
|
||||
skills: ['Edge ML', 'TensorRT', 'C++', 'Quantization'],
|
||||
seniority: 'mid',
|
||||
location: 'Remote',
|
||||
remote: true,
|
||||
salaryMin: 130000,
|
||||
salaryMax: 195000,
|
||||
matchScore: 82,
|
||||
postedAt: '2026-08-24T11:30:00Z',
|
||||
},
|
||||
{
|
||||
id: 'job-020',
|
||||
title: 'AI Research Engineer',
|
||||
employerId: 'emp-cohere',
|
||||
description:
|
||||
'Push the frontier of language model capabilities. Prototype new architectures, run large-scale experiments, and contribute to publications and open-source releases.',
|
||||
requiredCompetencies: ['stack-orchestration-c001', 'stack-science-c010', 'stack-science-c011'],
|
||||
skills: ['PyTorch', 'Research', 'Transformers', 'Distributed training'],
|
||||
seniority: 'senior',
|
||||
location: 'Berlin, Germany',
|
||||
remote: true,
|
||||
salaryMin: 155000,
|
||||
salaryMax: 235000,
|
||||
matchScore: 94,
|
||||
postedAt: '2026-08-20T09:00:00Z',
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,101 @@
|
||||
import type { Learner, Artifact, OralDefense, Microcredential } from '@nextcraft/types';
|
||||
|
||||
export const primaryLearner: Learner = {
|
||||
id: 'learner-001',
|
||||
name: 'Alex Rivera',
|
||||
email: 'alex.rivera@example.com',
|
||||
avatar: 'https://i.pravatar.cc/150?img=16',
|
||||
ageGroup: '18+',
|
||||
enrolledStacks: ['stack-orchestration', 'stack-safety'],
|
||||
progress: {
|
||||
'stack-orchestration': 62,
|
||||
'stack-safety': 41,
|
||||
},
|
||||
};
|
||||
|
||||
export const learnerMicrocredentials: Microcredential[] = [
|
||||
{ id: 'mc-001', competencyId: 'stack-orchestration-c001', issuedAt: '2026-07-12T00:00:00Z', verified: true, score: 94 },
|
||||
{ id: 'mc-002', competencyId: 'stack-orchestration-c003', issuedAt: '2026-07-28T00:00:00Z', verified: true, score: 91 },
|
||||
{ id: 'mc-003', competencyId: 'stack-orchestration-c004', issuedAt: '2026-08-04T00:00:00Z', verified: true, score: 88 },
|
||||
{ id: 'mc-004', competencyId: 'stack-safety-c003', issuedAt: '2026-08-20T00:00:00Z', verified: true, score: 90 },
|
||||
{ id: 'mc-005', competencyId: 'stack-orchestration-c006', issuedAt: null, verified: false, score: null },
|
||||
];
|
||||
|
||||
export const learnerArtifacts: Artifact[] = [
|
||||
{
|
||||
id: 'art-001',
|
||||
name: 'Multi-agent research assistant',
|
||||
type: 'code',
|
||||
url: 'https://example.com/artifacts/research-assistant',
|
||||
description: 'A LangGraph-based assistant that plans, retrieves, and drafts cited literature reviews with an eval harness.',
|
||||
createdAt: '2026-08-22T14:30:00Z',
|
||||
},
|
||||
{
|
||||
id: 'art-002',
|
||||
name: 'RAG retrieval quality dashboard',
|
||||
type: 'code',
|
||||
url: 'https://example.com/artifacts/rag-dashboard',
|
||||
description: 'Streamlit dashboard comparing chunking strategies and rerankers across 800 evaluation queries.',
|
||||
createdAt: '2026-08-15T09:12:00Z',
|
||||
},
|
||||
{
|
||||
id: 'art-003',
|
||||
name: 'Model card for internal Q&A agent',
|
||||
type: 'document',
|
||||
url: 'https://example.com/artifacts/model-card',
|
||||
description: 'Capabilities, limitations, intended use, and red-team findings for a document-grounded Q&A agent.',
|
||||
createdAt: '2026-08-19T11:00:00Z',
|
||||
},
|
||||
{
|
||||
id: 'art-004',
|
||||
name: 'Prompt regression suite',
|
||||
type: 'code',
|
||||
url: 'https://example.com/artifacts/prompt-regression',
|
||||
description: 'Pytest-based suite of 320 prompt assertions with LLM-as-judge scoring and CI integration.',
|
||||
createdAt: '2026-08-08T16:45:00Z',
|
||||
},
|
||||
{
|
||||
id: 'art-005',
|
||||
name: 'Agent topology diagram',
|
||||
type: 'design',
|
||||
url: 'https://example.com/artifacts/topology',
|
||||
description: 'Architecture diagram for a plan-and-execute agent with reflection and tool-retrieval sub-graphs.',
|
||||
createdAt: '2026-07-30T10:20:00Z',
|
||||
},
|
||||
];
|
||||
|
||||
export const upcomingDefenses: OralDefense[] = [
|
||||
{
|
||||
id: 'def-001',
|
||||
competencyId: 'stack-orchestration-c002',
|
||||
transcript: '',
|
||||
score: null,
|
||||
status: 'scheduled',
|
||||
},
|
||||
{
|
||||
id: 'def-002',
|
||||
competencyId: 'stack-orchestration-c005',
|
||||
transcript: '',
|
||||
score: null,
|
||||
status: 'scheduled',
|
||||
},
|
||||
{
|
||||
id: 'def-003',
|
||||
competencyId: 'stack-safety-c001',
|
||||
transcript: '',
|
||||
score: null,
|
||||
status: 'pending',
|
||||
},
|
||||
];
|
||||
|
||||
export const learnerSummary = {
|
||||
enrolledStacks: primaryLearner.enrolledStacks.length,
|
||||
microcredentialsEarned: learnerMicrocredentials.filter((m) => m.verified).length,
|
||||
artifactsSubmitted: learnerArtifacts.length,
|
||||
upcomingDefenses: upcomingDefenses.filter((d) => d.status === 'scheduled').length,
|
||||
averageScore:
|
||||
learnerMicrocredentials
|
||||
.filter((m) => m.score !== null)
|
||||
.reduce((acc, m) => acc + (m.score ?? 0), 0) /
|
||||
Math.max(1, learnerMicrocredentials.filter((m) => m.score !== null).length),
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "@nextcraft/mock-data",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./index.ts",
|
||||
"types": "./index.ts",
|
||||
"exports": {
|
||||
".": "./index.ts",
|
||||
"./*": "./*.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc --noEmit",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nextcraft/types": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"declaration": false,
|
||||
"declarationMap": false
|
||||
},
|
||||
"include": ["*.ts"]
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Nextcraft — Domain Types
|
||||
*
|
||||
* Competency-based credential model: stacks → competencies → microcredentials,
|
||||
* evidenced by artifacts, process traces, oral defenses, and rubric assessments.
|
||||
*/
|
||||
|
||||
export type CompetencyStatus = 'locked' | 'available' | 'in_progress' | 'mastered';
|
||||
|
||||
export type ArtifactType = 'code' | 'design' | 'simulation' | 'document';
|
||||
|
||||
export interface Competency {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
status: CompetencyStatus;
|
||||
stackId: string;
|
||||
prerequisites: string[];
|
||||
microcredentialId: string | null;
|
||||
}
|
||||
|
||||
export interface CompetencyStack {
|
||||
id: string;
|
||||
name: string;
|
||||
targetRoles: string;
|
||||
description: string;
|
||||
competencies: Competency[];
|
||||
color: StackColor;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
export type StackColor = 'indigo' | 'rose' | 'violet' | 'emerald' | 'cyan';
|
||||
|
||||
export interface Microcredential {
|
||||
id: string;
|
||||
competencyId: string;
|
||||
issuedAt: string | null;
|
||||
verified: boolean;
|
||||
score: number | null;
|
||||
}
|
||||
|
||||
export interface Artifact {
|
||||
id: string;
|
||||
name: string;
|
||||
type: ArtifactType;
|
||||
url: string;
|
||||
description: string;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface ProcessTraceStep {
|
||||
timestamp: string;
|
||||
action: string;
|
||||
metadata: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface ProcessTrace {
|
||||
id: string;
|
||||
competencyId: string;
|
||||
steps: ProcessTraceStep[];
|
||||
}
|
||||
|
||||
export type OralDefenseStatus = 'scheduled' | 'passed' | 'failed' | 'pending';
|
||||
|
||||
export interface OralDefense {
|
||||
id: string;
|
||||
competencyId: string;
|
||||
transcript: string;
|
||||
score: number | null;
|
||||
status: OralDefenseStatus;
|
||||
}
|
||||
|
||||
export interface RubricCriterion {
|
||||
name: string;
|
||||
passed: boolean;
|
||||
weight: number;
|
||||
}
|
||||
|
||||
export interface AssessmentRubric {
|
||||
id: string;
|
||||
competencyId: string;
|
||||
criteria: RubricCriterion[];
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from './domain';
|
||||
export * from './marketplace';
|
||||
export * from './user';
|
||||
export * from './ui';
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Nextcraft — Marketplace Types
|
||||
*
|
||||
* AI-era job board + talent marketplace. Jobs, employers, candidates,
|
||||
* postings, talent matches, and search filters.
|
||||
*/
|
||||
|
||||
export type Seniority = 'entry' | 'mid' | 'senior' | 'staff' | 'principal';
|
||||
|
||||
export interface Job {
|
||||
id: string;
|
||||
title: string;
|
||||
employerId: string;
|
||||
description: string;
|
||||
requiredCompetencies: string[];
|
||||
skills: string[];
|
||||
seniority: Seniority;
|
||||
location: string;
|
||||
remote: boolean;
|
||||
salaryMin: number;
|
||||
salaryMax: number;
|
||||
matchScore: number;
|
||||
postedAt: string;
|
||||
}
|
||||
|
||||
export interface Employer {
|
||||
id: string;
|
||||
name: string;
|
||||
logo: string;
|
||||
description: string;
|
||||
industry: string;
|
||||
size: string;
|
||||
location: string;
|
||||
website: string;
|
||||
socialLinks: Record<string, string>;
|
||||
culture: string;
|
||||
}
|
||||
|
||||
export interface Candidate {
|
||||
id: string;
|
||||
name: string;
|
||||
avatar: string;
|
||||
headline: string;
|
||||
competencyStackId: string;
|
||||
microcredentials: number;
|
||||
artifactCount: number;
|
||||
defenseScore: number;
|
||||
matchScore: number;
|
||||
bio: string;
|
||||
}
|
||||
|
||||
export type JobPostingStatus = 'active' | 'draft' | 'expired';
|
||||
|
||||
export interface JobPosting {
|
||||
id: string;
|
||||
jobId: string;
|
||||
status: JobPostingStatus;
|
||||
applicants: number;
|
||||
createdAt: string;
|
||||
}
|
||||
|
||||
export interface TalentMatch {
|
||||
candidateId: string;
|
||||
jobId: string;
|
||||
score: number;
|
||||
matchedSkills: string[];
|
||||
}
|
||||
|
||||
export interface SearchFilter {
|
||||
query: string;
|
||||
skills: string[];
|
||||
seniority: Seniority | null;
|
||||
remote: boolean | null;
|
||||
salaryMin: number | null;
|
||||
salaryMax: number | null;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "@nextcraft/types",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./index.ts",
|
||||
"types": "./index.ts",
|
||||
"exports": {
|
||||
".": "./index.ts",
|
||||
"./*": "./*.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc --noEmit",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true
|
||||
},
|
||||
"include": ["*.ts"]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Nextcraft — UI Types
|
||||
*
|
||||
* Theme surfaces, breakpoints, navigation items.
|
||||
*/
|
||||
|
||||
import type { Role } from './user';
|
||||
|
||||
export type Surface = 'learner' | 'marketplace' | 'employer' | 'admin';
|
||||
|
||||
export type ThemeMode = 'light' | 'dark';
|
||||
|
||||
export interface ThemeConfig {
|
||||
surface: Surface;
|
||||
mode: ThemeMode;
|
||||
}
|
||||
|
||||
export type Breakpoint = 'sm' | 'md' | 'lg' | 'xl';
|
||||
|
||||
export interface NavItem {
|
||||
label: string;
|
||||
href: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
export type RoleSurface = Role | 'marketplace';
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Nextcraft — User Types
|
||||
*
|
||||
* Three user roles: learner, employer, admin. Learners are segmented by
|
||||
* age group for compliance and content gating.
|
||||
*/
|
||||
|
||||
export type Role = 'learner' | 'employer' | 'admin';
|
||||
|
||||
export type AgeGroup = '16-17' | '18+';
|
||||
|
||||
export interface Learner {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
avatar: string;
|
||||
ageGroup: AgeGroup;
|
||||
enrolledStacks: string[];
|
||||
progress: Record<string, number>;
|
||||
}
|
||||
|
||||
export interface Admin {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
avatar: string;
|
||||
}
|
||||
|
||||
export interface EmployerUser {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
avatar: string;
|
||||
employerId: string;
|
||||
}
|
||||
|
||||
export type User = Learner | Admin | EmployerUser;
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "@nextcraft/ui",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./*": "./src/*"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc --noEmit",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nextcraft/types": "workspace:*",
|
||||
"lucide-react": "^0.468.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.3.1 || ^19.0.0",
|
||||
"react-dom": "^18.3.1 || ^19.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.2",
|
||||
"@types/react": "^19.0.0",
|
||||
"@types/react-dom": "^19.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './tokens';
|
||||
export * from './primitives';
|
||||
@@ -0,0 +1,65 @@
|
||||
'use client';
|
||||
|
||||
import { forwardRef, type ImgHTMLAttributes, type ReactNode, useState } from 'react';
|
||||
|
||||
export type AvatarSize = 'sm' | 'md' | 'lg';
|
||||
|
||||
export interface AvatarProps extends ImgHTMLAttributes<HTMLImageElement> {
|
||||
name: string;
|
||||
src?: string;
|
||||
size?: AvatarSize;
|
||||
fallback?: ReactNode;
|
||||
}
|
||||
|
||||
const sizeClasses: Record<AvatarSize, string> = {
|
||||
sm: 'h-8 w-8 text-xs',
|
||||
md: 'h-10 w-10 text-sm',
|
||||
lg: 'h-14 w-14 text-base',
|
||||
};
|
||||
|
||||
function initials(name: string): string {
|
||||
return name
|
||||
.split(' ')
|
||||
.filter(Boolean)
|
||||
.slice(0, 2)
|
||||
.map((part) => part[0]?.toUpperCase() ?? '')
|
||||
.join('');
|
||||
}
|
||||
|
||||
export const Avatar = forwardRef<HTMLImageElement, AvatarProps>(function Avatar(
|
||||
{ name, src, size = 'md', fallback, className, onError, ...rest },
|
||||
ref,
|
||||
) {
|
||||
const [errored, setErrored] = useState(false);
|
||||
const showImage = src && !errored;
|
||||
|
||||
return (
|
||||
<span
|
||||
className={[
|
||||
'inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full',
|
||||
'bg-primary-100 text-primary-700 font-medium dark:bg-primary-900/50 dark:text-primary-200',
|
||||
sizeClasses[size],
|
||||
className ?? '',
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
>
|
||||
{showImage ? (
|
||||
// eslint-disable-next-line jsx-a11y/alt-text
|
||||
<img
|
||||
ref={ref}
|
||||
src={src}
|
||||
alt={name}
|
||||
className="h-full w-full object-cover"
|
||||
onError={(e) => {
|
||||
setErrored(true);
|
||||
onError?.(e);
|
||||
}}
|
||||
{...rest}
|
||||
/>
|
||||
) : (
|
||||
fallback ?? initials(name)
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';
|
||||
|
||||
export type BadgeVariant = 'default' | 'success' | 'warning' | 'error' | 'info';
|
||||
|
||||
export interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
|
||||
variant?: BadgeVariant;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
const variantClasses: Record<BadgeVariant, string> = {
|
||||
default: 'bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-200',
|
||||
success: 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300',
|
||||
warning: 'bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300',
|
||||
error: 'bg-rose-100 text-rose-700 dark:bg-rose-900/40 dark:text-rose-300',
|
||||
info: 'bg-primary-100 text-primary-700 dark:bg-primary-900/40 dark:text-primary-300',
|
||||
};
|
||||
|
||||
export const Badge = forwardRef<HTMLSpanElement, BadgeProps>(function Badge(
|
||||
{ variant = 'default', className, children, ...rest },
|
||||
ref,
|
||||
) {
|
||||
return (
|
||||
<span
|
||||
ref={ref}
|
||||
className={[
|
||||
'inline-flex items-center gap-1 rounded-full px-2.5 py-0.5 text-xs font-medium',
|
||||
variantClasses[variant],
|
||||
className ?? '',
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
'use client';
|
||||
|
||||
import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
|
||||
export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'destructive' | 'outline';
|
||||
export type ButtonSize = 'sm' | 'md' | 'lg';
|
||||
|
||||
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: ButtonVariant;
|
||||
size?: ButtonSize;
|
||||
loading?: boolean;
|
||||
icon?: ReactNode;
|
||||
iconRight?: ReactNode;
|
||||
}
|
||||
|
||||
const sizeClasses: Record<ButtonSize, string> = {
|
||||
sm: 'h-8 px-3 text-xs gap-1.5',
|
||||
md: 'h-10 px-4 text-sm gap-2',
|
||||
lg: 'h-12 px-6 text-base gap-2.5',
|
||||
};
|
||||
|
||||
const variantClasses: Record<ButtonVariant, string> = {
|
||||
primary:
|
||||
'bg-primary-600 text-white hover:bg-primary-700 active:bg-primary-800 shadow-sm focus-visible:ring-primary-500',
|
||||
secondary:
|
||||
'bg-primary-100 text-primary-700 hover:bg-primary-200 active:bg-primary-300 focus-visible:ring-primary-500 dark:bg-primary-900/40 dark:text-primary-200 dark:hover:bg-primary-900/60',
|
||||
ghost:
|
||||
'bg-transparent text-slate-700 hover:bg-slate-100 active:bg-slate-200 focus-visible:ring-slate-400 dark:text-slate-200 dark:hover:bg-slate-800',
|
||||
destructive:
|
||||
'bg-rose-600 text-white hover:bg-rose-700 active:bg-rose-800 shadow-sm focus-visible:ring-rose-500',
|
||||
outline:
|
||||
'border border-slate-300 bg-transparent text-slate-800 hover:bg-slate-50 active:bg-slate-100 focus-visible:ring-slate-400 dark:border-slate-700 dark:text-slate-100 dark:hover:bg-slate-800',
|
||||
};
|
||||
|
||||
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
|
||||
{ variant = 'primary', size = 'md', loading = false, icon, iconRight, className, children, disabled, ...rest },
|
||||
ref,
|
||||
) {
|
||||
const isDisabled = disabled || loading;
|
||||
return (
|
||||
<button
|
||||
ref={ref}
|
||||
disabled={isDisabled}
|
||||
className={[
|
||||
'inline-flex items-center justify-center rounded-md font-medium transition-colors',
|
||||
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2',
|
||||
'disabled:opacity-50 disabled:pointer-events-none',
|
||||
sizeClasses[size],
|
||||
variantClasses[variant],
|
||||
className ?? '',
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
{...rest}
|
||||
>
|
||||
{loading ? <Loader2 className="h-4 w-4 animate-spin" aria-hidden /> : icon}
|
||||
{children}
|
||||
{iconRight}
|
||||
</button>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,71 @@
|
||||
import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';
|
||||
|
||||
export interface CardProps extends HTMLAttributes<HTMLDivElement> {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const Card = forwardRef<HTMLDivElement, CardProps>(function Card(
|
||||
{ className, children, ...rest },
|
||||
ref,
|
||||
) {
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={[
|
||||
'rounded-lg border border-slate-200 bg-white shadow-sm',
|
||||
'dark:border-slate-800 dark:bg-slate-900',
|
||||
className ?? '',
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export const CardHeader = forwardRef<HTMLDivElement, CardProps>(function CardHeader(
|
||||
{ className, children, ...rest },
|
||||
ref,
|
||||
) {
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={['flex flex-col gap-1 p-6 border-b border-slate-200 dark:border-slate-800', className ?? '']
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export const CardBody = forwardRef<HTMLDivElement, CardProps>(function CardBody(
|
||||
{ className, children, ...rest },
|
||||
ref,
|
||||
) {
|
||||
return (
|
||||
<div ref={ref} className={['p-6', className ?? ''].filter(Boolean).join(' ')} {...rest}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export const CardFooter = forwardRef<HTMLDivElement, CardProps>(function CardFooter(
|
||||
{ className, children, ...rest },
|
||||
ref,
|
||||
) {
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={['flex items-center gap-3 p-6 border-t border-slate-200 dark:border-slate-800', className ?? '']
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,5 @@
|
||||
export * from './button';
|
||||
export * from './input';
|
||||
export * from './card';
|
||||
export * from './badge';
|
||||
export * from './avatar';
|
||||
@@ -0,0 +1,57 @@
|
||||
'use client';
|
||||
|
||||
import { forwardRef, type InputHTMLAttributes, type ReactNode } from 'react';
|
||||
|
||||
export type InputSize = 'sm' | 'md' | 'lg';
|
||||
|
||||
export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
||||
label?: string;
|
||||
error?: string;
|
||||
icon?: ReactNode;
|
||||
inputSize?: InputSize;
|
||||
}
|
||||
|
||||
const sizeClasses: Record<InputSize, string> = {
|
||||
sm: 'h-8 text-xs px-2.5',
|
||||
md: 'h-10 text-sm px-3',
|
||||
lg: 'h-12 text-base px-4',
|
||||
};
|
||||
|
||||
export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
|
||||
{ label, error, icon, inputSize = 'md', className, id, ...rest },
|
||||
ref,
|
||||
) {
|
||||
const inputId = id ?? rest.name;
|
||||
return (
|
||||
<div className="flex flex-col gap-1.5">
|
||||
{label && (
|
||||
<label htmlFor={inputId} className="text-sm font-medium text-slate-700 dark:text-slate-200">
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
<div className="relative flex items-center">
|
||||
{icon && (
|
||||
<span className="pointer-events-none absolute left-3 flex items-center text-slate-400">{icon}</span>
|
||||
)}
|
||||
<input
|
||||
ref={ref}
|
||||
id={inputId}
|
||||
className={[
|
||||
'w-full rounded-md border bg-white text-slate-900 placeholder:text-slate-400 transition-colors',
|
||||
'border-slate-300 focus:border-primary-500 focus:ring-2 focus:ring-primary-500/30 focus:outline-none',
|
||||
'dark:bg-slate-900 dark:text-slate-100 dark:border-slate-700 dark:placeholder:text-slate-500',
|
||||
error && 'border-rose-500 focus:border-rose-500 focus:ring-rose-500/30',
|
||||
icon && 'pl-9',
|
||||
sizeClasses[inputSize],
|
||||
className ?? '',
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
aria-invalid={Boolean(error)}
|
||||
{...rest}
|
||||
/>
|
||||
</div>
|
||||
{error && <p className="text-xs text-rose-600 dark:text-rose-400">{error}</p>}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Nextcraft design tokens.
|
||||
*
|
||||
* Colors are also mirrored as Tailwind v4 @theme tokens in
|
||||
* apps/web/app/globals.css so that classes like `bg-primary-500` resolve.
|
||||
* The TS constants are for programmatic use (charts, custom styles).
|
||||
*/
|
||||
|
||||
import type { Breakpoint } from '@nextcraft/types';
|
||||
|
||||
export const colors = {
|
||||
primary: {
|
||||
50: '#eef2ff',
|
||||
100: '#e0e7ff',
|
||||
200: '#c7d2fe',
|
||||
300: '#a5b4fc',
|
||||
400: '#818cf8',
|
||||
500: '#6366f1',
|
||||
600: '#4f46e5',
|
||||
700: '#4338ca',
|
||||
800: '#3730a3',
|
||||
900: '#312e81',
|
||||
950: '#1e1b4b',
|
||||
},
|
||||
accent: {
|
||||
50: '#ecfdf5',
|
||||
100: '#d1fae5',
|
||||
200: '#a7f3d0',
|
||||
300: '#6ee7b7',
|
||||
400: '#34d399',
|
||||
500: '#10b981',
|
||||
600: '#059669',
|
||||
700: '#047857',
|
||||
800: '#065f46',
|
||||
900: '#064e3b',
|
||||
950: '#022c22',
|
||||
},
|
||||
neutral: {
|
||||
50: '#f8fafc',
|
||||
100: '#f1f5f9',
|
||||
200: '#e2e8f0',
|
||||
300: '#cbd5e1',
|
||||
400: '#94a3b8',
|
||||
500: '#64748b',
|
||||
600: '#475569',
|
||||
700: '#334155',
|
||||
800: '#1e293b',
|
||||
900: '#0f172a',
|
||||
950: '#020617',
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const spacing = {
|
||||
1: 4,
|
||||
2: 8,
|
||||
3: 12,
|
||||
4: 16,
|
||||
6: 24,
|
||||
8: 32,
|
||||
12: 48,
|
||||
16: 64,
|
||||
} as const;
|
||||
|
||||
export const radii = {
|
||||
sm: 4,
|
||||
md: 8,
|
||||
lg: 12,
|
||||
xl: 16,
|
||||
full: 9999,
|
||||
} as const;
|
||||
|
||||
export const shadows = {
|
||||
sm: '0 1px 2px 0 rgb(0 0 0 / 0.05)',
|
||||
md: '0 4px 6px -1px rgb(0 0 0 / 0.10), 0 2px 4px -2px rgb(0 0 0 / 0.10)',
|
||||
lg: '0 10px 15px -3px rgb(0 0 0 / 0.10), 0 4px 6px -4px rgb(0 0 0 / 0.10)',
|
||||
xl: '0 20px 25px -5px rgb(0 0 0 / 0.10), 0 8px 10px -6px rgb(0 0 0 / 0.10)',
|
||||
} as const;
|
||||
|
||||
export const breakpoints: Record<Breakpoint, number> = {
|
||||
sm: 375,
|
||||
md: 768,
|
||||
lg: 1024,
|
||||
xl: 1280,
|
||||
};
|
||||
|
||||
export const tokens = {
|
||||
colors,
|
||||
spacing,
|
||||
radii,
|
||||
shadows,
|
||||
breakpoints,
|
||||
} as const;
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
"declaration": true,
|
||||
"declarationMap": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx"]
|
||||
}
|
||||
Generated
+1695
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
packages:
|
||||
- 'apps/*'
|
||||
- 'packages/*'
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"moduleDetection": "force",
|
||||
"jsx": "preserve",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": false,
|
||||
"noEmit": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"incremental": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@nextcraft/ui": ["./packages/ui/src/index.ts"],
|
||||
"@nextcraft/ui/*": ["./packages/ui/src/*"],
|
||||
"@nextcraft/types": ["./packages/types/index.ts"],
|
||||
"@nextcraft/types/*": ["./packages/types/*"],
|
||||
"@nextcraft/mock-data": ["./packages/mock-data/index.ts"],
|
||||
"@nextcraft/mock-data/*": ["./packages/mock-data/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "**/node_modules", "**/.next", "**/dist"]
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"$schema": "https://turbo.build/schema.json",
|
||||
"tasks": {
|
||||
"build": {
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
|
||||
},
|
||||
"dev": {
|
||||
"cache": false,
|
||||
"persistent": true
|
||||
},
|
||||
"lint": {
|
||||
"dependsOn": ["^build"]
|
||||
},
|
||||
"typecheck": {
|
||||
"dependsOn": ["^build"]
|
||||
},
|
||||
"clean": {
|
||||
"cache": false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user