diff --git a/LICENSE b/LICENSE index 8ab70c0..31bafd2 100644 --- a/LICENSE +++ b/LICENSE @@ -1 +1,21 @@ -MIT \ No newline at end of file +MIT License + +Copyright (c) 2026 Gabriel Kaszewski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 86deea3..fec480a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,79 @@ # PocketChords -A rip-off of [TabsUltimate](https://www.tabultimateguitar.com/) with a focus on mobile users, without any ads or subscription. It is open source and free to use. +A rip-off of [Ultimate Guitar](https://www.ultimate-guitar.com/) with a focus on mobile users, without any ads or subscription. Self-hosted, open source and free to use. + +## Features + +- Import chord sheets from Ultimate Guitar URLs or HTML files (bulk import supported) +- Transpose chords up/down with one tap +- Piano keyboard and guitar fretboard chord diagrams +- Capo support with sounding-key display +- Adjustable font size (S/M/L) for readability while playing +- Search and sort your library +- Dark/light theme +- PWA — add to home screen for native feel +- JWT auth with registration/login +- OpenAPI docs at `/docs` + +## Architecture + +Hexagonal / ports-and-adapters with CQRS in the application layer. See `architecture.mmd` for the full diagram. + +``` +crates/ + domain/ # entities, value objects, ports, domain services + application/ # use cases: songs/, tabs/, auth/ (commands, queries, deps) + presentation/ # axum HTTP server, routes, extractors, OpenAPI + api-types/ # request/response DTOs + infra-wiring/ # shared config (AppConfig) + adapters/ + sqlite/ # SQLite persistence (songs, users, refresh sessions) + ug-parser/ # Ultimate Guitar HTML parser + auth/ # JWT + Argon2 password hashing +app/ # React Router SPA (Tailwind, shadcn/ui) +``` + +## Quick start + +```bash +# prerequisites: rust, node + +# run locally (builds frontend, starts backend on :8000) +make dev + +# or backend only (if frontend already built) +make dev-api + +# run checks (fmt, clippy, tests) +make check +``` + +## Deployment + +Single Docker image serves both API and SPA: + +```bash +# build and push to private registry +make deploy + +# or with a specific tag +./deploy.sh --tag v1.0.0 +``` + +### Environment variables + +| Variable | Default | Description | +| ---------------------- | ----------------------------- | ------------------------------ | +| `DATABASE_URL` | `sqlite://./pocket-chords.db` | SQLite connection string | +| `HOST` | `0.0.0.0` | Bind address | +| `PORT` | `8000` | Bind port | +| `JWT_SECRET` | _(required)_ | Secret for signing JWTs | +| `JWT_TTL_SECONDS` | `900` | Access token TTL (15 min) | +| `REFRESH_TTL_SECONDS` | `2592000` | Refresh token TTL (30 days) | +| `ALLOW_REGISTRATION` | `false` | Enable user registration | +| `CORS_ALLOWED_ORIGINS` | `*` | Comma-separated origins or `*` | +| `SPA_DIR` | `./app/build/client` | Path to SPA static files | + +## License + +MIT (see [LICENSE](LICENSE) for details). diff --git a/app/README.md b/app/README.md index 5c4780a..42e5617 100644 --- a/app/README.md +++ b/app/README.md @@ -1,87 +1,32 @@ -# Welcome to React Router! +# PocketChords — Frontend -A modern, production-ready template for building full-stack React applications using React Router. +React Router v7 SPA with Tailwind CSS and shadcn/ui. Mobile-first design for viewing chord charts while playing. -[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/remix-run/react-router-templates/tree/main/default) - -## Features - -- 🚀 Server-side rendering -- ⚡️ Hot Module Replacement (HMR) -- 📦 Asset bundling and optimization -- 🔄 Data loading and mutations -- 🔒 TypeScript by default -- 🎉 TailwindCSS for styling -- 📖 [React Router docs](https://reactrouter.com/) - -## Getting Started - -### Installation - -Install the dependencies: +## Setup ```bash npm install ``` -### Development - -Start the development server with HMR: +## Development ```bash npm run dev ``` -Your application will be available at `http://localhost:5173`. +Opens at `http://localhost:5173`. Set `VITE_API_URL` in `.env` to point to the backend (defaults to `/api`). -## Building for Production - -Create a production build: +## Build ```bash npm run build ``` -## Deployment +Outputs static files to `build/client/`. The Rust backend serves these in production. -### Docker Deployment +## Stack -To build and run using Docker: - -```bash -docker build -t my-app . - -# Run the container -docker run -p 3000:3000 my-app -``` - -The containerized application can be deployed to any platform that supports Docker, including: - -- AWS ECS -- Google Cloud Run -- Azure Container Apps -- Digital Ocean App Platform -- Fly.io -- Railway - -### DIY Deployment - -If you're familiar with deploying Node applications, the built-in app server is production-ready. - -Make sure to deploy the output of `npm run build` - -``` -├── package.json -├── package-lock.json (or pnpm-lock.yaml, or bun.lockb) -├── build/ -│ ├── client/ # Static assets -│ └── server/ # Server-side code -``` - -## Styling - -This template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever CSS framework you prefer. - ---- - -Built with ❤️ using React Router. +- React 19 + React Router 7 (SPA mode) +- Tailwind CSS 4 + shadcn/ui +- Tonal (music theory / chord voicings) +- Vite diff --git a/architecture.mmd b/architecture.mmd new file mode 100644 index 0000000..91ba699 --- /dev/null +++ b/architecture.mmd @@ -0,0 +1,64 @@ +graph TD + subgraph Presentation + MAIN[main.rs] + ROUTES[routes/] + EXTRACT[extractors] + OPENAPI[OpenAPI / Scalar] + SPA[SPA static files] + end + + subgraph Application + SONGS_UC[songs/] + TABS_UC[tabs/] + AUTH_UC[auth/] + end + + subgraph Domain + MODELS[models/] + VO[value_objects/] + PORTS[ports/] + SERVICES[services/] + ERRORS[errors/] + end + + subgraph Adapters + SQLITE[(SQLite)] + UG[UG Parser] + JWT[JWT + Argon2] + end + + subgraph "Shared Crates" + API_TYPES[api-types] + INFRA[infra-wiring] + end + + subgraph Frontend + REACT[React SPA] + end + + MAIN --> ROUTES + MAIN --> OPENAPI + ROUTES --> EXTRACT + ROUTES --> SONGS_UC + ROUTES --> TABS_UC + ROUTES --> AUTH_UC + ROUTES --> API_TYPES + + SONGS_UC --> PORTS + TABS_UC --> PORTS + AUTH_UC --> PORTS + + PORTS --> MODELS + PORTS --> VO + PORTS --> ERRORS + SERVICES --> MODELS + SERVICES --> VO + + SQLITE -.->|implements| PORTS + UG -.->|implements| PORTS + JWT -.->|implements| PORTS + + MAIN --> INFRA + MAIN --> SPA + REACT -->|/api/*| ROUTES + SPA -->|serves| REACT