{"id":46222572,"url":"https://github.com/andyfrith/todos-admin","last_synced_at":"2026-03-03T14:53:04.631Z","repository":{"id":338293026,"uuid":"1157343467","full_name":"andyfrith/todos-admin","owner":"andyfrith","description":"A production-ready full-stack starter built with the TanStack ecosystem: type-safe routing, server functions, real-time data with React Query, and a PostgreSQL-backed Todo CRUD app. ","archived":false,"fork":false,"pushed_at":"2026-02-13T20:19:42.000Z","size":4431,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-02-14T02:19:51.021Z","etag":null,"topics":["e2e-testing","playwright","postgre","react","react-hook-form","shadcn","tanstack-query","tanstack-router","tanstack-start","typescript","zod"],"latest_commit_sha":null,"homepage":"","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/andyfrith.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":"2026-02-13T17:57:13.000Z","updated_at":"2026-02-13T20:29:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/andyfrith/todos-admin","commit_stats":null,"previous_names":["andyfrith/todos-admin"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/andyfrith/todos-admin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyfrith%2Ftodos-admin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyfrith%2Ftodos-admin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyfrith%2Ftodos-admin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyfrith%2Ftodos-admin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andyfrith","download_url":"https://codeload.github.com/andyfrith/todos-admin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyfrith%2Ftodos-admin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30050210,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-03T14:38:37.398Z","status":"ssl_error","status_checked_at":"2026-03-03T14:38:06.721Z","response_time":61,"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":["e2e-testing","playwright","postgre","react","react-hook-form","shadcn","tanstack-query","tanstack-router","tanstack-start","typescript","zod"],"created_at":"2026-03-03T14:53:03.951Z","updated_at":"2026-03-03T14:53:04.626Z","avatar_url":"https://github.com/andyfrith.png","language":"TypeScript","readme":"# Todos Admin\n\nA **production-ready full-stack starter** built with the TanStack ecosystem: type-safe routing, server functions, real-time data with React Query, and a PostgreSQL-backed Todo CRUD app. Use it as a template to ship features fast—or as a reference for modular architecture and modern React patterns.\n\n---\n\n## 🎯 Purpose\n\n**Todos Admin** is a minimal but complete TanStack Start application. It gives you:\n\n- A **ready-to-extend** stack: React 19, TypeScript, TanStack Router \u0026 Query, Drizzle ORM, and Shadcn UI.\n- A **working Todo example** (list, add, edit, delete) so you see data flow from DB → server functions → hooks → UI.\n- **Documentation and structure** designed for both humans and AI-assisted development (e.g. Cursor, Claude).\n\nClone it, point it at a Postgres database, and start building—no boilerplate archaeology required.\n\n---\n\n## 📸 Screenshots\n\n![Todos Admin – Todo list view](screenshot1.png)\n\n_Todo list view_\n\n![Todos Admin – Add / Edit flow](screenshot2.png)\n\n_Add / Edit flow_\n\n---\n\n## ✨ Features\n\n| Feature                        | Description                                                                                    |\n| ------------------------------ | ---------------------------------------------------------------------------------------------- |\n| **Full Todo CRUD**             | List, create, edit, and delete todos with validation (title, summary, description, todo type). |\n| **Type-safe server functions** | TanStack Start server functions with Zod validation and Drizzle for persistence.               |\n| **TanStack Query**             | Caching, invalidation, and loading/error states out of the box.                                |\n| **File-based routing**         | TanStack Router with layouts; routes like `/`, `/todos`, `/todos/add`, `/todos/:id/edit`.      |\n| **Forms**                      | React Hook Form + Zod + Shadcn (Field, Input, Select, Checkbox) with a shared schema.          |\n| **Theming**                    | Light, dark, system, and Sunshine themes with next-themes and CSS variables (see [Theming](docs/ux/Theming.md)). |\n| **Toasts**                     | Sonner for success and error feedback on mutations.                                            |\n| **Storybook**                  | Isolated development and documentation for UI components and routes (see [Storybook](#-storybook) below). |\n| **Testing**                    | Vitest for unit/integration; Playwright for E2E (critical flows).                              |\n| **Dev experience**             | ESLint, Prettier, TanStack Router/Query devtools, Drizzle Studio.                              |\n\n---\n\n## 🛠️ Tech Stack\n\n| Layer                  | Technology                                                                        |\n| ---------------------- | --------------------------------------------------------------------------------- |\n| **Framework**          | [TanStack Start](https://tanstack.com/start) (React + Vite + Cloudflare Workers)  |\n| **Routing**            | [TanStack Router](https://tanstack.com/router) (file-based)                       |\n| **Data \u0026 cache**       | [TanStack Query](https://tanstack.com/query) (React Query)                        |\n| **Database**           | PostgreSQL + [Drizzle ORM](https://orm.drizzle.team/)                             |\n| **Validation \u0026 types** | [Zod](https://zod.dev/) + TypeScript                                              |\n| **Styling**            | [Tailwind CSS](https://tailwindcss.com/) v4 + [Shadcn UI](https://ui.shadcn.com/) |\n| **Forms**              | [React Hook Form](https://react-hook-form.com/) + `@hookform/resolvers` (Zod)     |\n| **Notifications**      | [Sonner](https://sonner.emilkowal.ski/)                                           |\n| **Testing**            | [Vitest](https://vitest.dev/), [Playwright](https://playwright.dev/)              |\n| **Package manager**    | pnpm                                                                              |\n\n---\n\n## 📁 Project Structure\n\nThe codebase follows a **modular (layered) architecture**: presentation → hooks → server functions → database. Each layer has a clear home.\n\n```\nsrc/\n├── router.tsx              # Router + TanStack Query context (do not call from app code)\n├── routeTree.gen.ts        # Generated routes (do not edit)\n├── styles.css              # Tailwind + theme variables\n├── components/\n│   ├── todos/              # Feature: list, item, add/edit forms + *.stories.tsx\n│   ├── ui/                 # Shadcn primitives (button, input, select, field, etc.)\n│   ├── storybook/          # Shadcn/UI stories (button, input, dialog, etc.)\n│   └── Header.tsx          # Layout + Header.stories.tsx\n├── routes/                 # File-based: __root, index, todos/, …; -*.stories.tsx for route stories\n├── hooks/                  # useTodos, useCreateTodo, useUpdateTodo, useDeleteTodo\n├── queries/                # TanStack Query options (e.g. todosQueryOptions)\n├── server/fn/              # Server functions: getTodos, createTodo, updateTodo, deleteTodo\n├── db/\n│   ├── schema.ts           # Drizzle table definitions (source of truth for DB)\n│   └── index.ts            # Drizzle client + connection\n├── lib/\n│   ├── schema.ts           # Zod schemas + inferred types (Todo, TodoSchema) for forms \u0026 API\n│   └── utils.ts            # cn() and other shared helpers\n├── integrations/           # TanStack Query provider + devtools\n└── data/                   # Static/demo data (e.g. demo server functions)\n```\n\n**Rule of thumb:** Routes and components use **hooks**; hooks use **server functions** and **query options**; server functions use **Drizzle** and **`lib/schema`**. No UI or routes in server/db code.\n\n---\n\n## 🏗️ Architecture Patterns\n\n- **Server functions as API** — All Todo operations are TanStack Start server functions (`createServerFn`). No REST route files for CRUD; the client calls functions like `createTodo({ data: { title } })`.\n- **Single source of truth for types** — DB shape in `src/db/schema.ts`; app and validation in `src/lib/schema.ts` (Zod + inferred types). Forms and server I/O share the same schemas.\n- **Query options + hooks** — Query keys and `queryFn`s live in `src/queries/`; hooks in `src/hooks/` wrap mutations, invalidate cache (e.g. `['todos']`), and show toasts.\n- **Layered dependencies** — Presentation (routes, components) → hooks → server functions → database. Keeps the app testable and easy to change.\n\nFor full detail (data flow, examples, best practices), see **[docs/technical/architecture.md](docs/technical/architecture.md)**.\n\n---\n\n## 📚 Documentation\n\n| Document                                                     | Description                                                                                      |\n| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ |\n| **[Blueprint: scaffold new apps](docs/blueprint/README.md)**  | Use this repo as a template: scaffolding tasks, Cursor prompts, and step-by-step guide.         |\n| **[Product requirements (PRD)](docs/prd.md)**                | Scope, data model, user flows, requirements, API contract, and implementation order for LLMs.    |\n| **[Technical architecture](docs/technical/architecture.md)** | Modular layers, directory layout, server functions, DB, hooks, queries, routes, and conventions. |\n| **[Deployment](docs/deployment.md)**                         | Cloudflare Workers: build, deploy (via Cloudflare + GitHub), env vars, custom domains.            |\n| **[Form patterns](docs/ux/forms-react-hook-form-shadcn.md)** | React Hook Form + Zod + Shadcn patterns used for Todo add/edit.                                  |\n| **[Theming](docs/ux/Theming.md)**                             | Theme options (light, dark, system, Sunshine), CSS variables, and adding new themes.             |\n| **[E2E testing](docs/e2e-testing.md)**                        | Playwright setup and conventions for end-to-end tests.                                            |\n\n---\n\n## 🚀 Getting Started\n\n### Prerequisites\n\n- Node.js (LTS)\n- pnpm (`npm install -g pnpm`)\n- PostgreSQL (local or Docker)\n\n### Setup\n\n1. **Clone and install**\n\n   ```bash\n   pnpm install\n   ```\n\n2. **Configure the database**\n\n   Copy `.env.example` to `.env` or `.env.local` and set either:\n   - `DATABASE_URL=postgres://user:password@host:port/dbname`  \n     or\n   - `DB_USER`, `DB_PASSWORD`, `DB_HOST`, `DB_PORT`, `DB_NAME`\n\n   Then create the schema:\n\n   ```bash\n   pnpm db:push\n   # or: pnpm db:generate \u0026\u0026 pnpm db:migrate\n   ```\n\n3. **Run the app**\n\n   ```bash\n   pnpm dev\n   ```\n\n   Open [http://localhost:3000](http://localhost:3000). You should see the app and be able to list, add, edit, and delete todos.\n\n### Other commands\n\n| Command                | Description                                        |\n| ---------------------- | -------------------------------------------------- |\n| `pnpm build`           | Production build                                   |\n| `pnpm preview`         | Preview production build locally (Workers runtime) |\n| `pnpm deploy`          | Build and deploy to Cloudflare Workers             |\n| `pnpm cf-typegen`      | Generate Wrangler types for bindings               |\n| `pnpm test`            | Run Vitest unit/integration tests                  |\n| `pnpm run test:e2e`    | Run Playwright E2E tests                           |\n| `pnpm run test:e2e:ui` | Playwright E2E in UI mode                          |\n| `pnpm lint`            | Run ESLint                                         |\n| `pnpm check`           | Prettier + ESLint (format and fix)                 |\n| `pnpm db:studio`       | Open Drizzle Studio                                |\n| `pnpm storybook`       | Start Storybook (default port 6006)                |\n| `pnpm build-storybook` | Build static Storybook for deployment              |\n\n### Deployment\n\nThe app deploys to **Cloudflare Workers** via the Cloudflare Vite plugin. To deploy:\n\n1. Log in once: `pnpm wrangler login`\n2. Deploy: `pnpm deploy`\n\nFor deployment (Cloudflare + GitHub), environment variables, and custom domains, see **[docs/deployment.md](docs/deployment.md)**.\n\n### Branching\n\nFeature work is done on branches created from **`development`**:\n\n```bash\ngit checkout development\ngit pull origin development\ngit checkout -b feature/your-feature-name\n```\n\nOpen pull requests against **`development`**. Merge to `master` when releasing. The **Lint \u0026 test** CI check must pass before merging into `development` or `master`. Deployment is handled by Cloudflare’s GitHub integration (see [Deployment](docs/deployment.md)).\n\n### Adding Shadcn components\n\nUse the latest Shadcn CLI:\n\n```bash\npnpm dlx shadcn@latest add button\n```\n\n### Storybook\n\nStories live under `src/components/` (e.g. `Header.stories.tsx`, `todos/FeatureInfo.stories.tsx`, `storybook/*.stories.*`) and `src/routes/`. For route files, **prefix the story filename with `-`** (e.g. `-index.stories.tsx`) so the TanStack Router plugin does not treat it as a route. Run `pnpm storybook` to open the UI; use `pnpm build-storybook` for a static build.\n\n---\n\n## 🔗 Learn more\n\n- [TanStack](https://tanstack.com) — Router, Query, Start, and more\n- [Drizzle ORM](https://orm.drizzle.team/)\n- [Shadcn UI](https://ui.shadcn.com/)\n- [Tailwind CSS](https://tailwindcss.com/)\n\n---\n\n## 📫 Let's Connect\n\n- **Portfolio:** [andyfrith.com](https://andyfrith.com)\n- **LinkedIn:** [linkedin.com/in/goodapplemedia](https://linkedin.com/in/goodapplemedia)\n- **GitHub:** [@andyfrith](https://github.com/andyfrith)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandyfrith%2Ftodos-admin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandyfrith%2Ftodos-admin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandyfrith%2Ftodos-admin/lists"}