# MCS TicketHub [![Node.js](https://img.shields.io/badge/Node.js-%23339933?logo=node.js&logoColor=white)](https://nodejs.org/) [![Express](https://img.shields.io/badge/Express-%236a6a6a?logo=express&logoColor=white)](https://expressjs.com/) [![React](https://img.shields.io/badge/React-%2361DAFB?logo=react&logoColor=black)](https://reactjs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-%23007ACC?logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![Vite](https://img.shields.io/badge/Vite-%23646CFF?logo=vite&logoColor=white)](https://vitejs.dev/) [![MySQL](https://img.shields.io/badge/MySQL-%2300758F?logo=mysql&logoColor=white)](https://www.mysql.com/) [![Docker](https://img.shields.io/badge/Docker-%230db7ed?logo=docker&logoColor=white)](https://www.docker.com/) [![Tailwind CSS](https://img.shields.io/badge/Tailwind%20CSS-%2338B2AC?logo=tailwindcss&logoColor=white)](https://tailwindcss.com/) MCS TicketHub — my first project. I intend to sell this application. The app manages "Losnummer" (ticket) records: a React + TypeScript frontend provides CSV import, table view, and row editing; an Express backend exposes REST endpoints and JWT-protected admin actions; data is persisted in a MySQL `lose` table. The project is containerised with Docker Compose for easy local development. ## Quick overview - Backend: Express.js (ES Modules), serves JSON APIs and EJS root view. - Frontend: React + TypeScript + Vite (UI for importing CSVs and managing entries). - Database: MySQL 8.0 with a simple schema (`lose` and `admin_user`). - Orchestration: `docker-compose.yml` to run backend and MySQL (frontend is prepared but commented out in compose). ## Goals - Import and manage losnummer (ticket) entries. - Allow admins to login and perform protected operations (create, delete, update rows). - Keep the setup easy to run locally via Docker. ## API (backend) All endpoints are served by the Express backend in `backend/server.js`. Public - GET / — renders `index.ejs` (simple root view) - POST /lose — accepts an update payload and attempts a conditional UPDATE on `lose` rows (no auth) - POST /login — admin login; returns a JWT token on success Protected (require Authorization: Bearer ) - GET /table-data — returns all rows from `lose` - POST /create-entry — bulk-insert losnummer values (body: { losnummer: [...] }) - DELETE /remove-entries — delete rows by losnummer (body: { losnummern: [...] }) - PUT /save-row — update a single row (body contains row fields) - DELETE /reset-data — delete all rows from `lose` Authentication - Tokens are generated using `jose` and signed with `SECRET_KEY` in `backend/services/tokenService.js`. - The `authenticate` middleware expects an `Authorization` header with `Bearer `. ## Database schema Schema available in `backend/scheme.sql` — main tables: - `lose` (columns): - `losnummer` VARCHAR(255) UNIQUE - `vorname`, `nachname`, `adresse`, `plz`, `email` (nullable) - `admin_user` (columns): `username` (unique), `password` (plain text in current implementation) Notes: - The current SQL uses simple types and a single `losnummer` unique constraint. Consider adding an auto-increment id column if needed. You can also see the database schema in `backend/scheme.sql`. ## Project structure (high level) - backend/ - `server.js` — Express app, routes and middleware - `services/database.js` — MySQL pool and query helpers - `services/tokenService.js` — token generation and authentication middleware - `scheme.sql` — DDL for tables - frontend/ - React + TypeScript app scaffolded with Vite - `src/components` — UI components (Admin, Table, Import GUI, Forms) - docker-compose.yml — config for backend and MySQL containers ## Commercial intent The project owner intends to sell this application commercially. If you are interested in licensing or purchasing the application, add contact details or a sales/licensing process to this README or repository metadata.