sahin.io

All skills and agents

project-architecture

How the angel-investments codebase is laid out — tech stack, data files, page inventory, navigation, theming, view modes, file naming, tests, and how to add a company, page, chart, theme or translation. Use when orienting in the repo or before adding or moving code, data files, pages, themes or translations.

Source file
.claude/skills/project-architecture/SKILL.md

Project architecture

Moved out of CLAUDE.md on 2026-10-11 (owner: keep CLAUDE.md thin). Parts of it predate the static public site; for what production actually serves, read the production-deployment skill.

What This Project Is

A public-facing portfolio dashboard for angel investor Sahin Boydas (sahin.io). It tracks the public portfolio (234 companies as of 2026-10-09; the count lives in the data, see "Counts" below) with rich data visualizations, founder profiles, co-investor analysis, and investment intelligence. Built as a React SPA with static JSON data files — no backend database for portfolio data.

Tech Stack

  • Frontend: React 19 + TypeScript + Tailwind CSS 4 + shadcn/ui
  • Router: wouter (with base path /angel-investments)
  • Backend: Express 4 + tRPC 11 (for auth/user features only)
  • Database: TiDB/MySQL via Drizzle ORM (user accounts only, not portfolio data)
  • Charts: Recharts, D3.js (force graphs, sankey, geo maps)
  • Build: Vite 7
  • i18n: react-i18next (English + Turkish)

Architecture

All portfolio data lives in static JSON files under client/public/ and client/src/data/. There is no API for portfolio data — everything is client-side. The tRPC backend handles only authentication and user management.

Key Data Files

File What It Contains
client/public/portfolio-data.json Core public companies (slug, name, market, stage, valuation, logo, exitStatus)
client/public/investment-intelligence.json Enriched data (invest_year, exit_status, market_cap, competitors)
client/public/enriched-company-data.json Deep company profiles (funding_rounds, founders, descriptions)
client/public/vc-data.json Co-investor VC firms and their portfolios
client/public/secondary-market-data.json Pre-IPO secondary market trading data
client/public/company-locations.json Geographic coordinates for map
client/public/news-items.json Portfolio news feed
client/src/data/portfolioData.ts TypeScript data loader + Company interface
client/src/data/founders-data.json Founder profiles with social links

Page Inventory (30+ pages)

Core: Home, InvestmentThesis, StageComparison, StatusPage, CoInvestors, Sectors Visualizations: Landscape, SectorHeatmap, GeoMap, Timeline, PortfolioNetworkGraph, InvestmentSankey, MarketTimingHeatmap People: Founders, FounderDetail, FounderNetwork, FounderTracker Research: CompanyIntelligence, CompanyDetails, CompanyMetrics, CompanyComparison, CompanyCompare, CompetitorRadar, ExitReadiness, ExitScenarioModeler VC Deep Dives: A16zPortfolio, SequoiaPortfolio, AccelPortfolio, FoundersFundPortfolio, YCPortfolio, VCLogos Content: NewsFeed, NewsDetail, Lessons, SecondaryMarket

Navigation Structure

The menu (groups Explore, Insights, Stories, Research; each page's label, title and description) is content/shared/navigation.yaml, built by shared/publicNavigation.ts and shown by the static header (server/publicChrome.ts), SiteSidebar.tsx and MobileSectionNav.tsx. Chrome copy is content/shared/chrome.yaml; run node scripts/sync-site-copy-module.mjs after editing either (page-content-yaml skill).

Theming

InvestorThemeContext provides 10+ theme presets (Default, Midnight, Forest, etc.). All pages use theme.colors.* for dynamic theming. ThemeSwitcher in navbar.

View Modes

Human mode (normal UI) and Agent mode (structured markdown for AI consumption). Toggled via ViewModeContext.

Common Questions You Might Ask

How do I add a new company?

Add it to client/public/portfolio-data.json. Optionally add enriched data to investment-intelligence.json and enriched-company-data.json.

How do I add a new page?

Public pages are no longer client/src/pages/ + App.tsx routes. Follow the new-react-page skill (file checklist: props builder in server/publicPages/, client/src/publicPages/*Page.tsx + *Types.ts + CSS, registration in types.ts, PublicReactPageView.tsx, components.client.ts/components.server.ts, the route in server/publicReactPages.ts or server/reactPageRoutes.ts, copy in content/pages/<page>.yaml, menu entry in content/shared/navigation.yaml, then node scripts/sync-site-copy-module.mjs). Each page family has its own page-* skill (index at https://sahin.io/angel-investments/skills-and-agents); add routes: to it or server/page-skills-coverage.test.ts fails.

How do I add a new chart/visualization?

Use Recharts for standard charts (bar, line, pie, area). Use D3.js for force graphs, sankey, geo projections. Import theme colors from useInvestorTheme().

How do I update the data?

Use the airtable-manus-sync skill (Airtable Manus view only).

How do I add a new theme?

Add a new entry in InvestorThemeContext.tsx with all required color fields (background, foreground, card, border, primary, accent, etc.), and its name and description in content/shared/themes.yaml (gallery groups are there too), then node scripts/sync-site-copy-module.mjs.

How do I add translations?

Add keys to client/src/i18n/locales/en.json and tr.json. Use useTranslation() hook with t('key') in components.

Where are the VC logos?

Stored as URLs in vc-data.json. Company logos are in portfolio-data.json as URLs.

How does the secondary market data work?

secondary-market-data.json contains pre-IPO trading estimates. Loaded async via fetch in pages that need it (SecondaryMarket, InvestmentSankey).

File Naming Convention

  • Pages: PascalCase (CompanyCompare.tsx)
  • Components: PascalCase (NavBar.tsx)
  • Data: kebab-case (portfolio-data.json)
  • Contexts: PascalCase with Context suffix (InvestorThemeContext.tsx)

Testing

Run pnpm test for vitest. Test files in server/*.test.ts. Frontend is manually tested via browser.