{"id":48056174,"url":"https://github.com/sethdavis512/portfolio","last_synced_at":"2026-04-04T14:27:57.192Z","repository":{"id":213571644,"uuid":"717127333","full_name":"sethdavis512/portfolio","owner":"sethdavis512","description":"Modern full-stack portfolio website with TypeScript monorepo architecture. React Router v7 frontend with SSR + KeystoneJS 6 headless CMS backend + PostgreSQL.","archived":false,"fork":false,"pushed_at":"2026-03-28T17:47:25.000Z","size":185390,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-28T19:25:53.145Z","etag":null,"topics":["backend","cms","frontend","fullstack","graphql","headless-cms","keystonejs","modern-stack","monorepo","portfolio","postgresql","prisma","react","react-router","ssr","tailwindcss","typescript","vite","web-development"],"latest_commit_sha":null,"homepage":"http://sethdavis.tech","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sethdavis512.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-11-10T16:09:09.000Z","updated_at":"2026-03-28T17:47:28.000Z","dependencies_parsed_at":"2024-02-10T20:24:11.491Z","dependency_job_id":"e6ef157c-27ef-44a4-a866-8a41f33a9a7a","html_url":"https://github.com/sethdavis512/portfolio","commit_stats":null,"previous_names":["sethdavis512/portfolio"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sethdavis512/portfolio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethdavis512%2Fportfolio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethdavis512%2Fportfolio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethdavis512%2Fportfolio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethdavis512%2Fportfolio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sethdavis512","download_url":"https://codeload.github.com/sethdavis512/portfolio/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sethdavis512%2Fportfolio/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31402474,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","cms","frontend","fullstack","graphql","headless-cms","keystonejs","modern-stack","monorepo","portfolio","postgresql","prisma","react","react-router","ssr","tailwindcss","typescript","vite","web-development"],"created_at":"2026-04-04T14:27:57.000Z","updated_at":"2026-04-04T14:27:57.151Z","avatar_url":"https://github.com/sethdavis512.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Portfolio Monorepo\n\n[![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge\u0026logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org/)\n[![React](https://img.shields.io/badge/React-20232A?style=for-the-badge\u0026logo=react\u0026logoColor=61DAFB)](https://reactjs.org/)\n[![KeystoneJS](https://img.shields.io/badge/KeystoneJS-000000?style=for-the-badge\u0026logo=keystone\u0026logoColor=white)](https://keystonejs.com/)\n[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-316192?style=for-the-badge\u0026logo=postgresql\u0026logoColor=white)](https://www.postgresql.org/)\n[![TailwindCSS](https://img.shields.io/badge/Tailwind_CSS-38B2AC?style=for-the-badge\u0026logo=tailwind-css\u0026logoColor=white)](https://tailwindcss.com/)\n\nA modern, full-stack portfolio website built with a monorepo architecture. Features a React/TypeScript frontend with SSR and a KeystoneJS 6 headless CMS backend, all managed in a single repository.\n\n**Live Site**: [sethdavis.tech](https://sethdavis.tech)\n\n## Key Features\n\n- **Server-Side Rendering (SSR)** with React Router v7\n- **Responsive Design** with TailwindCSS v4\n- **Type-Safe Development** with TypeScript throughout\n- **GraphQL API** with automatic type generation\n- **Headless CMS** with KeystoneJS 6 admin interface\n- **PostgreSQL Database** with Prisma ORM\n- **Analytics Integration** with PostHog\n- **Modern UI Components** with Radix UI primitives\n\n## Architecture\n\n- **Frontend**: `web/` — React Router v7, TypeScript, TailwindCSS, SSR, GraphQL client\n- **Backend**: `cms/` — KeystoneJS 6, PostgreSQL, Prisma ORM, GraphQL API\n- **Monorepo**: Unified development, shared tooling, and consistent TypeScript across both apps\n\n---\n\n## Frontend (`web/`)\n\n- **Framework**: React Router v7 (file-based routing, SSR, pre-rendering)\n- **Language**: TypeScript (strict mode)\n- **Styling**: TailwindCSS v4, `@tailwindcss/typography`, `tailwindcss-animate`\n- **GraphQL**: `graphql-request` client, codegen via `@graphql-codegen`\n- **UI**: Custom component library using `cva` (Class Variance Authority)\n- **Analytics**: PostHog integration\n- **Build**: Vite, TypeScript path mapping\n\n### Directory Structure (Frontend)\n\n```text\nweb/app/\n├── components/   # Reusable UI components\n├── routes/       # React Router v7 routes\n├── utils/        # Utility functions\n├── generated/    # Auto-generated GraphQL types\n├── queries/      # GraphQL query definitions\n└── images/       # Static assets\n```\n\n### Development (Frontend)\n\n- `npm run dev:web` — Start frontend dev server\n- `npm run generate:types` — Generate GraphQL types from CMS schema\n- Server-side data fetching in route loaders\n- Use absolute imports with `~/` prefix\n\n---\n\n## Backend (`cms/`)\n\n- **Framework**: KeystoneJS 6 (headless CMS)\n- **Database**: PostgreSQL (Prisma ORM)\n- **Auth**: KeystoneJS built-in, bcrypt password hashing\n- **API**: Auto-generated GraphQL at `/api/graphql`\n- **Language**: TypeScript\n\n### Directory Structure (Backend)\n\n```text\ncms/\n├── keystone.ts      # Main Keystone config\n├── schema.ts        # Database schema\n├── auth.ts          # Auth config\n├── seed.ts          # DB seeding\n├── migrations/      # Prisma migrations\n```\n\n### Development (Backend)\n\n- `npm run dev:cms` — Start CMS dev server (admin UI at `/admin`)\n- GraphQL playground at `/api/graphql`\n- Use Prisma migrations for schema changes\n- `npm run generate:types` after schema changes\n\n---\n\n## Getting Started\n\n1. **Install dependencies**\n\n    ```sh\n    npm install\n    ```\n\n2. **Set up environment variables**\n\n    - Copy `.env.example` to `.env` in both `web/` and `cms/` as needed\n    - Fill in database URLs, secrets, etc.\n\n3. **Run development servers**\n\n    ```sh\n    npm run dev\n    # or run frontend/cms separately:\n    npm run dev:web\n    npm run dev:cms\n    ```\n\n4. **Generate GraphQL types**\n\n    ```sh\n    npm run generate:types\n    ```\n\n5. **Apply database migrations**\n\n    ```sh\n    cd cms \u0026\u0026 npx prisma migrate deploy\n    ```\n\n6. **Seed the database**\n\n    ```sh\n    cd cms \u0026\u0026 npm run seed\n    ```\n\n---\n\n## Adding New Work Items\n\nWork items are managed in the **CMS** (KeystoneJS), not in code.\n\n1. **Add in CMS admin**: `localhost:3000/admin` or `admin.sethdavis.tech/admin`\n2. **Create Work entry** with title, slug, description, content, and images\n3. **Set status to PUBLISHED**\n4. **Sync to production**:\n\n   ```bash\n   cd cms \u0026\u0026 npx tsx sync-to-prod.ts --new-only\n   cd cms \u0026\u0026 npx tsx sync-images-to-prod.ts\n   cd web \u0026\u0026 railway up -d\n   ```\n\nCommandPalette, sitemap, and pre-rendering are all CMS-driven - no manual file updates needed.\n\n⚠️ **Use `railway up`, not `railway redeploy`** - redeploy only restarts, doesn't rebuild.\n\n---\n\n## Deployment \u0026 Environment\n\n- Production CMS endpoint: `https://admin.sethdavis.tech/api/graphql`\n- Environment-specific database URLs\n- Session management with secure cookies\n- CORS configured for production domains\n\n---\n\n## Security \u0026 Best Practices\n\n- All secrets in environment variables\n- Passwords hashed with bcrypt\n- Input validation on client and server\n- TypeScript for compile-time safety\n- CORS and session security\n\n---\n\n## Contribution\n\nPRs and issues welcome! Please follow the established code style and patterns:\n\n- Strict TypeScript\n- Functional, compositional React\n- TailwindCSS utilities\n- GraphQL codegen for types\n- Server-side data fetching in loaders\n\n---\n\n## License\n\nMIT © Seth Davis\n\n---\n\n## Credits\n\n- [KeystoneJS](https://keystonejs.io/)\n- [React Router](https://reactrouter.com/)\n- [TailwindCSS](https://tailwindcss.com/)\n- [Prisma](https://www.prisma.io/)\n- [Vite](https://vitejs.dev/)\n- [PostHog](https://posthog.com/)\n\n---\n\n## See Also\n\n- [Frontend README (`web/`)](web/README.md)\n- [CMS README (`cms/`)](cms/README.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsethdavis512%2Fportfolio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsethdavis512%2Fportfolio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsethdavis512%2Fportfolio/lists"}